|
|
package starainrt
|
|
|
|
|
|
import (
|
|
|
"bytes"
|
|
|
"errors"
|
|
|
)
|
|
|
|
|
|
/*
|
|
|
SecretKey 通信加密Key,不应当被修改
|
|
|
*/
|
|
|
const SecretKey string = "1996victorique1127B612BTXL"
|
|
|
|
|
|
var header []byte = []byte{11, 27, 19, 96}
|
|
|
var Crypto *StarCrypto
|
|
|
|
|
|
func init() {
|
|
|
Crypto = new(StarCrypto)
|
|
|
}
|
|
|
|
|
|
type StarQueue struct {
|
|
|
Encode bool
|
|
|
Msgid uint16
|
|
|
MsgPool []MsgUsed
|
|
|
UnFinMsg []byte
|
|
|
LastID int //= -1
|
|
|
}
|
|
|
|
|
|
func NewQueue() *StarQueue {
|
|
|
que := new(StarQueue)
|
|
|
que.LastID = -1
|
|
|
que.Encode = true
|
|
|
return que
|
|
|
}
|
|
|
|
|
|
func (this *StarQueue) BuildMessage(str string) []byte {
|
|
|
var msg []byte
|
|
|
var buffer bytes.Buffer
|
|
|
if this.Encode {
|
|
|
msg = Crypto.VicqueEncodeV1([]byte(str), SecretKey)
|
|
|
} else {
|
|
|
msg = []byte(str)
|
|
|
}
|
|
|
buffer.Write([]byte(Crypto.CRC32(msg)))
|
|
|
buffer.Write([]byte{byte(this.Msgid >> 8), byte(this.Msgid)})
|
|
|
buffer.Write(msg)
|
|
|
lens := len(buffer.Bytes())
|
|
|
if lens > 65535 {
|
|
|
return nil
|
|
|
}
|
|
|
msg = make([]byte, lens)
|
|
|
copy(msg, buffer.Bytes())
|
|
|
buffer.Reset()
|
|
|
ulens := uint16(lens)
|
|
|
buffer.Write(header)
|
|
|
buffer.Write([]byte{byte(ulens >> 8), byte(ulens)})
|
|
|
buffer.Write(msg)
|
|
|
this.Msgid++
|
|
|
return buffer.Bytes()
|
|
|
}
|
|
|
|
|
|
type MsgUsed struct {
|
|
|
ID uint16
|
|
|
Msg string
|
|
|
Crc32 string
|
|
|
Conn interface{}
|
|
|
}
|
|
|
|
|
|
func (this *StarQueue) ParseMessage(msg []byte, conn interface{}) int {
|
|
|
var buffer bytes.Buffer
|
|
|
buffer.Write(this.UnFinMsg)
|
|
|
buffer.Write(msg)
|
|
|
msg = buffer.Bytes()
|
|
|
if len(msg) <= 6 {
|
|
|
this.UnFinMsg = msg
|
|
|
return -2
|
|
|
}
|
|
|
if msg[0] != byte(11) {
|
|
|
this.UnFinMsg = []byte{}
|
|
|
//resend last
|
|
|
return this.LastID + 1
|
|
|
}
|
|
|
if msg[1] != byte(27) || msg[2] != byte(19) || msg[3] != byte(96) {
|
|
|
//resend last
|
|
|
this.UnFinMsg = []byte{}
|
|
|
return this.LastID + 1
|
|
|
}
|
|
|
length := uint16(uint(msg[4])<<uint(8) + uint(msg[5]))
|
|
|
if 6+length > uint16(len(msg)) {
|
|
|
this.UnFinMsg = msg
|
|
|
return -2
|
|
|
} else {
|
|
|
this.UnFinMsg = []byte{}
|
|
|
strmsg := msg[6 : length+6]
|
|
|
crc := strmsg[0:8]
|
|
|
id := strmsg[8:10]
|
|
|
strmsg = strmsg[10:]
|
|
|
if Crypto.CRC32([]byte(strmsg)) != string(crc) {
|
|
|
//resend last
|
|
|
this.UnFinMsg = []byte{}
|
|
|
return this.LastID + 1
|
|
|
} else {
|
|
|
if this.Encode {
|
|
|
strmsg = Crypto.VicqueDecodeV1(strmsg, SecretKey)
|
|
|
}
|
|
|
msgs := MsgUsed{uint16(uint(id[0])<<8 + uint(id[1])), string(strmsg), string(crc), conn}
|
|
|
this.LastID = int(msgs.ID)
|
|
|
this.MsgPool = append(this.MsgPool, msgs)
|
|
|
}
|
|
|
if 6+length == uint16(len(msg)) {
|
|
|
return -2
|
|
|
}
|
|
|
msg = msg[length+6:]
|
|
|
return this.ParseMessage(msg, conn)
|
|
|
}
|
|
|
return -2
|
|
|
}
|
|
|
|
|
|
func (this *StarQueue) Restore(n int) ([]MsgUsed, error) {
|
|
|
if n > len(this.MsgPool) {
|
|
|
return nil, errors.New("N is Too Large")
|
|
|
}
|
|
|
tmp := this.MsgPool[0:n]
|
|
|
if n != len(this.MsgPool) {
|
|
|
this.MsgPool = this.MsgPool[n:]
|
|
|
} else {
|
|
|
this.MsgPool = []MsgUsed{}
|
|
|
}
|
|
|
return tmp, nil
|
|
|
}
|
|
|
|
|
|
func (this *StarQueue) RestoreOne() (MsgUsed, error) {
|
|
|
if len(this.MsgPool) == 0 {
|
|
|
return MsgUsed{}, errors.New("N is Too Large")
|
|
|
}
|
|
|
tmp := this.MsgPool[0]
|
|
|
if 1 != len(this.MsgPool) {
|
|
|
this.MsgPool = this.MsgPool[1:]
|
|
|
} else {
|
|
|
this.MsgPool = []MsgUsed{}
|
|
|
}
|
|
|
return tmp, nil
|
|
|
}
|