COPIED FROM MYRCON.COM BECAUSE OF FORUM SHUTDOWN
Closure Imminent
Original Author: micovery
On-going support: PapaCharlie9
Contributors: Singh400, EBastard
Testers and supporters: dyn, EBastard, Singh400, ADKGamers, Hexacanon
==>Download and install instructions in the last section of post <==
This is an orphaned plugin! It is no longer supported by the original author. It is maintained by community contributors (see list above). Donations are purely voluntary, without minimum or maximum requirement, and go to the original author, not to the community contributors.
Description
This plugin is a customizable limits/rules enforcer. It allows you to setup and enforce limits based on player statistics, and server state.
It tracks extensive Battlelog stats and round stats. If you feel that there is a stat, or aggregate, or information that really needs to be included, post feedback on this thread. The plugin supports events like OnKill, OnTeamKill, OnJoin, OnSpawn, etc. You are able to perform actions triggered by those events.
Version 0.9.4.0 and later is optionally integrated with a MySQL server (using the Battlelog Cache plugin). This enables caching of Battlelog stats fetching, which over time should reduce the delay caused by restarting Procon/enabling Insane Limits when your server is full. This should also reduce load on Battlelog, which in turn will reduce the number of Web errors and exceptions. This version is compatible with TrueBalancer and other plugins that use stats fetching.
You can find limits ready to use in the Plugin Enhancements forum.
You can request help for developing new limits in the Insane Limits Requests thread.
By default, the plugin installs with virtual_mode set to True. This allows you to test your limits/rules without any risk of accidentally kicking or banning anyone. Once you feel your limits/rules are ready, you can disable virtual_mode.
Think this plugin is awesome? You can buy me a beer. DONATION
Twitter Live Feed
The live feed shows the plugin state, kicks, and bans for servers that elected to tweet this data.
Twitter / Account gesperrt
Video Demo
Note: the video shows an old version of the plugin. What you see may differ from the video, but the basic steps of creating a limit are the same.
Don't see a video player above? Then click on this sentence to see it on YouTube. Use high resolution and full screen.
Disclaimer
If you are careless with the rules, sometimes you can end up hurting more than helping. Having said that, it's not up to me or anyone to judge the merit of a limit/rule, otherwise this can become a flame war. Be polite when replying to posts in this thread, and don't flame others because you don't like their rules. I just give you the tool, and you (the server admin) make the rules.
My advise is, think creatively when coming up with the rules, and be open minded. If you do not know how to express your limit ideas in C#, ask in this thread. The data is there, available, ready to be consumed ... you just have to come up with the ideas.
Installation Instructions
Minimum Requirements
This plugin requires you to have sufficient privileges for running the following commands:
Additionaly, you need to have Read+Write file system permission in the following directories:
Supported Limit Evaluations
Note that limit evaluation is only performed after the plugin has fetched the player stats from Battlelog.
When you enable the plugin for the first time in a full server, it will take a couple of minutes to fetch all player stats
Limit Management
Creation - In order to create a new limit, you have to set new_limit variable to True.
This creates a new limit section with default values that you can change.
Deletion - In order to delete a limit, you have to set the variable delete_limit to the numerical id of the limit you want to delete.
Each limit has an id number, you can see the id number in the limit name, e.g. Limit #5.
Limit Definition
At its basic, there are four fields that determine the structure of a limit. These fields are state, action, and first_check, and second_check.
Both Expressions, and Code snippets must be syntactically correct in accordance to the C# language.The plugin compiles your Expression/Code in-memory with the Microsoft C# Compiler. If there are compilation errors, those are shown in the plugin log.
If you do not know what C# is, or what an expression is, or what a code snippet is ... do not worry. Study the examples in the Insane limits examples . Then, if you are still unclear, how to write an expression or a code snippet, ask for help in this thread.
Limit Evaluation
After compilation, limit evaluation is by far the most important of all steps this plugin goes through.
Limit evaluation is comprised of three steps:
Objects
When writing a limit Expression or Code snippet, there are several globally defined objects that can be used. These are server, player, killer, victim, kill, plugin, team1, team2, team3, team4, and limit. These objects contain values, and functions that can be accessed from within the Expressions, or Codesnippets.
Limit Object
The limit object represents the state the limit that was just activated. This object is only available during the second_check. The limit object implements the following interface:
Team Object (team1, team2, team3, team4)
The teamX object represents the state of the team with id X at the moment that the limit is being evaluated. The teamX object implements the following interface:
Server Object
The server object represents the state of the server at the moment that the limit is being evaluated. The server object implements the following interface:
Kill Object
The kill object represents information about the kill event. The kill object implements the following interface:
The KillReasonInterface object represents the friendly weapon name, broken down into separate fields:
Player, Killer, Victim Objects
The player object represents the state of player for which the current limit is being evaluated. The playerobject implements the following interface:
Plugin Object
The plugin represents this plugin itself. It gives you access to important functions for executing server commands, and interacting with ProCon. The plugin object implements the following interface:
Data and RoundData Objects
The Data object is a nested dictionary of key/value pairs that you can use to store custom data inside the plugin, server, limit, player, killer, and victim objects. The Data object implements the following interface:
Simple (Traditional) Replacements
This plugin supports an extensive list of message text replacements. A replacement is a string that starts and ends with the percent character %. When you use them in the text of a message, the plugin will try to replace it with the corresponding value. For example:
The message
becomes
Below is a list of all the replacements supported. Some replacements are not available for all types of events. For example, Killer-Name replacement is not available for OnSpawn event.
Advanced Replacements
In addition to the simple %key% replacments, this plugin also allows you to use a more advanced type of replacement. Within strings, you can use replacements that match properties in known objects. For example, if you use player.Name within a string, the plugin will detect it and replace it appropriately.
A common usage for advanced replacements is to list player stats in the Kick/Ban reason. For example:
The message
becomes
Settings
Plugin Commands
These are the commands supported by this plugin. You can run them from within the console field. Replies to the commands are printed in the plugin log.
GitHub Project Page
Wishlist items and bugs that need fixing are staged in the Issues section of the Insane Limits project page.
Download
This version REQUIRES Procon 1.4.2.1 or later!
The plugin will fail to load and will not show up in your Plugins list unless you use Procon 1.4.2.1 or later.
Before downloading, read these IMPORTANT Frequently Asked Questions:
If you post a question that is answered by this FAQ section, then I know you didn't take the time to read this #1 post, so why should I take the time to reply to you? Fair is fair, you need to put effort into helping yourself first if you want me to put effort into helping you.
Q: I downloaded the ZIP, but how do I install it?
A: Extract the InsaneLimits.cs file from the zip, that is the only file you need. Upload/copy it into either (or both) procon/Plugins/BF3 or procon/Plugins/BF4. Restart Procon. I you use a layer, all of the above must happen on your layer host, not on your local client.
Q: I get EXCEPTION: System.Security.SecurityException! Why?
A: Insane Limits is a plugin that needs to run without restrictions. Change your Procon settings as follows:
(Menu) Tools -> Options -> Plugins tab, Plugin security, Run plugins with no restrictions
If you already have that set, make sure your Procon layer host has write permission for the entire Procon installation folder.
Q: I get ERROR: X errors compiling Expression! Why?
A: Probably because you set first_check to Expression instead of what the instructions in the post told you to set it to, probably Code.
Q: All my limits are gone after I restarted Procon! -or- Why does it keep asking me to accept permissions after I restart Procon, I already accepted them!?
A: See this post for details about what you should and should not do when you are in this situation: https://forum.myrcon.com/showthread....l=1#post106210
Download Instructions
Download the ZIP archive from here: PapaCharlie9/insane-limits
On that page, click on the "zip" link below the version with the highest number (latest).
SEE THE NEXT THREE POSTS FOR ADDITIONAL DETAILS THAT WOULDN'T FIT IN THIS POST!
Closure Imminent
Original Author: micovery
On-going support: PapaCharlie9
Contributors: Singh400, EBastard
Testers and supporters: dyn, EBastard, Singh400, ADKGamers, Hexacanon
==>Download and install instructions in the last section of post <==
This is an orphaned plugin! It is no longer supported by the original author. It is maintained by community contributors (see list above). Donations are purely voluntary, without minimum or maximum requirement, and go to the original author, not to the community contributors.
Description
This plugin is a customizable limits/rules enforcer. It allows you to setup and enforce limits based on player statistics, and server state.
It tracks extensive Battlelog stats and round stats. If you feel that there is a stat, or aggregate, or information that really needs to be included, post feedback on this thread. The plugin supports events like OnKill, OnTeamKill, OnJoin, OnSpawn, etc. You are able to perform actions triggered by those events.
Version 0.9.4.0 and later is optionally integrated with a MySQL server (using the Battlelog Cache plugin). This enables caching of Battlelog stats fetching, which over time should reduce the delay caused by restarting Procon/enabling Insane Limits when your server is full. This should also reduce load on Battlelog, which in turn will reduce the number of Web errors and exceptions. This version is compatible with TrueBalancer and other plugins that use stats fetching.
You can find limits ready to use in the Plugin Enhancements forum.
You can request help for developing new limits in the Insane Limits Requests thread.
By default, the plugin installs with virtual_mode set to True. This allows you to test your limits/rules without any risk of accidentally kicking or banning anyone. Once you feel your limits/rules are ready, you can disable virtual_mode.
Think this plugin is awesome? You can buy me a beer. DONATION
Twitter Live Feed
The live feed shows the plugin state, kicks, and bans for servers that elected to tweet this data.
Twitter / Account gesperrt
Video Demo
Note: the video shows an old version of the plugin. What you see may differ from the video, but the basic steps of creating a limit are the same.
Don't see a video player above? Then click on this sentence to see it on YouTube. Use high resolution and full screen.
Disclaimer
If you are careless with the rules, sometimes you can end up hurting more than helping. Having said that, it's not up to me or anyone to judge the merit of a limit/rule, otherwise this can become a flame war. Be polite when replying to posts in this thread, and don't flame others because you don't like their rules. I just give you the tool, and you (the server admin) make the rules.
My advise is, think creatively when coming up with the rules, and be open minded. If you do not know how to express your limit ideas in C#, ask in this thread. The data is there, available, ready to be consumed ... you just have to come up with the ideas.
Installation Instructions
- Download the zip file containing the plugin source
- Extract the source file InsaneLimits.cs
- Copy the source file to ProCon's Plugins/BF3 directory
Minimum Requirements
This plugin requires you to have sufficient privileges for running the following commands:
- serverInfo
- mapList.list
- mapList.getMapIndices
- admin.listPlayers all
- punkBuster.pb_sv_command pb_sv_plist
- punkBuster.pb_sv_command pb_sv_ban
- punkBuster.pb_sv_command pb_sv_kick
Additionaly, you need to have Read+Write file system permission in the following directories:
- <ProCon>/
- <ProCon>/Plugins/BF3
- <ProCon>/Plugins/BF4
Supported Limit Evaluations
- OnJoin - Limit evaluated when player joins
- OnLeave - Limit evaluated when player leaves
- OnSpawn - Limit evaluated when player spawns
- OnKill - Limit evaluated when makes a kill (team-kills not counted)
- OnTeamKill - Limit evaluated when player makes a team-kill
- OnDeath - Limit evaluated when player dies (suicides not counted)
- OnTeamDeath - Limit evaluated when player is team-killed
- OnSuicide - Limit evaluated when player commits suicide
- OnAnyChat - Limit evaluated when players sends a chat message
- OnIntervalPlayers - Limit evaluated (for all players) every evaluation_interval number of seconds
- OnIntervalServer - Limit evaluated once every evaluation_interval number of seconds
- OnRoundOver - Limit evaluated when round over event is sent by PRoCon
- OnRoundStart - Limit evaluated after round over event, when first player spawns
- OnTeamChange - Limit evaluated after player switches team (admin move not counted as team-switch)
Note that limit evaluation is only performed after the plugin has fetched the player stats from Battlelog.
When you enable the plugin for the first time in a full server, it will take a couple of minutes to fetch all player stats
Limit Management
Creation - In order to create a new limit, you have to set new_limit variable to True.
This creates a new limit section with default values that you can change.
Deletion - In order to delete a limit, you have to set the variable delete_limit to the numerical id of the limit you want to delete.
Each limit has an id number, you can see the id number in the limit name, e.g. Limit #5.
Limit Definition
At its basic, there are four fields that determine the structure of a limit. These fields are state, action, and first_check, and second_check.
- state
Enabled - the limit will be used by the plugin thread
Disabled - the limit will be ignored by the plugin thread
Virtual - the limit will be used, but actions will be done in virtual_mode
This field is useful if you want to temporarily disable a limit from being used, but still want to preserve its definition. - action
(string, psv) - list of actions for this limit (Pipe separated ""|"")
e.g. Say | PBBan | Mail
These are all the allowed actions:- None - no action is performed against the player
- Kick - player is kicked, if the limit evaluates to True
- EABan - player is banned (using the BF3 ban-list), if the limit evaluates True
- PBBan - player is banned (using PunkBuster ban-list), if the limit evaluates True
- Kill - kills the player (delay optional), if the limit evaluates True
- Say - sends a message the server (All, Team, Squad, or Player), if the limit evaluates True
- Log - logs a message to a File, Plugin log, or both, if the limit evaluates True
- Mail - sends an e-mail to specified address, if the limit evaluates True
- SMS - sends an SMS message to the specified phone number, if the limit evaluates True
- Tweet - posts a Twitter status update (default account is @InsaneLimits), if the limit evaluates True
- PBCommand - executes the specified PunkBuster command, if the limit evaluates True
- ServerCommand - executes the specified Server command, if the limit evaluates True
- PRoConChat - sends the specified text to PRoCon's Chat-Tab, if the limit evaluates True
- PRoConEvent - adds the specified event to PRoCon's Events-Tab, if the limit evaluates True
- TaskbarNotify - sends a Windows Taskbar notification, if the limit evaluates True
- SoundNotify - plays an audio notification, if the limit evaluates True
- Yell - yells a message to the server (All, Team, or Player), if the limit evaluates True
Depending on the selected action, other fields are shown to specify more information about the action.
Supported PB ban-duration: Permanent, Temporary
Supported PB ban-type: PB_GUID (default)
Supported EA ban-duration: Permanent, Temporary, Round
Supported EA ban-type: EA_GUID, IPAddress, Name
Also note that each of these actions have a target player. You have to be careful on what target is for each action.
For example, during a Kill event, the target of the action is the Killer. But, during a Death event, the target of the action is the player that was killed. You don't want to accidentally Kick/Ban the wrong player!- first_check
Disabled - the limit does not evaluate anything in the first step of evaluation
Expression - the limit uses a C# conditional expression during the first step of evaluation
Code - the limit uses a C# code snippet (must return true/false) during the first step of evaluation - second_check
Disabled - the limit does not evaluate anything in the second step of evaluation
Expression - the limit uses a C# conditional expression during the second step of evaluation
Code - the limit uses a C# code snippet (must return true/false) during the second step of evaluation
Depending on the selected check type, an extra field will be shown for specifying the Expression, or Code text.
Both Expressions, and Code snippets must be syntactically correct in accordance to the C# language.The plugin compiles your Expression/Code in-memory with the Microsoft C# Compiler. If there are compilation errors, those are shown in the plugin log.
If you do not know what C# is, or what an expression is, or what a code snippet is ... do not worry. Study the examples in the Insane limits examples . Then, if you are still unclear, how to write an expression or a code snippet, ask for help in this thread.
Limit Evaluation
After compilation, limit evaluation is by far the most important of all steps this plugin goes through.
Limit evaluation is comprised of three steps:
- first_check Evaluation
During this step, the plugin executes the Expression/Code in first_check to get a True or False result.
If the result is False, the plugin does not perform any action, and quits. But, if it's True, it keeps going to the next step - second_check Evaluation (optional)
Next, the plugin runs the Expression/Code for the second_check, if it's enabled. If it's not enabled, it keeps going to next step. - action Execution
If the final result of the limit evaluation is True, the plugin then executes the actionassociated with the limit.
If the final result of the limit evaluation is False, no action is executed.
Objects
When writing a limit Expression or Code snippet, there are several globally defined objects that can be used. These are server, player, killer, victim, kill, plugin, team1, team2, team3, team4, and limit. These objects contain values, and functions that can be accessed from within the Expressions, or Codesnippets.
Limit Object
The limit object represents the state the limit that was just activated. This object is only available during the second_check. The limit object implements the following interface:
Код:
public interface LimitInfoInterface
{
//Number of times the limit has been activated, (Current round)
double Activations(String PlayerName);
double Activations(int TeamId, int SquadId);
double Activations(int TeamId);
// Number of times player has activated this limit (Current round) in the given TimeSpan, e.g. last 10 seconds, etc
double Activations(String PlayerName, TimeSpan time);
double Activations();
//Number of times the limit has been activated (All rounds)
double ActivationsTotal(String PlayerName);
double ActivationsTotal(int TeamId, int SquadId);
double ActivationsTotal(int TeamId);
double ActivationsTotal();
// Number of times this limit has been activated by player
/*
* Kill, TeamKill: Spree value is reset when player dies
* Death, TeamDeath, and Suicide: Spree value is reset whe player makes a kill
*
* Spawn, Join, Interval: Spree value is never reset, you may reset it manually.
*/
double Spree(String PlayerName);
// manually resets the Spree value for the player, (only for power-users)
void ResetSpree(String PlayerName);
/* Data Repository set/get custom data */
DataDictionaryInterface Data { get; }
DataDictionaryInterface RoundData { get; } //this dictionary is automaticaly cleared OnRoundStart
/* Other methods */
Team Object (team1, team2, team3, team4)
The teamX object represents the state of the team with id X at the moment that the limit is being evaluated. The teamX object implements the following interface:
Код:
public interface TeamInfoInterface
{
List<PlayerInfoInterface> players { get; }
double KillsRound { get; }
double DeathsRound { get; }
double SuicidesRound { get; }
double TeamKillsRound { get; }
double TeamDeathsRound { get; }
double HeadshotsRound { get; }
double ScoreRound { get; }
int TeamId { get; }
double Tickets { get; }
double RemainTickets { get; }
double RemainTicketsPercent { get; }
double StartTickets { get; }
// BF4
int Faction { get; } // US = 0, RU = 1, CN = 2
}
Server Object
The server object represents the state of the server at the moment that the limit is being evaluated. The server object implements the following interface:
Код:
public interface ServerInfoInterface
{
/* Server State */
int CurrentRound { get; }
int TotalRounds { get; }
int PlayerCount { get; }
int MaxPlayers { get; }
/* Current Map Data */
int MapIndex { get; }
String MapFileName { get; }
String Gamemode { get; }
/* Next Map Data */
int NextMapIndex { get; }
String NextMapFileName { get; }
String NextGamemode { get; }
double GameModeCounter { get; }
double CTFRoundTimeModifier { get; }
/* Map Rotation */
List<String> MapFileNameRotation { get; }
List<String> GamemodeRotation { get; }
List<int> LevelRoundsRotation { get; }
/* All players, Current Round, Stats */
double KillsRound { get; }
double DeathsRound { get; } // kind of useless, should be same as KillsTotal (suicides not counted as death)
double HeadshotsRound { get; }
double SuicidesRound { get; }
double TeamKillsRound { get; }
/* All players, All rounds, Stats */
double KillsTotal { get; }
double DeathsTotal { get; } // kind of useless, should be same s KillsTotal (suicides not counted as death)
double HeadshotsTotal { get; }
double SuicidesTotal { get; }
double TeamKillsTotal { get; }
/* Weapon Stats, Current Round, All Rounds (Total)*/
WeaponStatsInterface this[String WeaponName] { get; }
/* Other data */
double TimeRound { get; } // Time since round started
double TimeTotal { get; } // Time since plugin enabled
double TimeUp { get; } // Time since last server restart
double RoundsTotal { get; } //Round played since plugin enabled
/* Meta Data */
String Port { get; } // Layer/Server port number
String Host { get; } // Layer/Server Host
String Name { get; }
String Description { get; }
String GameVersion { get; } // BF3 or BF4
/* var.* value that is updated every update_interval seconds */
int BulletDamage { get; }
bool FriendlyFire { get; }
int GunMasterWeaponsPreset { get; }
double IdleTimeout { get; } // seconds
int SoldierHealth { get; }
bool VehicleSpawnAllowed { get; }
int VehicleSpawnDelay { get; }
// BF4
bool Commander { get; }
int MaxSpectators { get; }
String ServerType { get; }
int GetFaction(int TeamId); // US = 0, RU = 1, CN = 2
/* Team data */
double Tickets(int TeamId); //tickets for the specified team
double RemainTickets(int TeamId); //tickets remaining on specified team
double RemainTicketsPercent(int TeamId); //tickets remaining on specified team (as percent)
double StartTickets(int TeamId); //tickets at the begining of round for specified team
double TargetTickets { get; } //tickets needed to win
int OppositeTeamId(int TeamId); //id of the opposite team, 1->2, 2->1, 3->4, 4->3, *->0
int WinTeamId { get; } //id of the team that won previous round
/* Data Repository set/get custom data */
DataDictionaryInterface Data { get; }
DataDictionaryInterface RoundData { get; } //this dictionary is automaticaly cleared OnRoundStart
Kill Object
The kill object represents information about the kill event. The kill object implements the following interface:
Код:
public interface KillInfoInterface
{
String Weapon { get; }
bool Headshot { get; }
DateTime Time { get; }
String Category { get; } // BF3.defs or BF4.defs weapon category, such as SniperRifle or VehicleAir
}
The KillReasonInterface object represents the friendly weapon name, broken down into separate fields:
Код:
public interface KillReasonInterface
{
String Name { get; } // weapon name or reason, like Suicide
String Detail { get; } // BF4: ammo or attachment
String AttachedTo { get; } // BF4: main weapon when Name is a secondary attachment, like M320
String VehicleName { get; } // BF4: if Name is Death, this is the vehicle's name
String VehicleDetail { get; } // BF4: if Name is Death, this is the vehicle's detail (stuff after final slash)
}
Player, Killer, Victim Objects
The player object represents the state of player for which the current limit is being evaluated. The playerobject implements the following interface:
Код:
public interface PlayerInfoInterface
{
/* Online statistics (battlelog.battlefield.com) */
double Rank { get; }
double Kdr { get; }
double Time { get; }
double Kills { get; }
double Wins { get; }
double Skill { get; }
double Spm { get; }
double Score { get; }
double Deaths { get; }
double Losses { get; }
double Repairs { get; }
double Revives { get; }
double Accuracy { get; }
double Ressuplies { get; }
double QuitPercent { get; }
double ScoreTeam { get; }
double ScoreCombat{ get; }
double ScoreVehicle{ get; }
double ScoreObjective { get; }
double VehiclesKilled { get; }
double Kpm { get; }
double KillAssists { get; }
double ResetDeaths { get; }
double ResetKills { get; }
double ResetLosses { get; }
double ResetWins { get; }
double ResetScore { get; }
double ResetShotsFired { get; }
double ResetShotsHit { get; }
double ResetTime { get; }
double ReconTime { get; }
double EngineerTime { get; }
double AssaultTime { get; }
double SupportTime { get; }
double VehicleTime { get; }
double ReconPercent { get; }
double EngineerPercent { get; }
double AssaultPercent { get; }
double SupportPercent { get; }
double VehiclePercent { get; }
/* Player data */
String Name { get; }
String FullName { get; } // name including clan-tag
String Tag { get; }
String IPAddress { get; }
String CountryCode { get ; }
String CountryName { get; }
String PBGuid { get; }
String EAGuid { get; }
int TeamId { get; }
int SquadId { get; }
int Ping { get; }
int MaxPing { get; }
int MinPing { get; }
int MedianPing { get; } // of the last five samples
int AveragePing { get; } // of two to five samples
int Role { get; } // BF4: 0 = PLAYER, 1 = SPECTATOR, 2 = COMMANDER, 3 = MOBILE COMMANDER
/* Current round, Player Stats */
double KdrRound { get; }
double KpmRound { get; }
double SpmRound { get; }
double ScoreRound { get; }
double KillsRound { get; }
double DeathsRound { get; }
double HeadshotsRound { get; }
double TeamKillsRound { get; }
double TeamDeathsRound { get; }
double SuicidesRound { get; }
double TimeRound { get; }
/* All rounds, Player Stats */
double KdrTotal { get; }
double KpmTotal { get; }
double SpmTotal { get; }
double ScoreTotal { get; }
double KillsTotal { get; }
double DeathsTotal { get; }
double HeadshotsTotal { get; }
double TeamKillsTotal { get; }
double TeamDeathsTotal { get; }
double SuicidesTotal { get; }
double TimeTotal { get; }
double RoundsTotal { get; }
/* Weapon Stats, Current Round, All Rounds (Total) */
WeaponStatsInterface this[String WeaponName] { get; }
/* Battlelog Weapon Stats function: use kill.Weapon for WeaponName */
BattlelogWeaponStatsInterface GetBattlelog(String WeaponName);
/* Other Data */
DateTime JoinTime { get; }
String LastChat { get; } // text of the last chat sent by player
bool Battlelog404 { get; } // True - Player has no PC Battlelog profile
bool StatsError { get; } // True - Error occurred while processing player stats
/* Whitelist information */
bool inClanWhitelist { get; }
bool inPlayerWhitelist { get; }
bool isInWhitelist { get; }
/* Data Repository set/get custom data */
DataDictionaryInterface Data { get; }
DataDictionaryInterface RoundData { get; } //this dictionary is automaticaly cleared OnRoundStart
}
Plugin Object
The plugin represents this plugin itself. It gives you access to important functions for executing server commands, and interacting with ProCon. The plugin object implements the following interface:
Код:
public interface PluginInterface
{
/*
* Methods for sending messages
*/
bool SendGlobalMessage(String message);
bool SendTeamMessage(int teamId, String message);
bool SendSquadMessage(int teamId, int squadId, String message);
bool SendPlayerMessage(String name, String message);
bool SendGlobalMessage(String message, int delay);
bool SendTeamMessage(int teamId, String message, int delay);
bool SendSquadMessage(int teamId, int squadId, String message, int delay);
bool SendPlayerMessage(String name, String message, int delay);
bool SendGlobalYell(String message, int duration);
bool SendTeamYell(int teamId, String message, int duration);
bool SendPlayerYell(String name, String message, int duration);
bool SendMail(String address, String subject, String body);
bool SendSMS(String country, String carrier, String number, String message);
/*
* Methods used for writing to the Plugin console
*/
void ConsoleWrite(String text);
void ConsoleWarn(String text);
void ConsoleError(String text);
void ConsoleException(String text);
/*
* Methods for getting whitelist information
*
*/
bool isInWhitelist(String PlayerName);
bool isInPlayerWhitelist(String PlayerName);
bool isInClanWhitelist(String PlayerName);
bool isInWhiteList(String PlayerName, String list_name);
/* Method for checking custom lists */
bool isInList(String item, String list_name);
List<String> GetReservedSlotsList();
/*
* Methods getting and setting the Plugin's variables
*/
bool setPluginVarValue(String variable, String value);
String getPluginVarValue(String variable);
/*
* Method: R
*
* Replaces tags like %p_n% (Player Name), %k_n% (Killer Name), %v_n% (Victim Name), etc
*/
String R(String message);
/*
* Methods for actions
*/
bool KickPlayerWithMessage(String name, String message);
bool KillPlayer(String name); /* deprecated, do not use */
bool KillPlayer(String name, int delay);
bool EABanPlayerWithMessage(EABanType type, EABanDuration duration, String name, int minutes, String message);
bool PBBanPlayerWithMessage(PBBanDuration duration, String name, int minutes, String message);
bool PBCommand(String text);
bool MovePlayer(String name, int TeamId, int SquadId, bool force);
bool SendTaskbarNotification(String title, String messagge);
bool Log(String file, String message);
bool Tweet(String status);
bool PRoConChat(String text);
bool PRoConEvent(String text, String player);
bool SendSoundNotification(String soundfile, String soundfilerepeat);
void ServerCommand(params String[] arguments);
/* Other Methods */
String FriendlySpan(TimeSpan span); //converts a TimeSpan into a friendly formatted string e.g. "2 hours, 20 minutes, 15 seconds"
String BestPlayerMatch(String name); //looks in the internal player's list, and finds the best match for the given player name
bool IsInGameCommand(String text); //checks if the given text start with one of these characters: !/@?
bool IsCommand(String text); //checks if the given text start with one of these characters: !/@?
String ExtractInGameCommand(String text); //if given text starts with one of these charactets !/@? it removes them
String ExtractCommand(String text); //if given text starts with one of these charactets !/@? it removes them
String ExtractCommandPrefix(String text); //if given text starts with one of these chracters !/@? it returns the character
/* This method checks if the currently in-game player with matching name has
a Procon account on the Procon instance controlling this game server. Returns
False if the name does not match any of the players currently joined to the game server,
OR the name does not match any of the accounts on the Procon instance.
The canBan value is set to true if the player can temporary ban or permanently ban.
*/
bool CheckAccount(String name, out bool canKill, out bool canKick, out bool canBan, out bool canMove, out bool canChangeLevel);
double CheckPlayerIdle(String name); // -1 if unknown, otherwise idle time in seconds
/* Updated every update_interval seconds */
bool IsSquadLocked(int teamId, int squadId); // False if unknown or open, True if locked
String GetSquadLeaderName(int teamId, int squadId); // null if unknown, player name otherwise
/* This method looks in the internal player's list for player with matching name.
* If fuzzy argument is set to true, it will find the player name that best matches the given name
*/
PlayerInfoInterface GetPlayer(String name, bool fuzzy);
/*
* Creates a file in ProCOn's directory (InsaneLimits.dump)
* Detailed information about the exception.
*/
void DumpException(Exception e);
/* Data Repository set/get custom data */
DataDictionaryInterface Data { get; }
DataDictionaryInterface RoundData { get; } //this dictionary is automaticaly cleared OnRoundStart
/* Friendly names */
String FriendlyMapName(String mapFileName); //example: "MP_001" -> "Grand Bazaar"
String FriendlyModeName(String modeName); //example: "TeamDeathMatch0" -> "TDM"
KillReasonInterface FriendlyWeaponName(String killWeapon);
// BF3 example: "Weapons/XP2_L86/L86" => KillReasonInterface("L86", null, null)
// BF4 example: "U_AK12_M320_HE" => KillReasonInterface("M320", "HE", "AK12")
}
Data and RoundData Objects
The Data object is a nested dictionary of key/value pairs that you can use to store custom data inside the plugin, server, limit, player, killer, and victim objects. The Data object implements the following interface:
Код:
public interface DataDictionaryInterface
{
/* String Data */
String setString(String key, String value);
String getString(String key);
String unsetString(String key);
bool issetString(String key);
List<String> getStringKeys();
/* Boolean Data */
bool setBool(String key, bool value);
bool getBool(String key);
bool unsetBool(String key);
bool issetBool(String key);
List<String> getBoolKeys();
/* Double Data */
double setDouble(String key, double value);
double getDouble(String key);
double unsetDouble(String key);
bool issetDouble(String key);
List<String> getDoubleKeys();
/* Int Data */
int setInt(String key, int value);
int getInt(String key);
int unsetInt(String key);
bool issetInt(String key);
List<String> getIntKeys();
/* Object Data */
object setObject(String key, object value);
object getObject(String key);
object unsetObject(String key);
bool issetObject(String key);
List<String> getObjectKeys();
/* Generic set/get methods */
Object set(Type type, String key, Object value);
Object get(Type type, String key);
Object unset(Type type, String key);
bool isset(Type type, String key);
List<String> getKeys(Type type);
/* Other methods */
void Clear(); /* clear/unset all data from repository */
}
Simple (Traditional) Replacements
This plugin supports an extensive list of message text replacements. A replacement is a string that starts and ends with the percent character %. When you use them in the text of a message, the plugin will try to replace it with the corresponding value. For example:
The message
Код:
%k_n% killed %v_n% with a %w_n%
becomes
Код:
micovery killed NorthEye with a PP-2000
Below is a list of all the replacements supported. Some replacements are not available for all types of events. For example, Killer-Name replacement is not available for OnSpawn event.
Код:
// Killer Replacements (Evaluations: OnKill, OnDeath, OnTeamKills, and OnTeamDeath)
/* Legend:
* k - killer
* n - name
* ct - Clan-Tag
* cn - Country Name
* cc - Country Code
* ip - IPAddress
* eg - EA GUID
* pg - Punk Buster GUID
*/
%k_n% Killer name
%k_ct% Killer clan-Tag
%k_cn% Killer county-name
%k_cc% Killer county-code
%k_ip% Killer ip-address
%k_eg% Killer EA GUID
%k_pg% Killer Punk-Buster GUID
%k_fn% Killer full name, includes Clan-Tag (if any)
// Victim Replacements (Evaluations: OnKill, OnDeath, OnTeamKills, and OnTeamDeath)
/* Legend:
* v - victim
*/
%v_n% Victim name,
%v_ct% Victim clan-Tag
%v_cn% Victim county-name
%v_cc% Victim county-code
%v_ip% Victim ip-address
%v_eg% Victim EA GUID
%v_pg% Vitim Punk-Buster GUID
%v_fn% Victim full name, includes Clan-Tag (if any)
// Player Repalcements (Evaluations: OnJoin, OnSpawn, OnAnyChat, OnTeamChange, and OnSuicide)
/* Legend:
* p - player
* lc - last chat
*/
%p_n% Player name
%p_ct% Player clan-Tag
%p_cn% Player county-name
%p_cc% Player county-code
%p_ip% Player ip-address
%p_eg% Player EA GUID
%p_pg% Player Punk-Buster GUID
%p_fn% Player full name, includes Clan-Tag (if any)
%p_lc% Player, Text of last chat
// Weapon Replacements (Evaluations: OnKill, OnDeath, OnTeamKill, OnTeamDeath, OnSuicide)
/* Legend:
* w - weapon
* n - name
* p - player
* a - All (players)
* x - count
*/
%w_n% Weapon name,
%w_p_x% Weapon, number of times used by player in current round
%w_a_x% Weapon, number of times used by All players in current round
// Limit Replacements for Activations & Spree Counts, Current Round (Evaluations: Any)
/* Legend:
* th - ordinal count suffix e.g. 1st, 2nd, 3rd, 4th, etc
* x - count, 1, 2, 3, 4, etc
* p - player
* s - squad
* t - team
* a - All (players)
* r - SpRee
*/
%p_x_th% Limit, ordinal number of times limit has been activated by the player
%s_x_th% Limit, ordinal number of times limit has been activated by the player's squad
%t_x_th% Limit, ordinal number of times limit has been activated by the player's team
%a_x_th% Limit, ordinal number of times limit has been activated by all players in the server
%r_x_th% Limit, ordinal number of times limit has been activated by player without Spree value being reset
%p_x% Limit, number of times limit has been activated by the player
%s_x% Limit, number of times limit has been activated by the player's squad
%t_x% Limit, number of times limit has been activated by the player's team
%a_x% Limit, number of times limit has been activated by all players in the server
%r_x% Limit, number of times limit has been activated by player without Spree value being reset
// Limit Replacements for Activations, All Round (Evaluations: Any)
/* Legend:
* xa - Total count, for all rounds
*/
%p_xa_th% Limit, ordinal number of times limit has been activated by the player
%s_xa_th% Limit, ordinal number of times limit has been activated by the player's squad
%t_xa_th% Limit, ordinal number of times limit has been activated by the player's team
%a_xa_th% Limit, ordinal number of times limit has been activated by all players in the server
%p_xa% Limit, number of times limit has been activated by the player
%s_xa% Limit, number of times limit has been activated by the player's squad
%t_xa% Limit, number of times limit has been activated by the player's team
%a_xa% Limit, number of times limit has been activated by all players in the server
// Other replacements
%date% Current date, e.g. Sunday December 25, 2011,
%time% Current time, e.g. 12:00 AM
%server_host% Server/Layer host/IP
%server_port% Server/Layer port number
%l_id% Limit numeric id"
%l_n% Limit name""
Advanced Replacements
In addition to the simple %key% replacments, this plugin also allows you to use a more advanced type of replacement. Within strings, you can use replacements that match properties in known objects. For example, if you use player.Name within a string, the plugin will detect it and replace it appropriately.
A common usage for advanced replacements is to list player stats in the Kick/Ban reason. For example:
The message
Код:
player.Name you were banned for suspicious stats: Kpm: player.Kpm, Spm: player.Spm, Kdr: player.Kdr
becomes
Код:
micovery you were banned for suspicious stats: Kpm: 0.4, Spm: 120, Kdr: 0.61
Settings
- use_direct_fetch
True - if the cache is not available, fetch stats directly from Battlelog
False - disable direct fetches from Battlelog
If the Battlelog Cache plugin is installed, up-to-date and enabled, it will be used for player stats regardless of the setting of this option. If the Battlelog Cache plugin is not installed, not up-to-date or disabled, setting use_direct_fetch to True will act as a fallback system, fetching stats directly from Battlelog. Otherwise, stats fetching will fail since the cache is not available and this setting is False. In other words, when Battlelog Caches is available, it is used for stats fetching always. When it is not available, you can enable or disable fetching of stats directly from Battlelog with this setting. - use_slow_weapon_stats
True - fetch weapon stats for new players
False - skip fetching weapon stats for new players
Visible only if use_direct_fetch is set to True. Fetching weapon stats from Battlelog takes a long time, 15 seconds or more per player. By default, this slow fetch is disabled (False), so that your Procon restart or initial plugin enable time on a full server won't be delayed or bogged down while fetching weapon stats. However, if you have limits that use the GetBattlelog() function, you must set this value to True, or else stats will not be available. Also, see rcon_to_battlelog_codes.
NOTE: by default, use_slow_weapon_stats is set to False. If you set use_direct_fetch to False also, you will not see this setting. If you are using Battlelog Cache, you will not get per player weapon stats unless you do the following: temporarily set use_direct_fetch to True, set use_slow_weapon_stats to True, then set use_direct_fetch back to False. - use_stats_log
True - log Battlelog stats to the battle.log file
False - do not log Battlelog stats to the battle.log file
If set to True and stats fetching is enabled and stats are fetched successfully, all the stats that were fetched will be logged in a file that follows the standard logging file name pattern: procon/Logs/<server-ip>_<server-port>/YYYYMMDD_battle.log (text file). - player_white_list
(string, csv) - list of players that should never be kicked or banned - clan_white_list
(string, csv) - list of clan (tags) for players that should never be kicked or banned - virtual_mode
true - limit actions (kick, ban) are simulated, the actual commands are not sent to server
false - limit actions (kick, ban) are not simulated - console
(string) - you can use this field to run plugin commands
For example: !stats micovery will print the player statistic for the current round in the plugin console.
Note that plugin commands, are currently supported only inside ProCon, and not In-Game. - rcon_to_battlelog_codes
String[] Array - syntax: RCON=Battlelog, e.g., U_XBOW=WARSAW_ID_P_WNAME_CROSSBOW
Visible only if use_slow_weapon_stats is True. Lets you define mappings from RCON weapon codes to Battelog weapon stats codes. Useful when new unlocks or DLC are released and in-use before the next update of this plugin is available. You can also override incorrect mappings built-in to the plugin, if any. - smtp_port
(String) - Address of the SMTP Mail server used for Mail action - smtp_port
(integer > 0) - port number of the SMTP Mail server used for Mail action - smtp_account
(Stirng) - mail address for authenticating with the SMTP Mail used for Mail action - smtp_mail
(Stirng) - mail address (Sender/From) that is used for sending used for Mail action
This is usually the same as smtp_account ... depends on your SMTP Mail provider. - smtp_ssl
true - mail sent using secure socket (use this only if your SMTP provider requires it)
false - mail sent without using secure socket - say_interval
(float) - interval in seconds between say messages. Default value is 0.05, which is 50 milli-seconds
The point of this setting is to avoid spam, but you should not set this value too large. Ideally it should be between 0 and 1 second. - update_interval
(float) - interval in seconds between updates to certain player and server properties
In order to avoid lagging your Procon client or layer, certain values like plugin.IsSquadLocked and server.FriendlyFire are only updated every update_interval seconds, which must be 60 or more. - auto_hide_sections
true - when creating a new section, it will be hidden by default
false - when creating a new section, it will not be hidden - twitter_reset_defaults
true - resets the Twitter's access_token, and access_token_secret back to default values - twitter_setup
true - initiates the Twitter configuration, it will show a link that you have to visit to get the verification PIN - twitter_verifier_pin
(String) - this field is displayed for you to enter the Twitter verification PIN, it disappears as soon as you enter it
After entering your PIN, the plugin will try to exchange the PIN for a Twitter access_token, and access_token_secret. If the verifcation stage fails, you must re-initiate the Twitter setup process. - wait_timeout
(int) - interval in seconds to wait for a response from the game server
If you get several Timeout(xx seconds) expired, while waiting for ... exceptions in plugin.log, try increasing the wait_timeout value by 10 seconds. Repeat until the exceptions stop, but you should not exceed 90 seconds.
Plugin Commands
These are the commands supported by this plugin. You can run them from within the console field. Replies to the commands are printed in the plugin log.
- !round stats
Aggregate stats for all players, current round
!total stats
Aggregate stats for all players, all rounds
!weapon round stats
Weapon-Level aggregate stats for all players, current round
!weapon total stats
Weapon-Level aggregate stats for all players, all rounds
!web stats {player}
Battlelog stats for the current player
!round stats {player}
Aggregate stats for the current player, current round
!total stats {player}
Aggregate stats for the current player, all rounds
!weapon round stats {player}
Weapon-Level stats for the current player, current round
!weapon total stats {player}
Weapon-Level stats for the current player, all round
These are the most awesome of all the commands this plugin provides. Even if you are not using this plugin to enforce any limit, you could have it enabled for just monitoring player stats.
When calling player specific statistic commands, if you misspell, or only type part of the player name, the plugin will try to find the best match for the player name. - !dump limit {id}
This command creates a file in ProCon's directory containing the source-code for the limit with the specified id
For example, the following command
!dump limit 5
Creates the file LimitEvaluator5.cs inside ProCon's directory.
This command is very useful for debugging compilation errors, as you can see the code inside the file exactly as the plugin sees it (with the same line and column offsets). - !set {variable} {to|=} {value}
!set {variable} {value}
!set {variable}
This command is used for setting the value of this plugin's variables.
For the last invocation syntax the value is assumed to be True. - !get {variable}
This command prints the value of the specified variable.
GitHub Project Page
Wishlist items and bugs that need fixing are staged in the Issues section of the Insane Limits project page.
Download
This version REQUIRES Procon 1.4.2.1 or later!
The plugin will fail to load and will not show up in your Plugins list unless you use Procon 1.4.2.1 or later.
Before downloading, read these IMPORTANT Frequently Asked Questions:
If you post a question that is answered by this FAQ section, then I know you didn't take the time to read this #1 post, so why should I take the time to reply to you? Fair is fair, you need to put effort into helping yourself first if you want me to put effort into helping you.
Q: I downloaded the ZIP, but how do I install it?
A: Extract the InsaneLimits.cs file from the zip, that is the only file you need. Upload/copy it into either (or both) procon/Plugins/BF3 or procon/Plugins/BF4. Restart Procon. I you use a layer, all of the above must happen on your layer host, not on your local client.
Q: I get EXCEPTION: System.Security.SecurityException! Why?
A: Insane Limits is a plugin that needs to run without restrictions. Change your Procon settings as follows:
(Menu) Tools -> Options -> Plugins tab, Plugin security, Run plugins with no restrictions
If you already have that set, make sure your Procon layer host has write permission for the entire Procon installation folder.
Q: I get ERROR: X errors compiling Expression! Why?
A: Probably because you set first_check to Expression instead of what the instructions in the post told you to set it to, probably Code.
Q: All my limits are gone after I restarted Procon! -or- Why does it keep asking me to accept permissions after I restart Procon, I already accepted them!?
A: See this post for details about what you should and should not do when you are in this situation: https://forum.myrcon.com/showthread....l=1#post106210
Download Instructions
Download the ZIP archive from here: PapaCharlie9/insane-limits
On that page, click on the "zip" link below the version with the highest number (latest).
SEE THE NEXT THREE POSTS FOR ADDITIONAL DETAILS THAT WOULDN'T FIT IN THIS POST!