예제 #1
0
        private NetReceiverChannelBase CreateReceiverChannel(NetMessageType tp)
        {
            m_peer.VerifyNetworkThread();

            // create receiver channel
            NetReceiverChannelBase chan;
            NetDeliveryMethod      method = NetUtility.GetDeliveryMethod(tp);

            switch (method)
            {
            case NetDeliveryMethod.Unreliable:
                chan = new NetUnreliableUnorderedReceiver(this);
                break;

            case NetDeliveryMethod.ReliableOrdered:
                chan = new NetReliableOrderedReceiver(this, NetConstants.ReliableOrderedWindowSize);
                break;

            case NetDeliveryMethod.UnreliableSequenced:
                chan = new NetUnreliableSequencedReceiver(this);
                break;

            case NetDeliveryMethod.ReliableUnordered:
                chan = new NetReliableUnorderedReceiver(this, NetConstants.ReliableOrderedWindowSize);
                break;

            case NetDeliveryMethod.ReliableSequenced:
                chan = new NetReliableSequencedReceiver(this, NetConstants.ReliableSequencedWindowSize);
                break;

            default:
                throw new NetException("Unhandled NetDeliveryMethod!");
            }

            int channelSlot = (int)tp - 1;

            NetException.Assert(m_receiveChannels[channelSlot] == null);
            m_receiveChannels[channelSlot] = chan;

            return(chan);
        }
예제 #2
0
        private static async void UpdateIPsAndStartServices()
        {
            if (_pairingService == null)
            {
                return;
            }

            var hostnames = NetUtility.GetLocalHostNames().Select(h => h.CanonicalName.ToString());

            _pairingService.IPAddresses.Clear();
            _pairingService.IPAddresses.AddRange(hostnames);

            await _httpServer.Start();

            int port = int.Parse(_httpServer.ServiceName);

            _pairingService.Port = port;
            _pairingService.Publish();

            _log.Info("Pairing parameters:\nHostname: {0}\nPort: {1}\nPIN: {2}\nPairing Code: {3}", Hostname, port, PIN, _pairingService.TXTRecordData["Pair"]);
        }
예제 #3
0
        private void LoginButton_OnClicked(Button btn)
        {
            if (string.IsNullOrEmpty(emailTf.GetText()) || string.IsNullOrEmpty(passwordTf.GetText()))
            {
                windowService.Open(new OkWindow(windowService, "Error", "Fields can't be empty"));
                return;
            }

            windowService.Open(new TextWindow("Information", "Login in..."));

            var msg         = zoneClientNetPeer.CreateMessage();
            var messageData = new PlayerLoginMessageData();

            messageData.Email    = emailTf.GetText();
            messageData.Password = passwordTf.GetText();
            messageData.Encode(msg);

            var receiver = new IPEndPoint(NetUtility.Resolve(Constants.Host), Constants.ZoneServerPort);

            zoneClientNetPeer.SendUnconnectedMessage(msg, receiver);
        }
예제 #4
0
        public void init()
        {
            netServer = new NetServer(ServerConfigurator.netPeerConfig);

            serverController = new ServerController(netServer);
            serverController.StartServer();

            netServer.UPnP.ForwardPort(ServerConfigurator.port, "GServer");


            Console.WriteLine("[SA] Server Started and serving.");
            Console.WriteLine("Unique identifier is " + NetUtility.ToHexString(netServer.UniqueIdentifier));

            // in your separate thread
            while (netServer.MessageReceivedEvent.WaitOne()) // this will block until a message arrives
            {
                NetIncomingMessage msg = netServer.ReadMessage();
                sMessageParseManager.parseMessage(msg, this);
                netServer.Recycle(msg);
            }
        }
예제 #5
0
        public void Listen()
        {
            NetDebug.Log("[TCPServer] Listen.");

            IPEndPoint remote = NetUtility.GetIPEndPoint(setting.host, setting.port);

            if (null == remote)
            {
                NetDebug.Log("[TCPServer] ip port can not be null.");
                return;
            }

            socket = new Socket(remote.AddressFamily,
                                SocketType.Stream,
                                ProtocolType.Tcp);
            socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
            socket.Blocking = setting.blocking;
            socket.Bind(remote);
            socket.Listen(setting.backlog);
            AcceptAsync();
        }
 private void CheckOnlineStatus()
 {
     try
     {
         NetUtility.ResolveAsync(serverAddress, delegate(IPAddress adr)
         {
             if (adr == null)
             {
                 SetOnlineStatus(OnlineStatus.OFFLINE);
             }
             else
             {
                 SetOnlineStatus(OnlineStatus.ONLINE);
             }
         });
     }
     catch (Exception)
     {
         SetOnlineStatus(OnlineStatus.OFFLINE);
     }
 }
        private void tbServerAddress_TextChanged(object sender, TextChangedEventArgs e)
        {
            var newAddress = tbServerAddress.Text;

            lblAddressState.Content = "❓";
            try
            {
                if (!ipv4ValidationRegex.IsMatch(newAddress))
                {
                    lblAddressState.Content = "❗";
                    SetOnlineStatus(OnlineStatus.OFFLINE);
                    return;
                }

                SetOnlineStatus(OnlineStatus.CHECKING);
                NetUtility.ResolveAsync(newAddress, (address) =>
                {
                    if (address == null)
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            lblAddressState.Content = "❗";
                            SetOnlineStatus(OnlineStatus.OFFLINE);
                        }));
                        return;
                    }

                    serverAddress = newAddress;
                    GameProperties.Props.SetAndSave(PropertyKey.SERVER_ADDRESS, serverAddress);
                    lblAddressState.Content = "✔";
                    SetOnlineStatus(OnlineStatus.ONLINE);
                });
            }
            catch
            {
                // invalid address
                lblAddressState.Content = "❗";
                SetOnlineStatus(OnlineStatus.OFFLINE);
            }
        }
        // remoteWindowStart is remote expected sequence number; everything below this has arrived properly
        // seqNr is the actual nr received
        internal override void ReceiveAcknowledge(double now, int seqNr)
        {
            if (m_doFlowControl == false)
            {
                // we have no use for acks on this channel since we don't respect the window anyway
                m_connection.m_peer.LogVerbose("SuppressUnreliableUnorderedAcks sender/receiver mismatch!");
                return;
            }

            // late (dupe), on time or early ack?
            int relate = NetUtility.RelativeSequenceNumber(seqNr, m_windowStart);

            if (relate < 0)
            {
                //m_connection.m_peer.LogDebug("Received late/dupe ack for #" + seqNr);
                return; // late/duplicate ack
            }

            if (relate == 0)
            {
                //m_connection.m_peer.LogDebug("Received right-on-time ack for #" + seqNr);

                // ack arrived right on time
                NetException.Assert(seqNr == m_windowStart);

                m_receivedAcks[m_windowStart] = false;
                m_windowStart = (m_windowStart + 1) % NetConstants.NumSequenceNumbers;

                return;
            }

            // Advance window to this position
            m_receivedAcks[seqNr] = true;

            while (m_windowStart != seqNr)
            {
                m_receivedAcks[m_windowStart] = false;
                m_windowStart = (m_windowStart + 1) % NetConstants.NumSequenceNumbers;
            }
        }
예제 #9
0
        public void init()
        {
            NetPeerConfiguration config = new NetPeerConfiguration("GJABD_GAME");

            config.Port         = 14242;
            config.LocalAddress = IPAddress.Any;
            config.EnableUPnP   = true;
            config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);

            //ON PRODUCTION:
            //config.DisableMessageType(NetIncomingMessageType.WarningMessage);

            netServer = new NetServer(config);

            serverController = new ServerController(netServer);
            try
            {
                serverController.StartServer();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            netServer.UPnP.ForwardPort(14242, "GServer");



            Console.WriteLine("[SA] Server Started and serving.");
            Console.WriteLine("Unique identifier is " + NetUtility.ToHexString(netServer.UniqueIdentifier));

            // in your separate thread
            while (netServer.MessageReceivedEvent.WaitOne()) // this will block until a message arrives
            {
                NetIncomingMessage msg = netServer.ReadMessage();
                sMessageParseManager.parseMessage(msg, this);
                netServer.Recycle(msg);
            }
        }
예제 #10
0
        // may be on user thread
        private NetSenderChannelBase CreateSenderChannel(NetMessageType tp)
        {
            NetSenderChannelBase chan;

            lock (m_sendChannels)
            {
                NetDeliveryMethod method = NetUtility.GetDeliveryMethod(tp);
                int sequenceChannel      = (int)tp - (int)method;

                int channelSlot = (int)method - 1 + sequenceChannel;
                if (m_sendChannels[channelSlot] != null)
                {
                    // we were pre-empted by another call to this method
                    chan = m_sendChannels[channelSlot];
                }
                else
                {
                    switch (method)
                    {
                    case NetDeliveryMethod.Unreliable:
                    case NetDeliveryMethod.UnreliableSequenced:
                        chan = new NetUnreliableSenderChannel(this, NetUtility.GetWindowSize(method), method);
                        break;

                    case NetDeliveryMethod.ReliableOrdered:
                        chan = new NetReliableSenderChannel(this, NetUtility.GetWindowSize(method));
                        break;

                    case NetDeliveryMethod.ReliableSequenced:
                    case NetDeliveryMethod.ReliableUnordered:
                    default:
                        chan = new NetReliableSenderChannel(this, NetUtility.GetWindowSize(method));
                        break;
                    }
                    m_sendChannels[channelSlot] = chan;
                }
            }

            return(chan);
        }
예제 #11
0
        private IEnumerator InitMasterEndPoint()
        {
            float tStart;
            float tPass;
            float timeOut = 1.0f;

            while (masterServer == null)
            {
                Ping ping;
                foreach (var ip in masterIPs)
                {
                    tStart = Time.time;
                    tPass  = 0;

                    ping = new Ping(ip);

                    while (!ping.isDone && tPass < timeOut)
                    {
                        yield return(new WaitForSeconds(0.15f));

                        tPass = Time.time - tStart;
                    }

                    if (tPass >= timeOut || ping.time == -1)
                    {
                        Debug.Log("Ping timed out (" + tPass + "s)" + " for master : " + ip);
                        // timedout
                    }
                    else
                    {
                        masterServer = NetUtility.Resolve(ip, masterPort);
                        Debug.Log("Resolved Master : " + ip + " , Ping : " + ping.time + "ms");
                        initMasterConn = true;
                        yield break;
                    }
                    yield return(null);
                }
            }
        }
예제 #12
0
        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(NetUtility.GetLocalIPAddress(), 1234);

            server.Start();
            Clients = new List <ClientHandler>();

            Console.WriteLine($"Waiting for clients on {server.Server.LocalEndPoint}");

            while (true)
            {
                TcpClient client = server.AcceptTcpClient();

                // Assign the client to a handler
                Clients.Add(new ClientHandler(client));
                Console.WriteLine($"Accepted and assigned handler to {client.Client.RemoteEndPoint}.");
            }


            Console.WriteLine("Sever Execution Ended. Press any key to continue...");
            Console.ReadKey();
        }
예제 #13
0
        public void Listen(UDPSetting setting)
        {
            if (null == setting)
            {
                NetDebug.Error("[UDPConnection] the setting can not be null.");
                return;
            }

            this.setting = setting;
            Initialize(this.setting.ioNum);

            localEndPoint = NetUtility.GetIPEndPoint(setting.host, setting.port);
            socket        = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
            socket.Bind(localEndPoint);

            kcpHandle = new KCPServerHandle(setting);
            kcpHandle.onSendHandle    = OnSend;
            kcpHandle.onReceiveHandle = OnReceive;

            Start();
        }
예제 #14
0
        static void Main(string[] args)
        {
            NetPeerConfiguration config = new NetPeerConfiguration("garbagethrower");
            var client = new NetClient(config);

            client.Start();

            var target = new IPEndPoint(NetUtility.Resolve("localhost"), 14242);
            var buffer = new byte[1024];
            var rnd    = new Random();

            // use RawSend to throw poop at server
            while (true)
            {
                rnd.NextBytes(buffer);
                int length = rnd.Next(1, 1023);

                switch (rnd.Next(2))
                {
                case 0:
                    // complete randomness
                    break;

                case 1:
                    // semi-sensical
                    buffer[1] = 0;                             // not a fragment, sequence number 0
                    buffer[2] = 0;                             // not a fragment, sequence number 0
                    buffer[3] = (byte)length;                  // correct payload length
                    buffer[4] = (byte)(length >> 8);           // correct payload length
                    break;
                }

                // fling teh poop
                client.RawSend(buffer, 0, length, target);

                Thread.Sleep(1);
            }
        }
예제 #15
0
        private static void HandleLoginRequest(NetIncomingMessage msg)
        {
            var logger = Logger.Instance();

            logger.Write(String.Format("Received LoginRequest from {0}", NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier)), LogLevels.Informational);

            // Retrieve our username and password from the message.
            var user = msg.ReadString();
            var pass = msg.ReadString();

            // Attempt to authenticate the user.
            var result = Data.AuthenticateUser(user, pass);

            if (result[0] == 0)
            {
                // Login OK.
                // Generate a brand new GUID and add our user to the internal storage for later use.
                var id      = result[1];
                var guid    = Guid.NewGuid();
                var storage = GUIDStore.Instance();
                storage.AddGUID(id, guid);

                logger.Write(String.Format("Authenticated user at Peer: {0}", NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier)), LogLevels.Debug);
                logger.Write(String.Format("Added GUID: {0} to storage.", guid), LogLevels.Debug);

                // Send our user the OK and our realmlist.
                Send.AuthSuccess(msg.SenderConnection, guid);
            }
            else
            {
                // Login Failed.

                logger.Write(String.Format("Authentication failed for user at Peer: {0}", NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier)), LogLevels.Debug);

                // Tell our user they entered incorrect information.
                Send.AuthFailed(msg.SenderConnection);
            }
        }
예제 #16
0
        static void Main(string[] args)
        {
            Console.Write("Enter the Server IP address: ");
            string serverHostName = Console.ReadLine();


            Client.Connect(NetUtility.GetHostAddressIPv4(serverHostName), 1234);
            NetworkStream stream = Client.GetStream();

            Console.Write("Pick a Nickname: ");
            byte[] nickname        = Encoding.UTF8.GetBytes(Console.ReadLine());
            byte[] composedMessage = ComposeMessage(TransmissionType.Nickname, nickname);
            stream.Write(composedMessage, 0, composedMessage.Length);

            Thread receiverThread = new Thread(Receive);

            receiverThread.Start();

            while (true)
            {
                Console.Write("Message: ");
                ChatMessage msg = new ChatMessage(Console.ReadLine());
                Console.Write("To: ");
                msg.Destination = Console.ReadLine();

                // serialize the ChatMessage object and compose the server request
                byte[] serialized   = msg.ToByteArray();
                byte[] concatenated = ComposeMessage(TransmissionType.Message, serialized);

                stream.Write(concatenated, 0, concatenated.Length);
                stream.Flush();
            }

            stream.Close();
            Client.Close();
            Console.WriteLine("Ping message sent. Press any key to continue...");
            Console.ReadKey();
        }
예제 #17
0
        private static void HandleConfirmGuid(NetIncomingMessage msg)
        {
            var logger = Logger.Instance();

            logger.Write(String.Format("Received ConfirmGuid from {0}", NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier)), LogLevels.Informational);
            var store = GUIDStore.Instance();

            // See if our storage contains this Guid.
            var guid = Guid.Parse(msg.ReadString());

            if (store.Contains(guid))
            {
                // Yes it does, we can accept this client.
                logger.Write(String.Format("GUID: {0} Exists, allowing user on.", guid), LogLevels.Debug);
                Send.GuidOK(msg.SenderConnection, guid);
            }
            else
            {
                // No it doesn't, where did they come from?
                logger.Write(String.Format("GUID: {0} Does NotExists, notify user.", guid), LogLevels.Debug);
                Send.GuidError(msg.SenderConnection, guid);
            }
        }
예제 #18
0
        public static void AuthSuccess(NetConnection conn, Guid guid)
        {
            var data   = new NetBuffer();
            var list   = RealmList.Instance().GetRealms();
            var logger = Logger.Instance();

            data.Write((Int32)Packets.Server.AuthSuccess);
            data.Write(guid.ToString());
            data.Write(list.Count);
            foreach (var item in list)
            {
                data.Write(item.Value.Name);
                data.Write(item.Value.Hostname);
                data.Write(item.Value.Port);
                data.Write(
                    (from c in NetServer.Instance().Connections()
                     select NetUtility.ToHexString(c.RemoteUniqueIdentifier))
                    .Contains(item.Value.RemoteIdentifier) ? true : false
                    );
            }
            logger.Write(String.Format("Sending AuthSuccess to {0}", NetUtility.ToHexString(conn.RemoteUniqueIdentifier)), LogLevels.Debug);
            SendDataTo(conn, data);
        }
예제 #19
0
        private static void HandleAuthenticateClient(NetIncomingMessage msg)
        {
            var logger = Logger.Instance();
            var netid  = NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier);

            logger.Write(String.Format("Received AuthenticateClient from {0}", netid), LogLevels.Informational);

            // Get our user.
            var user = NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier);

            // Get our GUID.
            var guid = Guid.Parse(msg.ReadString());

            // Create a new user and add their (currently known) data.
            var store = PlayerStore.Instance();

            store.AddPlayer(netid);
            store.SetAuthorizationId(netid, guid);
            logger.Write(String.Format("Adding new Player with GUID: {0} AuthorizationID: {1}", guid, netid), LogLevels.Debug);

            // Try and confirm this guid with our authentication server.
            Send.ConfirmGuid(guid);
        }
예제 #20
0
        public static void MainClient()
        {
            Application.EnableVisualStyles();
            lobby = new Lobby();

            hostList = new Dictionary <long, IPEndPoint[]>();
            SSEngine.MasterServerEndpoint = new IPEndPoint(NetUtility.Resolve("localhost"), SSEngine.MasterServerPort);
            count           = 0;
            lastRefreshed   = 0.0f;
            SSEngine.IsHost = null;

            NetPeerConfiguration config = new NetPeerConfiguration("strange suits");

            config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
            config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
            config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse);
            SSEngine.Peer = new NetClient(config);
            SSEngine.Peer.Start();
            SSEngine.Peer.DiscoverKnownPeer(SSEngine.MasterServerEndpoint);

            lobby.StartUpdate();
            lobby.ShowDialog();
        }
예제 #21
0
        public void StartConnect(string address)
        {
            if (_isConnecting)
            {
                return;
            }

            // See if the IP includes a port.
            var    split = address.Split(':');
            string ip    = address;
            ushort port  = DEFAULT_PORT;

            if (split.Length > 2)
            {
                // Multiple colons?
                throw new InvalidOperationException("Not a valid Address.");
            }

            // IP:port format.
            if (split.Length == 2)
            {
                ip = split[0];
                if (!ushort.TryParse(split[1], out port))
                {
                    throw new InvalidOperationException("Not a valid port.");
                }
            }

            if (NetUtility.Resolve(ip, port) == null)
            {
                throw new InvalidOperationException("Not a valid Address.");
            }

            _connectTime  = DateTime.Now;
            _isConnecting = true;
            NetworkManager.ClientConnect(ip, port);
        }
예제 #22
0
        public void Connect(string address, int port)
        {
            Initialize();
            IsServer = false;
            State    = UDPConnectionState.OPENING;

            remoterPoint = NetUtility.GetIPEndPoint(address, port);
            if (null == remoterPoint)
            {
                NetDebug.Log("[TCPClient] remote can not be null.");
                return;
            }

            socket = new Socket(remoterPoint.AddressFamily,
                                SocketType.Dgram,
                                ProtocolType.Udp);
            socket.Connect(remoterPoint);

            ReceiveFromAsync(remoterPoint);
            //socket.Blocking = setting.blocking;
            //socket.NoDelay = setting.noDelay;

            Send(remoterPoint, UDPPacketType.SYN);
        }
예제 #23
0
        /// <summary>
        /// Start local network peer.
        /// </summary>
        public Network()
        {
            m_netPeerConfiguration.MaximumConnections = 32;
            m_netPeerConfiguration.Port = APIMain.ServerPort;
            m_netPeerConfiguration.ReceiveBufferSize = 1000000000;
            m_netPeerConfiguration.EnableMessageType(NetIncomingMessageType.UnconnectedData);
            //m_netPeerConfiguration.EnableMessageType(NetIncomingMessageType.DiscoveryRequest); Commented since client will get list of the servers from master server.
            m_netPeerConfiguration.EnableMessageType(NetIncomingMessageType.ConnectionApproval);

            this.m_masterServer = new IPEndPoint(NetUtility.Resolve(APIMain.MasterServerIP), APIMain.MasterServerPort);

            Log.HandleLog(LOGMessageTypes.Info, true, true, true, "Server configured.");
            Log.HandleEmptyMessage();
            Log.HandleLog(LOGMessageTypes.Info, "Initializing server...");

            m_netServer = new NetServer(m_netPeerConfiguration);
            m_netServer.Start();

            Log.HandleLog(LOGMessageTypes.Info, true, true, true, "Server initialized.");
            Log.HandleEmptyMessage();

            m_updateThread = new Thread(Update);
            m_updateThread.Start();
        }
예제 #24
0
        public bool AttemptConnection()
        {
            // Attempt Connection
            IPEndPoint ep;

            if (IPaddress != "")
            {
                ep = NetUtility.Resolve(IPaddress, 14240);
            }
            else
            {
                ep = NetUtility.Resolve("localhost", 14240);
            }

            if (client.GetConnection(ep) == null)
            {
                client.DiscoverKnownPeer(ep);

                connectedServerInfo.IPAddress = ep.ToString();
                connectedServerInfo.port      = ep.Port;

                myInfo.IPAddress = client.Configuration.BroadcastAddress.ToString();
                myInfo.port      = client.Port;

                //if (client.ConnectionStatus != NetConnectionStatus.Disconnected)
                //{
                //pConnected = true;
                // }
            }
            else
            {
                Debug.WriteLine("You're already connected idiot");
            }

            return(pConnected);
        }
예제 #25
0
        // private static bool no_more_tiles =false; //if we dont need to read updates on tiles anymore, to save work.

        static void Main(string[] args)
        {
            NetPeerConfiguration config = new NetPeerConfiguration("Flags");

            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            config.Port       = 14242; //our port
            config.EnableUPnP = true;  //enabling port forwarding using upnp.

            // create and start server
            NetServer server = new NetServer(config);

            server.Start();

            //gamerooms that will contain 2 players each.
            GameRoom        currentGameRoom = new GameRoom();
            List <GameRoom> gamerooms       = new List <GameRoom>(); //list of all gamerooms.

            List <int> tile_list = new List <int>();                 //list of tiles id's

            server.UPnP.ForwardPort(14242, "Flags game for school project");

            // schedule initial sending of position updates
            double nextSendUpdates = NetTime.Now;

            // run until escape is pressed
            while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
            {
                NetIncomingMessage msg;
                while ((msg = server.ReadMessage()) != null) //reading messages from clients.
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.DiscoveryRequest:

                        // Server received a discovery request from a client; send a discovery response
                        // with data about if its the first or second player.


                        NetOutgoingMessage msg_num_of_players = server.CreateMessage();
                        if (server.ConnectionsCount % 2 != 0)
                        {
                            msg_num_of_players.Write(1);
                        }
                        else
                        {
                            msg_num_of_players.Write(0);
                        }

                        server.SendDiscoveryResponse(msg_num_of_players, msg.SenderEndPoint);     //sending response.
                        break;


                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        //
                        // Just print diagnostic messages to console
                        //
                        Console.WriteLine(msg.ReadString());
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
                        if (status == NetConnectionStatus.Connected)
                        {
                            //
                            // A new player just connected!
                            //

                            //writing to console.
                            Console.WriteLine(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " connected!");

                            //in each connection we use it's TAG to keep game data of that client.
                            msg.SenderConnection.Tag = new int[602];

                            //resetting to -10 (meaning no game data to send to other clients)
                            int[] pos = msg.SenderConnection.Tag as int[];
                            for (int i = 0; i < pos.Length; i++)
                            {
                                pos[i] = -10;
                            }

                            //creating new game room if you are the first player.
                            if (server.ConnectionsCount % 2 == 1)
                            {
                                GameRoom tmp = new GameRoom();
                                currentGameRoom = tmp;
                                currentGameRoom.SetFirstPlayer(msg.SenderConnection);
                                gamerooms.Add(currentGameRoom);
                            }
                            else     //joining an existing room if you are the second player.
                            {
                                currentGameRoom.SetSecondPlayer(msg.SenderConnection);
                            }
                        }

                        break;

                    case NetIncomingMessageType.Data:          //reading game related data.
                        string data_string = msg.ReadString(); //reading message header
                        switch (data_string)
                        {
                        case "teleport":
                        {
                            int   tile_id = msg.ReadInt32();                   //reading message
                            int[] pos     = msg.SenderConnection.Tag as int[]; //using connection TAG to save data about that client
                            if (pos[600] == -10)
                            {
                                pos[600] = tile_id;
                            }
                            else
                            {
                                pos[601] = tile_id;
                            }
                            break;
                        }

                        case "tile_added":
                        {
                            int   tile_id = msg.ReadInt32();                   //reading message
                            int[] pos     = msg.SenderConnection.Tag as int[]; //using connection TAG to save data about that client
                            int   i       = 0;
                            while (pos[4 + i] != -10)
                            {
                                i++;
                            }
                            pos[4 + i] = tile_id;

                            break;
                        }

                        case "move":
                        {
                            int   id         = msg.ReadInt32();
                            int   indexinput = msg.ReadInt32();                   //reading message
                            int[] pos        = msg.SenderConnection.Tag as int[]; //using connection TAG to save data about that client
                            pos[0] = id;
                            pos[1] = indexinput;
                            break;
                        }

                        case "attacked":
                        {
                            int   id         = msg.ReadInt32();
                            int   indexinput = msg.ReadInt32();                   //reading message
                            int[] pos        = msg.SenderConnection.Tag as int[]; //using connection TAG to save data about that client
                            pos[2] = id;
                            pos[3] = indexinput;
                            break;
                        }
                        }

                        break;
                    }

                    //
                    // send position updates 30 times per second
                    //
                }

                double now = NetTime.Now;
                if (now > nextSendUpdates)
                {
                    // Yes, it's time to send position updates

                    // for each gameroom...
                    foreach (GameRoom gameroom in gamerooms)
                    {
                        // for each player...
                        foreach (NetConnection player in gameroom.players)
                        {
                            // ... send information to the other player
                            foreach (NetConnection otherPlayer in gameroom.players)
                            {
                                if (player != otherPlayer)
                                {
                                    NetOutgoingMessage om = server.CreateMessage();

                                    if (otherPlayer.Tag == null)
                                    {
                                        otherPlayer.Tag = new int[602];
                                    }

                                    int[] pos = otherPlayer.Tag as int[];
                                    if (pos[0] != -10 && pos[1] != -10) //if there is new data to write.
                                    {
                                        om.Write("move");
                                        om.Write(pos[0]);
                                        om.Write(pos[1]);

                                        // send message
                                        server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                        pos[0] = -10;
                                        pos[1] = -10;
                                    }

                                    int i = 0;
                                    while (pos[4 + i] == -10 && 4 + i < 599)
                                    {
                                        i++;
                                    }

                                    if (pos[4 + i] != -10)     //if there is new data to write.
                                    {
                                        om = server.CreateMessage();
                                        om.Write("tile_added");
                                        om.Write(pos[4 + i]);
                                        server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                        pos[4 + i] = -10;
                                    }


                                    if (pos[2] != -10 && pos[3] != -10) //if there is new data to write.
                                    {
                                        om = server.CreateMessage();
                                        om.Write("attacked");
                                        om.Write(pos[2]);
                                        om.Write(pos[3]);

                                        // send message
                                        server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                        pos[2] = -10;
                                        pos[3] = -10;
                                    }
                                    if (pos[600] != -10 || pos[601] != -10) //if there is new data to write.
                                    {
                                        om = server.CreateMessage();
                                        om.Write("teleport");
                                        if (pos[600] != -10)
                                        {
                                            om.Write(pos[600]);
                                            // send message
                                            server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                            pos[600] = -10;
                                        }
                                        else if (pos[601] != -10)
                                        {
                                            om.Write(pos[601]);
                                            // send message
                                            server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                            pos[601] = -10;
                                        }
                                    }
                                    //   server.SendMessage(om, player, NetDeliveryMethod.ReliableOrdered, 0);
                                }
                            }
                        }
                    }


                    // schedule next update
                    nextSendUpdates += (1.0 / 30.0);
                }

                // sleep to allow other processes to run smoothly
                Thread.Sleep(1);
            }
            server.Shutdown("app exiting");
        }
예제 #26
0
        static void RunServer(CancellationTokenSource token)
        {
            var config = new NetPeerConfiguration("Mafia")
            {
                Port = 12345
            };
            var server = new NetServer(config);

            server.Start();
            while (!token.IsCancellationRequested)
            {
                NetIncomingMessage im;
                while ((im = server.ReadMessage()) != null)
                {
                    // handle incoming message
                    switch (im.MessageType)
                    {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                        string text = im.ReadString();
                        Output(text);
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)im.ReadByte();

                        string reason = im.ReadString();
                        Output(NetUtility.ToHexString(im.SenderConnection.RemoteUniqueIdentifier) + " " + status + ": " + reason);

                        //if (status == NetConnectionStatus.Connected)
                        //{
                        //  string hail = im.SenderConnection.RemoteHailMessage.ReadString();
                        //  Output("Remote hail: " + hail);
                        //}
                        //if (status == NetConnectionStatus.Disconnected)
                        //{

                        //}
                        UpdateConnectionsList(im.SenderConnection, status);
                        break;

                    case NetIncomingMessageType.Data:
                        string action = im.ReadString();
                        string data   = im.ReadString();
                        Output(action + ":" + data);
                        // incoming chat message from a client
                        //string chat = im.ReadString();

                        //Output("Broadcasting '" + chat + "'");

                        //// broadcast this to all connections, except sender
                        //List<NetConnection> all = server.Connections; // get copy
                        //all.Remove(im.SenderConnection);

                        //if (all.Count > 0)
                        //{
                        //  NetOutgoingMessage om = server.CreateMessage();
                        //  om.Write(NetUtility.ToHexString(im.SenderConnection.RemoteUniqueIdentifier) + " said: " + chat);
                        //  server.SendMessage(om, all, NetDeliveryMethod.ReliableOrdered, 0);
                        //}
                        break;

                    default:
                        Output("Unhandled type: " + im.MessageType + " " + im.LengthBytes + " bytes " + im.DeliveryMethod + "|" + im.SequenceChannel);
                        break;
                    }
                    server.Recycle(im);
                }
                Thread.Sleep(1);
            }
            Console.WriteLine("Server is exiting..");
            server.FlushSendQueue();
        }
예제 #27
0
        static void Main(string[] args)
        {
            int playerNr = 1;

            Field[,] gamegrid;

            //Gamegrid erzeugen
            gamegrid = new Field[gamegridSize, gamegridSize];
            for (int i = 0; i < gamegrid.GetLength(0); i++)
            {
                for (int j = 0; j < gamegrid.GetLength(1); j++)
                {
                    gamegrid[i, j] = new Field();
                }
            }

            // Create PlayerList
            //playerList = new List<Player>();

            //Networking
            NetPeerConfiguration config = new NetPeerConfiguration("xnaapp");

            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            config.Port = 1337;

            //create and start Server
            NetServer server = new NetServer(config);

            server.Start();

            //Speed
            double nextSendUpdates = NetTime.Now;

            //Escape Exit
            while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
            {
                //READING MESSAGES //
                NetIncomingMessage msg;
                while ((msg = server.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.DiscoveryRequest:

                        //Recieved discovery request from cient -> send discovery response
                        server.SendDiscoveryResponse(null, msg.SenderEndPoint);
                        break;

                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        //Write all error messages
                        Console.WriteLine(msg.ReadString());
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
                        if (status == NetConnectionStatus.Connected)
                        {
                            // Player Connected !

                            Console.WriteLine(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " is connected !");

                            //Add new Player to List
                            msg.SenderConnection.Tag = new Player(playerNr, msg.SenderConnection.RemoteUniqueIdentifier, gamegridSize);
                            playerNr++;
                            //addPlayersServer(playerId);
                        }
                        else if (status == NetConnectionStatus.Disconnected)
                        {
                            Console.WriteLine(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + "disconnected!");
                            //Delete Player from List
                            //foreach(Player player in playerList){
                            //    if (player.playerId == playerId)
                            //    {
                            //        playerList.Remove(player);
                            //    }
                            //}
                        }
                        break;

                    case NetIncomingMessageType.Data:

                        //Recieve Client Message
                        int moveX = msg.ReadInt32();
                        int moveY = msg.ReadInt32();
                        //int gridSize = msg.ReadInt32();
                        Player msgPlayer = msg.SenderConnection.Tag as Player;

                        msgPlayer.directionX     = moveX;
                        msgPlayer.directionY     = moveY;
                        msg.SenderConnection.Tag = msgPlayer;
                        Console.WriteLine("---------------------------------------------------------");
                        Console.WriteLine("RECIEVED MSG Nr " + msgPlayer.playerNr + " PosX: " + msgPlayer.pos[0] + " PosY: " + msgPlayer.pos[1]);

                        //foreach (Player player in playerList)
                        //{
                        //    if (player.playerId == playerId)
                        //    {
                        //        player.directionX = moveX;
                        //        player.directionY = moveY;
                        //        Console.WriteLine("Id " + playerId + " X: " + moveX + " Y: " + moveY);

                        //        msg.SenderConnection.Tag = player;
                        //        return;
                        //    }

                        //}

                        break;
                    }


                    double now = NetTime.Now;

                    if (now > nextSendUpdates)
                    {
                        //Send Position Updates back

                        foreach (NetConnection player in server.Connections)
                        {
                            NetOutgoingMessage sendMessage = server.CreateMessage();

                            sendMessage.Write(player.RemoteUniqueIdentifier);

                            if (player.Tag == null)
                            {
                                Console.WriteLine("ACHTUNG KEIN TAG BEIM SENDEN !!! ");
                                player.Tag = new Player(playerNr, msg.SenderConnection.RemoteUniqueIdentifier, gamegridSize);
                                playerNr++;
                            }

                            Player msgPlayer = player.Tag as Player;
                            sendMessage.Write(msgPlayer.playerNr);

                            //Collision Detection and Movement //
                            if (!gamegrid[msgPlayer.pos[0], msgPlayer.pos[1]].isWall)
                            {
                                //Set Wall and Color
                                gamegrid[msgPlayer.pos[0], msgPlayer.pos[1]].isWall = true;
                                // Move


                                Console.WriteLine("Nr " + msgPlayer.playerNr + " PosX: " + msgPlayer.pos[0] + " PosY: " + msgPlayer.pos[1]);
                                Console.WriteLine(gamegrid[msgPlayer.pos[0], msgPlayer.pos[1]].isWall);
                                msgPlayer.move();
                                Console.WriteLine("Nr " + msgPlayer.playerNr + " PosX: " + msgPlayer.pos[0] + " PosY: " + msgPlayer.pos[1]);
                                Console.WriteLine(gamegrid[msgPlayer.pos[0], msgPlayer.pos[1]].isWall);
                            }
                            else
                            {
                                msgPlayer.isAlive = false;
                            }
                            sendMessage.Write(msgPlayer.isAlive);
                            sendMessage.Write(msgPlayer.pos[0]);
                            sendMessage.Write(msgPlayer.pos[1]);


                            Console.WriteLine("SENDED MSG Nr " + msgPlayer.playerNr + " PosX: " + msgPlayer.pos[0] + " PosY: " + msgPlayer.pos[1]);
                            server.SendMessage(sendMessage, player, NetDeliveryMethod.Unreliable);
                        }
                    }

                    nextSendUpdates += (1.0 / 10.0);//Sendeintervall
                }
                //to run smootly
                Thread.Sleep(1);
            }
            server.Shutdown("Server beendet");
        }
예제 #28
0
 public override int GetPacketSize() =>
 NetUtility.BitsToHoldGuid(_sourceMechGuid) +
 _usedWeapon.GetPacketSize() +
 _targetPosition.GetPacketSize();
        private async void HandleHandshake(NetPeerData peer, NetConnection connection)
        {
            try
            {
                var incPacket = await AwaitData(connection);

                var msgLogin = new MsgLoginStart();
                msgLogin.ReadFromBuffer(incPacket);

                var ip         = connection.RemoteEndPoint.Address;
                var isLocal    = IPAddress.IsLoopback(ip) && _config.GetCVar(CVars.AuthAllowLocal);
                var canAuth    = msgLogin.CanAuth;
                var needPk     = msgLogin.NeedPubKey;
                var authServer = _config.GetSecureCVar <string>("auth.server");


                if (Auth == AuthMode.Required && !isLocal)
                {
                    if (!canAuth)
                    {
                        connection.Disconnect("Connecting to this server requires authentication");
                        return;
                    }
                }

                NetEncryption?encryption = null;
                NetUserId     userId;
                string        userName;
                LoginType     type;
                var           padSuccessMessage = true;

                if (canAuth && Auth != AuthMode.Disabled)
                {
                    var verifyToken = new byte[4];
                    RandomNumberGenerator.Fill(verifyToken);
                    var msgEncReq = new MsgEncryptionRequest
                    {
                        PublicKey   = needPk ? RsaPublicKey : Array.Empty <byte>(),
                        VerifyToken = verifyToken
                    };

                    var outMsgEncReq = peer.Peer.CreateMessage();
                    outMsgEncReq.Write(false);
                    outMsgEncReq.WritePadBits();
                    msgEncReq.WriteToBuffer(outMsgEncReq);
                    peer.Peer.SendMessage(outMsgEncReq, connection, NetDeliveryMethod.ReliableOrdered);

                    incPacket = await AwaitData(connection);

                    var msgEncResponse = new MsgEncryptionResponse();
                    msgEncResponse.ReadFromBuffer(incPacket);

                    byte[] verifyTokenCheck;
                    byte[] sharedSecret;
                    try
                    {
                        verifyTokenCheck = _authRsaPrivateKey !.Decrypt(
                            msgEncResponse.VerifyToken,
                            RSAEncryptionPadding.OaepSHA256);
                        sharedSecret = _authRsaPrivateKey !.Decrypt(
                            msgEncResponse.SharedSecret,
                            RSAEncryptionPadding.OaepSHA256);
                    }
                    catch (CryptographicException)
                    {
                        // Launcher gives the client the public RSA key of the server BUT
                        // that doesn't persist if the server restarts.
                        // In that case, the decrypt can fail here.
                        connection.Disconnect("Token decryption failed./nPlease reconnect to this server from the launcher.");
                        return;
                    }

                    if (!verifyToken.SequenceEqual(verifyTokenCheck))
                    {
                        connection.Disconnect("Verify token is invalid");
                        return;
                    }

                    encryption = new NetAESEncryption(peer.Peer, sharedSecret, 0, sharedSecret.Length);

                    var authHashBytes = MakeAuthHash(sharedSecret, RsaPublicKey !);
                    var authHash      = Base64Helpers.ConvertToBase64Url(authHashBytes);

                    var client     = new HttpClient();
                    var url        = $"{authServer}api/session/hasJoined?hash={authHash}&userId={msgEncResponse.UserId}";
                    var joinedResp = await client.GetAsync(url);

                    joinedResp.EnsureSuccessStatusCode();

                    var joinedRespJson = JsonConvert.DeserializeObject <HasJoinedResponse>(
                        await joinedResp.Content.ReadAsStringAsync());

                    if (!joinedRespJson.IsValid)
                    {
                        connection.Disconnect("Failed to validate login");
                        return;
                    }

                    userId            = new NetUserId(joinedRespJson.UserData !.UserId);
                    userName          = joinedRespJson.UserData.UserName;
                    padSuccessMessage = false;
                    type = LoginType.LoggedIn;
                }
                else
                {
                    var reqUserName = msgLogin.UserName;

                    if (!UsernameHelpers.IsNameValid(reqUserName, out var reason))
                    {
                        connection.Disconnect($"Username is invalid ({reason.ToText()}).");
                        return;
                    }

                    // If auth is set to "optional" we need to avoid conflicts between real accounts and guests,
                    // so we explicitly prefix guests.
                    var origName = Auth == AuthMode.Disabled
                        ? reqUserName
                        : (isLocal ? $"localhost@{reqUserName}" : $"guest@{reqUserName}");
                    var name       = origName;
                    var iterations = 1;

                    while (_assignedUsernames.ContainsKey(name))
                    {
                        // This is shit but I don't care.
                        name = $"{origName}_{++iterations}";
                    }

                    userName = name;

                    (userId, type) = await AssignUserIdAsync(name);
                }

                var endPoint = connection.RemoteEndPoint;
                var connect  = await OnConnecting(endPoint, userId, userName, type);

                if (connect.IsDenied)
                {
                    connection.Disconnect($"Connection denied: {connect.DenyReason}");
                    return;
                }

                // Well they're in. Kick a connected client with the same GUID if we have to.
                if (_assignedUserIds.TryGetValue(userId, out var existing))
                {
                    existing.Disconnect("Another connection has been made with your account.");
                    // Have to wait until they're properly off the server to avoid any collisions.
                    await AwaitDisconnectAsync(existing);
                }

                var msg     = peer.Peer.CreateMessage();
                var msgResp = new MsgLoginSuccess
                {
                    UserId   = userId.UserId,
                    UserName = userName,
                    Type     = type
                };
                if (padSuccessMessage)
                {
                    msg.Write(true);
                    msg.WritePadBits();
                }

                msgResp.WriteToBuffer(msg);
                encryption?.Encrypt(msg);
                peer.Peer.SendMessage(msg, connection, NetDeliveryMethod.ReliableOrdered);

                Logger.InfoS("net",
                             "Approved {ConnectionEndpoint} with username {Username} user ID {userId} into the server",
                             connection.RemoteEndPoint, userName, userId);

                // Handshake complete!
                HandleInitialHandshakeComplete(peer, connection, userId, userName, encryption, type);
            }
            catch (ClientDisconnectedException)
            {
                Logger.InfoS("net",
                             $"Peer {NetUtility.ToHexString(connection.RemoteUniqueIdentifier)} disconnected while handshake was in-progress.");
            }
            catch (Exception e)
            {
                connection.Disconnect("Unknown server error occured during handshake.");
                Logger.ErrorS("net", "Exception during handshake with peer {0}:\n{1}",
                              NetUtility.ToHexString(connection.RemoteUniqueIdentifier), e);
            }
        }
예제 #30
0
        private void DiscoverPublicServers()
        {
            string deviceId;

#if PLATFORM_ANDROID
            try {
                deviceId = global::Android.Provider.Settings.Secure.GetString(Android.MainActivity.Current.ContentResolver, global::Android.Provider.Settings.Secure.AndroidId);
                if (deviceId == null)
                {
                    deviceId = "";
                }
            } catch {
                deviceId = "";
            }

            deviceId += "|Android " + global::Android.OS.Build.VERSION.Release + "|";

            try {
                string device = (string.IsNullOrEmpty(global::Android.OS.Build.Model) ? global::Android.OS.Build.Manufacturer : (global::Android.OS.Build.Model.StartsWith(global::Android.OS.Build.Manufacturer) ? global::Android.OS.Build.Model : global::Android.OS.Build.Manufacturer + " " + global::Android.OS.Build.Model));

                if (device == null)
                {
                    device = "";
                }
                else if (device.Length > 1)
                {
                    device = char.ToUpper(device[0]) + device.Substring(1);
                }

                deviceId += device;
            } catch {
            }
#else
            try {
                deviceId = Environment.MachineName;
                if (deviceId == null)
                {
                    deviceId = "";
                }
            } catch {
                deviceId = "";
            }

            deviceId += "|" + Environment.OSVersion.ToString() + "|";
#endif

            deviceId = Convert.ToBase64String(Encoding.UTF8.GetBytes(deviceId))
                       .Replace('+', '-').Replace('/', '_').TrimEnd('=');

            ServerListJson json;
            try {
                string currentVersion = App.AssemblyVersion;

                WebClient http = new WebClient();
                http.Encoding = Encoding.UTF8;
                http.Headers["User-Agent"] = "Jazz2 Resurrection";

                string content = http.DownloadString(ServerListUrl + "?fetch&v=" + currentVersion + "&d=" + deviceId);
                if (content == null)
                {
                    return;
                }

                json = ContentResolver.Current.Json.Parse <ServerListJson>(content);
            } catch {
                // Nothing to do...
                return;
            }

            // Remove lost local servers
            foreach (KeyValuePair <string, Server> pair in foundServers)
            {
                if (pair.Value.PublicEndPointList == null)
                {
                    continue;
                }

                if (pair.Value.IsLost)
                {
                    pair.Value.LatencyMs = -1;
                    serverUpdatedAction(pair.Value, false);
                }
                else
                {
                    pair.Value.IsLost = true;
                }
            }

            // Process server list
            if (json.s != null)
            {
                foreach (ServerListJson.Server s in json.s)
                {
                    List <IPEndPoint> endPoints;
                    if (!publicEndPoints.TryGetValue(s.u, out endPoints))
                    {
                        string[] endPointsRaw = s.e.Split('|');
                        endPoints = new List <IPEndPoint>(endPointsRaw.Length);
                        for (int i = 0; i < endPointsRaw.Length; i++)
                        {
                            int idx = endPointsRaw[i].LastIndexOf(':');
                            if (idx == -1)
                            {
                                continue;
                            }

                            int port;
                            if (!int.TryParse(endPointsRaw[i].Substring(idx + 1), NumberStyles.Any, CultureInfo.InvariantCulture, out port))
                            {
                                continue;
                            }

                            try {
                                IPAddress ip = NetUtility.Resolve(endPointsRaw[i].Substring(0, idx));

                                if (ip.IsIPv4MappedToIPv6)
                                {
                                    ip = ip.MapToIPv4();
                                }

                                endPoints.Add(new IPEndPoint(ip, port));
                            } catch {
                                // Nothing to do...
                            }
                        }

                        publicEndPoints[s.e] = endPoints;
                    }

                    if (endPoints.Count == 0)
                    {
                        // Endpoints cannot be parsed, skip this server
                        continue;
                    }

                    bool   isNew;
                    Server server;
                    if (!foundServers.TryGetValue(s.u, out server))
                    {
                        server = new Server {
                            UniqueIdentifier   = s.u,
                            ActiveEndPointName = endPoints[0].Address.ToString() + ":" + endPoints[0].Port.ToString(CultureInfo.InvariantCulture),
                            LatencyMs          = -1,
                            IsLost             = true
                        };

                        foundServers[s.u] = server;
                        isNew             = true;
                    }
                    else
                    {
                        isNew = false;
                    }

                    server.PublicEndPointList = endPoints;
                    server.Name = s.n;

                    server.CurrentPlayers = s.c;
                    server.MaxPlayers     = s.m;

                    serverUpdatedAction(server, isNew);

                    // Send ping request
                    server.LastPingTime = (long)(NetTime.Now * 1000);

                    NetOutgoingMessage m = client.CreateMessage();
                    m.Write(SpecialPacketTypes.Ping);
                    client.SendUnconnectedMessage(m, endPoints);
                }
            }
        }