12 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
-
Statikus client/server objektumok: A
KCClientésKCServerosztályok statikus konstruktorokban létrehozottClientésServerobjektumokat használtak, amelyek soha nem újrainizializálódtak disconnect után. -
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.
-
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
Clientobjektumot - 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_Disconnectedevent 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éreOnClientDisconnected()- 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
kCPlayersmind aclientSteamIdsdictionary-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:
- ✅ 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
- ✅ Timeout problémák csökkentése: A 15 másodperces timeout jelentősen csökkenti a "poor connection" üzeneteket
- ✅ Tiszta állapot: Minden disconnect után teljesen kitisztított állapotból indul az új kapcsolódás
- ✅ Event handler stabilitás: Az event handlerek most már nem vesznek el újrainicializálás során
- ✅ 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
- Másold a mod fájljait a Kingdoms and Castles mod mappájába
- Aktiváld a modot a játék mod menüjében
- Indítsd újra a játékot
Használat
Server létrehozása
- Főmenü -> Multiplayer
- Create Server
- Állítsd be a szerver beállításokat
- Várd meg, hogy a játékosok csatlakozzanak
Csatlakozás serverhez
- Főmenü -> Multiplayer
- Válaszd ki a servert a listából
- 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", "...");
}
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:
// 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
-
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ényekLeaveLobby 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.