private async void SendMessagesThread(CancellationToken token)
        {
            while (ConnectionStatus == ConnectionStatus.Connected)
            {
                while (SendMessageQueue.TryDequeue(out var message) && message != null)
                {
                    try
                    {
                        LidgrenServer.SendMessageToClient(this, message);
                    }
                    catch (Exception e)
                    {
                        ClientException.HandleDisconnectException("Send network message error: ", this, e);
                        return;
                    }

                    LmpPluginHandler.FireOnMessageSent(this, message);
                }
                try
                {
                    await Task.Delay(IntervalSettings.SettingsStore.SendReceiveThreadTickMs, token);
                }
                catch (TaskCanceledException)
                {
                    break;
                }
            }
        }
示例#2
0
        public void HandleHandshakeRequest(ClientStructure client, HandshakeRequestMsgData data)
        {
            var valid = CheckServerFull(client);

            valid &= valid && CheckUsernameLength(client, data.PlayerName);
            valid &= valid && CheckUsernameCharacters(client, data.PlayerName);
            valid &= valid && CheckPlayerIsAlreadyConnected(client, data.PlayerName);
            valid &= valid && CheckUsernameIsReserved(client, data.PlayerName);
            valid &= valid && CheckPlayerIsBanned(client, data.UniqueIdentifier);

            if (!valid)
            {
                LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) failed to handshake: {Reason}. Disconnecting");
                client.DisconnectClient = true;
                ClientConnectionHandler.DisconnectClient(client, Reason);
            }
            else
            {
                client.PlayerName       = data.PlayerName;
                client.UniqueIdentifier = data.UniqueIdentifier;
                client.Authenticated    = true;

                LmpPluginHandler.FireOnClientAuthenticated(client);

                LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) handshake successfully, Version: {data.MajorVersion}.{data.MinorVersion}.{data.BuildVersion}");

                HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.HandshookSuccessfully, "success");

                var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionJoinMsgData>();
                msgData.PlayerName = client.PlayerName;
                MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData);

                LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ClientRetriever.GetClients().Length}");
            }
        }
        public static void ConnectClient(NetConnection newClientConnection)
        {
            var newClientObject = new ClientStructure(newClientConnection);

            LmpPluginHandler.FireOnClientConnect(newClientObject);

            ServerContext.Clients.TryAdd(newClientObject.Endpoint, newClientObject);
            LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ServerContext.Clients.Count}");
        }
示例#4
0
        public void ReceiveCallback(ClientStructure client, NetIncomingMessage msg)
        {
            if (client == null || msg.LengthBytes <= 1)
            {
                return;
            }

            if (client.ConnectionStatus == ConnectionStatus.Connected)
            {
                client.LastReceiveTime = ServerContext.ServerClock.ElapsedMilliseconds;
            }

            var message = DeserializeMessage(msg);

            if (message == null)
            {
                return;
            }

            LmpPluginHandler.FireOnMessageReceived(client, message);
            //A plugin has handled this message and requested suppression of the default behavior
            if (message.Handled)
            {
                return;
            }

            if (message.VersionMismatch)
            {
                MessageQueuer.SendConnectionEnd(client, $"Version mismatch: Your version ({message.Data.MajorVersion}.{message.Data.MinorVersion}.{message.Data.BuildVersion}) " +
                                                $"does not match the server version: {LmpVersioning.CurrentVersion}.");
                return;
            }

            //Clients can only send HANDSHAKE until they are Authenticated.
            if (!client.Authenticated && message.MessageType != ClientMessageType.Handshake)
            {
                MessageQueuer.SendConnectionEnd(client, $"You must authenticate before sending a {message.MessageType} message");
                return;
            }

            //Handle the message
            try
            {
                HandlerDictionary[message.MessageType].HandleMessage(client, message);
            }
            catch (Exception e)
            {
                LunaLog.Error($"Error handling a message from {client.PlayerName}! {e}");
            }
        }
        public void ThreadMain()
        {
            try
            {
                WarpSystem.Reset();
                ChatSystem.Reset();

                while (ServerContext.ServerRunning)
                {
                    //Check timers
                    NukeCommand.CheckTimer();
                    DekesslerCommand.CheckTimer();

                    LmpPluginHandler.FireOnUpdate(); //Run plugin update

                    Thread.Sleep(GeneralSettings.SettingsStore.MainTimeTick);
                }
            }
            catch (Exception e)
            {
                LunaLog.Error($"Fatal error thrown, exception: {e}");
                new ShutDownCommand().Execute("Crashed!");
            }

            try
            {
                var disconnectTime  = DateTime.UtcNow.Ticks;
                var sendingMessages = true;
                while (sendingMessages)
                {
                    if (DateTime.UtcNow.Ticks - disconnectTime > TimeSpan.FromSeconds(5).Ticks)
                    {
                        LunaLog.Debug($"Shutting down with {ServerContext.PlayerCount} Players, " +
                                      $"{ServerContext.Clients.Count} connected Clients");
                        break;
                    }
                    sendingMessages = ClientRetriever.GetAuthenticatedClients().Any(c => c.SendMessageQueue.Count > 0);

                    Thread.Sleep(GeneralSettings.SettingsStore.MainTimeTick);
                }
                ServerContext.LidgrenServer.ShutdownLidgrenServer();
            }
            catch (Exception e)
            {
                LunaLog.Fatal($"Fatal error thrown during shutdown, exception: {e}");
                throw;
            }
        }
示例#6
0
        public static void DisconnectClient(ClientStructure client, string reason = "")
        {
            if (!string.IsNullOrEmpty(reason))
            {
                LunaLog.Debug($"{client.PlayerName} sent Connection end message, reason: {reason}");
            }

            if (client.ConnectionStatus != ConnectionStatus.Disconnected)
            {
                client.ConnectionStatus = ConnectionStatus.Disconnected;
                LmpPluginHandler.FireOnClientDisconnect(client);
                if (client.Authenticated)
                {
                    var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionLeaveMsgData>();
                    msgData.PlayerName = client.PlayerName;

                    MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData);
                    LockSystem.ReleasePlayerLocks(client);
                    WarpSystem.RemoveSubspace(client.Subspace);
                }

                try
                {
                    client.Connection?.Disconnect(reason);
                }
                catch (Exception e)
                {
                    LunaLog.Error($"Error closing client Connection: {e.Message}");
                }
            }

            //Remove Clients from list
            if (ServerContext.Clients.TryRemove(client.Endpoint, out ClientStructure removed))
            {
                LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ServerContext.Clients.Count}");
            }
            else
            {
                LunaLog.Error($"Error removing client: {client.PlayerName} from list");
            }

            //As this is the last client that is connected to the server, run a safety backup once he disconnects
            if (ServerContext.Clients.Count == 0)
            {
                BackupSystem.RunBackup();
                GcSystem.PerformGCNow();
            }
        }
示例#7
0
        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;
            }
        }
示例#8
0
        public void ReceiveCallback(ClientStructure client, NetIncomingMessage msg)
        {
            if (client == null || msg.LengthBytes <= 1)
            {
                return;
            }

            if (client.ConnectionStatus == ConnectionStatus.Connected)
            {
                client.LastReceiveTime = ServerContext.ServerClock.ElapsedMilliseconds;
            }

            var messageBytes = msg.ReadBytes(msg.LengthBytes);
            var message      = ServerContext.ClientMessageFactory.Deserialize(messageBytes, DateTime.UtcNow.Ticks) as IClientMessageBase;

            if (message == null)
            {
                LunaLog.Error("Error deserializing message!");
                return;
            }

            LmpPluginHandler.FireOnMessageReceived(client, message);
            //A plugin has handled this message and requested suppression of the default behavior
            if (message.Handled)
            {
                return;
            }

            if (message.VersionMismatch)
            {
                MessageQueuer.SendConnectionEnd(client, $"Version mismatch. Your version doesn't match the server's version: {VersionInfo.VersionNumber}.  Update your plugin.");
                return;
            }

            //Clients can only send HANDSHAKE until they are Authenticated.
            if (!client.Authenticated && message.MessageType != ClientMessageType.Handshake)
            {
                MessageQueuer.SendConnectionEnd(client, $"You must authenticate before sending a {message.MessageType} message");
                return;
            }

            LunaLog.Debug(message.MessageType.ToString());

            //Handle the message
            HandlerDictionary[message.MessageType].HandleMessage(client, message.Data);
        }
示例#9
0
        public static async void ThreadMain()
        {
            try
            {
                while (ServerContext.ServerRunning)
                {
                    //Check timers
                    NukeCommand.CheckTimer();
                    DekesslerCommand.CheckTimer();

                    LmpPluginHandler.FireOnUpdate(); //Run plugin update

                    await Task.Delay(IntervalSettings.SettingsStore.MainTimeTick);
                }
            }
            catch (Exception e)
            {
                LunaLog.Error($"Fatal error thrown, exception: {e}");
                ServerContext.Shutdown("Fatal error server side");
            }

            try
            {
                var disconnectTime  = LunaNetworkTime.UtcNow.Ticks;
                var sendingMessages = true;
                while (sendingMessages)
                {
                    if (LunaNetworkTime.UtcNow.Ticks - disconnectTime > TimeSpan.FromSeconds(5).Ticks)
                    {
                        LunaLog.Debug($"Shutting down with {ServerContext.PlayerCount} Players, " +
                                      $"{ServerContext.Clients.Count} connected Clients");
                        break;
                    }
                    sendingMessages = ClientRetriever.GetAuthenticatedClients().Any(c => c.SendMessageQueue.Count > 0);

                    await Task.Delay(IntervalSettings.SettingsStore.MainTimeTick);
                }
                LidgrenServer.ShutdownLidgrenServer();
            }
            catch (Exception e)
            {
                LunaLog.Fatal($"Fatal error thrown during shutdown, exception: {e}");
                throw;
            }
        }
示例#10
0
        private async void SendMessagesThread()
        {
            while (ConnectionStatus == ConnectionStatus.Connected)
            {
                if (SendMessageQueue.TryDequeue(out var message) && message != null)
                {
                    try
                    {
                        ServerContext.LidgrenServer.SendMessageToClient(this, message);
                    }
                    catch (Exception e)
                    {
                        ClientException.HandleDisconnectException("Send network message error: ", this, e);
                        return;
                    }

                    LmpPluginHandler.FireOnMessageSent(this, message);
                }
示例#11
0
        public static void ConnectClient(NetConnection newClientConnection)
        {
            var newClientObject = new ClientStructure(newClientConnection.RemoteEndPoint)
            {
                Subspace         = int.MinValue,
                PlayerStatus     = new PlayerStatus(),
                ConnectionStatus = ConnectionStatus.Connected,
                Connection       = newClientConnection,
                LastSendTime     = 0,
                LastReceiveTime  = ServerContext.ServerClock.ElapsedMilliseconds
            };

            Task.Run(() => MessageSender.StartSendingOutgoingMessages(newClientObject));

            LmpPluginHandler.FireOnClientConnect(newClientObject);

            ServerContext.Clients.TryAdd(newClientObject.Endpoint, newClientObject);
            VesselUpdateRelaySystem.AddPlayer(newClientObject);
            LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ServerContext.Clients.Count}");
        }
示例#12
0
        public void HandleHandshakeResponse(ClientStructure client, HandshakeResponseMsgData data)
        {
            var valid = CheckServerFull(client);

            valid &= valid && CheckUsernameLength(client, data.PlayerName);
            valid &= valid && CheckUsernameCharacters(client, data.PlayerName);
            valid &= valid && CheckWhitelist(client, data.PlayerName);
            valid &= valid && CheckPlayerIsAlreadyConnected(client, data.PlayerName);
            valid &= valid && CheckUsernameIsReserved(client, data.PlayerName);
            valid &= valid && CheckPlayerIsBanned(client, data.PlayerName, client.Endpoint.Address.ToString(), data.PublicKey);
            valid &= valid && CheckKey(client, data.PlayerName, data.PublicKey, data.ChallengeSignature);

            if (!valid)
            {
                LunaLog.Normal($"Client {data.PlayerName} failed to handshake: {Reason}. Disconnecting");
                client.DisconnectClient = true;
                ClientConnectionHandler.DisconnectClient(client, Reason);
            }
            else
            {
                client.PlayerName    = data.PlayerName;
                client.PublicKey     = data.PublicKey;
                client.Id            = Guid.NewGuid();
                client.Authenticated = true;

                LmpPluginHandler.FireOnClientAuthenticated(client);

                LunaLog.Normal($"Client {data.PlayerName} handshook successfully, Version: {data.MajorVersion}.{data.MinorVersion}.{data.BuildVersion}");

                CreatePlayerScenarioFiles(client, data.PlayerName);

                HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.HandshookSuccessfully, "success");

                var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionJoinMsgData>();
                msgData.PlayerName = client.PlayerName;

                MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData);

                LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ClientRetriever.GetClients().Length}");
            }
        }
示例#13
0
        private static void SendNetworkMessage(ClientStructure client, IServerMessageBase message)
        {
            if (client.ConnectionStatus == ConnectionStatus.CONNECTED)
            {
                try
                {
                    ServerContext.LidgrenServer.SendMessageToClient(client, message);
                }
                catch (Exception e)
                {
                    ClientException.HandleDisconnectException("Send network message error: ", client, e);
                    return;
                }
            }
            else
            {
                LunaLog.Normal($"Tried to send a message to client {client.PlayerName}, with connection status: {client.ConnectionStatus}");
            }

            LmpPluginHandler.FireOnMessageSent(client, message);
        }
示例#14
0
        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;

                if (!Common.PlatformIsWindows())
                {
                    LunaLog.Warning("Remember! Quit the server by using Control+C so the vessels are saved to the hard drive!");
                }


                if (Common.PlatformIsWindows())
                {
                    ExitSignal.Exit += (sender, args) => Exit();
                }
                else
                {
                    //Register the ctrl+c event and exit signal if we are on linux
                    Console.CancelKeyPress += (sender, args) => Exit();
                }

                //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;

                ServerContext.ServerStarting = true;

                //Set day for log change
                ServerContext.Day = LunaTime.Now.Day;

                LunaLog.Normal($"Starting Luna Server version: {LmpVersioning.CurrentVersion}");

                Universe.CheckUniverse();
                LoadSettingsAndGroups();
                VesselStoreSystem.LoadExistingVessels();
                ScenarioSystem.GenerateDefaultScenarios();
                ScenarioStoreSystem.LoadExistingScenarios();
                LmpPluginHandler.LoadPlugins();
                WarpSystem.Reset();

                LunaLog.Normal($"Starting {GeneralSettings.SettingsStore.WarpMode} server on Port {GeneralSettings.SettingsStore.Port}... ");
                LunaLog.Normal($"Server name: '{GeneralSettings.SettingsStore.ServerName}'...");
                LunaLog.Normal($"Server location: '{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}'...");

                ServerContext.ServerRunning = true;
                LidgrenServer.SetupLidgrenServer();

                //Do not add the command handler thread to the TaskContainer as it's a blocking task
                LongRunTaskFactory.StartNew(() => new CommandHandler().ThreadMain(), CancellationTokenSrc.Token);

                TaskContainer.Add(LongRunTaskFactory.StartNew(LogThread.RunLogThread, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(() => new ClientMainThread().ThreadMain(), CancellationTokenSrc.Token));

                TaskContainer.Add(LongRunTaskFactory.StartNew(() => BackupSystem.PerformBackups(CancellationTokenSrc.Token), CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenServer.StartReceiveingMessages, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenMasterServer.RefreshMasterServersList, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenMasterServer.RegisterWithMasterServer, CancellationTokenSrc.Token));

                TaskContainer.Add(LongRunTaskFactory.StartNew(VesselRelaySystem.RelayOldVesselMessages, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.RefreshLatestVersion, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.DisplayNewVersionMsg, CancellationTokenSrc.Token));

                while (ServerContext.ServerStarting)
                {
                    Thread.Sleep(500);
                }

                LunaLog.Normal("All systems up and running. Поехали!");
                LmpPluginHandler.FireOnServerStart();

                QuitEvent.WaitOne();

                LmpPluginHandler.FireOnServerStop();

                LunaLog.Normal("So long 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
            }
        }
示例#15
0
        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
            }
        }
示例#16
0
        public static void ReceiveCallback(ClientStructure client, NetIncomingMessage msg)
        {
            if (client == null || msg.LengthBytes <= 1)
            {
                return;
            }

            if (client.ConnectionStatus == ConnectionStatus.Connected)
            {
                client.LastReceiveTime = ServerContext.ServerClock.ElapsedMilliseconds;
            }

            if (!(ServerContext.ClientMessageFactory.Deserialize(msg, LunaNetworkTime.UtcNow.Ticks) is IClientMessageBase message))
            {
                return;
            }

            LmpPluginHandler.FireOnMessageReceived(client, message);
            //A plugin has handled this message and requested suppression of the default behavior
            if (message.Handled)
            {
                return;
            }

            if (message.VersionMismatch)
            {
                MessageQueuer.SendConnectionEnd(client, $"Version mismatch: Your version ({message.Data.MajorVersion}.{message.Data.MinorVersion}.{message.Data.BuildVersion}) " +
                                                $"does not match the server version: {LmpVersioning.CurrentVersion}.");
                return;
            }

            //Clients can only send HANDSHAKE until they are Authenticated.
            if (!client.Authenticated && message.MessageType != ClientMessageType.Handshake)
            {
                MessageQueuer.SendConnectionEnd(client, $"You must authenticate before sending a {message.MessageType} message");
                return;
            }

            switch (message.MessageType)
            {
            case ClientMessageType.Admin:
                AdminMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Handshake:
                HandshakeMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Chat:
                ChatMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.PlayerStatus:
                PlayerStatusMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.PlayerColor:
                PlayerColorMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Scenario:
                ScenarioDataMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Kerbal:
                KerbalMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Settings:
                SettingsMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Vessel:
                VesselMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.CraftLibrary:
                CraftLibraryMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Flag:
                FlagSyncMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Motd:
                MotdMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Warp:
                WarpControlMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Lock:
                LockSystemMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Mod:
                ModDataMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Groups:
                GroupMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Facility:
                FacilityMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.Screenshot:
                ScreenshotMsgReader.HandleMessage(client, message);
                break;

            case ClientMessageType.ShareProgress:
                ShareProgressMsgReader.HandleMessage(client, message);
                break;

            default:
                break;
            }
        }
示例#17
0
        public static void Main()
        {
            try
            {
                Console.Title = $"LMP {LmpVersioning.CurrentVersion}";

                Console.OutputEncoding  = Encoding.Unicode;
                ServerContext.StartTime = LunaNetworkTime.UtcNow.Ticks;

                LunaLog.Info("Remember! Quit the server by using 'Control + C' so a backup is properly made before closing!");

                if (Common.PlatformIsWindows())
                {
                    ExitSignal.Exit += (sender, args) => Exit();
                }
                else
                {
                    //Register the ctrl+c event and exit signal if we are on linux
                    Console.CancelKeyPress += (sender, args) => Exit();
                }

                //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();

                ServerContext.ServerStarting = true;

                //Set day for log change
                ServerContext.Day = LunaNetworkTime.Now.Day;

                LunaLog.Normal($"Luna Server version: {LmpVersioning.CurrentVersion} ({Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)})");

                Universe.CheckUniverse();
                LoadSettingsAndGroups();
                VesselStoreSystem.LoadExistingVessels();
                var scenariosCreated = ScenarioSystem.GenerateDefaultScenarios();
                ScenarioStoreSystem.LoadExistingScenarios(scenariosCreated);
                LmpPluginHandler.LoadPlugins();
                WarpSystem.Reset();

                LunaLog.Normal($"Starting '{GeneralSettings.SettingsStore.ServerName}' on Port {ConnectionSettings.SettingsStore.Port}... ");

                LidgrenServer.SetupLidgrenServer();
                LmpPortMapper.OpenLmpPort().Wait();
                LmpPortMapper.OpenWebPort().Wait();
                ServerContext.ServerRunning = true;
                WebServer.StartWebServer();

                //Do not add the command handler thread to the TaskContainer as it's a blocking task
                LongRunTaskFactory.StartNew(CommandHandler.ThreadMain, CancellationTokenSrc.Token);

                TaskContainer.Add(LongRunTaskFactory.StartNew(WebServer.RefreshWebServerInformation, CancellationTokenSrc.Token));

                TaskContainer.Add(LongRunTaskFactory.StartNew(LmpPortMapper.RefreshUpnpPort, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LogThread.RunLogThread, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(ClientMainThread.ThreadMain, CancellationTokenSrc.Token));

                TaskContainer.Add(LongRunTaskFactory.StartNew(() => BackupSystem.PerformBackups(CancellationTokenSrc.Token), CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenServer.StartReceivingMessages, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenMasterServer.RegisterWithMasterServer, CancellationTokenSrc.Token));

                TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.RefreshLatestVersion, CancellationTokenSrc.Token));
                TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.DisplayNewVersionMsg, CancellationTokenSrc.Token));

                while (ServerContext.ServerStarting)
                {
                    Thread.Sleep(500);
                }

                LunaLog.Normal("All systems up and running. Поехали!");
                LmpPluginHandler.FireOnServerStart();

                QuitEvent.WaitOne();

                LmpPluginHandler.FireOnServerStop();

                LunaLog.Normal("So long and thanks for all the fish!");
            }
            catch (Exception e)
            {
                LunaLog.Fatal(e is HandledException ? e.Message : $"Error in main server thread, Exception: {e}");
                Console.ReadLine(); //Avoid closing automatically
            }
        }
示例#18
0
        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;
            }
        }