237 lines
6.8 KiB
Go
237 lines
6.8 KiB
Go
package serverCommunication
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/gofiber/websocket/v2"
|
|
"krakatoa.net/backend/modules/cache"
|
|
"krakatoa.net/backend/modules/kraProtocol"
|
|
"krakatoa.net/backend/modules/logger"
|
|
"krakatoa.net/backend/modules/structs"
|
|
)
|
|
|
|
func HandleMinecraftMessage(conn *websocket.Conn, msg []byte) {
|
|
status, cmdID, dest, playerUuid, cmdNumber, args := kraProtocol.DecodeJavaMessage(msg)
|
|
|
|
mcClient := GetMinecraftClientByConn(conn)
|
|
|
|
if mcClient == nil {
|
|
logger.Minecraft.Warnln("mcClient is nil")
|
|
return
|
|
}
|
|
|
|
if status == kraProtocol.StatusReply {
|
|
if isCmdIDInList(mcClient.CmdIDs, cmdID) {
|
|
mcClient.RemoveCmdID(cmdID)
|
|
}
|
|
return
|
|
}
|
|
|
|
var raw []byte
|
|
var err error
|
|
|
|
// queue handling when message already in process
|
|
if status == kraProtocol.StatusGet {
|
|
// cmdID already in queue
|
|
logger.Minecraft.Debugln("cmdIDList", mcClient.CmdIDs)
|
|
if isCmdIDInList(mcClient.CmdIDs, cmdID) {
|
|
raw := kraProtocol.EncodeJavaMessage(kraProtocol.StatusMessageAlreadyInQueue, cmdID, dest, playerUuid, cmdNumber, args)
|
|
|
|
err = mcClient.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("write err", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// not in queue, add to queue
|
|
mcClient.CmdIDs = append(mcClient.CmdIDs, cmdID)
|
|
}
|
|
|
|
// dest handling
|
|
if dest == kraProtocol.DestBackend {
|
|
resArgs := minecraftCommandHandler(cmdNumber, playerUuid)
|
|
|
|
if status == kraProtocol.StatusGet {
|
|
raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusReply, cmdID, 0, playerUuid, cmdNumber, resArgs)
|
|
|
|
err = mcClient.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("write:", err)
|
|
}
|
|
}
|
|
} else if dest == kraProtocol.DestVoice || dest == kraProtocol.DestMobile { // forwarding messsage to voice or mobile
|
|
webClient := GetWebClientByUuid(playerUuid)
|
|
|
|
if webClient == nil || dest == kraProtocol.DestVoice && webClient.VoiceConn == nil || dest == kraProtocol.DestMobile && webClient.MobileConn == nil {
|
|
raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusErrTryAgain, cmdID, 0, playerUuid, cmdNumber, args)
|
|
|
|
err = mcClient.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("write:", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if status == kraProtocol.StatusGet {
|
|
webClient := GetWebClientByUuid(playerUuid)
|
|
|
|
var webCmdID int
|
|
|
|
if dest == kraProtocol.DestVoice {
|
|
webCmdID = structs.GenerateWebCmdID(webClient.CurrentVoiceCmdIDIndexByBackend)
|
|
|
|
webClient.CurrentVoiceCmdIDIndexByBackend = webCmdID
|
|
|
|
logger.Minecraft.Debugln("webCmdID", webCmdID)
|
|
|
|
a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: 10}
|
|
|
|
webClient.VoiceCmdIDsByBackend = append(webClient.VoiceCmdIDsByBackend, a)
|
|
|
|
logger.Minecraft.Debugln("VoiceCMDIDsByBackend", webClient.VoiceCmdIDsByBackend)
|
|
} else { // dest mobile
|
|
webCmdID = structs.GenerateWebCmdID(webClient.CurrentMobileVoiceCmdIDIndexByBackend)
|
|
|
|
webClient.CurrentMobileVoiceCmdIDIndexByBackend = webCmdID
|
|
|
|
logger.Minecraft.Debugln("webCmdID", webCmdID)
|
|
|
|
a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: 10}
|
|
|
|
webClient.MobileCmdIDsByBackend = append(webClient.MobileCmdIDsByBackend, a)
|
|
|
|
logger.Minecraft.Debugln("MobileCMDIDsByBackend", webClient.MobileCmdIDsByBackend)
|
|
}
|
|
|
|
raw = kraProtocol.EncodeWebMessage(kraProtocol.StatusGet, webCmdID, cmdNumber, args)
|
|
|
|
if dest == kraProtocol.DestVoice {
|
|
webClient.SendVoiceQueueMessages = append(webClient.SendVoiceQueueMessages, &structs.SendQueueMessage{MessageRaw: raw, CmdID: webCmdID, TrySendCount: 0, Time: time.Now()})
|
|
} else {
|
|
webClient.SendMobileQueueMessages = append(webClient.SendMobileQueueMessages, &structs.SendQueueMessage{MessageRaw: raw, CmdID: webCmdID, TrySendCount: 0, Time: time.Now()})
|
|
}
|
|
} else {
|
|
raw = kraProtocol.EncodeWebMessage(kraProtocol.StatusSend, 0, cmdNumber, args)
|
|
}
|
|
|
|
if dest == kraProtocol.DestVoice {
|
|
webClient.SendBinaryMessage(webClient.VoiceConn, raw)
|
|
} else {
|
|
webClient.SendBinaryMessage(webClient.MobileConn, raw)
|
|
}
|
|
} else if dest == kraProtocol.DestProxy {
|
|
client := GetMinecraftClientByName("proxy-1")
|
|
|
|
if client == nil {
|
|
raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusErrTryAgain, cmdID, 0, playerUuid, cmdNumber, "")
|
|
|
|
err = mcClient.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("write:", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if status == kraProtocol.StatusGet {
|
|
raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusGet, cmdID, dest, playerUuid, cmdNumber, args)
|
|
} else {
|
|
raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusSend, 0, dest, playerUuid, cmdNumber, args)
|
|
}
|
|
|
|
err = client.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("write:", err)
|
|
}
|
|
} else { // TODO: handle messages -> GameServer-1 to GameServer-2
|
|
logger.Minecraft.Debugln("dest not found", dest)
|
|
}
|
|
}
|
|
|
|
func GetMinecraftClientByName(Name string) *structs.MinecraftClient {
|
|
for name, client := range cache.MinecraftClients {
|
|
if name == Name {
|
|
logger.Minecraft.Debugln("return mc client", client.Name)
|
|
return client
|
|
}
|
|
}
|
|
|
|
logger.Minecraft.Warnln("mc client nil")
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetMinecraftClientByConn(conn *websocket.Conn) *structs.MinecraftClient {
|
|
for _, client := range cache.MinecraftClients {
|
|
if client.Conn == conn {
|
|
return client
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getMinecraftServerNameByDest(dest int) string {
|
|
if dest == kraProtocol.DestProxy {
|
|
return "proxy-1"
|
|
} else { // get players current server from db if dest is 11
|
|
return "lobby-1"
|
|
}
|
|
}
|
|
|
|
func minecraftCommandHandler(cmdNumber int, playerUuid string) (args string) {
|
|
switch cmdNumber {
|
|
case 10: // testing
|
|
return IsVoiceAndMobileSocketConnected(playerUuid)
|
|
default:
|
|
return "default"
|
|
}
|
|
}
|
|
|
|
// Deprecated: only for testing, use SendMessageToMinecraftServer instead
|
|
func SendMessageToServer(dest int, playerUuid string, args string) {
|
|
mcClient := GetMinecraftClientByName(getMinecraftServerNameByDest(dest))
|
|
|
|
raw := kraProtocol.EncodeJavaMessage(10, 1, 2, playerUuid, 15, args)
|
|
|
|
if mcClient != nil {
|
|
mcClient.SendBinaryMessage(raw)
|
|
}
|
|
}
|
|
|
|
func SendMessageToMinecraftServer(status int, dest int, playerUuid string, cmdNumber int, args string) error {
|
|
cmdID := kraProtocol.DefaultCmdID
|
|
|
|
serverName := getMinecraftServerNameByDest(dest)
|
|
|
|
mcClient := GetMinecraftClientByName(serverName)
|
|
|
|
if mcClient == nil {
|
|
return errors.New("mcClient nil")
|
|
}
|
|
|
|
if status == kraProtocol.StatusGet {
|
|
cmdID = mcClient.GenerateMinecraftCmdID()
|
|
}
|
|
|
|
raw := kraProtocol.EncodeJavaMessage(status, cmdID, dest, playerUuid, cmdNumber, args)
|
|
|
|
err := mcClient.SendBinaryMessage(raw)
|
|
|
|
if err != nil {
|
|
logger.Minecraft.Warnln("err", err)
|
|
return errors.New("write err: " + err.Error())
|
|
}
|
|
|
|
if status == kraProtocol.StatusGet {
|
|
mcClient.SendQueueMessages = append(mcClient.SendQueueMessages, &structs.SendQueueMessage{MessageRaw: raw, CmdID: cmdID, TrySendCount: 0, Time: time.Now()})
|
|
}
|
|
|
|
return nil
|
|
}
|