using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using Riptide; using Harmony; using System.Reflection; using KCM.Packets.Handlers; using KCM.Packets.Lobby; using KCM.ServerLobby; using KCM.Packets; using KCM.Packets.Network; using Riptide.Demos.Steam.PlayerHosted; namespace KCM { public class KCServer : MonoBehaviour { public static Server server; public static bool started = false; static KCServer() { // Initialize server in static constructor InitializeServer(); } 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; } private static void OnClientConnected(object obj, ServerConnectedEventArgs ev) { Main.helper.Log("Client connected"); if (server.ClientCount > LobbyHandler.ServerSettings.MaxPlayers) { ShowModal showModal = new ShowModal() { title = "Failed to connect", message = "Server is full." }; showModal.Send(ev.Client.Id); server.DisconnectClient(ev.Client.Id); return; } ev.Client.CanQualityDisconnect = false; Main.helper.Log("Client ID is: " + ev.Client.Id); new ServerHandshake() { clientId = ev.Client.Id, loadingSave = LobbyManager.loadingSave }.Send(ev.Client.Id); } private static void OnClientDisconnected(object obj, ServerDisconnectedEventArgs ev) { try { if (Main.clientSteamIds.ContainsKey(ev.Client.Id)) { new ChatSystemMessage() { Message = $"{Main.GetPlayerByClientID(ev.Client.Id).name} has left the server.", }.SendToAll(); Main.kCPlayers.Remove(Main.GetPlayerByClientID(ev.Client.Id).steamId); var playerEntry = LobbyHandler.playerEntries .Select(x => x.GetComponent()) .Where(x => x.Client == ev.Client.Id) .FirstOrDefault(); if (playerEntry != null) Destroy(playerEntry.gameObject); } Main.helper.Log($"Client disconnected. {ev.Reason}"); } catch (Exception ex) { Main.helper.Log($"Error handling client disconnect: {ex.Message}"); } } public static void StartServer() { // Reinitialize server to ensure clean state InitializeServer(); server.Start(0, 25, useMessageHandlers: false); Main.helper.Log($"Listening on port 7777. Max {LobbyHandler.ServerSettings.MaxPlayers} clients."); } public static bool IsRunning { get { return server.IsRunning; } } private void Update() { server.Update(); } private void OnApplicationQuit() { server.Stop(); } private void Preload(KCModHelper helper) { helper.Log("server?"); helper.Log("Preload run in server"); } private void SceneLoaded(KCModHelper helper) { } } }