diff --git a/modules/structs/MinecraftClient.go b/modules/structs/MinecraftClient.go index 5d2d20b..14a60f7 100644 --- a/modules/structs/MinecraftClient.go +++ b/modules/structs/MinecraftClient.go @@ -10,15 +10,10 @@ import ( ) type MinecraftClient struct { - Name string - Dest int - Conn *websocket.Conn - connMu sync.Mutex - //CmdIDs []int // cache for received cmdIDs - //cmdIDMu sync.Mutex - //CmdIDsByBackend []*A - //CmdIDsByBackendMu sync.Mutex - //CurrentCmdIDIndexByBackend int + Name string + Dest int + Conn *websocket.Conn + connMu sync.Mutex CurrentCmdID int // cmdID for the messages sent to the mc servers from backend SendQueueMessages []*SendQueueMessage sendQueueMessagesMu sync.Mutex @@ -33,20 +28,6 @@ func (mcClient *MinecraftClient) SendBinaryMessage(msg []byte) error { return mcClient.Conn.WriteMessage(websocket.BinaryMessage, msg) } -/* -func (mcClient *MinecraftClient) RemoveCmdID(cmdID int) { - mcClient.cmdIDMu.Lock() - defer mcClient.cmdIDMu.Unlock() - - newArr, err := removeCmdIDFromList(mcClient.CmdIDs, cmdID) - - if err != nil { - logger.Minecraft.Warnln("removeCmdIDFromList:", err) - } else { - mcClient.CmdIDs = newArr - } -} */ - func (mcClient *MinecraftClient) GenerateMinecraftCmdID() int { if mcClient.CurrentCmdID >= 4294967296 || mcClient.CurrentCmdID < 10 { return 10 diff --git a/modules/structs/WebClient.go b/modules/structs/WebClient.go index c7abe06..b7e0b6a 100644 --- a/modules/structs/WebClient.go +++ b/modules/structs/WebClient.go @@ -3,6 +3,7 @@ package structs import ( "errors" "sync" + "time" "github.com/gofiber/websocket/v2" "krakatoa.net/backend/modules/logger" @@ -21,23 +22,159 @@ type A struct { } type WebClient struct { - Uuid string - MobileConn *websocket.Conn - mobileConnMu sync.Mutex - MobileCmdIDs []int // cache for received cmdIDs - mobileCmdIDMu sync.Mutex - MobileCmdIDsByBackend []*A - mobileCmdIDsByBackendMu sync.Mutex - CurrentMobileVoiceCmdIDIndexByBackend int - VoiceConn *websocket.Conn - voiceConnMu sync.Mutex - VoiceCmdIDs []int // cache for received cmdIDs - voiceCmdIDMu sync.Mutex - VoiceCmdIDsByBackend []*A // messages from backend to voice, when response from voice then response to target requester - voiceCmdIDsByBackendMu sync.Mutex - CurrentVoiceCmdIDIndexByBackend int - SendVoiceQueueMessages []*SendQueueMessage - SendMobileQueueMessages []*SendQueueMessage + Uuid string + MobileConn *websocket.Conn + mobileConnMu sync.Mutex + //MobileCmdIDs []int // cache for received cmdIDs + //mobileCmdIDMu sync.Mutex + //MobileCmdIDsByBackend []*A + //mobileCmdIDsByBackendMu sync.Mutex + CurrentMobileSendMessageCmdIDIndexByBackend int + VoiceConn *websocket.Conn + voiceConnMu sync.Mutex + //VoiceCmdIDs []int // cache for received cmdIDs + //voiceCmdIDMu sync.Mutex + //VoiceCmdIDsByBackend []*A // messages from backend to voice, when response from voice then response to target requester + //voiceCmdIDsByBackendMu sync.Mutex + CurrentVoiceSendMessageCmdIDIndexByBackend int + SendVoiceQueueMessages []*SendQueueMessage + sendVoiceQueueMessagesMu sync.Mutex + SendMobileQueueMessages []*SendQueueMessage + sendMobileQueueMessagesMu sync.Mutex + ReceivedVoiceQueueMessages []*ReceivedQueueMessage + receivedVoiceQueueMessagesMu sync.Mutex + ReceivedMobileQueueMessages []*ReceivedQueueMessage + receivedMobileQueueMessagesMu sync.Mutex +} + +func (webClient *WebClient) AddMessageToVoiceSendQueue(originDest int, originCmdID int, messageRaw []byte, cmdID int) { + webClient.SendVoiceQueueMessages = append(webClient.SendVoiceQueueMessages, &SendQueueMessage{MessageRaw: messageRaw, CmdID: cmdID, TrySendCount: 0, OriginDest: originDest, OriginCmdID: originCmdID, Time: time.Now()}) +} + +func (webClient *WebClient) AddMessageToVoiceReceivedQueue(originDest int, originCmdID int, messageRaw []byte) { + webClient.ReceivedVoiceQueueMessages = append(webClient.ReceivedVoiceQueueMessages, &ReceivedQueueMessage{MessageRaw: messageRaw, OriginDest: originDest, OriginCmdID: originCmdID}) +} + +func (webClient *WebClient) AddMessageToMobileSendQueue(originDest int, originCmdID int, messageRaw []byte, cmdID int) { + webClient.SendMobileQueueMessages = append(webClient.SendMobileQueueMessages, &SendQueueMessage{MessageRaw: messageRaw, CmdID: cmdID, TrySendCount: 0, OriginDest: originDest, OriginCmdID: originCmdID, Time: time.Now()}) +} + +func (webClient *WebClient) AddMessageToMobileReceivedQueue(originDest int, originCmdID int, messageRaw []byte) { + webClient.ReceivedMobileQueueMessages = append(webClient.ReceivedMobileQueueMessages, &ReceivedQueueMessage{MessageRaw: messageRaw, OriginDest: originDest, OriginCmdID: originCmdID}) +} + +func (webClient *WebClient) IsCmdIDInSendVoiceMessagesQueue(cmdID int) bool { + return isCmdIDInSendMessagesQueue(webClient.SendVoiceQueueMessages, cmdID) +} + +func (webClient *WebClient) IsCmdIDInSendMobileMessagesQueue(cmdID int) bool { + return isCmdIDInSendMessagesQueue(webClient.SendMobileQueueMessages, cmdID) +} + +func isCmdIDInSendMessagesQueue(sendMessagesQueue []*SendQueueMessage, cmdID int) bool { + for _, queueMsg := range sendMessagesQueue { + if cmdID == queueMsg.CmdID { + return true + } + } + return false +} + +func (webClient *WebClient) IsCmdIDInReceivedVoiceMessagesQueue(cmdID int) bool { + return isCmdIDInReceivedMessagesQueue(webClient.ReceivedVoiceQueueMessages, cmdID) +} + +func (webClient *WebClient) IsCmdIDInReceivedMobileMessagesQueue(cmdID int) bool { + return isCmdIDInReceivedMessagesQueue(webClient.ReceivedMobileQueueMessages, cmdID) +} + +func isCmdIDInReceivedMessagesQueue(receivedMessagesQueue []*ReceivedQueueMessage, cmdID int) bool { + for _, queueMsg := range receivedMessagesQueue { + if cmdID == queueMsg.OriginCmdID { + return true + } + } + return false +} + +func (webClient *WebClient) GetMessageFromSendVoiceQueueByCmdID(cmdID int) (queueMsg SendQueueMessage, err error) { + return getMessageFromSendQueueByCmdID(webClient.SendVoiceQueueMessages, cmdID) +} + +func (webClient *WebClient) GetMessageFromSendMobileQueueByCmdID(cmdID int) (queueMsg SendQueueMessage, err error) { + return getMessageFromSendQueueByCmdID(webClient.SendMobileQueueMessages, cmdID) +} + +func getMessageFromSendQueueByCmdID(sendQueueMessages []*SendQueueMessage, cmdID int) (queueMsg SendQueueMessage, err error) { + for _, queueMsg := range sendQueueMessages { + if cmdID == queueMsg.CmdID { + return *queueMsg, nil + } + } + return SendQueueMessage{}, errors.New("message from send queue by cmdID not found") +} + +func (webClient *WebClient) GetMessageFromReceivedVoiceQueueByCmdID(cmdID int) (queueMsg ReceivedQueueMessage, err error) { + return getMessageFromReceivedQueueByCmdID(webClient.ReceivedVoiceQueueMessages, cmdID) +} + +func (webClient *WebClient) GetMessageFromReceivedMobileQueueByCmdID(cmdID int) (queueMsg ReceivedQueueMessage, err error) { + return getMessageFromReceivedQueueByCmdID(webClient.ReceivedMobileQueueMessages, cmdID) +} + +func getMessageFromReceivedQueueByCmdID(receivedQueueMessages []*ReceivedQueueMessage, cmdID int) (queueMsg ReceivedQueueMessage, err error) { + for _, queueMsg := range receivedQueueMessages { + if cmdID == queueMsg.OriginCmdID { + return *queueMsg, nil + } + } + return ReceivedQueueMessage{}, errors.New("message from received queue by cmdID not found") +} + +func (webClient *WebClient) RemoveMessageFromVoiceSendQueueByCmdID(cmdID int) { + removeMessageFromSendQueueByCmdID(webClient.SendVoiceQueueMessages, &webClient.sendVoiceQueueMessagesMu, cmdID) +} + +func (webClient *WebClient) RemoveMessageFromMobileSendQueueByCmdID(cmdID int) { + removeMessageFromSendQueueByCmdID(webClient.SendMobileQueueMessages, &webClient.sendMobileQueueMessagesMu, cmdID) +} + +func removeMessageFromSendQueueByCmdID(queueMessages []*SendQueueMessage, mutex *sync.Mutex, cmdID int) { + mutex.Lock() + defer mutex.Unlock() + + for index, message := range queueMessages { + if message.CmdID == cmdID { + logger.Web.Debugln("removeMessageFromSendQueueByCmdID before", queueMessages) + newArr := append(queueMessages[:index], queueMessages[index+1:]...) + queueMessages = newArr + logger.Web.Debugln("removeMessageFromSendQueueByCmdID after", queueMessages) + break + } + } +} + +func (webClient *WebClient) RemoveMessageFromVoiceReceivedQueueByCmdID(cmdID int) { + removeMessageFromReceivedQueueByCmdID(webClient.ReceivedVoiceQueueMessages, &webClient.receivedVoiceQueueMessagesMu, cmdID) +} + +func (webClient *WebClient) RemoveMessageFromMobileReceivedQueueByCmdID(cmdID int) { + removeMessageFromReceivedQueueByCmdID(webClient.ReceivedMobileQueueMessages, &webClient.receivedMobileQueueMessagesMu, cmdID) +} + +func removeMessageFromReceivedQueueByCmdID(queueMessages []*ReceivedQueueMessage, mutex *sync.Mutex, cmdID int) { + mutex.Lock() + defer mutex.Unlock() + + for index, message := range queueMessages { + if message.OriginCmdID == cmdID { + logger.Web.Debugln("removeMessageFromReceivedQueueByCmdID before", queueMessages) + newArr := append(queueMessages[:index], queueMessages[index+1:]...) + queueMessages = newArr + logger.Web.Debugln("removeMessageFromReceivedQueueByCmdID after", queueMessages) + break + } + } } func (webClient *WebClient) SendBinaryMessage(conn *websocket.Conn, msg []byte) error { @@ -77,6 +214,7 @@ func (webClient *WebClient) SendBinaryMessage(conn *websocket.Conn, msg []byte) return err } +/* func (webClient *WebClient) RemoveVoiceCmdID(cmdID int) { webClient.voiceCmdIDMu.Lock() defer webClient.voiceCmdIDMu.Unlock() @@ -149,7 +287,7 @@ func getCmdIDIndexFromList(arr []int, cmdID int) int { } return -1 } - +*/ func GenerateWebCmdID(currentIndex int) int { if currentIndex >= 250 || currentIndex < 10 { return 10 diff --git a/serverCommunication/minecraft.go b/serverCommunication/minecraft.go index 3e406c6..b046331 100644 --- a/serverCommunication/minecraft.go +++ b/serverCommunication/minecraft.go @@ -136,31 +136,29 @@ func HandleMinecraftMessage(conn *websocket.Conn, msg []byte) { var webCmdID int if dest == kraProtocol.DestVoice { - webCmdID = structs.GenerateWebCmdID(webClient.CurrentVoiceCmdIDIndexByBackend) + webCmdID = structs.GenerateWebCmdID(webClient.CurrentVoiceSendMessageCmdIDIndexByBackend) - webClient.CurrentVoiceCmdIDIndexByBackend = webCmdID + webClient.CurrentVoiceSendMessageCmdIDIndexByBackend = webCmdID logger.Minecraft.Debugln("webCmdID", webCmdID) - // TODO: Get minecraft server dest from func - a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: 10} + //a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: mcClient.Dest} - webClient.VoiceCmdIDsByBackend = append(webClient.VoiceCmdIDsByBackend, a) + //webClient.VoiceCmdIDsByBackend = append(webClient.VoiceCmdIDsByBackend, a) - logger.Minecraft.Debugln("VoiceCMDIDsByBackend", webClient.VoiceCmdIDsByBackend) + //logger.Minecraft.Debugln("VoiceCMDIDsByBackend", webClient.VoiceCmdIDsByBackend) } else { // dest mobile - webCmdID = structs.GenerateWebCmdID(webClient.CurrentMobileVoiceCmdIDIndexByBackend) + webCmdID = structs.GenerateWebCmdID(webClient.CurrentMobileSendMessageCmdIDIndexByBackend) - webClient.CurrentMobileVoiceCmdIDIndexByBackend = webCmdID + webClient.CurrentMobileSendMessageCmdIDIndexByBackend = webCmdID logger.Minecraft.Debugln("webCmdID", webCmdID) - // TODO: Get minecraft server dest from func - a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: 10} + //a := &structs.A{WebCmdID: webCmdID, CmdIDFromMinecraftServer: cmdID, DestFromMinecraftServer: mcClient.Dest} - webClient.MobileCmdIDsByBackend = append(webClient.MobileCmdIDsByBackend, a) + //webClient.MobileCmdIDsByBackend = append(webClient.MobileCmdIDsByBackend, a) - logger.Minecraft.Debugln("MobileCMDIDsByBackend", webClient.MobileCmdIDsByBackend) + //logger.Minecraft.Debugln("MobileCMDIDsByBackend", webClient.MobileCmdIDsByBackend) } raw = kraProtocol.EncodeWebMessage(kraProtocol.StatusGet, webCmdID, cmdNumber, args) diff --git a/serverCommunication/web.go b/serverCommunication/web.go index c0a7aba..664568d 100644 --- a/serverCommunication/web.go +++ b/serverCommunication/web.go @@ -31,7 +31,7 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt if status == kraProtocol.StatusReply { if isVoice { - logger.WebVoice.Debugln("Reply from Web Voice", webClient.VoiceCmdIDsByBackend) + logger.WebVoice.Debugln("Reply from Web Voice", webClient.SendVoiceQueueMessages) for _, data := range webClient.SendVoiceQueueMessages { if data.CmdID == cmdID { // forward to target dest mcClient := GetMinecraftClientByDest(data.OriginDest) @@ -41,7 +41,7 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt continue } - logger.WebVoice.Debugln("Forwarding reply from web voice to mc client", mcClient.Name, "cmdID", cmdID) + logger.WebVoice.Debugln("Forwarding reply from web voice to mc client", mcClient.Name, "cmdID", data.OriginCmdID) raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusReply, data.OriginCmdID, 0, webClient.Uuid, 0, "") @@ -52,25 +52,24 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt continue } - // remove cmdID from VoiceCMDIDsByBackend list - webClient.RemoveVoiceCmdIDByBackend(cmdID) - + webClient.RemoveMessageFromVoiceReceivedQueueByCmdID(cmdID) mcClient.RemoveMessageFromReceivedQueueByCmdID(data.OriginCmdID) } } - - if isCmdIDInList(webClient.VoiceCmdIDs, cmdID) { - webClient.RemoveVoiceCmdID(cmdID) - } } else { - logger.WebMobile.Debugln("Reply from Web Mobile", webClient.MobileCmdIDsByBackend) - for _, data := range webClient.MobileCmdIDsByBackend { - if data.WebCmdID == cmdID { // forward to target dest - mcClient := GetMinecraftClientByName(getMinecraftServerNameByDest(data.DestFromMinecraftServer)) + logger.WebMobile.Debugln("Reply from Web Mobile", webClient.SendMobileQueueMessages) + for _, data := range webClient.SendMobileQueueMessages { + if data.CmdID == cmdID { // forward to target dest + mcClient := GetMinecraftClientByDest(data.OriginDest) - logger.WebMobile.Debugln("Forwarding reply from web mobile to mc client", mcClient.Name, "cmdID", cmdID) + if mcClient == nil { + logger.WebVoice.Warnln("mcClient is nil -> given dest", data.OriginDest) + continue + } - raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusReply, data.CmdIDFromMinecraftServer, 0, webClient.Uuid, 0, "") + logger.WebMobile.Debugln("Forwarding reply from web mobile to mc client", mcClient.Name, "cmdID", data.OriginCmdID) + + raw = kraProtocol.EncodeJavaMessage(kraProtocol.StatusReply, data.OriginCmdID, 0, webClient.Uuid, 0, "") err = mcClient.SendBinaryMessage(raw) @@ -79,17 +78,11 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt return } - // remove cmdID from VoiceCMDIDsByBackend list - webClient.RemoveMobileCmdIDByBackend(cmdID) - - mcClient.RemoveMessageFromReceivedQueueByCmdID(data.CmdIDFromMinecraftServer) + webClient.RemoveMessageFromMobileReceivedQueueByCmdID(cmdID) + mcClient.RemoveMessageFromReceivedQueueByCmdID(data.OriginCmdID) return } } - - if isCmdIDInList(webClient.MobileCmdIDs, cmdID) { - webClient.RemoveMobileCmdID(cmdID) - } } return } @@ -98,12 +91,10 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt if status == kraProtocol.StatusGet { var cmdIDInList bool - logger.Web.Println("cmdID", isVoice, webClient.VoiceCmdIDs, webClient.MobileCmdIDs) - if isVoice { - cmdIDInList = isCmdIDInList(webClient.VoiceCmdIDs, cmdID) + cmdIDInList = webClient.IsCmdIDInReceivedVoiceMessagesQueue(cmdID) } else { - cmdIDInList = isCmdIDInList(webClient.MobileCmdIDs, cmdID) + cmdIDInList = webClient.IsCmdIDInReceivedMobileMessagesQueue(cmdID) } if cmdIDInList { // cmdID already in queue @@ -117,15 +108,10 @@ func HandleWebMessage(isVoice bool, conn *websocket.Conn, uuid string, msg []byt return } - // add cmdID to list if isVoice { - logger.Web.Debugln("voiceCmdIDs", webClient.VoiceCmdIDs) - webClient.VoiceCmdIDs = append(webClient.VoiceCmdIDs, cmdID) - logger.Web.Debugln("after voiceCmdIDs", webClient.VoiceCmdIDs) + webClient.AddMessageToVoiceReceivedQueue(kraProtocol.DestVoice, cmdID, raw) } else { - logger.Web.Debugln("MobileCmdIDs", webClient.MobileCmdIDs) - webClient.MobileCmdIDs = append(webClient.MobileCmdIDs, cmdID) - logger.Web.Debugln("after MobileCmdIDs", webClient.MobileCmdIDs) + webClient.AddMessageToMobileReceivedQueue(kraProtocol.DestMobile, cmdID, raw) } } diff --git a/servers/web/socketHub.go b/servers/web/socketHub.go index 317e594..ec00499 100644 --- a/servers/web/socketHub.go +++ b/servers/web/socketHub.go @@ -68,13 +68,11 @@ func RunHub() { logger.Web.Println("client unregister", uuid, client) if client.MobileConn == connection { client.MobileConn = nil - client.MobileCmdIDs = []int{} logger.Web.Println("delete mobileConn", client) serverCommunication.SendMessageToMinecraftServer(kraProtocol.DestBackend, 0, kraProtocol.StatusGet, 10, uuid, 64247, "") } else if client.VoiceConn == connection { client.VoiceConn = nil - client.VoiceCmdIDs = []int{} logger.Web.Println("delete voiceConn", client) serverCommunication.SendMessageToMinecraftServer(kraProtocol.DestBackend, 0, kraProtocol.StatusGet, 10, uuid, 22348, "")