/// <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; } } } }
/// <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(); } } }