Exemplo n.º 1
0
        /// <summary>
        /// Imports a Player XML Sheet from the specified path
        /// </summary>
        /// <param name="XmlPath">The full path to the XML file</param>
        public static void ImportPlayerXml(string XmlPath)
        {
            // Connect to database first!
            using (StatsDatabase Driver = new StatsDatabase())
            {
                // Load elements
                XDocument Doc       = XDocument.Load(new FileStream(XmlPath, FileMode.Open, FileAccess.Read));
                XElement  Info      = Doc.Root.Element("Info");
                XElement  TableData = Doc.Root.Element("TableData");

                // Make sure player doesnt already exist
                int Pid = Int32.Parse(Info.Element("Pid").Value);
                if (Driver.PlayerExists(Pid))
                {
                    throw new Exception(String.Format("Player with PID {0} already exists!", Pid));
                }

                // Begin Transaction
                using (DbTransaction Transaction = Driver.BeginTransaction())
                {
                    try
                    {
                        // Loop through tables
                        foreach (XElement Table in TableData.Elements())
                        {
                            // Loop through Rows
                            foreach (XElement Row in Table.Elements())
                            {
                                InsertQueryBuilder QueryBuilder = new InsertQueryBuilder(Table.Name.LocalName, Driver);
                                foreach (XElement Col in Row.Elements())
                                {
                                    if (Col.Name.LocalName == "name")
                                    {
                                        QueryBuilder.SetField(Col.Name.LocalName, Col.Value.UnescapeXML());
                                    }
                                    else
                                    {
                                        QueryBuilder.SetField(Col.Name.LocalName, Col.Value);
                                    }
                                }

                                QueryBuilder.Execute();
                            }
                        }

                        // Commit Transaction
                        Transaction.Commit();
                    }
                    catch
                    {
                        Transaction.Rollback();
                        throw;
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Adds a server's posted snapshot into the Snapshot Processing Queue, which
        /// will process the snapshot as soon as possible. This method is Non-Blocking.
        /// </summary>
        /// <remarks>
        /// Any errors that occur during the actual import of the data will be
        /// logged inside the StatsDebug log
        /// </remarks>
        /// <param name="Data">The snapshot data provided by the server.</param>
        /// <param name="ServerAddress">The IP address of the server.</param>
        /// <exception cref="UnauthorizedAccessException">
        ///     Thrown if the Server IP is not authorized to post game data to this server
        /// </exception>
        /// <exception cref="InvalidDataException">
        ///     Thrown if the provided Snapshot data is not valid, and cannot be processed
        /// </exception>
        public static void QueueServerSnapshot(string Data, IPAddress ServerAddress)
        {
            // Make sure the server is authorized
            if (!IsAuthorizedGameServer(ServerAddress))
            {
                throw new UnauthorizedAccessException("Un-Authorised Gameserver (Ip: " + ServerAddress + ")");
            }

            // Create the Snapshot Object
            Snapshot Snap = new Snapshot(Data, ServerAddress);

            // Update this server in the Database
            using (StatsDatabase Database = new StatsDatabase())
            {
                // Try and grab the ID of this server
                int id = Database.ExecuteScalar <int>(
                    "SELECT COALESCE(id, -1), COUNT(id) FROM servers WHERE ip=@P0 AND port=@P1",
                    ServerAddress, Snap.ServerPort
                    );

                // New server?
                if (id < 0)
                {
                    InsertQueryBuilder builder = new InsertQueryBuilder(Database);
                    builder.SetTable("servers");
                    builder.SetField("ip", ServerAddress);
                    builder.SetField("port", Snap.ServerPort);
                    builder.SetField("prefix", Snap.ServerPrefix);
                    builder.SetField("name", Snap.ServerName);
                    builder.SetField("queryport", Snap.QueryPort);
                    builder.SetField("lastupdate", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
                    builder.Execute();
                }
                else // existing
                {
                    UpdateQueryBuilder builder = new UpdateQueryBuilder(Database);
                    builder.SetTable("servers");
                    builder.SetField("prefix", Snap.ServerPrefix);
                    builder.SetField("name", Snap.ServerName);
                    builder.SetField("queryport", Snap.QueryPort);
                    builder.SetField("lastupdate", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
                    builder.AddWhere("id", Comparison.Equals, id);
                    builder.Execute();
                }
            }

            // Add snapshot to Queue
            SnapshotQueue.Enqueue(Snap);
        }
        /// <summary>
        /// Imports a players stats from the official gamespy ASP.
        /// This method is to be used in a background worker
        /// </summary>
        public void bWorker_ImportEaStats(object sender, DoWorkEventArgs e)
        {
            // Setup variables
            BackgroundWorker Worker = (BackgroundWorker)sender;
            int Pid = Int32.Parse(e.Argument.ToString());

            // Do work
            using (StatsDatabase Driver = new StatsDatabase())
            {
                // Make sure the player doesnt exist!
                if (Driver.PlayerExists(Pid))
                {
                    throw new Exception(String.Format("Player with PID {0} already exists!", Pid));
                }

                // Build variables
                Uri                GsUrl;
                WebRequest         Request;
                HttpWebResponse    Response;
                List <string[]>    PlayerLines;
                List <string[]>    AwardLines;
                List <string[]>    MapLines;
                InsertQueryBuilder Query;

                // Create Request
                string Url = String.Format(
                    "getplayerinfo.aspx?pid={0}&info=per*,cmb*,twsc,cpcp,cacp,dfcp,kila,heal,rviv,rsup,rpar,tgte,dkas,dsab,cdsc,rank,cmsc,kick,kill,deth,suic,"
                    + "ospm,klpm,klpr,dtpr,bksk,wdsk,bbrs,tcdr,ban,dtpm,lbtl,osaa,vrk,tsql,tsqm,tlwf,mvks,vmks,mvn*,vmr*,fkit,fmap,fveh,fwea,wtm-,wkl-,wdt-,"
                    + "wac-,wkd-,vtm-,vkl-,vdt-,vkd-,vkr-,atm-,awn-,alo-,abr-,ktm-,kkl-,kdt-,kkd-",
                    Pid);
                Worker.ReportProgress(1, "Requesting Player Stats");
                GsUrl   = new Uri("http://bf2web.gamespy.com/ASP/" + Url);
                Request = WebRequest.Create(GsUrl);

                // Get response
                Response = (HttpWebResponse)Request.GetResponse();
                if (Response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception("Unable to connect to the Gamespy ASP Webservice!");
                }

                // Read response data
                Worker.ReportProgress(2, "Parsing Stats Response");
                PlayerLines = new List <string[]>();
                using (StreamReader Reader = new StreamReader(Response.GetResponseStream()))
                    while (!Reader.EndOfStream)
                    {
                        PlayerLines.Add(Reader.ReadLine().Split('\t'));
                    }

                // Does the player exist?
                if (PlayerLines[0][0] != "O")
                {
                    throw new Exception("Player does not exist on the gamespy servers!");
                }

                // Fetch player mapinfo
                Worker.ReportProgress(3, "Requesting Player Map Data");
                GsUrl   = new Uri(String.Format("http://bf2web.gamespy.com/ASP/getplayerinfo.aspx?pid={0}&info=mtm-,mwn-,mls-", Pid));
                Request = WebRequest.Create(GsUrl);

                // Get response
                Response = (HttpWebResponse)Request.GetResponse();
                if (Response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception("Unable to connect to the Gamespy ASP Webservice!");
                }

                // Read response data
                Worker.ReportProgress(4, "Parsing Map Data Response");
                MapLines = new List <string[]>();
                using (StreamReader Reader = new StreamReader(Response.GetResponseStream()))
                    while (!Reader.EndOfStream)
                    {
                        MapLines.Add(Reader.ReadLine().Split('\t'));
                    }

                // Fetch player awards
                Worker.ReportProgress(5, "Requesting Player Awards");
                GsUrl   = new Uri(String.Format("http://bf2web.gamespy.com/ASP/getawardsinfo.aspx?pid={0}", Pid));
                Request = WebRequest.Create(GsUrl);

                // Get response
                Response = (HttpWebResponse)Request.GetResponse();
                if (Response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception("Unable to connect to the Gamespy ASP Webservice!");
                }

                // Read response data
                Worker.ReportProgress(6, "Parsing Player Awards Response");
                AwardLines = new List <string[]>();
                using (StreamReader Reader = new StreamReader(Response.GetResponseStream()))
                    while (!Reader.EndOfStream)
                    {
                        AwardLines.Add(Reader.ReadLine().Split('\t'));
                    }

                // === Process Player Info === //

                // Parse Player Data
                Dictionary <string, string> PlayerInfo = StatsParser.ParseHeaderData(PlayerLines[3], PlayerLines[4]);
                int Rounds = Int32.Parse(PlayerInfo["mode0"]) + Int32.Parse(PlayerInfo["mode1"]) + Int32.Parse(PlayerInfo["mode2"]);

                // Begin database transaction
                DbTransaction Transaction = Driver.BeginTransaction();

                // Wrap all DB inserts into a try block so we can rollback on error
                try
                {
                    // Insert Player Data
                    Worker.ReportProgress(7, "Inserting Player Data Into Table: player");
                    Query = new InsertQueryBuilder("player", Driver);
                    Query.SetField("id", Pid);
                    Query.SetField("name", " " + PlayerInfo["nick"].Trim()); // Online accounts always start with space in bf2stats
                    Query.SetField("country", "xx");
                    Query.SetField("time", PlayerInfo["time"]);
                    Query.SetField("rounds", Rounds);
                    Query.SetField("ip", "127.0.0.1");
                    Query.SetField("score", PlayerInfo["scor"]);
                    Query.SetField("cmdscore", PlayerInfo["cdsc"]);
                    Query.SetField("skillscore", PlayerInfo["cmsc"]);
                    Query.SetField("teamscore", PlayerInfo["twsc"]);
                    Query.SetField("kills", PlayerInfo["kill"]);
                    Query.SetField("deaths", PlayerInfo["deth"]);
                    Query.SetField("captures", PlayerInfo["cpcp"]);
                    Query.SetField("captureassists", PlayerInfo["cacp"]);
                    Query.SetField("defends", PlayerInfo["dfcp"]);
                    Query.SetField("damageassists", PlayerInfo["kila"]);
                    Query.SetField("heals", PlayerInfo["heal"]);
                    Query.SetField("revives", PlayerInfo["rviv"]);
                    Query.SetField("ammos", PlayerInfo["rsup"]);
                    Query.SetField("repairs", PlayerInfo["rpar"]);
                    Query.SetField("driverspecials", PlayerInfo["dsab"]);
                    Query.SetField("suicides", PlayerInfo["suic"]);
                    Query.SetField("killstreak", PlayerInfo["bksk"]);
                    Query.SetField("deathstreak", PlayerInfo["wdsk"]);
                    Query.SetField("rank", PlayerInfo["rank"]);
                    Query.SetField("banned", PlayerInfo["ban"]);
                    Query.SetField("kicked", PlayerInfo["kick"]);
                    Query.SetField("cmdtime", PlayerInfo["tcdr"]);
                    Query.SetField("sqltime", PlayerInfo["tsql"]);
                    Query.SetField("sqmtime", PlayerInfo["tsqm"]);
                    Query.SetField("lwtime", PlayerInfo["tlwf"]);
                    Query.SetField("wins", PlayerInfo["wins"]);
                    Query.SetField("losses", PlayerInfo["loss"]);
                    Query.SetField("joined", PlayerInfo["jond"]);
                    Query.SetField("rndscore", PlayerInfo["bbrs"]);
                    Query.SetField("lastonline", PlayerInfo["lbtl"]);
                    Query.SetField("mode0", PlayerInfo["mode0"]);
                    Query.SetField("mode1", PlayerInfo["mode1"]);
                    Query.SetField("mode2", PlayerInfo["mode2"]);
                    Query.Execute();

                    // Insert Army Data
                    Worker.ReportProgress(8, "Inserting Player Data Into Table: army");
                    Query = new InsertQueryBuilder("army", Driver);
                    Query.SetField("id", Pid);
                    for (int i = 0; i < 10; i++)
                    {
                        Query.SetField("time" + i, PlayerInfo["atm-" + i]);
                        Query.SetField("win" + i, PlayerInfo["awn-" + i]);
                        Query.SetField("loss" + i, PlayerInfo["alo-" + i]);
                        Query.SetField("best" + i, PlayerInfo["abr-" + i]);
                    }
                    Query.Execute();

                    // Insert Kit Data
                    Worker.ReportProgress(9, "Inserting Player Data Into Table: kits");
                    Query = new InsertQueryBuilder("kits", Driver);
                    Query.SetField("id", Pid);
                    for (int i = 0; i < 7; i++)
                    {
                        Query.SetField("time" + i, PlayerInfo["ktm-" + i]);
                        Query.SetField("kills" + i, PlayerInfo["kkl-" + i]);
                        Query.SetField("deaths" + i, PlayerInfo["kdt-" + i]);
                    }
                    Query.Execute();

                    // Insert Vehicle Data
                    Worker.ReportProgress(10, "Inserting Player Data Into Table: vehicles");
                    Query = new InsertQueryBuilder("vehicles", Driver);
                    Query.SetField("id", Pid);
                    Query.SetField("timepara", 0);
                    for (int i = 0; i < 7; i++)
                    {
                        Query.SetField("time" + i, PlayerInfo["vtm-" + i]);
                        Query.SetField("kills" + i, PlayerInfo["vkl-" + i]);
                        Query.SetField("deaths" + i, PlayerInfo["vdt-" + i]);
                        Query.SetField("rk" + i, PlayerInfo["vkr-" + i]);
                    }
                    Query.Execute();

                    // Insert Weapon Data
                    Worker.ReportProgress(11, "Inserting Player Data Into Table: weapons");
                    Query = new InsertQueryBuilder("weapons", Driver);
                    Query.SetField("id", Pid);
                    for (int i = 0; i < 9; i++)
                    {
                        Query.SetField("time" + i, PlayerInfo["wtm-" + i]);
                        Query.SetField("kills" + i, PlayerInfo["wkl-" + i]);
                        Query.SetField("deaths" + i, PlayerInfo["wdt-" + i]);
                    }

                    // Knife
                    Query.SetField("knifetime", PlayerInfo["wtm-9"]);
                    Query.SetField("knifekills", PlayerInfo["wkl-9"]);
                    Query.SetField("knifedeaths", PlayerInfo["wdt-9"]);
                    // Shockpad
                    Query.SetField("shockpadtime", PlayerInfo["wtm-10"]);
                    Query.SetField("shockpadkills", PlayerInfo["wkl-10"]);
                    Query.SetField("shockpaddeaths", PlayerInfo["wdt-10"]);
                    // Claymore
                    Query.SetField("claymoretime", PlayerInfo["wtm-11"]);
                    Query.SetField("claymorekills", PlayerInfo["wkl-11"]);
                    Query.SetField("claymoredeaths", PlayerInfo["wdt-11"]);
                    // Handgrenade
                    Query.SetField("handgrenadetime", PlayerInfo["wtm-12"]);
                    Query.SetField("handgrenadekills", PlayerInfo["wkl-12"]);
                    Query.SetField("handgrenadedeaths", PlayerInfo["wdt-12"]);
                    // SF Weapn Data
                    Query.SetField("tacticaldeployed", PlayerInfo["de-6"]);
                    Query.SetField("grapplinghookdeployed", PlayerInfo["de-7"]);
                    Query.SetField("ziplinedeployed", PlayerInfo["de-8"]);

                    Query.Execute();

                    // === Process Awards Data === //
                    Worker.ReportProgress(12, "Inserting Player Awards");
                    List <Dictionary <string, string> > Awards = StatsParser.ParseAwards(AwardLines);
                    foreach (Dictionary <string, string> Award in Awards)
                    {
                        Query = new InsertQueryBuilder("awards", Driver);
                        Query.SetField("id", Pid);
                        Query.SetField("awd", Award["id"]);
                        Query.SetField("level", Award["level"]);
                        Query.SetField("earned", Award["when"]);
                        Query.SetField("first", Award["first"]);
                        Query.Execute();
                    }

                    // === Process Map Data === //
                    Worker.ReportProgress(13, "Inserting Player Map Data");
                    PlayerInfo = StatsParser.ParseHeaderData(MapLines[3], MapLines[4]);
                    int[] Maps = new int[] {
                        0, 1, 2, 3, 4, 5, 6, 100, 101, 102, 103, 105,
                        601, 300, 301, 302, 303, 304, 305, 306, 307,
                        10, 11, 110, 200, 201, 202, 12
                    };
                    foreach (int MapId in Maps)
                    {
                        if (PlayerInfo.ContainsKey("mtm-" + MapId))
                        {
                            Query = new InsertQueryBuilder("maps", Driver);
                            Query.SetField("id", Pid);
                            Query.SetField("mapid", MapId);
                            Query.SetField("time", PlayerInfo["mtm-" + MapId]);
                            Query.SetField("win", PlayerInfo["mwn-" + MapId]);
                            Query.SetField("loss", PlayerInfo["mls-" + MapId]);
                            Query.SetField("best", 0);
                            Query.SetField("worst", 0);
                            Query.Execute();
                        }
                    }

                    // Commit transaction
                    Transaction.Commit();
                }
                catch (Exception)
                {
                    Transaction.Rollback();
                    throw;
                }
                finally
                {
                    // Dispose dispose the transaction
                    Transaction.Dispose();
                }
            }
        }