devbeni e1d81baf60 Fix ModalManager crash when asset bundle is missing
Problem: When Main.TransitionTo() tried to show an error modal about
missing multiplayer UI, it triggered ModalManager's static constructor
which tried to instantiate modalUIPrefab. Since the asset bundle was
missing, modalUIPrefab was null, causing:

System.TypeInitializationException: The type initializer for
'KCM.ModalManager' threw an exception.
---> System.ArgumentException: The Object you want to instantiate is null.
  at KCM.ModalManager..cctor () [0x00017]

This created a catch-22: couldn't show error modal about missing UI
because the modal itself needed the missing UI.

Root cause:
ModalManager static constructor didn't check if modalUIPrefab was null
before trying to instantiate it. ShowModal() and HideModal() also
assumed modalInst was always initialized.

Solutions:

ModalManager static constructor (lines 25-30):
- Add null check for PrefabManager.modalUIPrefab
- If null, log warning and return early
- Set instantiated = true to prevent re-initialization
- Log success message when initialization works

ShowModal() method (lines 55-59):
- Check if modalInst is null before using it
- If null (couldn't initialize), just log the modal content
- Format: "MODAL (not shown - UI missing): Title - Message"
- Prevents crash and preserves the error message in logs

HideModal() method (lines 81-84):
- Add null check before calling SetActive
- Safe to call even if modal not initialized

Results:
 No crash when modal UI is missing
 Error messages still logged even if not shown visually
 Graceful degradation throughout the mod
 ModalManager can be safely called from anywhere
 Clear logging shows what modals would have appeared

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 21:28:18 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
hm
2025-12-14 15:25:29 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00
2025-12-14 21:08:19 +01:00

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.

Description
No description provided
Readme 7.5 MiB
Languages
C# 100%