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.

140 lines
2.9 KiB
Go

package starainrt
import (
"bytes"
"errors"
)
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
Ip string
}
func (this *StarQueue) ParseMessage(msg []byte, ip string) 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), ip}
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, ip)
}
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
}