/// <summary> /// Backs up the asp database /// </summary> private void ExportAsASPBtn_Click(object sender, EventArgs e) { // Define backup folder for this backup, and create it if it doesnt exist string Folder = Path.Combine(Paths.DocumentsFolder, "Backups", "bak_" + DateTime.Now.ToString("yyyyMMdd_HHmm")); if (!Directory.Exists(Folder)) Directory.CreateDirectory(Folder); // Abortion indicator bool Aborted = false; // Open the database connection StatsDatabase Database; try { Database = new StatsDatabase(); } catch (Exception Ex) { MessageBox.Show( "Unable to connect to database\r\n\r\nMessage: " + Ex.Message, "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); // Stop the ASP server, and close this form ASP.ASPServer.Stop(); this.Close(); return; } // Show loading screen LoadingForm.ShowScreen(this); // Backup each table into its own bak file foreach (string Table in StatsDatabase.StatsTables) { // Create file path string BakFile = Path.Combine(Folder, Table + ".bak"); // Backup tables try { using (Stream Str = File.Open(BakFile, FileMode.Create)) using (StreamWriter Wtr = new StreamWriter(Str)) { // Use a memory efficient way to export this stuff foreach (Dictionary<string, object> Row in Database.QueryReader("SELECT * FROM " + Table)) Wtr.WriteLine(String.Join("\t", Row.Values)); Wtr.Flush(); } } catch (Exception Ex) { // Close loading form LoadingForm.CloseForm(); // Display the Exception Form ExceptionForm Form = new ExceptionForm(Ex, false); Form.Message = "An error occured while trying to backup the \"" + Table + "\" table. " + "The backup operation will now be cancelled."; DialogResult Result = Form.ShowDialog(); Aborted = true; // Try and remove backup folder try { DirectoryInfo Dir = new DirectoryInfo(Folder); Dir.Delete(true); } catch { } } if (Aborted) break; } // Only display success message if we didnt abort if (!Aborted) { // Close loading form LoadingForm.CloseForm(); string NL = Environment.NewLine; MessageBox.Show( String.Concat("Backup has been completed successfully!", NL, NL, "Backup files have been saved to:", NL, Folder), "Backup Success", MessageBoxButtons.OK, MessageBoxIcon.Information ); } // Close the connection Database.Dispose(); }
/// <summary> /// Imports ASP created BAK files (Mysql Out FILE) /// </summary> private void ImportASPBtn_Click(object sender, EventArgs e) { // Open File Select Dialog FolderSelectDialog Dialog = new FolderSelectDialog(); Dialog.Title = "Select ASP Database Backup Folder"; Dialog.InitialDirectory = Path.Combine(Paths.DocumentsFolder, "Backups"); if (Dialog.ShowDialog()) { // Get files list from path string path = Dialog.SelectedPath; string[] BakFiles = Directory.GetFiles(path, "*.bak"); if (BakFiles.Length > 0) { // Open the database connection StatsDatabase Database; try { Database = new StatsDatabase(); } catch (Exception Ex) { MessageBox.Show( "Unable to connect to database\r\n\r\nMessage: " + Ex.Message, "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); // Stop the ASP server, and close this form ASP.ASPServer.Stop(); this.Close(); return; } // Show task dialog TaskForm.Show(this, "Importing Stats", "Importing ASP Stats Bak Files...", false); TaskForm.UpdateStatus("Removing old stats data"); // Clear old database records Database.Truncate(); Thread.Sleep(500); // Begin transaction DbTransaction Transaction = Database.BeginTransaction(); // import each table foreach (string file in BakFiles) { // Get table name string table = Path.GetFileNameWithoutExtension(file); // Update progress TaskForm.UpdateStatus("Processing stats table: " + table); // Import table data try { // Sqlite kinda sucks... no import methods if (Database.DatabaseEngine == DatabaseEngine.Sqlite) { string[] Lines = File.ReadAllLines(file); foreach (string line in Lines) { string[] Values = line.Split('\t'); Database.Execute( String.Format("INSERT INTO {0} VALUES({1})", table, "\"" + String.Join("\", \"", Values) + "\"") ); } } else Database.Execute(String.Format("LOAD DATA LOCAL INFILE '{0}' INTO TABLE {1};", file.Replace('\\', '/'), table)); } catch (Exception Ex) { // Show exception error ExceptionForm Form = new ExceptionForm(Ex, false); Form.Message = String.Format("Failed to import data into table {0}!{2}{2}Error: {1}", table, Ex.Message, Environment.NewLine); DialogResult Result = Form.ShowDialog(); // Rollback! TaskForm.UpdateStatus("Rolling back stats data"); Transaction.Rollback(); // Update message TaskForm.CloseForm(); return; } } // Commit the transaction, and alert the user Transaction.Commit(); TaskForm.CloseForm(); Notify.Show("Stats imported successfully!", "Operation Successful", AlertType.Success); // Displose Connection Database.Dispose(); } else { // Alert the user and tell them they failed MessageBox.Show( "Unable to locate any .bak files in this folder. Please select an ASP created database backup folder that contains backup files.", "Backup Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } } }
/// <summary> /// Handles the Http Connecting client in a new thread /// </summary> private static void HandleRequest(object Sync) { // Setup the variables HttpClient Client = Sync as HttpClient; StatsDatabase Database; // Update client count, and fire connection event SessionRequests++; RequestRecieved(); // Make sure our stats Database is online try { // If we arent suppossed to be running, show a 503 if (!IsRunning) throw new Exception("Unable to accept client because the server is not running"); // If database is offline, Try to re-connect Database = new StatsDatabase(); } catch(Exception e) { ServerLog.Write("ERROR: [HandleRequest] " + e.Message); // Set service is unavialable Client.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; Client.Response.Send(); return; } // Make sure request method is supported if (Client.Request.HttpMethod != "GET" && Client.Request.HttpMethod != "POST" && Client.Request.HttpMethod != "HEAD") { ServerLog.Write("NOTICE: [HandleRequest] Invalid HttpMethod {0} used by client", Client.Request.HttpMethod); Client.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; Client.Response.Send(); return; } // Process Request try { // Get our requested document string Document = Client.Request.Url.AbsolutePath.ToLower(); switch (Document.Replace("/asp/", "")) { case "bf2statistics.php": new SnapshotPost(Client, Database); break; case "createplayer.aspx": new CreatePlayer(Client, Database); break; case "getbackendinfo.aspx": new GetBackendInfo(Client); break; case "getawardsinfo.aspx": new GetAwardsInfo(Client, Database); break; case "getclaninfo.aspx": new GetClanInfo(Client, Database); break; case "getleaderboard.aspx": new GetLeaderBoard(Client, Database); break; case "getmapinfo.aspx": new GetMapInfo(Client, Database); break; case "getplayerid.aspx": new GetPlayerID(Client, Database); break; case "getplayerinfo.aspx": new GetPlayerInfo(Client, Database); break; case "getrankinfo.aspx": new GetRankInfo(Client, Database); break; case "getunlocksinfo.aspx": new GetUnlocksInfo(Client, Database); break; case "ranknotification.aspx": new RankNotification(Client, Database); break; case "searchforplayers.aspx": new SearchForPlayers(Client, Database); break; case "selectunlock.aspx": new SelectUnlock(Client, Database); break; default: Client.Response.StatusCode = (int)HttpStatusCode.NotFound; Client.Response.Send(); break; } } catch (Exception E) { ServerLog.Write("ERROR: " + E.Message); if (!Client.ResponseSent) { // Internal service error Client.Response.StatusCode = (int)HttpStatusCode.InternalServerError; Client.Response.Send(); } } finally { // Make sure a response is sent to prevent client hang if (!Client.ResponseSent) Client.Response.Send(); Database.Dispose(); } }
/// <summary> /// Loads the players stats from the database, and fills out the forms /// labels with the current information /// </summary> private void LoadPlayer() { StatsDatabase Driver; // Establish DB connection try { Driver = new StatsDatabase(); } catch (DbConnectException Ex) { ExceptionForm.ShowDbConnectError(Ex); HttpServer.Stop(); Load += (s, e) => Close(); // Close form return; } // Fetch Player from database SelectQueryBuilder Builder = new SelectQueryBuilder(Driver); Builder.SelectFromTable("player"); Builder.SelectColumns( "name", "score", "cmdscore", "skillscore", "teamscore", "joined", "country", "rank", "wins", "losses", "permban", "clantag", "isbot"); Builder.AddWhere("id", Comparison.Equals, Pid); List<Dictionary<string, object>> Rows = Driver.ExecuteReader(Builder.BuildCommand()); Player = Rows[0]; // Set window title this.Text = String.Concat(Player["name"].ToString().Trim(), " (", Pid, ")"); // Set country flag try { string Country = String.IsNullOrEmpty(Player["country"].ToString()) ? "XX" : Player["country"].ToString(); CountryPicture.Image = Image.FromStream(Program.GetResource("BF2Statistics.Resources." + Country.ToUpper() + ".png")); } catch { } // Joined Label int Joind = Int32.Parse(Player["joined"].ToString()); DateTime D = DateTime.UtcNow.FromUnixTimestamp(Joind); LabelJoined.Text = String.Concat(D.ToString("yyyy-MM-dd HH:mm"), " GMT"); Tipsy.SetToolTip(LabelJoined, String.Concat(D.ToLocalTime().ToString("yyyy-MM-dd HH:mm"), " Local Time.")); // Fill out the rest of the labels LabelNick.Text = Player["name"].ToString().Trim(); ClanTagBox.Text = Player["clantag"].ToString(); RankSelect.SelectedIndex = Int32.Parse(Player["rank"].ToString()); PermBanSelect.SelectedIndex = Int32.Parse(Player["permban"].ToString()); LabelGlobalScore.Text = Player["score"].ToString(); LabelWinLoss.Text = String.Concat(Player["wins"], " / ", Player["losses"]); LabelTeamScore.Text = Player["teamscore"].ToString(); LabelCombatScore.Text = Player["skillscore"].ToString(); LabelCommandScore.Text = Player["cmdscore"].ToString(); // Get Leaderboard Position Rows = Driver.Query("SELECT COUNT(id) as count FROM player WHERE score > @P0", Int32.Parse(Player["score"].ToString())); int Position = Int32.Parse(Rows[0]["count"].ToString()) + 1; LabelPosition.Text = Position.ToString(); SaveBtn.Enabled = false; // Lock unlocks button if player is Bot if (Int32.Parse(Player["isbot"].ToString()) > 0) ResetUnlocksBtn.Enabled = false; // Close Connection Driver.Dispose(); }
/// <summary> /// Imports ASP created BAK files (Mysql Out FILE) /// </summary> private async void ImportASPBtn_Click(object sender, EventArgs e) { // Open File Select Dialog FolderSelectDialog Dialog = new FolderSelectDialog(); Dialog.Title = "Select ASP Database Backup Folder"; Dialog.InitialDirectory = Path.Combine(Paths.DocumentsFolder, "Database Backups"); if (Dialog.ShowDialog()) { // Get files list from path string path = Dialog.SelectedPath; string[] BakFiles = Directory.GetFiles(path, "*.bak"); if (BakFiles.Length > 0) { // Open the database connection StatsDatabase Database = null; try { Database = new StatsDatabase(); } catch (Exception Ex) { if (Ex is DbConnectException) { ExceptionForm.ShowDbConnectError(Ex as DbConnectException); return; } MessageBox.Show( "Unable to connect to database\r\n\r\nMessage: " + Ex.Message, "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); return; } finally { if (Database == null) { // Stop the ASP server, and close this form HttpServer.Stop(); this.Close(); } } // Show task dialog TaskForm.Show(this, "Importing Stats", "Importing ASP Stats Bak Files...", false); this.Enabled = false; // Don't block the GUI await Task.Run(() => ImportFromBakup(BakFiles, Database)); // Alert user and close task form Notify.Show("Stats imported successfully!", "Operation Successful", AlertType.Success); TaskForm.CloseForm(); this.Enabled = true; // Displose Connection Database.Dispose(); } else { // Alert the user and tell them they failed MessageBox.Show( "Unable to locate any .bak files in this folder. Please select an ASP created database backup folder that contains backup files.", "Backup Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } } }