Exemplo n.º 1
0
        private static void QueryReceived(IAsyncResult result)
        {
            try
            {
                var bytes = _connection.EndReceiveFrom(result, ref obtainedIP);
                var obtainedEP = (IPEndPoint)obtainedIP;

                Log.Info("Received packet from address " + obtainedEP.ToString());

                if (PendingSessions.ContainsKey(obtainedEP))
                {
                    var strData = Encoding.ASCII.GetString(obtainedData, 0, bytes);

                    Log.Debug("Received data: " + strData.Substring(4));

                    var lines = strData.Substring(4).Split('\n');

                    var xuid = PendingSessions[obtainedEP].XUID;
                    var client = Client.Get(xuid);
                    var gt = client.GamerTag;

                    if (lines[0].StartsWith("statusResponse"))
                    {
                        Log.Info("Received a statusResponse.");

                        if (lines.Length >= 2)
                        {
                            var dictionary = GetParams(lines[1].Split('\\'));

                            if (!dictionary.ContainsKey("fs_game"))
                            {
                                dictionary.Add("fs_game", "");
                            }

                            try
                            {
                                using (GeoIPCountry geo = new GeoIPCountry("GeoIP.dat"))
                                {
                                    var countrycode = geo.GetCountryCode(obtainedEP.Address);
                                    Console.WriteLine("Country code of IP address " + obtainedEP.Address.ToString() + ": " + countrycode);
                                    dictionary.Add("countrycode", countrycode);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.ToString());
                            }

                            dictionary.Add("xuid", xuid.ToString("X16"));

                            lock (Servers)
                            {
                                /*
                                if (Servers.ContainsKey(obtainedEP))
                                {
                                    Servers.Remove(obtainedEP);
                                }
                                */

                                ServerData info = null;

                                if (!Servers.ContainsKey(obtainedEP))
                                {
                                    info = new ServerData();
                                    Servers.Add(obtainedEP, info);
                                }
                                else
                                {
                                    info = Servers[obtainedEP];
                                }

                                info.GameData = dictionary;
                                info.Address = obtainedEP;
                                info.HostName = gt;
                                info.HostXUID = xuid;
                                info.LastUpdated = DateTime.UtcNow;

                                Servers[obtainedEP] = info;

                                /*
                                Servers.Add(obtainedEP, new ServerData()
                                {
                                    GameData = dictionary,
                                    Address = obtainedEP,
                                    HostName = gt,
                                    HostXUID = xuid,
                                    LastUpdated = DateTime.UtcNow
                                });
                                */
                            }
                        }
                    }
                    else if (lines[0].StartsWith("0hpong"))
                    {
                        Log.Info("Received a 0hpong.");

                        var data = lines[0].Split(' ');
                        var ingame = (data[3] == "1");
                        var players = int.Parse(data[4]);
                        var maxPlayers = int.Parse(data[5]);


                        if (ingame)
                        {
                            ServerData info = null;

                            if (!Servers.ContainsKey(obtainedEP))
                            {
                                info = new ServerData();
                                Servers.Add(obtainedEP, info);
                            }
                            else
                            {
                                info = Servers[obtainedEP];
                            }

                            info.GameData = new Dictionary<string, string>();
                            //info.Address = obtainedEP;
                            //info.HostName = gt;
                            //info.HostXUID = xuid;
                            //info.LastUpdated = DateTime.UtcNow;

                            // hpong-exclusive data
                            info.InGame = ingame;
                            info.CurrentPlayers = players;
                            info.MaxPlayers = maxPlayers;

                            Servers[obtainedEP] = info;

                            // send getstatus if in-game
                            StartAdvancedQuery(PendingSessions[obtainedEP]);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }

            _connection.BeginReceiveFrom(obtainedData, 0, obtainedData.Length, SocketFlags.None, ref obtainedIP, new AsyncCallback(QueryReceived), null);
        }
        public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            var reader   = packet.GetReader();
            var request  = new MatchRegisterHostingRequestPacket(reader);
            var playlist = server.Playlist;

            var challengePassed = false;

            if (MatchRequestHostingHandler.Challenges.ContainsKey(client.XUID))
            {
                var oldChallenge = MatchRequestHostingHandler.Challenges[client.XUID];

                if (request.Challenge == oldChallenge)
                {
                    challengePassed = true;
                }
            }

            if (!challengePassed)
            {
                Log.Warn(string.Format("Client {0} replied with a wrong host registration challenge.", client.XUID.ToString("X16")));
            }

            var existingMatches = from session in server.Sessions
                                  where session.HostXUID == client.XUID
                                  select session;

            if (existingMatches.Count() > 0)
            {
                var match = existingMatches.First();
                match.GameID = request.Session.GameID;
                match.SetLastTouched();

                Log.Debug(string.Format("Updated match as registered by {0}", client.XUID.ToString("X16")));
            }
            else
            {
                if (!Client.IsHostAllowed(client.XUID))
                {
                    Log.Info(string.Format("Non-allowed client (XUID {0}) tried to register lobby", client.XUID.ToString("X16")));
                    return;
                }
                else if (!Client.IsHostAllowed(request.Session.ExternalIP.Address))
                {
                    Log.Info(string.Format("Non-allowed client (IP {0}) tried to register lobby", request.Session.ExternalIP));
                    return;
                }
                else
                {
                    request.Session.Unclean  = (CIServer.IsUnclean(client.XUID, packet.GetSource().Address) || CIServer.IsUnclean(client.XUIDAlias, packet.GetSource().Address));
                    request.Session.HostXUID = client.XUID;
                    request.Session.Country  = "";

                    try
                    {
                        var countrycode = geo.GetCountryCode(request.Session.ExternalIP.Address);
                        Console.WriteLine("Country code of IP address " + request.Session.ExternalIP.ToString() + ": " + countrycode.ToString());

                        request.Session.Country = countrycode;
                    }
                    catch { }

                    server.Sessions.Add(request.Session);

                    Log.Info(string.Format("Registered session by {0}; lobby at {1}", client.XUID.ToString("X16"), request.Session.ExternalIP));
                }
            }

            // this response appears wrong for now
            var responsePacket = new MatchRegisterHostingResponsePacket(request.ReplyType, request.Sequence);

            var response = packet.MakeResponse();

            responsePacket.Write(response.GetWriter());
            response.Send();
        }
Exemplo n.º 3
0
        public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            if (!packet.Secure)
            {
                return;
            }

            var random   = new Random();
            var reader   = packet.GetReader();
            var request  = new MatchRequestListRequestPacket(reader);
            var playlist = server.Playlist;
            var country  = "";

            try
            {
                country = geo.GetCountryCode(client.ExternalIP.Address);
            }
            catch { }

            client.CurrentState = playlist; // set player as being in this playlist

            var unclean = CIServer.IsUnclean(client.XUID, packet.GetSource().Address) || CIServer.IsUnclean(client.XUIDAlias, packet.GetSource().Address);

            // match hosts
            // TODO: possibly skew 'preferred' players like XBL... 'random' isn't really a matchmaking algorithm
            lock (server.Sessions)
            {
                IEnumerable <MatchSession> sessions = null;

                if (client.GameBuild < 47)
                {
                    sessions = (from session in server.Sessions
                                where /*session.HostXUID != client.XUID && */ (DateTime.Now - session.LastTouched).TotalSeconds < 60 && session.Unclean == unclean
                                orderby random.Next()
                                select session).Take(19);
                }
                else
                {
                    var localsessions = (from session in server.Sessions
                                         where (DateTime.Now - session.LastTouched).TotalSeconds < 60 && session.Unclean == unclean && session.Country == country
                                         orderby random.Next()
                                         select session).Take(20);

                    var remaining = (50 - localsessions.Count());

                    var othersessions = (from session in server.Sessions
                                         where /*session.HostXUID != client.XUID && */ (DateTime.Now - session.LastTouched).TotalSeconds < 60 && session.Unclean == unclean
                                         orderby random.Next()
                                         select session).Take(remaining);

                    sessions = localsessions.Concat(othersessions);
                }

                if (unclean)
                {
                    var list = sessions.ToList();
                    var i    = 0;

                    while (list.Count < 19)
                    {
                        list.Add(new MatchSession()
                        {
                            Clients    = new List <MatchSessionClient>(),
                            ExternalIP = new IPEndPoint(0x7F000001, 28960 + i),
                            GameID     = i,
                            HostXUID   = i + 123,
                            InternalIP = new IPEndPoint(0x7F000001, 28960 + i)
                        });

                        i++;
                    }

                    sessions = list.Take(19);
                }

                var responsePacket = new MatchRequestListResponsePacket(request.ReplyType, request.Sequence, sessions);

                var response = packet.MakeResponse();
                responsePacket.Write(response.GetWriter(), Client.IsVersionAllowed(client.GameVersion, client.GameBuild));
                response.Send();

                Log.Debug(string.Format("Sent {0} sessions to {1}", sessions.Count(), client.XUID.ToString("X16")));
            }
        }
Exemplo n.º 4
0
        private static void QueryReceived(IAsyncResult result)
        {
            try
            {
                var bytes      = _connection.EndReceiveFrom(result, ref obtainedIP);
                var obtainedEP = (IPEndPoint)obtainedIP;

                Log.Info("Received packet from address " + obtainedEP.ToString());

                if (PendingSessions.ContainsKey(obtainedEP))
                {
                    var strData = Encoding.ASCII.GetString(obtainedData, 0, bytes);

                    Log.Debug("Received data: " + strData.Substring(4));

                    var lines = strData.Substring(4).Split('\n');

                    var xuid   = PendingSessions[obtainedEP].XUID;
                    var client = Client.Get(xuid);
                    var gt     = client.GamerTag;

                    if (lines[0].StartsWith("statusResponse"))
                    {
                        Log.Info("Received a statusResponse.");

                        if (lines.Length >= 2)
                        {
                            var dictionary = GetParams(lines[1].Split('\\'));

                            if (!dictionary.ContainsKey("fs_game"))
                            {
                                dictionary.Add("fs_game", "");
                            }

                            try
                            {
                                using (GeoIPCountry geo = new GeoIPCountry("GeoIP.dat"))
                                {
                                    var countrycode = geo.GetCountryCode(obtainedEP.Address);
                                    Console.WriteLine("Country code of IP address " + obtainedEP.Address.ToString() + ": " + countrycode);
                                    dictionary.Add("countrycode", countrycode);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.ToString());
                            }

                            dictionary.Add("xuid", xuid.ToString("X16"));

                            lock (Servers)
                            {
                                /*
                                 * if (Servers.ContainsKey(obtainedEP))
                                 * {
                                 *  Servers.Remove(obtainedEP);
                                 * }
                                 */

                                ServerData info = null;

                                if (!Servers.ContainsKey(obtainedEP))
                                {
                                    info = new ServerData();
                                    Servers.Add(obtainedEP, info);
                                }
                                else
                                {
                                    info = Servers[obtainedEP];
                                }

                                info.GameData    = dictionary;
                                info.Address     = obtainedEP;
                                info.HostName    = gt;
                                info.HostXUID    = xuid;
                                info.LastUpdated = DateTime.UtcNow;

                                Servers[obtainedEP] = info;

                                /*
                                 * Servers.Add(obtainedEP, new ServerData()
                                 * {
                                 *  GameData = dictionary,
                                 *  Address = obtainedEP,
                                 *  HostName = gt,
                                 *  HostXUID = xuid,
                                 *  LastUpdated = DateTime.UtcNow
                                 * });
                                 */
                            }
                        }
                    }
                    else if (lines[0].StartsWith("0hpong"))
                    {
                        Log.Info("Received a 0hpong.");

                        var data       = lines[0].Split(' ');
                        var ingame     = (data[3] == "1");
                        var players    = int.Parse(data[4]);
                        var maxPlayers = int.Parse(data[5]);


                        if (ingame)
                        {
                            ServerData info = null;

                            if (!Servers.ContainsKey(obtainedEP))
                            {
                                info = new ServerData();
                                Servers.Add(obtainedEP, info);
                            }
                            else
                            {
                                info = Servers[obtainedEP];
                            }

                            info.GameData = new Dictionary <string, string>();
                            //info.Address = obtainedEP;
                            //info.HostName = gt;
                            //info.HostXUID = xuid;
                            //info.LastUpdated = DateTime.UtcNow;

                            // hpong-exclusive data
                            info.InGame         = ingame;
                            info.CurrentPlayers = players;
                            info.MaxPlayers     = maxPlayers;

                            Servers[obtainedEP] = info;

                            // send getstatus if in-game
                            StartAdvancedQuery(PendingSessions[obtainedEP]);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }

            _connection.BeginReceiveFrom(obtainedData, 0, obtainedData.Length, SocketFlags.None, ref obtainedIP, new AsyncCallback(QueryReceived), null);
        }