Example #1
0
        static void Main(string[] args)
        {
#if !DEBUG
            //Log.Initialize("IWNetServer.log", LogLevel.Data | LogLevel.Error | LogLevel.Warning | LogLevel.Info, true);
            Log.Initialize("IWNetServer.log", LogLevel.Data | LogLevel.Info | LogLevel.Error, true);
#else
            Log.Initialize("IWNetServer.log", LogLevel.All, true);
#endif
            Log.Info("IWNetServer starting...");

            if (args.Length == 1)
            {
                if (args[0] == "--genkey")
                {
                    GenerateKey();
                    return;
                }
            }

            IPServer ipServer = new IPServer();
            ipServer.Start();

            LogServer logServer = new LogServer();
            logServer.Start();

            CIServer ciServer = new CIServer();
            ciServer.Start();

            for (byte i = 1; i <= 19; i++)
            {
                MatchServer currentMatchServer = new MatchServer(i);
                currentMatchServer.Start();
            }

            HttpHandler httpServer = new HttpHandler();
            httpServer.Start();

            ServerParser.Start();

            while (true)
            {
                try
                {
                    Client.UpdateBanList();
                    //HttpHandler.ClearConnections();

#if !DEBUG
                    //MatchServer.CleanMyOldMessySessions();
                    //Client.CleanClientsThatAreLongGone();
#endif
                }
                catch (Exception e) { Log.Error(e.ToString()); }

                Thread.Sleep(5000);
            }
        }
Example #2
0
        static void Main(string[] args)
        {
#if !DEBUG
            //Log.Initialize("IWNetServer.log", LogLevel.Data | LogLevel.Error | LogLevel.Warning | LogLevel.Info, true);
            Log.Initialize("IWNetServer.log", LogLevel.Data | LogLevel.Info | LogLevel.Error, true);
#else
            Log.Initialize("IWNetServer.log", LogLevel.All, true);
#endif
            Log.Info("IWNetServer starting...");

            if (args.Length == 1)
            {
                if (args[0] == "--genkey")
                {
                    GenerateKey();
                    return;
                }
            }

            IPServer ipServer = new IPServer();
            ipServer.Start();

            LogServer logServer = new LogServer();
            logServer.Start();

            CIServer ciServer = new CIServer();
            ciServer.Start();

            for (byte i = 1; i <= 19; i++)
            {
                MatchServer currentMatchServer = new MatchServer(i);
                currentMatchServer.Start();
            }

            HttpHandler httpServer = new HttpHandler();
            httpServer.Start();

            ServerParser.Start();

            while (true)
            {
                try
                {
                    Client.UpdateBanList();
                    //HttpHandler.ClearConnections();

#if !DEBUG
                    //MatchServer.CleanMyOldMessySessions();
                    //Client.CleanClientsThatAreLongGone();
#endif
                }
                catch (Exception e) { Log.Error(e.ToString()); }

                Thread.Sleep(5000);
            }
        }
Example #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")));
            }
        }
        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();
        }
Example #5
0
        public static void Run()
        {
            var server = new DotNetServer();

            var pipe = server.Start();

            server.Host((env, respond, error) =>
            {
                var path = env["Owin.RequestUri"] as string;

                /*
                 * if (path == "/")
                 *  respond(
                 *          "200 OK",
                 *          new Dictionary<string, IList<string>>()
                 *          {
                 *              { "Content-Type",  new string[] { "text/plain" } }
                 *          },
                 *          new object[] { Encoding.ASCII.GetBytes("Hello world.") }
                 *      );
                 * else if (path == "/stream")
                 * {
                 *  StreamingApp(env, respond, error);
                 * }
                 * else if (path == "/bufferedecho")
                 * {
                 *  BufferedEcho(env, respond, error);
                 * }
                 */

                var urlParts = path.Substring(1).Split(new[] { '/' }, 2);

                if (urlParts.Length >= 1)
                {
                    if (urlParts[0] == "nick")
                    {
                        var steamID = long.Parse(urlParts[1]);
                        var client  = Client.Get(steamID);

                        Console.WriteLine(steamID);

                        if (client.GameVersion != 0)
                        {
                            var nickname = client.GamerTag;
                            respond(
                                "200 OK",
                                new Dictionary <string, IList <string> >()
                            {
                                { "Content-Type", new string[] { "text/plain" } }
                            },
                                new object[] { Encoding.ASCII.GetBytes(nickname) }
                                );
                            return;
                        }
                    }
                    else if (urlParts[0] == "stats")
                    {
                        var statistics   = Client.GetStatistics();
                        var retString    = "[Stats]\r\n";
                        var totalPlayers = 0;

                        foreach (var stat in statistics)
                        {
                            retString += string.Format("playerState{0}={1}\r\n", stat.StatisticID, stat.StatisticCount);

                            totalPlayers += stat.StatisticCount;
                        }

                        retString += string.Format("totalPlayers={0}\r\n", totalPlayers);

                        retString   += "[Lobbies]\r\n";
                        totalPlayers = 0;
                        foreach (var serverc in MatchServer.Servers)
                        {
                            var cnt = serverc.Value.Sessions.Count(sess => (DateTime.Now - sess.LastTouched).TotalSeconds < 60);
                            //var cnt = serverc.Value.Sessions.Count;
                            retString    += string.Format("lobbies{0}={1}\r\n", serverc.Key, cnt);
                            totalPlayers += cnt;
                        }

                        retString += string.Format("totalLobbies={0}", totalPlayers);
                        respond(
                            "200 OK",
                            new Dictionary <string, IList <string> >()
                        {
                            { "Content-Type", new string[] { "text/plain" } }
                        },
                            new object[] { Encoding.ASCII.GetBytes(retString) }
                            );
                        return;
                    }
                    else if (urlParts[0] == "clean")
                    {
                        long clientID = 0;
                        var valid     = false;

                        if (long.TryParse(urlParts[1], out clientID))
                        {
                            if (clientID != 0x110000100000002)
                            {
                                var client = Client.Get(clientID);

                                if ((DateTime.UtcNow - client.LastTouched).TotalSeconds < 300)
                                {
                                    var state = CIServer.IsUnclean(clientID, null);

                                    if (!state)
                                    {
                                        valid = true;
                                    }
                                }
                            }
                        }
                        respond(
                            "200 OK",
                            new Dictionary <string, IList <string> >()
                        {
                            { "Content-Type", new string[] { "text/plain" } }
                        },
                            new object[] { Encoding.ASCII.GetBytes((valid) ? "valid" : "invalid") }
                            );
                        return;
                    }
                    else if (urlParts[0] == "cleanExt")
                    {
                        long clientID = 0;
                        var valid     = false;
                        var reason    = "invalid-id";

                        if (long.TryParse(urlParts[1], out clientID))
                        {
                            if (clientID != 0x110000100000002)
                            {
                                var client = Client.Get(clientID);

                                if ((DateTime.UtcNow - client.LastTouched).TotalHours < 6)
                                {
                                    var state = CIServer.IsUnclean(clientID, null);

                                    if (state)
                                    {
                                        reason = CIServer.WhyUnclean(clientID);
                                    }
                                    else
                                    {
                                        reason = "actually-valid";
                                        valid  = true;
                                    }
                                }
                                else
                                {
                                    reason = "not-registered-at-lsp";
                                }
                            }
                            else
                            {
                                reason = "00002-IDGEN-error";
                            }
                        }
                        respond(
                            "200 OK",
                            new Dictionary <string, IList <string> >()
                        {
                            { "Content-Type", new string[] { "text/plain" } }
                        },
                            new object[] { Encoding.ASCII.GetBytes(((valid) ? "valid" : "invalid") + "\r\n" + reason) }
                            );

                        return;
                    }
                    else if (urlParts[0] == "pc")
                    {
                        var file = "pc/" + urlParts[1].Replace('\\', '/');

                        if (!File.Exists(file))
                        {
                            respond(
                                "200 OK",
                                new Dictionary <string, IList <string> >()
                            {
                                { "Content-Type", new string[] { "text/plain" } }
                            },
                                new object[] { Encoding.ASCII.GetBytes("Not found!") }
                                );
                        }
                        else
                        {
                            var stream = File.OpenRead(file);
                            var b      = new byte[stream.Length];
                            stream.Read(b, 0, (int)stream.Length);
                            stream.Close();

                            respond(
                                "200 OK",
                                new Dictionary <string, IList <string> >()
                            {
                                { "Content-Type", new string[] { "application/octet-stream" } }
                            },
                                new object[] { b }
                                );
                        }

                        return;
                    }
                    else if (urlParts[0] == "servers")
                    {
                        var filter = urlParts[1].Replace(".xml", "");
                        if (filter.Contains("yeQA4reD"))
                        {
                            respond(
                                "200 OK",
                                new Dictionary <string, IList <string> >()
                            {
                                { "Content-Type", new string[] { "text/xml" } }
                            },
                                new object[] { Encoding.ASCII.GetBytes(ProcessServers(filter)) }
                                );
                        }
                        else
                        {
                            respond(
                                "200 OK",
                                new Dictionary <string, IList <string> >()
                            {
                                { "Content-Type", new string[] { "text/html" } }
                            },
                                new object[] { Encoding.ASCII.GetBytes("Invalid") }
                                );
                        }
                        return;
                    }
                    else
                    {
                        respond(
                            "200 OK",
                            new Dictionary <string, IList <string> >()
                        {
                            { "Content-Type", new string[] { "text/html" } }
                        },
                            new object[] { Encoding.ASCII.GetBytes("Invalid") }
                            );
                    }
                }
            });
            Log.Info("Listening on " + server.ListenEndPoint);
        }
Example #6
0
        void server_PacketReceived(object sender, UdpPacketReceivedEventArgs e)
        {
            var packet     = e.Packet;
            var reader     = packet.GetReader();
            var basePacket = new MatchBaseRequestPacket(reader);

            var client = Client.Get(basePacket.XUID);

            /*if (!Client.IsAllowed(basePacket.XUID))
             * {
             *  Log.Info(string.Format("Non-allowed client (XUID {0}) tried to get matches", basePacket.XUID.ToString("X16")));
             *  return;
             * }
             *
             * if (!Client.IsAllowed(client.XUIDAlias))
             * {
             *  Log.Info(string.Format("Non-allowed client (XUID {0}) tried to get matches", basePacket.XUID.ToString("X16")));
             *  return;
             * }*/

            var ipAddress = packet.GetSource().Address;

            if (!Client.IsAllowed(ipAddress))
            {
                Log.Info(string.Format("Non-allowed client (IP {0}) tried to get matches", ipAddress));
                return;
            }

            client.SetLastTouched();
            client.CurrentState = _playlist;
            client.SetLastMatched();

            if (!Client.IsVersionAllowed(client.GameVersion, client.GameBuild))
            {
                return;
            }

            var sessions = from session in Sessions
                           where session.HostXUID == client.XUID && (DateTime.Now - session.LastTouched).TotalSeconds < 120
                           select session;

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

                if (CIServer.IsUnclean(session.HostXUID, packet.GetSource().Address))
                {
                    session.Unclean = true;
                }

                foreach (var updateClient in session.Clients)
                {
                    var updClient = Client.Get(updateClient.XUID);
                    updClient.CurrentState = _playlist;
                    updClient.SetLastTouched();
                    updClient.SetLastMatched();
                }
            }

            if (_handlers.ContainsKey(basePacket.CommandType))
            {
                _handlers[basePacket.CommandType].HandleCommand(this, client, packet, basePacket);
            }
            else
            {
                Log.Info(string.Format("Client {0} sent unknown match packet {1}", basePacket.XUID.ToString("X16"), basePacket.CommandType));
            }
        }
Example #7
0
        public void OnResponse(HttpListenerContext context)
        {
            try
            {
                var url = context.Request.Url.PathAndQuery;

                Log.Debug(string.Format("HTTP request for {0}", url));

                var urlParts = url.Substring(1).Split(new[] { '/' }, 2);

                if (urlParts.Length >= 1)
                {
                    if (urlParts[0] == "nick")
                    {
                        var steamID = long.Parse(urlParts[1]);
                        var client  = Client.Get(steamID);

                        if (client.GameVersion != 0)
                        {
                            var nickname = client.GamerTag;

                            //rp.status = (int)RespState.OK;
                            //rp.Headers["Content-Type"] = "text/plain";
                            var b = Encoding.ASCII.GetBytes(nickname);
                            context.Response.ContentLength64 = b.Length;
                            context.Response.ContentType     = "text/plain";
                            context.Response.OutputStream.Write(b, 0, b.Length);
                            context.Response.OutputStream.Close();
                            return;
                        }
                    }
                    else if (urlParts[0] == "stats")
                    {
                        var statistics   = Client.GetStatistics();
                        var retString    = "[Stats]\r\n";
                        var totalPlayers = 0;

                        foreach (var stat in statistics)
                        {
                            retString += string.Format("playerState{0}={1}\r\n", stat.StatisticID, stat.StatisticCount);

                            totalPlayers += stat.StatisticCount;
                        }

                        retString += string.Format("totalPlayers={0}\r\n", totalPlayers);

                        retString   += "[Lobbies]\r\n";
                        totalPlayers = 0;
                        foreach (var server in MatchServer.Servers)
                        {
                            var cnt = server.Value.Sessions.Count(sess => (DateTime.Now - sess.LastTouched).TotalSeconds < 60);

                            retString    += string.Format("lobbies{0}={1}\r\n", server.Key, cnt);
                            totalPlayers += cnt;
                        }

                        retString += string.Format("totalLobbies={0}", totalPlayers);

                        /*rp.status = (int)RespState.OK;
                         * rp.Headers["Content-Type"] = "text/plain";
                         * rp.BodyData = Encoding.ASCII.GetBytes(retString);*/
                        var b = Encoding.ASCII.GetBytes(retString);
                        context.Response.ContentLength64 = b.Length;
                        context.Response.ContentType     = "text/plain";
                        context.Response.OutputStream.Write(b, 0, b.Length);
                        context.Response.OutputStream.Close();
                        return;
                    }
                    else if (urlParts[0] == "clean")
                    {
                        long clientID = 0;
                        var  valid    = false;

                        if (long.TryParse(urlParts[1], out clientID))
                        {
                            var client = Client.Get(clientID);

                            if ((DateTime.UtcNow - client.LastTouched).TotalSeconds < 300)
                            {
                                var state = CIServer.IsUnclean(clientID, null);

                                if (!state)
                                {
                                    valid = true;
                                }
                            }
                        }

                        var b = Encoding.ASCII.GetBytes((valid) ? "valid" : "invalid");
                        context.Response.ContentLength64 = b.Length;
                        context.Response.ContentType     = "text/plain";
                        context.Response.OutputStream.Write(b, 0, b.Length);
                        context.Response.OutputStream.Close();
                        return;
                    }
                    else if (urlParts[0] == "cleanExt")
                    {
                        long clientID = 0;
                        var  valid    = false;
                        var  reason   = "invalid-id";

                        if (long.TryParse(urlParts[1], out clientID))
                        {
                            var client = Client.Get(clientID);

                            if ((DateTime.UtcNow - client.LastTouched).TotalHours < 6)
                            {
                                var state = CIServer.IsUnclean(clientID, null);

                                if (state)
                                {
                                    reason = CIServer.WhyUnclean(clientID);
                                }
                                else
                                {
                                    reason = "actually-valid";
                                    valid  = true;
                                }
                            }
                            else
                            {
                                reason = "not-registered-at-lsp";
                            }
                        }

                        var b = Encoding.ASCII.GetBytes(((valid) ? "valid" : "invalid") + "\r\n" + reason);
                        context.Response.ContentLength64 = b.Length;
                        context.Response.ContentType     = "text/plain";
                        context.Response.OutputStream.Write(b, 0, b.Length);
                        context.Response.OutputStream.Close();
                        return;
                    }

                    /*else if (urlParts[0] == "key_public.xml")
                     * {
                     *  if (_keyXML == string.Empty)
                     *  {
                     *      _keyXML = File.ReadAllText("key-public.xml");
                     *  }
                     *
                     *  var b = Encoding.ASCII.GetBytes(_keyXML);
                     *  context.Response.ContentLength64 = b.Length;
                     *  context.Response.ContentType = "text/plain";
                     *  context.Response.OutputStream.Write(b, 0, b.Length);
                     *  context.Response.OutputStream.Close();
                     *  return;
                     * }*/
                    else if (urlParts[0] == "pc")
                    {
                        var file = "pc/" + urlParts[1].Replace('\\', '/');

                        if (!File.Exists(file))
                        {
                            /*rp.status = (int)RespState.NOT_FOUND;
                             * rp.Headers["Content-Type"] = "text/plain";
                             * rp.BodyData = Encoding.ASCII.GetBytes("Not Found!");*/
                            var b = Encoding.ASCII.GetBytes("Not Found!");
                            context.Response.ContentLength64 = b.Length;
                            context.Response.ContentType     = "text/plain";
                            context.Response.OutputStream.Write(b, 0, b.Length);
                            context.Response.OutputStream.Close();
                        }
                        else
                        {
                            var stream = File.OpenRead(file);
                            var b      = new byte[stream.Length];
                            stream.Read(b, 0, (int)stream.Length);
                            stream.Close();

                            context.Response.ContentLength64 = b.Length;
                            context.Response.ContentType     = "application/octet-stream";
                            context.Response.OutputStream.Write(b, 0, b.Length);
                            context.Response.OutputStream.Close();
                        }

                        return;
                    }
                    else if (urlParts[0] == "servers")
                    {
                        var filter = urlParts[1].Replace(".xml", "");
                        if (filter.Contains("yeQA4reD"))
                        {
                            var b = Encoding.ASCII.GetBytes(ProcessServers(filter));
                            context.Response.ContentLength64 = b.Length;
                            context.Response.ContentType     = "text/xml";
                            context.Response.OutputStream.Write(b, 0, b.Length);
                            context.Response.OutputStream.Close();
                        }
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e.ToString());
                var b = Encoding.ASCII.GetBytes(e.Message);
                context.Response.ContentLength64 = b.Length;
                context.Response.ContentType     = "text/plain";
                context.Response.OutputStream.Write(b, 0, b.Length);
                context.Response.OutputStream.Close();
                return;
            }

            var bt = Encoding.ASCII.GetBytes("Unknown Player");

            context.Response.ContentLength64 = bt.Length;
            context.Response.ContentType     = "text/plain";
            context.Response.OutputStream.Write(bt, 0, bt.Length);
            context.Response.OutputStream.Close();
        }