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
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
        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
        }
예제 #5
0
        private void Run()
        {
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, _port);
            //IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("109.237.208.88"), _port);

            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            _socket.Bind(localEP);

            // 4096 bytes should be enough
            byte[] buffer = new byte[4096];

            while (true)
            {
                try
                {
                    Thread.Sleep(1);

                    // might be unneeded, but just to clean up
                    Array.Clear(buffer, 0, buffer.Length);

                    // create a temp EP
                    EndPoint remoteEP = new IPEndPoint(localEP.Address, localEP.Port);

                    // and wait for reception
                    int bytes = _socket.ReceiveFrom(buffer, ref remoteEP);
                    IPEndPoint remoteIP = (IPEndPoint)remoteEP;

                    // decrypt a possible RSA packet
                    var encrypted = false;

                    var pbuffer = buffer;

                    if (buffer[0] == 0xFE)
                    {
                        var cryptBuffer = new byte[bytes - 1];
                        Array.Copy(buffer, 1, cryptBuffer, 0, cryptBuffer.Length);

                        encrypted = true;

                        pbuffer = _rsa.Decrypt(cryptBuffer, true);

                        bytes = pbuffer.Length;
                    }

                    encrypted = true;

                    // trigger packet handler
                    UdpPacket packet = new UdpPacket(pbuffer, bytes, remoteIP, _socket, _name, encrypted);

                    // trigger in remote thread. it could be the 'upacket' is unneeded, but better safe than sorry with delegates
            #if NO
                    ThreadPool.QueueUserWorkItem(delegate (object upacket)
                    {
            #else
                    object upacket = packet;
            #endif

                        try
                        {
                            if (PacketReceived != null)
                            {
                                PacketReceived(this, new UdpPacketReceivedEventArgs((UdpPacket)upacket));
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error(string.Format("Error occurred in a processing call in server {0}: {1}", _name, ex.ToString()));
                        }
            #if NO
                    }, packet);
            #endif

                    Log.Debug(string.Format("Received packet at {0} from {1}:{2}", _name, remoteIP.Address, remoteIP.Port));
                }
                catch (Exception e)
                {
                    Log.Error(string.Format("Error occurred in server {0}: {1}", _name, e.ToString()));
                }
            }
        }
        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();
        }
예제 #7
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")));
            }
        }
예제 #8
0
 public UdpPacketReceivedEventArgs(UdpPacket packet)
 {
     Packet = packet;
 }