示例#1
0
        public void StatusCallbackFunction(ref StatusInfo info, IntPtr context)
        {
            switch (info.connectionInfo.state)
            {
            case ConnectionState.None:
                break;

            case ConnectionState.Connecting: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                //Console.WriteLine("connecting on file server");

                if (mainServer.bannedIPs.Contains(info.connectionInfo.address.GetIP()))
                {
                    //Console.WriteLine("Ban player attempted to connect to the server, IP: {0}", info.connectionInfo.address.GetIP());
                    server.CloseConnection(info.connection);
                }
                else
                {
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                }
            } break;

            case ConnectionState.Connected: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                if (mainServer.motdBytes != null)
                {
                    server.SendMessageToConnection(info.connection, mainServer.motdBytes);
                }

                //Console.WriteLine("connected on file server");
            } break;

            case ConnectionState.ClosedByPeer:
            case ConnectionState.ProblemDetectedLocally:
                mainServer.RemovePlayer(info.connection);
                break;
            }
        }
示例#2
0
    void InitCallbacks()
    {
        status = (info, context) => {
            switch (info.connectionInfo.state)
            {
            case ConnectionState.None:
                break;

            case ConnectionState.Connecting:
                server.AcceptConnection(info.connection);
                break;

            case ConnectionState.Connected:
                Debug.Log("Client connected - ID: " + info.connection + ", IP: " + info.connectionInfo.address.GetIP());
                break;

            case ConnectionState.ClosedByPeer:
                server.CloseConnection(info.connection);
                Debug.Log("Client disconnected - ID: " + info.connection + ", IP: " + info.connectionInfo.address.GetIP());
                break;
            }
        };
    }
示例#3
0
        public static void ServerLoop()
        {
            Library.Initialize();

            server = new NetworkingSockets();
            Address address = new Address();

            NetworkingUtils utils = new NetworkingUtils();

            utils.SetDebugCallback(DebugType.Important, (type, message) => {
                Console.WriteLine("Valve Debug - Type: {0}, Message: {1}", type, message);
            });

            unsafe {
                int sendRateMin    = 5 * 1024 * 1024;
                int sendRateMax    = MAX_UPLOAD;
                int sendBufferSize = MAX_BUFFER;
                utils.SetConfigurationValue(ConfigurationValue.SendRateMin, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendRateMin));
                utils.SetConfigurationValue(ConfigurationValue.SendRateMax, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendRateMax));
                utils.SetConfigurationValue(ConfigurationValue.SendBufferSize, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendBufferSize));
            }

            address.SetAddress("::0", port);

            uint listenSocket = server.CreateListenSocket(ref address);
            uint pollGroup    = server.CreatePollGroup();

            Console.WriteLine($"Server {SERVER_NAME} started Listening on port {port} for maximum of {MAX_PLAYERS} players\nEnforcing maps is {ENFORCE_MAPS}");

            StartAnnouncing();

            StatusCallback status = (ref StatusInfo info, IntPtr context) => {
                switch (info.connectionInfo.state)
                {
                case ConnectionState.None:
                    break;

                case ConnectionState.Connecting:
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                    break;

                case ConnectionState.Connected:
                    Console.WriteLine("Client connected - IP: " + info.connectionInfo.address.GetIP());

                    bool openSlot = false;

                    for (byte i = 0; i < MAX_PLAYERS; i++)
                    {
                        if (players[i] == null)
                        {
                            players[i] = new Player(i, info.connection, info.connectionInfo.address);

                            byte[] versionNumber  = ASCIIEncoding.ASCII.GetBytes(VERSION_NUMBER);
                            byte[] versionMessage = new byte[versionNumber.Length + 1];

                            versionMessage[0] = (byte)OpCode.VersionNumber;
                            Array.Copy(versionNumber, 0, versionMessage, 1, versionNumber.Length);
                            server.SendMessageToConnection(players[i].connection, versionMessage, SendFlags.Reliable | SendFlags.NoNagle);

                            if (ENFORCE_MAPS)
                            {
                                server.SendMessageToConnection(players[i].connection, mapListBytes, SendFlags.Reliable);
                                server.SendMessageToConnection(players[i].connection, GetCurrentMapHashMessage(), SendFlags.Reliable);
                            }

                            foreach (Player player in players)
                            {
                                if (player != null && player != players[i])
                                {
                                    server.SendMessageToConnection(players[i].connection, new byte[] { (byte)OpCode.Connect, player.playerID }, SendFlags.Reliable);
                                    server.SendMessageToConnection(player.connection, new byte[] { (byte)OpCode.Connect, i }, SendFlags.Reliable);

                                    if (player.usernameMessage != null)
                                    {
                                        server.SendMessageToConnection(players[i].connection, player.usernameMessage, SendFlags.Reliable);
                                    }
                                    if (player.allGearUploaded)
                                    {
                                        foreach (KeyValuePair <string, byte[]> value in player.gear)
                                        {
                                            server.SendMessageToConnection(players[i].connection, value.Value, SendFlags.Reliable);
                                        }
                                    }
                                }
                            }

                            server.FlushMessagesOnConnection(players[i].connection);

                            openSlot = true;
                            break;
                        }
                    }

                    if (!openSlot)
                    {
                        server.CloseConnection(info.connection);
                    }
                    break;

                case ConnectionState.ClosedByPeer:
                    RemovePlayer(info.connection);
                    break;
                }
            };

#if VALVESOCKETS_SPAN
            MessageCallback messageCallback = (in NetworkingMessage netMessage) => {
                byte[] messageData = new byte[netMessage.length];
                netMessage.CopyTo(messageData);

                Player sendingPlayer = null;
                foreach (Player player in players)
                {
                    if (player != null && player.connection == netMessage.connection)
                    {
                        sendingPlayer = player;
                        break;
                    }
                }

                if (sendingPlayer != null)
                {
                    ProcessMessage(messageData, sendingPlayer.playerID, server);
                }
            };
#else
            const int maxMessages = 256;

            NetworkingMessage[] netMessages = new NetworkingMessage[maxMessages];
#endif
            while (RUNNING)
            {
                server.DispatchCallback(status);

#if VALVESOCKETS_SPAN
                server.ReceiveMessagesOnPollGroup(pollGroup, messageCallback, 256);
#else
                int netMessagesCount = server.ReceiveMessagesOnConnection(listenSocket, netMessages, maxMessages);

                if (netMessagesCount > 0)
                {
                    for (int i = 0; i < netMessagesCount; i++)
                    {
                        ref NetworkingMessage netMessage = ref netMessages[i];

                        byte[] messageData = new byte[netMessage.length];
                        netMessage.CopyTo(messageData);

                        Player sendingPlayer = null;
                        foreach (Player player in players)
                        {
                            if (player != null && player.connection == netMessage.connection)
                            {
                                sendingPlayer = player;
                                break;
                            }
                        }

                        //Console.WriteLine("Recieved packet from connection {0}, sending player null: {1}", netMessage.connection, sendingPlayer == null);

                        if (sendingPlayer != null)
                        {
                            ProcessMessage(messageData, sendingPlayer.playerID, server);
                        }

                        netMessage.Destroy();
                    }
                }
#endif

                mapVotes.Clear();
                total_players = 0;
                foreach (Player player in players)
                {
                    if (player != null)
                    {
                        total_players++;

                        if (player.timeoutWatch.ElapsedMilliseconds > 15000)
                        {
                            Console.WriteLine($"{player.playerID} has been timed out for not responding for 15 seconds");

                            RemovePlayer(player.connection, player.playerID, true);
                        }

                        if (!mapVotes.ContainsKey(player.currentVote))
                        {
                            mapVotes.Add(player.currentVote, 1);
                        }
                        else
                        {
                            mapVotes[player.currentVote]++;
                        }
                    }
                }

                // Handle map voting and map enforcement
                if (ENFORCE_MAPS)
                {
                    if (total_players == 0)
                    {
                        currentMapHash = "1";
                    }

                    bool startNewTimer = false;
                    if (mapVotes.ContainsKey("current"))
                    {
                        if (mapVotes["current"] < (int)Math.Ceiling((float)total_players / 2))
                        {
                            if (!mapVoteTimer.IsRunning)
                            {
                                startNewTimer = true;
                            }
                        }
                    }
                    else if (!mapVoteTimer.IsRunning && total_players > 0)
                    {
                        startNewTimer = true;
                    }

                    if (startNewTimer)
                    {
                        mapVoteTimer.Restart();

                        byte[] mapVoteMsg = new byte[] { (byte)OpCode.MapVote, 0, 0 };

                        foreach (Player player in players)
                        {
                            if (player != null)
                            {
                                server.SendMessageToConnection(player.connection, mapVoteMsg, SendFlags.Reliable);
                            }
                        }
                    }

                    if (mapVoteTimer.IsRunning && mapVoteTimer.ElapsedMilliseconds > 30000 && total_players > 0)
                    {
                        mapVoteTimer.Stop();

                        Tuple <string, int> mostVoted = null;

                        foreach (var item in mapVotes)
                        {
                            if (!item.Key.Equals("current"))
                            {
                                if (mostVoted == null || mostVoted.Item2 < item.Value)
                                {
                                    mostVoted = Tuple.Create <string, int>(item.Key, item.Value);
                                }
                            }
                        }

                        currentMapHash = mostVoted.Item1;

                        byte[] newMapMessage = GetCurrentMapHashMessage();

                        foreach (Player player in players)
                        {
                            if (player != null)
                            {
                                server.SendMessageToConnection(player.connection, newMapMessage, SendFlags.Reliable);

                                player.currentVote = "current";
                            }
                        }
                    }
                    else if (total_players == 0)
                    {
                        mapVoteTimer.Stop();
                    }
                }
            }
        static void Run(CancellationTokenSource cts)
        {
            ushort            port    = 8080;
            NetworkingSockets server  = new NetworkingSockets();
            Address           address = new Address();

            address.SetAddress("::0", port);

            uint listenSocket = server.CreateListenSocket(ref address);

            StatusCallback status = (info, context) => {
                switch (info.connectionInfo.state)
                {
                case ConnectionState.None:
                    break;

                case ConnectionState.Connecting:
                    server.AcceptConnection(info.connection);
                    break;

                case ConnectionState.Connected:
                    Console.WriteLine("Client connected - ID: " + info.connection + ", IP: " + info.connectionInfo.address.GetIP());
                    break;

                case ConnectionState.ClosedByPeer:
                    server.CloseConnection(info.connection);
                    Console.WriteLine("Client disconnected - ID: " + info.connection + ", IP: " + info.connectionInfo.address.GetIP());
                    break;
                }
            };

#if VALVESOCKETS_SPAN
            MessageCallback message = (in NetworkingMessage netMessage) => {
                Console.WriteLine("Message received from - ID: " + netMessage.connection + ", Channel ID: " + netMessage.channel + ", Data length: " + netMessage.length);
            };
#else
            const int maxMessages = 20;

            NetworkingMessage[] netMessages = new NetworkingMessage[maxMessages];
#endif

            while (!cts.IsCancellationRequested)
            {
                server.DispatchCallback(status);

#if VALVESOCKETS_SPAN
                server.ReceiveMessagesOnListenSocket(listenSocket, message, 20);
#else
                int netMessagesCount = server.ReceiveMessagesOnListenSocket(listenSocket, netMessages, maxMessages);

                if (netMessagesCount > 0)
                {
                    for (int i = 0; i < netMessagesCount; i++)
                    {
                        ref NetworkingMessage netMessage = ref netMessages[i];

                        Console.WriteLine("Message received from - ID: " + netMessage.connection + ", Channel ID: " + netMessage.channel + ", Data length: " + netMessage.length);

                        netMessage.Destroy();
                    }
                }
#endif

                Thread.Sleep(15);
            }
示例#5
0
        public void StatusCallbackFunction(ref StatusInfo info, IntPtr context)
        {
            switch (info.connectionInfo.state)
            {
            case ConnectionState.None:
                break;

            case ConnectionState.Connecting: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                //Console.WriteLine("connecting on file server");

                if (mainServer.bannedIPs.Contains(info.connectionInfo.address.GetIP()))
                {
                    //Console.WriteLine("Ban player attempted to connect to the server, IP: {0}", info.connectionInfo.address.GetIP());
                    server.CloseConnection(info.connection);
                }
                else
                {
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                }
            } break;

            case ConnectionState.Connected: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                if (mainServer.motdBytes != null)
                {
                    server.SendMessageToConnection(info.connection, mainServer.motdBytes);
                }

                foreach (Player player in mainServer.players)
                {
                    foreach (Plugin plugin in mainServer.loadedPlugins)
                    {
                        if (plugin.hash != "")
                        {
                            byte[] hashBytes   = ASCIIEncoding.ASCII.GetBytes(plugin.hash);
                            byte[] hashMessage = new byte[hashBytes.Length + 2];

                            hashMessage[0] = (byte)OpCode.PluginHash;
                            hashMessage[1] = plugin.pluginID;
                            Array.Copy(hashBytes, 0, hashMessage, 2, hashBytes.Length);

                            server.SendMessageToConnection(player.connection, hashMessage, SendFlags.Reliable);
                        }
                    }
                }

                //Console.WriteLine("connected on file server");
            } break;

            case ConnectionState.ClosedByPeer:
            case ConnectionState.ProblemDetectedLocally:
                mainServer.RemovePlayer(info.connection);
                break;
            }
        }