public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            var reader = packet.GetReader();
            var request = new MatchUnregisterHostingRequestPacket(reader);
            var playlist = server.Playlist;

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

            if (sessions.Count() > 0)
            {
                var session = sessions.First();
                server.Sessions.Remove(session);

                if (ServerParser.Servers.ContainsKey(session.ExternalIP))
                {
                    ServerParser.Servers.Remove(session.ExternalIP);
                }
            }

            Log.Debug(string.Format("{0} unregistered their session", client.XUID.ToString("X16")));

            // send response, sadly
        }
        public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            lock (server.Sessions)
            {
                var sessions = from session in server.Sessions
                               where session.HostXUID == client.XUID
                               select session;

                if (sessions.Count() > 0)
                {
                    var session = sessions.First();
                    session.SetLastTouched();
                }
            }
        }
        public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            var reader = packet.GetReader();
            var request = new MatchRequestHostingRequestPacket(reader);
            var playlist = server.Playlist;
            var random = new Random();

            var challenge = (uint)(random.Next());
            Challenges[client.XUID] = challenge;

            var responsePacket = new MatchRequestHostingResponsePacket(request.ReplyType, request.Sequence, challenge);

            var response = packet.MakeResponse();
            responsePacket.Write(response.GetWriter());
            response.Send();

            Log.Debug(string.Format("Sent reply to hosting request from {0} (replyType {1})", client.XUID.ToString("X16"), request.ReplyType));
        }
        public void HandleCommand(MatchServer server, Client client, UdpPacket packet, MatchBaseRequestPacket baseRequest)
        {
            var reader = packet.GetReader();
            var request = new MatchUpdateClientsRequestPacket(reader);
            var playlist = server.Playlist;

            Log.Debug(string.Format("Obtained client list from {0}", client.XUID.ToString("X16")));

            foreach (var sessionClient in request.Clients)
            {
                var thisClient = Client.Get(sessionClient.XUID);
                if (thisClient.GameVersion != 0)
                {
                    thisClient.CurrentState = playlist;
                    thisClient.SetLastTouched();

                    Log.Debug(string.Format("{0} - value {1}", thisClient.GamerTag, sessionClient.Value));
                }
                else
                {
                    Log.Warn(string.Format("Obtained invalid client {0}!", sessionClient.XUID.ToString("X16")));
                }
            }

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

            if (sessions.Count() > 0)
            {
                var session = sessions.First();
                session.Clients = request.Clients;
                session.SetLastTouched();
            }

            // no response... yet
        }
        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();
        }
        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")));
            }
        }