public override void HandleMessage(ClientStructure client, IMessageData messageData) { var message = messageData as VesselBaseMsgData; switch (message?.VesselMessageType) { case VesselMessageType.LIST_REQUEST: HandleVesselListRequest(client); break; case VesselMessageType.VESSELS_REQUEST: HandleVesselsRequest(client, messageData); break; case VesselMessageType.PROTO: HandleVesselProto(client, message); break; case VesselMessageType.REMOVE: HandleVesselRemove(client, message); break; case VesselMessageType.CHANGE: MessageQueuer.RelayMessage <VesselSrvMsg>(client, message); break; case VesselMessageType.UPDATE: VesselRelaySystem.HandleVesselMessage(client, message); break; default: throw new NotImplementedException("Warp Type not implemented"); } }
public void HandleChangeSubspace(ClientStructure client, WarpChangeSubspaceMsgData message) { if (message.PlayerName != client.PlayerName) { return; } var oldSubspace = client.Subspace; var newSubspace = message.Subspace; if (oldSubspace != newSubspace) { var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <WarpChangeSubspaceMsgData>(); msgData.PlayerName = client.PlayerName; msgData.Subspace = message.Subspace; MessageQueuer.RelayMessage <WarpSrvMsg>(client, msgData); if (newSubspace != -1) { client.Subspace = newSubspace; //If client stopped warping and there's nobody in that subspace, remove it if (!ServerContext.Clients.Any(c => c.Value.Subspace == oldSubspace)) { WarpSystem.RemoveSubspace(oldSubspace); VesselRelaySystem.RemoveSubspace(oldSubspace); } } } }
public override void HandleMessage(ClientStructure client, IClientMessageBase message) { var messageData = message.Data as VesselBaseMsgData; switch (messageData?.VesselMessageType) { case VesselMessageType.Sync: HandleVesselsSync(client, messageData); message.Recycle(); break; case VesselMessageType.Proto: HandleVesselProto(client, messageData); break; case VesselMessageType.Dock: HandleVesselDock(client, messageData); break; case VesselMessageType.Remove: HandleVesselRemove(client, messageData); break; case VesselMessageType.Position: VesselRelaySystem.HandleVesselMessage(client, messageData); if (!GeneralSettings.SettingsStore.ShowVesselsInThePast || client.Subspace == WarpContext.LatestSubspace) { VesselDataUpdater.WritePositionDataToFile(messageData); } break; case VesselMessageType.Flightstate: VesselRelaySystem.HandleVesselMessage(client, messageData); break; case VesselMessageType.Update: VesselDataUpdater.WriteUpdateDataToFile(messageData); MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData); break; case VesselMessageType.Resource: VesselDataUpdater.WriteResourceDataToFile(messageData); MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData); break; case VesselMessageType.PartSync: VesselDataUpdater.WriteModuleDataToFile(messageData); MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData); break; case VesselMessageType.Fairing: VesselDataUpdater.WriteFairingDataToFile(messageData); MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData); break; default: throw new NotImplementedException("Vessel message type not implemented"); } }
public override void HandleMessage(ClientStructure client, IMessageData messageData) { var message = messageData as VesselBaseMsgData; switch (message?.VesselMessageType) { case VesselMessageType.VesselsRequest: HandleVesselsRequest(client); break; case VesselMessageType.Proto: HandleVesselProto(client, message); break; case VesselMessageType.Dock: HandleVesselDock(client, message); break; case VesselMessageType.Remove: HandleVesselRemove(client, message); break; case VesselMessageType.Position: VesselRelaySystem.HandleVesselMessage(client, message); if (!GeneralSettings.SettingsStore.ShowVesselsInThePast || client.Subspace == WarpContext.LatestSubspace) { VesselFileUpdater.WritePositionDataToFile(message); } break; case VesselMessageType.Flightstate: VesselRelaySystem.HandleVesselMessage(client, message); break; case VesselMessageType.Update: VesselFileUpdater.WriteUpdateDataToFile(message); MessageQueuer.RelayMessage <VesselSrvMsg>(client, message); break; case VesselMessageType.Resource: VesselFileUpdater.WriteResourceDataToFile(message); MessageQueuer.RelayMessage <VesselSrvMsg>(client, message); break; default: throw new NotImplementedException("Warp Type not implemented"); } }
public static void DisconnectClient(ClientStructure client, string reason = "") { if (!string.IsNullOrEmpty(reason)) { LunaLog.Debug($"{client.PlayerName} sent Connection end message, reason: {reason}"); } VesselUpdateRelaySystem.RemovePlayer(client); //Remove Clients from list if (ServerContext.Clients.ContainsKey(client.Endpoint)) { ServerContext.Clients.TryRemove(client.Endpoint, out client); LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ServerContext.Clients.Count}"); } if (client.ConnectionStatus != ConnectionStatus.Disconnected) { client.ConnectionStatus = ConnectionStatus.Disconnected; LmpPluginHandler.FireOnClientDisconnect(client); if (client.Authenticated) { ChatSystem.RemovePlayer(client.PlayerName); var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionLeaveMsgData>(); msgData.PlayerName = client.PlayerName; MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData); LockSystem.ReleasePlayerLocks(client); if (!ServerContext.Clients.Any(c => c.Value.Subspace == client.Subspace)) { WarpSystem.RemoveSubspace(client.Subspace); VesselRelaySystem.RemoveSubspace(client.Subspace); } } try { client.Connection?.Disconnect(reason); } catch (Exception e) { LunaLog.Debug($"Error closing client Connection: {e.Message}"); } ServerContext.LastPlayerActivity = ServerContext.ServerClock.ElapsedMilliseconds; } }
public override void HandleMessage(ClientStructure client, IMessageData messageData) { var message = messageData as VesselBaseMsgData; switch (message?.VesselMessageType) { case VesselMessageType.ListRequest: HandleVesselListRequest(client); break; case VesselMessageType.VesselsRequest: HandleVesselsRequest(client, messageData); break; case VesselMessageType.Proto: HandleVesselProto(client, message); break; case VesselMessageType.Dock: HandleVesselDock(client, message); break; case VesselMessageType.Remove: HandleVesselRemove(client, message); break; case VesselMessageType.Change: MessageQueuer.RelayMessage <VesselSrvMsg>(client, message); break; case VesselMessageType.Update: VesselRelaySystem.HandleVesselMessage(client, message); break; case VesselMessageType.Position: VesselRelaySystem.HandleVesselMessage(client, message); break; case VesselMessageType.Flightstate: VesselRelaySystem.HandleVesselMessage(client, message); break; default: throw new NotImplementedException("Warp Type not implemented"); } }
private static void HandleVesselProto(ClientStructure client, VesselBaseMsgData message) { var msgData = (VesselProtoMsgData)message; if (VesselContext.RemovedVessels.Contains(msgData.VesselId)) { return; } var path = Path.Combine(ServerContext.UniverseDirectory, "Vessels", $"{msgData.VesselId}.txt"); if (!File.Exists(path)) { LunaLog.Debug($"Saving vessel {msgData.VesselId} from {client.PlayerName}"); } FileHandler.WriteToFile(path, msgData.VesselData); VesselRelaySystem.HandleVesselMessage(client, message); }
public void HandleNewSubspace(ClientStructure client, WarpNewSubspaceMsgData message) { if (message.PlayerCreator != client.PlayerName) { return; } LunaLog.Debug($"{client.PlayerName} created a new subspace. Id {WarpContext.NextSubspaceId}"); //Create Subspace WarpContext.Subspaces.TryAdd(WarpContext.NextSubspaceId, message.ServerTimeDifference); VesselRelaySystem.CreateNewSubspace(WarpContext.NextSubspaceId); //Tell all Clients about the new Subspace var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <WarpNewSubspaceMsgData>(); msgData.ServerTimeDifference = message.ServerTimeDifference; msgData.PlayerCreator = message.PlayerCreator; msgData.SubspaceKey = WarpContext.NextSubspaceId; MessageQueuer.SendToAllClients <WarpSrvMsg>(msgData); WarpContext.NextSubspaceId++; }
public static void Main() { try { ServerContext.StartTime = DateTime.UtcNow.Ticks; //Start the server clock ServerContext.ServerClock.Start(); //Set the last player activity time to server start ServerContext.LastPlayerActivity = ServerContext.ServerClock.ElapsedMilliseconds; //Register the ctrl+c event Console.CancelKeyPress += CatchExit; ServerContext.ServerStarting = true; LunaLog.Debug("Loading settings..."); if (GeneralSettings.SettingsStore.GameDifficulty == GameDifficulty.Custom) { GameplaySettings.Reset(); GameplaySettings.Load(); } //Set day for log change ServerContext.Day = DateTime.Now.Day; //Load plugins LmpPluginHandler.LoadPlugins(); Console.Title = $"LMPServer v{VersionInfo.VersionNumber}"; while (ServerContext.ServerStarting || ServerContext.ServerRestarting) { if (ServerContext.ServerRestarting) { LunaLog.Debug("Reloading settings..."); GeneralSettings.Reset(); GeneralSettings.Load(); if (GeneralSettings.SettingsStore.GameDifficulty == GameDifficulty.Custom) { LunaLog.Debug("Reloading gameplay settings..."); GameplaySettings.Reset(); GameplaySettings.Load(); } } ServerContext.ServerRestarting = false; LunaLog.Normal($"Starting Luna Server v{VersionInfo.FullVersionNumber}"); if (GeneralSettings.SettingsStore.GameDifficulty == GameDifficulty.Custom) { //Generate the config file by accessing the object. LunaLog.Debug("Loading gameplay settings..."); GameplaySettings.Load(); } //Load universe LunaLog.Normal("Loading universe... "); Universe.CheckUniverse(); LunaLog.Normal($"Starting {GeneralSettings.SettingsStore.WarpMode} server on Port {GeneralSettings.SettingsStore.Port}... "); ServerContext.ServerRunning = true; var commandThread = Task.Run(() => new CommandHandler().ThreadMain()); var clientThread = Task.Run(() => new ClientMainThread().ThreadMain()); ServerContext.LidgrenServer.SetupLidgrenServer(); Task.Run(() => ServerContext.LidgrenServer.StartReceiveingMessages()); Task.Run(() => ServerContext.LidgrenServer.RegisterWithMasterServer()); var vesselRelayThread = Task.Run(() => VesselRelaySystem.RelayOldVesselMessages()); var vesselRelayFarThread = Task.Run(() => VesselUpdateRelaySystem.RelayToFarPlayers()); var vesselRelayMediumThread = Task.Run(() => VesselUpdateRelaySystem.RelayToMediumDistancePlayers()); var vesselRelayCloseThread = Task.Run(() => VesselUpdateRelaySystem.RelayToClosePlayers()); while (ServerContext.ServerStarting) { Thread.Sleep(500); } LunaLog.Normal("Ready!"); LmpPluginHandler.FireOnServerStart(); while (ServerContext.ServerRunning) { //Run the log expire function every 10 minutes if (ServerContext.ServerClock.ElapsedMilliseconds - _lastLogExpiredCheck > 600000) { _lastLogExpiredCheck = ServerContext.ServerClock.ElapsedMilliseconds; LogExpire.ExpireLogs(); } // Check if the day has changed, every minute if (ServerContext.ServerClock.ElapsedMilliseconds - _lastDayCheck > 60000) { _lastDayCheck = ServerContext.ServerClock.ElapsedMilliseconds; if (ServerContext.Day != DateTime.Now.Day) { LunaLog.LogFilename = Path.Combine(LunaLog.LogFolder, $"lmpserver {DateTime.Now:yyyy-MM-dd HH-mm-ss}.log"); LunaLog.WriteToLog($"Continued from logfile {DateTime.Now:yyyy-MM-dd HH-mm-ss}.log"); ServerContext.Day = DateTime.Now.Day; } } Thread.Sleep(500); } LmpPluginHandler.FireOnServerStop(); commandThread.Wait(); clientThread.Wait(); vesselRelayThread.Wait(); vesselRelayFarThread.Wait(); vesselRelayMediumThread.Wait(); vesselRelayCloseThread.Wait(); } LunaLog.Normal("Goodbye and thanks for all the fish!"); Environment.Exit(0); } catch (Exception e) { LunaLog.Fatal($"Error in main server thread, Exception: {e}"); throw; } }
public static void Main() { try { Console.Title = $"LMPServer {LmpVersioning.CurrentVersion}"; #if DEBUG Console.Title += " DEBUG"; #endif Console.OutputEncoding = Encoding.Unicode; ServerContext.StartTime = LunaTime.UtcNow.Ticks; //We disable quick edit as otherwise when you select some text for copy/paste then you can't write to the console and server freezes //This just happens on windows.... if (Common.PlatformIsWindows()) { ConsoleUtil.DisableConsoleQuickEdit(); } //We cannot run more than 6 instances ofd servers + clients as otherwise the sync time will fail (30 seconds / 5 seconds = 6) but we use 3 for safety if (GetRunningInstances() > 3) { throw new HandledException("Cannot run more than 3 servers at a time!"); } //Start the server clock ServerContext.ServerClock.Start(); //Set the last player activity time to server start ServerContext.LastPlayerActivity = ServerContext.ServerClock.ElapsedMilliseconds; //Register the ctrl+c event Console.CancelKeyPress += CatchExit; ServerContext.ServerStarting = true; //Set day for log change ServerContext.Day = LunaTime.Now.Day; LunaLog.Normal($"Starting Luna Server version: {LmpVersioning.CurrentVersion}"); Universe.CheckUniverse(); LoadSettingsAndGroups(); LmpPluginHandler.LoadPlugins(); WarpSystem.Reset(); ChatSystem.Reset(); LunaLog.Normal($"Starting {GeneralSettings.SettingsStore.WarpMode} server on Port {GeneralSettings.SettingsStore.Port}... "); ServerContext.ServerRunning = true; ServerContext.LidgrenServer.SetupLidgrenServer(); Task.Run(() => new CommandHandler().ThreadMain()); Task.Run(() => new ClientMainThread().ThreadMain()); Task.Run(() => ServerContext.LidgrenServer.StartReceiveingMessages()); Task.Run(() => ServerContext.LidgrenServer.RefreshMasterServersList()); Task.Run(() => ServerContext.LidgrenServer.RegisterWithMasterServer()); Task.Run(() => LogThread.RunLogThread()); Task.Run(() => VesselRelaySystem.RelayOldVesselMessages()); Task.Run(() => VesselUpdateRelaySystem.RelayToFarPlayers()); Task.Run(() => VesselUpdateRelaySystem.RelayToMediumDistancePlayers()); Task.Run(() => VesselUpdateRelaySystem.RelayToClosePlayers()); Task.Run(() => VersionChecker.CheckForNewVersions()); while (ServerContext.ServerStarting) { Thread.Sleep(500); } LunaLog.Normal("All systems up and running. Поехали!"); LmpPluginHandler.FireOnServerStart(); QuitEvent.WaitOne(); WarpSystem.SaveSubspacesToFile(); LmpPluginHandler.FireOnServerStop(); LunaLog.Normal("Goodbye and thanks for all the fish!"); } catch (Exception e) { if (e is HandledException) { LunaLog.Fatal(e.Message); } else { LunaLog.Fatal($"Error in main server thread, Exception: {e}"); } Console.ReadLine(); //Avoid closing automatically } }