public List<AdKatsSpecialPlayer> FetchMatchingSpecialPlayers(String group, AdKatsPlayer aPlayer) { DebugWrite("Entering FetchMatchingSpecialPlayers", 6); try { var matchingPlayers = new List<AdKatsSpecialPlayer>(); using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { //Attempt to execute the query command.CommandText = @" SELECT `specialplayer_id`, `player_group`, `player_id`, `player_game`, `player_server`, `player_identifier`, `player_effective`, `player_expiration` FROM `adkats_specialplayers` WHERE `player_expiration` > UTC_TIMESTAMP() AND ( `player_id` = @player_id OR `player_identifier` = @player_name OR `player_identifier` = @player_guid OR `player_identifier` = @player_ip )"; command.Parameters.AddWithValue("@player_id", aPlayer.player_id); command.Parameters.AddWithValue("@player_name", aPlayer.player_name); command.Parameters.AddWithValue("@player_guid", aPlayer.player_guid); command.Parameters.AddWithValue("@player_ip", aPlayer.player_ip); using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { var asPlayer = new AdKatsSpecialPlayer(); asPlayer.player_group = reader.GetString("player_group"); if (asPlayer.player_group != group) { continue; } Int32? player_id = null; if (!reader.IsDBNull(2)) { player_id = reader.GetInt32("player_id"); } if (!reader.IsDBNull(3)) asPlayer.player_game = reader.GetInt32("player_game"); if (!reader.IsDBNull(4)) asPlayer.player_server = reader.GetInt32("player_server"); if (!reader.IsDBNull(5)) asPlayer.player_identifier = reader.GetString("player_identifier"); asPlayer.player_effective = reader.GetDateTime("player_effective"); asPlayer.player_expiration = reader.GetDateTime("player_expiration"); if (asPlayer.player_game != null && asPlayer.player_game != _gameID) { DebugWrite("Matching player rejected for mismatched game id", 4); continue; } if (asPlayer.player_server != null && asPlayer.player_server != _serverID) { DebugWrite("Matching player rejected for mismatched server id", 4); continue; } if (player_id != null) { if (player_id != aPlayer.player_id) { DebugWrite("Matching player rejected for mismatched player id", 4); continue; } asPlayer.player_object = aPlayer; } if (String.IsNullOrEmpty(asPlayer.player_identifier) && asPlayer.player_identifier != aPlayer.player_name && asPlayer.player_identifier != aPlayer.player_guid && asPlayer.player_identifier != aPlayer.player_ip) { DebugWrite("Matching player rejected for mismatched player identifier", 4); continue; } matchingPlayers.Add(asPlayer); } } } } return matchingPlayers; } catch (Exception e) { HandleException(new AdKatsException("Error while taking action for Disperse record.", e)); } DebugWrite("Exiting FetchMatchingSpecialPlayers", 6); return null; }
//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; }
//IN Progress private void FetchUserList() { DebugWrite("fetchUserList starting!", 6); //Make sure database connection active if (this.HandlePossibleDisconnect()) { return; } //Make sure roles and commands are loaded before performing this if (this._CommandNameDictionary.Count == 0 || this._RoleKeyDictionary.Count == 0) { this.FetchCommands(); this.FetchRoles(); return; } Dictionary<long, AdKatsUser> tempUserCache = new Dictionary<long, AdKatsUser>(); try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @"SELECT `adkats_users`.`user_id`, `adkats_users`.`user_name`, `adkats_users`.`user_email`, `adkats_users`.`user_phone`, `adkats_users`.`user_role` FROM `adkats_users`"; using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { //Create the user object AdKatsUser user = new AdKatsUser(); user.user_id = reader.GetInt32("user_id"); //0 user.user_name = reader.GetString("user_name"); //1 if (!reader.IsDBNull(2)) user.user_email = reader.GetString("user_email"); //2 if (!reader.IsDBNull(3)) user.user_phone = reader.GetString("user_phone"); //3 if (!this._RoleIDDictionary.TryGetValue(reader.GetInt32("user_role"), out user.user_role)) { this.ConsoleError("Unable to find user role for role_id " + reader.GetInt32("user_role")); return; } //Add the user to temp list tempUserCache.Add(user.user_id, user); } } } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `adkats_users`.`user_id`, `adkats_usersoldiers`.`player_id`, `tbl_playerdata`.`ClanTag` AS `clan_tag`, `tbl_playerdata`.`SoldierName` AS `player_name`, `tbl_playerdata`.`EAGUID` AS `player_guid`, `tbl_playerdata`.`IP_Address` AS `player_ip` FROM `adkats_users` INNER JOIN `adkats_usersoldiers` ON `adkats_users`.`user_id` = `adkats_usersoldiers`.`user_id` INNER JOIN `tbl_playerdata` ON `adkats_usersoldiers`.`player_id` = `tbl_playerdata`.`PlayerID` ORDER BY `user_id` ASC"; using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { //Create the new player object AdKatsPlayer aPlayer = new AdKatsPlayer(); //Import the information Int32 userID = reader.GetInt32("user_id"); //0 aPlayer.player_id = reader.GetInt32("player_id"); //1 if (!reader.IsDBNull(2)) aPlayer.clan_tag = reader.GetString("clan_tag"); //2 if (!reader.IsDBNull(3)) aPlayer.player_name = reader.GetString("player_name"); //3 if (!reader.IsDBNull(4)) aPlayer.player_guid = reader.GetString("player_guid"); //4 if (!reader.IsDBNull(5)) aPlayer.player_ip = reader.GetString("player_ip"); //5 //Add soldier to user AdKatsUser aUser = null; if (tempUserCache.TryGetValue(userID, out aUser)) { if (aUser.soldierDictionary.ContainsKey(aPlayer.player_id)) { aUser.soldierDictionary.Remove(aPlayer.player_id); } aUser.soldierDictionary.Add(aPlayer.player_id, aPlayer); } else { this.ConsoleError("Unable to add soldier " + aPlayer.player_name + " to user " + userID + " when fetching user list."); } } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while fetching access list.", e)); } //Update the user cache this._UserCache = tempUserCache; //Update all currently online players lock (this._PlayersMutex) { foreach (AdKatsPlayer aPlayer in this._PlayerDictionary.Values) { this.AssignPlayerRole(aPlayer); } } //Update the last update time this._LastUserFetch = DateTime.UtcNow; if (this._UserCache.Count > 0) { this.DebugWrite("User List Fetched from Database. User Count: " + this._UserCache.Count, 1); //Update MULTIBalancer Whitelists this.UpdateMULTIBalancerWhitelist(); //Update Server Reserved Slots this.UpdateReservedSlots(); this.UpdateSpectatorList(); } else { this.ConsoleWarn("No users in the user table. Add a new user with 'Add User'."); } DebugWrite("fetchUserList finished!", 6); }
private Boolean AimbotHackCheck(AdKatsPlayer aPlayer, Boolean debugMode) { Boolean acted = false; try { if (aPlayer == null || aPlayer.stats == null || aPlayer.stats.WeaponStats == null) { return false; } List<String> allowedCategories; switch (this._GameVersion) { case GameVersion.BF3: allowedCategories = new List<string>() { "Sub machine guns", "Assault rifles", "Carbines", "Machine guns" }; break; case GameVersion.BF4: allowedCategories = new List<string>() { "PDW", "ASSAULT RIFLE", "CARBINE", "LMG" }; break; default: return false; } List<AdKatsWeaponStats> topWeapons = aPlayer.stats.WeaponStats.Values.ToList(); topWeapons.Sort(delegate(AdKatsWeaponStats a1, AdKatsWeaponStats a2) { if (a1.Kills == a2.Kills) { return 0; } return (a1.Kills < a2.Kills) ? (1) : (-1); }); AdKatsWeaponStats actedWeapon = null; Double actedHskr = -1; Int32 index = 0; foreach (AdKatsWeaponStats weaponStat in topWeapons) { //Break after 15th top weapon if (index++ > 15) { break; } //Only count certain weapon categories if (allowedCategories.Contains(weaponStat.Category)) { //Only take weapons with more than 100 kills if (weaponStat.Kills > 100) { //Check for aimbot hack this.DebugWrite("Checking " + weaponStat.ID + " HSKR (" + weaponStat.HSKR + " >? " + (this._HskTriggerLevel / 100) + ")", 6); if (weaponStat.HSKR > (this._HskTriggerLevel / 100)) { if (weaponStat.HSKR > actedHskr) { actedHskr = weaponStat.HSKR; actedWeapon = weaponStat; } } } } } if (actedWeapon != null) { acted = true; String formattedName = actedWeapon.ID.Replace("-", "").Replace(" ", "").ToUpper(); this.ConsoleWarn(aPlayer.player_name + " auto-banned for aimbot. [" + formattedName + "-" + (int) (actedWeapon.HSKR * 100) + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]"); if (!debugMode) { //Create the ban record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_ban_perm"], command_numeric = 0, target_name = aPlayer.player_name, target_player = aPlayer, source_name = "AutoAdmin", record_message = this._HackerCheckerHSKBanMessage + " [" + formattedName + "-" + (int) (actedWeapon.HSKR * 100) + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]" }; //Process the record this.QueueRecordForProcessing(record); //this.AdminSayMessage(player.player_name + " auto-banned for aimbot. [" + actedWeapon.id + "-" + (int) actedWeapon.hskr + "-" + (int) actedWeapon.kills + "-" + (int) actedWeapon.headshots + "]"); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error running HSK hack check.", e)); } return acted; }
private Boolean DamageHackCheck(AdKatsPlayer aPlayer, Boolean debugMode) { Boolean acted = false; try { if (aPlayer == null || aPlayer.stats == null || aPlayer.stats.WeaponStats == null) { return false; } List<String> allowedCategories = null; switch (this._GameVersion) { case GameVersion.BF3: allowedCategories = new List<string>() { "Sub machine guns", "Assault rifles", "Carbines", "Machine guns", "Handheld weapons" }; break; case GameVersion.BF4: allowedCategories = new List<string>() { "PDW", "ASSAULT RIFLE", "CARBINE", "LMG", "SIDEARM" }; break; default: return false; } List<AdKatsWeaponStats> topWeapons = aPlayer.stats.WeaponStats.Values.ToList(); topWeapons.Sort(delegate(AdKatsWeaponStats a1, AdKatsWeaponStats a2) { if (a1.Kills == a2.Kills) { return 0; } return (a1.Kills < a2.Kills) ? (1) : (-1); }); AdKatsWeaponStats actedWeapon = null; Double actedPerc = -1; Int32 index = 0; foreach (AdKatsWeaponStats weaponStat in topWeapons) { //Break after 15th top weapon if (index++ > 15) { break; } //Only count certain weapon categories if (allowedCategories.Contains(weaponStat.Category)) { StatLibraryWeapon weapon = null; if (this._StatLibrary.Weapons.TryGetValue(weaponStat.ID, out weapon)) { //Only handle weapons that do < 50 max dps if (weapon.damage_max < 50) { //Only take weapons with more than 50 kills if (weaponStat.Kills > 50) { //Check for damage hack if (weaponStat.DPS > weapon.damage_max) { //Get the percentage over normal Double percDiff = (weaponStat.DPS - weapon.damage_max) / weaponStat.DPS; if (percDiff > (this._DpsTriggerLevel / 100)) { if (percDiff > actedPerc) { actedPerc = percDiff; actedWeapon = weaponStat; } } } } } } else { this.ConsoleWarn("Could not find " + weaponStat.ID + " in " + this._GameVersion + " library of " + this._StatLibrary.Weapons.Count + " weapons."); } } } if (actedWeapon != null) { acted = true; String formattedName = actedWeapon.ID.Replace("-", "").Replace(" ", "").ToUpper(); this.ConsoleWarn(aPlayer.player_name + " auto-banned for damage mod. [" + formattedName + "-" + (int) actedWeapon.DPS + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]"); if (!debugMode) { //Create the ban record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_ban_perm"], command_numeric = 0, target_name = aPlayer.player_name, target_player = aPlayer, source_name = "AutoAdmin", record_message = _HackerCheckerDPSBanMessage + " [" + formattedName + "-" + (int) actedWeapon.DPS + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]" }; //Process the record this.QueueRecordForProcessing(record); //this.AdminSayMessage(player.player_name + " auto-banned for damage mod. [" + actedWeapon.id + "-" + (int) actedWeapon.dps + "-" + (int) actedWeapon.kills + "-" + (int) actedWeapon.headshots + "]"); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error running DPS hack check", e)); } return acted; }
private AdKatsPlayer UpdatePlayer(AdKatsPlayer player) { this.DebugWrite("updatePlayer starting!", 6); //Make sure database connection active if (this.HandlePossibleDisconnect()) { return player; } if (player == null || player.player_id < 0 || (String.IsNullOrEmpty(player.player_name) && String.IsNullOrEmpty(player.player_guid) & String.IsNullOrEmpty(player.player_ip))) { this.ConsoleError("Attempted to update player without required information."); } else { try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { //Set the insert command structure command.CommandText = @" UPDATE `" + this._MySqlDatabaseName + @"`.`tbl_playerdata` SET `SoldierName` = '" + player.player_name + @"', `EAGUID` = '" + player.player_guid + @"', `IP_Address` = '" + player.player_ip + @"' WHERE `tbl_playerdata`.`PlayerID` = " + player.player_id; //Attempt to execute the query if (command.ExecuteNonQuery() > 0) { this.DebugWrite("Update player info success.", 5); } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while updating player.", e)); } } DebugWrite("updatePlayer finished!", 6); return player; }
public Boolean PlayerProtected(AdKatsPlayer aPlayer) { Boolean protect = false; foreach (String whitelistedValue in this._HackerCheckerWhitelist) { if (aPlayer.player_name == whitelistedValue) { this.DebugWrite(aPlayer.player_name + " protected from hacker checker by id.", 2); protect = true; break; } if (aPlayer.player_guid == whitelistedValue) { this.DebugWrite(aPlayer.player_name + " protected from hacker checker by guid.", 2); protect = true; break; } if (aPlayer.player_ip == whitelistedValue) { this.DebugWrite(aPlayer.player_name + " protected from hacker checker by IP.", 2); protect = true; break; } } return protect; }
private Boolean IsAdminAssistant(AdKatsPlayer aPlayer) { DebugWrite("IsAdminAssistant starting!", 7); if (!_EnableAdminAssistants) { return false; } Boolean isAdminAssistant = aPlayer.player_aa; if (aPlayer.player_aa_fetched) { return isAdminAssistant; } if (HandlePossibleDisconnect()) { return false; } if (RoleIsAdmin(aPlayer.player_role)) { return false; } try { using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT 'isAdminAssistant' FROM `adkats_records_main` WHERE ( SELECT count(`command_action`) FROM `adkats_records_main` WHERE `command_action` = " + GetCommandByKey("player_report_confirm").command_id + @" AND `source_id` = " + aPlayer.player_id + @" AND (`adkats_records_main`.`record_time` BETWEEN date_sub(UTC_TIMESTAMP(),INTERVAL 30 DAY) AND UTC_TIMESTAMP()) ) >= " + _MinimumRequiredMonthlyReports + @" LIMIT 1 UNION SELECT 'isGrandfatheredAdminAssistant' FROM `adkats_records_main` WHERE ( SELECT count(`command_action`) FROM `adkats_records_main` WHERE `command_action` = " + GetCommandByKey("player_report_confirm").command_id + @" AND `source_id` = " + aPlayer.player_id + @" ) >= 75"; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { //Player is an admin assistant, give them access to the self_admins command isAdminAssistant = true; } aPlayer.player_aa_fetched = true; } } } } catch (Exception e) { HandleException(new AdKatsException("Error while checking if player is an admin assistant.", e)); } DebugWrite("IsAdminAssistant finished!", 7); return isAdminAssistant; }
private String ReplacePlayerInformation(String originalString, AdKatsPlayer aPlayer) { String processedString = ""; if (String.IsNullOrEmpty(originalString)) { return processedString; } //Create new instance of original string processedString += originalString; if (aPlayer == null) { return processedString; } if (aPlayer.player_id > 0) { processedString = processedString.Replace("%player_id%", aPlayer.player_id + ""); } if (!String.IsNullOrEmpty(aPlayer.player_name)) { processedString = processedString.Replace("%player_name%", aPlayer.player_name); } if (!String.IsNullOrEmpty(aPlayer.player_guid)) { processedString = processedString.Replace("%player_guid%", aPlayer.player_guid); } if (!String.IsNullOrEmpty(aPlayer.player_pbguid)) { processedString = processedString.Replace("%player_pbguid%", aPlayer.player_pbguid); } if (!String.IsNullOrEmpty(aPlayer.player_ip)) { processedString = processedString.Replace("%player_ip%", aPlayer.player_ip); } return processedString; }
private void FetchUserList() { DebugWrite("fetchUserList starting!", 6); if (HandlePossibleDisconnect()) { return; } try { if (!SendQuery("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE ( TABLE_SCHEMA = '" + _mySqlDatabaseName + "' AND TABLE_NAME = 'adkats_users' AND COLUMN_NAME = 'user_expiration' )", false)) { SendNonQuery("Adding user expiration.", "ALTER TABLE `adkats_users` ADD COLUMN `user_expiration` DATETIME NOT NULL AFTER `user_role`", true); SendNonQuery("Adding initial user expiration values.", "UPDATE `adkats_users` SET `user_expiration` = DATE_ADD(UTC_TIMESTAMP(), INTERVAL 20 YEAR)", true); } if (!SendQuery("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE ( TABLE_SCHEMA = '" + _mySqlDatabaseName + "' AND TABLE_NAME = 'adkats_users' AND COLUMN_NAME = 'user_notes' )", false)) { SendNonQuery("Adding user notes.", "ALTER TABLE `adkats_users` ADD COLUMN `user_notes` VARCHAR(1000) NOT NULL DEFAULT 'No Notes' AFTER `user_expiration`", true); } using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @"SELECT `adkats_users`.`user_id`, `adkats_users`.`user_name`, `adkats_users`.`user_email`, `adkats_users`.`user_phone`, `adkats_users`.`user_role`, `adkats_users`.`user_expiration`, `adkats_users`.`user_notes` FROM `adkats_users`"; var validIDs = new List<Int64>(); using (MySqlDataReader reader = command.ExecuteReader()) { 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 (_userCache) { while (reader.Read()) { int userID = reader.GetInt32("user_id"); //0 validIDs.Add(userID); string userName = reader.GetString("user_name"); //1 String userEmail = null; if (!reader.IsDBNull(2)) userEmail = reader.GetString("user_email"); //2 String userPhone = null; if (!reader.IsDBNull(3)) userPhone = reader.GetString("user_phone"); //3 AdKatsRole userRole; if (!_RoleIDDictionary.TryGetValue(reader.GetInt32("user_role"), out userRole)) { ConsoleError("Unable to find user role for role ID " + reader.GetInt32("user_role")); continue; } DateTime expirationTime = reader.GetDateTime("user_expiration"); String userNotes = reader.GetString("user_notes"); AdKatsUser aUser; if (_userCache.TryGetValue(userID, out aUser)) { if (expirationTime < DateTime.UtcNow) { userRole = _RoleKeyDictionary["guest_default"]; expirationTime = DateTime.UtcNow.AddYears(20); QueueUserForUpload(aUser); } aUser.user_name = userName; aUser.user_email = userEmail; aUser.user_phone = userPhone; aUser.user_role = userRole; aUser.user_expiration = expirationTime; aUser.user_notes = userNotes; } else { aUser = new AdKatsUser { user_id = userID, user_name = userName, user_email = userEmail, user_phone = userPhone, user_role = userRole, user_expiration = expirationTime, user_notes = userNotes }; if (expirationTime < DateTime.UtcNow) { userRole = _RoleKeyDictionary["guest_default"]; expirationTime = DateTime.UtcNow.AddYears(20); QueueUserForUpload(aUser); } _userCache.Add(aUser.user_id, aUser); } } foreach (AdKatsUser remUser in _userCache.Values.Where(usr => validIDs.All(id => id != usr.user_id)).ToList()) { _userCache.Remove(remUser.user_id); ConsoleSuccess("User " + remUser.user_name + " removed."); } } } } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `adkats_users`.`user_id`, `adkats_usersoldiers`.`player_id`, `tbl_playerdata`.`GameID` AS `game_id`, `tbl_playerdata`.`ClanTag` AS `clan_tag`, `tbl_playerdata`.`SoldierName` AS `player_name`, `tbl_playerdata`.`EAGUID` AS `player_guid`, `tbl_playerdata`.`IP_Address` AS `player_ip` FROM `adkats_users` INNER JOIN `adkats_usersoldiers` ON `adkats_users`.`user_id` = `adkats_usersoldiers`.`user_id` INNER JOIN `tbl_playerdata` ON `adkats_usersoldiers`.`player_id` = `tbl_playerdata`.`PlayerID` ORDER BY `user_id` ASC"; using (MySqlDataReader reader = command.ExecuteReader()) { 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 (_userCache) { foreach (AdKatsPlayer aPlayer in _userCache.Values.SelectMany(aUser => aUser.soldierDictionary.Values)) { aPlayer.update_playerUpdated = false; } while (reader.Read()) { int userID = reader.GetInt32("user_id"); //0 int playerID = reader.GetInt32("player_id"); //1 int gameID = reader.GetInt32("game_id"); //2 String clanTag = null; if (!reader.IsDBNull(3)) clanTag = reader.GetString("clan_tag"); //3 String playerName = null; if (!reader.IsDBNull(4)) playerName = reader.GetString("player_name"); //4 String playerGUID = null; if (!reader.IsDBNull(5)) playerGUID = reader.GetString("player_guid"); //5 String playerIP = null; if (!reader.IsDBNull(6)) playerIP = reader.GetString("player_ip"); //6 AdKatsUser aUser; if (_userCache.TryGetValue(userID, out aUser)) { AdKatsPlayer aPlayer; if (aUser.soldierDictionary.TryGetValue(playerID, out aPlayer)) { aPlayer.game_id = gameID; aPlayer.clan_tag = clanTag; aPlayer.player_name = playerName; aPlayer.player_guid = playerGUID; aPlayer.player_ip = playerIP; } else { aPlayer = new AdKatsPlayer { player_id = playerID, game_id = gameID, clan_tag = clanTag, player_name = playerName, player_guid = playerGUID, player_ip = playerIP }; aUser.soldierDictionary.Add(playerID, aPlayer); } aPlayer.player_role = aUser.user_role; aPlayer.update_playerUpdated = true; } else { ConsoleError("Unable to add soldier " + playerID + " to user " + userID + " when fetching user list. User not found."); } } foreach (AdKatsUser aUser in _userCache.Values) { foreach (AdKatsPlayer aPlayer in aUser.soldierDictionary.Values.Where(aPlayer => !aPlayer.update_playerUpdated)) { aUser.soldierDictionary.Remove(aPlayer.player_id); } } if (!_firstPlayerListComplete) { OnlineAdminSayMessage("User fetch complete. Fetching player list."); } } } } var tempSpecialPlayerCache = new List<AdKatsSpecialPlayer>(); using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT `player_group`, `player_id`, `player_game`, `player_server`, `player_identifier`, `player_effective`, `player_expiration` FROM `adkats_specialplayers` WHERE `player_expiration` > UTC_TIMESTAMP() ORDER BY `player_group` DESC"; using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { var asPlayer = new AdKatsSpecialPlayer(); asPlayer.player_group = reader.GetString("player_group"); //0 if (!reader.IsDBNull(1)) asPlayer.player_object = FetchPlayer(false, true, false, null, reader.GetInt32("player_id"), null, null, null); //1 if (!reader.IsDBNull(2)) asPlayer.player_game = reader.GetInt32("player_game"); //2 if (!reader.IsDBNull(3)) asPlayer.player_server = reader.GetInt32("player_server"); //3 if (!reader.IsDBNull(4)) asPlayer.player_identifier = reader.GetString("player_identifier"); //4 asPlayer.player_effective = reader.GetDateTime("player_effective"); asPlayer.player_expiration = reader.GetDateTime("player_expiration"); //Check if special player applies to this server Boolean allowed = true; if (asPlayer.player_object == null) { //If they didn't define a player, they must define an identifier if (String.IsNullOrEmpty(asPlayer.player_identifier)) { allowed = false; } //Did they define a game for the special player? if (asPlayer.player_game != null) { //They did, only use if the given game id is this server's game id if (asPlayer.player_game != _gameID) { allowed = false; } } } else if (asPlayer.player_object.game_id != _gameID) { allowed = false; } //Did they define a server for the special player? if (asPlayer.player_server != null) { //They did, only use if the given server id is this server's server id if (asPlayer.player_server != _serverID) { allowed = false; } } if (allowed) { //Add the user to temp list tempSpecialPlayerCache.Add(asPlayer); } } } } //Update the special player cache 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 (_specialPlayerGroupCache) { _specialPlayerGroupCache.Clear(); foreach (AdKatsSpecialPlayer asPlayer in tempSpecialPlayerCache) { List<AdKatsSpecialPlayer> currentList; if (_specialPlayerGroupCache.TryGetValue(asPlayer.player_group, out currentList)) { currentList.Add(asPlayer); } else { currentList = new List<AdKatsSpecialPlayer> { asPlayer }; _specialPlayerGroupCache.Add(asPlayer.player_group, currentList); } } //Debug logging purposes only if (_debugLevel > 4) { foreach (string key in _specialPlayerGroupCache.Keys) { List<AdKatsSpecialPlayer> asPlayerList; if (_specialPlayerGroupCache.TryGetValue(key, out asPlayerList)) { DebugWrite("SPECIAL: List: " + key, 4); foreach (AdKatsSpecialPlayer asPlayer in asPlayerList) { if (asPlayer.player_object != null) { DebugWrite("SPECIAL: Contents: " + asPlayer.player_object.player_name, 4); } else { DebugWrite("SPECIAL: Contents: " + asPlayer.player_identifier, 4); } } } } } } } } catch (Exception e) { HandleException(new AdKatsException("Error while fetching access list.", e)); } _PlayerRoleRefetch = true; _PlayerProcessingWaitHandle.Set(); UpdateMULTIBalancerWhitelist(); UpdateMULTIBalancerDisperseList(); UpdateReservedSlots(); UpdateSpectatorList(); _lastUserFetch = DateTime.UtcNow; if (_userCache.Count > 0) { DebugWrite("User List Fetched from Database. User Count: " + _userCache.Count, 1); } else { ConsoleWarn("No users in the user table. Add a new user with 'Add User'."); } UpdateSettingPage(); DebugWrite("fetchUserList finished!", 6); }
private Boolean AssignPlayerRole(AdKatsPlayer aPlayer) { AdKatsUser matchingUser = _userCache.Values.FirstOrDefault(aUser => aUser.soldierDictionary.Values.Any(uPlayer => uPlayer.player_id == aPlayer.player_id || uPlayer.player_guid == aPlayer.player_guid)); AdKatsRole aRole = null; Boolean authorized = false; if (matchingUser != null) { authorized = true; aRole = matchingUser.user_role; } else { aRole = _RoleKeyDictionary["guest_default"]; } //Debug Block if (aPlayer.player_role == null) { if (authorized) { DebugWrite("Player " + aPlayer.player_name + " has been assigned authorized role " + aRole.role_name + ".", 4); } else { DebugWrite("Player " + aPlayer.player_name + " has been assigned the guest role.", 4); } } else { if (aPlayer.player_role.role_key != aRole.role_key) { if (authorized) { DebugWrite("Role for authorized player " + aPlayer.player_name + " has been CHANGED to " + aRole.role_name + ".", 4); PlayerSayMessage(aPlayer.player_name, "You have been assigned the authorized role " + aRole.role_name + ".", 1); } else { DebugWrite("Player " + aPlayer.player_name + " has been assigned the guest role.", 4); PlayerSayMessage(aPlayer.player_name, "You have been assigned the guest role.", 1); } } } aPlayer.player_role = aRole; aPlayer.player_aa = IsAdminAssistant(aPlayer); if (aPlayer.player_aa) { DebugWrite(aPlayer.player_name + " IS an Admin Assistant.", 3); } return authorized; }
//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; }
//DONE private AdKatsPlayer FetchPlayer(Boolean allowUpdate, Boolean allowOtherGames, Boolean allowNameSubstringSearch, Int32? gameID, Int64 playerID, String playerName, String playerGUID, String playerIP) { DebugWrite("fetchPlayer starting!", 6); //Create return list AdKatsPlayer aPlayer = null; //Make sure database connection active if (HandlePossibleDisconnect()) { //If AdKats is disconnected from the database, return the player as-is aPlayer = new AdKatsPlayer { game_id = _gameID, player_name = playerName, player_guid = playerGUID, player_ip = playerIP }; AssignPlayerRole(aPlayer); return aPlayer; } if (playerID < 0 && String.IsNullOrEmpty(playerName) && String.IsNullOrEmpty(playerGUID) && String.IsNullOrEmpty(playerIP)) { ConsoleError("Attempted to fetch player with no information."); } else { try { using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { String sql = @" SELECT `PlayerID` as `player_id`, `SoldierName` as `player_name`, `EAGUID` as `player_guid`, `PBGUID` as `player_pbguid`, `IP_Address` as `player_ip`"; if (_gameID > 0) { sql += ",`GameID` as `game_id` "; } sql += "FROM `" + _mySqlDatabaseName + @"`.`tbl_playerdata` "; bool sqlEnder = true; if (playerID >= 0) { sql += " WHERE ( "; sqlEnder = false; sql += " `PlayerID` = " + playerID + " "; } if (!String.IsNullOrEmpty(playerGUID)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `EAGUID` = '" + playerGUID + "' "; } if (String.IsNullOrEmpty(playerGUID) && !String.IsNullOrEmpty(playerName)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `SoldierName` LIKE '" + ((allowNameSubstringSearch) ? ("%" + playerName + "%") : (playerName)) + "' "; } if (String.IsNullOrEmpty(playerGUID) && !String.IsNullOrEmpty(playerIP)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `IP_Address` = '" + playerIP + "' "; } if (!sqlEnder) { sql += " ) "; } if ((_gameID > 0 && !allowOtherGames) || gameID != null) { if (gameID != null) { sql += " AND `GameID` = " + gameID + " "; } else { sql += " AND `GameID` = " + _gameID + " "; } } sql += @" LIMIT 1"; command.CommandText = sql; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { aPlayer = new AdKatsPlayer(); //Player ID will never be null aPlayer.player_id = reader.GetInt64("player_id"); aPlayer.game_id = reader.GetInt32("game_id"); if (!reader.IsDBNull(1)) aPlayer.player_name = reader.GetString("player_name"); if (!reader.IsDBNull(2)) aPlayer.player_guid = reader.GetString("player_guid"); if (!reader.IsDBNull(3)) aPlayer.player_pbguid = reader.GetString("player_pbguid"); if (!reader.IsDBNull(4)) aPlayer.player_ip = reader.GetString("player_ip"); } else { DebugWrite("No player matching search information. " + allowUpdate + ", " + allowOtherGames + ", " + ((gameID != null) ? (gameID + "") : ("No game ID")) + ", " + playerID + ", " + ((!String.IsNullOrEmpty(playerName)) ? (playerName) : ("No name search")) + ", " + ((!String.IsNullOrEmpty(playerGUID)) ? (playerGUID) : ("No GUID search")) + ", " + ((!String.IsNullOrEmpty(playerIP)) ? (playerIP) : ("No IP search")), 4); } } } if (allowUpdate) { if (aPlayer == null) { DebugWrite("Adding player to database.", 5); using (MySqlCommand command = connection.CreateCommand()) { Int32? useableGameID = null; if (gameID != null) { useableGameID = gameID; } else if (_gameID > 0) { useableGameID = _gameID; } //Set the insert command structure Boolean hasPrevious = (_gameID > 0) || !String.IsNullOrEmpty(playerName) || !String.IsNullOrEmpty(playerGUID) || !String.IsNullOrEmpty(playerIP); command.CommandText = @" INSERT INTO `" + _mySqlDatabaseName + @"`.`tbl_playerdata` ( " + ((useableGameID != null) ? ("`GameID`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerName)) ? (((useableGameID != null) ? (",") : ("")) + "`SoldierName`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? ((hasPrevious ? (",") : ("")) + "`EAGUID`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? ((hasPrevious ? (",") : ("")) + "`IP_Address`") : ("")) + @" ) VALUES ( " + ((useableGameID != null) ? (useableGameID + "") : ("")) + @" " + ((!String.IsNullOrEmpty(playerName)) ? (((useableGameID != null) ? (",") : ("")) + "'" + playerName + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? ((hasPrevious ? (",") : ("")) + "'" + playerGUID + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? ((hasPrevious ? (",") : ("")) + "'" + playerIP + "'") : ("")) + @" ) ON DUPLICATE KEY UPDATE `PlayerID` = LAST_INSERT_ID(`PlayerID`) " + ((!String.IsNullOrEmpty(playerName)) ? (@",`SoldierName` = '" + playerName + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? (@",`EAGUID` = '" + playerGUID + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? (@",`IP_Address` = '" + playerIP + "'") : ("")); //Attempt to execute the query if (command.ExecuteNonQuery() > 0) { //Rows affected should be > 0 aPlayer = new AdKatsPlayer { player_id = command.LastInsertedId, player_name = playerName, player_guid = playerGUID, player_ip = playerIP }; if (useableGameID != null) { aPlayer.game_id = (long) useableGameID; } else { aPlayer.game_id = _gameID; } } else { ConsoleError("Unable to add player to database."); return null; } } } if (!String.IsNullOrEmpty(playerName) && !String.IsNullOrEmpty(aPlayer.player_guid) && playerName != aPlayer.player_name) { aPlayer.player_name_previous = aPlayer.player_name; aPlayer.player_name = playerName; var record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = _serverID, command_type = _CommandKeyDictionary["player_changename"], command_numeric = 0, target_name = aPlayer.player_name, target_player = aPlayer, source_name = "AdKats", record_message = aPlayer.player_name_previous }; QueueRecordForProcessing(record); DebugWrite(aPlayer.player_name_previous + " changed their name to " + playerName + ". Updating the database.", 2); UpdatePlayer(aPlayer); } } if (aPlayer == null) { return null; } //Assign player role AssignPlayerRole(aPlayer); //Pull player first seen if (aPlayer.player_id > 0) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT FirstSeenOnServer FROM tbl_server_player INNER JOIN tbl_playerstats ON tbl_playerstats.StatsID = tbl_server_player.StatsID WHERE tbl_server_player.PlayerID = @player_id ORDER BY tbl_playerstats.FirstSeenOnServer LIMIT 1"; command.Parameters.AddWithValue("@player_id", aPlayer.player_id); using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { aPlayer.player_firstseen = reader.GetDateTime("FirstSeenOnServer"); } else { aPlayer.player_firstseen = DateTime.UtcNow; DebugWrite("No stats found to fetch first seen time.", 5); } } } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT (Playtime/60) as playtime_minutes FROM tbl_server_player INNER JOIN tbl_playerstats ON tbl_playerstats.StatsID = tbl_server_player.StatsID WHERE tbl_server_player.PlayerID = @player_id AND tbl_server_player.Serverid = @server_id ORDER BY Serverid ASC"; command.Parameters.AddWithValue("@player_id", aPlayer.player_id); command.Parameters.AddWithValue("@server_id", _serverID); using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { aPlayer.player_serverplaytime = TimeSpan.FromMinutes(reader.GetDouble("playtime_minutes")); } else { DebugWrite("No stats found to fetch time on server.", 5); } } } } } } catch (Exception e) { HandleException(new AdKatsException("Error while fetching player.", e)); } } DebugWrite("fetchPlayer finished!", 6); return aPlayer; }
private void UpdatePlayerReputation(AdKatsPlayer aPlayer) { try { if (_commandSourceReputationDictionary == null || !_commandSourceReputationDictionary.Any() || _commandTargetReputationDictionary == null || !_commandTargetReputationDictionary.Any()) { DebugWrite("Reputation dictionaries not populated. Can't update reputation for " + aPlayer.player_name + ".", 4); } double sourceReputation = 0.0; double targetReputation = (-25) * FetchPoints(aPlayer, true); double totalReputation = 0; double totalReputationConstrained = 0; using (MySqlConnection connection = GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @"SELECT command_type, command_action, count(record_id) command_count FROM adkats_records_main WHERE source_id = @player_id AND target_name <> source_name GROUP BY command_type, command_action"; command.Parameters.AddWithValue("player_id", aPlayer.player_id); using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { String typeAction = reader.GetInt32("command_type") + "|" + reader.GetInt32("command_action"); Double command_count = reader.GetDouble("command_count"); Double weight = 0; if (_commandSourceReputationDictionary.TryGetValue(typeAction, out weight)) { sourceReputation += (weight * command_count); } else { ConsoleError("Unable to find source weight for type|action: " + typeAction); } } } } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @"SELECT command_type, command_action, count(record_id) command_count FROM adkats_records_main WHERE target_id = @player_id AND target_name <> source_name GROUP BY command_type, command_action"; command.Parameters.AddWithValue("player_id", aPlayer.player_id); using (MySqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { String typeAction = reader.GetInt32("command_type") + "|" + reader.GetInt32("command_action"); Double command_count = reader.GetDouble("command_count"); Double weight = 0; if (_commandTargetReputationDictionary.TryGetValue(typeAction, out weight)) { targetReputation += (weight * command_count); } else { ConsoleError("Unable to find target weight for type|action: " + typeAction); } } } } totalReputation = sourceReputation + targetReputation; if (totalReputation >= 0) { totalReputationConstrained = (1000 * totalReputation) / (totalReputation + 1000); } else { totalReputationConstrained = -(1000 * Math.Abs(totalReputation)) / (Math.Abs(totalReputation) + 1000); } using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @"REPLACE INTO adkats_player_reputation VALUES ( @player_id, @game_id, @target_rep, @source_rep, @total_rep, @total_rep_co )"; command.Parameters.AddWithValue("player_id", aPlayer.player_id); if (aPlayer.game_id <= 0) { aPlayer.game_id = _gameID; } command.Parameters.AddWithValue("game_id", aPlayer.game_id); command.Parameters.AddWithValue("target_rep", targetReputation); command.Parameters.AddWithValue("source_rep", sourceReputation); command.Parameters.AddWithValue("total_rep", totalReputation); command.Parameters.AddWithValue("total_rep_co", totalReputationConstrained); Int32 rowsAffected = command.ExecuteNonQuery(); if (_firstPlayerListComplete && aPlayer.player_reputation != totalReputationConstrained) { DebugWrite(aPlayer.player_name + "'s reputation " + ((totalReputationConstrained > aPlayer.player_reputation) ? ("increased") : ("decreased")) + " to " + Math.Round(totalReputationConstrained, 2), 3); } aPlayer.player_reputation = totalReputationConstrained; } } } catch (Exception e) { HandleException(new AdKatsException("Error while updating player reputation.", e)); } }
private void RunGCPHackCheck(AdKatsPlayer aPlayer, Boolean verbose) { try { //Fetch hack status from GCP servers Hashtable hcResponse = this.FetchGCPHackCheck(aPlayer.player_name); String status = (String) hcResponse["status"]; if (status == "success") { Hashtable response = (Hashtable) hcResponse["response"]; String result = (String) response["result"]; if (result == "dirty") { this.ConsoleWarn(aPlayer.player_name + " is hacking."); try { List<AdKatsWeaponStats> weaponList = (from DictionaryEntry pair in (Hashtable) response["weapons"] let weaponStats = (Hashtable) pair.Value select new AdKatsWeaponStats { ID = (String) pair.Key, Kills = (Double) weaponStats["kills"], Headshots = (Double) weaponStats["headshots"], DPS = (Double) weaponStats["DPS"], HSKR = (Double) weaponStats["HKR"], Hits = (Double) weaponStats["hit"], Shots = (Double) weaponStats["shot"] }).ToList(); AdKatsWeaponStats actedWeapon = null; Double actedDPS = 0; Double actedHSKR = 0; foreach (AdKatsWeaponStats weapon in weaponList) { if (weapon.DPS > actedDPS) { actedWeapon = weapon; actedDPS = weapon.DPS; } else if (weapon.HSKR > actedHSKR) { actedWeapon = weapon; actedHSKR = weapon.HSKR; } } //Create record for player in actual player list if (actedWeapon != null) { AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_ban_perm"], command_numeric = 0, target_name = aPlayer.player_name, target_player = aPlayer, source_name = "AutoAdmin", record_message = "Hacking/Cheating Automatic Ban [" + actedWeapon.ID.Replace("-", "").Replace(" ", "").ToUpper() + "-" + (int) actedWeapon.DPS + "DPS-" + (int) (actedWeapon.HSKR * 100) + "HSKR-" + (int) actedWeapon.Kills + "]" }; //Process the record this.QueueRecordForProcessing(record); this.ConsoleWarn(aPlayer.player_name + " auto-banned for hacking. [" + actedWeapon.ID.Replace("-", "").Replace(" ", "").ToUpper() + "-" + (int) actedWeapon.DPS + "DPS-" + (int) (actedWeapon.HSKR * 100) + "HSKR-" + (int) actedWeapon.Kills + "]"); } else { this.ConsoleError("actedWeapon was null in hackerchecker."); } } catch (Exception e) { this.HandleException(new AdKatsException("Unable to parse player hack information", e)); } } else if (result == "clean") { if (verbose) { this.ConsoleSuccess(aPlayer.player_name + " is clean."); } else { this.DebugWrite(aPlayer.player_name + " is clean.", 2); } } else { this.ConsoleError("Unknown hacker result '" + result + "'."); } } else { this.ConsoleError(aPlayer.player_name + " not found or could not be hacker-checked."); } } catch (Exception e) { this.HandleException(new AdKatsException("Error while processing GCP hack check.", e)); } }
private void QueuePlayerForHackerCheck(AdKatsPlayer player) { DebugWrite("Entering queuePlayerForHackerCheck", 7); try { if (_pluginEnabled) { DebugWrite("Preparing to queue player for hacker check", 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 (_HackerCheckerQueue) { _HackerCheckerQueue.Enqueue(player); DebugWrite("Player queued for checking", 6); _HackerCheckerWaitHandle.Set(); } } } catch (Exception e) { HandleException(new AdKatsException("Error while queueing player for hacker check.", e)); } DebugWrite("Exiting queuePlayerForHackerCheck", 7); }
private void RunStatSiteHackCheck(AdKatsPlayer aPlayer, Boolean debug) { this.DebugWrite("HackerChecker running on " + aPlayer.player_name, 5); Boolean acted = false; if (this._UseDpsChecker) { this.DebugWrite("Preparing to DPS check " + aPlayer.player_name, 5); acted = this.DamageHackCheck(aPlayer, debug); } if (this._UseHskChecker && !acted) { this.DebugWrite("Preparing to HSK check " + aPlayer.player_name, 5); acted = this.AimbotHackCheck(aPlayer, debug); } if (!acted && debug) { this.ConsoleSuccess(aPlayer.player_name + " is clean."); } }
public Boolean PlayerProtected(AdKatsPlayer aPlayer) { //Pull players from special player cache 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 (_specialPlayerGroupCache) { List<AdKatsSpecialPlayer> protectedList; if (_specialPlayerGroupCache.TryGetValue("whitelist_hackerchecker", out protectedList)) { foreach (AdKatsSpecialPlayer asPlayer in protectedList) { if (asPlayer.player_object != null && asPlayer.player_object.player_id == aPlayer.player_id) { DebugWrite(aPlayer.player_name + " protected from hacker checker by database ID.", 2); return true; } if (!String.IsNullOrEmpty(asPlayer.player_identifier)) { if (aPlayer.player_name == asPlayer.player_identifier) { DebugWrite(aPlayer.player_name + " protected from hacker checker by NAME.", 2); return true; } if (aPlayer.player_guid == asPlayer.player_identifier) { DebugWrite(aPlayer.player_name + " protected from hacker checker by GUID.", 2); return true; } if (aPlayer.player_ip == asPlayer.player_identifier) { DebugWrite(aPlayer.player_name + " protected from hacker checker by IP.", 2); return true; } } } } } return false; }
public AdKatsPlayerStats FetchPlayerStats(AdKatsPlayer aPlayer) { this.DebugWrite("entering getPlayerStats", 7); //Create return value AdKatsPlayerStats stats = new AdKatsPlayerStats(); try { //Fetch from BF3Stats Hashtable responseData = null; if (this._GameVersion == GameVersion.BF3) { responseData = this.fetchBF3StatsPlayer(aPlayer.player_name); if (responseData != null) { String dataStatus = (String) responseData["status"]; if (dataStatus == "error") { stats.StatsException = new AdKatsException("BF3 Stats reported error."); } else if (dataStatus == "notfound") { stats.StatsException = new AdKatsException(aPlayer.player_name + " not found"); } else { //Pull the global stats stats.Platform = (String) responseData["plat"]; stats.ClanTag = (String) responseData["tag"]; stats.Language = (String) responseData["language"]; stats.Country = (String) responseData["country"]; stats.CountryName = (String) responseData["country_name"]; DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); stats.FirstSeen = dtDateTime.AddSeconds((Double) responseData["date_insert"]); stats.LastPlayerUpdate = dtDateTime.AddSeconds((Double) responseData["date_update"]); //Get internal stats if (dataStatus == "data") { Hashtable statsList = (Hashtable) responseData["stats"]; stats.LastStatUpdate = dtDateTime.AddSeconds((Double) statsList["date_update"]); //Get rank Hashtable rankTable = (Hashtable) statsList["rank"]; stats.Rank = (Double) rankTable["nr"]; //Get overall Hashtable global = (Hashtable) statsList["global"]; stats.Kills = (Double) global["kills"]; stats.Deaths = (Double) global["deaths"]; stats.Wins = (Double) global["wins"]; stats.Losses = (Double) global["losses"]; stats.Shots = (Double) global["shots"]; stats.Hits = (Double) global["hits"]; stats.Headshots = (Double) global["headshots"]; stats.Time = TimeSpan.FromSeconds((Double) global["time"]); //Get weapons stats.WeaponStats = new Dictionary<String, AdKatsWeaponStats>(); Hashtable weaponStats = (Hashtable) statsList["weapons"]; foreach (String weaponKey in weaponStats.Keys) { //Create new construct AdKatsWeaponStats weapon = new AdKatsWeaponStats(); //Grab data Hashtable currentWeapon = (Hashtable) weaponStats[weaponKey]; //Parse into construct weapon.ID = (String) currentWeapon["id"]; weapon.Shots = (Double) currentWeapon["shots"]; weapon.Hits = (Double) currentWeapon["hits"]; weapon.Kills = (Double) currentWeapon["kills"]; weapon.Headshots = (Double) currentWeapon["headshots"]; weapon.Category = (String) currentWeapon["category"]; weapon.Kit = (String) currentWeapon["kit"]; weapon.Range = (String) currentWeapon["range"]; weapon.Time = TimeSpan.FromSeconds((Double) currentWeapon["time"]); //Calculate values weapon.HSKR = weapon.Headshots / weapon.Kills; weapon.KPM = weapon.Kills / weapon.Time.TotalMinutes; weapon.DPS = weapon.Kills / weapon.Hits * 100; //Assign the construct stats.WeaponStats.Add(weapon.ID, weapon); } } else { stats.StatsException = new AdKatsException(aPlayer.player_name + " did not have stats"); } } } } else if (this._GameVersion == GameVersion.BF4) { responseData = this.FetchBF4StatsPlayer(aPlayer.player_name); if (responseData != null) { if (responseData.ContainsKey("error")) { stats.StatsException = new AdKatsException("BF4 stats returned error '" + ((String) responseData["error"]) + "' when querying for player '" + aPlayer.player_name + "'."); this.ConsoleError(stats.StatsException.ToString()); return null; } else if (!responseData.ContainsKey("player") || !responseData.ContainsKey("stats") || !responseData.ContainsKey("weapons")) { stats.StatsException = new AdKatsException("BF4 stats response for player '" + aPlayer.player_name + "' was invalid."); this.ConsoleError(stats.StatsException.ToString()); return null; } else { try { //Player section Hashtable playerData = (Hashtable) responseData["player"]; if (playerData != null && playerData.Count > 0) { stats.Platform = (String) playerData["plat"]; stats.ClanTag = (String) playerData["tag"]; stats.Country = (String) playerData["country"]; stats.CountryName = (String) playerData["countryName"]; DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); Double createMilli = (Double) playerData["dateCreate"]; stats.FirstSeen = dtDateTime.AddMilliseconds(createMilli); Double updateMilli = (Double) playerData["dateUpdate"]; stats.LastPlayerUpdate = dtDateTime.AddMilliseconds(updateMilli); //Get rank Hashtable rankData = (Hashtable) playerData["rank"]; stats.Rank = (Double) rankData["nr"]; } else { stats.StatsException = new AdKatsException(aPlayer.player_name + " did not have global info."); } //Get Stats Hashtable statsData = (Hashtable) responseData["stats"]; if (statsData != null && statsData.Count > 0) { //Stat last update is the same as last player update in BF4 stats.LastStatUpdate = stats.LastPlayerUpdate; stats.Kills = (Double) statsData["kills"]; stats.Deaths = (Double) statsData["deaths"]; stats.Wins = (Double) statsData["numWins"]; stats.Losses = (Double) statsData["numLosses"]; stats.Shots = (Double) statsData["shotsFired"]; stats.Hits = (Double) statsData["shotsHit"]; stats.Headshots = (Double) statsData["headshots"]; stats.Time = TimeSpan.FromSeconds((Double) statsData["timePlayed"]); } else { stats.StatsException = new AdKatsException(aPlayer.player_name + " did not have global stats."); } //Get Weapons ArrayList weaponData = (ArrayList) responseData["weapons"]; if (weaponData != null && weaponData.Count > 0) { stats.WeaponStats = new Dictionary<String, AdKatsWeaponStats>(); foreach (Hashtable currentWeapon in weaponData) { //Create new construct AdKatsWeaponStats weapon = new AdKatsWeaponStats(); //Grab stat data Hashtable currentWeaponStats = (Hashtable) currentWeapon["stat"]; weapon.ID = (String) currentWeaponStats["id"]; weapon.Time = TimeSpan.FromSeconds((Double) currentWeaponStats["time"]); weapon.Shots = (Double) currentWeaponStats["shots"]; weapon.Hits = (Double) currentWeaponStats["hits"]; weapon.Kills = (Double) currentWeaponStats["kills"]; weapon.Headshots = (Double) currentWeaponStats["hs"]; //Grab detail data Hashtable currentWeaponDetail = (Hashtable) currentWeapon["detail"]; weapon.Category = (String) currentWeaponDetail["category"]; //leave kit alone //leave range alone //Calculate values weapon.HSKR = weapon.Headshots / weapon.Kills; weapon.KPM = weapon.Kills / weapon.Time.TotalMinutes; weapon.DPS = weapon.Kills / weapon.Hits * 100; //Assign the construct stats.WeaponStats.Add(weapon.ID, weapon); } } else { stats.StatsException = new AdKatsException(aPlayer.player_name + " did not have weapon stats."); } } catch (Exception e) { this.ConsoleError(e.ToString()); } } } } } catch (Exception e) { stats.StatsException = new AdKatsException("Server error fetching stats.", e); } //Assign the stats if no errors if (stats.StatsException == null) { aPlayer.stats = stats; } else { //this.HandleException(stats.stats_exception); } this.DebugWrite("exiting getPlayerStats", 7); return stats; }
private Boolean KPMHackCheck(AdKatsPlayer aPlayer, Boolean debugMode) { Boolean acted = false; try { if (aPlayer == null || aPlayer.stats == null || aPlayer.stats.WeaponStats == null) { return false; } List<String> allowedCategories; switch (_gameVersion) { case GameVersion.BF3: allowedCategories = new List<string> { "Sub machine guns", "Assault rifles", "Carbines", "Machine guns", "Sniper rifles", "Shotguns" }; break; case GameVersion.BF4: allowedCategories = new List<string> { "PDW", "ASSAULT RIFLE", "CARBINE", "LMG", "SNIPER RIFLE", "DMR", "SHOTGUN" }; break; default: return false; } List<AdKatsWeaponStats> topWeapons = aPlayer.stats.WeaponStats.Values.ToList(); topWeapons.Sort(delegate(AdKatsWeaponStats a1, AdKatsWeaponStats a2) { if (a1.Kills == a2.Kills) { return 0; } return (a1.Kills < a2.Kills) ? (1) : (-1); }); AdKatsWeaponStats actedWeapon = null; Double actedKpm = -1; Int32 index = 0; foreach (AdKatsWeaponStats weaponStat in topWeapons) { //Break after 15th top weapon if (index++ > 15) { break; } //Only count certain weapon categories if (allowedCategories.Contains(weaponStat.Category)) { //Only take weapons with more than 100 kills if (weaponStat.Kills > 100) { //Check for KPM limit DebugWrite("Checking " + weaponStat.ID + " KPM (" + String.Format("{0:0.00}", weaponStat.KPM) + " >? " + (_KpmTriggerLevel) + ")", 6); if (weaponStat.KPM > (_KpmTriggerLevel)) { if (weaponStat.KPM > actedKpm) { actedKpm = weaponStat.KPM; actedWeapon = weaponStat; } } } } } if (actedWeapon != null) { acted = true; String formattedName = actedWeapon.ID.Replace("-", "").Replace(" ", "").ToUpper(); ConsoleWarn(aPlayer.player_name + ((debugMode) ? (" debug") : (" auto")) + "-banned for KPM. [" + formattedName + "-" + String.Format("{0:0.00}", actedWeapon.KPM) + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]"); if (!debugMode) { //Create the ban record var record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = _serverID, command_type = _CommandKeyDictionary["player_ban_perm"], command_numeric = 0, target_name = aPlayer.player_name, target_player = aPlayer, source_name = "AutoAdmin", record_message = _HackerCheckerKPMBanMessage + " [" + formattedName + "-" + String.Format("{0:0.00}", actedWeapon.KPM) + "-" + (int) actedWeapon.Kills + "-" + (int) actedWeapon.Headshots + "]" }; //Process the record QueueRecordForProcessing(record); } } } catch (Exception e) { HandleException(new AdKatsException("Error running KPM hack check.", e)); } return acted; }
public void SetPluginVariable(String strVariable, String strValue) { if (strValue == null) { return; } try { //this.ConsoleWrite("'" + strVariable + "' -> '" + strValue + "'"); if (strVariable == "UpdateSettings") { //Do nothing. Settings page will be updated after return. } else if (Regex.Match(strVariable, @"Auto-Enable/Keep-Alive").Success) { Boolean autoEnable = Boolean.Parse(strValue); if (autoEnable != this._UseKeepAlive) { if(autoEnable) this.Enable(); this._UseKeepAlive = autoEnable; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Auto-Enable/Keep-Alive", typeof (Boolean), this._UseKeepAlive)); } } else if (Regex.Match(strVariable, @"Send Query").Success) { this.SendQuery(strValue, true); } else if (Regex.Match(strVariable, @"Send Non-Query").Success) { this.SendNonQuery("Experimental Query", strValue, true); } else if (Regex.Match(strVariable, @"Hacker-Check Player").Success) { if (String.IsNullOrEmpty(strValue) || !this._ThreadsReady) { return; } this.ConsoleWarn("Preparing to hacker check " + strValue); if (String.IsNullOrEmpty(strValue) || strValue.Length < 3) { this.ConsoleError("Player name must be at least 3 characters long."); return; } if (!this.SoldierNameValid(strValue)) { this.ConsoleError("Player name contained invalid characters."); return; } AdKatsPlayer aPlayer = new AdKatsPlayer() { player_name = strValue }; this.FetchPlayerStats(aPlayer); if (aPlayer.stats != null) { this.RunStatSiteHackCheck(aPlayer, true); } else { this.ConsoleError("Stats not found for " + strValue); } } else if (Regex.Match(strVariable, @"Setting Import").Success) { Int32 tmp = -1; if (int.TryParse(strValue, out tmp)) { if (tmp != -1) this.QueueSettingImport(tmp); } else { this.ConsoleError("Invalid Input for Setting Import"); } } else if (Regex.Match(strVariable, @"Using AdKats WebAdmin").Success) { Boolean tmp = false; if (Boolean.TryParse(strValue, out tmp)) { this._UsingAwa = tmp; //Update necessary settings for AWA use if (this._UsingAwa) { this._UseBanEnforcer = true; this._FetchActionsFromDb = true; this._DbCommunicationWaitHandle.Set(); } } else { this.ConsoleError("Invalid Input for Using AdKats WebAdmin"); } } #region debugging else if (Regex.Match(strVariable, @"Command Entry").Success) { if (String.IsNullOrEmpty(strValue)) { return; } //Check if the message is a command if (strValue.StartsWith("@") || strValue.StartsWith("!")) { strValue = strValue.Substring(1); } else if (strValue.StartsWith("/@") || strValue.StartsWith("/!")) { strValue = strValue.Substring(2); } else if (strValue.StartsWith("/")) { strValue = strValue.Substring(1); } else { this.ConsoleError("Invalid command format."); return; } AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.Settings, source_name = "SettingsAdmin" }; this.CompleteRecordInformation(record, strValue); } else if (Regex.Match(strVariable, @"Debug level").Success) { Int32 tmp = 2; if (int.TryParse(strValue, out tmp)) { if (tmp != this._DebugLevel) { this._DebugLevel = tmp; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Debug level", typeof (int), this._DebugLevel)); } } } else if (Regex.Match(strVariable, @"Debug Soldier Name").Success) { if (this.SoldierNameValid(strValue)) { if (strValue != this._DebugSoldierName) { this._DebugSoldierName = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Debug Soldier Name", typeof (String), this._DebugSoldierName)); } } } else if (Regex.Match(strVariable, @"Server VOIP Address").Success) { if (strValue != this._ServerVoipAddress) { this._ServerVoipAddress = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Server VOIP Address", typeof (String), this._ServerVoipAddress)); } } else if (Regex.Match(strVariable, @"Rule Print Delay").Success) { Double delay = Double.Parse(strValue); if (this._ServerRulesDelay != delay) { if (delay <= 0) { this.ConsoleError("Delay cannot be negative."); delay = 1.0; } this._ServerRulesDelay = delay; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Rule Print Delay", typeof (Double), this._ServerRulesDelay)); } } else if (Regex.Match(strVariable, @"Rule Print Interval").Success) { Double interval = Double.Parse(strValue); if (this._ServerRulesInterval != interval) { if (interval <= 0) { this.ConsoleError("Interval cannot be negative."); interval = 5.0; } this._ServerRulesInterval = interval; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Rule Print Interval", typeof (Double), this._ServerRulesInterval)); } } else if (Regex.Match(strVariable, @"Server Rule List").Success) { this._ServerRulesList = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Server Rule List", typeof (String), CPluginVariable.EncodeStringArray(this._ServerRulesList))); } else if (Regex.Match(strVariable, @"Feed MULTIBalancer Whitelist").Success) { Boolean feedMTB = Boolean.Parse(strValue); if (feedMTB != this._FeedMultiBalancerWhitelist) { this._FeedMultiBalancerWhitelist = feedMTB; this.FetchUserList(); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Feed MULTIBalancer Whitelist", typeof (Boolean), this._FeedMultiBalancerWhitelist)); } } else if (Regex.Match(strVariable, @"Feed Server Reserved Slots").Success) { Boolean feedSRS = Boolean.Parse(strValue); if (feedSRS != this._FeedServerReservedSlots) { this._FeedServerReservedSlots = feedSRS; this.FetchUserList(); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Feed Server Reserved Slots", typeof(Boolean), this._FeedServerReservedSlots)); } } else if (Regex.Match(strVariable, @"Feed Server Spectator List").Success) { Boolean feedSSL = Boolean.Parse(strValue); if (feedSSL != this._FeedServerSpectatorList) { if (this._GameVersion != GameVersion.BF4) { this.ConsoleError("This feature can only be enabled on BF4 servers."); return; } this._FeedServerSpectatorList = feedSSL; this.FetchUserList(); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Feed Server Spectator List", typeof(Boolean), this._FeedServerSpectatorList)); } } else if (Regex.Match(strVariable, @"Feed Stat Logger Settings").Success) { Boolean feedSLS = Boolean.Parse(strValue); if (feedSLS != this._FeedStatLoggerSettings) { this._FeedStatLoggerSettings = feedSLS; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Feed Stat Logger Settings", typeof (Boolean), this._FeedStatLoggerSettings)); } } else if (Regex.Match(strVariable, @"Use Experimental Tools").Success) { Boolean useEXP = Boolean.Parse(strValue); if (useEXP != this._UseExperimentalTools) { this._UseExperimentalTools = useEXP; if (this._UseExperimentalTools) { if (this._ThreadsReady) { this.ConsoleWarn("Using experimental tools. Take caution."); } } else { this.ConsoleWarn("Experimental tools disabled."); this._UseWeaponLimiter = false; this._UseGrenadeCookCatcher = false; this._UseHackerChecker = false; this._UseDpsChecker = false; this._UseHskChecker = false; } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use Experimental Tools", typeof (Boolean), this._UseExperimentalTools)); this.QueueSettingForUpload(new CPluginVariable(@"Use NO EXPLOSIVES Limiter", typeof (Boolean), this._UseWeaponLimiter)); } } else if (Regex.Match(strVariable, @"Round Timer: Enable").Success) { Boolean useTimer = Boolean.Parse(strValue); if (useTimer != this._UseRoundTimer) { this._UseRoundTimer = useTimer; if (this._UseRoundTimer) { if (this._ThreadsReady) { this.ConsoleWarn("Internal Round Timer activated, will enable on next round."); } } else { this.ConsoleWarn("Internal Round Timer disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Round Timer: Enable", typeof (Boolean), this._UseRoundTimer)); } } else if (Regex.Match(strVariable, @"Round Timer: Round Duration Minutes").Success) { Double duration = Double.Parse(strValue); if (this._RoundTimeMinutes != duration) { if (duration <= 0) { duration = 30.0; } this._RoundTimeMinutes = duration; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Round Timer: Round Duration Minutes", typeof (Double), this._RoundTimeMinutes)); } } else if (Regex.Match(strVariable, @"Use NO EXPLOSIVES Limiter").Success) { Boolean useLimiter = Boolean.Parse(strValue); if (useLimiter != this._UseWeaponLimiter) { this._UseWeaponLimiter = useLimiter; if (this._UseWeaponLimiter) { if (this._ThreadsReady) { this.ConsoleWarn("Internal NO EXPLOSIVES punish limit activated."); } } else { this.ConsoleWarn("Internal NO EXPLOSIVES punish limit disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use NO EXPLOSIVES Limiter", typeof (Boolean), this._UseWeaponLimiter)); } } else if (Regex.Match(strVariable, @"NO EXPLOSIVES Weapon String").Success) { if (this._WeaponLimiterString != strValue) { if (!String.IsNullOrEmpty(strValue)) { this._WeaponLimiterString = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"NO EXPLOSIVES Weapon String", typeof (String), this._WeaponLimiterString)); } else { this.ConsoleError("Weapon String cannot be empty."); } } } else if (Regex.Match(strVariable, @"NO EXPLOSIVES Exception String").Success) { if (this._WeaponLimiterExceptionString != strValue) { if (!String.IsNullOrEmpty(strValue)) { this._WeaponLimiterExceptionString = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"NO EXPLOSIVES Exception String", typeof (String), this._WeaponLimiterExceptionString)); } else { this.ConsoleError("Weapon exception String cannot be empty."); } } } else if (Regex.Match(strVariable, @"Use Grenade Cook Catcher").Success) { Boolean useCookCatcher = Boolean.Parse(strValue); if (useCookCatcher != this._UseGrenadeCookCatcher) { this._UseGrenadeCookCatcher = useCookCatcher; if (this._UseGrenadeCookCatcher) { if (this._ThreadsReady) { this.ConsoleWarn("Internal Grenade Cook Catcher activated."); } } else { this.ConsoleWarn("Internal Grenade Cook Catcher disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use Grenade Cook Catcher", typeof (Boolean), this._UseGrenadeCookCatcher)); } } else if (Regex.Match(strVariable, @"HackerChecker: Enable").Success) { Boolean useHackChecker = Boolean.Parse(strValue); if (useHackChecker != this._UseHackerChecker) { this._UseHackerChecker = useHackChecker; if (this._UseHackerChecker) { if (this._ThreadsReady) { this.ConsoleWarn("Internal Hacker Checker activated."); } } else { this.ConsoleWarn("Internal Hacker Checker disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: Enable", typeof (Boolean), this._UseHackerChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: Whitelist").Success) { this._HackerCheckerWhitelist = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: Whitelist", typeof (String), CPluginVariable.EncodeStringArray(this._HackerCheckerWhitelist))); } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Enable").Success) { Boolean useDamageChecker = Boolean.Parse(strValue); if (useDamageChecker != this._UseDpsChecker) { this._UseDpsChecker = useDamageChecker; if (this._UseDpsChecker) { if (this._ThreadsReady) { this.ConsoleWarn("Internal Damage Mod Checker activated."); } } else { this.ConsoleWarn("Internal Damage Mod Checker disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Enable", typeof (Boolean), this._UseDpsChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Trigger Level").Success) { Double triggerLevel = Double.Parse(strValue); if (this._DpsTriggerLevel != triggerLevel) { if (triggerLevel <= 0) { triggerLevel = 100.0; } this._DpsTriggerLevel = triggerLevel; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Trigger Level", typeof (Double), this._DpsTriggerLevel)); } } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Ban Message").Success) { if (this._HackerCheckerDPSBanMessage != strValue) { this._HackerCheckerDPSBanMessage = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Ban Message", typeof(String), this._HackerCheckerDPSBanMessage)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Enable").Success) { Boolean useAimbotChecker = Boolean.Parse(strValue); if (useAimbotChecker != this._UseHskChecker) { this._UseHskChecker = useAimbotChecker; if (this._UseHskChecker) { if (this._ThreadsReady) { this.ConsoleWarn("Internal Aimbot Checker activated."); } } else { this.ConsoleWarn("Internal Aimbot Checker disabled."); } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Enable", typeof (Boolean), this._UseHskChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Trigger Level").Success) { Double triggerLevel = Double.Parse(strValue); if (this._HskTriggerLevel != triggerLevel) { if (triggerLevel <= 0) { triggerLevel = 100.0; } this._HskTriggerLevel = triggerLevel; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Trigger Level", typeof (Double), this._HskTriggerLevel)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Ban Message").Success) { if (this._HackerCheckerHSKBanMessage != strValue) { this._HackerCheckerHSKBanMessage = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Ban Message", typeof(String), this._HackerCheckerHSKBanMessage)); } } #endregion #region HTTP settings else if (Regex.Match(strVariable, @"External Access Key").Success) { if (strValue != this._ExternalCommandAccessKey) { this._ExternalCommandAccessKey = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"External Access Key", typeof (String), this._ExternalCommandAccessKey)); } } else if (Regex.Match(strVariable, @"Fetch Actions from Database").Success) { Boolean fetch = Boolean.Parse(strValue); if (fetch != this._FetchActionsFromDb) { this._FetchActionsFromDb = fetch; this._DbCommunicationWaitHandle.Set(); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Fetch Actions from Database", typeof (Boolean), this._FetchActionsFromDb)); } } #endregion #region ban settings else if (Regex.Match(strVariable, @"Use Additional Ban Message").Success) { Boolean use = Boolean.Parse(strValue); if (this._UseBanAppend != use) { this._UseBanAppend = use; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use Additional Ban Message", typeof (Boolean), this._UseBanAppend)); } } else if (Regex.Match(strVariable, @"Additional Ban Message").Success) { if (strValue.Length > 30) { strValue = strValue.Substring(0, 30); this.ConsoleError("Ban append cannot be more than 30 characters."); } if (this._BanAppend != strValue) { this._BanAppend = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Additional Ban Message", typeof (String), this._BanAppend)); } } else if (Regex.Match(strVariable, @"Procon Ban Admin Name").Success) { if (strValue.Length > 16) { strValue = strValue.Substring(0, 16); this.ConsoleError("Procon ban admin id cannot be more than 16 characters."); } if (this._CBanAdminName != strValue) { this._CBanAdminName = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Procon Ban Admin Name", typeof (String), this._CBanAdminName)); } } else if (Regex.Match(strVariable, @"Use Ban Enforcer").Success) { Boolean use = Boolean.Parse(strValue); if (this._UseBanEnforcer != use) { this._UseBanEnforcer = use; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use Ban Enforcer", typeof (Boolean), this._UseBanEnforcer)); if (this._UseBanEnforcer) { this._FetchActionsFromDb = true; this._DbCommunicationWaitHandle.Set(); } } } else if (Regex.Match(strVariable, @"Enforce New Bans by NAME").Success) { Boolean enforceName = Boolean.Parse(strValue); if (this._DefaultEnforceName != enforceName) { this._DefaultEnforceName = enforceName; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by NAME", typeof (Boolean), this._DefaultEnforceName)); } } else if (Regex.Match(strVariable, @"Enforce New Bans by GUID").Success) { Boolean enforceGUID = Boolean.Parse(strValue); if (this._DefaultEnforceGUID != enforceGUID) { this._DefaultEnforceGUID = enforceGUID; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by GUID", typeof (Boolean), this._DefaultEnforceGUID)); } } else if (Regex.Match(strVariable, @"Enforce New Bans by IP").Success) { Boolean enforceIP = Boolean.Parse(strValue); if (this._DefaultEnforceIP != enforceIP) { this._DefaultEnforceIP = enforceIP; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by IP", typeof(Boolean), this._DefaultEnforceIP)); } } else if (Regex.Match(strVariable, @"Ban Search").Success) { if (String.IsNullOrEmpty(strValue) || strValue.Length < 3) { this.ConsoleError("Search query must be 3 or more characters."); return; } lock (this._BanEnforcerSearchResults) { this._BanEnforcerSearchResults = new List<AdKatsBan>(); List<AdKatsPlayer> matchingPlayers; if (this.FetchMatchingPlayers(strValue, out matchingPlayers, false)) { foreach (AdKatsPlayer aPlayer in matchingPlayers) { AdKatsBan aBan = this.FetchPlayerBan(aPlayer); if (aBan != null) { this._BanEnforcerSearchResults.Add(aBan); } } } if (this._BanEnforcerSearchResults.Count == 0) { this.ConsoleError("No players matching '" + strValue + "' have active bans."); } } } #endregion #region In-Game Command Settings else if (Regex.Match(strVariable, @"Minimum Required Reason Length").Success) { Int32 required = Int32.Parse(strValue); if (this._RequiredReasonLength != required) { this._RequiredReasonLength = required; if (this._RequiredReasonLength < 1) { this._RequiredReasonLength = 1; } //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Minimum Required Reason Length", typeof (Int32), this._RequiredReasonLength)); } } else if (Regex.Match(strVariable, @"Allow Commands from Admin Say").Success) { Boolean allowSayCommands = Boolean.Parse(strValue); if (this._AllowAdminSayCommands != allowSayCommands) { this._AllowAdminSayCommands = allowSayCommands; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Allow Commands from Admin Say", typeof(Boolean), this._AllowAdminSayCommands)); } } else if (strVariable.StartsWith("USR")) { //USR1 | ColColonCleaner | User Email //USR1 | ColColonCleaner | User Phone //USR1 | ColColonCleaner | User Role //USR1 | ColColonCleaner | Delete User? //USR1 | ColColonCleaner | Add Soldier? //USR1 | ColColonCleaner | Soldiers | 293492 | ColColonCleaner | Delete Soldier? String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String user_id_str = commandSplit[0].TrimStart("USR".ToCharArray()).Trim(); Int32 user_id = Int32.Parse(user_id_str); String section = commandSplit[2].Trim(); AdKatsUser aUser = null; if (this._UserCache.TryGetValue(user_id, out aUser)) { switch (section) { case "User Email": if (String.IsNullOrEmpty(strValue) || Regex.IsMatch(strValue, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")) { aUser.user_email = strValue; } else { this.ConsoleError(strValue + " is an invalid email address."); return; } //Reupload the user this.QueueUserForUpload(aUser); break; case "User Phone": aUser.user_phone = strValue; //Reupload the user this.QueueUserForUpload(aUser); break; case "User Role": AdKatsRole aRole = null; if (this._RoleNameDictionary.TryGetValue(strValue, out aRole)) { aUser.user_role = aRole; } else { this.ConsoleError("Role " + strValue + " not found."); return; } //Reupload the user this.QueueUserForUpload(aUser); break; case "Delete User?": if (strValue.ToLower() == "delete") { this.QueueUserForRemoval(aUser); } break; case "Add Soldier?": this.TryAddUserSoldier(aUser, strValue); //Reupload the user this.QueueUserForUpload(aUser); break; case "Soldiers": if (strVariable.Contains("Delete Soldier?") && strValue.ToLower() == "delete") { String player_id_str = commandSplit[3].Trim(); Int64 player_id = Int64.Parse(player_id_str); aUser.soldierDictionary.Remove(player_id); //Reupload the user this.QueueUserForUpload(aUser); } break; default: this.ConsoleError("Section " + section + " not found."); break; } } } else if (strVariable.StartsWith("CDE")) { //Trim off all but the command ID and section //5. Command List|CDE1 | Kill Player | Active //5. Command List|CDE1 | Kill Player | Logging //5. Command List|CDE1 | Kill Player | Text String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String command_id_str = commandSplit[0].TrimStart("CDE".ToCharArray()).Trim(); Int32 command_id = Int32.Parse(command_id_str); String section = commandSplit[2].Trim(); AdKatsCommand command = null; if (this._CommandIDDictionary.TryGetValue(command_id, out command)) { if (section == "Active") { //Check for valid value if (strValue == "Active") { command.command_active = AdKatsCommand.CommandActive.Active; } else if (strValue == "Disabled") { command.command_active = AdKatsCommand.CommandActive.Disabled; } else if (strValue == "Invisible") { command.command_active = AdKatsCommand.CommandActive.Invisible; } else { this.ConsoleError("Activity setting " + strValue + " was invalid."); return; } } else if (section == "Logging") { //Check for valid value switch (strValue) { case "Log": command.command_logging = AdKatsCommand.CommandLogging.Log; break; case "Mandatory": command.command_logging = AdKatsCommand.CommandLogging.Mandatory; break; case "Ignore": command.command_logging = AdKatsCommand.CommandLogging.Ignore; break; case "Unable": command.command_logging = AdKatsCommand.CommandLogging.Unable; break; default: this.ConsoleError("Logging setting " + strValue + " was invalid."); return; } } else if (section == "Text") { if (String.IsNullOrEmpty(strValue)) { this.ConsoleError("Command text cannot be blank."); return; } //Make sure command text only contains alphanumeric chars, underscores, and dashes Regex rgx = new Regex("[^a-zA-Z0-9_-]"); strValue = rgx.Replace(strValue, ""); //Check to make sure text is not a duplicate foreach (AdKatsCommand testCommand in this._CommandNameDictionary.Values) { if (testCommand.command_text == strValue) { this.ConsoleError("Command text cannot be the same as another command."); return; } } //Assign the command text command.command_text = strValue; } else { this.ConsoleError("Section " + section + " not understood."); return; } //Upload the command changes this.QueueCommandForUpload(command); } else { this.ConsoleError("Command " + command_id + " not found in command dictionary."); } } else if (strVariable.StartsWith("RLE")) { //Trim off all but the command ID and section //RLE1 | Default Guest | CDE3 | Kill Player String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String roleIDStr = commandSplit[0].TrimStart("RLE".ToCharArray()).Trim(); Int32 roleID = Int32.Parse(roleIDStr); //If second section is a command prefix, this is the allow/deny clause if (commandSplit[2].Trim().StartsWith("CDE")) { String commandIDStr = commandSplit[2].Trim().TrimStart("CDE".ToCharArray()); Int32 commandID = Int32.Parse(commandIDStr); //Fetch needed role AdKatsRole aRole = null; if (this._RoleIDDictionary.TryGetValue(roleID, out aRole)) { //Fetch needed command AdKatsCommand aCommand = null; if (this._CommandIDDictionary.TryGetValue(commandID, out aCommand)) { switch (strValue.ToLower()) { case "allow": lock (aRole.allowedCommands) { if (!aRole.allowedCommands.ContainsKey(aCommand.command_key)) { aRole.allowedCommands.Add(aCommand.command_key, aCommand); } } this.QueueRoleForUpload(aRole); break; case "deny": lock (aRole.allowedCommands) { aRole.allowedCommands.Remove(aCommand.command_key); } this.QueueRoleForUpload(aRole); break; default: this.ConsoleError("Unknown setting when assigning command allowance."); return; } } else { this.ConsoleError("Command " + commandID + " not found in command dictionary."); } } else { this.ConsoleError("Role " + roleID + " not found in role dictionary."); } } else if (commandSplit[2].Contains("Delete Role?") && strValue.ToLower() == "delete") { //Fetch needed role AdKatsRole aRole = null; if (this._RoleIDDictionary.TryGetValue(roleID, out aRole)) { this.QueueRoleForRemoval(aRole); } else { this.ConsoleError("Unable to fetch role for deletion."); } } } else if (strVariable.StartsWith("BAN")) { //Trim off all but the command ID and section //BAN1 | ColColonCleaner | Some Reason String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String banIDStr = commandSplit[0].TrimStart("BAN".ToCharArray()).Trim(); Int32 banID = Int32.Parse(banIDStr); AdKatsBan aBan = null; foreach (AdKatsBan innerBan in this._BanEnforcerSearchResults) { if (innerBan.ban_id == banID) { aBan = innerBan; break; } } if (aBan != null) { switch (strValue) { case "Active": aBan.ban_status = strValue; break; case "Disabled": aBan.ban_status = strValue; break; default: this.ConsoleError("Unknown setting when assigning ban status."); return; } this.UpdateBanStatus(aBan); this.ConsoleSuccess("Ban " + aBan.ban_id + " is now " + strValue); } else { this.ConsoleError("Unable to update ban. This should not happen."); } } #endregion #region punishment settings else if (Regex.Match(strVariable, @"Punishment Hierarchy").Success) { this._PunishmentHierarchy = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Punishment Hierarchy", typeof (String), CPluginVariable.EncodeStringArray(this._PunishmentHierarchy))); } else if (Regex.Match(strVariable, @"Combine Server Punishments").Success) { Boolean combine = Boolean.Parse(strValue); if (this._CombineServerPunishments != combine) { this._CombineServerPunishments = combine; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Combine Server Punishments", typeof (Boolean), this._CombineServerPunishments)); } } else if (Regex.Match(strVariable, @"Only Kill Players when Server in low population").Success) { Boolean onlyKill = Boolean.Parse(strValue); if (onlyKill != this._OnlyKillOnLowPop) { this._OnlyKillOnLowPop = onlyKill; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Only Kill Players when Server in low population", typeof (Boolean), this._OnlyKillOnLowPop)); } } else if (Regex.Match(strVariable, @"Low Population Value").Success) { Int32 lowPop = Int32.Parse(strValue); if (lowPop != this._LowPopPlayerCount) { this._LowPopPlayerCount = lowPop; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Low Population Value", typeof (Int32), this._LowPopPlayerCount)); } } else if (Regex.Match(strVariable, @"Use IRO Punishment").Success) { Boolean iro = Boolean.Parse(strValue); if (iro != this._IROActive) { this._IROActive = iro; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Use IRO Punishment", typeof (Boolean), this._IROActive)); } } else if (Regex.Match(strVariable, @"IRO Punishment Overrides Low Pop").Success) { Boolean overrideIRO = Boolean.Parse(strValue); if (overrideIRO != this._IROOverridesLowPop) { this._IROOverridesLowPop = overrideIRO; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"IRO Punishment Overrides Low Pop", typeof (Boolean), this._IROOverridesLowPop)); } } else if (Regex.Match(strVariable, @"IRO Timeout Minutes").Success) { Int32 timeout = Int32.Parse(strValue); if (timeout != this._IROTimeout) { this._IROTimeout = timeout; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"IRO Timeout (Minutes)", typeof (Int32), this._IROTimeout)); } } #endregion #region sql settings else if (Regex.Match(strVariable, @"MySQL Hostname").Success) { _MySqlHostname = strValue; this._DbSettingsChanged = true; this._DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Port").Success) { Int32 tmp = 3306; int.TryParse(strValue, out tmp); if (tmp > 0 && tmp < 65536) { _MySqlPort = strValue; this._DbSettingsChanged = true; this._DbCommunicationWaitHandle.Set(); } else { this.ConsoleError("Invalid value for MySQL Port: '" + strValue + "'. Must be number between 1 and 65535!"); } } else if (Regex.Match(strVariable, @"MySQL Database").Success) { this._MySqlDatabaseName = strValue; this._DbSettingsChanged = true; this._DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Username").Success) { _MySqlUsername = strValue; this._DbSettingsChanged = true; this._DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Password").Success) { _MySqlPassword = strValue; this._DbSettingsChanged = true; this._DbCommunicationWaitHandle.Set(); } #endregion #region email settings else if (Regex.Match(strVariable, @"Send Emails").Success) { //Disabled this._UseEmail = Boolean.Parse(strValue); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("Send Emails", typeof (Boolean), this._UseEmail)); } else if (Regex.Match(strVariable, @"Use SSL?").Success) { this._EmailHandler.UseSSL = Boolean.Parse(strValue); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("Use SSL?", typeof(Boolean), this._EmailHandler.UseSSL)); } else if (Regex.Match(strVariable, @"SMTP-Server address").Success) { if (!String.IsNullOrEmpty(strValue)) { this._EmailHandler.SMTPServer = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("SMTP-Server address", typeof (String), this._EmailHandler.SMTPServer)); } } else if (Regex.Match(strVariable, @"SMTP-Server port").Success) { Int32 iPort = Int32.Parse(strValue); if (iPort > 0) { this._EmailHandler.SMTPPort = iPort; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("SMTP-Server port", typeof(Int32), this._EmailHandler.SMTPPort)); } } else if (Regex.Match(strVariable, @"Sender address").Success) { if (string.IsNullOrEmpty(strValue)) { this._EmailHandler.SenderEmail = "SENDER_CANNOT_BE_EMPTY"; this.ConsoleError("No sender for email was given! Canceling Operation."); } else { this._EmailHandler.SenderEmail = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("Sender address", typeof(String), this._EmailHandler.SenderEmail)); } } else if (Regex.Match(strVariable, @"SMTP-Server username").Success) { if (string.IsNullOrEmpty(strValue)) { this._EmailHandler.SMTPUser = "******"; this.ConsoleError("No username for SMTP was given! Canceling Operation."); } else { this._EmailHandler.SMTPUser = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("SMTP-Server username", typeof(String), this._EmailHandler.SMTPUser)); } } else if (Regex.Match(strVariable, @"SMTP-Server password").Success) { if (string.IsNullOrEmpty(strValue)) { this._EmailHandler.SMTPPassword = "******"; this.ConsoleError("No password for SMTP was given! Canceling Operation."); } else { this._EmailHandler.SMTPPassword = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("SMTP-Server password", typeof(String), this._EmailHandler.SMTPPassword)); } } else if (Regex.Match(strVariable, @"Custom HTML Addition").Success) { this._EmailHandler.CustomHTMLAddition = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable("Custom HTML Addition", typeof(String), this._EmailHandler.CustomHTMLAddition)); } else if (Regex.Match(strVariable, @"Extra Recipient Email Addresses").Success) { this._EmailHandler.RecipientEmails = CPluginVariable.DecodeStringArray(strValue).ToList(); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Extra Recipient Email Addresses", typeof (String), strValue)); } #endregion #region mute settings else if (Regex.Match(strVariable, @"On-Player-Muted Message").Success) { if (this._MutedPlayerMuteMessage != strValue) { this._MutedPlayerMuteMessage = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"On-Player-Muted Message", typeof (String), this._MutedPlayerMuteMessage)); } } else if (Regex.Match(strVariable, @"On-Player-Killed Message").Success) { if (this._MutedPlayerKillMessage != strValue) { this._MutedPlayerKillMessage = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"On-Player-Killed Message", typeof (String), this._MutedPlayerKillMessage)); } } else if (Regex.Match(strVariable, @"On-Player-Kicked Message").Success) { if (this._MutedPlayerKickMessage != strValue) { this._MutedPlayerKickMessage = strValue; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"On-Player-Kicked Message", typeof (String), this._MutedPlayerKickMessage)); } } if (Regex.Match(strVariable, @"# Chances to give player before kicking").Success) { Int32 tmp = 5; int.TryParse(strValue, out tmp); if (this._MutedPlayerChances != tmp) { this._MutedPlayerChances = tmp; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"# Chances to give player before kicking", typeof (Int32), this._MutedPlayerChances)); } } #endregion #region TeamSwap settings else if (Regex.Match(strVariable, @"Auto-Whitelist Count").Success) { Int32 tmp = 1; int.TryParse(strValue, out tmp); if (tmp != this._PlayersToAutoWhitelist) { if (tmp < 0) tmp = 0; this._PlayersToAutoWhitelist = tmp; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Auto-Whitelist Count", typeof (Int32), this._PlayersToAutoWhitelist)); } } else if (Regex.Match(strVariable, @"Ticket Window High").Success) { Int32 tmp = 2; int.TryParse(strValue, out tmp); if (tmp != this._TeamSwapTicketWindowHigh) { this._TeamSwapTicketWindowHigh = tmp; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Ticket Window High", typeof (Int32), this._TeamSwapTicketWindowHigh)); } } else if (Regex.Match(strVariable, @"Ticket Window Low").Success) { Int32 tmp = 2; int.TryParse(strValue, out tmp); if (tmp != this._TeamSwapTicketWindowLow) { this._TeamSwapTicketWindowLow = tmp; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Ticket Window Low", typeof (Int32), this._TeamSwapTicketWindowLow)); } } #endregion #region Admin Assistants else if (Regex.Match(strVariable, @"Enable Admin Assistant Perk").Success) { Boolean enableAA = Boolean.Parse(strValue); if (this._EnableAdminAssistantPerk != enableAA) { this._EnableAdminAssistantPerk = enableAA; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Enable Admin Assistant Perk", typeof (Boolean), this._EnableAdminAssistantPerk)); } } else if (Regex.Match(strVariable, @"Minimum Confirmed Reports Per Month").Success) { Int32 monthlyReports = Int32.Parse(strValue); if (this._MinimumRequiredMonthlyReports != monthlyReports) { this._MinimumRequiredMonthlyReports = monthlyReports; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Minimum Confirmed Reports Per Month", typeof (Int32), this._MinimumRequiredMonthlyReports)); } } #endregion #region Messaging Settings else if (Regex.Match(strVariable, @"Yell display time seconds").Success) { Int32 yellTime = Int32.Parse(strValue); if (this._YellDuration != yellTime) { this._YellDuration = yellTime; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Yell display time seconds", typeof (Int32), this._YellDuration)); } } else if (Regex.Match(strVariable, @"Pre-Message List").Success) { this._PreMessageList = new List<String>(CPluginVariable.DecodeStringArray(strValue)); //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Pre-Message List", typeof (String), CPluginVariable.EncodeStringArray(this._PreMessageList.ToArray()))); } else if (Regex.Match(strVariable, @"Require Use of Pre-Messages").Success) { Boolean require = Boolean.Parse(strValue); if (require != this._RequirePreMessageUse) { this._RequirePreMessageUse = require; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Require Use of Pre-Messages", typeof (Boolean), this._RequirePreMessageUse)); } } else if (Regex.Match(strVariable, @"Display Admin Name in Kick and Ban Announcement").Success) { Boolean display = Boolean.Parse(strValue); if (display != this._ShowAdminNameInSay) { this._ShowAdminNameInSay = display; //Once setting has been changed, upload the change to database this.QueueSettingForUpload(new CPluginVariable(@"Display Admin Name in Kick and Ban Announcement", typeof (Boolean), this._ShowAdminNameInSay)); } } #endregion #region access settings else if (Regex.Match(strVariable, @"Add User").Success) { if (this.SoldierNameValid(strValue)) { //Create the access objectdd AdKatsUser user = new AdKatsUser { user_name = strValue }; Boolean valid = true; lock (this._UserCache) { foreach (AdKatsUser aUser in this._UserCache.Values) { if (user.user_name == aUser.user_name) { valid = false; } } } if (!valid) { this.ConsoleError("Unable to add " + user.user_name + ", a user with that user id already exists."); return; } //Queue it for processing this.QueueUserForUpload(user); } else { this.ConsoleError("User id had invalid formatting, please try again."); } } else if (Regex.Match(strVariable, @"Add Role").Success) { if (!String.IsNullOrEmpty(strValue)) { String roleName = new Regex("[^a-zA-Z0-9 _-]").Replace(strValue, ""); String roleKey = roleName.Replace(' ', '_'); if (!String.IsNullOrEmpty(roleName) && !String.IsNullOrEmpty(roleKey)) { AdKatsRole aRole = new AdKatsRole { role_key = roleKey, role_name = roleName }; //By default we should include all commands as allowed lock (this._CommandNameDictionary) { foreach (AdKatsCommand aCommand in this._CommandNameDictionary.Values) { aRole.allowedCommands.Add(aCommand.command_key, aCommand); } } //Queue it for upload this.QueueRoleForUpload(aRole); } else { this.ConsoleError("Role id had invalid characters, please try again."); } } } #endregion } catch (Exception e) { this.HandleException(new AdKatsException("Error occured while updating AdKats settings.", e)); } }
public Boolean FetchPlayerFromName(String playerNameInput, Boolean externalFetchOverFuzzy, out AdKatsPlayer aPlayer, out Boolean confirmNeeded, out String resultMessage) { //Set default return values resultMessage = "Error finding player for " + playerNameInput; confirmNeeded = false; aPlayer = null; try { //Check for an exact match if (_PlayerDictionary.TryGetValue(playerNameInput, out aPlayer) || _PlayerLeftDictionary.TryGetValue(playerNameInput, out aPlayer)) { return true; } //Check online players for substring match List<String> currentPlayerNames = _PlayerDictionary.Keys.ToList(); //Get all subString matches var subStringMatches = new List<string>(); subStringMatches.AddRange(currentPlayerNames.Where(playerName => Regex.Match(playerName, playerNameInput, RegexOptions.IgnoreCase).Success)); if (subStringMatches.Count == 1) { //Only one subString match, call processing without confirmation if able if (_PlayerDictionary.TryGetValue(subStringMatches[0], out aPlayer)) { resultMessage = "Player match found for " + playerNameInput; return true; } ConsoleError("Error fetching player for substring match."); return false; } if (subStringMatches.Count > 1) { //Multiple players matched the query, choose correct one String msg = "'" + playerNameInput + "' matches multiple players: "; bool first = true; String suggestion = null; foreach (String playerName in subStringMatches) { if (first) { msg = msg + playerName; first = false; } else { msg = msg + ", " + playerName; } //Suggest player names that start with the text admins entered over others if (playerName.ToLower().StartsWith(playerNameInput.ToLower())) { suggestion = playerName; } } if (suggestion == null) { //If no player id starts with what admins typed, suggest subString id with lowest Levenshtein distance Int32 bestDistance = Int32.MaxValue; foreach (String playerName in subStringMatches) { Int32 distance = LevenshteinDistance(playerNameInput, playerName); if (distance < bestDistance) { bestDistance = distance; suggestion = playerName; } } } //If the suggestion is still null, something has failed if (suggestion == null) { ConsoleError("id suggestion system failed subString match"); return false; } //Use suggestion for target if (_PlayerDictionary.TryGetValue(suggestion, out aPlayer)) { resultMessage = msg; confirmNeeded = true; return true; } ConsoleError("Substring match fetch failed."); return false; } //There were no players found in the online dictionary. Run a search on the offline dictionary List<String> leftPlayerNames = _PlayerLeftDictionary.Keys.ToList(); //Get all subString matches var subStringLeftMatches = new List<string>(); subStringLeftMatches.AddRange(leftPlayerNames.Where(playerName => Regex.Match(playerName, playerNameInput, RegexOptions.IgnoreCase).Success)); if (subStringLeftMatches.Count == 1) { //Only one subString match, call processing without confirmation if able if (_PlayerLeftDictionary.TryGetValue(subStringLeftMatches[0], out aPlayer)) { resultMessage = "Player match found for " + playerNameInput; return true; } ConsoleError("Error fetching player for substring match."); return false; } if (subStringLeftMatches.Count > 1) { //Multiple players matched the query, choose correct one String msg = "'" + playerNameInput + "' matches multiple offline players: "; bool first = true; String suggestion = null; foreach (String playerName in subStringLeftMatches) { if (first) { msg = msg + playerName; first = false; } else { msg = msg + ", " + playerName; } //Suggest player names that start with the text admins entered over others if (playerName.ToLower().StartsWith(playerNameInput.ToLower())) { suggestion = playerName; } } if (suggestion == null) { //If no player id starts with what admins typed, suggest subString id with lowest Levenshtein distance Int32 bestDistance = Int32.MaxValue; foreach (String playerName in subStringLeftMatches) { Int32 distance = LevenshteinDistance(playerNameInput, playerName); if (distance < bestDistance) { bestDistance = distance; suggestion = playerName; } } } //If the suggestion is still null, something has failed if (suggestion == null) { ConsoleError("id suggestion system failed subString match"); return false; } //Use suggestion for target if (_PlayerLeftDictionary.TryGetValue(suggestion, out aPlayer)) { resultMessage = msg; confirmNeeded = true; return true; } ConsoleError("Substring match fetch failed."); return false; } if (!externalFetchOverFuzzy) { if (currentPlayerNames.Count > 0) { //Player not found in either dictionary, run a fuzzy search using Levenshtein Distance on all players in server String fuzzyMatch = null; Int32 bestFuzzyDistance = Int32.MaxValue; foreach (String playerName in currentPlayerNames) { Int32 distance = LevenshteinDistance(playerNameInput, playerName); if (distance < bestFuzzyDistance) { bestFuzzyDistance = distance; fuzzyMatch = playerName; } } //If the suggestion is still null, something has failed if (fuzzyMatch == null) { ConsoleError("id suggestion system failed fuzzy match"); return false; } if (_PlayerDictionary.TryGetValue(fuzzyMatch, out aPlayer)) { resultMessage = "Fuzzy player match found for " + playerNameInput; confirmNeeded = true; return true; } ConsoleError("Player suggestion found matching player, but it could not be fetched."); return false; } if (leftPlayerNames.Count > 0) { //No players in the online dictionary, but there are players in the offline dictionary, //run a fuzzy search using Levenshtein Distance on all players who have left String fuzzyMatch = null; Int32 bestFuzzyDistance = Int32.MaxValue; foreach (String playerName in leftPlayerNames) { Int32 distance = LevenshteinDistance(playerNameInput, playerName); if (distance < bestFuzzyDistance) { bestFuzzyDistance = distance; fuzzyMatch = playerName; } } //If the suggestion is still null, something has failed if (fuzzyMatch == null) { ConsoleError("id suggestion system failed fuzzy match"); return false; } if (_PlayerLeftDictionary.TryGetValue(fuzzyMatch, out aPlayer)) { resultMessage = "Fuzzy player match found for " + playerNameInput; confirmNeeded = true; return true; } ConsoleError("Player suggestion found matching player, but it could not be fetched."); return false; } ConsoleError("Unable to find a matching player."); return false; } aPlayer = FetchPlayer(false, true, true, null, -1, playerNameInput, null, null); if (aPlayer == null) { return false; } resultMessage = "Offline player found."; aPlayer.player_online = false; confirmNeeded = true; return true; } catch (Exception e) { HandleException(new AdKatsException("Error while fetching player from name.", e)); } return false; }
private Boolean AssignPlayerRole(AdKatsPlayer aPlayer) { AdKatsRole aRole = null; Boolean authorized = false; lock (this._UserCache) { foreach (AdKatsUser aUser in this._UserCache.Values) { foreach (Int64 playerID in aUser.soldierDictionary.Keys) { if (playerID == aPlayer.player_id) { authorized = true; aRole = this._RoleKeyDictionary[aUser.user_role.role_key]; } } } } if (aRole == null) { aRole = this._RoleKeyDictionary["guest_default"]; } if (aPlayer.player_role == null) { if (authorized) { this.DebugWrite("Player " + aPlayer.player_name + " has been assigned authorized role " + aRole.role_name + ".", 4); } else { this.DebugWrite("Player " + aPlayer.player_name + " has been assigned the guest role.", 4); } } else { if (aPlayer.player_role.role_key != aRole.role_key) { if (authorized) { this.DebugWrite("Role for authorized player " + aPlayer.player_name + " has been CHANGED to " + aRole.role_name + ".", 4); //Tell the player about the access update? this.PlayerSayMessage(aPlayer.player_name, "You have been assigned the authorized role " + aRole.role_name + "."); } else { this.DebugWrite("Player " + aPlayer.player_name + " has been assigned the guest role.", 4); //Tell the player about the access update? this.PlayerSayMessage(aPlayer.player_name, "You have been assigned the guest role."); } } } aPlayer.player_role = aRole; return authorized; }
public void SetPluginVariable(String strVariable, String strValue) { if (strValue == null) { return; } try { if (strVariable == "UpdateSettings") { //Do nothing. Settings page will be updated after return. } else if (Regex.Match(strVariable, @"Auto-Enable/Keep-Alive").Success) { Boolean autoEnable = Boolean.Parse(strValue); if (autoEnable != _useKeepAlive) { if (autoEnable) Enable(); _useKeepAlive = autoEnable; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Auto-Enable/Keep-Alive", typeof (Boolean), _useKeepAlive)); } } else if (Regex.Match(strVariable, @"Unlock Settings").Success) { if (String.IsNullOrEmpty(strValue) || strValue.Length < 5) { return; } if (strValue != _settingsPassword) { ConsoleError("Password incorrect."); return; } _settingsLocked = false; ConsoleSuccess("Settings unlocked."); QueueSettingForUpload(new CPluginVariable(@"Settings Locked", typeof (Boolean), _settingsLocked)); } else if (Regex.Match(strVariable, @"Lock Settings - Create Password").Success) { if (String.IsNullOrEmpty(strValue) || strValue.Length < 5) { ConsoleError("Password had invalid format/length, unable to submit."); return; } _settingsPassword = strValue; _settingsLocked = true; ConsoleSuccess("Password created. Settings Locked."); QueueSettingForUpload(new CPluginVariable(@"Settings Password", typeof (String), _settingsPassword)); QueueSettingForUpload(new CPluginVariable(@"Settings Locked", typeof (Boolean), _settingsLocked)); } else if (Regex.Match(strVariable, @"Lock Settings").Success) { if (String.IsNullOrEmpty(strValue) || strValue.Length < 5) { return; } if (strValue != _settingsPassword) { ConsoleError("Password incorrect."); return; } _settingsLocked = true; ConsoleSuccess("Settings locked."); QueueSettingForUpload(new CPluginVariable(@"Settings Locked", typeof (Boolean), _settingsLocked)); } else if (Regex.Match(strVariable, @"Settings Password").Success) { if (String.IsNullOrEmpty(strValue) || strValue.Length < 5) { return; } _settingsPassword = strValue; } else if (Regex.Match(strVariable, @"Settings Locked").Success) { _settingsLocked = Boolean.Parse(strValue); } else if (Regex.Match(strVariable, @"Send Query").Success) { SendQuery(strValue, true); } else if (Regex.Match(strVariable, @"Send Non-Query").Success) { SendNonQuery("Experimental Query", strValue, true); } else if (Regex.Match(strVariable, @"Hacker-Check Player").Success) { //Create new thread to run hack check var statCheckingThread = new Thread(new ThreadStart(delegate { try { Thread.CurrentThread.Name = "SpecialHackerCheck"; if (String.IsNullOrEmpty(strValue) || !_threadsReady) { return; } ConsoleWarn("Preparing to hacker check " + strValue); if (String.IsNullOrEmpty(strValue) || strValue.Length < 3) { ConsoleError("Player name must be at least 3 characters long."); return; } if (!SoldierNameValid(strValue)) { ConsoleError("Player name contained invalid characters."); return; } var aPlayer = new AdKatsPlayer { player_name = strValue }; FetchPlayerStats(aPlayer); if (aPlayer.stats != null) { RunStatSiteHackCheck(aPlayer, true); } else { ConsoleError("Stats not found for " + strValue); } } catch (Exception e) { HandleException(new AdKatsException("Error while manual stat checking player.", e)); } LogThreadExit(); })); //Start the thread StartAndLogThread(statCheckingThread); } else if (Regex.Match(strVariable, @"Setting Import").Success) { Int32 tmp = -1; if (int.TryParse(strValue, out tmp)) { if (tmp != -1) QueueSettingImport(tmp); } else { ConsoleError("Invalid Input for Setting Import"); } } else if (Regex.Match(strVariable, @"Using AdKats WebAdmin").Success) { Boolean tmp = false; if (Boolean.TryParse(strValue, out tmp)) { _UsingAwa = tmp; //Update necessary settings for AWA use if (_UsingAwa) { _UseBanEnforcer = true; _fetchActionsFromDb = true; _DbCommunicationWaitHandle.Set(); } } else { ConsoleError("Invalid Input for Using AdKats WebAdmin"); } } else if (Regex.Match(strVariable, @"Command Entry").Success) { if (String.IsNullOrEmpty(strValue)) { return; } //Check if the message is a command if (strValue.StartsWith("@") || strValue.StartsWith("!") || strValue.StartsWith(".")) { strValue = strValue.Substring(1); } else if (strValue.StartsWith("/@") || strValue.StartsWith("/!") || strValue.StartsWith("/.")) { strValue = strValue.Substring(2); } else if (strValue.StartsWith("/")) { strValue = strValue.Substring(1); } else { ConsoleError("Invalid command format."); return; } var record = new AdKatsRecord { record_source = AdKatsRecord.Sources.Settings, source_name = "SettingsAdmin" }; CompleteRecordInformation(record, strValue); } else if (Regex.Match(strVariable, @"Debug level").Success) { Int32 tmp; if (int.TryParse(strValue, out tmp)) { if (tmp == 23548) { Boolean wasAuth = _isTestingAuthorized; _isTestingAuthorized = true; if (!wasAuth) { ConsoleWrite("Server is priviledged for testing during this instance."); } } else if (tmp != _debugLevel) { _debugLevel = tmp; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Debug level", typeof (int), _debugLevel)); } } } else if (Regex.Match(strVariable, @"Debug Soldier Name").Success) { if (SoldierNameValid(strValue)) { if (strValue != _debugSoldierName) { _debugSoldierName = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Debug Soldier Name", typeof (String), _debugSoldierName)); } } } else if (Regex.Match(strVariable, @"Maximum Temp-Ban Duration Minutes").Success) { Double maxDuration = Double.Parse(strValue); if (maxDuration <= 0) { ConsoleError("Max duration cannot be negative."); return; } TimeSpan tempMaxDur = TimeSpan.FromMinutes(maxDuration); if (tempMaxDur.TotalDays > 3650) { ConsoleError("Max duration cannot be longer than 10 years."); return; } _MaxTempBanDuration = tempMaxDur; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Maximum Temp-Ban Duration Minutes", typeof(Double), _MaxTempBanDuration.TotalMinutes)); } else if (Regex.Match(strVariable, @"Server VOIP Address").Success) { if (strValue != _ServerVoipAddress) { _ServerVoipAddress = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Server VOIP Address", typeof (String), _ServerVoipAddress)); } } else if (Regex.Match(strVariable, @"Rule Print Delay").Success) { Double delay = Double.Parse(strValue); if (_ServerRulesDelay != delay) { if (delay <= 0) { ConsoleError("Delay cannot be negative."); delay = 1.0; } _ServerRulesDelay = delay; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Rule Print Delay", typeof(Double), _ServerRulesDelay)); } } else if (Regex.Match(strVariable, @"Rule Print Interval").Success) { Double interval = Double.Parse(strValue); if (_ServerRulesInterval != interval) { if (interval <= 0) { ConsoleError("Interval cannot be negative."); interval = 5.0; } _ServerRulesInterval = interval; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Rule Print Interval", typeof(Double), _ServerRulesInterval)); } } else if (Regex.Match(strVariable, @"Server Rule List").Success) { _ServerRulesList = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Server Rule List", typeof(String), CPluginVariable.EncodeStringArray(_ServerRulesList))); } else if (Regex.Match(strVariable, @"Server Rule Numbers").Success) { Boolean ruleNumbers = Boolean.Parse(strValue); if (ruleNumbers != _ServerRulesNumbers) { _ServerRulesNumbers = ruleNumbers; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Server Rule Numbers", typeof(Boolean), _ServerRulesNumbers)); } } else if (Regex.Match(strVariable, @"AFK System Enable").Success) { Boolean afkSystemEnable = Boolean.Parse(strValue); if (afkSystemEnable != _AFKSystemEnable) { _AFKSystemEnable = afkSystemEnable; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK System Enable", typeof(Boolean), _AFKSystemEnable)); } } else if (Regex.Match(strVariable, @"AFK Ignore Chat").Success) { Boolean afkIgnoreChat = Boolean.Parse(strValue); if (afkIgnoreChat != _AFKIgnoreChat) { _AFKIgnoreChat = afkIgnoreChat; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Ignore Chat", typeof(Boolean), _AFKIgnoreChat)); } } else if (Regex.Match(strVariable, @"AFK Auto-Kick Enable").Success) { Boolean afkAutoKickEnable = Boolean.Parse(strValue); if (afkAutoKickEnable != _AFKAutoKickEnable) { _AFKAutoKickEnable = afkAutoKickEnable; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Auto-Kick Enable", typeof(Boolean), _AFKAutoKickEnable)); } } else if (Regex.Match(strVariable, @"AFK Trigger Minutes").Success) { Double afkAutoKickDurationMinutes = Double.Parse(strValue); if (_AFKTriggerDurationMinutes != afkAutoKickDurationMinutes) { if (afkAutoKickDurationMinutes < 0) { ConsoleError("Duration cannot be negative."); return; } _AFKTriggerDurationMinutes = afkAutoKickDurationMinutes; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Trigger Minutes", typeof(Double), _AFKTriggerDurationMinutes)); } } else if (Regex.Match(strVariable, @"AFK Minimum Players").Success) { Int32 afkAutoKickMinimumPlayers = Int32.Parse(strValue); if (_AFKTriggerMinimumPlayers != afkAutoKickMinimumPlayers) { if (afkAutoKickMinimumPlayers < 0) { ConsoleError("Minimum players cannot be negative."); return; } _AFKTriggerMinimumPlayers = afkAutoKickMinimumPlayers; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Minimum Players", typeof(Int32), _AFKTriggerMinimumPlayers)); } } else if (Regex.Match(strVariable, @"AFK Ignore User List").Success) { Boolean afkIgnoreUserList = Boolean.Parse(strValue); if (afkIgnoreUserList != _AFKIgnoreUserList) { _AFKIgnoreUserList = afkIgnoreUserList; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Ignore User List", typeof(Boolean), _AFKIgnoreUserList)); } } else if (Regex.Match(strVariable, @"AFK Ignore Roles").Success) { _AFKIgnoreRoles = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"AFK Ignore Roles", typeof(String), CPluginVariable.EncodeStringArray(_AFKIgnoreRoles))); } else if (Regex.Match(strVariable, @"Feed MULTIBalancer Whitelist").Success) { Boolean feedMTBWhite = Boolean.Parse(strValue); if (feedMTBWhite != _FeedMultiBalancerWhitelist) { _FeedMultiBalancerWhitelist = feedMTBWhite; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Feed MULTIBalancer Whitelist", typeof (Boolean), _FeedMultiBalancerWhitelist)); } } else if (Regex.Match(strVariable, @"Automatic MULTIBalancer Whitelist for Admins").Success) { Boolean feedMTBWhiteUser = Boolean.Parse(strValue); if (feedMTBWhiteUser != _FeedMultiBalancerWhitelist_UserCache) { _FeedMultiBalancerWhitelist_UserCache = feedMTBWhiteUser; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Automatic MULTIBalancer Whitelist for Admins", typeof (Boolean), _FeedMultiBalancerWhitelist_UserCache)); } } else if (Regex.Match(strVariable, @"Feed MULTIBalancer Even Dispersion List").Success) { Boolean feedMTBBlack = Boolean.Parse(strValue); if (feedMTBBlack != _FeedMultiBalancerDisperseList) { _FeedMultiBalancerDisperseList = feedMTBBlack; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Feed MULTIBalancer Even Dispersion List", typeof (Boolean), _FeedMultiBalancerDisperseList)); } } else if (Regex.Match(strVariable, @"Feed Server Reserved Slots").Success) { Boolean feedSRS = Boolean.Parse(strValue); if (feedSRS != _FeedServerReservedSlots) { _FeedServerReservedSlots = feedSRS; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Feed Server Reserved Slots", typeof (Boolean), _FeedServerReservedSlots)); } } else if (Regex.Match(strVariable, @"Automatic Reserved Slot for User Cache").Success) { Boolean feedSRSUser = Boolean.Parse(strValue); if (feedSRSUser != _FeedServerReservedSlots_UserCache) { _FeedServerReservedSlots_UserCache = feedSRSUser; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Automatic Reserved Slot for User Cache", typeof (Boolean), _FeedServerReservedSlots_UserCache)); } } else if (Regex.Match(strVariable, @"Feed Server Spectator List").Success) { Boolean feedSSL = Boolean.Parse(strValue); if (feedSSL != _FeedServerSpectatorList) { if (_gameVersion != GameVersion.BF4) { ConsoleError("This feature can only be enabled on BF4 servers."); return; } _FeedServerSpectatorList = feedSSL; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Feed Server Spectator List", typeof (Boolean), _FeedServerSpectatorList)); } } else if (Regex.Match(strVariable, @"Automatic Spectator Slot for User Cache").Success) { Boolean feedSSLUser = Boolean.Parse(strValue); if (feedSSLUser != _FeedServerSpectatorList_UserCache) { _FeedServerSpectatorList_UserCache = feedSSLUser; FetchAllAccess(true); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Automatic Spectator Slot for User Cache", typeof (Boolean), _FeedServerSpectatorList_UserCache)); } } else if (Regex.Match(strVariable, @"Feed Stat Logger Settings").Success) { Boolean feedSLS = Boolean.Parse(strValue); if (feedSLS != _FeedStatLoggerSettings) { _FeedStatLoggerSettings = feedSLS; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Feed Stat Logger Settings", typeof (Boolean), _FeedStatLoggerSettings)); } } else if (Regex.Match(strVariable, @"Use Experimental Tools").Success) { Boolean useEXP = Boolean.Parse(strValue); if (useEXP != _useExperimentalTools) { _useExperimentalTools = useEXP; if (_useExperimentalTools) { if (_threadsReady) { ConsoleWarn("Using experimental tools. Take caution."); } } else { ConsoleWarn("Experimental tools disabled."); _UseWeaponLimiter = false; _UseGrenadeCookCatcher = false; _UseHackerChecker = false; _UseDpsChecker = false; _UseHskChecker = false; } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use Experimental Tools", typeof (Boolean), _useExperimentalTools)); QueueSettingForUpload(new CPluginVariable(@"Use NO EXPLOSIVES Limiter", typeof (Boolean), _UseWeaponLimiter)); } } else if (Regex.Match(strVariable, @"Round Timer: Enable").Success) { Boolean useTimer = Boolean.Parse(strValue); if (useTimer != _useRoundTimer) { _useRoundTimer = useTimer; if (_useRoundTimer) { if (_threadsReady) { ConsoleWarn("Internal Round Timer activated, will enable on next round."); } } else { ConsoleWarn("Internal Round Timer disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Round Timer: Enable", typeof (Boolean), _useRoundTimer)); } } else if (Regex.Match(strVariable, @"Round Timer: Round Duration Minutes").Success) { Double duration = Double.Parse(strValue); if (_maxRoundTimeMinutes != duration) { if (duration <= 0) { duration = 30.0; } _maxRoundTimeMinutes = duration; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Round Timer: Round Duration Minutes", typeof (Double), _maxRoundTimeMinutes)); } } else if (Regex.Match(strVariable, @"Use NO EXPLOSIVES Limiter").Success) { Boolean useLimiter = Boolean.Parse(strValue); if (useLimiter != _UseWeaponLimiter) { _UseWeaponLimiter = useLimiter; if (_UseWeaponLimiter) { if (_threadsReady) { ConsoleWarn("Internal NO EXPLOSIVES punish limit activated."); } } else { ConsoleWarn("Internal NO EXPLOSIVES punish limit disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use NO EXPLOSIVES Limiter", typeof (Boolean), _UseWeaponLimiter)); } } else if (Regex.Match(strVariable, @"NO EXPLOSIVES Weapon String").Success) { if (_WeaponLimiterString != strValue) { if (!String.IsNullOrEmpty(strValue)) { _WeaponLimiterString = strValue; } else { ConsoleError("Weapon String cannot be empty."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"NO EXPLOSIVES Weapon String", typeof (String), _WeaponLimiterString)); } } else if (Regex.Match(strVariable, @"NO EXPLOSIVES Exception String").Success) { if (_WeaponLimiterExceptionString != strValue) { if (!String.IsNullOrEmpty(strValue)) { _WeaponLimiterExceptionString = strValue; } else { ConsoleError("Weapon exception String cannot be empty."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"NO EXPLOSIVES Exception String", typeof (String), _WeaponLimiterExceptionString)); } } else if (Regex.Match(strVariable, @"Use Grenade Cook Catcher").Success) { Boolean useCookCatcher = Boolean.Parse(strValue); if (useCookCatcher != _UseGrenadeCookCatcher) { _UseGrenadeCookCatcher = useCookCatcher; if (_UseGrenadeCookCatcher) { if (_threadsReady) { ConsoleWarn("Internal Grenade Cook Catcher activated."); } } else { ConsoleWarn("Internal Grenade Cook Catcher disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use Grenade Cook Catcher", typeof (Boolean), _UseGrenadeCookCatcher)); } } else if (Regex.Match(strVariable, @"HackerChecker: Enable").Success) { Boolean useHackChecker = Boolean.Parse(strValue); if (useHackChecker != _UseHackerChecker) { _UseHackerChecker = useHackChecker; if (_UseHackerChecker) { if (_threadsReady) { ConsoleWarn("Internal Hacker Checker activated."); } } else { ConsoleWarn("Internal Hacker Checker disabled."); _UseDpsChecker = false; QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Enable", typeof (Boolean), _UseDpsChecker)); _UseHskChecker = false; QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Enable", typeof (Boolean), _UseHskChecker)); _UseKpmChecker = false; QueueSettingForUpload(new CPluginVariable(@"HackerChecker: KPM Checker: Enable", typeof (Boolean), _UseKpmChecker)); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: Enable", typeof (Boolean), _UseHackerChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: Whitelist").Success) { //_HackerCheckerWhitelist = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database //QueueSettingForUpload(new CPluginVariable(@"HackerChecker: Whitelist", typeof (String), CPluginVariable.EncodeStringArray(_HackerCheckerWhitelist))); } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Enable").Success) { Boolean useDamageChecker = Boolean.Parse(strValue); if (useDamageChecker != _UseDpsChecker) { _UseDpsChecker = useDamageChecker; if (_UseDpsChecker) { if (_threadsReady) { ConsoleWarn("Internal Damage Mod Checker activated."); } } else { ConsoleWarn("Internal Damage Mod Checker disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Enable", typeof (Boolean), _UseDpsChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Trigger Level").Success) { Double triggerLevel = Double.Parse(strValue); if (_DpsTriggerLevel != triggerLevel) { if (triggerLevel <= 0) { triggerLevel = 100.0; } _DpsTriggerLevel = triggerLevel; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Trigger Level", typeof (Double), _DpsTriggerLevel)); } } else if (Regex.Match(strVariable, @"HackerChecker: DPS Checker: Ban Message").Success) { if (_HackerCheckerDPSBanMessage != strValue) { _HackerCheckerDPSBanMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: DPS Checker: Ban Message", typeof (String), _HackerCheckerDPSBanMessage)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Enable").Success) { Boolean useAimbotChecker = Boolean.Parse(strValue); if (useAimbotChecker != _UseHskChecker) { _UseHskChecker = useAimbotChecker; if (_UseHskChecker) { if (_threadsReady) { ConsoleWarn("Internal Aimbot Checker activated."); } } else { ConsoleWarn("Internal Aimbot Checker disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Enable", typeof (Boolean), _UseHskChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Trigger Level").Success) { Double triggerLevel = Double.Parse(strValue); if (_HskTriggerLevel != triggerLevel) { if (triggerLevel <= 0) { triggerLevel = 100.0; } _HskTriggerLevel = triggerLevel; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Trigger Level", typeof (Double), _HskTriggerLevel)); } } else if (Regex.Match(strVariable, @"HackerChecker: HSK Checker: Ban Message").Success) { if (_HackerCheckerHSKBanMessage != strValue) { _HackerCheckerHSKBanMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: HSK Checker: Ban Message", typeof (String), _HackerCheckerHSKBanMessage)); } } else if (Regex.Match(strVariable, @"HackerChecker: KPM Checker: Enable").Success) { Boolean useKPMChecker = Boolean.Parse(strValue); if (useKPMChecker != _UseKpmChecker) { _UseKpmChecker = useKPMChecker; if (_UseKpmChecker) { if (_threadsReady) { ConsoleWarn("Internal KPM Checker activated."); } } else { ConsoleWarn("Internal KPM Checker disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: KPM Checker: Enable", typeof (Boolean), _UseKpmChecker)); } } else if (Regex.Match(strVariable, @"HackerChecker: KPM Checker: Trigger Level").Success) { Double triggerLevel = Double.Parse(strValue); if (_KpmTriggerLevel != triggerLevel) { if (triggerLevel <= 0) { triggerLevel = 100.0; } _KpmTriggerLevel = triggerLevel; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: KPM Checker: Trigger Level", typeof (Double), _KpmTriggerLevel)); } } else if (Regex.Match(strVariable, @"HackerChecker: KPM Checker: Ban Message").Success) { if (_HackerCheckerKPMBanMessage != strValue) { _HackerCheckerKPMBanMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"HackerChecker: KPM Checker: Ban Message", typeof (String), _HackerCheckerKPMBanMessage)); } } else if (Regex.Match(strVariable, @"External Access Key").Success) { if (strValue != _ExternalCommandAccessKey) { _ExternalCommandAccessKey = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"External Access Key", typeof (String), _ExternalCommandAccessKey)); } } else if (Regex.Match(strVariable, @"Fetch Actions from Database").Success) { Boolean fetch = Boolean.Parse(strValue); if (fetch != _fetchActionsFromDb) { _fetchActionsFromDb = fetch; _DbCommunicationWaitHandle.Set(); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Fetch Actions from Database", typeof (Boolean), _fetchActionsFromDb)); } } else if (Regex.Match(strVariable, @"Use Additional Ban Message").Success) { Boolean use = Boolean.Parse(strValue); if (_UseBanAppend != use) { _UseBanAppend = use; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use Additional Ban Message", typeof (Boolean), _UseBanAppend)); } } else if (Regex.Match(strVariable, @"Additional Ban Message").Success) { if (strValue.Length > 30) { strValue = strValue.Substring(0, 30); ConsoleError("Ban append cannot be more than 30 characters."); } if (_BanAppend != strValue) { _BanAppend = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Additional Ban Message", typeof (String), _BanAppend)); } } else if (Regex.Match(strVariable, @"Procon Ban Admin Name").Success) { if (strValue.Length > 16) { strValue = strValue.Substring(0, 16); ConsoleError("Procon ban admin id cannot be more than 16 characters."); } if (_CBanAdminName != strValue) { _CBanAdminName = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Procon Ban Admin Name", typeof (String), _CBanAdminName)); } } else if (Regex.Match(strVariable, @"Use Ban Enforcer").Success) { Boolean use = Boolean.Parse(strValue); if (_UseBanEnforcer != use) { _UseBanEnforcer = use; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use Ban Enforcer", typeof (Boolean), _UseBanEnforcer)); if (_UseBanEnforcer) { _fetchActionsFromDb = true; _DbCommunicationWaitHandle.Set(); } } } else if (Regex.Match(strVariable, @"Enforce New Bans by NAME").Success) { Boolean enforceName = Boolean.Parse(strValue); if (_DefaultEnforceName != enforceName) { _DefaultEnforceName = enforceName; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by NAME", typeof (Boolean), _DefaultEnforceName)); } } else if (Regex.Match(strVariable, @"Enforce New Bans by GUID").Success) { Boolean enforceGUID = Boolean.Parse(strValue); if (_DefaultEnforceGUID != enforceGUID) { _DefaultEnforceGUID = enforceGUID; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by GUID", typeof (Boolean), _DefaultEnforceGUID)); } } else if (Regex.Match(strVariable, @"Enforce New Bans by IP").Success) { Boolean enforceIP = Boolean.Parse(strValue); if (_DefaultEnforceIP != enforceIP) { _DefaultEnforceIP = enforceIP; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Enforce New Bans by IP", typeof (Boolean), _DefaultEnforceIP)); } } else if (Regex.Match(strVariable, @"Ban Search").Success) { 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(), ""); if (String.IsNullOrEmpty(strValue) || strValue.Length < 3) { ConsoleError("Search query must be 3 or more characters."); return; } lock (_BanEnforcerSearchResults) { _BanEnforcerSearchResults = FetchMatchingBans(strValue, 5); if (_BanEnforcerSearchResults.Count == 0) { ConsoleError("No players matching '" + strValue + "' have active bans."); } } } else if (Regex.Match(strVariable, @"Minimum Required Reason Length").Success) { Int32 required = Int32.Parse(strValue); if (_RequiredReasonLength != required) { _RequiredReasonLength = required; if (_RequiredReasonLength < 1) { _RequiredReasonLength = 1; } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Minimum Required Reason Length", typeof (Int32), _RequiredReasonLength)); } } else if (Regex.Match(strVariable, @"Minimum Report Handle Seconds").Success) { Int32 minimumReportHandleSeconds = Int32.Parse(strValue); if (_MinimumReportHandleSeconds != minimumReportHandleSeconds) { _MinimumReportHandleSeconds = minimumReportHandleSeconds; if (_MinimumReportHandleSeconds < 0) { _MinimumReportHandleSeconds = 0; } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Minimum Report Handle Seconds", typeof (Int32), _MinimumReportHandleSeconds)); } } else if (Regex.Match(strVariable, @"Allow Commands from Admin Say").Success) { Boolean allowSayCommands = Boolean.Parse(strValue); if (_AllowAdminSayCommands != allowSayCommands) { _AllowAdminSayCommands = allowSayCommands; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Allow Commands from Admin Say", typeof (Boolean), _AllowAdminSayCommands)); } } else if (Regex.Match(strVariable, @"External plugin player commands").Success) { _ExternalPlayerCommands = new List<String>(CPluginVariable.DecodeStringArray(strValue)); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"External plugin player commands", typeof(String), CPluginVariable.EncodeStringArray(_ExternalPlayerCommands.ToArray()))); } else if (Regex.Match(strVariable, @"External plugin admin commands").Success) { _ExternalAdminCommands = new List<String>(CPluginVariable.DecodeStringArray(strValue)); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"External plugin admin commands", typeof(String), CPluginVariable.EncodeStringArray(_ExternalAdminCommands.ToArray()))); } else if (strVariable.StartsWith("USR")) { //USR1 | ColColonCleaner | User Email //USR1 | ColColonCleaner | User Phone //USR1 | ColColonCleaner | User Role //USR1 | ColColonCleaner | Delete User? //USR1 | ColColonCleaner | Add Soldier? //USR1 | ColColonCleaner | Soldiers | 293492 | ColColonCleaner | Delete Soldier? String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String user_id_str = commandSplit[0].TrimStart("USR".ToCharArray()).Trim(); Int32 user_id = Int32.Parse(user_id_str); String section = commandSplit[2].Trim(); AdKatsUser aUser = null; if (_userCache.TryGetValue(user_id, out aUser)) { switch (section) { case "User Email": if (String.IsNullOrEmpty(strValue) || Regex.IsMatch(strValue, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")) { aUser.user_email = strValue; //Reupload the user QueueUserForUpload(aUser); } else { ConsoleError(strValue + " is an invalid email address."); return; } break; case "User Expiration": DateTime newExpiration; if (DateTime.TryParse(strValue, out newExpiration)) { aUser.user_expiration = newExpiration; //Reupload the user QueueUserForUpload(aUser); } else { ConsoleError(strValue + " is an invalid date."); } break; case "User Notes": if (String.IsNullOrEmpty(strValue)) { ConsoleError("User notes cannot be blank."); return; } aUser.user_notes = strValue; //Reupload the user QueueUserForUpload(aUser); break; case "User Phone": aUser.user_phone = strValue; //Reupload the user QueueUserForUpload(aUser); break; case "User Role": AdKatsRole aRole = null; if (_RoleNameDictionary.TryGetValue(strValue, out aRole)) { aUser.user_role = aRole; } else { ConsoleError("Role " + strValue + " not found."); return; } //Reupload the user QueueUserForUpload(aUser); break; case "Delete User?": if (strValue.ToLower() == "delete") { QueueUserForRemoval(aUser); } break; case "Add Soldier?": var addSoldierThread = new Thread(new ThreadStart(delegate { Thread.CurrentThread.Name = "addsoldier"; DebugWrite("Starting a user change thread.", 2); TryAddUserSoldier(aUser, strValue); QueueUserForUpload(aUser); DebugWrite("Exiting a user change thread.", 2); LogThreadExit(); })); StartAndLogThread(addSoldierThread); break; case "Soldiers": if (strVariable.Contains("Delete Soldier?") && strValue.ToLower() == "delete") { String player_id_str = commandSplit[3].Trim(); Int64 player_id = Int64.Parse(player_id_str); aUser.soldierDictionary.Remove(player_id); //Reupload the user QueueUserForUpload(aUser); } break; default: ConsoleError("Section " + section + " not found."); break; } } } else if (strVariable.StartsWith("CDE")) { //Trim off all but the command ID and section //5. Command List|CDE1 | Kill Player | Active //5. Command List|CDE1 | Kill Player | Logging //5. Command List|CDE1 | Kill Player | Text String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String command_id_str = commandSplit[0].TrimStart("CDE".ToCharArray()).Trim(); Int32 command_id = Int32.Parse(command_id_str); String section = commandSplit[2].Trim(); AdKatsCommand command = null; if (_CommandIDDictionary.TryGetValue(command_id, out command)) { if (section == "Active") { //Check for valid value if (strValue == "Active") { command.command_active = AdKatsCommand.CommandActive.Active; } else if (strValue == "Disabled") { command.command_active = AdKatsCommand.CommandActive.Disabled; } else if (strValue == "Invisible") { command.command_active = AdKatsCommand.CommandActive.Invisible; } else { ConsoleError("Activity setting " + strValue + " was invalid."); return; } } else if (section == "Logging") { //Check for valid value switch (strValue) { case "Log": command.command_logging = AdKatsCommand.CommandLogging.Log; break; case "Mandatory": command.command_logging = AdKatsCommand.CommandLogging.Mandatory; break; case "Ignore": command.command_logging = AdKatsCommand.CommandLogging.Ignore; break; case "Unable": command.command_logging = AdKatsCommand.CommandLogging.Unable; break; default: ConsoleError("Logging setting " + strValue + " was invalid."); return; } } else if (section == "Text") { if (String.IsNullOrEmpty(strValue)) { ConsoleError("Command text cannot be blank."); return; } //Make sure command text only contains alphanumeric chars, underscores, and dashes var rgx = new Regex("[^a-zA-Z0-9_-]"); strValue = rgx.Replace(strValue, "").ToLower(); //Check to make sure text is not a duplicate foreach (AdKatsCommand testCommand in _CommandNameDictionary.Values) { if (testCommand.command_text == strValue) { ConsoleError("Command text cannot be the same as another command."); return; } } //Assign the command text 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 (_CommandTextDictionary) { _CommandTextDictionary.Remove(command.command_text); command.command_text = strValue; _CommandTextDictionary.Add(command.command_text, command); } } else { ConsoleError("Section " + section + " not understood."); return; } //Upload the command changes QueueCommandForUpload(command); } else { ConsoleError("Command " + command_id + " not found in command dictionary."); } } else if (strVariable.StartsWith("RLE")) { //Trim off all but the role ID and section //RLE1 | Default Guest | CDE3 | Kill Player String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String roleIDStr = commandSplit[0].TrimStart("RLE".ToCharArray()).Trim(); Int32 roleID = Int32.Parse(roleIDStr); //If second section is a command prefix, this is the allow/deny clause if (commandSplit[2].Trim().StartsWith("CDE")) { String commandIDStr = commandSplit[2].Trim().TrimStart("CDE".ToCharArray()); Int32 commandID = Int32.Parse(commandIDStr); //Fetch needed role AdKatsRole aRole = null; if (_RoleIDDictionary.TryGetValue(roleID, out aRole)) { //Fetch needed command AdKatsCommand aCommand = null; if (_CommandIDDictionary.TryGetValue(commandID, out aCommand)) { switch (strValue.ToLower()) { case "allow": 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 (aRole.RoleAllowedCommands) { if (!aRole.RoleAllowedCommands.ContainsKey(aCommand.command_key)) { aRole.RoleAllowedCommands.Add(aCommand.command_key, aCommand); } } QueueRoleForUpload(aRole); break; case "deny": 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 (aRole.RoleAllowedCommands) { aRole.RoleAllowedCommands.Remove(aCommand.command_key); } QueueRoleForUpload(aRole); break; default: ConsoleError("Unknown setting when assigning command allowance."); return; } } else { ConsoleError("Command " + commandID + " not found in command dictionary."); } } else { ConsoleError("Role " + roleID + " not found in role dictionary."); } } else if (commandSplit[2].Contains("Delete Role?") && strValue.ToLower() == "delete") { //Fetch needed role AdKatsRole aRole = null; if (_RoleIDDictionary.TryGetValue(roleID, out aRole)) { QueueRoleForRemoval(aRole); } else { ConsoleError("Unable to fetch role for deletion."); } } } else if (strVariable.StartsWith("BAN")) { //Trim off all but the command ID and section //BAN1 | ColColonCleaner | Some Reason String[] commandSplit = CPluginVariable.DecodeStringArray(strVariable); String banIDStr = commandSplit[0].TrimStart("BAN".ToCharArray()).Trim(); Int32 banID = Int32.Parse(banIDStr); AdKatsBan aBan = null; foreach (AdKatsBan innerBan in _BanEnforcerSearchResults) { if (innerBan.ban_id == banID) { aBan = innerBan; break; } } if (aBan != null) { switch (strValue) { case "Active": aBan.ban_status = strValue; break; case "Disabled": aBan.ban_status = strValue; break; default: ConsoleError("Unknown setting when assigning ban status."); return; } UpdateBanStatus(aBan); ConsoleSuccess("Ban " + aBan.ban_id + " is now " + strValue); } else { ConsoleError("Unable to update ban. This should not happen."); } } else if (Regex.Match(strVariable, @"Punishment Hierarchy").Success) { _PunishmentHierarchy = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Punishment Hierarchy", typeof (String), CPluginVariable.EncodeStringArray(_PunishmentHierarchy))); } else if (Regex.Match(strVariable, @"Combine Server Punishments").Success) { Boolean combine = Boolean.Parse(strValue); if (_CombineServerPunishments != combine) { _CombineServerPunishments = combine; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Combine Server Punishments", typeof (Boolean), _CombineServerPunishments)); } } else if (Regex.Match(strVariable, @"Only Kill Players when Server in low population").Success) { Boolean onlyKill = Boolean.Parse(strValue); if (onlyKill != _OnlyKillOnLowPop) { _OnlyKillOnLowPop = onlyKill; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Only Kill Players when Server in low population", typeof (Boolean), _OnlyKillOnLowPop)); } } else if (Regex.Match(strVariable, @"Low Population Value").Success) { Int32 lowPop = Int32.Parse(strValue); if (lowPop != _lowPopulationPlayerCount) { _lowPopulationPlayerCount = lowPop; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Low Population Value", typeof (Int32), _lowPopulationPlayerCount)); } } else if (Regex.Match(strVariable, @"Use IRO Punishment").Success) { Boolean iro = Boolean.Parse(strValue); if (iro != _IROActive) { _IROActive = iro; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use IRO Punishment", typeof (Boolean), _IROActive)); } } else if (Regex.Match(strVariable, @"IRO Punishment Overrides Low Pop").Success) { Boolean overrideIRO = Boolean.Parse(strValue); if (overrideIRO != _IROOverridesLowPop) { _IROOverridesLowPop = overrideIRO; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"IRO Punishment Overrides Low Pop", typeof (Boolean), _IROOverridesLowPop)); } } else if (Regex.Match(strVariable, @"IRO Timeout Minutes").Success) { Int32 timeout = Int32.Parse(strValue); if (timeout != _IROTimeout) { _IROTimeout = timeout; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"IRO Timeout Minutes", typeof(Int32), _IROTimeout)); } } else if (Regex.Match(strVariable, @"MySQL Hostname").Success) { _mySqlHostname = strValue; _dbSettingsChanged = true; _DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Port").Success) { Int32 tmp = 3306; int.TryParse(strValue, out tmp); if (tmp > 0 && tmp < 65536) { _mySqlPort = strValue; _dbSettingsChanged = true; _DbCommunicationWaitHandle.Set(); } else { ConsoleError("Invalid value for MySQL Port: '" + strValue + "'. Must be number between 1 and 65535!"); } } else if (Regex.Match(strVariable, @"MySQL Database").Success) { _mySqlDatabaseName = strValue; _dbSettingsChanged = true; _DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Username").Success) { _mySqlUsername = strValue; _dbSettingsChanged = true; _DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"MySQL Password").Success) { _mySqlPassword = strValue; _dbSettingsChanged = true; _DbCommunicationWaitHandle.Set(); } else if (Regex.Match(strVariable, @"Send Emails").Success) { //Disabled _UseEmail = Boolean.Parse(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("Send Emails", typeof (Boolean), _UseEmail)); } else if (Regex.Match(strVariable, @"Use SSL?").Success) { _EmailHandler.UseSSL = Boolean.Parse(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("Use SSL?", typeof (Boolean), _EmailHandler.UseSSL)); } else if (Regex.Match(strVariable, @"SMTP-Server address").Success) { if (!String.IsNullOrEmpty(strValue)) { _EmailHandler.SMTPServer = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("SMTP-Server address", typeof (String), _EmailHandler.SMTPServer)); } } else if (Regex.Match(strVariable, @"SMTP-Server port").Success) { Int32 iPort = Int32.Parse(strValue); if (iPort > 0) { _EmailHandler.SMTPPort = iPort; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("SMTP-Server port", typeof (Int32), _EmailHandler.SMTPPort)); } } else if (Regex.Match(strVariable, @"Sender address").Success) { if (string.IsNullOrEmpty(strValue)) { _EmailHandler.SenderEmail = "SENDER_CANNOT_BE_EMPTY"; ConsoleError("No sender for email was given! Canceling Operation."); } else { _EmailHandler.SenderEmail = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("Sender address", typeof (String), _EmailHandler.SenderEmail)); } } else if (Regex.Match(strVariable, @"SMTP-Server username").Success) { if (string.IsNullOrEmpty(strValue)) { _EmailHandler.SMTPUser = "******"; ConsoleError("No username for SMTP was given! Canceling Operation."); } else { _EmailHandler.SMTPUser = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("SMTP-Server username", typeof (String), _EmailHandler.SMTPUser)); } } else if (Regex.Match(strVariable, @"SMTP-Server password").Success) { if (string.IsNullOrEmpty(strValue)) { _EmailHandler.SMTPPassword = "******"; ConsoleError("No password for SMTP was given! Canceling Operation."); } else { _EmailHandler.SMTPPassword = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("SMTP-Server password", typeof (String), _EmailHandler.SMTPPassword)); } } else if (Regex.Match(strVariable, @"Custom HTML Addition").Success) { _EmailHandler.CustomHTMLAddition = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("Custom HTML Addition", typeof (String), _EmailHandler.CustomHTMLAddition)); } else if (Regex.Match(strVariable, @"Extra Recipient Email Addresses").Success) { _EmailHandler.RecipientEmails = CPluginVariable.DecodeStringArray(strValue).ToList(); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Extra Recipient Email Addresses", typeof (String), strValue)); } else if (Regex.Match(strVariable, @"Use Metabans?").Success) { _useMetabans = Boolean.Parse(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable("Use Metabans?", typeof (Boolean), _useMetabans)); } else if (Regex.Match(strVariable, @"Metabans API Key").Success) { if (string.IsNullOrEmpty(strValue)) { _metabansAPIKey = ""; ConsoleError("No API key for Metabans was given! Canceling Operation."); } else { _metabansAPIKey = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Metabans API Key", typeof (String), _metabansAPIKey)); } } else if (Regex.Match(strVariable, @"Metabans Username").Success) { if (string.IsNullOrEmpty(strValue)) { _metabansUsername = ""; ConsoleError("No username for Metabans was given! Canceling Operation."); } else { _metabansUsername = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Metabans Username", typeof (String), _metabansUsername)); } } else if (Regex.Match(strVariable, @"On-Player-Muted Message").Success) { if (_MutedPlayerMuteMessage != strValue) { _MutedPlayerMuteMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"On-Player-Muted Message", typeof (String), _MutedPlayerMuteMessage)); } } else if (Regex.Match(strVariable, @"On-Player-Killed Message").Success) { if (_MutedPlayerKillMessage != strValue) { _MutedPlayerKillMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"On-Player-Killed Message", typeof (String), _MutedPlayerKillMessage)); } } else if (Regex.Match(strVariable, @"On-Player-Kicked Message").Success) { if (_MutedPlayerKickMessage != strValue) { _MutedPlayerKickMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"On-Player-Kicked Message", typeof (String), _MutedPlayerKickMessage)); } } if (Regex.Match(strVariable, @"# Chances to give player before kicking").Success) { Int32 tmp = 5; int.TryParse(strValue, out tmp); if (_MutedPlayerChances != tmp) { _MutedPlayerChances = tmp; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"# Chances to give player before kicking", typeof (Int32), _MutedPlayerChances)); } } else if (Regex.Match(strVariable, @"Ignore commands for mute enforcement").Success) { Boolean ignoreCommands = Boolean.Parse(strValue); if (_MutedPlayerIgnoreCommands != ignoreCommands) { _MutedPlayerIgnoreCommands = ignoreCommands; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Ignore commands for mute enforcement", typeof(Boolean), _MutedPlayerIgnoreCommands)); } } else if (Regex.Match(strVariable, @"Ticket Window High").Success) { Int32 tmp = 2; int.TryParse(strValue, out tmp); if (tmp != _TeamSwapTicketWindowHigh) { _TeamSwapTicketWindowHigh = tmp; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Ticket Window High", typeof (Int32), _TeamSwapTicketWindowHigh)); } } else if (Regex.Match(strVariable, @"Ticket Window Low").Success) { Int32 tmp = 2; int.TryParse(strValue, out tmp); if (tmp != _TeamSwapTicketWindowLow) { _TeamSwapTicketWindowLow = tmp; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Ticket Window Low", typeof (Int32), _TeamSwapTicketWindowLow)); } } else if (Regex.Match(strVariable, @"Enable Admin Assistants").Success) { Boolean enableAA = Boolean.Parse(strValue); if (_EnableAdminAssistants != enableAA) { _EnableAdminAssistants = enableAA; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Enable Admin Assistants", typeof (Boolean), _EnableAdminAssistants)); } } else if (Regex.Match(strVariable, @"Enable Admin Assistant Perk").Success) { Boolean enableAA = Boolean.Parse(strValue); if (_EnableAdminAssistantPerk != enableAA) { _EnableAdminAssistantPerk = enableAA; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Enable Admin Assistant Perk", typeof (Boolean), _EnableAdminAssistantPerk)); } } else if (Regex.Match(strVariable, @"Use AA Report Auto Handler").Success) { Boolean useAAHandler = Boolean.Parse(strValue); if (useAAHandler != _UseAAReportAutoHandler) { _UseAAReportAutoHandler = useAAHandler; if (_UseAAReportAutoHandler) { if (_threadsReady) { ConsoleWarn("Internal Automatic Report Handler activated."); } } else { ConsoleWarn("Internal Automatic Report Handler disabled."); } //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use AA Report Auto Handler", typeof (Boolean), _UseAAReportAutoHandler)); } } else if (Regex.Match(strVariable, @"Auto-Report-Handler Strings").Success) { _AutoReportHandleStrings = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Auto-Report-Handler Strings", typeof (String), CPluginVariable.EncodeStringArray(_AutoReportHandleStrings))); } else if (Regex.Match(strVariable, @"Minimum Confirmed Reports Per Month").Success) { Int32 monthlyReports = Int32.Parse(strValue); if (_MinimumRequiredMonthlyReports != monthlyReports) { _MinimumRequiredMonthlyReports = monthlyReports; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Minimum Confirmed Reports Per Month", typeof (Int32), _MinimumRequiredMonthlyReports)); } } else if (Regex.Match(strVariable, @"Yell display time seconds").Success) { Int32 yellTime = Int32.Parse(strValue); if (_YellDuration != yellTime) { _YellDuration = yellTime; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Yell display time seconds", typeof (Int32), _YellDuration)); } } else if (Regex.Match(strVariable, @"Pre-Message List").Success) { _PreMessageList = new List<String>(CPluginVariable.DecodeStringArray(strValue)); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Pre-Message List", typeof (String), CPluginVariable.EncodeStringArray(_PreMessageList.ToArray()))); } else if (Regex.Match(strVariable, @"Require Use of Pre-Messages").Success) { Boolean require = Boolean.Parse(strValue); if (require != _RequirePreMessageUse) { _RequirePreMessageUse = require; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Require Use of Pre-Messages", typeof (Boolean), _RequirePreMessageUse)); } } else if (Regex.Match(strVariable, @"Use first spawn message").Success) { Boolean useFirstSpawnMessage = Boolean.Parse(strValue); if (useFirstSpawnMessage != _UseFirstSpawnMessage) { _UseFirstSpawnMessage = useFirstSpawnMessage; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Use first spawn message", typeof(Boolean), _UseFirstSpawnMessage)); } } else if (Regex.Match(strVariable, @"First spawn message text").Success) { if (_FirstSpawnMessage != strValue) { _FirstSpawnMessage = strValue; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"First spawn message text", typeof(String), _FirstSpawnMessage)); } } else if (Regex.Match(strVariable, @"Display Admin Name in Kick and Ban Announcement").Success) { Boolean display = Boolean.Parse(strValue); if (display != _ShowAdminNameInSay) { _ShowAdminNameInSay = display; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Display Admin Name in Kick and Ban Announcement", typeof (Boolean), _ShowAdminNameInSay)); } } else if (Regex.Match(strVariable, @"Inform players of reports against them").Success) { Boolean inform = Boolean.Parse(strValue); if (inform != _InformReportedPlayers) { _InformReportedPlayers = inform; //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Inform players of reports against them", typeof (Boolean), _InformReportedPlayers)); } } else if (Regex.Match(strVariable, @"Player Inform Exclusion Strings").Success) { _PlayerInformExclusionStrings = CPluginVariable.DecodeStringArray(strValue); //Once setting has been changed, upload the change to database QueueSettingForUpload(new CPluginVariable(@"Player Inform Exclusion Strings", typeof (String), CPluginVariable.EncodeStringArray(_PlayerInformExclusionStrings))); } else if (Regex.Match(strVariable, @"Add User").Success) { if (SoldierNameValid(strValue)) { var aUser = new AdKatsUser { user_name = strValue, user_expiration = DateTime.UtcNow.AddYears(20), user_notes = "No Notes" }; Boolean valid = true; 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 (_userCache) { valid = _userCache.Values.All(iUser => aUser.user_name != iUser.user_name); } if (!valid) { ConsoleError("Unable to add " + aUser.user_name + ", a user with that name already exists."); return; } var addUserThread = new Thread(new ThreadStart(delegate { Thread.CurrentThread.Name = "userchange"; DebugWrite("Starting a user change thread.", 2); //Attempt to add soldiers matching the user's name TryAddUserSoldier(aUser, aUser.user_name); QueueUserForUpload(aUser); DebugWrite("Exiting a user change thread.", 2); LogThreadExit(); })); StartAndLogThread(addUserThread); } else { ConsoleError("User id had invalid formatting, please try again."); } } else if (Regex.Match(strVariable, @"Add Role").Success) { if (!String.IsNullOrEmpty(strValue)) { String roleName = new Regex("[^a-zA-Z0-9 _-]").Replace(strValue, ""); String roleKey = roleName.Replace(' ', '_'); if (!String.IsNullOrEmpty(roleName) && !String.IsNullOrEmpty(roleKey)) { var aRole = new AdKatsRole { role_key = roleKey, role_name = roleName }; //By default we should include all commands as allowed 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 (_CommandNameDictionary) { foreach (AdKatsCommand aCommand in _CommandNameDictionary.Values) { aRole.RoleAllowedCommands.Add(aCommand.command_key, aCommand); } } //Queue it for upload QueueRoleForUpload(aRole); } else { ConsoleError("Role had invalid characters, please try again."); } } } if (FullDebug) { ConsoleWrite("updating settings page"); } } catch (Exception e) { HandleException(new AdKatsException("Error occured while updating AdKats settings.", e)); } }
//DONE private AdKatsPlayer FetchPlayer(Boolean allowUpdate, Boolean allowOtherGames, Int64 playerID, String playerName, String playerGUID, String playerIP) { DebugWrite("fetchPlayer starting!", 6); //Create return list AdKatsPlayer aPlayer = null; //Make sure database connection active if (this.HandlePossibleDisconnect()) { //If AdKats is disconnected from the database, return the player as-is aPlayer = new AdKatsPlayer { player_name = playerName, player_guid = playerGUID, player_ip = playerIP }; return aPlayer; } if (playerID < 0 && String.IsNullOrEmpty(playerName) && String.IsNullOrEmpty(playerGUID) && String.IsNullOrEmpty(playerIP)) { this.ConsoleError("Attempted to fetch player with no information."); } else { try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { String sql = @" SELECT `PlayerID` as `player_id`, `SoldierName` as `player_name`, `EAGUID` as `player_guid`, `PBGUID` as `player_pbguid`, `IP_Address` as `player_ip`"; if (this._GameID > 0) { sql += ",`GameID` as `game_id` "; } sql += "FROM `" + this._MySqlDatabaseName + @"`.`tbl_playerdata` "; bool sqlEnder = true; if (playerID >= 0) { sql += " WHERE ( "; sqlEnder = false; sql += " `PlayerID` = " + playerID + " "; } if (!String.IsNullOrEmpty(playerGUID)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `EAGUID` LIKE '" + playerGUID + "' "; } if (String.IsNullOrEmpty(playerGUID) && !String.IsNullOrEmpty(playerName)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `SoldierName` LIKE '" + playerName + "' "; } if (String.IsNullOrEmpty(playerGUID) && !String.IsNullOrEmpty(playerIP)) { if (sqlEnder) { sql += " WHERE ( "; sqlEnder = false; } else { sql += " OR "; } sql += " `IP_Address` LIKE '" + playerIP + "' "; } if (!sqlEnder) { sql += " ) "; } if (this._GameID > 0 && !allowOtherGames) { sql += " AND `GameID` = " + this._GameID + " "; } command.CommandText = sql; using (MySqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { aPlayer = new AdKatsPlayer(); //Player ID will never be null aPlayer.player_id = reader.GetInt64("player_id"); if (this._GameID > 0) { aPlayer.game_id = reader.GetInt32("game_id"); } if (!reader.IsDBNull(1)) aPlayer.player_name = reader.GetString("player_name"); if (!reader.IsDBNull(2)) aPlayer.player_guid = reader.GetString("player_guid"); if (!reader.IsDBNull(3)) aPlayer.player_pbguid = reader.GetString("player_pbguid"); if (!reader.IsDBNull(4)) aPlayer.player_ip = reader.GetString("player_ip"); } else { this.DebugWrite("No player matching search information.", 5); } } } if (allowUpdate) { if (aPlayer == null) { this.DebugWrite("Adding player to database.", 5); using (MySqlCommand command = connection.CreateCommand()) { //Set the insert command structure Boolean hasPrevious = (this._GameID > 0) || !String.IsNullOrEmpty(playerName) || !String.IsNullOrEmpty(playerGUID) || !String.IsNullOrEmpty(playerIP); command.CommandText = @" INSERT INTO `" + this._MySqlDatabaseName + @"`.`tbl_playerdata` ( " + ((this._GameID > 0) ? ("`GameID`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerName)) ? (((this._GameID > 0) ? (",") : ("")) + "`SoldierName`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? ((hasPrevious ? (",") : ("")) + "`EAGUID`") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? ((hasPrevious ? (",") : ("")) + "`IP_Address`") : ("")) + @" ) VALUES ( " + ((this._GameID > 0) ? (this._GameID + "") : ("")) + @" " + ((!String.IsNullOrEmpty(playerName)) ? (((this._GameID > 0) ? (",") : ("")) + "'" + playerName + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? ((hasPrevious ? (",") : ("")) + "'" + playerGUID + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? ((hasPrevious ? (",") : ("")) + "'" + playerIP + "'") : ("")) + @" ) ON DUPLICATE KEY UPDATE `PlayerID` = LAST_INSERT_ID(`PlayerID`) " + ((!String.IsNullOrEmpty(playerName)) ? (@",`SoldierName` = '" + playerName + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerGUID)) ? (@",`EAGUID` = '" + playerGUID + "'") : ("")) + @" " + ((!String.IsNullOrEmpty(playerIP)) ? (@",`IP_Address` = '" + playerIP + "'") : ("")); //Attempt to execute the query if (command.ExecuteNonQuery() > 0) { //Rows affected should be > 0 aPlayer = new AdKatsPlayer { player_id = command.LastInsertedId, player_name = playerName, player_guid = playerGUID, player_ip = playerIP }; } else { this.ConsoleError("Unable to add player to database."); return null; } } } if (!String.IsNullOrEmpty(playerName) && !String.IsNullOrEmpty(aPlayer.player_guid) && playerName != aPlayer.player_name) { this.DebugWrite(aPlayer.player_name + " changed their id to " + playerName + ". Updating the database.", 2); using (MySqlCommand command = connection.CreateCommand()) { //Set the insert command structure command.CommandText = @"UPDATE `" + this._MySqlDatabaseName + @"`.`tbl_playerdata` SET `SoldierName` = '" + playerName + "' WHERE `EAGUID` = '" + aPlayer.player_guid + "'"; //Attempt to execute the query if (command.ExecuteNonQuery() <= 0) { this.ConsoleError("Could not update " + aPlayer.player_name + "'s id-change to " + playerName + " in the database."); } //Update the player id in the player object aPlayer.player_name = playerName; } } } if (aPlayer == null) { return null; } //Load admin assistat status aPlayer.player_aa = this.IsAdminAssistant(aPlayer); if (aPlayer.player_aa) { this.DebugWrite(aPlayer.player_name + " IS an Admin Assistant.", 3); } else { this.DebugWrite(aPlayer.player_name + " is NOT an Admin Assistant.", 4); } //Assign player role this.AssignPlayerRole(aPlayer); } } catch (Exception e) { this.HandleException(new AdKatsException("Error while fetching player.", e)); } } DebugWrite("fetchPlayer finished!", 6); return aPlayer; }
//DONE private Boolean IsAdminAssistant(AdKatsPlayer player) { DebugWrite("fetchAdminAssistants starting!", 6); //Make sure database connection active if (this.HandlePossibleDisconnect()) { return false; } try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { command.CommandText = @" SELECT 'isAdminAssistant' FROM `adkats_records_main` WHERE ( SELECT count(`command_action`) FROM `adkats_records_main` WHERE `command_action` = " + this.GetCommandByKey("player_report_confirm").command_id + @" AND `source_id` = " + player.player_id + @" AND (`adkats_records_main`.`record_time` BETWEEN date_sub(UTC_TIMESTAMP(),INTERVAL 30 DAY) AND UTC_TIMESTAMP()) ) >= " + this._MinimumRequiredMonthlyReports + " LIMIT 1"; using (MySqlDataReader reader = command.ExecuteReader()) { return reader.Read(); } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while checking if player is an admin assistant.", e)); } DebugWrite("fetchAdminAssistants finished!", 6); return false; }
//DONE private Int32 FetchPoints(AdKatsPlayer player) { DebugWrite("fetchPoints starting!", 6); Int32 returnVal = -1; //Make sure database connection active if (this.HandlePossibleDisconnect()) { return returnVal; } try { using (MySqlConnection connection = this.GetDatabaseConnection()) { using (MySqlCommand command = connection.CreateCommand()) { if (this._CombineServerPunishments) { command.CommandText = @"SELECT `total_points` FROM `" + this._MySqlDatabaseName + @"`.`adkats_infractions_global` WHERE `player_id` = @player_id"; command.Parameters.AddWithValue("@player_id", player.player_id); } else { command.CommandText = @"SELECT `total_points` FROM `" + this._MySqlDatabaseName + @"`.`adkats_infractions_server` WHERE `player_id` = @player_id and `server_id` = @server_id"; command.Parameters.AddWithValue("@player_id", player.player_id); command.Parameters.AddWithValue("@server_id", this._ServerID); } using (MySqlDataReader reader = command.ExecuteReader()) { returnVal = reader.Read() ? reader.GetInt32("total_points") : 0; } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while getting infraction points for player.", e)); } DebugWrite("fetchPoints finished!", 6); return returnVal; }
private void QueuePlayerForHackerCheck(AdKatsPlayer player) { this.DebugWrite("Entering queuePlayerForHackerCheck", 7); try { if (this._IsEnabled) { this.DebugWrite("Preparing to queue player for hacker check", 6); lock (this._HackerCheckerMutex) { this._HackerCheckerQueue.Enqueue(player); this.DebugWrite("Player queued for checking", 6); this._HackerCheckerWaitHandle.Set(); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while queueing player for hacker check.", e)); } this.DebugWrite("Exiting queuePlayerForHackerCheck", 7); }
private Boolean HasAccess(AdKatsPlayer aPlayer, AdKatsCommand command) { try { if (aPlayer == null) { this.ConsoleError("player was null in hasAccess."); return false; } if (aPlayer.player_role == null) { this.ConsoleError("player role was null in hasAccess."); return false; } if (command == null) { this.ConsoleError("Command was null in hasAccess."); return false; } lock (aPlayer.player_role) { lock (aPlayer.player_role.allowedCommands) { foreach (AdKatsCommand innerCommand in aPlayer.player_role.allowedCommands.Values) { if (innerCommand.command_active != AdKatsCommand.CommandActive.Disabled && command.command_id == innerCommand.command_id) return true; } } } return false; } catch (Exception e) { this.HandleException(new AdKatsException("Error while checking command access on player.", e)); return false; } }
private Boolean HasAccess(AdKatsPlayer aPlayer, AdKatsCommand command) { try { if (aPlayer == null) { ConsoleError("player was null in hasAccess."); return false; } if (aPlayer.player_role == null) { ConsoleError("player role was null in hasAccess."); return false; } if (command == null) { ConsoleError("Command was null in hasAccess."); return false; } 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 (aPlayer.player_role) { 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 (aPlayer.player_role.RoleAllowedCommands) { if (aPlayer.player_role.RoleAllowedCommands.ContainsKey(command.command_key)) { return true; } if (aPlayer.player_role.ConditionalAllowedCommands.Values.Any(innerCommand => (innerCommand.Value.command_key == command.command_key) && innerCommand.Key(this, aPlayer))) { return true; } } } } catch (Exception e) { HandleException(new AdKatsException("Error while checking command access on player.", e)); } return false; }