public String GenerateBanReason(AdKatsBan aBan) { String banDurationString; //If ban time > 1000 days just say perm TimeSpan remainingTime = this.getRemainingBanTime(aBan); if (remainingTime.TotalDays > 1000) { banDurationString = "[perm]"; } else { banDurationString = "[" + this.FormatTimeString(remainingTime) + "]"; } String sourceNameString = "[" + aBan.ban_record.source_name + "]"; String banAppendString = ((this._UseBanAppend) ? ("[" + this._BanAppend + "]") : ("")); //Create the full message String fullMessage = aBan.ban_record.record_message + " " + banDurationString + sourceNameString + banAppendString; //Trim the kick message if necessary Int32 cutLength = fullMessage.Length - 80; if (cutLength > 0) { String cutReason = aBan.ban_record.record_message.Substring(0, aBan.ban_record.record_message.Length - cutLength); fullMessage = cutReason + " " + banDurationString + sourceNameString + banAppendString; } return fullMessage; }
//DONE private void UploadBan(AdKatsBan aBan) { DebugWrite("uploadBan starting!", 6); Boolean success = false; //Make sure database connection active if (this.HandlePossibleDisconnect()) { return; } if (aBan == null) { this.ConsoleError("Ban invalid in uploadBan."); } else { try { //Upload the inner record if needed if (aBan.ban_record.record_id < 0) { if (!this.UploadRecord(aBan.ban_record)) { return; } } using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" INSERT INTO `" + this._MySqlDatabaseName + @"`.`adkats_bans` ( `player_id`, `latest_record_id`, `ban_status`, `ban_notes`, `ban_startTime`, `ban_endTime`, `ban_enforceName`, `ban_enforceGUID`, `ban_enforceIP`, `ban_sync` ) VALUES ( @player_id, @latest_record_id, @ban_status, @ban_notes, UTC_TIMESTAMP(), DATE_ADD(UTC_TIMESTAMP(), INTERVAL @ban_durationMinutes MINUTE), @ban_enforceName, @ban_enforceGUID, @ban_enforceIP, @ban_sync ) ON DUPLICATE KEY UPDATE `latest_record_id` = @latest_record_id, `ban_status` = @ban_status, `ban_notes` = @ban_notes, `ban_startTime` = UTC_TIMESTAMP(), `ban_endTime` = DATE_ADD(UTC_TIMESTAMP(), INTERVAL @ban_durationMinutes MINUTE), `ban_enforceName` = @ban_enforceName, `ban_enforceGUID` = @ban_enforceGUID, `ban_enforceIP` = @ban_enforceIP, `ban_sync` = @ban_sync"; command.Parameters.AddWithValue("@player_id", aBan.ban_record.target_player.player_id); command.Parameters.AddWithValue("@latest_record_id", aBan.ban_record.record_id); if (String.IsNullOrEmpty(aBan.ban_status)) { aBan.ban_exception = new AdKatsException("Ban status was null or empty when posting."); this.HandleException(aBan.ban_exception); return; } if (aBan.ban_status != "Active" && aBan.ban_status != "Disabled" && aBan.ban_status != "Expired") { aBan.ban_exception = new AdKatsException("Ban status of '" + aBan.ban_status + "' was invalid when posting."); this.HandleException(aBan.ban_exception); return; } command.Parameters.AddWithValue("@ban_status", aBan.ban_status); if (String.IsNullOrEmpty(aBan.ban_notes)) aBan.ban_notes = "NoNotes"; command.Parameters.AddWithValue("@ban_notes", aBan.ban_notes); command.Parameters.AddWithValue("@ban_enforceName", aBan.ban_enforceName ? ('Y') : ('N')); command.Parameters.AddWithValue("@ban_enforceGUID", aBan.ban_enforceGUID ? ('Y') : ('N')); command.Parameters.AddWithValue("@ban_enforceIP", aBan.ban_enforceIP ? ('Y') : ('N')); command.Parameters.AddWithValue("@ban_sync", "*" + this._ServerID + "*"); //Handle permaban case if (aBan.ban_record.command_action.command_key == "player_ban_perm") { aBan.ban_record.command_numeric = (Int32) this._PermaBanEndTime.Subtract(DateTime.UtcNow).TotalMinutes; } command.Parameters.AddWithValue("@ban_durationMinutes", aBan.ban_record.command_numeric); //Attempt to execute the query if (command.ExecuteNonQuery() >= 0) { //Rows affected should be > 0 this.DebugWrite("Success Uploading Ban on player " + aBan.ban_record.target_player.player_id, 5); success = true; } } if (success) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `ban_id`, `ban_startTime`, `ban_endTime`, `ban_status` FROM `adkats_bans` WHERE `player_id` = @player_id"; command.Parameters.AddWithValue("@player_id", aBan.ban_record.target_player.player_id); //Attempt to execute the query using (MySqlDataReader reader = command.ExecuteReader()) { //Grab the ban ID if (reader.Read()) { aBan.ban_id = reader.GetInt64("ban_id"); aBan.ban_startTime = reader.GetDateTime("ban_startTime"); aBan.ban_endTime = reader.GetDateTime("ban_endTime"); String status = reader.GetString("ban_status"); if (status != aBan.ban_status) { aBan.ban_exception = new AdKatsException("Ban status was invalid when confirming ban post. Your database is not in strict mode."); this.HandleException(aBan.ban_exception); return; } //Update setting page to reflect the ban count this.UpdateSettingPage(); this.DebugWrite("Ban ID: " + aBan.ban_id, 5); } else { this.ConsoleError("Could not fetch ban information after upload"); } } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while uploading new ban.", e)); } } DebugWrite("uploadBan finished!", 6); }
public void EnforceBan(AdKatsBan aBan, Boolean verbose) { this.DebugWrite("Entering enforceBan", 6); try { //Create the total kick message String generatedBanReason = this.GenerateBanReason(aBan); this.DebugWrite("Ban Enforce Message: '" + generatedBanReason + "'", 3); //Perform Actions if (this._PlayerDictionary.ContainsKey(aBan.ban_record.target_player.player_name)) { ExecuteCommand("procon.protected.send", "admin.kickPlayer", aBan.ban_record.target_player.player_name, generatedBanReason); this.RemovePlayerFromDictionary(aBan.ban_record.target_player.player_name); //Inform the server of the enforced ban if (verbose) { this.AdminSayMessage("Enforcing ban on " + aBan.ban_record.target_player.player_name + " for " + aBan.ban_record.record_message); } } } catch (Exception e) { aBan.ban_exception = new AdKatsException("Error while enforcing ban.", e); this.HandleException(aBan.ban_exception); } this.DebugWrite("Exiting enforceBan", 6); }
//DONE private Boolean UpdateBanStatus(AdKatsBan aBan) { DebugWrite("updateBanStatus starting!", 6); //Make sure database connection active if (this.HandlePossibleDisconnect()) { return false; } Boolean success = false; if (aBan == null) { this.ConsoleError("Ban invalid in updateBanStatus."); } else { try { //Conditionally modify the ban_sync for this server if (!aBan.ban_sync.Contains("*" + this._ServerID + "*")) { aBan.ban_sync += ("*" + this._ServerID + "*"); } using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { String query = @" UPDATE `" + this._MySqlDatabaseName + @"`.`adkats_bans` SET `ban_sync` = '" + aBan.ban_sync + @"', `ban_status` = '" + aBan.ban_status + @"' WHERE `ban_id` = " + aBan.ban_id; command.CommandText = query; //Attempt to execute the query if (command.ExecuteNonQuery() > 0) { success = true; } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while updating status of ban.", e)); } } DebugWrite("updateBanStatus finished!", 6); return success; }
//TODO complete private void UpdateDatabase37014000() { try { //Check if old database table exists if(!this.ConfirmTable("adkats_records")) { this.ConsoleWarn("Not updating database, no old tables to pull from."); return; } //If the new main record table contains records return without handling using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT * FROM `adkats_records_main` LIMIT 1"; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { this.ConsoleWarn("Not updating database, new records already found."); return; } } } } this.ConsoleWarn("Updating database information from version 3.7 spec to 4.0 spec. DO NOT DISABLE ADKATS!"); this.ConsoleWrite("Updating Users."); //Add new users for every player in the access list List<AdKatsUser> oldUsers = new List<AdKatsUser>(); using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `player_name`, `access_level` FROM `adkats_accesslist` ORDER BY `access_level` ASC"; using (MySqlDataReader reader = command.ExecuteReader()) { while(reader.Read()) { //Set all users to default guest role oldUsers.Add(new AdKatsUser(){ user_name = reader.GetString("player_name"), user_role = this._RoleKeyDictionary["guest_default"] }); } } } } foreach (AdKatsUser aUser in oldUsers) { this.ConsoleWrite("Processing user " + aUser.user_name); //Attempt to add soldiers matching the user's names this.TryAddUserSoldier(aUser, aUser.user_name); this.UploadUser(aUser); } this.ConsoleSuccess(oldUsers.Count + " old users fetched and updated to new spec."); this.ConsoleWarn("Updating Records..."); //Generate old->new command key dictionary Dictionary<String, AdKatsCommand> commandConversionDictionary = new Dictionary<string, AdKatsCommand>(); commandConversionDictionary.Add("AdminSay", this._CommandKeyDictionary["admin_say"]); commandConversionDictionary.Add("AdminTell", this._CommandKeyDictionary["admin_tell"]); commandConversionDictionary.Add("AdminYell", this._CommandKeyDictionary["admin_yell"]); commandConversionDictionary.Add("CallAdmin", this._CommandKeyDictionary["player_calladmin"]); commandConversionDictionary.Add("ConfirmReport", this._CommandKeyDictionary["player_report_confirm"]); commandConversionDictionary.Add("EndLevel", this._CommandKeyDictionary["round_end"]); commandConversionDictionary.Add("EnforceBan", this._CommandKeyDictionary["banenforcer_enforce"]); commandConversionDictionary.Add("Exception", this._CommandKeyDictionary["adkats_exception"]); commandConversionDictionary.Add("ForceMove", this._CommandKeyDictionary["player_fmove"]); commandConversionDictionary.Add("Forgive", this._CommandKeyDictionary["player_forgive"]); commandConversionDictionary.Add("Join", this._CommandKeyDictionary["player_join"]); commandConversionDictionary.Add("Kick", this._CommandKeyDictionary["player_kick"]); commandConversionDictionary.Add("Kill", this._CommandKeyDictionary["player_kill"]); commandConversionDictionary.Add("KickAll", this._CommandKeyDictionary["server_kickall"]); commandConversionDictionary.Add("LowPopKill", this._CommandKeyDictionary["player_kill_lowpop"]); commandConversionDictionary.Add("Move", this._CommandKeyDictionary["player_move"]); commandConversionDictionary.Add("Mute", this._CommandKeyDictionary["player_mute"]); commandConversionDictionary.Add("NextLevel", this._CommandKeyDictionary["round_next"]); commandConversionDictionary.Add("Nuke", this._CommandKeyDictionary["server_nuke"]); commandConversionDictionary.Add("PermaBan", this._CommandKeyDictionary["player_ban_perm"]); commandConversionDictionary.Add("PlayerSay", this._CommandKeyDictionary["player_say"]); commandConversionDictionary.Add("PlayerYell", this._CommandKeyDictionary["player_yell"]); commandConversionDictionary.Add("PlayerTell", this._CommandKeyDictionary["player_tell"]); commandConversionDictionary.Add("Punish", this._CommandKeyDictionary["player_punish"]); commandConversionDictionary.Add("RepeatKill", this._CommandKeyDictionary["player_kill_repeat"]); commandConversionDictionary.Add("Report", this._CommandKeyDictionary["player_report"]); commandConversionDictionary.Add("RestartLevel", this._CommandKeyDictionary["round_restart"]); commandConversionDictionary.Add("RequestRules", this._CommandKeyDictionary["self_rules"]); commandConversionDictionary.Add("RoundWhitelist", this._CommandKeyDictionary["player_roundwhitelist"]); commandConversionDictionary.Add("KillSelf", this._CommandKeyDictionary["self_kill"]); commandConversionDictionary.Add("Teamswap", this._CommandKeyDictionary["self_teamswap"]); commandConversionDictionary.Add("TempBan", this._CommandKeyDictionary["player_ban_temp"]); //TODO finish list this.ConsoleWrite("Updating Bans..."); //Download all bans Double totalBans = 0; Double bansDownloaded = 0; Double bansUpdated = 0; DateTime startTime = DateTime.UtcNow; using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT COUNT(*) AS `ban_count` FROM `adkats_banlist`"; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { totalBans = reader.GetInt64("ban_count"); } } } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `adkats_records`.`record_id`, `adkats_records`.`server_id`, `adkats_records`.`command_type`, `adkats_records`.`command_action`, `adkats_records`.`command_numeric`, `adkats_records`.`target_name`, `adkats_records`.`target_id`, `adkats_records`.`source_name`, `adkats_records`.`source_id`, `adkats_records`.`record_message`, `adkats_records`.`record_time`, `adkats_records`.`adkats_read`, `adkats_records`.`adkats_web`, `adkats_banlist`.`ban_id`, `adkats_banlist`.`player_id`, `adkats_banlist`.`latest_record_id`, `adkats_banlist`.`ban_status`, `adkats_banlist`.`ban_notes`, `adkats_banlist`.`ban_sync`, `adkats_banlist`.`ban_startTime`, `adkats_banlist`.`ban_endTime`, `adkats_banlist`.`ban_enforceName`, `adkats_banlist`.`ban_enforceGUID`, `adkats_banlist`.`ban_enforceIP` FROM `adkats_banlist` INNER JOIN `adkats_records` ON `adkats_banlist`.`latest_record_id` = `adkats_records`.`record_id`"; List<AdKatsBan> importedBans = new List<AdKatsBan>(); using (MySqlDataReader reader = command.ExecuteReader()) { //Loop through all incoming bans while (reader.Read()) { //Create the ban element AdKatsBan aBan = new AdKatsBan { ban_id = reader.GetInt64("ban_id"), ban_status = reader.GetString("ban_status"), ban_notes = reader.GetString("ban_notes"), ban_sync = reader.GetString("ban_sync"), ban_startTime = reader.GetDateTime("ban_startTime"), ban_endTime = reader.GetDateTime("ban_endTime"), ban_enforceName = (reader.GetString("ban_enforceName") == "Y"), ban_enforceGUID = (reader.GetString("ban_enforceGUID") == "Y"), ban_enforceIP = (reader.GetString("ban_enforceIP") == "Y") }; AdKatsRecord aRecord = new AdKatsRecord(); aRecord.record_source = AdKatsRecord.Sources.InternalAutomated; aRecord.server_id = reader.GetInt64("server_id"); AdKatsCommand aCommandType = null; if (commandConversionDictionary.TryGetValue(reader.GetString("command_type"), out aCommandType)) { aRecord.command_type = aCommandType; } else { //Skip record //this.ConsoleError("Unable to parse '" + reader.GetString("command_type") + "' as a valid command type. Skipping ban record."); continue; } AdKatsCommand aCommandAction = null; if (commandConversionDictionary.TryGetValue(reader.GetString("command_action"), out aCommandAction)) { aRecord.command_action = aCommandAction; } else { //Skip record //this.ConsoleError("Unable to parse '" + reader.GetString("command_action") + "' as a valid command action. Skipping ban record."); continue; } aRecord.command_numeric = reader.GetInt32("command_numeric"); aRecord.record_message = reader.GetString("record_message"); aRecord.target_name = reader.GetString("target_name"); if (!reader.IsDBNull(6)) { Int32 playerID = reader.GetInt32(6); aRecord.target_player = new AdKatsPlayer { player_id = playerID }; } aRecord.source_name = reader.GetString("source_name"); if (!reader.IsDBNull(8)) { Int32 playerID = reader.GetInt32(8); aRecord.source_player = new AdKatsPlayer { player_id = playerID }; } aRecord.record_time = reader.GetDateTime("record_time"); aBan.ban_record = aRecord; importedBans.Add(aBan); if (++bansDownloaded % 100 == 0) { this.ConsoleWrite(Math.Round(100 * bansDownloaded / totalBans, 2) + "% of bans downloaded. AVG " + Math.Round(bansDownloaded / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " downloads/sec."); } } } if (importedBans.Count > 0) { this.ConsoleWarn(importedBans.Count + " bans downloaded, beginning update to 4.0 spec."); } startTime = DateTime.UtcNow; //Upload all of those bans to the new database foreach (AdKatsBan aBan in importedBans) { this.UploadBan(aBan); if (++bansUpdated % 15 == 0) { this.ConsoleWrite(Math.Round(100 * bansUpdated / totalBans, 2) + "% of bans updated. AVG " + Math.Round(bansUpdated / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " updates/sec."); } } this.ConsoleSuccess("All AdKats Enforced bans updated to 4.0 spec."); } } //Import all records that do not have command action TempBan or PermaBan Double recordsDownloaded = 0; Double recordsProcessed = 0; List<AdKatsRecord> oldRecords = new List<AdKatsRecord>(); using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `record_id`, `server_id`, `command_type`, `command_action`, `command_numeric`, `target_name`, `target_id`, `source_name`, `source_id`, `record_message`, `record_time`, `adkats_read`, `adkats_web` FROM `adkats_records` WHERE `command_action` <> 'Exception' ORDER BY `record_id` ASC"; using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { AdKatsRecord aRecord = new AdKatsRecord(); aRecord.record_source = AdKatsRecord.Sources.InternalAutomated; aRecord.server_id = reader.GetInt64("server_id"); AdKatsCommand aCommandType = null; if (commandConversionDictionary.TryGetValue(reader.GetString("command_type"), out aCommandType)) { aRecord.command_type = aCommandType; } else { //Skip record //this.ConsoleError("Unable to parse '" + reader.GetString("command_type") + "' as a valid command type. Skipping record."); continue; } AdKatsCommand aCommandAction = null; if (commandConversionDictionary.TryGetValue(reader.GetString("command_action"), out aCommandAction)) { aRecord.command_action = aCommandAction; } else { //Skip record //this.ConsoleError("Unable to parse '" + reader.GetString("command_action") + "' as a valid command action. Cancelling database update."); return; } aRecord.command_numeric = reader.GetInt32("command_numeric"); aRecord.record_message = reader.GetString("record_message"); aRecord.target_name = reader.GetString("target_name"); if (!reader.IsDBNull(6)) { Int32 playerID = reader.GetInt32(6); aRecord.target_player = new AdKatsPlayer { player_id = playerID }; } aRecord.source_name = reader.GetString("source_name"); if (!reader.IsDBNull(8)) { Int32 playerID = reader.GetInt32(8); aRecord.source_player = new AdKatsPlayer { player_id = playerID }; } aRecord.record_time = reader.GetDateTime("record_time"); //Set all users to default guest role oldRecords.Add(aRecord); if (++recordsDownloaded % 5000 == 0) { this.ConsoleWrite(recordsDownloaded + " records downloaded for processing."); } } } } } this.ConsoleSuccess("All records prepared for update."); //Upload all of those records to the new database spec this.ConsoleWarn("Updating all prepared records..."); foreach (AdKatsRecord aRecord in oldRecords) { //Attempt to upload the record this.UploadRecord(aRecord); if (++recordsProcessed % 50 == 0) { this.ConsoleWrite(Math.Round(100 * recordsProcessed / recordsDownloaded, 3) + "% of records updated into 4.0 spec."); } } this.ConsoleSuccess("All records updated to 4.0 spec."); } catch (Exception e) { this.HandleException(new AdKatsException("Error while updating database information from 3.7 spec to 4.0 spec.", e)); } }
//DONE private AdKatsBan FetchPlayerBan(AdKatsPlayer player) { DebugWrite("fetchPlayerBan starting!", 6); AdKatsBan aBan = null; //Make sure database connection active if (this.HandlePossibleDisconnect()) { return null; } try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { //Build the query String query = @" SELECT `adkats_bans`.`ban_id`, `adkats_bans`.`player_id`, `adkats_bans`.`latest_record_id`, `adkats_bans`.`ban_status`, `adkats_bans`.`ban_notes`, `adkats_bans`.`ban_startTime`, `adkats_bans`.`ban_endTime`, `adkats_bans`.`ban_enforceName`, `adkats_bans`.`ban_enforceGUID`, `adkats_bans`.`ban_enforceIP`, `adkats_bans`.`ban_sync` FROM `adkats_bans` INNER JOIN `tbl_playerdata` ON `tbl_playerdata`.`PlayerID` = `adkats_bans`.`player_id` WHERE `adkats_bans`.`ban_status` = 'Active' "; if (this._GameID > 0) { query += " AND `tbl_playerdata`.`GameID` = " + this._GameID; } query += " AND ("; Boolean started = false; if (!String.IsNullOrEmpty(player.player_name)) { started = true; query += "(`tbl_playerdata`.`SoldierName` = '" + player.player_name + @"' AND `adkats_bans`.`ban_enforceName` = 'Y')"; } if (!String.IsNullOrEmpty(player.player_guid)) { if (started) { query += " OR "; } started = true; query += "(`tbl_playerdata`.`EAGUID` = '" + player.player_guid + "' AND `adkats_bans`.`ban_enforceGUID` = 'Y')"; } if (!String.IsNullOrEmpty(player.player_ip)) { if (started) { query += " OR "; } started = true; query += "(`tbl_playerdata`.`IP_Address` = '" + player.player_ip + "' AND `adkats_bans`.`ban_enforceIP` = 'Y')"; } if (!started) { this.HandleException(new AdKatsException("No data to fetch ban with. This should never happen.")); return null; } query += ")"; //Assign the query command.CommandText = query; using (MySqlDataReader reader = command.ExecuteReader()) { Boolean fetchedFirstBan = false; if (reader.Read()) { fetchedFirstBan = true; //Create the ban element aBan = new AdKatsBan { ban_id = reader.GetInt64("ban_id"), ban_status = reader.GetString("ban_status"), ban_notes = reader.GetString("ban_notes"), ban_sync = reader.GetString("ban_sync"), ban_startTime = reader.GetDateTime("ban_startTime"), ban_endTime = reader.GetDateTime("ban_endTime"), ban_enforceName = (reader.GetString("ban_enforceName") == "Y"), ban_enforceGUID = (reader.GetString("ban_enforceGUID") == "Y"), ban_enforceIP = (reader.GetString("ban_enforceIP") == "Y"), ban_record = this.FetchRecordByID(reader.GetInt64("latest_record_id"), false) }; //Get the record information } if (reader.Read() && fetchedFirstBan) { this.ConsoleWarn("Multiple banned players matched ban information, possible duplicate account"); } } } //If bans were fetched successfully, update the ban lists and sync back if (aBan != null) { Int64 totalSeconds = (long) aBan.ban_endTime.Subtract(DateTime.UtcNow).TotalSeconds; if (totalSeconds < 0) { aBan.ban_status = "Expired"; //Update the sync for this ban this.UpdateBanStatus(aBan); return null; } //Update the sync for this ban this.UpdateBanStatus(aBan); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while fetching player ban.", e)); } return aBan; }
private void SubmitToMetabans(AdKatsBan aBan, AssessmentTypes type) { DebugWrite("^4Metabans (SubmitAssessment): Submitting assessment of GUID " + aBan.ban_record.target_player.player_guid, 3); var api = new MetabansAPI(_metabansUsername, _metabansAPIKey, enumBoolOnOff.On); api.ExecuteCommand += new MetabansAPI.ExecuteCommandHandler(api_ExecuteCommand); api.mb_assess_player_ok += new MetabansAPI.RequestSuccessHandler(api_mb_assess_player_ok); SupportedGames gameType; switch (_gameVersion) { case GameVersion.BF3: gameType = SupportedGames.BF_3; break; case GameVersion.BF4: gameType = SupportedGames.BF_4; break; default: ConsoleError("Invalid game version when posting to metabans."); return; break; } api.mb_assess_player(gameType, aBan.ban_record.target_player.player_guid, type, aBan.ban_record.record_message, (int) (aBan.ban_endTime - aBan.ban_startTime).TotalSeconds).Post(); }
public void EnforceBan(AdKatsBan aBan, Boolean verbose) { DebugWrite("Entering enforceBan", 6); try { //Create the total kick message String generatedBanReason = GenerateBanReason(aBan); DebugWrite("Ban Enforce Message: '" + generatedBanReason + "'", 3); //Perform Actions if (_PlayerDictionary.ContainsKey(aBan.ban_record.target_player.player_name) && aBan.ban_startTime < DateTime.UtcNow) { ExecuteCommand("procon.protected.send", "admin.kickPlayer", aBan.ban_record.target_player.player_name, generatedBanReason); //Inform the server of the enforced ban if (verbose) { String banDurationString; //If ban time > 1000 days just say perm TimeSpan remainingTime = GetRemainingBanTime(aBan); if (remainingTime.TotalDays > 1000) { banDurationString = "permanent"; } else { banDurationString = FormatTimeString(remainingTime, 2); } AdminSayMessage("Enforcing " + banDurationString + " ban on " + aBan.ban_record.target_player.player_name + " for " + aBan.ban_record.record_message); } } } catch (Exception e) { aBan.ban_exception = new AdKatsException("Error while enforcing ban.", e); HandleException(aBan.ban_exception); } DebugWrite("Exiting enforceBan", 6); }
//DONE private void ImportBansFromBBM5108() { //Check if tables exist from BF3 Ban Manager if (!this.ConfirmTable("bm_banlist")) { return; } this.ConsoleWarn("BF3 Ban Manager tables detected. Checking validity...."); //Check if any BBM5108 bans exist in the AdKats Banlist try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT * FROM `" + this._MySqlDatabaseName + @"`.`adkats_bans` WHERE `adkats_bans`.`ban_notes` = 'BBM5108' LIMIT 1"; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { this.ConsoleWarn("BF3 Ban Manager bans already imported, canceling import."); return; } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while checking for BBM Bans.", e)); return; } this.ConsoleWarn("Validity confirmed. Preparing to fetch all BF3 Ban Manager Bans..."); Double totalBans = 0; Double bansImported = 0; Queue<BBM5108Ban> inboundBBMBans = new Queue<BBM5108Ban>(); DateTime startTime = DateTime.UtcNow; try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { this.DebugWrite("Creating query to import BBM5108", 3); command.CommandText = @" SELECT soldiername, eaguid, ban_length, ban_duration, ban_reason FROM bm_banlist INNER JOIN bm_soldiers ON bm_banlist.soldierID = bm_soldiers.soldierID"; using (MySqlDataReader reader = command.ExecuteReader()) { Boolean told = false; while (reader.Read()) { if (!told) { this.DebugWrite("BBM5108 bans found, grabbing.", 3); told = true; } BBM5108Ban bbmBan = new BBM5108Ban { soldiername = reader.IsDBNull(reader.GetOrdinal("soldiername")) ? null : reader.GetString("soldiername"), eaguid = reader.IsDBNull(reader.GetOrdinal("eaguid")) ? null : reader.GetString("eaguid"), ban_length = reader.GetString("ban_length"), ban_duration = reader.GetDateTime("ban_duration"), ban_reason = reader.IsDBNull(reader.GetOrdinal("ban_reason")) ? null : reader.GetString("ban_reason") }; inboundBBMBans.Enqueue(bbmBan); totalBans++; } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while fetching BBM Bans.", e)); return; } this.ConsoleWarn(totalBans + " Ban Manager bans fetched, starting import to AdKats Ban Enforcer..."); try { //Loop through all BBMBans in order that they came in while (inboundBBMBans.Count > 0) { //Break from the loop if the plugin is disabled or the setting is reverted. if (!this._IsEnabled || !this._UseBanEnforcer) { this.ConsoleError("You exited the ban import process process early, the process was not completed and cannot recover without manual override. Talk to ColColonCleaner."); break; } BBM5108Ban bbmBan = inboundBBMBans.Dequeue(); //Create the record AdKatsRecord record = new AdKatsRecord(); //Fetch the player record.target_player = this.FetchPlayer(true, true, -1, bbmBan.soldiername, bbmBan.eaguid, null); record.record_source = AdKatsRecord.Sources.InternalAutomated; if (bbmBan.ban_length == "permanent") { this.DebugWrite("Ban is permanent", 4); record.command_type = this._CommandKeyDictionary["player_ban_perm"]; record.command_action = this._CommandKeyDictionary["player_ban_perm"]; record.command_numeric = 0; } else if (bbmBan.ban_length == "seconds") { this.DebugWrite("Ban is temporary", 4); record.command_type = this._CommandKeyDictionary["player_ban_temp"]; record.command_action = this._CommandKeyDictionary["player_ban_temp"]; record.command_numeric = (Int32) (bbmBan.ban_duration - DateTime.UtcNow).TotalMinutes; } else { //Ignore all other cases e.g. round bans this.DebugWrite("Ban type '" + bbmBan.ban_length + "' not usable", 3); continue; } record.source_name = "BanEnforcer"; record.server_id = this._ServerID; if (!String.IsNullOrEmpty(record.target_player.player_name)) { record.target_name = record.target_player.player_name; } record.isIRO = false; record.record_message = bbmBan.ban_reason; //Update the ban enforcement depending on available information Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); //Create the ban AdKatsBan aBan = new AdKatsBan { ban_record = record, ban_notes = "BBM5108", ban_enforceName = nameAvailable && (this._DefaultEnforceName || (!guidAvailable && !ipAvailable) || !String.IsNullOrEmpty(bbmBan.soldiername)), ban_enforceGUID = guidAvailable && (this._DefaultEnforceGUID || (!nameAvailable && !ipAvailable) || !String.IsNullOrEmpty(bbmBan.eaguid)), ban_enforceIP = ipAvailable && this._DefaultEnforceIP }; if (!aBan.ban_enforceName && !aBan.ban_enforceGUID && !aBan.ban_enforceIP) { this.ConsoleError("Unable to create ban, no proper player information"); continue; } //Upload the ban this.DebugWrite("Uploading Ban Manager ban.", 5); this.UploadBan(aBan); if (++bansImported % 25 == 0) { this.ConsoleWrite(Math.Round(100 * bansImported / totalBans, 2) + "% of Ban Manager bans uploaded. AVG " + Math.Round(bansImported / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " uploads/sec."); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while processing imported BBM Bans to AdKats banlist.", e)); return; } if (inboundBBMBans.Count == 0) { this.ConsoleSuccess("All Ban Manager bans imported into AdKats Ban Enforcer!"); } }
public void PermaBanTarget(AdKatsRecord record, String additionalMessage) { DebugWrite("Entering permaBanTarget", 6); try { //Perform Actions //Only post to ban enforcer if there are no exceptions if (_UseBanEnforcer && record.record_exception == null) { //Update the ban enforcement depending on available information Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); //Create the ban var aBan = new AdKatsBan { ban_record = record, ban_enforceName = nameAvailable && (_DefaultEnforceName || (!guidAvailable && !ipAvailable)), ban_enforceGUID = guidAvailable && (_DefaultEnforceGUID || (!nameAvailable && !ipAvailable)), ban_enforceIP = ipAvailable && (_DefaultEnforceIP || (!nameAvailable && !guidAvailable)) }; //Queue the ban for upload QueueBanForProcessing(aBan); } else { if (record.record_exception != null) { HandleException(new AdKatsException("Defaulting to procon banlist usage since exceptions existed in record")); } //Trim the ban message if necessary String banMessage = record.source_name + " - " + record.record_message; Int32 cutLength = banMessage.Length - 80; if (cutLength > 0) { banMessage = banMessage.Substring(0, banMessage.Length - cutLength); } DebugWrite("Ban Message: '" + banMessage + "'", 3); if (!String.IsNullOrEmpty(record.target_player.player_guid)) { ExecuteCommand("procon.protected.send", "banList.add", "guid", record.target_player.player_guid, "perm", banMessage); ExecuteCommand("procon.protected.send", "banList.save"); ExecuteCommand("procon.protected.send", "banList.list"); } else if (!String.IsNullOrEmpty(record.target_player.player_ip)) { ExecuteCommand("procon.protected.send", "banList.add", "ip", record.target_player.player_ip, "perm", banMessage); ExecuteCommand("procon.protected.send", "banList.save"); ExecuteCommand("procon.protected.send", "banList.list"); } else if (!String.IsNullOrEmpty(record.target_player.player_name)) { ExecuteCommand("procon.protected.send", "banList.add", "id", record.target_player.player_name, "perm", banMessage); ExecuteCommand("procon.protected.send", "banList.save"); ExecuteCommand("procon.protected.send", "banList.list"); } else { ConsoleError("Player has no information to ban with."); SendMessageToSource(record, "ERROR"); } } if (record.target_name != record.source_name) { AdminSayMessage("Player " + record.target_player.player_name + " was BANNED by " + ((_ShowAdminNameInSay) ? (record.source_name) : ("admin")) + " for " + record.record_message + additionalMessage); } SendMessageToSource(record, "You PERMA BANNED " + record.target_player.player_name + "." + additionalMessage); record.record_action_executed = true; } catch (Exception e) { record.record_exception = new AdKatsException("Error while taking action for PermaBan record.", e); HandleException(record.record_exception); FinalizeRecord(record); } DebugWrite("Exiting permaBanTarget", 6); }
public void FuturePermaBanTarget(AdKatsRecord record, String additionalMessage) { DebugWrite("Entering permaBanTarget", 6); try { record.record_action_executed = true; if (_UseBanEnforcer && record.record_exception == null) { Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); var aBan = new AdKatsBan { ban_record = record, ban_enforceName = nameAvailable && (_DefaultEnforceName || (!guidAvailable && !ipAvailable)), ban_enforceGUID = guidAvailable && (_DefaultEnforceGUID || (!nameAvailable && !ipAvailable)), ban_enforceIP = ipAvailable && (_DefaultEnforceIP || (!nameAvailable && !guidAvailable)) }; QueueBanForProcessing(aBan); DateTime endTime = record.record_time + TimeSpan.FromMinutes(record.command_numeric); SendMessageToSource(record, "You FUTURE BANNED " + record.target_player.player_name + ". Their ban will activate at " + endTime + " UTC. " + additionalMessage); } else { SendMessageToSource(record, "Future ban cannot be posted."); FinalizeRecord(record); return; } } catch (Exception e) { record.record_exception = new AdKatsException("Error while taking action for PermaBan record.", e); HandleException(record.record_exception); FinalizeRecord(record); } DebugWrite("Exiting permaBanTarget", 6); }
private void QueueBanForProcessing(AdKatsBan aBan) { DebugWrite("Entering queueBanForProcessing", 7); try { if (_pluginEnabled) { DebugWrite("Preparing to queue ban for processing", 6); if (_isTestingAuthorized) PushThreadDebug(DateTime.Now.Ticks, (String.IsNullOrEmpty(Thread.CurrentThread.Name) ? ("mainthread") : (Thread.CurrentThread.Name)), Thread.CurrentThread.ManagedThreadId, new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(), ""); lock (_BanEnforcerProcessingQueue) { _BanEnforcerProcessingQueue.Enqueue(aBan); DebugWrite("Ban queued for processing", 6); _DbCommunicationWaitHandle.Set(); } } } catch (Exception e) { HandleException(new AdKatsException("Error while queueing ban for processing.", e)); } DebugWrite("Exiting queueBanForProcessing", 7); }
//DONE private List<AdKatsBan> FetchPlayerBans(AdKatsPlayer player) { DebugWrite("FetchPlayerBans starting!", 6); var aBanList = new List<AdKatsBan>(); //Make sure database connection active if (HandlePossibleDisconnect()) { return null; } try { using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { //Build the query String query = @" SELECT `adkats_bans`.`ban_id`, `adkats_bans`.`player_id`, `adkats_bans`.`latest_record_id`, `adkats_bans`.`ban_status`, `adkats_bans`.`ban_notes`, `adkats_bans`.`ban_startTime`, `adkats_bans`.`ban_endTime`, `adkats_bans`.`ban_enforceName`, `adkats_bans`.`ban_enforceGUID`, `adkats_bans`.`ban_enforceIP`, `adkats_bans`.`ban_sync` FROM `adkats_bans` INNER JOIN `tbl_playerdata` ON `tbl_playerdata`.`PlayerID` = `adkats_bans`.`player_id` WHERE `adkats_bans`.`ban_status` = 'Active' "; if (_gameID > 0 && player.game_id < 0) { query += " AND `tbl_playerdata`.`GameID` = " + _gameID; } else if (player.game_id > 0) { query += " AND `tbl_playerdata`.`GameID` = " + player.game_id; } else { ConsoleError("Unusable game IDs when fetching player bans for " + player.player_name + "."); return aBanList; } query += " AND ("; Boolean started = false; if (!String.IsNullOrEmpty(player.player_name)) { started = true; query += "(`tbl_playerdata`.`SoldierName` = '" + player.player_name + @"' AND `adkats_bans`.`ban_enforceName` = 'Y')"; } if (!String.IsNullOrEmpty(player.player_guid)) { if (started) { query += " OR "; } started = true; query += "(`tbl_playerdata`.`EAGUID` = '" + player.player_guid + "' AND `adkats_bans`.`ban_enforceGUID` = 'Y')"; } if (!String.IsNullOrEmpty(player.player_ip)) { if (started) { query += " OR "; } started = true; query += "(`tbl_playerdata`.`IP_Address` = '" + player.player_ip + "' AND `adkats_bans`.`ban_enforceIP` = 'Y')"; } if (!started) { HandleException(new AdKatsException("No data to fetch ban with. This should never happen.")); return aBanList; } query += ")"; //Assign the query command.CommandText = query; using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { //Create the ban element var aBan = new AdKatsBan { ban_id = reader.GetInt64("ban_id"), ban_status = reader.GetString("ban_status"), ban_notes = reader.GetString("ban_notes"), ban_sync = reader.GetString("ban_sync"), ban_startTime = reader.GetDateTime("ban_startTime"), ban_endTime = reader.GetDateTime("ban_endTime"), ban_enforceName = (reader.GetString("ban_enforceName") == "Y"), ban_enforceGUID = (reader.GetString("ban_enforceGUID") == "Y"), ban_enforceIP = (reader.GetString("ban_enforceIP") == "Y"), ban_record = FetchRecordByID(reader.GetInt64("latest_record_id"), false) }; if (aBan.ban_endTime.Subtract(DateTime.UtcNow).TotalSeconds < 0) { aBan.ban_status = "Expired"; UpdateBanStatus(aBan); } else if (!String.IsNullOrEmpty(player.player_name_previous) && aBan.ban_enforceName && !aBan.ban_enforceGUID && !aBan.ban_enforceIP) { var record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = _serverID, command_type = _CommandKeyDictionary["player_unban"], command_numeric = 0, target_name = player.player_name, target_player = player, source_name = "BanEnforcer", record_message = "Name-Banned player has changed their name. (" + player.player_name_previous + " -> " + player.player_name + ")" }; QueueRecordForProcessing(record); } else if (_serverGroup == FetchServerGroup(aBan.ban_record.server_id) && aBan.ban_startTime < DateTime.UtcNow) { aBanList.Add(aBan); } } if (aBanList.Count > 1) { ConsoleWarn("Multiple bans matched player information, multiple accounts detected."); } } } } } catch (Exception e) { HandleException(new AdKatsException("Error while fetching player ban.", e)); } DebugWrite("FetchPlayerBans finished!", 6); return aBanList; }
private AdKatsBan FetchBanByID(Int64 ban_id) { DebugWrite("FetchBanByID starting!", 6); AdKatsBan aBan = null; //Make sure database connection active if (HandlePossibleDisconnect()) { return null; } try { using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { //Build the query command.CommandText = @" SELECT `ban_id`, `player_id`, `latest_record_id`, `ban_status`, `ban_notes`, `ban_startTime`, `ban_endTime`, `ban_enforceName`, `ban_enforceGUID`, `ban_enforceIP`, `ban_sync` FROM `adkats_bans` WHERE `ban_id` = @ban_id"; command.Parameters.AddWithValue("@ban_id", ban_id); using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { //Create the ban object aBan = new AdKatsBan { ban_id = reader.GetInt64("ban_id"), ban_status = reader.GetString("ban_status"), ban_notes = reader.GetString("ban_notes"), ban_sync = reader.GetString("ban_sync"), ban_startTime = reader.GetDateTime("ban_startTime"), ban_endTime = reader.GetDateTime("ban_endTime"), ban_enforceName = (reader.GetString("ban_enforceName") == "Y"), ban_enforceGUID = (reader.GetString("ban_enforceGUID") == "Y"), ban_enforceIP = (reader.GetString("ban_enforceIP") == "Y"), ban_record = FetchRecordByID(reader.GetInt64("latest_record_id"), false) }; if (aBan.ban_endTime.Subtract(DateTime.UtcNow).TotalSeconds < 0) { aBan.ban_status = "Expired"; UpdateBanStatus(aBan); } } } } } } catch (Exception e) { HandleException(new AdKatsException("Error while fetching ban.", e)); } DebugWrite("FetchBanByID finished!", 6); return aBan; }
public void TempBanTarget(AdKatsRecord record, String additionalMessage) { this.DebugWrite("Entering tempBanTarget", 6); try { //Subtract 1 second for visual effect Int32 seconds = (record.command_numeric * 60) - 1; //Perform Actions //Only post to ban enforcer if there are no exceptions if (this._UseBanEnforcer && record.record_exception == null) { //Update the ban enforcement depending on available information Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); //Create the ban AdKatsBan aBan = new AdKatsBan { ban_record = record, ban_enforceName = nameAvailable && (this._DefaultEnforceName || (!guidAvailable && !ipAvailable)), ban_enforceGUID = guidAvailable && (this._DefaultEnforceGUID || (!nameAvailable && !ipAvailable)), ban_enforceIP = ipAvailable && (this._DefaultEnforceIP || (!nameAvailable && !guidAvailable)) }; //Queue the ban for upload this.QueueBanForProcessing(aBan); } else { if (record.record_exception != null) { this.HandleException(new AdKatsException("Defaulting to procon banlist usage since exceptions existed in record")); } //Trim the ban message if necessary String banMessage = record.record_message; Int32 cutLength = banMessage.Length - 80; if (cutLength > 0) { banMessage = banMessage.Substring(0, banMessage.Length - cutLength); } this.DebugWrite("Ban Message: '" + banMessage + "'", 3); if (!String.IsNullOrEmpty(record.target_player.player_guid)) { this.ExecuteCommand("procon.protected.send", "banList.add", "guid", record.target_player.player_guid, "seconds", seconds + "", banMessage); this.ExecuteCommand("procon.protected.send", "banList.save"); this.ExecuteCommand("procon.protected.send", "banList.list"); } else if (!String.IsNullOrEmpty(record.target_player.player_ip)) { this.ExecuteCommand("procon.protected.send", "banList.add", "ip", record.target_player.player_ip, "seconds", seconds + "", banMessage); this.ExecuteCommand("procon.protected.send", "banList.save"); this.ExecuteCommand("procon.protected.send", "banList.list"); } else if (!String.IsNullOrEmpty(record.target_player.player_name)) { this.ExecuteCommand("procon.protected.send", "banList.add", "id", record.target_player.player_name, "seconds", seconds + "", banMessage); this.ExecuteCommand("procon.protected.send", "banList.save"); this.ExecuteCommand("procon.protected.send", "banList.list"); } else { this.ConsoleError("Player has no information to ban with."); this.SendMessageToSource(record, "ERROR"); } this.RemovePlayerFromDictionary(record.target_player.player_name); } if (record.target_name != record.source_name) { this.AdminSayMessage("Player " + record.target_name + " was BANNED by " + ((this._ShowAdminNameInSay) ? (record.source_name) : ("admin")) + " for " + record.record_message + " " + additionalMessage); } this.SendMessageToSource(record, "You TEMP BANNED " + record.target_name + " for " + this.FormatTimeString(TimeSpan.FromMinutes(record.command_numeric)) + "." + additionalMessage); record.record_action_executed = true; } catch (Exception e) { record.record_exception = new AdKatsException("Error while taking action for TempBan record.", e); this.HandleException(record.record_exception); this.FinalizeRecord(record); } this.DebugWrite("Exiting tempBanTarget", 6); }
private void QueueBanForProcessing(AdKatsBan aBan) { this.DebugWrite("Entering queueBanForProcessing", 7); try { if (this._IsEnabled) { this.DebugWrite("Preparing to queue ban for processing", 6); lock (_BanEnforcerMutex) { this._BanEnforcerProcessingQueue.Enqueue(aBan); this.DebugWrite("Ban queued for processing", 6); this._DbCommunicationWaitHandle.Set(); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while queueing ban for processing.", e)); } this.DebugWrite("Exiting queueBanForProcessing", 7); }
private void DatabaseCommunicationThreadLoop() { try { this.DebugWrite("DBCOMM: Starting Database Comm Thread", 1); Thread.CurrentThread.Name = "databasecomm"; Boolean firstRun = true; while (true) { try { this.DebugWrite("DBCOMM: Entering Database Comm Thread Loop", 7); if (!this._IsEnabled) { this.DebugWrite("DBCOMM: Detected AdKats not enabled. Exiting thread " + Thread.CurrentThread.Name, 6); break; } //Sleep for 10ms Thread.Sleep(10); //Check if database connection settings have changed if (this._DbSettingsChanged) { this.DebugWrite("DBCOMM: DB Settings have changed, calling test.", 6); if (this.TestDatabaseConnection()) { this.DebugWrite("DBCOMM: Database Connection Good. Continuing Thread.", 6); } else { this._DbSettingsChanged = true; continue; } } //On first run, pull all roles and commands and update database if needed if (firstRun) { this.FetchCommands(); this.FetchRoles(); this.UpdateDatabase37014000(); } //Every 60 seconds feed stat logger settings if (this._LastStatLoggerStatusUpdateTime.AddSeconds(60) < DateTime.UtcNow) { this._LastStatLoggerStatusUpdateTime = DateTime.UtcNow; if (this._StatLoggerVersion == "BF3") { //this.setExternalPluginSetting("CChatGUIDStatsLoggerBF3", "Enable Chatlogging?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLoggerBF3", "Log ServerSPAM?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLoggerBF3", "Instant Logging of Chat Messages?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLoggerBF3", "Enable chatlog filter(Regex)?", "No"); if (this._FeedStatLoggerSettings) { //Due to narwhals, Stat logger time offset is in the opposite direction of Adkats time offset Double slOffset = DateTime.UtcNow.Subtract(DateTime.Now).TotalHours; this.SetExternalPluginSetting("CChatGUIDStatsLoggerBF3", "Servertime Offset", slOffset + ""); } } else if (this._StatLoggerVersion == "UNIVERSAL") { //this.setExternalPluginSetting("CChatGUIDStatsLogger", "Enable Chatlogging?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLogger", "Log ServerSPAM?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLogger", "Instant Logging of Chat Messages?", "No"); //this.setExternalPluginSetting("CChatGUIDStatsLogger", "Enable chatlog filter(Regex)?", "No"); if (this._FeedStatLoggerSettings) { //Due to narwhals, Stat logger time offset is in the opposite direction of Adkats time offset Double slOffset = DateTime.UtcNow.Subtract(DateTime.Now).TotalHours; this.SetExternalPluginSetting("CChatGUIDStatsLogger", "Servertime Offset", slOffset + ""); } } else { this.ConsoleError("Stat logger version is unknown, unable to feed stat logger settings."); } //TODO put back in the future //this.confirmStatLoggerSetup(); } //Update server ID if (this._ServerID < 0) { //Checking for database server info if (this.FetchServerID() >= 0) { this.ConsoleSuccess("Database Server Info Fetched. Server ID is " + this._ServerID + "!"); //Push all settings for this instance to the database this.UploadAllSettings(); } else { //Inform the user this.ConsoleError("Database Server info could not be fetched! Make sure XpKiller's Stat Logger is running on this server!"); //Disable the plugin this.Disable(); break; } } else { this.DebugWrite("Skipping server ID fetch. Server ID: " + this._ServerID, 7); } //Check if settings need sync if (this._SettingImportID != this._ServerID || this._LastDbSettingFetch.AddSeconds(DbSettingFetchFrequency) < DateTime.UtcNow) { this.DebugWrite("Preparing to fetch settings from server " + _ServerID, 6); //Fetch new settings from the database this.FetchSettings(this._SettingImportID, this._SettingImportID != this._ServerID); } //Handle Inbound Setting Uploads if (this._SettingUploadQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound setting queue to get new settings", 7); Queue<CPluginVariable> inboundSettingUpload; lock (this._SettingUploadQueue) { this.DebugWrite("DBCOMM: Inbound settings found. Grabbing.", 6); //Grab all settings in the queue inboundSettingUpload = new Queue<CPluginVariable>(this._SettingUploadQueue.ToArray()); //Clear the queue for next run this._SettingUploadQueue.Clear(); } //Loop through all settings in order that they came in while (inboundSettingUpload.Count > 0) { CPluginVariable setting = inboundSettingUpload.Dequeue(); this.UploadSetting(setting); } } //Handle Inbound Command Uploads if (this._CommandUploadQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound command queue to get new commands", 7); Queue<AdKatsCommand> inboundCommandUpload; lock (this._CommandUploadQueue) { this.DebugWrite("DBCOMM: Inbound commands found. Grabbing.", 6); //Grab all commands in the queue inboundCommandUpload = new Queue<AdKatsCommand>(this._CommandUploadQueue.ToArray()); //Clear the queue for next run this._CommandUploadQueue.Clear(); } //Loop through all commands in order that they came in while (inboundCommandUpload.Count > 0) { AdKatsCommand command = inboundCommandUpload.Dequeue(); this.UploadCommand(command); this.FetchCommands(); this.FetchRoles(); this.FetchUserList(); this.UpdateSettingPage(); } } //Handle Inbound Role Uploads if (this._RoleUploadQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound role queue to get new roles", 7); Queue<AdKatsRole> inboundRoleUpload; lock (this._RoleUploadQueue) { this.DebugWrite("DBCOMM: Inbound roles found. Grabbing.", 6); //Grab all roles in the queue inboundRoleUpload = new Queue<AdKatsRole>(this._RoleUploadQueue.ToArray()); //Clear the queue for next run this._RoleUploadQueue.Clear(); } //Loop through all roles in order that they came in while (inboundRoleUpload.Count > 0) { AdKatsRole aRole = inboundRoleUpload.Dequeue(); this.UploadRole(aRole); this.FetchCommands(); this.FetchRoles(); this.FetchUserList(); this.UpdateSettingPage(); } } //Handle Inbound Role Removal if (this._RoleRemovalQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock removal role queue to get new roles", 7); Queue<AdKatsRole> inboundRoleRemoval; lock (this._RoleRemovalQueue) { this.DebugWrite("DBCOMM: Inbound roles found. Grabbing.", 6); //Grab all roles in the queue inboundRoleRemoval = new Queue<AdKatsRole>(this._RoleRemovalQueue.ToArray()); //Clear the queue for next run this._RoleRemovalQueue.Clear(); } //Loop through all commands in order that they came in while (inboundRoleRemoval.Count > 0) { AdKatsRole aRole = inboundRoleRemoval.Dequeue(); this.RemoveRole(aRole); this.FetchCommands(); this.FetchRoles(); this.FetchUserList(); this.UpdateSettingPage(); } } //Check for new actions from the database at given interval if (this._FetchActionsFromDb && (DateTime.UtcNow > this._LastDbActionFetch.AddSeconds(DbActionFetchFrequency))) { this.RunActionsFromDB(); } else { this.DebugWrite("DBCOMM: Skipping DB action fetch", 7); } //Call banlist at set interval (20 seconds) if (this._UseBanEnforcerPreviousState && (DateTime.UtcNow > this._LastBanListCall.AddSeconds(20))) { this._LastBanListCall = DateTime.UtcNow; this.DebugWrite("banlist.list called at interval.", 6); this.ExecuteCommand("procon.protected.send", "banList.list"); } //Handle access updates if (this._UserUploadQueue.Count > 0 || this._UserRemovalQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound access queues to retrive access changes", 7); Queue<AdKatsUser> inboundUserRemoval; Queue<AdKatsUser> inboundUserUploads; lock (_UserMutex) { this.DebugWrite("DBCOMM: Inbound access changes found. Grabbing.", 6); //Grab all in the queue inboundUserUploads = new Queue<AdKatsUser>(this._UserUploadQueue.ToArray()); inboundUserRemoval = new Queue<AdKatsUser>(this._UserRemovalQueue.ToArray()); //Clear the queue for next run this._UserUploadQueue.Clear(); this._UserRemovalQueue.Clear(); } //Loop through all records in order that they came in while (inboundUserUploads.Count > 0) { AdKatsUser user = inboundUserUploads.Dequeue(); this.UploadUser(user); } //Loop through all records in order that they came in while (inboundUserRemoval.Count > 0) { AdKatsUser user = inboundUserRemoval.Dequeue(); this.ConsoleWarn("Removing user " + user.user_name); this.RemoveUser(user); } this.FetchUserList(); //Update the setting page with new information this.UpdateSettingPage(); } else if (DateTime.UtcNow > this._LastUserFetch.AddSeconds(DbUserFetchFrequency)) { //Handle user updates directly from the database this.FetchUserList(); //If there are now users in the user list, update the UI if (this._UserCache.Count > 0) { //Update the setting page with new information this.UpdateSettingPage(); } } else if (this._UserCache.Count == 0) { //Handle access updates directly from the database this.FetchUserList(); //If there are now people in the access list, update the UI if (this._UserCache.Count > 0) { //Update the setting page with new information this.UpdateSettingPage(); } } else { this.DebugWrite("DBCOMM: No inbound user changes.", 7); } //Start the other threads if (firstRun) { //Start other threads this._PlayerListingThread.Start(); this._KillProcessingThread.Start(); this._MessageProcessingThread.Start(); this._CommandParsingThread.Start(); this._ActionHandlingThread.Start(); this._TeamSwapThread.Start(); this._BanEnforcerThread.Start(); this._HackerCheckerThread.Start(); firstRun = false; this._ThreadsReady = true; this.UpdateSettingPage(); //Register a command to indicate availibility to other plugins this.RegisterCommand(this._IssueCommandMatchCommand); this.RegisterCommand(this._FetchAuthorizedSoldiersMatchCommand); this.ConsoleWrite("^b^2Running!^n^0 Version: " + this.GetPluginVersion()); } //Ban Enforcer if (this._UseBanEnforcer) { this.FetchNameBanCount(); this.FetchGUIDBanCount(); this.FetchIPBanCount(); if (!this._UseBanEnforcerPreviousState || (DateTime.UtcNow > this._LastDbBanFetch.AddSeconds(DbBanFetchFrequency))) { //Load all bans on startup if (!this._UseBanEnforcerPreviousState) { //Get all bans from procon this.ConsoleWarn("Preparing to queue procon bans for import. Please wait."); this._DbCommunicationWaitHandle.Reset(); this.ExecuteCommand("procon.protected.send", "banList.list"); this._DbCommunicationWaitHandle.WaitOne(TimeSpan.FromMinutes(5)); if (this._CBanProcessingQueue.Count > 0) { this.ConsoleWrite(this._CBanProcessingQueue.Count + " procon bans queued for import. Import might take several minutes if you have many bans!"); } else { this.ConsoleWrite("No procon bans to import into Ban Enforcer."); } } } else { this.DebugWrite("DBCOMM: Skipping DB ban fetch", 7); } //Handle Inbound Ban Comms if (this._BanEnforcerProcessingQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound ban enforcer queue to retrive new bans", 7); Queue<AdKatsBan> inboundBans; lock (this._BanEnforcerMutex) { this.DebugWrite("DBCOMM: Inbound bans found. Grabbing.", 6); //Grab all messages in the queue inboundBans = new Queue<AdKatsBan>(this._BanEnforcerProcessingQueue.ToArray()); //Clear the queue for next run this._BanEnforcerProcessingQueue.Clear(); } Int32 index = 1; //Loop through all bans in order that they came in while (inboundBans.Count > 0) { if (!this._IsEnabled || !this._UseBanEnforcer) { this.ConsoleWarn("Canceling ban import mid-operation."); break; } //Grab the ban AdKatsBan aBan = inboundBans.Dequeue(); this.DebugWrite("DBCOMM: Processing Frostbite Ban: " + index++, 6); //Upload the ban this.UploadBan(aBan); //Only perform special action when ban is direct //Indirect bans are through the procon banlist, so the player has already been kicked if (aBan.ban_record.source_name != "BanEnforcer") { //Enforce the ban this.EnforceBan(aBan, false); } else { this.RemovePlayerFromDictionary(aBan.ban_record.target_player.player_name); } } } //Handle BF3 Ban Manager imports if (!this._UseBanEnforcerPreviousState) { //Import all bans from BF3 Ban Manager this.ImportBansFromBBM5108(); } //Handle Inbound CBan Uploads if (this._CBanProcessingQueue.Count > 0) { if (!this._UseBanEnforcerPreviousState) { this.ConsoleWarn("Do not disable AdKats or change any settings until upload is complete!"); } this.DebugWrite("DBCOMM: Preparing to lock inbound cBan queue to retrive new cBans", 7); Double totalCBans = 0; Double bansImported = 0; Boolean earlyExit = false; DateTime startTime = DateTime.UtcNow; Queue<CBanInfo> inboundCBans; lock (this._CBanProcessingQueue) { this.DebugWrite("DBCOMM: Inbound cBans found. Grabbing.", 6); //Grab all cBans in the queue inboundCBans = new Queue<CBanInfo>(this._CBanProcessingQueue.ToArray()); totalCBans = inboundCBans.Count; //Clear the queue for next run this._CBanProcessingQueue.Clear(); } //Loop through all cBans in order that they came in Boolean bansFound = false; while (inboundCBans.Count > 0) { //Break from the loop if the plugin is disabled or the setting is reverted. if (!this._IsEnabled || !this._UseBanEnforcer) { this.ConsoleWarn("You exited the ban upload process early, the process was not completed."); earlyExit = true; break; } bansFound = true; CBanInfo cBan = inboundCBans.Dequeue(); //Create the record AdKatsRecord record = new AdKatsRecord(); record.record_source = AdKatsRecord.Sources.InternalAutomated; //Permabans and Temp bans longer than 1 year will be defaulted to permaban if (cBan.BanLength.Seconds > 0 && cBan.BanLength.Seconds < 31536000) { record.command_type = this._CommandKeyDictionary["player_ban_temp"]; record.command_action = this._CommandKeyDictionary["player_ban_temp"]; record.command_numeric = cBan.BanLength.Seconds / 60; } else { record.command_type = this._CommandKeyDictionary["player_ban_perm"]; record.command_action = this._CommandKeyDictionary["player_ban_perm"]; record.command_numeric = 0; } record.source_name = this._CBanAdminName; record.server_id = this._ServerID; record.target_player = this.FetchPlayer(true, true, -1, cBan.SoldierName, cBan.Guid, cBan.IpAddress); if (!String.IsNullOrEmpty(record.target_player.player_name)) { record.target_name = record.target_player.player_name; } record.isIRO = false; record.record_message = cBan.Reason; //Update the ban enforcement depending on available information Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); //Create the ban AdKatsBan aBan = new AdKatsBan { ban_record = record, ban_enforceName = nameAvailable && (this._DefaultEnforceName || (!guidAvailable && !ipAvailable) || !String.IsNullOrEmpty(cBan.SoldierName)), ban_enforceGUID = guidAvailable && (this._DefaultEnforceGUID || (!nameAvailable && !ipAvailable) || !String.IsNullOrEmpty(cBan.Guid)), ban_enforceIP = ipAvailable && (this._DefaultEnforceIP || (!nameAvailable && !guidAvailable) || !String.IsNullOrEmpty(cBan.IpAddress)) }; if (!aBan.ban_enforceName && !aBan.ban_enforceGUID && !aBan.ban_enforceIP) { this.ConsoleError("Unable to create ban, no proper player information"); continue; } //Upload the ban this.DebugWrite("Uploading ban from procon.", 5); this.UploadBan(aBan); if (!this._UseBanEnforcerPreviousState && (++bansImported % 25 == 0)) { this.ConsoleWrite(Math.Round(100 * bansImported / totalCBans, 2) + "% of bans uploaded. AVG " + Math.Round(bansImported / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " uploads/sec."); } } if (bansFound && !earlyExit) { //If all bans have been queued for processing, clear the ban list this.ExecuteCommand("procon.protected.send", "banList.clear"); this.ExecuteCommand("procon.protected.send", "banList.save"); this.ExecuteCommand("procon.protected.send", "banList.list"); if (!this._UseBanEnforcerPreviousState) { this.ConsoleSuccess("All bans uploaded into AdKats database."); } } } this._UseBanEnforcerPreviousState = true; } else { //If the ban enforcer was previously enabled, and the user disabled it, repopulate procon's ban list if (this._UseBanEnforcerPreviousState) { this.RepopulateProconBanList(); this._UseBanEnforcerPreviousState = false; } //If not, completely ignore all ban enforcer code } //Handle Inbound Records if (this._UnprocessedRecordQueue.Count > 0) { this.DebugWrite("DBCOMM: Preparing to lock inbound record queue to retrive new records", 7); Queue<AdKatsRecord> inboundRecords; lock (this._UnprocessedRecordMutex) { this.DebugWrite("DBCOMM: Inbound records found. Grabbing.", 6); //Grab all messages in the queue inboundRecords = new Queue<AdKatsRecord>(this._UnprocessedRecordQueue.ToArray()); //Clear the queue for next run this._UnprocessedRecordQueue.Clear(); } //Loop through all records in order that they came in while (inboundRecords.Count > 0) { //Pull the next record AdKatsRecord record = inboundRecords.Dequeue(); //Upload the record this.HandleRecordUpload(record); //Check for action handling needs if (!record.record_action_executed) { //Action is only called after initial upload, not after update this.DebugWrite("DBCOMM: Upload success. Attempting to add to action queue.", 6); //Only queue the record for action handling if it's not an enforced ban if (record.command_type.command_key != "banenforcer_enforce") { this.QueueRecordForActionHandling(record); } } else { this.DebugWrite("DBCOMM: Update success. Record does not need action handling.", 6); //finalize the record this.FinalizeRecord(record); } } } else { this.DebugWrite("DBCOMM: No unprocessed records. Waiting for input", 7); this._DbCommunicationWaitHandle.Reset(); if (this._FetchActionsFromDb || this._UseBanEnforcer || this._UsingAwa) { //If waiting on DB input, the maximum time we can wait is "db action frequency" this._DbCommunicationWaitHandle.WaitOne(DbActionFetchFrequency * 1000); } else { //Maximum wait time is DB access fetch time this._DbCommunicationWaitHandle.WaitOne(DbUserFetchFrequency * 1000); } } } catch (Exception e) { if (e is ThreadAbortException) { this.HandleException(new AdKatsException("Database Comm thread aborted. Exiting.")); break; } this.HandleException(new AdKatsException("Error occured in Database Comm thread. Skipping current loop.", e)); } } this.DebugWrite("DBCOMM: Ending Database Comm Thread", 1); } catch (Exception e) { this.HandleException(new AdKatsException("Error occured in database comm thread.", e)); } }
//DONE private void RepopulateProconBanList() { DebugWrite("repopulateProconBanList starting!", 6); this.ConsoleWarn("Downloading bans from database, please wait. This might take several minutes depending on your ban count!"); //Make sure database connection active if (this.HandlePossibleDisconnect()) { return; } Double totalBans = 0; Double bansDownloaded = 0; Double bansRepopulated = 0; Boolean earlyExit = false; DateTime startTime = DateTime.UtcNow; try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT COUNT(*) AS `ban_count` FROM `adkats_bans`"; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { totalBans = reader.GetInt64("ban_count"); } } } if (totalBans < 1) { return; } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `ban_id`, `player_id`, `latest_record_id`, `ban_status`, `ban_notes`, `ban_sync`, `ban_startTime`, `ban_endTime`, `ban_enforceName`, `ban_enforceGUID`, `ban_enforceIP` FROM `adkats_bans`"; List<AdKatsBan> importedBans = new List<AdKatsBan>(); using (MySqlDataReader reader = command.ExecuteReader()) { //Loop through all incoming bans while (reader.Read()) { //Break from the loop if the plugin is disabled or the setting is reverted. if (!this._IsEnabled || this._UseBanEnforcer) { this.ConsoleWarn("You exited the ban download process early, the process was not completed."); earlyExit = true; break; } //Create the ban element AdKatsBan aBan = new AdKatsBan { ban_id = reader.GetInt64("ban_id"), ban_status = reader.GetString("ban_status"), ban_notes = reader.GetString("ban_notes"), ban_sync = reader.GetString("ban_sync"), ban_startTime = reader.GetDateTime("ban_startTime"), ban_endTime = reader.GetDateTime("ban_endTime"), ban_record = this.FetchRecordByID(reader.GetInt64("latest_record_id"), false), ban_enforceName = (reader.GetString("ban_enforceName") == "Y"), ban_enforceGUID = (reader.GetString("ban_enforceGUID") == "Y"), ban_enforceIP = (reader.GetString("ban_enforceIP") == "Y") }; importedBans.Add(aBan); if (++bansDownloaded % 15 == 0) { this.ConsoleWrite(Math.Round(100 * bansDownloaded / totalBans, 2) + "% of bans downloaded. AVG " + Math.Round(bansDownloaded / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " downloads/sec."); } } } if (importedBans.Count > 0) { this.ConsoleWarn(importedBans.Count + " bans downloaded, beginning repopulation to ban list."); } startTime = DateTime.UtcNow; foreach(AdKatsBan aBan in importedBans) { //Get the record information Int64 totalBanSeconds = (long) aBan.ban_endTime.Subtract(DateTime.UtcNow).TotalSeconds; if (totalBanSeconds > 0) { this.DebugWrite("Re-ProconBanning: " + aBan.ban_record.target_player.player_name + " for " + totalBanSeconds + "sec for " + aBan.ban_record.record_message, 4); //Push the id ban if (aBan.ban_enforceName) { Thread.Sleep(75); //Permabans and Temp bans longer than 1 year will be defaulted to permaban if (totalBanSeconds > 0 && totalBanSeconds < 31536000) { this.ExecuteCommand("procon.protected.send", "banList.add", "id", aBan.ban_record.target_player.player_name, "seconds", totalBanSeconds + "", aBan.ban_record.record_message); } else { this.ExecuteCommand("procon.protected.send", "banList.add", "id", aBan.ban_record.target_player.player_name, "perm", aBan.ban_record.record_message); } } //Push the guid ban if (aBan.ban_enforceGUID) { Thread.Sleep(75); //Permabans and Temp bans longer than 1 year will be defaulted to permaban if (totalBanSeconds > 0 && totalBanSeconds < 31536000) { this.ExecuteCommand("procon.protected.send", "banList.add", "guid", aBan.ban_record.target_player.player_guid, "seconds", totalBanSeconds + "", aBan.ban_record.record_message); } else { this.ExecuteCommand("procon.protected.send", "banList.add", "guid", aBan.ban_record.target_player.player_guid, "perm", aBan.ban_record.record_message); } } //Push the IP ban if (aBan.ban_enforceIP) { Thread.Sleep(75); //Permabans and Temp bans longer than 1 year will be defaulted to permaban if (totalBanSeconds > 0 && totalBanSeconds < 31536000) { this.ExecuteCommand("procon.protected.send", "banList.add", "ip", aBan.ban_record.target_player.player_ip, "seconds", totalBanSeconds + "", aBan.ban_record.record_message); } else { this.ExecuteCommand("procon.protected.send", "banList.add", "ip", aBan.ban_record.target_player.player_ip, "perm", aBan.ban_record.record_message); } } } if (++bansRepopulated % 15 == 0) { this.ConsoleWrite(Math.Round(100 * bansRepopulated / totalBans, 2) + "% of bans repopulated. AVG " + Math.Round(bansRepopulated / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " downloads/sec."); } } this.ExecuteCommand("procon.protected.send", "banList.save"); this.ExecuteCommand("procon.protected.send", "banList.list"); if (!earlyExit) { this.ConsoleSuccess("All AdKats Enforced bans repopulated to procon's ban list."); } //Update the last db ban fetch time this._LastDbBanFetch = DateTime.UtcNow; } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while repopulating procon banlist.", e)); } }
private TimeSpan getRemainingBanTime(AdKatsBan aBan) { return aBan.ban_endTime.Subtract(DateTime.UtcNow); }
private void HandleActiveBanEnforcer() { //Call banlist at set interval (20 seconds) if (_UseBanEnforcerPreviousState && (DateTime.UtcNow > _lastBanListCall.AddSeconds(20))) { _lastBanListCall = DateTime.UtcNow; DebugWrite("banlist.list called at interval.", 6); ExecuteCommand("procon.protected.send", "banList.list"); } FetchNameBanCount(); FetchGUIDBanCount(); FetchIPBanCount(); if (!_UseBanEnforcerPreviousState || (DateTime.UtcNow > _lastDbBanFetch.AddSeconds(DbBanFetchFrequency))) { //Load all bans on startup if (!_UseBanEnforcerPreviousState) { //Get all bans from procon ConsoleWarn("Preparing to queue procon bans for import. Please wait."); _DbCommunicationWaitHandle.Reset(); ExecuteCommand("procon.protected.send", "banList.list"); _DbCommunicationWaitHandle.WaitOne(TimeSpan.FromMinutes(5)); if (_CBanProcessingQueue.Count > 0) { ConsoleWrite(_CBanProcessingQueue.Count + " procon bans queued for import. Import might take several minutes if you have many bans!"); } else { ConsoleWrite("No procon bans to import into Ban Enforcer."); } } } else { DebugWrite("DBCOMM: Skipping DB ban fetch", 7); } //Handle Inbound Ban Comms if (_BanEnforcerProcessingQueue.Count > 0) { DebugWrite("DBCOMM: Preparing to lock inbound ban enforcer queue to retrive new bans", 7); Queue<AdKatsBan> inboundBans; if (_isTestingAuthorized) PushThreadDebug(DateTime.Now.Ticks, (String.IsNullOrEmpty(Thread.CurrentThread.Name) ? ("mainthread") : (Thread.CurrentThread.Name)), Thread.CurrentThread.ManagedThreadId, new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(), ""); lock (_BanEnforcerProcessingQueue) { DebugWrite("DBCOMM: Inbound bans found. Grabbing.", 6); //Grab all messages in the queue inboundBans = new Queue<AdKatsBan>(_BanEnforcerProcessingQueue.ToArray()); //Clear the queue for next run _BanEnforcerProcessingQueue.Clear(); } Int32 index = 1; //Loop through all bans in order that they came in while (inboundBans.Count > 0) { if (!_pluginEnabled || !_UseBanEnforcer) { ConsoleWarn("Canceling ban import mid-operation."); break; } //Grab the ban AdKatsBan aBan = inboundBans.Dequeue(); DebugWrite("DBCOMM: Processing Frostbite Ban: " + index++, 6); //Upload the ban UploadBan(aBan); //Only perform special action when ban is direct //Indirect bans are through the procon banlist, so the player has already been kicked if (aBan.ban_record.source_name != "BanEnforcer") { //Enforce the ban EnforceBan(aBan, false); } } } //Handle BF3 Ban Manager imports if (!_UseBanEnforcerPreviousState) { //Import all bans from BF3 Ban Manager ImportBansFromBBM5108(); } //Handle Inbound CBan Uploads if (_CBanProcessingQueue.Count > 0) { if (!_UseBanEnforcerPreviousState) { ConsoleWarn("Do not disable AdKats or change any settings until upload is complete!"); } DebugWrite("DBCOMM: Preparing to lock inbound cBan queue to retrive new cBans", 7); Double totalCBans = 0; Double bansImported = 0; Boolean earlyExit = false; DateTime startTime = DateTime.UtcNow; Queue<CBanInfo> inboundCBans; if (_isTestingAuthorized) PushThreadDebug(DateTime.Now.Ticks, (String.IsNullOrEmpty(Thread.CurrentThread.Name) ? ("mainthread") : (Thread.CurrentThread.Name)), Thread.CurrentThread.ManagedThreadId, new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(), ""); lock (_CBanProcessingQueue) { DebugWrite("DBCOMM: Inbound cBans found. Grabbing.", 6); //Grab all cBans in the queue inboundCBans = new Queue<CBanInfo>(_CBanProcessingQueue.ToArray()); totalCBans = inboundCBans.Count; //Clear the queue for next run _CBanProcessingQueue.Clear(); } //Loop through all cBans in order that they came in Boolean bansFound = false; while (inboundCBans.Count > 0) { //Break from the loop if the plugin is disabled or the setting is reverted. if (!_pluginEnabled || !_UseBanEnforcer) { ConsoleWarn("You exited the ban upload process early, the process was not completed."); earlyExit = true; break; } bansFound = true; CBanInfo cBan = inboundCBans.Dequeue(); //Create the record var record = new AdKatsRecord(); record.record_source = AdKatsRecord.Sources.InternalAutomated; //Permabans and Temp bans longer than 1 year will be defaulted to permaban switch (cBan.BanLength.Subset) { case TimeoutSubset.TimeoutSubsetType.Seconds: record.command_type = _CommandKeyDictionary["player_ban_temp"]; record.command_action = _CommandKeyDictionary["player_ban_temp"]; record.command_numeric = cBan.BanLength.Seconds / 60; break; case TimeoutSubset.TimeoutSubsetType.Permanent: record.command_type = _CommandKeyDictionary["player_ban_perm"]; record.command_action = _CommandKeyDictionary["player_ban_perm"]; record.command_numeric = 0; break; case TimeoutSubset.TimeoutSubsetType.Round: //Accept round ban as 1 hour timeban record.command_type = _CommandKeyDictionary["player_ban_temp"]; record.command_action = _CommandKeyDictionary["player_ban_temp"]; record.command_numeric = 60; break; default: //Ban type is unknown, unable to process continue; } record.source_name = _CBanAdminName; record.server_id = _serverID; record.target_player = FetchPlayer(true, false, false, null, -1, cBan.SoldierName, (!String.IsNullOrEmpty(cBan.Guid)) ? (cBan.Guid.ToUpper()) : (null), cBan.IpAddress); if (!String.IsNullOrEmpty(record.target_player.player_name)) { record.target_name = record.target_player.player_name; } record.isIRO = false; record.record_message = cBan.Reason; //Update the ban enforcement depending on available information Boolean nameAvailable = !String.IsNullOrEmpty(record.target_player.player_name); Boolean guidAvailable = !String.IsNullOrEmpty(record.target_player.player_guid); Boolean ipAvailable = !String.IsNullOrEmpty(record.target_player.player_ip); //Create the ban var aBan = new AdKatsBan { ban_record = record, ban_enforceName = nameAvailable && (_DefaultEnforceName || (!guidAvailable && !ipAvailable) || !String.IsNullOrEmpty(cBan.SoldierName)), ban_enforceGUID = guidAvailable && (_DefaultEnforceGUID || (!nameAvailable && !ipAvailable) || !String.IsNullOrEmpty(cBan.Guid)), ban_enforceIP = ipAvailable && (_DefaultEnforceIP || (!nameAvailable && !guidAvailable) || !String.IsNullOrEmpty(cBan.IpAddress)) }; if (!aBan.ban_enforceName && !aBan.ban_enforceGUID && !aBan.ban_enforceIP) { ConsoleError("Unable to create ban, no proper player information"); continue; } //Upload the ban DebugWrite("Uploading ban from procon.", 5); UploadBan(aBan); if (!_UseBanEnforcerPreviousState && (++bansImported % 25 == 0)) { ConsoleWrite(Math.Round(100 * bansImported / totalCBans, 2) + "% of bans uploaded. AVG " + Math.Round(bansImported / ((DateTime.UtcNow - startTime).TotalSeconds), 2) + " uploads/sec."); } } if (bansFound && !earlyExit) { //If all bans have been queued for processing, clear the ban list ExecuteCommand("procon.protected.send", "banList.clear"); ExecuteCommand("procon.protected.send", "banList.save"); ExecuteCommand("procon.protected.send", "banList.list"); if (!_UseBanEnforcerPreviousState) { ConsoleSuccess("All bans uploaded into AdKats database."); } } } _UseBanEnforcerPreviousState = true; }