コード例 #1
0
        public static void ThreadMain()
        {
            try
            {
                //Register commands
                CommandHandler.RegisterCommand("help", CommandHandler.DisplayHelp, "Displays this help");
                CommandHandler.RegisterCommand("say", CommandHandler.Say, "Broadcasts a message to clients");
                CommandHandler.RegisterCommand("dekessler", Dekessler.RunDekessler, "Clears out debris from the server");
                CommandHandler.RegisterCommand("nukeksc", NukeKSC.RunNukeKSC, "Clears ALL vessels from KSC and the Runway");
                CommandHandler.RegisterCommand("listclients", ListClients, "Lists connected clients");
                CommandHandler.RegisterCommand("countclients", CountClients, "Counts connected clients");

                //Main loop
                while (Server.serverRunning)
                {
                    string input = "";
                    try
                    {
                        input = Console.ReadLine();
                        if (input == null)
                        {
                            DarkLog.Debug("Terminal may be not attached or broken, Exiting out of command handler");
                            return;
                        }
                    }
                    catch
                    {
                        if (Server.serverRunning)
                        {
                            DarkLog.Debug("Ignored mono Console.ReadLine() bug");
                        }
                        Thread.Sleep(500);
                    }
                    DarkLog.Normal("Command input: " + input);
                    if (input.StartsWith("/"))
                    {
                        string commandPart  = input.Substring(1);
                        string argumentPart = "";
                        if (commandPart.Contains(" "))
                        {
                            if (commandPart.Length > commandPart.IndexOf(' ') + 1)
                            {
                                argumentPart = commandPart.Substring(commandPart.IndexOf(' ') + 1);
                            }
                            commandPart = commandPart.Substring(0, commandPart.IndexOf(' '));
                        }
                        if (commandPart.Length > 0)
                        {
                            if (commands.ContainsKey(commandPart))
                            {
                                try
                                {
                                    commands[commandPart].func(argumentPart);
                                }
                                catch (Exception e)
                                {
                                    DarkLog.Error("Error handling command " + commandPart + ", Exception " + e);
                                }
                            }
                            else
                            {
                                DarkLog.Normal("Unknown command: " + commandPart);
                            }
                        }
                    }
                    else
                    {
                        if (input != "")
                        {
                            commands["say"].func(input);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Server.serverRunning)
                {
                    DarkLog.Fatal("Error in command handler thread, Exception: " + e);
                    throw;
                }
            }
        }
コード例 #2
0
        public static void Main()
        {
            #if !DEBUG
            try
            {
            #endif
            //Start the server clock
            serverClock = new Stopwatch();
            serverClock.Start();

            Settings.Reset();

            //Set the last player activity time to server start
            lastPlayerActivity = serverClock.ElapsedMilliseconds;

            //Periodic garbage collection
            long lastGarbageCollect = 0;

            //Periodic screenshot check
            long lastScreenshotExpiredCheck = 0;

            //Periodic log check
            long lastLogExpiredCheck = 0;

            //Periodic day check
            long lastDayCheck = 0;

            //Set universe directory and modfile path
            universeDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Universe");
            modFile           = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DMPModControl.txt");

            if (!Directory.Exists(configDirectory))
            {
                Directory.CreateDirectory(configDirectory);
            }

            string oldSettingsFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DMPServerSettings.txt");
            string newSettingsFile = Path.Combine(Server.configDirectory, "Settings.txt");
            string oldGameplayFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DMPGameplaySettings.txt");
            string newGameplayFile = Path.Combine(Server.configDirectory, "GameplaySettings.txt");

            // Run the conversion
            BackwardsCompatibility.ConvertSettings(oldSettingsFile, newSettingsFile);
            if (File.Exists(oldGameplayFile))
            {
                if (!File.Exists(newGameplayFile))
                {
                    File.Move(oldGameplayFile, newGameplayFile);
                }
                File.Delete(oldGameplayFile);
            }

            //Register the server commands
            CommandHandler.RegisterCommand("exit", Server.ShutDown, "Shuts down the server");
            CommandHandler.RegisterCommand("quit", Server.ShutDown, "Shuts down the server");
            CommandHandler.RegisterCommand("shutdown", Server.ShutDown, "Shuts down the server");
            CommandHandler.RegisterCommand("restart", Server.Restart, "Restarts the server");
            CommandHandler.RegisterCommand("kick", KickCommand.KickPlayer, "Kicks a player from the server");
            CommandHandler.RegisterCommand("ban", BanSystem.fetch.BanPlayer, "Bans a player from the server");
            CommandHandler.RegisterCommand("banip", BanSystem.fetch.BanIP, "Bans an IP Address from the server");
            CommandHandler.RegisterCommand("bankey", BanSystem.fetch.BanPublicKey, "Bans a Guid from the server");
            CommandHandler.RegisterCommand("pm", PMCommand.HandleCommand, "Sends a message to a player");
            CommandHandler.RegisterCommand("admin", AdminCommand.HandleCommand, "Sets a player as admin/removes admin from the player");
            CommandHandler.RegisterCommand("whitelist", WhitelistCommand.HandleCommand, "Change the server whitelist");
            //Register the ctrl+c event
            Console.CancelKeyPress += new ConsoleCancelEventHandler(CatchExit);
            serverStarting          = true;

            //Fix kerbals from 0.23.5 to 0.24 (Now indexed by string, thanks Squad!
            BackwardsCompatibility.FixKerbals();

            //Remove player tokens
            BackwardsCompatibility.RemoveOldPlayerTokens();

            //Add new stock parts
            BackwardsCompatibility.UpdateModcontrolPartList();

            if (System.Net.Sockets.Socket.OSSupportsIPv6)
            {
                Settings.settingsStore.address = "::";
            }

            DarkLog.Debug("Loading settings...");
            Settings.Load();
            if (Settings.settingsStore.gameDifficulty == GameDifficulty.CUSTOM)
            {
                GameplaySettings.Reset();
                GameplaySettings.Load();
            }

            //Test compression
            if (Settings.settingsStore.compressionEnabled)
            {
                long testTime = Compression.TestSysIOCompression();
                Compression.compressionEnabled = true;
                DarkLog.Debug("System.IO compression works: " + Compression.sysIOCompressionWorks + ", test time: " + testTime + " ms.");
            }

            //Set day for log change
            day = DateTime.Now.Day;

            //Load plugins
            DMPPluginHandler.LoadPlugins();

            Console.Title = "DMPServer " + Common.PROGRAM_VERSION + ", protocol " + Common.PROTOCOL_VERSION;

            while (serverStarting || serverRestarting)
            {
                if (serverRestarting)
                {
                    DarkLog.Debug("Reloading settings...");
                    Settings.Reset();
                    Settings.Load();
                    if (Settings.settingsStore.gameDifficulty == GameDifficulty.CUSTOM)
                    {
                        DarkLog.Debug("Reloading gameplay settings...");
                        GameplaySettings.Reset();
                        GameplaySettings.Load();
                    }
                }

                serverRestarting = false;
                DarkLog.Normal("Starting DMPServer " + Common.PROGRAM_VERSION + ", protocol " + Common.PROTOCOL_VERSION);

                if (Settings.settingsStore.gameDifficulty == GameDifficulty.CUSTOM)
                {
                    //Generate the config file by accessing the object.
                    DarkLog.Debug("Loading gameplay settings...");
                    GameplaySettings.Load();
                }

                //Load universe
                DarkLog.Normal("Loading universe... ");
                CheckUniverse();

                DarkLog.Normal("Starting " + Settings.settingsStore.warpMode + " server on port " + Settings.settingsStore.port + "... ");

                serverRunning = true;
                Thread commandThread = new Thread(new ThreadStart(CommandHandler.ThreadMain));
                Thread clientThread  = new Thread(new ThreadStart(ClientHandler.ThreadMain));
                commandThread.Start();
                clientThread.Start();
                while (serverStarting)
                {
                    Thread.Sleep(500);
                }

                StartHTTPServer();
                DarkLog.Normal("Ready!");
                DMPPluginHandler.FireOnServerStart();
                while (serverRunning)
                {
                    //Run a garbage collection every 30 seconds.
                    if ((serverClock.ElapsedMilliseconds - lastGarbageCollect) > 30000)
                    {
                        lastGarbageCollect = serverClock.ElapsedMilliseconds;
                        GC.Collect();
                    }
                    //Run the screenshot expire function every 10 minutes
                    if ((serverClock.ElapsedMilliseconds - lastScreenshotExpiredCheck) > 600000)
                    {
                        lastScreenshotExpiredCheck = serverClock.ElapsedMilliseconds;
                        ScreenshotExpire.ExpireScreenshots();
                    }
                    //Run the log expire function every 10 minutes
                    if ((serverClock.ElapsedMilliseconds - lastLogExpiredCheck) > 600000)
                    {
                        lastLogExpiredCheck = serverClock.ElapsedMilliseconds;
                        LogExpire.ExpireLogs();
                    }
                    // Check if the day has changed, every minute
                    if ((serverClock.ElapsedMilliseconds - lastDayCheck) > 60000)
                    {
                        lastDayCheck = serverClock.ElapsedMilliseconds;
                        if (day != DateTime.Now.Day)
                        {
                            DarkLog.LogFilename = Path.Combine(DarkLog.LogFolder, "dmpserver " + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".log");
                            DarkLog.WriteToLog("Continued from logfile " + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".log");
                            day = DateTime.Now.Day;
                        }
                    }

                    Thread.Sleep(500);
                }
                DMPPluginHandler.FireOnServerStop();
                commandThread.Abort();
                clientThread.Join();
            }
            DarkLog.Normal("Goodbye!");
            Environment.Exit(0);
            #if !DEBUG
        }

        catch (Exception e)
        {
            DarkLog.Fatal("Error in main server thread, Exception: " + e);
            throw;
        }
            #endif
        }
コード例 #3
0
        private static void Load()
        {
            DarkLog.Debug("Loading settings");
            FieldInfo[] settingFields = typeof(SettingsStore).GetFields();
            if (!File.Exists(settingsFile))
            {
                try
                {
                    if (System.Net.Sockets.Socket.OSSupportsIPv6)
                    {
                        //Default to listening on IPv4 and IPv6 if possible.
                        settingsStore.address = "::";
                    }
                }
                catch
                {
                    //May throw on Windows XP
                }
                Save();
            }
            using (FileStream fs = new FileStream(settingsFile, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    string currentLine;
                    string trimmedLine;
                    string currentKey;
                    string currentValue;
                    while (true)
                    {
                        currentLine = sr.ReadLine();
                        if (currentLine == null)
                        {
                            break;
                        }
                        trimmedLine = currentLine.Trim();
                        if (!String.IsNullOrEmpty(trimmedLine))
                        {
                            if (trimmedLine.Contains(",") && !trimmedLine.StartsWith("#"))
                            {
                                currentKey   = trimmedLine.Substring(0, trimmedLine.IndexOf(","));
                                currentValue = trimmedLine.Substring(trimmedLine.IndexOf(",") + 1);

                                foreach (FieldInfo settingField in settingFields)
                                {
                                    if (settingField.Name.ToLower() == currentKey)
                                    {
                                        if (settingField.FieldType == typeof(string))
                                        {
                                            settingField.SetValue(settingsStore, currentValue);
                                        }
                                        if (settingField.FieldType == typeof(int))
                                        {
                                            int intValue = Int32.Parse(currentValue);
                                            settingField.SetValue(settingsStore, (int)intValue);
                                        }
                                        if (settingField.FieldType == typeof(double))
                                        {
                                            double doubleValue = Double.Parse(currentValue);
                                            settingField.SetValue(settingsStore, (double)doubleValue);
                                        }
                                        if (settingField.FieldType == typeof(bool))
                                        {
                                            if (currentValue == "1")
                                            {
                                                settingField.SetValue(settingsStore, true);
                                            }
                                            else
                                            {
                                                settingField.SetValue(settingsStore, false);
                                            }
                                        }
                                        if (settingField.FieldType.IsEnum)
                                        {
                                            int   intValue   = Int32.Parse(currentValue);
                                            Array enumValues = settingField.FieldType.GetEnumValues();
                                            if (intValue <= enumValues.Length)
                                            {
                                                settingField.SetValue(settingsStore, enumValues.GetValue(intValue));
                                            }
                                        }
                                        //DarkLog.Debug(settingField.Name + ": " + currentValue);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Save();
        }
コード例 #4
0
        public static void SendToClient(ClientObject client, ServerMessage message, bool highPriority)
        {
            //Because we dodge the queue, we need to lock it up again...
            lock (client.sendLock)
            {
                if (message == null)
                {
                    return;
                }
                //All messages have an 8 byte header
                client.bytesQueuedOut += 8;
                if (message.data != null)
                {
                    //Count the payload if we have one.
                    client.bytesQueuedOut += message.data.Length;
                }
                if (highPriority)
                {
                    client.sendMessageQueueHigh.Enqueue(message);
                }
                else
                {
                    client.sendMessageQueueLow.Enqueue(message);
                    //If we need to optimize
                    if (client.bytesQueuedOut > OPTIMIZE_QUEUE_LIMIT)
                    {
                        //And we haven't optimized in the last 5 seconds
                        long currentTime    = DateTime.UtcNow.Ticks;
                        long optimizedBytes = 0;
                        if ((currentTime - client.lastQueueOptimizeTime) > 50000000)
                        {
                            client.lastQueueOptimizeTime = currentTime;
                            DarkLog.Debug("Optimizing " + client.playerName + " (" + client.bytesQueuedOut + " bytes queued)");

                            //Create a temporary filter list
                            List <ServerMessage> oldClientMessagesToSend = new List <ServerMessage>();
                            List <ServerMessage> newClientMessagesToSend = new List <ServerMessage>();
                            //Steal all the messages from the queue and put them into a list
                            ServerMessage stealMessage = null;
                            while (client.sendMessageQueueLow.TryDequeue(out stealMessage))
                            {
                                oldClientMessagesToSend.Add(stealMessage);
                            }
                            //Clear the client send queue
                            List <string> seenProtovesselUpdates = new List <string>();
                            List <string> seenPositionUpdates    = new List <string>();
                            //Iterate backwards over the list
                            oldClientMessagesToSend.Reverse();
                            foreach (ServerMessage currentMessage in oldClientMessagesToSend)
                            {
                                if (currentMessage.type != ServerMessageType.VESSEL_PROTO && currentMessage.type != ServerMessageType.VESSEL_UPDATE)
                                {
                                    //Message isn't proto or position, don't skip it.
                                    newClientMessagesToSend.Add(currentMessage);
                                }
                                else
                                {
                                    //Message is proto or position
                                    if (currentMessage.type == ServerMessageType.VESSEL_PROTO)
                                    {
                                        using (MessageReader mr = new MessageReader(currentMessage.data))
                                        {
                                            //Don't care about the send time, it's already the latest in the queue.
                                            mr.Read <double>();
                                            string vesselID = mr.Read <string>();
                                            if (!seenProtovesselUpdates.Contains(vesselID))
                                            {
                                                seenProtovesselUpdates.Add(vesselID);
                                                newClientMessagesToSend.Add(currentMessage);
                                            }
                                            else
                                            {
                                                optimizedBytes += 8 + currentMessage.data.Length;
                                            }
                                        }
                                    }

                                    if (currentMessage.type == ServerMessageType.VESSEL_UPDATE)
                                    {
                                        using (MessageReader mr = new MessageReader(currentMessage.data))
                                        {
                                            //Don't care about the send time, it's already the latest in the queue.
                                            mr.Read <double>();
                                            string vesselID = mr.Read <string>();
                                            if (!seenPositionUpdates.Contains(vesselID))
                                            {
                                                seenPositionUpdates.Add(vesselID);
                                                newClientMessagesToSend.Add(currentMessage);
                                            }
                                            else
                                            {
                                                //8 byte message header plus payload
                                                optimizedBytes += 8 + currentMessage.data.Length;
                                            }
                                        }
                                    }
                                }
                            }
                            //Flip it back to the right order
                            newClientMessagesToSend.Reverse();
                            foreach (ServerMessage putBackMessage in newClientMessagesToSend)
                            {
                                client.sendMessageQueueLow.Enqueue(putBackMessage);
                            }
                            float optimizeTime = (DateTime.UtcNow.Ticks - currentTime) / 10000f;
                            client.bytesQueuedOut -= optimizedBytes;
                            DarkLog.Debug("Optimized " + optimizedBytes + " bytes in " + Math.Round(optimizeTime, 3) + " ms.");
                        }
                    }
                }
                client.sendEvent.Set();
            }
        }
コード例 #5
0
ファイル: Settings.cs プロジェクト: nevercast/DarkMultiPlayer
        public static void Load()
        {
            FieldInfo[] settingFields = typeof(SettingsStore).GetFields();
            if (!File.Exists(Path.Combine(serverPath, SETTINGS_FILE_NAME)))
            {
                Save();
            }
            using (FileStream fs = new FileStream(settingsFile, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    string currentLine;
                    string trimmedLine;
                    string currentKey;
                    string currentValue;
                    while (true)
                    {
                        currentLine = sr.ReadLine();
                        if (currentLine == null)
                        {
                            break;
                        }
                        trimmedLine = currentLine.Trim();
                        if (!String.IsNullOrEmpty(trimmedLine))
                        {
                            if (trimmedLine.Contains(",") && !trimmedLine.StartsWith("#"))
                            {
                                currentKey   = trimmedLine.Substring(0, trimmedLine.IndexOf(","));
                                currentValue = trimmedLine.Substring(trimmedLine.IndexOf(",") + 1);

                                foreach (FieldInfo settingField in settingFields)
                                {
                                    if (settingField.Name.ToLower() == currentKey)
                                    {
                                        if (settingField.FieldType == typeof(string))
                                        {
                                            settingField.SetValue(settingsStore, currentValue);
                                        }
                                        if (settingField.FieldType == typeof(int))
                                        {
                                            int intValue = Int32.Parse(currentValue);
                                            settingField.SetValue(settingsStore, (int)intValue);
                                        }
                                        if (settingField.FieldType == typeof(bool))
                                        {
                                            if (currentValue == "1")
                                            {
                                                settingField.SetValue(settingsStore, true);
                                            }
                                            else
                                            {
                                                settingField.SetValue(settingsStore, false);
                                            }
                                        }
                                        if (settingField.FieldType.IsEnum)
                                        {
                                            int   intValue   = Int32.Parse(currentValue);
                                            Array enumValues = settingField.FieldType.GetEnumValues();
                                            if (intValue <= enumValues.Length)
                                            {
                                                settingField.SetValue(settingsStore, enumValues.GetValue(intValue));
                                            }
                                        }
                                        DarkLog.Debug(settingField.Name + ": " + currentValue);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Save();
        }
コード例 #6
0
 private static void SendNetworkMessage(ClientObject client, ServerMessage message)
 {
     //Write the send times down in SYNC_TIME_REPLY packets
     if (message.type == ServerMessageType.SYNC_TIME_REPLY)
     {
         try
         {
             using (MessageWriter mw = new MessageWriter())
             {
                 using (MessageReader mr = new MessageReader(message.data))
                 {
                     client.bytesQueuedOut += 8;
                     //Client send time
                     mw.Write <long>(mr.Read <long>());
                     //Server receive time
                     mw.Write <long>(mr.Read <long>());
                     //Server send time
                     mw.Write <long>(DateTime.UtcNow.Ticks);
                     message.data = mw.GetMessageBytes();
                 }
             }
         }
         catch (Exception e)
         {
             DarkLog.Debug("Error rewriting SYNC_TIME packet, Exception " + e);
         }
     }
     //Continue sending
     byte[] messageBytes = Common.PrependNetworkFrame((int)message.type, message.data);
     client.lastSendTime    = Server.serverClock.ElapsedMilliseconds;
     client.bytesQueuedOut -= messageBytes.Length;
     client.bytesSent      += messageBytes.Length;
     if (client.connectionStatus == ConnectionStatus.CONNECTED)
     {
         try
         {
             client.connection.GetStream().Write(messageBytes, 0, messageBytes.Length);
         }
         catch (Exception e)
         {
             HandleDisconnectException("Send Network Message", client, e);
             return;
         }
     }
     DMPPluginHandler.FireOnMessageSent(client, message);
     if (message.type == ServerMessageType.CONNECTION_END)
     {
         using (MessageReader mr = new MessageReader(message.data))
         {
             string reason = mr.Read <string>();
             DarkLog.Normal("Disconnecting client " + client.playerName + ", sent CONNECTION_END (" + reason + ") to endpoint " + client.endpoint);
             client.disconnectClient = true;
             DisconnectClient(client);
         }
     }
     if (message.type == ServerMessageType.HANDSHAKE_REPLY)
     {
         using (MessageReader mr = new MessageReader(message.data))
         {
             int    response = mr.Read <int>();
             string reason   = mr.Read <string>();
             if (response != 0)
             {
                 DarkLog.Normal("Disconnecting client " + client.playerName + ", sent HANDSHAKE_REPLY (" + reason + ") to endpoint " + client.endpoint);
                 client.disconnectClient = true;
                 DisconnectClient(client);
             }
         }
     }
 }
コード例 #7
0
        internal static void HandleMessage(ClientObject client, ClientMessage message)
        {
            //Prevent plugins from dodging SPLIT_MESSAGE. If they are modified, every split message will be broken.
            if (message.type != ClientMessageType.SPLIT_MESSAGE)
            {
                DMPPluginHandler.FireOnMessageReceived(client, message);

                if (message.handled)
                {
                    //a plugin has handled this message and requested suppression of the default DMP behavior
                    return;
                }
            }

            //Clients can only send HEARTBEATS, HANDSHAKE_REQUEST or CONNECTION_END's until they are authenticated.
            if (!client.authenticated && !(message.type == ClientMessageType.HEARTBEAT || message.type == ClientMessageType.HANDSHAKE_RESPONSE || message.type == ClientMessageType.CONNECTION_END))
            {
                Messages.ConnectionEnd.SendConnectionEnd(client, "You must authenticate before attempting to send a " + message.type.ToString() + " message");
                return;
            }

#if !DEBUG
            try
            {
#endif
            switch (message.type)
            {
            case ClientMessageType.HEARTBEAT:
                //Don't do anything for heartbeats, they just keep the connection alive
                break;

            case ClientMessageType.HANDSHAKE_RESPONSE:
                Messages.Handshake.HandleHandshakeResponse(client, message.data);
                break;

            case ClientMessageType.CHAT_MESSAGE:
                Messages.Chat.HandleChatMessage(client, message.data);
                break;

            case ClientMessageType.PLAYER_STATUS:
                Messages.PlayerStatus.HandlePlayerStatus(client, message.data);
                break;

            case ClientMessageType.PLAYER_COLOR:
                Messages.PlayerColor.HandlePlayerColor(client, message.data);
                break;

            case ClientMessageType.GROUP:
                Messages.GroupMessage.HandleMessage(client, message.data);
                break;

            case ClientMessageType.SCENARIO_DATA:
                Messages.ScenarioData.HandleScenarioModuleData(client, message.data);
                break;

            case ClientMessageType.SYNC_TIME_REQUEST:
                Messages.SyncTimeRequest.HandleSyncTimeRequest(client, message.data);
                break;

            case ClientMessageType.KERBALS_REQUEST:
                Messages.KerbalsRequest.HandleKerbalsRequest(client);
                break;

            case ClientMessageType.KERBAL_PROTO:
                Messages.KerbalProto.HandleKerbalProto(client, message.data);
                break;

            case ClientMessageType.VESSELS_REQUEST:
                Messages.VesselRequest.HandleVesselsRequest(client, message.data);
                break;

            case ClientMessageType.VESSEL_PROTO:
                Messages.VesselProto.HandleVesselProto(client, message.data);
                break;

            case ClientMessageType.VESSEL_UPDATE:
                Messages.VesselUpdate.HandleVesselUpdate(client, message.data);
                break;

            case ClientMessageType.VESSEL_REMOVE:
                Messages.VesselRemove.HandleVesselRemoval(client, message.data);
                break;

            case ClientMessageType.PERMISSION:
                Messages.PermissionMessage.HandleMessage(client, message.data);
                break;

            case ClientMessageType.CRAFT_LIBRARY:
                Messages.CraftLibrary.HandleCraftLibrary(client, message.data);
                break;

            case ClientMessageType.SCREENSHOT_LIBRARY:
                Messages.ScreenshotLibrary.HandleScreenshotLibrary(client, message.data);
                break;

            case ClientMessageType.FLAG_SYNC:
                Messages.FlagSync.HandleFlagSync(client, message.data);
                break;

            case ClientMessageType.PING_REQUEST:
                Messages.PingRequest.HandlePingRequest(client, message.data);
                break;

            case ClientMessageType.MOTD_REQUEST:
                Messages.MotdRequest.HandleMotdRequest(client);
                break;

            case ClientMessageType.WARP_CONTROL:
                Messages.WarpControl.HandleWarpControl(client, message.data);
                break;

            case ClientMessageType.LOCK_SYSTEM:
                Messages.LockSystem.HandleLockSystemMessage(client, message.data);
                break;

            case ClientMessageType.MOD_DATA:
                Messages.ModData.HandleModDataMessage(client, message.data);
                break;

            case ClientMessageType.KERBAL_REMOVE:
                Messages.VesselRemove.HandleKerbalRemoval(client, message.data);
                break;

            case ClientMessageType.SPLIT_MESSAGE:
                Messages.SplitMessage.HandleSplitMessage(client, message.data);
                break;

            case ClientMessageType.CONNECTION_END:
                Messages.ConnectionEnd.HandleConnectionEnd(client, message.data);
                break;

            case ClientMessageType.MODPACK_DATA:
                Messages.Modpack.HandleModpackMessage(client, message.data);
                break;

            default:
                DarkLog.Debug("Unhandled message type " + message.type);
                Messages.ConnectionEnd.SendConnectionEnd(client, "Unhandled message type " + message.type);
#if DEBUG
                throw new NotImplementedException("Message type not implemented");
#else
                break;
#endif
            }
#if !DEBUG
        }

        catch (Exception e)
        {
            DarkLog.Debug("Error handling " + message.type + " from " + client.playerName + ", exception: " + e);
            Messages.ConnectionEnd.SendConnectionEnd(client, "Server failed to process " + message.type + " message");
        }
#endif
        }
コード例 #8
0
        public static void LoadPlugins()
        {
            string pluginDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");

            if (!Directory.Exists(pluginDirectory))
            {
                Directory.CreateDirectory(pluginDirectory);
            }
            DarkLog.Debug("Loading plugins!");
            //Load all the assemblies just in case they depend on each other during instantation
            List <Assembly> loadedAssemblies = new List <Assembly>();

            string[] pluginFiles = Directory.GetFiles(pluginDirectory, "*", SearchOption.AllDirectories);
            foreach (string pluginFile in pluginFiles)
            {
                if (Path.GetExtension(pluginFile).ToLower() == ".dll")
                {
                    try
                    {
                        //UnsafeLoadFrom will not throw an exception if the dll is marked as unsafe, such as downloaded from internet in Windows
                        //See http://stackoverflow.com/a/15238782
                        Assembly loadedAssembly = Assembly.UnsafeLoadFrom(pluginFile);
                        loadedAssemblies.Add(loadedAssembly);
                        DarkLog.Debug("Loaded " + pluginFile);
                    }
                    catch (NotSupportedException)
                    {
                        //This should only occur if using Assembly.LoadFrom() above instead of Assembly.UnsafeLoadFrom()
                        DarkLog.Debug("Can't load dll, perhaps it is blocked: " + pluginFile);
                    }
                    catch
                    {
                        DarkLog.Debug("Error loading " + pluginFile);
                    }
                }
            }

            //Iterate through the assemblies looking for classes that have the IDMPPlugin interface

            Type dmpInterfaceType = typeof(IDMPPlugin);

            foreach (Assembly loadedAssembly in loadedAssemblies)
            {
                Type[] loadedTypes = loadedAssembly.GetExportedTypes();
                foreach (Type loadedType in loadedTypes)
                {
                    Type[] typeInterfaces       = loadedType.GetInterfaces();
                    bool   containsDMPInterface = false;
                    foreach (Type typeInterface in typeInterfaces)
                    {
                        if (typeInterface == dmpInterfaceType)
                        {
                            containsDMPInterface = true;
                        }
                    }
                    if (containsDMPInterface)
                    {
                        DarkLog.Debug("Loading plugin: " + loadedType.FullName);

                        try
                        {
                            IDMPPlugin pluginInstance = ActivatePluginType(loadedType);

                            if (pluginInstance != null)
                            {
                                DarkLog.Debug("Loaded plugin: " + loadedType.FullName);

                                loadedPlugins.Add(pluginInstance);
                            }
                        }
                        catch (Exception ex)
                        {
                            DarkLog.Error("Error loading plugin " + loadedType.FullName + "(" + loadedType.Assembly.FullName + ") Exception: " + ex.ToString());
                        }
                    }
                }
            }
            DarkLog.Debug("Done!");
        }
コード例 #9
0
        public static void ThreadMain()
        {
            try
            {
                clients = new List <ClientObject>().AsReadOnly();

                Messages.WarpControl.Reset();
                Messages.Chat.Reset();
                Messages.ScreenshotLibrary.Reset();

                SetupTCPServer();

                while (Server.serverRunning)
                {
                    //Process current clients
                    foreach (ClientObject client in clients)
                    {
                        Messages.Heartbeat.CheckHeartBeat(client);
                    }
                    ModpackSystem.fetch.SendFilesToClients();
                    //Check timers
                    NukeKSC.CheckTimer();
                    Dekessler.CheckTimer();
                    Messages.WarpControl.CheckTimer();
                    //Run plugin update
                    DMPPluginHandler.FireOnUpdate();
                    Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                DarkLog.Error("Fatal error thrown, exception: " + e);
                Server.ShutDown("Crashed!");
            }
            try
            {
                long disconnectTime = DateTime.UtcNow.Ticks;
                bool sendingHighPriotityMessages = true;
                while (sendingHighPriotityMessages)
                {
                    if ((DateTime.UtcNow.Ticks - disconnectTime) > 50000000)
                    {
                        DarkLog.Debug("Shutting down with " + Server.playerCount + " players, " + clients.Count + " connected clients");
                        break;
                    }
                    sendingHighPriotityMessages = false;
                    foreach (ClientObject client in clients)
                    {
                        if (client.authenticated && (client.sendMessageQueueHigh.Count > 0))
                        {
                            sendingHighPriotityMessages = true;
                        }
                    }
                    Thread.Sleep(10);
                }
                ShutdownTCPServer();
            }
            catch (Exception e)
            {
                DarkLog.Fatal("Fatal error thrown during shutdown, exception: " + e);
                throw;
            }
        }
コード例 #10
0
        public static void ThreadMain()
        {
            try
            {
                //Register commands
                CommandHandler.RegisterCommand("help", CommandHandler.DisplayHelp, "Displays this help");
                CommandHandler.RegisterCommand("say", CommandHandler.Say, "Broadcasts a message to clients");
                CommandHandler.RegisterCommand("dekessler", Dekessler.RunDekessler, "Clears out debris from the server");
                CommandHandler.RegisterCommand("nukeksc", NukeKSC.RunNukeKSC, "Clears ALL vessels from KSC and the Runway");
                CommandHandler.RegisterCommand("listclients", ListClients, "Lists connected clients");
                CommandHandler.RegisterCommand("countclients", CountClients, "Counts connected clients");
                CommandHandler.RegisterCommand("connectionstats", ConnectionStats, "Displays network traffic usage");
                CommandHandler.RegisterCommand("editgroup", Groups.fetch.EditGroupCommand, "Sets the group to edit");
                CommandHandler.RegisterCommand("addplayer", Groups.fetch.AddPlayerToGroupCommand, "Adds player to group, first player becomes admin");
                CommandHandler.RegisterCommand("removeplayer", Groups.fetch.RemovePlayerFromGroupCommand, "Removes player from group");
                CommandHandler.RegisterCommand("addadmin", Groups.fetch.AddPlayerAdminCommand, "Adds admin to group");
                CommandHandler.RegisterCommand("removeadmin", Groups.fetch.RemovePlayerAdminCommand, "Removes admin from group");
                CommandHandler.RegisterCommand("showgroups", Groups.fetch.ShowGroupsCommand, "Shows group database");
                CommandHandler.RegisterCommand("editvessel", Permissions.fetch.EditVesselCommand, "Edits vessel permissions, takes same ID from Universe/Vessels/");
                CommandHandler.RegisterCommand("vesselowner", Permissions.fetch.SetVesselOwnerCommand, "Sets a vessel owner");
                CommandHandler.RegisterCommand("vesselgroup", Permissions.fetch.SetVesselGroupCommand, "Sets a vessels group");
                CommandHandler.RegisterCommand("vesselprotection", Permissions.fetch.SetVesselProtectionCommand, "Sets vessel protection level. Valid levels: public, group, private.");
                CommandHandler.RegisterCommand("showvessels", Permissions.fetch.ShowVesselsCommand, "Shows vessel protection database");

                //Main loop
                while (Server.serverRunning)
                {
                    string input = "";
                    try
                    {
                        input = Console.ReadLine();
                        if (input == null)
                        {
                            DarkLog.Debug("Terminal may be not attached or broken, Exiting out of command handler");
                            return;
                        }
                    }
                    catch
                    {
                        if (Server.serverRunning)
                        {
                            DarkLog.Debug("Ignored mono Console.ReadLine() bug");
                        }
                        Thread.Sleep(500);
                    }
                    DarkLog.Normal("Command input: " + input);
                    if (input.StartsWith("/", StringComparison.Ordinal))
                    {
                        HandleServerInput(input.Substring(1));
                    }
                    else
                    {
                        if (input != "")
                        {
                            commands["say"].func(input);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Server.serverRunning)
                {
                    DarkLog.Fatal("Error in command handler thread, Exception: " + e);
                    throw;
                }
            }
        }
コード例 #11
0
        public void AdminCommand(string commandArgs)
        {
            string func       = "";
            string playerName = "";

            func = commandArgs;
            if (commandArgs.Contains(" "))
            {
                func = commandArgs.Substring(0, commandArgs.IndexOf(" "));
                if (commandArgs.Substring(func.Length).Contains(" "))
                {
                    playerName = commandArgs.Substring(func.Length + 1);
                }
            }

            switch (func)
            {
            default:
                DarkLog.Normal("Undefined function. Usage: /admin [add|del] playername or /admin show");
                break;

            case "add":
                if (File.Exists(Path.Combine(Server.universeDirectory, "Players", playerName + ".txt")))
                {
                    if (!serverAdmins.Contains(playerName))
                    {
                        DarkLog.Debug("Added '" + playerName + "' to admin list.");
                        serverAdmins.Add(playerName);
                        //Notify all players an admin has been added

                        Messages.ServerClient_AdminAddSend msg = new Messages.ServerClient_AdminAddSend();
                        msg.name = playerName;
                        Broadcast(msg);
                    }
                    else
                    {
                        DarkLog.Normal("'" + playerName + "' is already an admin.");
                    }
                }
                else
                {
                    DarkLog.Normal("'" + playerName + "' does not exist.");
                }
                break;

            case "del":
                if (serverAdmins.Contains(playerName))
                {
                    DarkLog.Normal("Removed '" + playerName + "' from the admin list.");
                    serverAdmins.Remove(playerName);
                    //Notify all players an admin has been removed
                    Messages.ServerClient_AdminRemoveSend msg = new Messages.ServerClient_AdminRemoveSend();
                    msg.name = playerName;
                    Broadcast(msg);
                }
                else
                {
                    DarkLog.Normal("'" + playerName + "' is not an admin.");
                }
                break;

            case "show":
                foreach (string player in serverAdmins)
                {
                    DarkLog.Normal(player);
                }
                break;
            }
        }
コード例 #12
0
        public static void LoadPlugins()
        {
            DarkLog.Debug("Loading plugins!");
            //Load all the assemblies just in case they depend on each other during instantation
            List <Assembly> loadedAssemblies = new List <Assembly>();

            string[] pluginFiles = Directory.GetFiles(Server.pluginDirectory, "*", SearchOption.AllDirectories);
            foreach (string pluginFile in pluginFiles)
            {
                if (Path.GetExtension(pluginFile).ToLower() == ".dll")
                {
                    try
                    {
                        Assembly loadedAssembly = Assembly.LoadFile(pluginFile);
                        loadedAssemblies.Add(loadedAssembly);
                        DarkLog.Debug("Loaded " + pluginFile);
                    }
                    catch
                    {
                        DarkLog.Debug("Error loading " + pluginFile);
                    }
                }
            }
            //Add all the event types
            pluginEvents.Add(typeof(DMPUpdate), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnServerStart), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnServerStop), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnClientConnect), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnClientAuthenticated), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnClientDisconnect), new List <Delegate>());
            pluginEvents.Add(typeof(DMPOnMessageReceived), new List <Delegate>());
            //Iterate through the assemblies looking for the DMPPlugin attribute
            foreach (Assembly loadedAssembly in loadedAssemblies)
            {
                Type[] loadedTypes = loadedAssembly.GetExportedTypes();
                foreach (Type loadedType in loadedTypes)
                {
                    if (loadedType.IsDefined(typeof(DMPPluginAttribute), false))
                    {
                        DarkLog.Debug("Loading " + loadedType.Name);
                        object       pluginInstance = Activator.CreateInstance(loadedType);
                        MethodInfo[] methodInfos    = loadedType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
                        foreach (MethodInfo methodInfo in methodInfos)
                        {
                            try
                            {
                                foreach (Type evT in pluginEvents.Keys)
                                {
                                    if (evT.Name.Substring(3) == methodInfo.Name)
                                    {
                                        DarkLog.Debug("Event registered : " + evT.Name);
                                        Delegate     deg  = Delegate.CreateDelegate(evT, pluginInstance, methodInfo);
                                        DMPEventInfo info = new DMPEventInfo();
                                        info.loadedAssembly = loadedAssembly.FullName;
                                        info.loadedType     = loadedType.Name;
                                        delegateInfo.Add(deg, info);
                                        pluginEvents[evT].Add(deg);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                DarkLog.Error("Error loading " + methodInfo.Name + " from " + loadedType.Name + ", Exception: " + e.Message);
                            }
                        }
                    }
                }
            }
            DarkLog.Debug("Done!");
        }
コード例 #13
0
        public static void HandleCommand(string commandArgs)
        {
            string func       = "";
            string playerName = "";

            func = commandArgs;
            if (commandArgs.Contains(" "))
            {
                func = commandArgs.Substring(0, commandArgs.IndexOf(" "));
                if (commandArgs.Substring(func.Length).Contains(" "))
                {
                    playerName = commandArgs.Substring(func.Length + 1);
                }
            }

            switch (func)
            {
            default:
                DarkLog.Normal("Undefined function. Usage: /admin [add|del] playername or /admin show");
                break;

            case "add":
                if (File.Exists(Path.Combine(Server.universeDirectory, "Players", playerName + ".txt")))
                {
                    if (!AdminSystem.fetch.IsAdmin(playerName))
                    {
                        DarkLog.Debug("Added '" + playerName + "' to admin list.");
                        AdminSystem.fetch.AddAdmin(playerName);
                        //Notify all players an admin has been added
                        ServerMessage newMessage = new ServerMessage();
                        newMessage.type = ServerMessageType.ADMIN_SYSTEM;
                        using (MessageWriter mw = new MessageWriter())
                        {
                            mw.Write <int>((int)AdminMessageType.ADD);
                            mw.Write <string>(playerName);
                            newMessage.data = mw.GetMessageBytes();
                        }
                        ClientHandler.SendToAll(null, newMessage, true);
                    }
                    else
                    {
                        DarkLog.Normal("'" + playerName + "' is already an admin.");
                    }
                }
                else
                {
                    DarkLog.Normal("'" + playerName + "' does not exist.");
                }
                break;

            case "del":
                if (AdminSystem.fetch.IsAdmin(playerName))
                {
                    DarkLog.Normal("Removed '" + playerName + "' from the admin list.");
                    AdminSystem.fetch.RemoveAdmin(playerName);
                    //Notify all players an admin has been removed
                    ServerMessage newMessage = new ServerMessage();
                    newMessage.type = ServerMessageType.ADMIN_SYSTEM;
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)AdminMessageType.REMOVE);
                        mw.Write <string>(playerName);
                        newMessage.data = mw.GetMessageBytes();
                    }
                    ClientHandler.SendToAll(null, newMessage, true);
                }
                else
                {
                    DarkLog.Normal("'" + playerName + "' is not an admin.");
                }
                break;

            case "show":
                foreach (string player in AdminSystem.fetch.GetAdmins())
                {
                    DarkLog.Normal(player);
                }
                break;
            }
        }
コード例 #14
0
        public static void UpdateModcontrolPartList()
        {
            if (!File.Exists(Server.modFile))
            {
                return;
            }
            bool          readingParts      = false;
            string        modcontrolVersion = "";
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("#MODCONTROLVERSION=" + Common.MODCONTROL_VERSION);
            List <string> stockParts   = Common.GetStockParts();
            List <string> modParts     = new List <string>();
            bool          partsPrinted = false;

            using (StreamReader sr = new StreamReader(Server.modFile))
            {
                string currentLine = null;
                while ((currentLine = sr.ReadLine()) != null)
                {
                    string trimmedLine = currentLine.Trim();
                    if (!readingParts)
                    {
                        if (trimmedLine.StartsWith("#MODCONTROLVERSION="))
                        {
                            modcontrolVersion = trimmedLine.Substring(currentLine.IndexOf("=") + 1);
                            if (modcontrolVersion == Common.MODCONTROL_VERSION)
                            {
                                //Mod control file is up to date.
                                return;
                            }
                        }
                        else
                        {
                            sb.AppendLine(currentLine);
                        }
                        if (trimmedLine == "!partslist")
                        {
                            readingParts = true;
                        }
                    }
                    else
                    {
                        if (trimmedLine.StartsWith("#") || trimmedLine == string.Empty)
                        {
                            sb.AppendLine(currentLine);
                            continue;
                        }
                        //This is an edge case, but it's still possible if someone moves something manually.
                        if (trimmedLine.StartsWith("!"))
                        {
                            if (!partsPrinted)
                            {
                                partsPrinted = true;
                                foreach (string stockPart in stockParts)
                                {
                                    sb.AppendLine(stockPart);
                                }
                                foreach (string modPart in modParts)
                                {
                                    sb.AppendLine(modPart);
                                }
                            }
                            readingParts = false;
                            sb.AppendLine(currentLine);
                            continue;
                        }
                        if (!stockParts.Contains(currentLine))
                        {
                            modParts.Add(currentLine);
                        }
                    }
                }
            }
            if (!partsPrinted)
            {
                partsPrinted = true;
                foreach (string stockPart in stockParts)
                {
                    sb.AppendLine(stockPart);
                }
                foreach (string modPart in modParts)
                {
                    sb.AppendLine(modPart);
                }
            }
            File.WriteAllText(Server.modFile + ".new", sb.ToString());
            File.Copy(Server.modFile + ".new", Server.modFile, true);
            File.Delete(Server.modFile + ".new");
            DarkLog.Debug("Added " + Common.MODCONTROL_VERSION + " parts to modcontrol.txt");
        }
コード例 #15
0
 private static void StopMeshServer()
 {
     DarkLog.Debug("Stopping mesh server");
     meshServer.Shutdown();
     meshServerThread = null;
 }
コード例 #16
0
        public void Load()
        {
            if (Settings.settingsStore.modpackMode == DarkMultiPlayerCommon.ModpackMode.GAMEDATA)
            {
                DarkLog.Debug("Loading GameData mod list");
                if (File.Exists(modpackServerCacheObjects))
                {
                    File.Delete(modpackServerCacheObjects);
                }
                hashCount = 0;
                modpackData.Clear();
                objectData.Clear();
                string[] modFiles = Directory.GetFiles(modpackPath, "*", SearchOption.AllDirectories);
                foreach (string filePath in modFiles)
                {
                    hashCount++;
                    if (!filePath.ToLower().StartsWith(modpackPath.ToLower(), StringComparison.Ordinal))
                    {
                        DarkLog.Error("Not adding file that is in GameData, symlinks are not supported.");
                        DarkLog.Error("File was: " + filePath);
                        continue;
                    }
                    string trimmedPath = filePath.Substring(modpackPath.Length + 1).Replace('\\', '/');
                    bool   skipFile    = false;
                    foreach (string excludePath in excludeList)
                    {
                        if (trimmedPath.ToLower().StartsWith(excludePath, StringComparison.Ordinal))
                        {
                            skipFile = true;
                        }
                    }
                    foreach (string excludePath in containsExcludeList)
                    {
                        if (trimmedPath.ToLower().Contains(excludePath))
                        {
                            skipFile = true;
                        }
                    }
                    if (skipFile)
                    {
                        continue;
                    }
                    string sha256sum = Common.CalculateSHA256Hash(filePath);

                    if (!modpackData.ContainsKey(trimmedPath))
                    {
                        if (DateTime.UtcNow.Ticks > nextHashTime)
                        {
                            nextHashTime = DateTime.UtcNow.Ticks + TimeSpan.TicksPerSecond;
                            DarkLog.Debug("Hashing: " + hashCount + "/" + modFiles.Length);
                        }
                        modpackData.Add(trimmedPath, sha256sum);
                    }
                    //Need to check because we may have a duplicate file in GameData
                    if (!objectData.ContainsKey(sha256sum))
                    {
                        objectData.Add(sha256sum, trimmedPath);
                    }
                }
                DarkLog.Debug("Hashed " + modFiles.Length + " files");
                using (StreamWriter sw = new StreamWriter(modpackServerCacheObjects))
                {
                    foreach (KeyValuePair <string, string> kvp in modpackData)
                    {
                        sw.WriteLine("{0}={1}", kvp.Key, kvp.Value);
                    }
                }
            }
        }