mirror of
https://github.com/v2fly/v2ray-core.git
synced 2026-01-06 09:15:37 -05:00
SwitchAccount command
This commit is contained in:
40
proxy/vmess/command/accounts.go
Normal file
40
proxy/vmess/command/accounts.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/serial"
|
||||
"github.com/v2ray/v2ray-core/common/uuid"
|
||||
"github.com/v2ray/v2ray-core/transport"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterResponseCommand(1, func() Command { return new(SwitchAccount) })
|
||||
}
|
||||
|
||||
// Size: 16 + 8 = 24
|
||||
type SwitchAccount struct {
|
||||
ID *uuid.UUID
|
||||
ValidUntil time.Time
|
||||
}
|
||||
|
||||
func (this *SwitchAccount) Marshal(writer io.Writer) (int, error) {
|
||||
idBytes := this.ID.Bytes()
|
||||
timestamp := this.ValidUntil.Unix()
|
||||
timeBytes := serial.Int64Literal(timestamp).Bytes()
|
||||
|
||||
writer.Write(idBytes)
|
||||
writer.Write(timeBytes)
|
||||
|
||||
return 24, nil
|
||||
}
|
||||
|
||||
func (this *SwitchAccount) Unmarshal(data []byte) error {
|
||||
if len(data) != 24 {
|
||||
return transport.CorruptedPacket
|
||||
}
|
||||
this.ID, _ = uuid.ParseBytes(data[0:16])
|
||||
this.ValidUntil = time.Unix(serial.BytesLiteral(data[16:24]).Int64Value(), 0)
|
||||
return nil
|
||||
}
|
||||
35
proxy/vmess/command/accounts_test.go
Normal file
35
proxy/vmess/command/accounts_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package command_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/uuid"
|
||||
. "github.com/v2ray/v2ray-core/proxy/vmess/command"
|
||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||
"github.com/v2ray/v2ray-core/testing/assert"
|
||||
)
|
||||
|
||||
func TestSwitchAccount(t *testing.T) {
|
||||
v2testing.Current(t)
|
||||
|
||||
sa := &SwitchAccount{
|
||||
ID: uuid.New(),
|
||||
ValidUntil: time.Now(),
|
||||
}
|
||||
|
||||
cmd, err := CreateResponseCommand(1)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
buffer := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
nBytes, err := sa.Marshal(buffer)
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(nBytes).Equals(buffer.Len())
|
||||
|
||||
cmd.Unmarshal(buffer.Bytes())
|
||||
sa2, ok := cmd.(*SwitchAccount)
|
||||
assert.Bool(ok).IsTrue()
|
||||
assert.String(sa.ID).Equals(sa2.ID.String())
|
||||
assert.Int64(sa.ValidUntil.Unix()).Equals(sa2.ValidUntil.Unix())
|
||||
}
|
||||
17
proxy/vmess/command/command.go
Normal file
17
proxy/vmess/command/command.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrorNoSuchCommand = errors.New("No such command.")
|
||||
)
|
||||
|
||||
type Command interface {
|
||||
Marshal(io.Writer) (int, error)
|
||||
Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
type CommandCreator func() Command
|
||||
@@ -1,3 +1,18 @@
|
||||
package command
|
||||
|
||||
type ResponseCmd byte
|
||||
var (
|
||||
cmdCache = make(map[byte]CommandCreator)
|
||||
)
|
||||
|
||||
func RegisterResponseCommand(id byte, cmdFactory CommandCreator) error {
|
||||
cmdCache[id] = cmdFactory
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateResponseCommand(id byte) (Command, error) {
|
||||
creator, found := cmdCache[id]
|
||||
if !found {
|
||||
return nil, ErrorNoSuchCommand
|
||||
}
|
||||
return creator(), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user