# Kingdoms and Castles Multiplayer Mod Ez a mod multiplayer funkcionalitást ad a Kingdoms and Castles játékhoz. ## Legutóbbi javítások (2025-12-14) ### Kapcsolati problémák javítása #### Probléma A játékosok gyakran tapasztaltak "poor connection", "lost connection", vagy "server disconnected" üzeneteket, és ezután nem tudtak újra csatlakozni anélkül, hogy újraindították volna a játékot. #### Gyökérok 1. **Statikus client/server objektumok**: A `KCClient` és `KCServer` osztályok statikus konstruktorokban létrehozott `Client` és `Server` objektumokat használtak, amelyek soha nem újrainizializálódtak disconnect után. 2. **Event handler elvesztés**: Az event handlerek (Connected, Disconnected, MessageReceived, stb.) a statikus konstruktorban lettek feliratkozva, de amikor új server/client objektumok lettek létrehozva, ezek a handlerek elvesztek. 3. **Nem tisztított állapot**: A disconnect után a játék állapota nem lett teljesen kitisztítva, így a következő kapcsolódási kísérlet hibás állapotból indult. #### Megoldások ##### 1. KCClient.cs - Javított újracsatlakozási képesség **Változtatások:** - Új `InitializeClient()` metódus amely: - Teljesen kitisztítja a régi client objektumot - Lecsatlakoztatja a régi kapcsolatot ha létezik - Leiratkozik az összes event handlerről - Létrehoz egy új, tiszta `Client` objektumot - Növelt timeout (15 másodperc) a gyakori timeout-ok elkerülésére - Újra feliratkozik az event handlerekre - Módosított `Connect()` metódus: - Minden kapcsolódás előtt újrainicializálja a client-et - Növelt connection attempts (10) a megbízhatóbb kapcsolódásért - Javított `Client_Disconnected` event handler: - Tisztítja a client state-et (clientSteamIds) - Megkülönbözteti az önkéntes és nem várt disconnect-eket - Csak nem várt disconnect esetén mutat error modalt **Érintett kód részletek:** ```csharp // KCClient.cs:34-62 private static void InitializeClient() { // Clean up old client if exists if (client != null) { if (client.IsConnected || client.IsConnecting) { client.Disconnect(); } // Unsubscribe from old events client.Connected -= Client_Connected; client.ConnectionFailed -= Client_ConnectionFailed; client.Disconnected -= Client_Disconnected; client.MessageReceived -= PacketHandler.HandlePacket; } // Create new client instance client = new Client(Main.steamClient); // Set a higher timeout to prevent frequent disconnections client.TimeoutTime = 15000; // 15 seconds instead of default 5 seconds // Subscribe to events client.Connected += Client_Connected; client.ConnectionFailed += Client_ConnectionFailed; client.Disconnected += Client_Disconnected; client.MessageReceived += PacketHandler.HandlePacket; } ``` ##### 2. KCServer.cs - Javított server event handling **Változtatások:** - Új `InitializeServer()` metódus hasonló logikával mint a client: - Leállítja a régi server-t ha fut - Leiratkozik az event handlerökről - Létrehoz új server objektumot - Növelt timeout (15 másodperc) - Újra feliratkozik az event handlerekre - Event handlerek kiszervezése statikus metódusokba: - `OnClientConnected()` - külön metódus a client csatlakozás kezelésére - `OnClientDisconnected()` - külön metódus a client lecsatlakozás kezelésére - Try-catch blokkok a biztonságos error handling-ért - `StartServer()` mindig újrainicializálja a server-t: - Garantálja a tiszta állapotot minden indításkor **Érintett kód részletek:** ```csharp // KCServer.cs:30-56 private static void InitializeServer() { // Clean up old server if exists if (server != null) { if (server.IsRunning) { server.Stop(); } // Unsubscribe from old events server.MessageReceived -= PacketHandler.HandlePacketServer; server.ClientConnected -= OnClientConnected; server.ClientDisconnected -= OnClientDisconnected; } // Create new server instance server = new Server(Main.steamServer); // Set a higher timeout to prevent frequent disconnections server.TimeoutTime = 15000; // 15 seconds instead of default 5 seconds // Subscribe to events server.MessageReceived += PacketHandler.HandlePacketServer; server.ClientConnected += OnClientConnected; server.ClientDisconnected += OnClientDisconnected; } ``` ##### 3. LobbyManager.cs - Javított cleanup **Változtatások:** - `LeaveLobby()` metódus teljes átírása: - Részletes logging minden lépésnél - Null-safe ellenőrzések - Try-catch blokk a biztonságos cleanup-ért - Kitisztítja mind a `kCPlayers` mind a `clientSteamIds` dictionary-ket - Visszaállítja az összes flag-et (`loadingSave`, `registerServer`) - Garantálja hogy mindig visszatér a ServerBrowser-hez még hiba esetén is **Érintett kód részletek:** ```csharp // LobbyManager.cs:151-205 public void LeaveLobby() { Main.helper.Log("LeaveLobby called - cleaning up connection state"); try { // Disconnect client first if (KCClient.client != null && (KCClient.client.IsConnected || KCClient.client.IsConnecting)) { Main.helper.Log("Disconnecting client..."); KCClient.client.Disconnect(); } // Stop server if running if (KCServer.IsRunning) { Main.helper.Log("Stopping server..."); KCServer.server.Stop(); } // Leave Steam lobby if (lobbyId.IsValid()) { Main.helper.Log("Leaving Steam lobby..."); SteamMatchmaking.LeaveLobby(lobbyId); } // Clear player data Main.helper.Log("Clearing player data..."); Main.kCPlayers.Clear(); Main.clientSteamIds.Clear(); // Clear UI LobbyHandler.ClearPlayerList(); LobbyHandler.ClearChatEntries(); // Reset flags ServerBrowser.registerServer = false; loadingSave = false; // ... continues with transition } catch (Exception ex) { // Error handling with fallback } } ``` ### Eredmények Ezekkel a változtatásokkal a következő problémák lettek megoldva: 1. ✅ **Reconnect képesség**: A játékosok most már tudnak újra csatlakozni disconnect után anélkül, hogy újraindítanák a játékot 2. ✅ **Timeout problémák csökkentése**: A 15 másodperces timeout jelentősen csökkenti a "poor connection" üzeneteket 3. ✅ **Tiszta állapot**: Minden disconnect után teljesen kitisztított állapotból indul az új kapcsolódás 4. ✅ **Event handler stabilitás**: Az event handlerek most már nem vesznek el újrainicializálás során 5. ✅ **Jobb error handling**: Try-catch blokkok és részletes logging a problémák könnyebb diagnosztizálásához ### Korábbi javítások #### Map szinkronizáció javítás (c4eb7e9) - Javítva: A client-ek rossz map paraméterekkel generáltak világot - Megoldás: WorldSeed packet most tartalmazza az összes szükséges map paramétert (size, type, rivers) #### StartGame NullReferenceException javítás (fc467f4) - Javítva: NullReferenceException a multiplayer játék indításakor - Megoldás: Eltávolítva a MainMenuMode.StartGame() reflection hívás, közvetlen átmenet playing mode-ba ## Telepítés 1. Másold a mod fájljait a Kingdoms and Castles mod mappájába 2. Aktiváld a modot a játék mod menüjében 3. Indítsd újra a játékot ## Használat ### Server létrehozása 1. Főmenü -> Multiplayer 2. Create Server 3. Állítsd be a szerver beállításokat 4. Várd meg, hogy a játékosok csatlakozzanak ### Csatlakozás serverhez 1. Főmenü -> Multiplayer 2. Válaszd ki a servert a listából 3. Kattints a "Join" gombra ### Asset Bundle hibák javítása (2025-12-14) #### Probléma Ha az "serverbrowserpkg" asset bundle fájl hiányzik a mod könyvtárából, a mod NullReferenceException-öket dobott több helyen: - PrefabManager.PreScriptLoad(): Crash az asset bundle betöltésekor - ServerBrowser.SceneLoaded(): Crash amikor null prefab-okat próbált instantiate-lni - Main.TransitionTo(): Crash amikor null UI referenciákat próbált elérni #### Megoldások **PrefabManager.cs:31-36** - Null check az asset bundle betöltés után - Ha az asset bundle null, részletes hibaüzenet és early return - Egyértelmű útmutatás a felhasználónak **ServerBrowser.cs:302-309** - Prefab null check a SceneLoaded elején - Ha a prefabok null-ok, részletes hibaüzenet és early return - Megakadályozza a crash-t és informálja a felhasználót **Main.cs:228-244** - Null check minden UI referencia használata előtt - Ha a felhasználó a multiplayer menüt próbálja megnyitni de az UI nincs betöltve: - Részletes modal üzenet jelenik meg - A játék nem crash-el - Útmutatás a probléma megoldásához **Érintett kód részletek:** ```csharp // PrefabManager.cs if (assetBundle == null) { Main.helper.Log("ERROR: Asset bundle 'serverbrowserpkg' not found! UI features will not work."); Main.helper.Log("Please ensure the asset bundle file is in the mod directory."); return; } // ServerBrowser.cs if (PrefabManager.serverBrowserPrefab == null || PrefabManager.serverLobbyPrefab == null) { Main.helper.Log("ERROR: UI prefabs not loaded. Asset bundle is missing."); return; } // Main.cs if (ServerBrowser.serverBrowserRef != null && ServerBrowser.serverLobbyRef != null) { // Safe to use UI references } else if ((int)state > 21) { // Show error modal instead of crashing ModalManager.ShowModal("Multiplayer Not Available", "..."); } ``` **ModalManager.cs:25-30, 55-59, 81-84** - Null check a statikus konstruktorban a modalUIPrefab betöltés előtt - Ha null, csak log-ol és visszatér gracefully - ShowModal() ellenőrzi hogy modalInst létezik-e - Ha nem, log-olja a modal tartalmát: "MODAL (not shown - UI missing): Title - Message" - HideModal() null-safe lett - Megakadályozza a TypeInitializationException-t **Érintett kód részletek:** ```csharp // ModalManager.cs statikus konstruktor if (PrefabManager.modalUIPrefab == null) { Main.helper.Log("WARNING: ModalManager cannot initialize - modalUIPrefab is null"); instantiated = true; return; } // ShowModal metódus if (modalInst == null) { Main.helper.Log($"MODAL (not shown - UI missing): {title} - {message}"); return; } ``` **Eredmények:** - ✅ Nincs crash ha az asset bundle hiányzik - ✅ Világos hibaüzenetek a felhasználónak - ✅ Graceful degradation - a mod többi része működik - ✅ Útmutatás a probléma megoldásához - ✅ ModalManager biztonságosan hívható bárhonnan - ✅ Modal üzenetek log-olva még ha nem is jelennek meg **MEGJEGYZÉS:** Az asset bundle fájl jelenleg hiányzik a mod könyvtárából. A multiplayer UI funkciók működéséhez szükséges a "serverbrowserpkg" fájl hozzáadása. ## Ismert problémák 1. **Hiányzó Asset Bundle**: A "serverbrowserpkg" asset bundle fájl jelenleg hiányzik a mod könyvtárából. Ez azt jelenti, hogy: - A multiplayer UI (Server Browser, Server Lobby) nem jelenik meg - A Multiplayer gomb a főmenüben hibaüzenetet fog mutatni - A mod többi része (connection handling, stb.) továbbra is működik **Megoldás:** Helyezd el a "serverbrowserpkg" fájlt a mod gyökérkönyvtárába és indítsd újra a játékot. Ha egyéb hibát találsz, kérlek jelentsd a fejlesztőknek. ## Fejlesztői megjegyzések ### Debugging A mod részletes loggolást tartalmaz, amely segít a problémák diagnosztizálásában. A logok a következő helyeken jelennek meg: - `[WORLD SYNC]` prefix: World generation szinkronizációs események - `LeaveLobby called` - `Lobby cleanup completed`: Disconnect/cleanup folyamat ### Hozzájárulás Ha szeretnél hozzájárulni a mod fejlesztéséhez, pull request-eket szívesen fogadunk! ## Licensz Ez a mod a Riptide Networking library-t használja, amely MIT licensz alatt áll.