package serverCommunication import ( "errors" "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 { // TODO: if isCmdIDInList(mcClient.CmdIDs, cmdID) { mcClient.RemoveCmdID(cmdID) } return } var raw []byte var err error 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) } 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) webCmdID := 20 a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: 10} webClient.VoiceCMDIDsByBackend = append(webClient.VoiceCMDIDsByBackend, a) logger.Minecraft.Debugln("VoiceCMDIDsByBackend", webClient.VoiceCMDIDsByBackend) raw = kraProtocol.EncodeWebMessage(kraProtocol.StatusGet, webCmdID, cmdNumber, args) } 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 := 0 raw := kraProtocol.EncodeJavaMessage(status, cmdID, dest, playerUuid, cmdNumber, args) serverName := getMinecraftServerNameByDest(dest) mcClient := GetMinecraftClientByName(serverName) if mcClient == nil { return errors.New("mcClient nil") } err := mcClient.SendBinaryMessage(raw) if err != nil { logger.Minecraft.Warnln("err", err) return errors.New("write err: " + err.Error()) } return nil }