Exemplo n.º 1
0
        public static void SendAllPlayerColors(ClientObject client)
        {
            Dictionary <string, float[]> sendColors = new Dictionary <string, float[]>();

            foreach (ClientObject otherClient in ClientHandler.GetClients())
            {
                if (otherClient.authenticated && otherClient.playerColor != null)
                {
                    if (otherClient != client)
                    {
                        sendColors[otherClient.playerName] = otherClient.playerColor;
                    }
                }
            }
            ServerMessage newMessage = new ServerMessage();

            newMessage.type = ServerMessageType.PLAYER_COLOR;
            using (MessageWriter mw = new MessageWriter())
            {
                mw.Write <int>((int)PlayerColorMessageType.LIST);
                mw.Write <int>(sendColors.Count);
                foreach (KeyValuePair <string, float[]> kvp in sendColors)
                {
                    mw.Write <string>(kvp.Key);
                    mw.Write <float[]>(kvp.Value);
                }
                newMessage.data = mw.GetMessageBytes();
            }
            ClientHandler.SendToClient(client, newMessage, true);
        }
Exemplo n.º 2
0
        private static void HandleReportRate(ClientObject client, float newSubspaceRate)
        {
            int reportedSubspace = client.subspace;

            client.subspaceRate = newSubspaceRate;
            //Get minimum rate
            foreach (ClientObject otherClient in ClientHandler.GetClients())
            {
                if (otherClient.authenticated && otherClient.subspace == reportedSubspace)
                {
                    if (otherClient.subspaceRate < newSubspaceRate)
                    {
                        newSubspaceRate = otherClient.subspaceRate;
                    }
                }
            }
            //Bound the rate
            if (newSubspaceRate < 0.3f)
            {
                newSubspaceRate = 0.3f;
            }
            if (newSubspaceRate > 1f)
            {
                newSubspaceRate = 1f;
            }
            //Relock the subspace if the rate is more than 3% out of the average
            if (Math.Abs(subspaces[reportedSubspace].subspaceSpeed - newSubspaceRate) > 0.03f)
            {
                //Update the subspace's epoch to now, so we have a new time to lock from.
                UpdateSubspace(reportedSubspace);
                //Change the subspace speed and report it to the clients
                subspaces[reportedSubspace].subspaceSpeed = newSubspaceRate;
                ServerMessage relockMessage = new ServerMessage();
                relockMessage.type = ServerMessageType.WARP_CONTROL;
                using (MessageWriter mw = new MessageWriter())
                {
                    mw.Write <int>((int)WarpMessageType.RELOCK_SUBSPACE);
                    mw.Write <int>(reportedSubspace);
                    mw.Write <long>(subspaces[reportedSubspace].serverClock);
                    mw.Write <double>(subspaces[reportedSubspace].planetTime);
                    mw.Write <float>(subspaces[reportedSubspace].subspaceSpeed);
                    relockMessage.data = mw.GetMessageBytes();
                }
                ClientHandler.SendToAll(null, relockMessage, true);
                //Save to disk
                SaveLatestSubspace();
            }
            //Tell other players about the reported rate
            ServerMessage reportMessage = new ServerMessage();

            reportMessage.type = ServerMessageType.WARP_CONTROL;
            using (MessageWriter mw = new MessageWriter())
            {
                mw.Write <int>((int)WarpMessageType.REPORT_RATE);
                mw.Write <string>(client.playerName);
                mw.Write <float>(client.subspaceRate);
                reportMessage.data = mw.GetMessageBytes();
            }
            ClientHandler.SendToAll(client, reportMessage, true);
        }
Exemplo n.º 3
0
        public static void SendSetSubspaceToAll(int subspace)
        {
            DarkLog.Debug("Sending everyone to subspace " + subspace);
            ServerMessage newMessage = new ServerMessage();

            newMessage.type = ServerMessageType.SET_SUBSPACE;
            using (MessageWriter mw = new MessageWriter())
            {
                mw.Write <int>(subspace);
                newMessage.data = mw.GetMessageBytes();
            }
            ClientHandler.SendToAll(null, newMessage, true);
            //Tell everyone else they changed
            foreach (ClientObject otherClient in ClientHandler.GetClients())
            {
                if (otherClient.authenticated)
                {
                    ServerMessage changeMessage = new ServerMessage();
                    changeMessage.type = ServerMessageType.WARP_CONTROL;
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)WarpMessageType.CHANGE_SUBSPACE);
                        mw.Write <string>(otherClient.playerName);
                        mw.Write <int>(subspace);
                        changeMessage.data = mw.GetMessageBytes();
                    }
                    ClientHandler.SendToAll(otherClient, changeMessage, true);
                }
            }
        }
Exemplo n.º 4
0
        public static void SendSetSubspace(ClientObject client)
        {
            if (!Settings.settingsStore.keepTickingWhileOffline && ClientHandler.GetClients().Length == 1)
            {
                DarkLog.Debug("Reverting server time to last player connection");
                long currentTime = DateTime.UtcNow.Ticks;
                foreach (KeyValuePair <int, Subspace> subspace in subspaces)
                {
                    subspace.Value.serverClock   = currentTime;
                    subspace.Value.subspaceSpeed = 1f;
                }
                SaveLatestSubspace();
            }
            int targetSubspace = -1;

            if (Settings.settingsStore.sendPlayerToLatestSubspace || !offlinePlayerSubspaces.ContainsKey(client.playerName))
            {
                targetSubspace = GetLatestSubspace();
            }
            else
            {
                DarkLog.Debug("Sending " + client.playerName + " to the previous subspace " + targetSubspace);
                targetSubspace = offlinePlayerSubspaces[client.playerName];
            }
            SendSetSubspace(client, targetSubspace);
        }
Exemplo n.º 5
0
        public void TestGetClientsReturnTwoClients()
        {
            ClientHandler _sut   = new ClientHandler();
            int           actual = _sut.GetClients(true).Count;

            Assert.AreEqual(2, actual);
        }
Exemplo n.º 6
0
        public void TestGetClientsReturnListOfClientM()
        {
            ClientHandler _sut     = new ClientHandler();
            Type          expected = typeof(ClientM);
            Type          actual   = _sut.GetClients(true)[0].GetType();

            Assert.AreEqual(expected, actual);
        }
Exemplo n.º 7
0
 public static void SendConsoleMessageToAdmins(string message)
 {
     foreach (ClientObject client in ClientHandler.GetClients())
     {
         if (client.authenticated && DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName))
         {
             SendConsoleMessageToClient(client, message);
         }
     }
 }
Exemplo n.º 8
0
 public static void SendConnectionEndToAll(string reason)
 {
     foreach (ClientObject client in ClientHandler.GetClients())
     {
         if (client.authenticated)
         {
             SendConnectionEnd(client, reason);
         }
     }
 }
Exemplo n.º 9
0
 public static void SendSetSubspaceToAll(int subspace)
 {
     DarkLog.Debug("Sending everyone to subspace " + subspace);
     foreach (ClientObject otherClient in ClientHandler.GetClients())
     {
         if (otherClient.authenticated)
         {
             SendSetSubspace(otherClient, subspace);
         }
     }
 }
Exemplo n.º 10
0
        private static void HandleLowestRateChange(ClientObject client)
        {
            string         newWarpMaster = null;
            PlayerWarpRate lowestRate    = null;

            if (warpMaster != null && warpList.ContainsKey(warpMaster))
            {
                newWarpMaster = warpMaster;
                lowestRate    = warpList[warpMaster];
            }
            else
            {
                newWarpMaster = client.playerName;
                lowestRate    = warpList[client.playerName];
            }

            foreach (ClientObject testClient in ClientHandler.GetClients())
            {
                if (!warpList.ContainsKey(testClient.playerName))
                {
                    newWarpMaster = null;
                    break;
                }

                PlayerWarpRate pwr = warpList[testClient.playerName];

                if (pwr.rateIndex == 0)
                {
                    newWarpMaster = null;
                    break;
                }
                if (pwr.isPhysWarp != lowestRate.isPhysWarp)
                {
                    newWarpMaster = null;
                    break;
                }
                if (pwr.rateIndex < lowestRate.rateIndex)
                {
                    newWarpMaster = testClient.playerName;
                    lowestRate    = pwr;
                }
            }

            if (newWarpMaster != warpMaster)
            {
                //No expire time
                SendSetController(newWarpMaster, long.MinValue);
                warpMaster = newWarpMaster;
            }
        }
Exemplo n.º 11
0
 public static void SendAllReportedSkewRates(ClientObject client)
 {
     foreach (ClientObject otherClient in ClientHandler.GetClients())
     {
         if (otherClient.authenticated)
         {
             if (otherClient != client)
             {
                 ServerMessage newMessage = new ServerMessage();
                 newMessage.type = ServerMessageType.WARP_CONTROL;
                 using (MessageWriter mw = new MessageWriter())
                 {
                     mw.Write <int>((int)WarpMessageType.REPORT_RATE);
                     mw.Write <string>(otherClient.playerName);
                     mw.Write <float>(otherClient.subspaceRate);
                     newMessage.data = mw.GetMessageBytes();
                 }
                 ClientHandler.SendToClient(client, newMessage, true);
             }
         }
     }
 }
Exemplo n.º 12
0
 public static void SendAllPlayerStatus(ClientObject client)
 {
     foreach (ClientObject otherClient in ClientHandler.GetClients())
     {
         if (otherClient.authenticated)
         {
             if (otherClient != client)
             {
                 ServerMessage newMessage = new ServerMessage();
                 newMessage.type = ServerMessageType.PLAYER_STATUS;
                 using (MessageWriter mw = new MessageWriter())
                 {
                     mw.Write <string>(otherClient.playerName);
                     mw.Write <string>(otherClient.playerStatus.vesselText);
                     mw.Write <string>(otherClient.playerStatus.statusText);
                     newMessage.data = mw.GetMessageBytes();
                 }
                 ClientHandler.SendToClient(client, newMessage, true);
             }
         }
     }
 }
Exemplo n.º 13
0
 public static void SendAllSubspaces(ClientObject client)
 {
     //Send all the locks.
     foreach (KeyValuePair <int, Subspace> subspace in subspaces)
     {
         ServerMessage newMessage = new ServerMessage();
         newMessage.type = ServerMessageType.WARP_CONTROL;
         using (MessageWriter mw = new MessageWriter())
         {
             mw.Write <int>((int)WarpMessageType.NEW_SUBSPACE);
             mw.Write <string>("");
             mw.Write <int>(subspace.Key);
             mw.Write <long>(subspace.Value.serverClock);
             mw.Write <double>(subspace.Value.planetTime);
             mw.Write <float>(subspace.Value.subspaceSpeed);
             newMessage.data = mw.GetMessageBytes();
         }
         ClientHandler.SendToClient(client, newMessage, true);
     }
     //Tell the player "when" everyone is.
     foreach (ClientObject otherClient in ClientHandler.GetClients())
     {
         if (otherClient.authenticated && (otherClient.playerName != client.playerName))
         {
             ServerMessage newMessage = new ServerMessage();
             newMessage.type = ServerMessageType.WARP_CONTROL;
             using (MessageWriter mw = new MessageWriter())
             {
                 mw.Write <int>((int)WarpMessageType.CHANGE_SUBSPACE);
                 mw.Write <string>(otherClient.playerName);
                 mw.Write <int>(otherClient.subspace);
                 newMessage.data = mw.GetMessageBytes();
             }
             ClientHandler.SendToClient(client, newMessage, true);
         }
     }
 }
Exemplo n.º 14
0
        public static void SendSetSubspace(ClientObject client)
        {
            if (!Settings.settingsStore.keepTickingWhileOffline && ClientHandler.GetClients().Length == 1)
            {
                DarkLog.Debug("Reverting server time to last player connection");
                long currentTime = DateTime.UtcNow.Ticks;
                foreach (KeyValuePair <int, Subspace> subspace in subspaces)
                {
                    subspace.Value.serverClock   = currentTime;
                    subspace.Value.subspaceSpeed = 1f;
                    SaveLatestSubspace();
                }
            }
            int targetSubspace = -1;

            if (Settings.settingsStore.sendPlayerToLatestSubspace || !playerSubspace.ContainsKey(client.playerName))
            {
                DarkLog.Debug("Sending " + client.playerName + " to the latest subspace " + targetSubspace);
                targetSubspace = GetLatestSubspace();
            }
            else
            {
                DarkLog.Debug("Sending " + client.playerName + " to the previous subspace " + targetSubspace);
                targetSubspace = playerSubspace[client.playerName];
            }
            client.subspace = targetSubspace;
            ServerMessage newMessage = new ServerMessage();

            newMessage.type = ServerMessageType.SET_SUBSPACE;
            using (MessageWriter mw = new MessageWriter())
            {
                mw.Write <int>(targetSubspace);
                newMessage.data = mw.GetMessageBytes();
            }
            ClientHandler.SendToClient(client, newMessage, true);
        }
Exemplo n.º 15
0
        public static void HandleWarpControl(ClientObject client, byte[] messageData)
        {
            ServerMessage newMessage = new ServerMessage();

            newMessage.type = ServerMessageType.WARP_CONTROL;
            newMessage.data = messageData;
            using (MessageReader mr = new MessageReader(messageData))
            {
                WarpMessageType warpType   = (WarpMessageType)mr.Read <int>();
                string          fromPlayer = mr.Read <string>();
                if (fromPlayer == client.playerName)
                {
                    if (warpType == WarpMessageType.NEW_SUBSPACE)
                    {
                        int newSubspaceID = mr.Read <int>();
                        if (subspaces.ContainsKey(newSubspaceID))
                        {
                            DarkLog.Debug("Kicked for trying to create an existing subspace");
                            Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for trying to create an existing subspace");
                            return;
                        }
                        else
                        {
                            Subspace newSubspace = new Subspace();
                            newSubspace.serverClock   = mr.Read <long>();
                            newSubspace.planetTime    = mr.Read <double>();
                            newSubspace.subspaceSpeed = mr.Read <float>();
                            subspaces.Add(newSubspaceID, newSubspace);
                            client.subspace = newSubspaceID;
                            SaveLatestSubspace();
                        }
                    }
                    if (warpType == WarpMessageType.CHANGE_SUBSPACE)
                    {
                        client.subspace = mr.Read <int>();
                    }
                    if (warpType == WarpMessageType.REPORT_RATE)
                    {
                        int reportedSubspace = mr.Read <int>();
                        if (client.subspace != reportedSubspace)
                        {
                            DarkLog.Debug("Warning, setting client " + client.playerName + " to subspace " + client.subspace);
                            client.subspace = reportedSubspace;
                        }
                        float newSubspaceRate = mr.Read <float>();
                        client.subspaceRate = newSubspaceRate;
                        foreach (ClientObject otherClient in ClientHandler.GetClients())
                        {
                            if (otherClient.authenticated && otherClient.subspace == reportedSubspace)
                            {
                                if (newSubspaceRate > otherClient.subspaceRate)
                                {
                                    newSubspaceRate = otherClient.subspaceRate;
                                }
                            }
                        }
                        if (newSubspaceRate < 0.3f)
                        {
                            newSubspaceRate = 0.3f;
                        }
                        if (newSubspaceRate > 1f)
                        {
                            newSubspaceRate = 1f;
                        }
                        //Relock the subspace if the rate is more than 3% out of the average
                        if (Math.Abs(subspaces[reportedSubspace].subspaceSpeed - newSubspaceRate) > 0.03f)
                        {
                            UpdateSubspace(reportedSubspace);
                            subspaces[reportedSubspace].subspaceSpeed = newSubspaceRate;
                            ServerMessage relockMessage = new ServerMessage();
                            relockMessage.type = ServerMessageType.WARP_CONTROL;
                            using (MessageWriter mw = new MessageWriter())
                            {
                                mw.Write <int>((int)WarpMessageType.RELOCK_SUBSPACE);
                                mw.Write <string>(Settings.settingsStore.consoleIdentifier);
                                mw.Write <int>(reportedSubspace);
                                mw.Write <long>(subspaces[reportedSubspace].serverClock);
                                mw.Write <double>(subspaces[reportedSubspace].planetTime);
                                mw.Write <float>(subspaces[reportedSubspace].subspaceSpeed);
                                relockMessage.data = mw.GetMessageBytes();
                            }
                            SaveLatestSubspace();
                            //DarkLog.Debug("Subspace " + client.subspace + " locked to " + newSubspaceRate + "x speed.");
                            ClientHandler.SendToClient(client, relockMessage, true);
                            ClientHandler.SendToAll(client, relockMessage, true);
                        }
                    }
                }
                else
                {
                    DarkLog.Debug(client.playerName + " tried to send an update for " + fromPlayer + ", kicking.");
                    Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending an update for another player");
                    return;
                }
            }
            ClientHandler.SendToAll(client, newMessage, true);
        }
Exemplo n.º 16
0
        public static void HandleHandshakeResponse(ClientObject client, byte[] messageData)
        {
            int    protocolVersion;
            string playerName = "";
            string playerPublicKey;

            byte[] playerChallangeSignature;
            string clientVersion = "";
            string reason        = "";
            Regex  regex         = new Regex(@"[\""<>|$]"); // Regex to detect quotation marks, and other illegal characters
            //0 - Success
            HandshakeReply handshakeReponse = HandshakeReply.HANDSHOOK_SUCCESSFULLY;

            try
            {
                using (MessageReader mr = new MessageReader(messageData))
                {
                    protocolVersion          = mr.Read <int>();
                    playerName               = mr.Read <string>();
                    playerPublicKey          = mr.Read <string>();
                    playerChallangeSignature = mr.Read <byte[]>();
                    clientVersion            = mr.Read <string>();
                    try
                    {
                        client.compressionEnabled = mr.Read <bool>();
                    }
                    catch
                    {
                        //This is safe to ignore. We want to tell people about version mismatches still.
                        client.compressionEnabled = false;
                    }
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Error in HANDSHAKE_REQUEST from " + client.playerName + ": " + e);
                SendHandshakeReply(client, HandshakeReply.MALFORMED_HANDSHAKE, "Malformed handshake");
                return;
            }
            if (regex.IsMatch(playerName))
            {
                // Invalid username
                handshakeReponse = HandshakeReply.INVALID_PLAYERNAME;
                reason           = "Invalid username";
            }
            if (playerName.Contains("/") || playerName.Contains(@"\") || playerName.Contains("\n") || playerName.Contains("\r"))
            {
                handshakeReponse = HandshakeReply.INVALID_PLAYERNAME;
                reason           = "Invalid username";
            }
            if (protocolVersion != Common.PROTOCOL_VERSION)
            {
                //Protocol mismatch
                handshakeReponse = HandshakeReply.PROTOCOL_MISMATCH;
                reason           = "Protocol mismatch";
            }
            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                //Check client isn't already connected
                ClientObject testClient = ClientHandler.GetClientByName(playerName);
                if (testClient != null)
                {
                    Messages.Heartbeat.Send(testClient);
                    Thread.Sleep(1000);
                }
                if (ClientHandler.ClientConnected(testClient))
                {
                    handshakeReponse = HandshakeReply.ALREADY_CONNECTED;
                    reason           = "Client already connected";
                }
            }
            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                bool reserveKick = false;
                //Check the client isn't using a reserved name
                if (playerName == "Initial")
                {
                    reserveKick = true;
                }
                if (playerName == Settings.settingsStore.consoleIdentifier)
                {
                    reserveKick = true;
                }
                if (reserveKick)
                {
                    handshakeReponse = HandshakeReply.RESERVED_NAME;
                    reason           = "Kicked for using a reserved name";
                }
            }
            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                //Check the client matches any database entry
                string storedPlayerFile      = Path.Combine(Server.universeDirectory, "Players", playerName + ".txt");
                string storedPlayerPublicKey = "";
                if (File.Exists(storedPlayerFile))
                {
                    storedPlayerPublicKey = File.ReadAllText(storedPlayerFile);
                    if (playerPublicKey != storedPlayerPublicKey)
                    {
                        handshakeReponse = HandshakeReply.INVALID_KEY;
                        reason           = "Invalid key for user";
                    }
                    else
                    {
                        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024))
                        {
                            rsa.PersistKeyInCsp = false;
                            rsa.FromXmlString(playerPublicKey);
                            bool result = rsa.VerifyData(client.challange, CryptoConfig.CreateFromName("SHA256"), playerChallangeSignature);
                            if (!result)
                            {
                                handshakeReponse = HandshakeReply.INVALID_KEY;
                                reason           = "Public/private key mismatch";
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        File.WriteAllText(storedPlayerFile, playerPublicKey);
                        DarkLog.Debug("Client " + playerName + " registered!");
                    }
                    catch
                    {
                        handshakeReponse = HandshakeReply.INVALID_PLAYERNAME;
                        reason           = "Invalid username";
                    }
                }
            }

            client.playerName    = playerName;
            client.publicKey     = playerPublicKey;
            client.clientVersion = clientVersion;

            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                if (BanSystem.fetch.IsPlayerNameBanned(client.playerName) || BanSystem.fetch.IsIPBanned(client.ipAddress) || BanSystem.fetch.IsPublicKeyBanned(client.publicKey))
                {
                    handshakeReponse = HandshakeReply.PLAYER_BANNED;
                    reason           = "You were banned from the server!";
                }
            }

            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                if (ClientHandler.GetActiveClientCount() >= Settings.settingsStore.maxPlayers)
                {
                    handshakeReponse = HandshakeReply.SERVER_FULL;
                    reason           = "Server is full";
                }
            }

            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                if (Settings.settingsStore.whitelisted && !WhitelistSystem.fetch.IsWhitelisted(client.playerName))
                {
                    handshakeReponse = HandshakeReply.NOT_WHITELISTED;
                    reason           = "You are not on the whitelist";
                }
            }

            if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY)
            {
                client.authenticated = true;
                string devClientVersion = "";
                DMPPluginHandler.FireOnClientAuthenticated(client);

                if (client.clientVersion.Length == 40)
                {
                    devClientVersion = client.clientVersion.Substring(0, 7);
                }
                else
                {
                    devClientVersion = client.clientVersion;
                }
                DarkLog.Normal("Client " + playerName + " handshook successfully, version: " + devClientVersion);

                if (!Directory.Exists(Path.Combine(Server.universeDirectory, "Scenarios", client.playerName)))
                {
                    Directory.CreateDirectory(Path.Combine(Server.universeDirectory, "Scenarios", client.playerName));
                    foreach (string file in Directory.GetFiles(Path.Combine(Server.universeDirectory, "Scenarios", "Initial")))
                    {
                        File.Copy(file, Path.Combine(Server.universeDirectory, "Scenarios", playerName, Path.GetFileName(file)));
                    }
                }
                SendHandshakeReply(client, handshakeReponse, "success");
                Server.playerCount = ClientHandler.GetActiveClientCount();
                Server.players     = ClientHandler.GetActivePlayerNames();
                DarkLog.Debug("Online players is now: " + Server.playerCount + ", connected: " + ClientHandler.GetClients().Length);
            }
            else
            {
                DarkLog.Normal("Client " + playerName + " failed to handshake: " + reason);
                SendHandshakeReply(client, handshakeReponse, reason);
            }
        }