package handlers import ( "bytes" "customServer/internal/protocol" "customServer/internal/state" "fmt" "net" ) func HandleEnterLobbyRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling EnterLobbyRequest") // Pre-push the game list so it's there when the client transitions gameList := getMockGameListBytes() conn.Write(protocol.WrapPacket(609, gameList, 999)) return []byte{}, 601 } func HandleLobbyPlayerListRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling LobbyPlayerListRequest") mockSmallPlayer := state.GetMockSmallPlayerBytes() // PlayerList Message playerList := make([]byte, 0) playerList = append(playerList, 0x0a) playerList = append(playerList, protocol.EncodeVarint(uint64(len(mockSmallPlayer)))...) playerList = append(playerList, mockSmallPlayer...) // Deflate compressed := protocol.ZlibCompress(playerList) responsePayload := make([]byte, 0) responsePayload = append(responsePayload, 0x0a) // Field 1: playerList (ByteString) responsePayload = append(responsePayload, protocol.EncodeVarint(uint64(len(compressed)))...) responsePayload = append(responsePayload, compressed...) return responsePayload, 604 } func HandleLobbyGameListRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling LobbyGameListRequest") return getMockGameListBytes(), 609 } func HandleObservableGameListRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling ObservableGameListRequest") return getMockGameListBytes(), 622 } func HandleLobbyCreateGameRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling LobbyCreateGameRequest") // 1. Scan the request data for Field 607 (LobbyCreateGameRequest) // Actually, the dispatcher already gives us the requestData which IS the payload of the request number? // In the original main.go, the Switch handled requestNumber. // For 607, it manually scanned payloadBytes again. var configBytes []byte msgReader := bytes.NewReader(requestData) for { tag, err := protocol.ReadVarint(msgReader) if err != nil { break } fieldNum := tag >> 3 wireType := tag & 0x7 if fieldNum == 607 && wireType == 2 { length, _ := protocol.ReadVarint(msgReader) createGameReqBytes := make([]byte, length) msgReader.Read(createGameReqBytes) // Extract Configuration (Field 1) from LobbyCreateGameRequest reqReader := bytes.NewReader(createGameReqBytes) for { rtag, rerr := protocol.ReadVarint(reqReader) if rerr != nil { break } rfieldNum := rtag >> 3 rwireType := rtag & 0x7 if rfieldNum == 1 && rwireType == 2 { rlength, _ := protocol.ReadVarint(reqReader) configBytes = make([]byte, rlength) reqReader.Read(configBytes) break } else { protocol.SkipField(reqReader, rwireType) } } break } else { protocol.SkipField(msgReader, wireType) } } // Update State newGameID := int64(4016461897007108096) state.GlobalManager.CreateGame(newGameID) // Construct Response (LobbyGameCreatedRequest 608) gameDetails := getMockGameDetailsBytes(newGameID, configBytes, [][]byte{state.GetMockPlayerBytes()}) // Push updated game list gameList := getMockGameListBytes() conn.Write(protocol.WrapPacket(609, gameList, 1000)) responsePayload := make([]byte, 0) responsePayload = append(responsePayload, 0x0a) responsePayload = append(responsePayload, protocol.EncodeVarint(uint64(len(gameDetails)))...) responsePayload = append(responsePayload, gameDetails...) return responsePayload, 608 } func HandleLobbyJoinGameRequest(conn net.Conn, requestData []byte) ([]byte, int) { fmt.Println("[TCP] Handling LobbyJoinGameRequest") state.GlobalManager.CreateGame(4016461897007108096) // Construct LobbyNewPlayerRequest (611) gameDetails := getMockGameDetailsBytes(4016461897007108096, nil, [][]byte{state.GetMockPlayerBytes()}) // LobbyNewPlayerRequest Message newPlayerReq := make([]byte, 0) // Field 1: GameDetails newPlayerReq = append(newPlayerReq, 0x0a) newPlayerReq = append(newPlayerReq, protocol.EncodeVarint(uint64(len(gameDetails)))...) newPlayerReq = append(newPlayerReq, gameDetails...) // Field 2: JoiningPlayer newPlayerReq = append(newPlayerReq, 0x10) newPlayerReq = append(newPlayerReq, protocol.EncodeVarint(uint64(state.MockUserID))...) return newPlayerReq, 611 } // Helpers func getMockGameDetailsBytes(gameID int64, configBytes []byte, players [][]byte) []byte { gameDetails := make([]byte, 0) gameDetails = append(gameDetails, 0x08) gameDetails = append(gameDetails, protocol.EncodeVarint(uint64(gameID))...) for _, p := range players { gameDetails = append(gameDetails, 0x12) gameDetails = append(gameDetails, protocol.EncodeVarint(uint64(len(p)))...) gameDetails = append(gameDetails, p...) } if len(configBytes) > 0 { // Field 3: Configuration (From request) gameDetails = append(gameDetails, 0x1a) gameDetails = append(gameDetails, protocol.EncodeVarint(uint64(len(configBytes)))...) gameDetails = append(gameDetails, configBytes...) } else { // Field 3: Configuration (Fallback) fallbackConfig := getFallbackConfigBytes() gameDetails = append(gameDetails, 0x1a) gameDetails = append(gameDetails, protocol.EncodeVarint(uint64(len(fallbackConfig)))...) gameDetails = append(gameDetails, fallbackConfig...) } return gameDetails } func getMockGameListBytes() []byte { // For the lobby list, show a game with NO players so anyone can join gameData := getMockGameDetailsBytes(4016461897007108096, nil, [][]byte{}) // GameList Message gameList := make([]byte, 0) gameList = append(gameList, 0x0a) gameList = append(gameList, protocol.EncodeVarint(uint64(len(gameData)))...) gameList = append(gameList, gameData...) // Deflate compressed := protocol.ZlibCompress(gameList) responsePayload := make([]byte, 0) responsePayload = append(responsePayload, 0x0a) // Field 1: gameList (ByteString) responsePayload = append(responsePayload, protocol.EncodeVarint(uint64(len(compressed)))...) responsePayload = append(responsePayload, compressed...) return responsePayload } func getFallbackConfigBytes() []byte { fallbackConfig := make([]byte, 0) name := "Fallback Game" fallbackConfig = append(fallbackConfig, 0x0a) fallbackConfig = append(fallbackConfig, protocol.EncodeVarint(uint64(len(name)))...) fallbackConfig = append(fallbackConfig, name...) fallbackConfig = append(fallbackConfig, 0x10, 0x00, 0x18, 0x01, 0x20, 0x00) fallbackConfig = append(fallbackConfig, 0x28) fallbackConfig = append(fallbackConfig, protocol.EncodeVarint(1)...) fallbackConfig = append(fallbackConfig, 0x30) fallbackConfig = append(fallbackConfig, protocol.EncodeVarint(6)...) fallbackConfig = append(fallbackConfig, 0x48, 0x00, 0x50, 0x2d) // Field 11: Data (IronGameConfiguration) ironData := state.GetMockIronGameConfigurationBytes() fallbackConfig = append(fallbackConfig, 0x5a) // (11 << 3) | 2 = 88 | 2 = 90 = 0x5a fallbackConfig = append(fallbackConfig, protocol.EncodeVarint(uint64(len(ironData)))...) fallbackConfig = append(fallbackConfig, ironData...) return fallbackConfig }