Files
K-C-Multiplayer/README.md
devbeni 5e014a74da Fix NullReferenceException crashes when asset bundle is missing
Problem: When the 'serverbrowserpkg' asset bundle file is missing,
the mod crashed at multiple points:
- PrefabManager.PreScriptLoad(): NullReferenceException on line 58
- ServerBrowser.SceneLoaded(): "Object to instantiate is null" at line 312
- Main.TransitionTo(): NullReferenceException at lines 227-228

These crashes made the mod unusable and prevented proper error reporting.

Root cause:
The asset bundle file containing UI prefabs was missing from the mod
directory, causing all prefab references to be null. The code didn't
check for null before using these references.

Solutions:

PrefabManager.cs:
- Add null check after LoadAssetBundle() call (line 31-36)
- Return early with clear error message if bundle is null
- Provide guidance to user about missing file
- Better logging for successful loads

ServerBrowser.SceneLoaded():
- Add prefab null check at method start (line 302-309)
- Return early if prefabs are null
- Prevents crash during UI instantiation
- Clear error messages in log

Main.TransitionTo():
- Add comprehensive null checks before using UI references (line 228)
- If UI not loaded but user tries to access multiplayer menu:
  * Show user-friendly modal dialog
  * Explain the problem clearly
  * Provide reinstall guidance
- Gracefully handle missing UI without crashing

Results:
 No crashes when asset bundle is missing
 Clear, actionable error messages for users
 Graceful degradation - rest of mod still works
 User gets helpful modal instead of silent crash
 Better debugging with detailed logs

Updated README.md with:
- Documentation of all asset bundle fixes
- Code examples showing the changes
- Known Issues section noting missing asset bundle
- Instructions for resolving the issue

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 21:24:55 +01:00

11 KiB

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:

// 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:

// 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:

// 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:

// 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", "...");
}

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

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.