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])< 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 }