Page 1 of 175 123 11 51 101 ... LastLast
Results 1 to 10 of 1748
  1. #1

    Insane Limits 0.0.0.8 (beta, BF3)

    Insane Limits 0.0.0.8 is no longer continued. Please check the >>>NEW THREAD<<<


    The source for this plugin has moved to to GitHub since version 0.0.0.8-patch-3. Jump to the Insane Limits GitHub Project Page to grab the latest source.

    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.

    For a full list of examples, jump to the index in the Insane Limits - Examples thread.

    By default, the plugin ships 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.




    Twitter Live Feed


    The live feed shows the plugin state, kicks, and bans for servers that elected to tweet this data.



    http://twitter.com/InsaneLimits


    Video Demo




    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


    1. Download the zip file containing the plugin source (in the attachments)
    2. Extract the source file InsaneLimits.cs
    3. 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


    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
    • OnInterval - (deprecated) Same behavior as OnIntervalPlayers
    • 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


    Architecture


    When the plugin is enabled, it starts two threads:

    1. The fetch thread is in charge of monitoring the players that join the server. It fetches player statistics from battlelog.battlefield.com
    2. The enforcer thread is in charge of evaluating Interval limits. When the enforcer thread finds that a player violates a limit, it performs an action (Kick, Ban, etc) against that player.


    The two threads have different responsibilities, but they synchronize their work.


    Fetch-thread Flow


    When players join the server, they are added the stats queue. The fetch thread is constantly monitoring this queue. If there is a player in the queue, it removes him from the queue, and fetches the battlelog stats for the player.

    The stats queue can grow or shrink depending on how fast players join, and how long the web-requests take. If you enable the plugin on a full server, you will see that almost immediately all players are queued for stats fetching. Once the stats are fetched for all players in the queue, they are added to the internal player's list.


    Enforcer-thread Flow


    The enforcer thread runs on a timer (every second). It checks if there are any interval limits ready to be executed. If there are, it will evaluate those limits.

    Each time around that the enforcer checks for the available limits is called an iteration. If there are no players in the server, or there are no limits available, the enforcer skips the current iteration and sleeps until the next iteration.

    The enforcer is only responsible for Limits that evaluate OnIterval, events. Enforcing for other types of events like OnKill, and OnSpawn, is done in the main thread when procon sends the event information.


    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.

    1. 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.
    2. 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


      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!
    3. 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
    4. 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 thread. 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:

    1. 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
    2. 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.
    3. action Execution

      If the final result of the limit evaluation is True, the plugin then executes the action associated 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 Code snippets.


    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:

    Code:
    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 */
        String LogFile { get; }
    }


    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:

    Code:
    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; }
    }


    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:

    Code:
    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; }
    
        /* 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; }
    
        /* 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:

    Code:
    public interface KillInfoInterface
    {
        String Weapon { get; }
        bool Headshot { get; }
        DateTime Time { get; }
    }


    Player, Killer, Victim Objects


    The player object represents the state of player for which the current limit is being evaluated. The player object implements the following interface:

    Code:
    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 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; }
    
        
        /* 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; }
    
        /* 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:

    Code:
    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 SendGlobalMessage(String message, int delay);
        bool SendTeamMessage(int teamId, String message, int delay);
        bool SendSquadMessage(int teamId, int squadId, String message, int delay);
    
        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);
    
        /*
         * 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);
    
        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
    
        /*
         * 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
    }


    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:

    Code:
    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
    Code:
        %k_n% killed %v_n% with a %w_n%
    becomes
    Code:
            
        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.

    Code:
        // 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

    Code:
        player.Name you were banned for suspicious stats: Kpm: player.Kpm, Spm: player.Spm, Kdr: player.Kdr
    becomes

    Code:
        micovery you were banned for suspicious stats: Kpm: 0.4, Spm: 120, Kdr: 0.61


    Settings


    1. player_white_list
      (string, csv) - list of players that should never be kicked or banned
    2. clan_white_list
      (string, csv) - list of clan (tags) for players that should never be kicked or banned
    3. 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
    4. 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.
    5. smtp_port
      (String) - Address of the SMTP Mail server used for Mail action
    6. smtp_port
      (integer > 0) - port number of the SMTP Mail server used for Mail action
    7. smtp_account
      (Stirng) - mail address for authenticating with the SMTP Mail used for Mail action
    8. 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.
    9. smtp_ssl
      true - mail sent using secure socket (use this only if your SMTP provider requires it)
      false - mail sent without using secure socket
    10. 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.
    11. 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
    12. twitter_reset_defaults
      true - resets the Twitter's access_token, and access_token_secret back to default values
    13. twitter_setup
      true - initiates the Twitter configuration, it will show a link that you have to visit to get the verification PIN
    14. 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.


    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.
    Plugin Commands:


    • !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.



    In-Game Commands
    In-Game Commands:



    These are the In-Game commands supported by this plugin. You can run them only from within the game. Replies to the commands are printed in the game chat.

    • !stats
      List the available stats, Battlelog

      !stats [web|battlelog]
      List the available stats, Battlelog

      !stats round
      List the available stats, current round

      !stats total
      List the available stats, all rounds

      These commands are used as a shortcut for players to view what type of stats they can query. The plugin will try to fit all stat types into a single chat message.
    • !my {type}
      Print Battlelog stat of the specified type for the player that executed the command

      !my round {type}
      Print current round stat of the specified type for the player that executed the command

      !my total {type}
      Print all rounds stat of the specified type for the player that executed the command

      ?{player} {type}
      Print Battlelog stat of the specified type for the specified player

      ?{player} round {type}
      Print current round stat of the specified type for the specified player

      ?{player} total {type}
      Print all rounds stat of the specified type for the specified player

      The player name can be a sub-string, or even misspelled. The plugin will find the best match.

      These are the allowed stat types:
      • Battlelog: kdr, kpm, time, kills, wins, skill, spm, score, deaths, losses, repairs, accuracy, quit pecent, team score, combat socre, objective score, vehicles killed, recon time, engineer time, assault time, support time, vehicle time, engineer percent, assault percent, vehicle percent
      • Round: kdr, kpm, spm, score, kills, deaths, headshots, team kills, team deaths, suicides, time
      • Total: kdr, kpm spm, socre, kills, deaths, headshots, team kills, team deaths, suicides, time, rounds


      Here are some example commands:

      !my kdr
      !my spm
      !my engineer percent
      !micovery recon time



    Wish-List 0.0.0.9 (in order of priority)
    wishlist:

    1. Enable LINQ support for Battlelog weapon stats
    2. Add replacements for all custom dictionary keys in player, killer, victim, limit, server, plugin object
      eg. " key1 = player.DataRound.String(key1), key2 = plugin.Data.Int(key2)"
    3. Add option to compile limit from class file
    4. Add option to specify In-Game command prefixes
    5. Enable weapon-level In-Game stat commands
    6. Add option to get player's ping



    Change Log
    Change Log:

    • 0.0.0.8-patch-3 (beta, BF3)
      - Fixed collection modified exception in getPluginVars function
    • 0.0.0.8-patch-2 (beta, BF3)
      - Fixed dead-lock in fetch thread during OnJoin limit evaluation
      - Fixed "Collection was modified" exeption in getSettings function
      - Added wait logic, for when plugin is being disabled, to wait for all threads to finish
      - Moved the "Custom Privacy Policy" settings to be stored in the *conf file
      - Changed stats command to info
      e.g.
      !info
      !info round
      !info total
      !info online
      !info battlelog
      !info web
    • 0.0.0.8-patch-1 (beta, BF3) (unstable)
      - Added setting wait_timeout to specify how long (seconds) to wait for server commands to return, before timing-out
    • 0.0.0.8 (beta, BF3) (unstable)

      - Removed check_interval setting, Limits now have independent intervals
      - Added section privacy_policy_agreement, which you must accept the first time plugin is enabled
      - Changed behavior so that OnJoin limits are not evaluated anymore by enforcer_thread
      - OnJoin limit evalutions are now done (sequentially) within fetch thread, while inserting new player batches
      - Added "System.Threading" library for use within Limit's Code
      - Shortened the "friendly" ban duration messages appended to PBBans and EABans
      - Truncated EABan Messages at 80 characters
      - Changed EA Round-Bans to work with new R19 syntax "rounds", but left it to 1 Round default
      - Added smtp_ssl option under "Custom SMTP" section
      - Changed behavior of PBBan/EABan, and Kick actions to automatically remove players from internal player's list
      - Added setting auto_hide_sections (True/False) to control default state show/hide for new sections.
      - Changed behavior to automatically remove players from player's list after a kick or ban action
      - Added setting say_procon_chat to control whether or not message is shown in the PRoCon Chat Tab
      - Added Tweet action, by default Tweets go to (http://twitter.com/InsaneLimits), but you can change this under Custom Twitter
      - Added Tweet(String status) function to plugin object
      - Added twitter_reset_defaults to manually restore default Twitter account values
      - Added PBCommand action (to send any PunkBuster command)

      e.g. pb_command_text = pb_sv_getss "micovery"

      - Added function PBCommand(String text) to plugin object
      - Added ServerCommand action (to send BF3 server commands)

      e.g. server_command_text = admin.say "Hello World" all

      - Added PRoConEvent action to add entry in the ProCon Events Tab
      - Added function PRoConEvent(String text, String player) to plugin object
      - Added PRoConChat action to add entry in the ProCOn Chat Tab
      - Added function PRoConChat(String text) to plugin object
      - Changed behavior to auto-recompile limits (if not already compiled) after loading from limits file
      - Added compile_limit option, for manual recompilaiton of All limits, or just the NotCompiled limits
      - Added properties Port and Host to server object
      - Added properties Name and Description to server object
      - Changed SMS carrier names that included "&" character e.g. AT&T
      - Renamed the following functions (deprecated old ones, will be removed in next version)
      • IsInGameCommand -> IsCommand
      • ExtractInGameCommand -> ExtractCommand

      - Added function ExtractCommandPrefix to the plugin object
      - Modified the stats command to only respond if the {player-name} is a perfect match or command prefix is "?"

      e.g.
      !mico kdr (will not work)
      !micovery kdr (will work)
      ?mico kdr (will work)

      - Added evaluation_interval setting, allows limits to have independent interval values
      - Added OnIntervalPlayers event, evaluates for all players every evaluation_interval seconds
      - Added OnIntervalServer event, evaluates once every evaluation_interval seconds
      - Deprecated OnInterval event, it's same as OnIntervalPlayers
      - Fixed defect where execption was raised during replacements for OnRoundOver and OnRoundStart events
      - Added OnLeave event
      - Added new messaging functions with delay (in seconds) parameter to the plugin object
      • SendGlobalMessage(String message, int delay);
      • SendTeamMessage(int teamId, String message, int delay);
      • SendSquadMessage(int teamId, int squadId, String message, int delay);

      - Added support for using line-break escape sequence "\n" in say_message

      e.g. say_message = Line1\nLine2\Line3\nLine4

      - Addded support for using tab escape sequence "\t" in say_message

      e.g. say_message = AAAA\tBBBB\tCCCC\tDDDD\tEEEE

      - Added internal event handlers for more map-list state functions (to keep track of map-list changes appropirately)
    • 0.0.0.7 (beta, BF3) (stable)
    • 0.0.0.6 (beta, BF3)
    • 0.0.0.5 (beta, BF3)
    • 0.0.0.4 (beta, BF3)
    • 0.0.0.3 (beta, BF3)
    • 0.0.0.2 (beta, BF3)
    • 0.0.0.1 - original (beta, BF3) release

    Attached Files Attached Files
    Last edited by Ike; 12-07-2012 at 23:14.

  2. #2
    Looking forward to this.

  3. #3
    Good, let me know how it goes when you try it.

    Here is a list of aggregates I am planning to add/track:

    • RoundsPlayed - Number of rounds played since joining the server.
    • TimeIdle - Amount of time player has been idle
    • TimeTotal - Total time (in seconds) that the players has been in the server
    • HeadshotsTotal - Number of headshots the player has had since joining the server
    • HeadshotsRound - Number of headshots the player has had since the beginning of the round
    • KpmRound - Kills/minute ratio for the current round
    • KpmTotal - Kills/minute ratio since player joined the server
    • KdrTotal - Kill/Death ratio since player joined the server
    • TeamkillsRound - Number of team-kills for the current round
    • TeamkillsTotal - Number of team-kills since joining the server


    I will also add a weapon dictionary to store weapon-specific round-stats for each player. The weapon dictionary will hold:

    • KillsTotal - number of kills with specific weapon since joining the server
    • KillsRound - number of kills with specific weapon for the current round


    You will be able to get weapon-specific info like this:

    Code:
        player.weapons["M1911"].KillsRound
    There will also be new types of actions like: Kill (instant), Warn, and KillSpawn.
    Last edited by micovery; 21-12-2011 at 15:33.

  4. #4
    Looks very powerfull - i will try out in the next days as well!
    thumbs up

  5. #5
    Senior Member
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    102
    mhhhh ... i'm not a engineer ...
    Greetings VAM

  6. #6
    Quote Originally Posted by VAM View Post
    mhhhh ... i'm not a engineer ...
    Ha, no need to be ... maybe too much documentation is a bit scary :-)

    Are you trying to build a limit/rule expression? It's simpler that it seems. (Only the code-snippets are advanced).

  7. #7

  8. #8
    Looks good, yesterday I had this guy called "why_hack" come on the server who then slaughtered everyone, unfortunately i wasn't around at the time.
    http://battlelog.battlefield.com/bf3...ats/381413780/

    You can see obviously he has impossible stats, not sure why dice cant run simple checks for things like that.

    What stat would you think would be best to get rid of players like this? total time and total kills? total time and rank?

  9. #9
    Quote Originally Posted by Kilack View Post
    Looks good, yesterday I had this guy called "why_hack" come on the server who then slaughtered everyone, unfortunately i wasn't around at the time.
    http://battlelog.battlefield.com/bf3...ats/381413780/

    You can see obviously he has impossible stats, not sure why dice cant run simple checks for things like that.

    What stat would you think would be best to get rid of players like this? total time and total kills? total time and rank?
    Hey Kilack, this is more to do with another plugin but along the lines of what you want to go along with this is the plugin ProconRulz where you can have a rule for how many headshots within a certain period of time, e.g. 5 per 15 seconds or however you wish to set. So if a player exceeds this then they are auto banned.

  10. #10
    Quote Originally Posted by Kilack View Post
    Looks good, yesterday I had this guy called "why_hack" come on the server who then slaughtered everyone, unfortunately i wasn't around at the time.
    http://battlelog.battlefield.com/bf3...ats/381413780/

    You can see obviously he has impossible stats, not sure why dice cant run simple checks for things like that.

    What stat would you think would be best to get rid of players like this? total time and total kills? total time and rank?
    Haha wow, ridiculous stats. Clay is right, you can use ProconRulz for live-round sanity checks.

    At the moment, this plugin does not have too many live-round stats, but has plenty of battle-log stats you can use to weed out those players as soon as they join the server. This Expression will activate for very suspicious players like the one you showed:

    Code:
               ( player.Kdr > 15 || player.Skill > 1000)
    It checks if the player's KDR or Skill are ridiculously high. You can use a Temporary ban action for those players.

 

 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •