You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
2.9 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}