/* public override void OnSquadListPlayers(int teamId, int squadId, int playerCount, List<string> playersInSquad) { if (!fIsEnabled) return; DebugWrite("Got ^bOnSquadListPlayers^n: " + teamId + "/" + squadId + " has " + playerCount, 7); try { if (playersInSquad == null || playersInSquad.Count == 0) return; // Logging if (DebugLevel >= 6) { String ss = "Squad ("; int t = Math.Max(0, Math.Min(teamId, TEAM_NAMES.Length-1)); int s = Math.Max(0, Math.Min(squadId, SQUAD_NAMES.Length-1)); ss = ss + TEAM_NAMES[t] + "/" + SQUAD_NAMES[s] + "): "; bool first = true; foreach (String grunt in playersInSquad) { if (first) { ss = ss + grunt; first = false; } else { ss = ss + ", " + grunt; } } ConsoleWrite("^9" + ss); } } catch (Exception e) { ConsoleException(e); } } */ public override void OnPlayerKilled(Kill kKillerVictimDetails) { if (!fIsEnabled) return; String killer = kKillerVictimDetails.Killer.SoldierName; String victim = kKillerVictimDetails.Victim.SoldierName; String weapon = kKillerVictimDetails.DamageType; bool isAdminKill = false; if (String.IsNullOrEmpty(killer)) { killer = victim; isAdminKill = (weapon == "Death"); } DebugWrite("^9^bGot OnPlayerKilled^n: " + killer + " -> " + victim + " (" + weapon + ")", 8); if (isAdminKill) DebugWrite("^9OnPlayerKilled: admin kill: ^b" + victim + "^n (" + weapon + ")", 7); try { if (fGameState == GameState.Unknown || fGameState == GameState.Warmup) { bool wasUnknown = (fGameState == GameState.Unknown); fGameState = (this.TotalPlayerCount < 4) ? GameState.Warmup : GameState.Playing; if (wasUnknown || fGameState == GameState.Playing) DebugWrite("OnPlayerKilled: ^b^3Game state = " + fGameState, 6); fNeedPlayerListUpdate = (fGameState == GameState.Playing); } if (!isAdminKill) { KillUpdate(killer, victim); if (fPluginState == PluginState.Active && fGameState == GameState.Playing) { if (!IsModelInSync()) { if (fTimeOutOfJoint == 0) { // If a move or reassign takes too long, abort it, checked in OnListPlayers fTimeOutOfJoint = GetTimeInRoundMinutes(); } } else { fTimeOutOfJoint = 0; BalanceAndUnstack(victim); } } } } catch (Exception e) { ConsoleException(e); } }
public override void OnPlayerKilled(Kill kKillerVictimDetails) { base.OnPlayerKilled(kKillerVictimDetails); foreach (Message m in messages.FindAll((m) => m.enabled)) try { m.OnPlayerKilled(kKillerVictimDetails); } catch (Exception exc) { ConsoleError("Exception with OnPlayerKilled of '" + m.name + "': " + exc.Message + " " + exc.StackTrace); } }
//******************************************************************************************** // this procedure gets called when each KILL occurs in the game //******************************************************************************************** public override void OnPlayerKilled(Kill k) { // EVENT EXCEPTION BLOCK: try { if (k == null) { WriteDebugInfo("*******************OnPlayerKilled*****************NULL KILL OBJECT"); return; } if (k.Killer == null) { WriteDebugInfo("*******************OnPlayerKilled***************NULL KILLER OBJECT"); return; } CPlayerInfo Killer = k.Killer; CPlayerInfo Victim = k.Victim; string player_name = Killer.SoldierName; string victim_name = Victim.SoldierName; // cache the player info in case we want the GUID if (player_name != null && player_name != "") player_info[player_name] = Killer; if (victim_name != null && victim_name != "") player_info[victim_name] = Victim; WriteDebugInfo("*******************OnPlayerKilled*************************"+player_name); if (Victim == null) { WriteDebugInfo(String.Format("NULL VICTIM on this kill by {0}", player_name)); return; } WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled [{0}] [{1}]", player_name, victim_name)); string weapon_key = k.DamageType; if (weapon_key == "" || weapon_key == null) weapon_key = "No weapon key"; WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled [{0}] weapon_key [{1}]", player_name, weapon_key)); Weapon weapon_used; try { if (weapon_key == null) weapon_used = null; else weapon_used = weaponDefines[weapon_key]; } catch { weapon_used = null; } string weapon_descr = weapon_desc(weapon_key); WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled [{0}] weapon_descr [{1}]", player_name, weapon_descr)); string weapon_kit; try { if (weapon_used == null) weapon_kit = "No weapon kit"; else weapon_kit = item_key(weapon_used.KitRestriction); } catch { weapon_kit = "No weapon kit"; } WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled [{0}] kit [{1}]", player_name, weapon_kit)); string damage; try { damage = item_key(weapon_used.Damage); } catch { damage = "No damage key"; } WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled [{0}] damage [{1}]", player_name, damage)); add_kill_count(player_name, weapon_key); add_kill_count(player_name, damage); add_kill_count(player_name, weapon_kit); // debug string killer_counts = ""; if (kill_counts.ContainsKey(player_name)) foreach (string item_name in kill_counts[player_name].Keys) { List<string> item_list = new List<string>(); item_list.Add(item_name); killer_counts += item_name + "(" + count_kill_items(player_name, item_list).ToString() + ") "; } else killer_counts = "0 kill counts"; WriteDebugInfo( String.Format("^bProconRulz: [{0} {1} [{2}]] killed [{3}] with [{4}], damage {5}, range {6}", weapon_kit, player_name, killer_counts, victim_name, weapon_descr, damage, (Int32)k.Distance)); //end debug // clear the dead soldier out of the 'counts' if it's first come first served // this will open up an opportunity for someone else to spawn with this players items if (reservationMode == ReserveItemEnum.Player_loses_item_when_dead) { spawn_counts.zero_player(Victim.SoldierName); } TriggerEnum kill_type = TriggerEnum.Kill; string blocked_item = ""; if (k.IsSuicide || player_name == null || player_name == "") // BF3 reports no killer with SoldierCollision { kill_type = TriggerEnum.Suicide; // - this is just for testing the suicide data WriteDebugInfo("Suicide info: " + "k.IsSuicide=" + (k.IsSuicide ? "true" : "false") + ", player_name=" + (player_name == null ? "null" : "\"" + player_name + "\"") + ", victim_name=" + (victim_name == null ? "null" : "\"" + victim_name + "\"") + ", weapon_key=" + weapon_key ); if (player_name == null || player_name == "") player_name = victim_name; } else if (test_block(player_name, weapon_key)) { kill_type = TriggerEnum.PlayerBlock; blocked_item = weapon_descr; WriteDebugInfo(String.Format("ProconRulz: PlayerBlock [{0}] with weapon [{1}]", player_name, blocked_item)); } else if (test_block(player_name, weapon_kit)) { kill_type = TriggerEnum.PlayerBlock; blocked_item = weapon_kit; WriteDebugInfo(String.Format("ProconRulz: PlayerBlock [{0}] with kit [{1}]", player_name, blocked_item)); } else if (test_block(player_name, damage)) { kill_type = TriggerEnum.PlayerBlock; blocked_item = damage; WriteDebugInfo(String.Format("ProconRulz: PlayerBlock [{0}] with damage [{1}]", player_name, blocked_item)); } else if (Killer.TeamID == Victim.TeamID) kill_type = TriggerEnum.TeamKill; WriteDebugInfo(String.Format("ProconRulz: OnPlayerKilled for [{0}] is Event {1}", player_name, Enum.GetName(typeof(TriggerEnum), kill_type))); // now we do the main work of scanning the rules for this KILL scan_rules(kill_type, player_name, new Dictionary<SubstEnum, string>(), null, k, blocked_item); } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in OnPlayerKilled"); PrintException(ex); } }
//Move delayed players when they are killed public override void OnPlayerKilled(Kill kKillerVictimDetails) { //Used for delayed player moving if (isEnabled && this.teamswapOnDeathMoveDic.Count > 0) { lock (this.teamswapMutex) { this.teamswapOnDeathCheckingQueue.Enqueue(kKillerVictimDetails.Victim); this.teamswapHandle.Set(); } } //Update player death information if (this.playerDictionary.ContainsKey(kKillerVictimDetails.Victim.SoldierName)) { lock (this.playersMutex) { //Only add the last death if it's not a death by admin if (!String.IsNullOrEmpty(kKillerVictimDetails.Killer.SoldierName)) { this.playerDictionary[kKillerVictimDetails.Victim.SoldierName].lastDeath = DateTime.Now; } } } //ADK Metro No EXPLOSIVES special enforcement if (this.useNoExplosivesLimit) { //Check if restricted weapon if (Regex.Match(kKillerVictimDetails.DamageType, @"(?:M320|RPG|SMAW|C4|M67|Claymore|MAV|FGM-148|FIM92|ROADKILL)", RegexOptions.IgnoreCase).Success) { //Check if suicide if (kKillerVictimDetails.Killer.SoldierName != kKillerVictimDetails.Victim.SoldierName) { //Get player from the dictionary AdKat_Player killer = null; if (this.playerDictionary.TryGetValue(kKillerVictimDetails.Killer.SoldierName, out killer)) { //Create the punish record AdKat_Record record = new AdKat_Record(); record.server_id = this.server_id; record.command_type = AdKat_CommandType.PunishPlayer; record.command_numeric = 0; record.target_name = killer.player_name; record.target_player = killer; record.source_name = "AutoAdmin"; String removeWeapon = "Weapons/"; String removeGadgets = "Gadgets/"; String weapon = kKillerVictimDetails.DamageType; int index = weapon.IndexOf(removeWeapon); weapon = (index < 0) ? (weapon):(weapon.Remove(index, removeWeapon.Length)); index = weapon.IndexOf(removeGadgets); weapon = (index < 0) ? (weapon):(weapon.Remove(index, removeGadgets.Length)); record.record_message = "Using Explosives [" + weapon + "]"; this.adminSay("Punishing " + killer.player_name + " for " + record.record_message); //Process the record this.queueRecordForProcessing(record); } } } } }
private bool process_parts(ParsedRule rule, List<PartClass> parts, string player_name, ref Dictionary<SubstEnum, string> keywords, Kill k, string item) { PartClass current_part = null; try { bool playercount_updated = false; // we only update PlayerCount etc ONCE either after a successful // PlayerCount, or before the use of %c% etc // check each of the PARTS. // for each part in the rule, call process_part() foreach (PartClass p in parts) { current_part = p; // so we can display the part that caused exception if needed // see if we should update PlayerCount etc here // rule can by NULL if parts is a list of TargetActions if (rule != null && !playercount_updated && p.has_count) { update_counts(player_name, rule.id, ref keywords); playercount_updated = true; } // HERE IS WHERE WE LEAVE THE PROC AND RETURN FALSE IF A CONDITION FAILS if (!process_part(rule, p, player_name, k, item, ref keywords)) return false; WriteDebugInfo(String.Format("ProconRulz: process_parts [{0}] OK", player_name)); } return true; } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in process_parts (ProconRulz will continue)"); WriteConsole("ProconRulz: Rule was: " + rule.unparsed_rule); if (current_part != null) { WriteConsole("ProconRulz: Rule part was: " + current_part.ToString()); } else { WriteConsole("ProconRulz: Rule part was null"); } PrintException(ex); return false; } }
//********************************************************************************************** //********************************************************************************************** // CHECK THE RULES to see if we should kill, kick, say //********************************************************************************************** //********************************************************************************************** // here is where we scan the rules after a player has joined, spawned or a kill has occurred private void scan_rules(TriggerEnum trigger, string name, Dictionary<SubstEnum, string> keywords, Inventory inv, Kill k, string item) { WriteDebugInfo(String.Format("ProconRulz: Scan_rules[{0}] with Event {1}", name, Enum.GetName(typeof(TriggerEnum), trigger))); // don't do anything if rulz_enable has been set to false if (!rulz_enable) return; // CATCH EXCEPTIONS try { // initial population of the 'keywords' dictionary assign_initial_keywords(name, ref keywords); // loop through the rules foreach (ParsedRule rule in parsed_rules) { // skip comments if (rule.comment) continue; if (rule.trigger == trigger) { WriteDebugInfo(String.Format("ProconRulz: scan_rules[{0}] [{1}]", name, rule.unparsed_rule)); if (process_rule(trigger, rule, name, ref keywords, inv, k, item)) { WriteDebugInfo(String.Format("ProconRulz: scan_rules[{0}] [{1}] FIRED", name, rule.unparsed_rule)); break; // break if any rule fires } } // else WriteDebugInfo(String.Format("ProconRulz: scan_rules[{0}] skipped", name)); } // end looping through the rules } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in scan_rules"); PrintException(ex); } }
public void OnPlayerKilled(Kill killInfo) { if (killInfo == null) return; if(this.OnCommandMove.ContainsKey(killInfo.Victim.SoldierName)) { if (this.OnCommandMove[killInfo.Victim.SoldierName] == false) { //normal move if (this.OnCommandMoveDone.Contains(killInfo.Victim.SoldierName)) { this.OnCommandMoveDone.Remove(killInfo.Victim.SoldierName); this.OnCommandMove.Remove(killInfo.Victim.SoldierName); this.DebugInfoGuard("^3^bMoving player to the other team went wrong on his last death. Not trying again! - ^8" + killInfo.Victim.SoldierName); } else { this.DebugInfoGuard("^2Trying to move dead player to the other side, due to TB-MoveCommand: ^b" + killInfo.Victim.SoldierName); int team = 0; if (this.dicPlayerCache[killInfo.Victim.SoldierName].teamID == 1) team = 2; else team = 1; this.OnCommandMoveDone.Add(killInfo.Victim.SoldierName); if (this.boolVirtual) { this.ExecuteCommand("procon.protected.pluginconsole.write", "^b[TB] VIRTUAL^n admin.movePlayer " + killInfo.Victim.SoldierName + " " + team.ToString() + " 0 false"); } else { this.ExecuteCommand("procon.protected.send", "admin.movePlayer", killInfo.Victim.SoldierName, team.ToString(), "0", "false"); } } } else if(this.OnCommandMove[killInfo.Victim.SoldierName] == true) { //force move this.TSForceMove = DateTime.Now - this.DTForceMove; if (this.TSForceMove.TotalMilliseconds > 10000) { this.DebugInfoGuard("^3^bForce Moving player to the other team went wrong! - ^8" + killInfo.Victim.SoldierName); this.OnCommandMove.Remove(killInfo.Victim.SoldierName); } } } else if (this.boolwaitfordeath) { CPlayerInfo victim = killInfo.Victim; if (dicPlayerCache[victim.SoldierName].teamID == intFromTeam) { this.DebugInfo("Player ^b^0" + victim.SoldierName + "^n^9 died."); if (dicPlayerCache[victim.SoldierName].playerWL == 0 && !dicPlayerCache[victim.SoldierName].IsCommander && !dicPlayerCache[victim.SoldierName].IsSpectator) { if(this.boolwaitdead == false){ this.DebugInfo("^4Player ^b" + victim.SoldierName + "^n needs to be balanced."); this.strdeadplayer = victim.SoldierName; //this.dicPlayerCache[victim.SoldierName].tobebalanced = true; //CompareTeams(); this.ExecuteCommand("procon.protected.send", "admin.listPlayers", "all"); } } else { this.DebugInfo("^1Player ^b" + victim.SoldierName + "^n is VIP, Commander, Spectator or has been allready moved once."); } } } }
private void assign_keywords(TriggerEnum trigger, ParsedRule rulex, string player_name, ref Dictionary<SubstEnum, string> keywords, Inventory inv, Kill k, string item) { // HERE's WHERE WE UPDATE THE SUBST KEYWORDS (and conditions can as well, // e.g. TargetPlayer) // this would be more efficient if I only updated the keywords that are // actually used in the rulz // update player count etc for this rule (for use of %c% parameter // or subsequent Count condition) if (trigger == TriggerEnum.Spawn) { keywords[SubstEnum.Kit] = kit_desc(item_key(inv.Kit)); keywords[SubstEnum.KitKey] = item_key(inv.Kit); // keywords[Weaponkey, Weapon, Damage, SpecKey, Spec] all set in OnPlaeyrSpawned } else if (trigger == TriggerEnum.Kill || trigger == TriggerEnum.TeamKill || trigger == TriggerEnum.Suicide || trigger == TriggerEnum.PlayerBlock ) { try { // we're in a 'kill' type event here // as far as I can tell, 'k.DamageType' usually contains // weapon key, but sometimes can be null // with BF3, k.Killer.SoldierName can be empty (null or ""?) if (k == null) return; string victim_name = (k.Victim == null) ? "No victim" : k.Victim.SoldierName; keywords[SubstEnum.Victim] = victim_name; string weapon_key = k.DamageType; Weapon weapon_used; try { if (weapon_key == null) weapon_used = null; else weapon_used = weaponDefines[weapon_key]; } catch { weapon_used = null; } string weapon_descr = weapon_desc(weapon_key); string damage; try { damage = (weapon_used == null) ? "No damage key" : item_key(weapon_used.Damage); } catch { damage = "No damage key"; } keywords[SubstEnum.Weapon] = weapon_descr; keywords[SubstEnum.WeaponKey] = weapon_key; keywords[SubstEnum.KitKey] = spawned_kit(player_name); keywords[SubstEnum.Kit] = kit_desc(spawned_kit(player_name)); keywords[SubstEnum.VictimKit] = kit_desc(spawned_kit(victim_name)); keywords[SubstEnum.VictimTeamKey] = players.team_id(victim_name); keywords[SubstEnum.VictimTeam] = team_name(players.team_id(victim_name)); keywords[SubstEnum.VictimCountry] = players.cname(victim_name); keywords[SubstEnum.VictimCountryKey] = players.ckey(victim_name); keywords[SubstEnum.Damage] = damage; keywords[SubstEnum.Range] = k.Distance.ToString("0.0"); keywords[SubstEnum.Headshot] = k.Headshot ? "Headshot" : ""; } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in assign_keywords #2"); PrintException(ex); return; } } if (trigger == TriggerEnum.PlayerBlock) { keywords.Add(SubstEnum.BlockedItem, item); WriteDebugInfo(String.Format("ProconRulz: test_rule[{0}] is PlayerBlock event for [{1}] OK", player_name, item)); } }
public override void OnPlayerKilled(Kill info) { if (ZombieModeEnabled == false) return; if (GetState() != GState.Idle) { PlayerState.UpdateSpawnTime(info.Killer.SoldierName); PlayerState.UpdateSpawnTime(info.Victim.SoldierName); PlayerState.SetSpawned(info.Victim.SoldierName, false); // Since we can't log vars values in plugin.log, at least log to console.log if (DebugLevel > 5) ExecuteCommand("procon.protected.send", "vars.bulletDamage"); } if (GetState() != GState.Playing) return; // Extract the short weapon name Match WeaponMatch = Regex.Match(info.DamageType, @"Weapons/[^/]*/([^/]*)", RegexOptions.IgnoreCase); String WeaponName = (WeaponMatch.Success) ? WeaponMatch.Groups[1].Value : info.DamageType; if (fGameVersion == GameVersion.BF4) { WeaponName = FriendlyWeaponName(WeaponName); } const String INDIRECT_KILL = "INDIRECT KILL"; String KillerName = (String.IsNullOrEmpty(info.Killer.SoldierName)) ? INDIRECT_KILL : info.Killer.SoldierName; String KillerTeam = info.Killer.TeamID.ToString(); String VictimName = info.Victim.SoldierName; String VictimTeam = info.Victim.TeamID.ToString(); String DamageType = info.DamageType; String InfectMessage = null; int RemainingHumans = 0; // Killed by admin? if (info.DamageType == "Death") return; DebugWrite("OnPlayerKilled: " + KillerName + " killed " + VictimName + " with " + WeaponName, 4); lock (TeamHuman) { RemainingHumans = TeamHuman.Count - 1; } if (RemainingHumans > 0) { InfectMessage = "*** Only " + RemainingHumans + " humans left!"; // $$$ - custom message } else { InfectMessage = "*** No humans left!"; // $$$ - custom message } RemainingHumans = TeamHuman.Count; String Notice = WeaponName + " results in non-scoring accidental death, respawn and try again"; // $$$ - custom message // Weapon validation if (KillerName == INDIRECT_KILL) { TellPlayer(VictimName + ": " + Notice, VictimName, false); return; } else if (Regex.Match(DamageType, @"(?:DamageArea|RoadKill|SoldierCollision)").Success) { DebugWrite("OnPlayerKilled: " + DamageType + " is a non-scoring kill of both parties", 3); TellPlayer(Notice, KillerName, false); if (KillerName != VictimName) TellPlayer(Notice, VictimName, false); KillPlayerAfterDelay(KillerName, 5); return; } else if (KillerName != VictimName && ValidateWeapon(DamageType, KillerTeam) == false) { String msg = "ZOMBIE RULE VIOLATION! " + WeaponName + " can't be used by " + ((KillerTeam == ZOMBIE_TEAM) ? "Zombie!" : "Human!"); // $$$ - custom message DebugWrite(msg + " " + KillerName + " killed " + VictimName, 2); TellAll(KillerName + " -> " + msg); int Count = KillTracker.GetViolations(KillerName); if (Count < WarnsBeforeKickForRulesViolations) { // Warning KillPlayerAfterDelay(KillerName, 5); } else if (TempBanInsteadOfKick) { DebugWrite("OnPlayerKilled: ^b^8TEMP BAN " + KillerName, 1); String unit = "seconds"; double dur = TempBanSeconds; if (TempBanSeconds > 60 && TempBanSeconds < (90*60)) { unit = "minutes"; dur = dur / 60.0; } else if (TempBanSeconds < (24*60*60)) { unit = "hours"; dur = dur / (60.0 * 60.0); } else if (TempBanSeconds >= (24*60*60)) { unit = "days"; dur = dur / (24.0 * 60.0 * 60.0); } TellAll("::::: Banning " + KillerName + " for " + dur.ToString("F0") + " " + unit + "! :::::"); // $$$ - custom message TempBanPlayer(KillerName, "ZOMBIE RULE VIOLATION: bad weapon"); // $$$ - custom message } else { DebugWrite("OnPlayerKilled: ^b^8KICK " + KillerName, 2); KickPlayer(KillerName, msg); } KillTracker.SetViolations(KillerName, Count+1); return; } // Scoring logic if (KillerName == VictimName) { if (KillerTeam == HUMAN_TEAM && InfectSuicides) { DebugWrite("Suicide infected: " + VictimName, 3); Infect("Suicide", VictimName); TellAll(InfectMessage, false); // do not overwrite Infect yell --RemainingHumans; } else { TellPlayer(VictimName + ": Suicide with " + Notice, VictimName, false); return; } } else if (KillerTeam == HUMAN_TEAM && VictimTeam == ZOMBIE_TEAM) { KillTracker.ZombieKilled(KillerName, VictimName); DebugWrite(String.Concat("Human ", KillerName, " just killed zombie ", VictimName, " with ", WeaponName), 3); int TotalCount = 0; lock(TeamHuman) { TotalCount = TeamHuman.Count + TeamZombie.Count; } TellAll("*** Humans killed " + KillTracker.GetZombiesKilled() + " of " + GetKillsNeeded(TotalCount) + " zombies needed to win!"); // $$$ - custom message // Check for self-infecting kill if (Regex.Match(info.DamageType, @"(?:Knife|Melee|Defib|Repair)", RegexOptions.IgnoreCase).Success) { // Infect player Infect("Contact Kill", KillerName); // overwrite infect yell TellPlayer("You infected yourself with that " + WeaponName + " kill!", KillerName); // $$$ - custom message } } else if (KillerTeam == ZOMBIE_TEAM && VictimTeam == HUMAN_TEAM) { DebugWrite(String.Concat("Zombie ", KillerName, " just killed human ", VictimName, " with ", WeaponName), 3); if (Regex.Match(WeaponName, @"(?:Knife|Melee|Defib|Repair)", RegexOptions.IgnoreCase).Success) { KillTracker.HumanKilled(KillerName, VictimName); if (KillTracker.GetPlayerHumanDeathCount(VictimName) == DeathsNeededToBeInfected) { Infect(KillerName, VictimName); TellAll(InfectMessage, false); // do not overwrite Infect yell --RemainingHumans; } } else { Notice = "Zombie " + KillerName + " using " + WeaponName + " did NOT infect human " + VictimName; DebugWrite(Notice, 3); TellPlayer(Notice, KillerName); TellPlayer(Notice, VictimName, false); } } lock (TeamHuman) { DebugWrite("OnPlayerKilled: " + RemainingHumans + " humans vs " + ((RemainingHumans == TeamHuman.Count) ? TeamZombie.Count : (TeamZombie.Count+1)) + " zombies with " + KillTracker.GetZombiesKilled() + " of " + GetKillsNeeded(TeamZombie.Count + TeamHuman.Count) + " zombies killed", (VictimTeam == HUMAN_TEAM) ? 2 : 3); } CheckVictoryConditions(RemainingHumans == 0); }
public override void OnPlayerKilled(Kill kKillerVictimDetails) { }
// // IPRoConPluginInterface2 // public void OnPlayerKilled(Kill kKillerVictimDetails) { }
public override void OnPlayerKilled(Kill info) { }
private void QueueKillForProcessing(Kill kKillerVictimDetails) { DebugWrite("Entering queueKillForProcessing", 7); try { if (_pluginEnabled) { DebugWrite("Preparing to queue kill for processing", 6); if (_isTestingAuthorized) PushThreadDebug(DateTime.Now.Ticks, (String.IsNullOrEmpty(Thread.CurrentThread.Name) ? ("mainthread") : (Thread.CurrentThread.Name)), Thread.CurrentThread.ManagedThreadId, new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(), ""); lock (_KillProcessingQueue) { _KillProcessingQueue.Enqueue(kKillerVictimDetails); DebugWrite("Kill queued for processing", 6); _KillProcessingWaitHandle.Set(); } } } catch (Exception e) { HandleException(new AdKatsException("Error while queueing kill for processing.", e)); } DebugWrite("Exiting queueKillForProcessing", 7); }
public virtual void OnPlayerKilled(Kill kill) { }
public void OnPlayerKilled(Kill kKillerVictimDetails) { int opk_iKillPayoff = 0; int opk_iCurrencyLost = 0; Weapon weaponUsed = this.GetWeaponDefines()[kKillerVictimDetails.DamageType]; string weaponUsedName = this.GetLocalized(weaponUsed.Name, String.Format("global.Weapons.{0}", kKillerVictimDetails.DamageType.ToLower())); CPlayerInfo Killer = kKillerVictimDetails.Killer; CPlayerInfo Victim = kKillerVictimDetails.Victim; if (m_ebynPayForKills == enumBoolYesNo.Yes) { opk_iKillPayoff += m_iAmountPaidPerKill; } if (m_ebynDeductForDeaths == enumBoolYesNo.Yes) { opk_iCurrencyLost += m_iAmountLostPerDeath; } if (m_ebynPayForHeadshots == enumBoolYesNo.Yes) { if (kKillerVictimDetails.Headshot) { opk_iKillPayoff += m_iAmountPaidPerHeadshot; } } if (m_ebynPayForSpecificWeaponKills == enumBoolYesNo.Yes) { string[] weaponAndValue = new string[2]; foreach (string weapAndPayValue in this.m_lstWeaponAndPayValue) { weaponAndValue = Regex.Split(weapAndPayValue, "="); if (weaponAndValue[0].Contains(weaponUsedName)) { opk_iKillPayoff += int.Parse(weaponAndValue[1]); break; } } } //***************************************** //Enable Mugging //***************************************** if (m_ebynEnableMugging == enumBoolYesNo.Yes) //modified to account for TK { if ((m_ebynEnableTKStop == enumBoolYesNo.Yes) && (Killer.TeamID == Victim.TeamID) && (Killer.SoldierName != Victim.SoldierName)) //To allow TK remove this if from around one below. { } else { if (m_lstMuggingWeapons.Contains(weaponUsedName)) { int opk_iMuggingPayoff = MuggingHandler(Killer.SoldierName, Victim.SoldierName); opk_iKillPayoff += opk_iMuggingPayoff; opk_iCurrencyLost += opk_iMuggingPayoff; } } } //***************************************** //Auto Bounties //***************************************** if (m_ebynEnableAutoBounties == enumBoolYesNo.Yes && Killer.SoldierName != Victim.SoldierName) { if ((m_ebynEnableTKStop == enumBoolYesNo.Yes) && (Killer.TeamID == Victim.TeamID) && (Killer.SoldierName != Victim.SoldierName)) //To allow TK remove this if from around one below. { } else { AutoBountyHandler(Killer.SoldierName, Victim.SoldierName); } } //***************************************** //Player Bounties //***************************************** if (m_ebynEnablePlayerBounties == enumBoolYesNo.Yes && Killer.SoldierName != Victim.SoldierName) { if ((m_ebynEnableTKStop == enumBoolYesNo.Yes) && (Killer.TeamID == Victim.TeamID) && (Killer.SoldierName != Victim.SoldierName)) //To allow TK remove this if from around one below. { } else { PlayerBountyHandler("kill", Killer.SoldierName, Victim.SoldierName, 0); } } //***************************************** //Bounty Payoff //***************************************** if (m_dicPlayersAndBounties.ContainsKey(Victim.SoldierName) && m_dicPlayersAndBounties[Victim.SoldierName] > 0 && Killer.SoldierName != Victim.SoldierName) { if ((m_ebynEnableTKStop == enumBoolYesNo.Yes) && (Killer.TeamID == Victim.TeamID) && (Killer.SoldierName != Victim.SoldierName)) //To allow TK remove this if from around one below. { } else { opk_iKillPayoff += m_dicPlayersAndBounties[Victim.SoldierName]; m_dicPlayersAndBounties.Remove(Victim.SoldierName); } } if (m_dicPlayerStreaks.ContainsKey(Victim.SoldierName)) { m_dicPlayerStreaks.Remove(Victim.SoldierName); } if (opk_iKillPayoff > 0) { m_dicPlayersAndBalances[Killer.SoldierName] += opk_iKillPayoff; } if (opk_iCurrencyLost > 0 && m_dicPlayersAndBalances[Victim.SoldierName] >= opk_iCurrencyLost) { m_dicPlayersAndBalances[Victim.SoldierName] -= opk_iCurrencyLost; } }
public override void OnPlayerKilled(Kill killInfo) { if (killInfo == null) return; CPlayerInfo killer = killInfo.Killer; CPlayerInfo victim = killInfo.Victim; PlayerProfile vp = getPlayerProfile(victim.SoldierName); PlayerProfile kp = getPlayerProfile(killer.SoldierName); if (vp != null) { vp.state = PlayerState.dead; vp.updateInfo(victim); vp.updateLastDeath(); if (vp.getDelayedTeamId() > 0) { DebugWrite("Player " + vp + " has died, he was flagged to be moved to ^bDTeam(" + TN(vp.getDelayedTeamId()) + ").DSquad(" + SQN(vp.getDelayedSquadId()) + ")^n", 3); /* do not skip the balance check, this is delayed move, teams may already be balanced */ enforceDelayedMove(vp); } } if (kp != null) { kp.updateInfo(killer); kp.updateLastKill(); } }
private void ProcessPlayerKill(Kill kKillerVictimDetails) { try { //Used for delayed player moving if (this._TeamswapOnDeathMoveDic.Count > 0) { lock (this._TeamswapMutex) { this._TeamswapOnDeathCheckingQueue.Enqueue(kKillerVictimDetails.Victim); this._TeamswapWaitHandle.Set(); } } //TEMP BF4 weapon code things this.UploadWeaponCode(kKillerVictimDetails.DamageType); Boolean gKillHandled = false; //Update player death information if (this._PlayerDictionary.ContainsKey(kKillerVictimDetails.Victim.SoldierName)) { lock (this._PlayersMutex) { AdKatsPlayer victim = this._PlayerDictionary[kKillerVictimDetails.Victim.SoldierName]; this.DebugWrite("Setting " + victim.player_name + " time of death to " + kKillerVictimDetails.TimeOfDeath, 7); victim.lastDeath = kKillerVictimDetails.TimeOfDeath; //Only add the last death if it's not a death by admin if (!String.IsNullOrEmpty(kKillerVictimDetails.Killer.SoldierName)) { try { //ADK grenade cooking catcher if (this._UseExperimentalTools && this._UseGrenadeCookCatcher) { if (this._RoundCookers == null) { this._RoundCookers = new Dictionary<String, AdKatsPlayer>(); } Double fuseTime = 0; if (this._GameVersion == GameVersion.BF3) { fuseTime = 3735.00; } else if (this._GameVersion == GameVersion.BF4) { fuseTime = 3132.00; } //2865 MINI const double possibleRange = 750.00; //Update killer information AdKatsPlayer killer = null; if (this._PlayerDictionary.TryGetValue(kKillerVictimDetails.Killer.SoldierName, out killer)) { //Initialize / clean up the recent kills queue if (killer.recentKills == null) { killer.recentKills = new Queue<KeyValuePair<AdKatsPlayer, DateTime>>(); } //Only keep the last 6 kills in memory while (killer.recentKills.Count > 1) { killer.recentKills.Dequeue(); } //Add the player killer.recentKills.Enqueue(new KeyValuePair<AdKatsPlayer, DateTime>(victim, kKillerVictimDetails.TimeOfDeath)); //Check for cooked grenade and non-suicide if (kKillerVictimDetails.DamageType.Contains("M67")) { if (kKillerVictimDetails.Killer.SoldierName != kKillerVictimDetails.Victim.SoldierName) { Boolean told = false; List<KeyValuePair<AdKatsPlayer, String>> possible = new List<KeyValuePair<AdKatsPlayer, String>>(); List<KeyValuePair<AdKatsPlayer, String>> sure = new List<KeyValuePair<AdKatsPlayer, String>>(); foreach (KeyValuePair<AdKatsPlayer, DateTime> cooker in killer.recentKills) { //Get the actual time since cooker value Double milli = kKillerVictimDetails.TimeOfDeath.Subtract(cooker.Value).TotalMilliseconds; //Calculate the percentage probability Double probability = 0.00; if (Math.Abs(milli - fuseTime) < possibleRange) { probability = (1 - Math.Abs((milli - fuseTime) / possibleRange)) * 100; this.DebugWrite(cooker.Key.player_name + " cooking probability: " + probability + "%", 2); } else { probability = 0.00; } //If probability > 60% report the player and add them to the round cookers list if (probability > 60.00) { this.DebugWrite(cooker.Key.player_name + " in " + killer.player_name + " recent kills has a " + probability + "% cooking probability.", 2); gKillHandled = true; //Code to avoid spam if (cooker.Key.lastAction.AddSeconds(2) < DateTime.UtcNow) { cooker.Key.lastAction = DateTime.UtcNow; } else { this.DebugWrite("Skipping additional auto-actions for multi-kill event.", 2); continue; } if (!told) { //Inform the victim player that they will not be punished this.PlayerSayMessage(kKillerVictimDetails.Killer.SoldierName, "You appear to be a victim of grenade cooking and will NOT be punished."); told = true; } //Create the probability String String probString = ((int) probability) + "-" + ((int) milli); //If the player is already on the round cooker list, ban them if (this._RoundCookers.ContainsKey(cooker.Key.player_name)) { //Create the ban record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_punish"], command_numeric = 0, target_name = cooker.Key.player_name, target_player = cooker.Key, source_name = "AutoAdmin", record_message = "Rules: Cooking Grenades [" + probString + "-X] [Victim " + killer.player_name + " Protected]" }; //Process the record this.QueueRecordForProcessing(record); //this.adminSay("Punishing " + killer.player_name + " for " + record.record_message); this.DebugWrite(record.target_player.player_name + " punished for " + record.record_message, 2); return; } //else if probability > 92.5% add them to the SURE list, and round cooker list if (probability > 92.5) { this._RoundCookers.Add(cooker.Key.player_name, cooker.Key); this.DebugWrite(cooker.Key.player_name + " added to round cooker list.", 2); //Add to SURE sure.Add(new KeyValuePair<AdKatsPlayer, String>(cooker.Key, probString)); } //Otherwise add them to the round cooker list, and add to POSSIBLE list else { this._RoundCookers.Add(cooker.Key.player_name, cooker.Key); this.DebugWrite(cooker.Key.player_name + " added to round cooker list.", 2); //Add to POSSIBLE possible.Add(new KeyValuePair<AdKatsPlayer, String>(cooker.Key, probString)); } } } //This method used for dealing with multiple kills at the same instant i.e twin/triple headshots if (sure.Count == 1 && possible.Count == 0) { AdKatsPlayer player = sure[0].Key; String probString = sure[0].Value; //Create the ban record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_punish"], command_numeric = 0, target_name = player.player_name, target_player = player, source_name = "AutoAdmin", record_message = "Rules: Cooking Grenades [" + probString + "] [Victim " + killer.player_name + " Protected]" }; //Process the record this.QueueRecordForProcessing(record); //this.adminSay("Punishing " + killer.player_name + " for " + record.record_message); this.DebugWrite(record.target_player.player_name + " punished for " + record.record_message, 2); } else { AdKatsPlayer player = null; String probString = null; foreach (KeyValuePair<AdKatsPlayer, String> playerPair in sure) { player = playerPair.Key; probString = playerPair.Value; //Create the report record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_report"], command_numeric = 0, target_name = player.player_name, target_player = player, source_name = "AutoAdmin", record_message = "Possible Grenade Cooker [" + probString + "] [Victim " + killer.player_name + " Protected]" }; //Process the record this.QueueRecordForProcessing(record); this.DebugWrite(record.target_player.player_name + " reported for " + record.record_message, 2); } foreach (KeyValuePair<AdKatsPlayer, String> playerPair in possible) { player = playerPair.Key; probString = playerPair.Value; //Create the report record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_report"], command_numeric = 0, target_name = player.player_name, target_player = player, source_name = "AutoAdmin", record_message = "Possible Grenade Cooker [" + probString + "] [Victim " + killer.player_name + " Protected]" }; //Process the record this.QueueRecordForProcessing(record); this.DebugWrite(record.target_player.player_name + " reported for " + record.record_message, 2); } } } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error in grenade cook catcher.", e)); } } } } try { if (this._UseExperimentalTools && this._UseWeaponLimiter && !gKillHandled) { //Check for restricted weapon if (Regex.Match(kKillerVictimDetails.DamageType, @"(?:" + this._WeaponLimiterString + ")", RegexOptions.IgnoreCase).Success) { //Check for exception type if (!Regex.Match(kKillerVictimDetails.DamageType, @"(?:" + this._WeaponLimiterExceptionString + ")", RegexOptions.IgnoreCase).Success) { //Check if suicide if (kKillerVictimDetails.Killer.SoldierName != kKillerVictimDetails.Victim.SoldierName) { //Get player from the dictionary AdKatsPlayer killer = null; if (this._PlayerDictionary.TryGetValue(kKillerVictimDetails.Killer.SoldierName, out killer)) { //Code to avoid spam if (killer.lastAction.AddSeconds(2) < DateTime.UtcNow) { killer.lastAction = DateTime.UtcNow; //Create the punish record AdKatsRecord record = new AdKatsRecord { record_source = AdKatsRecord.Sources.InternalAutomated, server_id = this._ServerID, command_type = this._CommandKeyDictionary["player_punish"], command_numeric = 0, target_name = killer.player_name, target_player = killer, source_name = "AutoAdmin" }; const string removeWeapon = "Weapons/"; const string removeGadgets = "Gadgets/"; const string removePrefix = "U_"; String weapon = kKillerVictimDetails.DamageType; Int32 index = weapon.IndexOf(removeWeapon, System.StringComparison.Ordinal); weapon = (index < 0) ? (weapon) : (weapon.Remove(index, removeWeapon.Length)); index = weapon.IndexOf(removeGadgets, System.StringComparison.Ordinal); weapon = (index < 0) ? (weapon) : (weapon.Remove(index, removeGadgets.Length)); index = weapon.IndexOf(removePrefix, System.StringComparison.Ordinal); weapon = (index < 0) ? (weapon) : (weapon.Remove(index, removePrefix.Length)); if (weapon == "RoadKill") { record.record_message = "Rules: Roadkilling with EOD or MAV"; } else if (weapon == "Death") { record.record_message = "Rules: Using Mortar"; } else { record.record_message = "Rules: Using Explosives [" + weapon + "]"; } //Process the record this.QueueRecordForProcessing(record); } else { this.DebugWrite("Skipping additional auto-actions for multi-kill event.", 2); } } } } } } } catch (Exception e) { this.HandleException(new AdKatsException("Error in no explosives auto-admin.", e)); } } catch (Exception e) { this.HandleException(new AdKatsException("Error while processing player kill.", e)); } this.DebugWrite("Exiting OnPlayerKilled", 7); }
// check a condition (e.g. "Kit Recon 2") in the current rule // rule.trigger is already confirmed to be the current event (e.g. Kill, Spawn) private bool process_part(ParsedRule rule, PartClass p, string player_name, Kill k, string msg, ref Dictionary<SubstEnum, string> keywords) { // CATCH EXCEPTIONS try { string not = p.negated ? "Not " : ""; bool return_val = false; string player_team_id = "-1"; if (keywords.ContainsKey(SubstEnum.PlayerTeamKey)) { player_team_id = keywords[SubstEnum.PlayerTeamKey]; } switch (p.part_type) { case PartEnum.Headshot: // test "Headshot" return_val = p.negated ? !k.Headshot : k.Headshot; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Headshot {2}", player_name, not, return_val)); return return_val; case PartEnum.Protected: // test player os on reserved slots list return_val = p.negated ? !protected_player(player_name) : protected_player(player_name); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Protected {2}", player_name, not, return_val)); return return_val; case PartEnum.Admin: // test player is an admin return_val = p.negated ? !is_admin(player_name) : is_admin(player_name); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Admin {2}", player_name, not, return_val)); return return_val; case PartEnum.Admins: // test if any admins are currently online return_val = p.negated ? !admins_present() : admins_present(); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Admins {2}", player_name, not, return_val)); return return_val; case PartEnum.Team: // test "team attack|defend" bool team_matches = team_match(p.string_list, player_team_id); return_val = p.negated ? !team_matches : team_matches; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Actual team {2} versus {3} {4}", player_name, not, team_key(player_team_id), keys_join(p.string_list), return_val)); return return_val; case PartEnum.Ping: // test "Ping N" int current_ping = players.ping(player_name); return_val = p.negated ? current_ping < p.int1 : current_ping >= p.int1; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Ping {2} versus limit {3} {4}", player_name, not, current_ping, p.int1, return_val)); return return_val; case PartEnum.Teamsize: // test "Teamsize N" int min_teamsize = players.min_teamsize(); return_val = p.negated ? min_teamsize > p.int1 : min_teamsize <= p.int1; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Teamsize {2} versus limit {3} {4}", player_name, not, min_teamsize, p.int1, return_val)); return return_val; case PartEnum.Map: // test map name or filename contains string1 return_val = p.negated ? !map_match(p.string_list) : map_match(p.string_list); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Actual map {2} versus {3} {4}", player_name, not, current_map.PublicLevelName + " or " + current_map.FileName, keys_join(p.string_list), return_val)); return return_val; case PartEnum.MapMode: // test "mapmode rush|conquest" return_val = p.negated ? !mapmode_match(p.string_list) : mapmode_match(p.string_list); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}Actual MapMode {2} versus {3} {4}", player_name, not, current_map_mode, keys_join(p.string_list), return_val)); return return_val; case PartEnum.Kit: case PartEnum.Weapon: case PartEnum.Spec: case PartEnum.Damage: // test "Kit Recon 2" etc if (rule.trigger == TriggerEnum.Spawn) // will check *player* item as well as team count (spawn) return test_spawn_item(player_team_id, player_name, p); else // will also test kill item for TeamKill and Suicide return test_kill_item(k, p); case PartEnum.TeamKit: case PartEnum.TeamWeapon: case PartEnum.TeamSpec: case PartEnum.TeamDamage: return test_spawned_count(player_team_id, p); case PartEnum.Range: // test "Range > int1" return_val = p.negated ? !(k.Distance < p.int1) : k.Distance > p.int1; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}range {2} > limit {3} {4}", player_name, not, k.Distance, p.int1, return_val)); return return_val; case PartEnum.Count: case PartEnum.PlayerCount: // check how many times PLAYER has triggered this rule int current_count = count_rule(player_name, rule.id); bool count_valid = current_count > p.int1; return_val = p.negated ? !count_valid : count_valid; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}PlayerCount {2} (actual {3}) {4}", player_name, not, p.int1, current_count, return_val)); return return_val; case PartEnum.TeamCount: // check how many times PLAYER'S TEAM has triggered this rule int current_team_count = count_team_rule(players.team_id(player_name), rule.id); bool count_team_valid = current_team_count > p.int1; return_val = p.negated ? !count_team_valid : count_team_valid; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}TeamCount {2} (actual {3}) {4}", player_name, not, p.int1, current_team_count, return_val)); return return_val; case PartEnum.ServerCount: // check how many times ALL PLAYERS have triggered this rule int current_server_count = count_server_rule(rule.id); bool count_server_valid = current_server_count > p.int1; return_val = p.negated ? !count_server_valid : count_server_valid; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}ServerCount {2} (Actual {3}) {4}", player_name, not, p.int1, current_server_count, return_val)); return return_val; case PartEnum.Rate: // check condition "Rate X Y" i.e. X hits on this rule in Y seconds add_rate(player_name, rule.id); bool rate_valid = check_rate(player_name, rule.id, p.int1, p.int2); return p.negated ? !rate_valid : rate_valid; case PartEnum.Text: // check say text condition e.g. "Text ofc 4 ever,teamwork is everything" int index = -1; foreach (string t in p.string_list) { index = msg.ToLower().IndexOf(t.ToLower()); if (index >= 0 && keywords[SubstEnum.Text] != null && keywords[SubstEnum.Text].Length >= t.Length + 2) { // set up TargetText for TargetPlayer keywords[SubstEnum.TargetText] = keywords[SubstEnum.Text].Substring(index + t.Length).Trim(); } if (index >= 0) break; } return_val = p.negated ? index == -1 : index != -1; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}text {2} {3}", player_name, not, keys_join(p.string_list), return_val)); return return_val; case PartEnum.TargetPlayer: // check TargetPlayer condition, i.e. can we extract a playername from the say text // updated from v33 for find_players to return a LIST of player names // if only ONE playername matches, then automatically add TargetConfirm to action list... WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] checking TargetPlayer[{1}]", player_name, keywords[SubstEnum.Text])); List<string> player_names = new List<string>(); if (p.string_list != null && p.string_list.Count != 0) { // here the 'targettext' is specified in the rule e.g. "TargetPlayer bambam" player_names = find_players(rulz_vars.replace_vars(player_name, replace_keys(p.string_list[0], keywords))); } // note only 1 playername is allowed in condition else // because it could contain rulz_item_separator { // here the targettext from a previous "Text" condition will be used // if successful, we will modify TargetText to be AFTER the playername match string string[] t_words = null; if (keywords.ContainsKey(SubstEnum.TargetText)) { t_words = quoted_split(keywords[SubstEnum.TargetText]); } if (t_words != null && t_words.Length > 0) { player_names = find_players(t_words[0]); if (keywords[SubstEnum.TargetText].Length - t_words[0].Length > 1) { keywords[SubstEnum.TargetText] = keywords[SubstEnum.TargetText].Substring(t_words[0].Length + 1); } else { keywords[SubstEnum.TargetText] = ""; } } } return_val = p.negated ? player_names.Count == 0 : player_names.Count == 1; keywords[SubstEnum.Target] = player_names.Count == 0 ? "" : player_names[0]; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1}TargetPlayer {2} {3} with {4}", player_name, not, keys_join(p.string_list), return_val, String.Join(",", player_names.ToArray()))); return return_val; case PartEnum.Set: // set rulz variable rulz_vars.set_value(player_name, p.string_list[0], p.string_list[1], keywords); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] Set {1} {2}", player_name, keys_join(p.string_list), true)); return true; // set always succeeds case PartEnum.Incr: rulz_vars.incr(player_name, p.string_list[0], keywords); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] Increment {1} {2}", player_name, p.string_list[0], true)); return true; // Incr always succeeds case PartEnum.Decr: rulz_vars.decr(player_name, p.string_list[0], keywords); WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] Decrement {1} {2}", player_name, p.string_list[0], true)); return true; // Decr always succeeds case PartEnum.Test: // aka If // test var1 compare var2 (c.string_list[0..2]) WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] IF %c% is [{1}]", player_name, keywords[SubstEnum.Count])); return_val = rulz_vars.test(player_name, p.string_list[0], p.string_list[1], p.string_list[2], keywords); if (p.negated) return_val = !return_val; WriteDebugInfo(String.Format("ProconRulz: check_condition [{0}] {1} IF {2} {3}", player_name, not, keys_join(p.string_list), return_val)); return return_val; default: take_action(player_name, p, keywords); return true; } } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in process_part (ProconRulz will continue...)"); WriteConsole("ProconRulz: process_part rule.unparsed_rule = " + ((rule == null) ? "(rule=null)" : (rule.unparsed_rule == null ? "(null)" : "[" + rule.unparsed_rule + "]") ) ); WriteConsole("ProconRulz: process_part player_name = " + ((player_name == null) ? "(null)" :"[" + player_name + "]")); WriteConsole("ProconRulz: process_part p.part_type = " + ((p == null) ? "(p=null)" : (p.part_type == null ? "(null)" : p.part_type.ToString()) ) ); WriteConsole("ProconRulz: process_part k.Killer.SoldierName = " + ((k == null) ? "(k=null)" : ((k.Killer == null) ? "(k.Killer=null)" : ((k.Killer.SoldierName==null) ? "(null)" : ("["+k.Killer.SoldierName+"]")) ) ) ); PrintException(ex); return false; } }
private void QueueKillForProcessing(Kill kKillerVictimDetails) { this.DebugWrite("Entering queueKillForProcessing", 7); try { if (this._IsEnabled) { this.DebugWrite("Preparing to queue kill for processing", 6); lock (this._KillProcessingQueue) { this._KillProcessingQueue.Enqueue(kKillerVictimDetails); this.DebugWrite("Kill queued for processing", 6); this._KillProcessingWaitHandle.Set(); } } } catch (Exception e) { this.HandleException(new AdKatsException("Error while queueing kill for processing.", e)); } this.DebugWrite("Exiting queueKillForProcessing", 7); }
// test a rule (we have already confirmed Spawn or Kill trigger is true) // will return 'true' if the rule is applied private bool process_rule(TriggerEnum trigger, ParsedRule rule, string player_name, ref Dictionary<SubstEnum, string> keywords, Inventory inv, Kill k, string item) { WriteDebugInfo(String.Format("ProconRulz: process_rule[{0}] with event {1}", player_name, Enum.GetName(typeof(TriggerEnum), trigger))); // CATCH EXCEPTIONS try { List<PartClass> parts = new List<PartClass>(rule.parts); if (trigger == TriggerEnum.Say) keywords[SubstEnum.Text] = item; // Populate the Counts AS IF THIS RULE SUCCEEDED so conditions can use them keywords[SubstEnum.ServerCount] = count_server_rule(rule.id).ToString() + 1; keywords[SubstEnum.Count] = count_rule(player_name, rule.id).ToString() + 1; keywords[SubstEnum.TeamCount] = count_team_rule(players.team_id(player_name), rule.id).ToString() + 1; // populate the 'keywords' dictionary assign_keywords(trigger, rule, player_name, ref keywords, inv, k, item); if (!process_parts(rule, parts, player_name, ref keywords, k, item)) { WriteDebugInfo(String.Format("ProconRulz: process_rule[{0}] in rule [{1}] tests NEGATIVE", player_name, rule.unparsed_rule)); return false; } WriteDebugInfo(String.Format("ProconRulz: process_rule[{0}] in rule [{1}] all conditions OK", player_name, rule.unparsed_rule)); // return 'true' to quit rulz checks after this rule // if rule contains End, Kill, Kick, TempBan, Ban unless it contains Continue. return end_rulz(parts); } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in test_rule_and_exec(" + rule.unparsed_rule + ")"); PrintException(ex); return false; } }
//Move delayed players when they are killed public override void OnPlayerKilled(Kill kKillerVictimDetails) { this.DebugWrite("Entering OnPlayerKilled", 7); try { //If the plugin is not enabled just return if (!this._IsEnabled || !this._ThreadsReady) { return; } //Otherwise, queue the kill for processing this.QueueKillForProcessing(kKillerVictimDetails); } catch (Exception e) { this.HandleException(new AdKatsException("Error while handling onPlayerKilled.", e)); } }
// test for an item on a KILL private bool test_kill_item(Kill k, PartClass c) { try { if (k == null) return false; string weapon_key = k.DamageType; if (weapon_key == "") weapon_key = null; Weapon weapon_used; try { if (weapon_key == null) weapon_used = null; else weapon_used = weaponDefines[weapon_key]; } catch { weapon_used = null; } string weapon_descr = weapon_desc(weapon_key); string weapon_kit; try { if (weapon_used == null) weapon_kit = "No weapon kit"; else weapon_kit = item_key(weapon_used.KitRestriction); } catch { weapon_kit = "No weapon kit"; } string damage; try { damage = item_key(weapon_used.Damage); } catch { damage = "No damage key"; } switch (c.part_type) { case PartEnum.Weapon: WriteDebugInfo(String.Format("ProconRulz: Test kill item [WEAPON {0}]", keys_join(c.string_list))); if (weapon_key == null) return c.negated; if (keys_match(weapon_key, c.string_list)) { WriteDebugInfo(String.Format("ProconRulz: Test kill item [WEAPON {0}] found", weapon_key)); break; } // not found, so return false unless c.negated return c.negated; case PartEnum.Damage: WriteDebugInfo(String.Format("ProconRulz: Test kill item [DAMAGE {0}]", keys_join(c.string_list))); if (keys_match(damage, c.string_list)) { WriteDebugInfo(String.Format("ProconRulz: Test kill item [DAMAGE {0}] found", damage)); break; } return c.negated; case PartEnum.Kit: WriteDebugInfo(String.Format("ProconRulz: Test kill item [KIT {0}]", keys_join(c.string_list))); string test_kit = weapon_kit; // either use the kit type of the weapon, or the kit the player spawned with if (player_kit.ContainsKey(k.Killer.SoldierName)) test_kit = player_kit[k.Killer.SoldierName]; if (keys_match(test_kit, c.string_list)) { WriteDebugInfo(String.Format("ProconRulz: Test kill item [KIT {0}] found", test_kit)); break; } return c.negated; default: // item type can be None WriteDebugInfo(String.Format("ProconRulz: Test kill item [ignored] OK")); return true; } // end switch on item type bool success; if (c.int1 == 0) { success = true; if (c.negated) success = !success; WriteDebugInfo(String.Format("ProconRulz: Test kill item {0}", success)); // The item is being counted, and the count is above the limit in the rule return success; } // check the item_limit value WriteDebugInfo(String.Format("ProconRulz: Test kill item [{0}] has {1}({2}) versus rule limit {3}", k.Killer.SoldierName, keys_join(c.string_list), count_kill_items(k.Killer.SoldierName, c.string_list), c.int1)); success = count_kill_items(k.Killer.SoldierName, c.string_list) > c.int1; if (c.negated) success = !success; return success; } catch (Exception ex) { WriteConsole("ProconRulz: recoverable exception in test_kill_item"); PrintException(ex); return false; } }
private void m_prcClient_PlayerKilled(PRoConClient sender, Kill kill) { this.InvokeIfRequired(() => { lock (this.PlayerDictionaryLocker) { var killer = this.Players.ContainsKey(kill.Killer.SoldierName) == true ? this.Players[kill.Killer.SoldierName] : null; var victim = this.Players.ContainsKey(kill.Victim.SoldierName) == true ? this.Players[kill.Victim.SoldierName] : null; // Don't award a kill for a suicide if (killer != null && kill.IsSuicide == false) { var tag = killer.Tag as AdditionalPlayerInfo; if (tag != null) { if (killer.Tag != null && tag.Player != null) { tag.Player.Kills++; } killer.SubItems["kills"].Tag = ((Double)killer.SubItems["kills"].Tag) + 1; killer.SubItems["kills"].Text = ((Double)killer.SubItems["kills"].Tag).ToString(CultureInfo.InvariantCulture); killer.SubItems["kdr"].Tag = kill; if (killer.SubItems["deaths"].Tag != null && (Double)killer.SubItems["deaths"].Tag > 0) { killer.SubItems["kdr"].Text = String.Format("{0:0.00}", ((Double)killer.SubItems["kills"].Tag / (Double)killer.SubItems["deaths"].Tag)); } else { killer.SubItems["kdr"].Text = String.Format("{0:0.00}", (Double)killer.SubItems["kills"].Tag); } if (tag.Player != null) { this.AddKillToTeamTotal(tag.Player.TeamID); } } } if (victim != null) { var tag = victim.Tag as AdditionalPlayerInfo; if (tag != null) { if (victim.Tag != null && tag.Player != null) { tag.Player.Deaths++; } victim.SubItems["deaths"].Tag = (Double)victim.SubItems["deaths"].Tag + 1; victim.SubItems["deaths"].Text = ((Double)victim.SubItems["deaths"].Tag).ToString(CultureInfo.InvariantCulture); victim.SubItems["kdr"].Tag = kill; if (victim.SubItems["deaths"].Tag != null && (Double)victim.SubItems["deaths"].Tag > 0) { victim.SubItems["kdr"].Text = String.Format("{0:0.00}", ((Double)victim.SubItems["kills"].Tag / (Double)victim.SubItems["deaths"].Tag)); } else { victim.SubItems["kdr"].Text = String.Format("{0:0.00}", (Double)victim.SubItems["kills"].Tag); } victim.ImageIndex = this.Main.iglFlags.Images.IndexOfKey("flag_death.png"); if (tag.Player != null) { this.AddDeathToTeamTotal(tag.Player.TeamID); } } } this.tmrKillDeathHighlight.Enabled = true; } this.FinalizeTotalsAverages(); // this.ArrangePlayers(); }); }
//Move delayed players when they are killed public override void OnPlayerKilled(Kill kKillerVictimDetails) { //Used for delayed player moving if (isEnabled && this.teamswapOnDeathMoveDic.Count > 0) { lock (this.teamswapMutex) { this.teamswapOnDeathCheckingQueue.Enqueue(kKillerVictimDetails.Victim); this.teamswapHandle.Set(); } } //Update player death information if (this.playerDictionary.ContainsKey(kKillerVictimDetails.Victim.SoldierName)) { lock (this.playersMutex) { //Only add the last death if it's not a death by admin if (!String.IsNullOrEmpty(kKillerVictimDetails.Killer.SoldierName)) { this.playerDictionary[kKillerVictimDetails.Victim.SoldierName].lastDeath = DateTime.Now; } } } }
public override void OnPlayerKilled(Kill kKillerVictimDetails) { if (plugin_loaded) { try { lastKiller = kKillerVictimDetails.Killer.SoldierName; lastVictim = kKillerVictimDetails.Victim.SoldierName; lastWeapon = kKillerVictimDetails.DamageType; lastUsedWeapon = FWeaponName(lastWeapon); if (showweaponcode == enumBoolYesNo.Yes) WritePluginConsole("^2^n" + lastKiller + "^1^b [ " + lastUsedWeapon + " ]^7^n " + lastVictim, "KILL", 0); // Zeige Die Waffen in der Konsole Farblich hervorgehoben WritePluginConsole("[OnPlayerKilled] Killer: " + lastKiller,"DEBUG", 8); WritePluginConsole("[OnPlayerKilled] Victim: " + lastVictim,"DEBUG", 8); WritePluginConsole("[OnPlayerKilled] DamageType: " + lastWeapon,"DEBUG", 8); if (lastKiller != "" && lastKiller != lastVictim) { if (isprohibitedWeapon(lastUsedWeapon)) PlayerWarn(lastKiller, lastUsedWeapon); } if (lastKiller == lastVictim) { players.Suicide(lastVictim); } if (lastKiller != lastVictim) { if (lastKiller != "") players.Kill(lastKiller); if (lastVictim != "") players.Death(lastVictim); } } catch (Exception ex) { WritePluginConsole("^1^bOnPlayerKilled returs an Error: ^0^n" + ex.ToString(), "ERROR", 4); } } }