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>
310 lines
11 KiB
Markdown
310 lines
11 KiB
Markdown
# 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", "...");
|
|
}
|
|
```
|
|
|
|
**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.
|