Backend/modules/kraProtocol/kraProtocol.go

195 lines
4.2 KiB
Go

package kraProtocol
import (
"reflect"
"krakatoa.net/backend/modules/structs"
)
const (
StatusSend = 10
StatusGet = 11
StatusMessageAlreadyInQueue = 12
StatusErrNoPerms = 13
StatusErrTryAgain = 14
StatusErrArgLenTooBig = 15
StatusReply = 16
DestBackend = 1
DestVoice = 2
DestMobile = 3
DestProxy = 10
DestPlayersCurrentServer = 11
DefaultCmdID = 1
DummyUUID = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
)
func EncodeWebMessage(status int, cmdID int, cmdNumber int, args interface{}) []byte {
argType := reflect.TypeOf(args).String()
var argLen int
var kraProtocolMessageToClientData structs.KraProtocolMessageToClient
if argType == "string" {
argLen = len(args.(string))
} else {
kraProtocolMessageToClientData = args.(structs.KraProtocolMessageToClient)
argLen = kraProtocolMessageToClientData.ByteLength
}
rawLen := 4 + argLen
raw := make([]byte, rawLen)
raw[0] = byte(status)
raw[1] = byte(cmdID)
raw[2] = byte(cmdNumber & 0xFF)
raw[3] = byte((cmdNumber >> 8) & 0xFF)
if argLen > 4 {
raw[4] = byte(argLen & 0xFF)
raw[5] = byte((argLen >> 8) & 0xFF)
if argType == "string" {
for i, c := range reflect.ValueOf(args).String() {
raw[4+i] = byte(c)
}
} else {
raw[4] = byte(kraProtocolMessageToClientData.Value & 0xFF)
for i := 1; i < kraProtocolMessageToClientData.ByteLength; i++ {
raw[4+i] = byte((kraProtocolMessageToClientData.Value >> (8 * i)) & 0xFF)
}
}
}
return raw
}
// for testing only
func SimulateMessageFromWebClient(status int, cmdID int, dest int, cmdNumber int, args string) []byte {
argLen := len(args)
rawLen := 4 + argLen + 1
raw := make([]byte, rawLen)
raw[0] = byte(status)
raw[1] = byte(cmdID)
raw[2] = byte(dest)
raw[3] = byte(cmdNumber & 0xFF)
raw[4] = byte((cmdNumber >> 8) & 0xFF)
raw[5] = byte(argLen & 0xFF)
raw[6] = byte((argLen >> 8) & 0xFF)
for i, c := range args {
raw[5+i] = byte(c)
}
return raw
}
func EncodeJavaMessage(status int, cmdID int, dest int, playerUuid string, cmdNumber int, args interface{}) []byte {
argType := reflect.TypeOf(args).String()
var argLen int
var kraProtocolMessageToClientData structs.KraProtocolMessageToClient
if argType == "string" {
argLen = len(args.(string))
} else {
kraProtocolMessageToClientData = args.(structs.KraProtocolMessageToClient)
argLen = kraProtocolMessageToClientData.ByteLength
}
argLen = 40 + argLen
raw := make([]byte, argLen)
raw[0] = byte(status)
raw[1] = byte(cmdID)
raw[2] = byte((cmdID >> 8) & 0xFF)
raw[3] = byte((cmdID >> 16) & 0xFF)
raw[4] = byte((cmdID >> 24) & 0xFF)
raw[5] = byte(dest)
for i, c := range playerUuid {
raw[6+i] = byte(c)
}
raw[38] = byte(cmdNumber)
raw[39] = byte((cmdNumber >> 8) & 0xFF)
if argLen > 40 {
if argType == "string" {
for i, c := range reflect.ValueOf(args).String() {
raw[40+i] = byte(c)
}
} else {
raw[40] = byte(kraProtocolMessageToClientData.Value & 0xFF)
for i := 1; i < kraProtocolMessageToClientData.ByteLength; i++ {
raw[40+i] = byte((kraProtocolMessageToClientData.Value >> (8 * i) & 0xFF))
}
}
}
return raw
}
func DecodeWebMessage(data []byte) (Status int, CmdID int, Dest int, CmdNumber int, Args string) {
status := data[0]
cmdID := data[1]
if int(status) == StatusReply {
return int(status), int(cmdID), 0, 0, ""
}
dest := data[2]
cmdNumber := int(data[4])*256 + int(data[3])
argLen := len(data) - 5
args := make([]byte, argLen)
for i := 0; i < int(argLen); i++ {
args[i] = data[5+i]
}
return int(status), int(cmdID), int(dest), int(cmdNumber), string(args)
}
func DecodeJavaMessage(data []byte) (Status int, CmdID int, Dest int, PlayerUuid string, CmdNumber int, Args string) {
status := data[0]
cmdID := int(data[1]) + int(data[2])*256 + int(data[3])*256*256 + int(data[4])*256*256*256
dest := data[5]
playerUuid := make([]byte, 32)
for i := 0; i < 32; i++ {
playerUuid[i] = data[6+i]
}
cmdNumber := int(data[38]) + int(data[39])*256
argLen := len(data) - 40
args := make([]byte, argLen)
for i := 0; i < int(argLen); i++ {
args[i] = data[40+i]
}
return int(status), cmdID, int(dest), string(playerUuid), cmdNumber, string(args)
}