Jump to content
Bartis11313

Big Thread of Insane Limits (fixed)

Recommended Posts

My last thread had some errors so i will post fixed version with every script working + some extra ones I made or rewrote for bf4/updated it. The thread I rewrote for bf4 is: old anticheat script for bf3

1. Set tickets on round end (Do not add the tickrate), I am not sure if it will work without thread sleep since I have spotted issues with tickrate & tickets change on end
OnRoundOver
Code
 

int tickets = 100;
int health = 100;
int delay = 100;
int bleed = 100;

plugin.ServerCommand("vars.soldierHealth", health.ToString());
plugin.ServerCommand("vars.vehicleSpawnDelay", delay.ToString());
plugin.ServerCommand("vars.ticketBleedRate", bleed.ToString());
plugin.PRoConChat("^bRestarted values");
plugin.ConsoleWrite("^bRestarted values");

Thread scriptdelay = new Thread(new ThreadStart(delegate {
Thread.Sleep(5 * 1000);

if (server.NextGamemode == "ConquestLarge0") { //CQL
    tickets = 125;

    plugin.ServerCommand("vars.serverName");
    plugin.ServerCommand("vars.gameModeCounter", tickets.ToString());
    plugin.PRoConChat("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickets: " + (tickets * 8).ToString ("F0") + " [^4" + tickets + "^0%]");
    plugin.ConsoleWrite("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickets: " + (tickets * 8).ToString ("F0") + " [^4" + tickets + "^0%]");
}


if (server.NextGamemode == "RushLarge0") { //RUSH
    if (server.PlayerCount <= 29) {
        tickets = 150;
    }
    if ((server.PlayerCount >= 30) && (server.PlayerCount <= 44)) {
        tickets = 200;
    }
    if (server.PlayerCount >= 45) {
        tickets = 250;
    }
    plugin.ServerCommand("vars.serverName");
    plugin.ServerCommand("vars.gameModeCounter", tickets.ToString());
    plugin.PRoConChat("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickets: [^4" + tickets + "^0%]");
    plugin.ConsoleWrite("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickets: [^4" + tickets + "^0%]");
}


if (server.NextGamemode == "ConquestSMall0") { //CQS
    tickets = 150;
    plugin.ServerCommand("vars.serverName");
    plugin.ServerCommand("vars.gameModeCounter", tickets.ToString());
}

})); 
scriptdelay.Name = "ScriptDelay";
scriptdelay.Start();
	
return false;

2.  Map command (vips)
Examples -> !map siege cql = next map is Siege of Shanghai with Conquest Large and 1 round. -> !map siege cql 2 = next map is Siege of Shanghai with Conquest Large and 2 rounds.
OnAnyChat
Code

//OnAnyChat

//first check: code

int level = 2;
try
{
    level = Convert.ToInt32(plugin.getPluginVarValue("debug_level"));
}
catch (Exception e) { }

Match m = Regex.Match(player.LastChat, @"^\s*!map\s+([^\s]+)\s+([^\s]+)$", RegexOptions.IgnoreCase);
Match m2 = Regex.Match(player.LastChat, @"^\s*!map\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)$", RegexOptions.IgnoreCase);

if (plugin.GetReservedSlotsList().Contains(player.Name)) return false;

List<String> mapFileNames = server.MapFileNameRotation;
List<String> modeNames = server.GamemodeRotation;
List<int> rounds = server.LevelRoundsRotation;

Converter<String, int> MapCodeToIndex = delegate (String mc) {
    int i = 0;
    foreach (String mapFileName in mapFileNames)
    {
        if (Regex.Match(mapFileName, mc, RegexOptions.IgnoreCase).Success)
        {
            return i;
        }
        i = i + 1;
    }
    return i;
};

if (!m.Success) return false;

//if(!m2.Success) will fail for "m" match so leave it

if (m.Success)
{
    int r = 1;
    String name = m.Groups[1].Value;
    String mode = m.Groups[2].Value;
    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("locker", "MP_Prison");
    dict.Add("zavod", "MP_Abandoned");
    dict.Add("lancang", "MP_Damage");
    dict.Add("flood", "MP_Flooded");
    dict.Add("golmud", "MP_Journey");
    dict.Add("paracel", "MP_Naval");
    dict.Add("hainan", "MP_Resort");
    dict.Add("rogue", "MP_TheDish");
    dict.Add("dawn", "MP_Tremors");
    dict.Add("silk", "XP1_001");
    dict.Add("altai", "XP1_002");
    dict.Add("gulin", "XP1_003");
    dict.Add("dragon pass", "XP1_004");
    dict.Add("caspian", "XP0_Caspian");
    dict.Add("firestorm", "XP0_Firestorm");
    dict.Add("metro", "XP0_Metro");
    dict.Add("oman", "XP0_Oman");
    dict.Add("islands", "XP2_001");
    dict.Add("nansha", "XP2_002");
    dict.Add("wavebr", "XP2_003");
    dict.Add("mortar", "XP2_004");
    dict.Add("pearl", "XP3_MarketPl");
    dict.Add("propaganda", "XP3_Prpganda");
    dict.Add("lumpini", "XP3_UrbanGdn");
    dict.Add("sunken", "XP3_WtrFront");
    dict.Add("whiteout", "XP4_Arctic");
    dict.Add("hammerhead", "XP4_SubBase");
    dict.Add("hangar", "XP4_Titan");
    dict.Add("giants", "XP4_WalkerFactory");
    dict.Add("night", "XP5_Night_01");
    dict.Add("outbreak", "XP6_CMP");
    dict.Add("valley", "XP7_Valley");
    string mapcorrect = dict[name];

    Dictionary<string, string> mapss = new Dictionary<string, string>();
    mapss.Add("locker", "locker");
    mapss.Add("zavod", "zavod");
    mapss.Add("lancang", "lancang");
    mapss.Add("flood", "flood");
    mapss.Add("golmud", "golmud");
    mapss.Add("paracel", "paracel");
    mapss.Add("hainan", "hainan");
    mapss.Add("rogue", "rogue");
    mapss.Add("dawn", "dawn");
    mapss.Add("silk", "silk");
    mapss.Add("altai", "altai");
    mapss.Add("gulin", "gulin");
    mapss.Add("dragon pass", "dragon pass");
    mapss.Add("caspian", "caspian");
    mapss.Add("firestorm", "firestorm");
    mapss.Add("metro", "metro");
    mapss.Add("oman", "oman");
    mapss.Add("islands", "islands");
    mapss.Add("nansha", "nansha");
    mapss.Add("wavebr", "wavebr");
    mapss.Add("mortar", "mortar");
    mapss.Add("pearl", "pearl");
    mapss.Add("propaganda", "propaganda");
    mapss.Add("lumpini", "lumpini");
    mapss.Add("sunken", "sunken");
    mapss.Add("whiteout", "whiteout");
    mapss.Add("hammerhead", "hammerhead");
    mapss.Add("hangar", "hangar");
    mapss.Add("giants", "giants");
    mapss.Add("night", "night");
    mapss.Add("outbreak", "outbreak");
    mapss.Add("valley", "valley");
    string mapcheck = mapss[name];

    Dictionary<string, string> modes = new Dictionary<string, string>();
    modes.Add("cql", "ConquestLarge0");
    modes.Add("cqs", "ConquestSmall0");
    modes.Add("domination", "Domination0");
    modes.Add("defuse", "Elimination0");
    modes.Add("obli", "Obliteration");
    modes.Add("rush", "RushLarge0");
    modes.Add("tdm", "TeamDeathMatch0");
    modes.Add("sqdm", "SquadDeathMatch0");
    modes.Add("airsup", "AirSuperiority0");
    modes.Add("ctf", "CaptureTheflag0");
    modes.Add("cas", "CarrierAssaultSmall0");
    modes.Add("cal", "CarrierAssaultLarge0");
    modes.Add("sqobli", "SquadObliteration0");
    modes.Add("gunmaster", "GunMaster0");
    modes.Add("guntroll", "GunMaster1");
    string modecorrect = modes[mode];

    Dictionary<string, string> modes2 = new Dictionary<string, string>();
    modes2.Add("cql", "cql");
    modes2.Add("cqs", "cqs");
    modes2.Add("domination", "domination");
    modes2.Add("defuse", "defuse");
    modes2.Add("obli", "obli");
    modes2.Add("rush", "rush");
    modes2.Add("tdm", "tdm");
    modes2.Add("sqdm", "sqdm");
    modes2.Add("airsup", "airsup");
    modes2.Add("ctf", "ctf");
    modes2.Add("cas", "cas");
    modes2.Add("cal", "cal");
    modes2.Add("sqobli", "sqobli");
    modes2.Add("gunmaster", "gunmaster");
    modes2.Add("guntroll", "guntroll");
    string modecheck1 = modes2[mode];

    if (server.MapFileNameRotation.Contains(mapcorrect))
    {

        int mapIndex = MapCodeToIndex(mapcorrect);
        if (mapIndex < modeNames.Count && modeNames[mapIndex] == modecorrect)
        {

            if (level >= 2) plugin.ConsoleWrite("^b[MAP]^n special case, setting next to existing map entry #" + mapIndex + ", " + plugin.FriendlyMapName(mapcorrect));

            plugin.SendGlobalMessage("Next map: " + plugin.FriendlyMapName(mapcorrect) + " " + plugin.FriendlyModeName(modecorrect) + " Rounds: " + r.ToString());

            // Set it as the next map
            plugin.ServerCommand("mapList.setNextMapIndex", mapIndex.ToString());

            return false;
        }
    }
    int lastMap = server.MapFileNameRotation.Count;

    plugin.ConsoleWrite("^b[MAP]^n setnext: temp map inserted at index #" + lastMap);
    plugin.SendGlobalMessage("Next map: " + plugin.FriendlyMapName(mapcorrect) + " " + plugin.FriendlyModeName(modecorrect) + " Rounds: " + r.ToString());
    plugin.ServerCommand("mapList.add", mapcorrect, modecorrect, r.ToString());
    plugin.ServerCommand("mapList.setNextMapIndex", lastMap.ToString());
    // Refresh map list
    plugin.ServerCommand("mapList.list");

}

if (m2.Success)
{
    int r = 1;
    String name = m2.Groups[1].Value;
    String mode = m2.Groups[2].Value;
    r = Convert.ToInt32(m2.Groups[3].Value);

    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("locker", "MP_Prison");
    dict.Add("zavod", "MP_Abandoned");
    dict.Add("lancang", "MP_Damage");
    dict.Add("flood", "MP_Flooded");
    dict.Add("golmud", "MP_Journey");
    dict.Add("paracel", "MP_Naval");
    dict.Add("hainan", "MP_Resort");
    dict.Add("rogue", "MP_TheDish");
    dict.Add("dawn", "MP_Tremors");
    dict.Add("silk", "XP1_001");
    dict.Add("altai", "XP1_002");
    dict.Add("gulin", "XP1_003");
    dict.Add("dragon pass", "XP1_004");
    dict.Add("caspian", "XP0_Caspian");
    dict.Add("firestorm", "XP0_Firestorm");
    dict.Add("metro", "XP0_Metro");
    dict.Add("oman", "XP0_Oman");
    dict.Add("islands", "XP2_001");
    dict.Add("nansha", "XP2_002");
    dict.Add("wavebr", "XP2_003");
    dict.Add("mortar", "XP2_004");
    dict.Add("pearl", "XP3_MarketPl");
    dict.Add("propaganda", "XP3_Prpganda");
    dict.Add("lumpini", "XP3_UrbanGdn");
    dict.Add("sunken", "XP3_WtrFront");
    dict.Add("whiteout", "XP4_Arctic");
    dict.Add("hammerhead", "XP4_SubBase");
    dict.Add("hangar", "XP4_Titan");
    dict.Add("giants", "XP4_WalkerFactory");
    dict.Add("night", "XP5_Night_01");
    dict.Add("outbreak", "XP6_CMP");
    dict.Add("valley", "XP7_Valley");
    string mapcorrect = dict[name];

    Dictionary<string, string> mapss = new Dictionary<string, string>();
    mapss.Add("locker", "locker");
    mapss.Add("zavod", "zavod");
    mapss.Add("lancang", "lancang");
    mapss.Add("flood", "flood");
    mapss.Add("golmud", "golmud");
    mapss.Add("paracel", "paracel");
    mapss.Add("hainan", "hainan");
    mapss.Add("rogue", "rogue");
    mapss.Add("dawn", "dawn");
    mapss.Add("silk", "silk");
    mapss.Add("altai", "altai");
    mapss.Add("gulin", "gulin");
    mapss.Add("dragon pass", "dragon pass");
    mapss.Add("caspian", "caspian");
    mapss.Add("firestorm", "firestorm");
    mapss.Add("metro", "metro");
    mapss.Add("oman", "oman");
    mapss.Add("islands", "islands");
    mapss.Add("nansha", "nansha");
    mapss.Add("wavebr", "wavebr");
    mapss.Add("mortar", "mortar");
    mapss.Add("pearl", "pearl");
    mapss.Add("propaganda", "propaganda");
    mapss.Add("lumpini", "lumpini");
    mapss.Add("sunken", "sunken");
    mapss.Add("whiteout", "whiteout");
    mapss.Add("hammerhead", "hammerhead");
    mapss.Add("hangar", "hangar");
    mapss.Add("giants", "giants");
    mapss.Add("night", "night");
    mapss.Add("outbreak", "outbreak");
    mapss.Add("valley", "valley");
    string mapcheck = mapss[name];

    Dictionary<string, string> modes = new Dictionary<string, string>();
    modes.Add("cql", "ConquestLarge0");
    modes.Add("cqs", "ConquestSmall0");
    modes.Add("domination", "Domination0");
    modes.Add("defuse", "Elimination0");
    modes.Add("obli", "Obliteration");
    modes.Add("rush", "RushLarge0");
    modes.Add("tdm", "TeamDeathMatch0");
    modes.Add("sqdm", "SquadDeathMatch0");
    modes.Add("airsup", "AirSuperiority0");
    modes.Add("ctf", "CaptureTheflag0");
    modes.Add("cas", "CarrierAssaultSmall0");
    modes.Add("cal", "CarrierAssaultLarge0");
    modes.Add("sqobli", "SquadObliteration0");
    modes.Add("gunmaster", "GunMaster0");
    modes.Add("guntroll", "GunMaster1");
    string modecorrect = modes[mode];

    Dictionary<string, string> modes2 = new Dictionary<string, string>();
    modes2.Add("cql", "cql");
    modes2.Add("cqs", "cqs");
    modes2.Add("domination", "domination");
    modes2.Add("defuse", "defuse");
    modes2.Add("obli", "obli");
    modes2.Add("rush", "rush");
    modes2.Add("tdm", "tdm");
    modes2.Add("sqdm", "sqdm");
    modes2.Add("airsup", "airsup");
    modes2.Add("ctf", "ctf");
    modes2.Add("cas", "cas");
    modes2.Add("cal", "cal");
    modes2.Add("sqobli", "sqobli");
    modes2.Add("gunmaster", "gunmaster");
    modes2.Add("guntroll", "guntroll");
    string modecheck1 = modes2[mode];

    if (server.MapFileNameRotation.Contains(mapcorrect))
    {

        int mapIndex = MapCodeToIndex(mapcorrect);
        if (mapIndex < modeNames.Count && modeNames[mapIndex] == modecorrect)
        {

            if (level >= 2) plugin.ConsoleWrite("^b[MAP]^n special case, setting next to existing map entry #" + mapIndex + ", " + plugin.FriendlyMapName(mapcorrect));

            plugin.SendGlobalMessage("Next map: " + plugin.FriendlyMapName(mapcorrect) + " " + plugin.FriendlyModeName(modecorrect) + " Rounds: " + r.ToString());

            // Set it as the next map
            plugin.ServerCommand("mapList.setNextMapIndex", mapIndex.ToString());

            return false;
        }
    }
    int lastMap = server.MapFileNameRotation.Count;

    plugin.ConsoleWrite("^b[MAP]^n setnext: temp map inserted at index #" + lastMap);
    plugin.SendGlobalMessage("Next map: " + plugin.FriendlyMapName(mapcorrect) + " " + plugin.FriendlyModeName(modecorrect) + " Rounds: " + r.ToString());
    plugin.ServerCommand("mapList.add", mapcorrect, modecorrect, r.ToString());
    plugin.ServerCommand("mapList.setNextMapIndex", lastMap.ToString());
    // Refresh map list
    plugin.ServerCommand("mapList.list");
}

2.5 - Addon for indexes check
OnRoundStart
Code

/*way that is broken in limits

Broken code
var index_delete = new List<int> { 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (int element in index_delete) {
    plugin.ServerCommand ("mapList.remove", element.ToString());
}
    

Broken code
int indexNum = server.MapFileNameRotation.Count;
for(int i=<your default index number>;i<indexNum;i++) {
    plugin.ServerCommand("mapList.remove", i.ToString());
} 

Below Working code with pretty bad quality, it works for il though...
*/

int a = 11;
int b = 12;
int c = 13;
int d = 14;
int e = 15;
int f = 16;
int g = 17;
plugin.ServerCommand("mapList.remove", a.ToString());
plugin.ServerCommand("mapList.remove", b.ToString());
plugin.ServerCommand("mapList.remove", c.ToString());
plugin.ServerCommand("mapList.remove", d.ToString());
plugin.ServerCommand("mapList.remove", e.ToString());
plugin.ServerCommand("mapList.remove", f.ToString());
plugin.ServerCommand("mapList.remove", g.ToString());

3. Check player command
Example -> !check Bartis
OnAnyChat
Code

Match m = Regex.Match(player.LastChat, @"^\s*[/[email protected]]check\s+([^\s]+)", RegexOptions.IgnoreCase);
if (!m.Success)
    return false;
List<String> vips = plugin.GetReservedSlotsList();
if (!vips.Contains(player.Name))
{
    plugin.SendPlayerMessage(player.Name, "You Can't use this command.");
    return false;
}
if (m.Success)
{
    // Match target player name
    String name = m.Groups[1].Value;
    List<PlayerInfoInterface> all = new List<PlayerInfoInterface>();
    all.AddRange(team1.players);
    all.AddRange(team2.players);
    all.AddRange(team3.players);
    all.AddRange(team4.players);
    PlayerInfoInterface target = null;
    int count = 0;
    foreach (PlayerInfoInterface p in all)
    {
        if (Regex.Match(p.Name, name, RegexOptions.IgnoreCase).Success)
        {
            target = p;
            ++count;
        }
    }
    if (count == 0 || target == null)
    {
        plugin.SendPlayerMessage(player.Name, "No player name matches '" + name + "'");
        return false;
    }
    else if (count > 1)
    {
        plugin.SendPlayerMessage(player.Name, "Too many names match '" + name + "', try again");
        return false;
    }

    double headshots = target.HeadshotsRound;
    double killsNOW = target.KillsRound;
    double result = Math.Round((headshots / killsNOW), 2);

    plugin.SendPlayerMessage(player.Name, target.Name + " stats:");
    plugin.SendPlayerMessage(player.Name, target.Name + " K/D: " + "[" + target.Kdr + "]" + " | " + "REAL K/D: " + "[" + (target.Kills / target.Deaths).ToString("F2") + "]");
    plugin.SendPlayerMessage(player.Name, target.Name + " Wins: " + (((target.Wins) / (target.Wins + target.Losses)) * 100).ToString("F2") + "%" + " |" + " Skill: " + target.Skill + " | " + "KPM: " + target.Kpm.ToString("F2"));
    plugin.SendPlayerMessage(player.Name, target.Name + " HS on Round: " + result * 100 + "%.");
    plugin.SendPlayerMessage(player.Name, target.Name + " KPM on Round: " + Math.Round((target.KpmRound), 2));
    plugin.SendPlayerMessage(player.Name, target.Name + " Country: " + target.CountryName + ".");
}

4. Tickrate change for next map (will fail if admin changed map after)
OnServerInterval
Time for interval in s - add as less as possible

double RemainTicketsPercent = 100;
int tickrate = 60;

string[] maps = { "MP_Prison" }; // add more since it's an array if you want. Usefull for water maps

if (server.RemainTicketsPercent(1) == 5 || server.RemainTicketsPercent(2) == 5)
{
    bool ifMap = Array.Exists(maps, element => element == server.NextMapFileName);
    if (ifMap)
    {
        tickrate = 60;
        plugin.ServerCommand("vars.OutHighFrequency", tickrate.ToString());
        plugin.PRoConChat("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickrate: [^4" + tickrate + "Hz]");
        plugin.ConsoleWrite("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickrate: [^4" + tickrate + "Hz]");
    }
    else
    {
        tickrate = 40;
        plugin.ServerCommand("vars.OutHighFrequency", tickrate.ToString());
        plugin.PRoConChat("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickrate: [^4" + tickrate + "Hz]");
        plugin.ConsoleWrite("^bNext map: [^2" + plugin.FriendlyMapName(server.NextMapFileName) + "^0<> ^3" + plugin.FriendlyModeName(server.NextGamemode) + "^0] | Tickrate: [^4" + tickrate + "Hz]");
    }
}
return false;

5. Reports webhook

Example -> !report Bartis teamkills
OnAnyChat
First expression

(Regex.Match(player.LastChat, @"[/[email protected]]report" ,RegexOptions.IgnoreCase).Success)

Second Check Code


string webhookUrl = ""; //EDIT
string serverName = server.Name;
string webhookString = null;

// Don't edit
String playerName = null;
String playerMessage = null;
String reportReason = null;
Match regexResult = null;

Match regexMatch = Regex.Match(player.LastChat, @"^\s*[/[email protected]]report\s+([^\s]+)\s+([^.*]+)", RegexOptions.IgnoreCase);


if (regexMatch.Success)
{
	regexResult = regexMatch;
}
else
{
	playerMessage = "Error! Correct command: !report <part of playername> <reason>";
	plugin.SendPlayerMessage(player.Name, playerMessage);
	return false;
}

String name = regexResult.Groups[1].Value;
List<PlayerInfoInterface> all = new List<PlayerInfoInterface>();
all.AddRange(team1.players);
all.AddRange(team2.players);
if (team3.players.Count > 0) all.AddRange(team3.players);
if (team4.players.Count > 0) all.AddRange(team4.players);
PlayerInfoInterface target = null;
int count = 0;
foreach (PlayerInfoInterface p in all)
{
	if (Regex.Match(p.Name, name, RegexOptions.IgnoreCase).Success)
	{
		target = p;
		++count;
		playerName = p.Name;
	}
}

String BL = "https://battlelog.battlefield.com/bf4/user/" + playerName;
if (count == 0)
{
	playerMessage = "No such player name matches (" + name + ")";
	plugin.SendPlayerMessage(player.Name, playerMessage);
	return false;
}
else if (count > 1)
{
	playerMessage = "Multiple players match the target name (" + name + "), try again!";
	plugin.SendPlayerMessage(player.Name, playerMessage);
	return false;
}
else if (count == 1)
{
	reportReason = regexResult.Groups[2].Value;
	double headshots = target.HeadshotsRound;
	double killsNOW = target.KillsRound;
	double result = Math.Round((headshots / killsNOW), 2);
	double KPM = Math.Round((target.KpmRound), 2);
	double HS = result * 100;
	double KD = Math.Round(target.KdrRound, 2);
	double Kills = target.KillsRound;
	double Deaths = target.DeathsRound;
	try
	{
		WebRequest request = WebRequest.Create(webhookUrl);
		request.Method = "POST";
		request.ContentType = "application/json";
		webhookString = "{\"content\": \"**```py\\n'Player Report'\\[email protected]" + serverName + "\\nReported_from: " + "'" + player.Name + "'" + "\\nReported_player: " + "'" + playerName + "'" + "\\nReason: " + "'" + reportReason + "'" + "\\nStats: " + "KILLS: " + Kills + " DEATHS: " + Deaths + " HS: " + HS + "%" + " KD: " + KD + " KPM: " + KPM + "\\n```**" + "BL: " + BL + "\"}";
		byte[] byteArray = Encoding.UTF8.GetBytes(webhookString);
		request.ContentLength = byteArray.Length;
		Stream dataStream = request.GetRequestStream();
		dataStream.Write(byteArray, 0, byteArray.Length);
		dataStream.Close();
		plugin.ConsoleWrite("Received a report from " + player.Name);
		playerMessage = "Thanks, we have received your report!";
		plugin.SendPlayerMessage(player.Name, playerMessage);
		plugin.SendPlayerYell(player.Name, playerMessage, 10);
	}
	catch (Exception e)
	{
		plugin.ConsoleWrite("Error: " + e);
		playerMessage = "Plugin error! Please try again later.";
		plugin.SendPlayerMessage(player.Name, playerMessage);
		plugin.SendPlayerYell(player.Name, playerMessage, 10);
	}
}

return false;

6. Custom factions
OnRoundOver
Code

String msg = "";
int Team1 = 0;
int Team2 = 0;
int i = 0;

Dictionary<int,String> Teams = new Dictionary<int,String>();
Teams.Add(0, "US");
Teams.Add(1, "RU");
Teams.Add(2, "CN");

if (server.NextGamemode == "ConquestLarge0" && server.NextGamemode != "RushLarge0") {// CQL
switch (server.NextMapFileName)
{
	case "MP_Tremors":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Siege":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Damage":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Journey":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_TheDish":	
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Prison":
		Team1 = 0;
		Team2 = 1;
		break;
	case "MP_Flooded":
		Team1 = 0;
		Team2 = 0;
		break;
	case "MP_Abandoned":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Naval":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Resort":
		Team1 = 0;
		Team2 = 2;
		break;
}
}
if (server.NextGamemode == "RushLarge0") { //RUSH
switch (server.NextMapFileName)
{
	case "MP_Tremors":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Siege":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Damage":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Journey":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_TheDish":	
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Prison":
		Team1 = 0;
		Team2 = 1;
		break;
	case "MP_Flooded":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Abandoned":
		Team1 = 1;
		Team2 = 2;
		break;
	case "MP_Naval":
		Team1 = 0;
		Team2 = 2;
		break;
	case "MP_Resort":
		Team1 = 0;
		Team2 = 2;
		break;
}
}
 //Special DLC Cases

if(server.NextMapFileName.StartsWith("XP1_")) {
	Team1 = 0;
	Team2 = 2;
}
if(server.NextMapFileName.StartsWith("XP2_")) {
	Team1 = 0;
	Team2 = 1;
}
if(server.NextMapFileName.StartsWith("XP3_")) {
	Team1 = 0;
	Team2 = 2;
}
if(server.NextMapFileName.StartsWith("XP4_")) {
	Team1 = 0;
	Team2 = 1;
}
if(server.NextMapFileName.StartsWith("XP5_Night_01")) {
	Team1 = 1;
	Team2 = 0;
}
if(server.NextMapFileName.StartsWith("XP6_CMP")) {
	Team1 = 0;
	Team2 = 2;
}
if(server.NextMapFileName.StartsWith("XP7_Valley")) {
	Team1 = 0;
	Team2 = 2;
 }


plugin.ServerCommand("vars.teamFactionOverride", "1", Convert.ToString(Team1));
plugin.ServerCommand("vars.teamFactionOverride", "2", Convert.ToString(Team2));
msg = "Setting factions to " + Teams[Team1] + " vs " + Teams[Team2] + " on next round...";

plugin.SendGlobalMessage(msg);
plugin.ConsoleWrite("^b^1ADMIN FACTIONS >^0^n " + msg);
plugin.PRoConChat("^b^1ADMIN FACTIONS >^0^n " + msg);
plugin.PRoConEvent(msg, "Insane Limits");

return false;

7. Fetch BL example
Your choice how you want, it's an example how you can fetch it without json objects. I may be wrong, but this is impossible in limits (for json). I made simple array method with regex as alternative
 

try
{
    string guid = ""; // Your server guid
    WebClient client = new WebClient();
    string json = client.DownloadString("https://keeper.battlelog.com/snapshot/" + guid);
    string[] args = json.Split(',');
    string snapshot = args[1];
    string maxPlayers = args[6];
    if (snapshot.Contains("SUCCESS"))
    {
        int players = int.Parse(Regex.Match(maxPlayers, @"\d+", RegexOptions.RightToLeft).Value); // Most of values you want are numbers and they are on right
		// Do something, it's maxPlayers value from keeper. Remember ToString() method if you want to display it     
    }
    else
    {
        plugin.ConsoleWrite("Error while trying to fetch BL");
    }    
}
catch (Exception e)
{
    plugin.ConsoleWrite("Plugin Error: " + e);
}

8. Make every player sure how to properly report someone
Examples -> cheat -> CHEATER -> ChEaTEr... etc
OnAnyChat
First Code
 

//first

List<String> hackusations = new List<String>();
	// Matching hack, hacker, hacking, hacks, wallhack etc
	hackusations.Add(@"\b(wall)?hack(er|ing|ed|s)?\b");
	// Matching cheat, cheater, cheating, cheats etc
	hackusations.Add(@"\bcheat(er|ing|ed|s)?\b");
	// Matching exploit, exploiter, exploiting, exploits etc
	hackusations.Add(@"\bexploit(er|ing|ed|s)?\b");
	// Matching glitch, glitcher, glitching etc
	hackusations.Add(@"\bglitch(er|ing|ed)?\b");
    
	string[] chat_words = Regex.Split(player.LastChat, @"[\s!\?\.]+");
	chat_words = Array.ConvertAll(chat_words, d => d.ToLower());
    
	foreach(string chat_word in chat_words)
		foreach(string word in hackusations)
			if (Regex.Match(chat_word, "^"+word+"$", RegexOptions.IgnoreCase).Success)
				return true;

	return false;

Second Code
 

string playerMessage = "Please use !report to call admins or report cheaters";

plugin.SendPlayerMessage(player.Name, player.Name + " " + playerMessage);

9. Anticheat DPS/HS/KPM (very high values) 

YOU HAVE TO enable slow fetch in insane limits options to make it working
This is rewritten script  for bf4+ I have added discord webhook option 
OnJoin
Expression

(!player.StatsError)

Code

// Revision : 5
// action taken on damage modifiers
Action<String> DamageModifierPlayer = delegate (String who) {
    // set action here default is 1 hour ban
    String message = "you have been banned for having suscpicious stats";
    plugin.EABanPlayerWithMessage(EABanType.EA_GUID, EABanDuration.Temporary, who, 60, message);
};
// action taken for blackpoint violaters
Action<String> BlackPointPlayer = delegate (String who) {
    // set action here default is 1 hour ban
    String message = "you have been banned for having suscpicious stats";
    plugin.EABanPlayerWithMessage(EABanType.EA_GUID, EABanDuration.Temporary, who, 60, message);
};
// how many black points are required for the action to be taken
int TakeAction = 20; // recommended is 20 and above Minimum is 20
                     // how many black points are required for notification to trigger
int NotifyMe = 5; // recommended above 5 and below TakeAction value
// here you can setup a notification
Action<String> NotifyMeAbout = delegate (String who) {
    // set notification here, such as email,sound notification, taskbar notification, logging etc ..
    // this is triggered for all players who have Black points above the NotifyMe value
    plugin.Log("Cheat-Log.log", plugin.R("[%date% %time%] [%server_host%] [server.Name] [player.EAGuid] " + who)); // this will log player name only with his EA GUID, still require testing
};
// options END

string webhookUrl = ""; // Add your webhook

if (limit.Activations(player.Name) != 1) return false;
if ((player.Time / 60) / 60 < 15) return false;

Dictionary<String, double> avg_HK = new Dictionary<String, double>();
// PDW
avg_HK["MX4"] = 16.55;
avg_HK["PP-2000"] = 14.14;
avg_HK["UMP45"] = 19.81;
avg_HK["CBJ-MS"] = 19.9;
avg_HK["PDR"] = 18.29;
avg_HK["Scorpion"] = 14.32;
avg_HK["JS2"] = 13.03;
avg_HK["P90"] = 14.74;
avg_HK["UMP9"] = 13.43;
avg_HK["ASVal"] = 15.99;
avg_HK["MP7"] = 16.36;
avg_HK["SR2"] = 17.58;
avg_HK["ASVal"] = 16.83;
avg_HK["MPX"] = 18.67;
avg_HK["Groza-4"] = 13.45;
// Carabines
avg_HK["AK5C"] = 16.59;
avg_HK["ACR"] = 14.33;
avg_HK["SG553LB"] = 18.41;
avg_HK["AKU-12"] = 15.58;
avg_HK["A91"] = 14.58;
avg_HK["ACE 52"] = 20.82;
avg_HK["G36C"] = 17.84;
avg_HK["M4A1"] = 18.22;
avg_HK["ACE 21"] = 16.28;
avg_HK["Type-95B-1"] = 19.43;
avg_HK["MTAR21"] = 18.67;
avg_HK["Groza-1"] = 20.28;
// Assault
avg_HK["AK12"] = 19.52;
avg_HK["SCAR-H"] = 19.77;
avg_HK["M416"] = 18.86;
avg_HK["SAR-21"] = 16.63;
avg_HK["AEK-971"] = 16.86;
avg_HK["FAMAS"] = 17.21;
avg_HK["Steyr AUG"] = 18.92;
avg_HK["M16A4"] = 17.31;
avg_HK["CZ805"] = 13.49;
avg_HK["QBZ-95"] = 21.17;
avg_HK["ACE 23"] = 16.85;
avg_HK["F2000"] = 15.29;
avg_HK["L85A2"] = 16.17;
avg_HK["AR160"] = 18.21;
avg_HK["Bulldog"] = 20.08;
avg_HK["AN94"] = 16.34;
//Support
avg_HK["Ultimax"] = 19.36;
avg_HK["Type88"] = 18.04;
avg_HK["LSAT"] = 16.42;
avg_HK["Pecheneg"] = 21.17;
avg_HK["QBB95"] = 16.38;
avg_HK["M240"] = 20.81;
avg_HK["M249"] = 18.16;
avg_HK["MG4"] = 16.44;
avg_HK["RPK-12"] = 19.25;
avg_HK["M60E4"] = 22.58;
avg_HK["RPK"] = 20.15;
avg_HK["AWS"] = 15.45;
avg_HK["L86A2"] = 17.59;
// Recon
avg_HK["CS-LR4"] = 50.26;
avg_HK["M40A5"] = 55.92;
avg_HK["Scoutelite"] = 50.62;
avg_HK["SV98"] = 52.13;
avg_HK["JNG90"] = 52.81;
avg_HK["SRS .338"] = 51.38;
avg_HK["Model98B"] = 58.18;
avg_HK["M200"] = 57.62;
avg_HK["FY-JS"] = 53.46;
avg_HK["Gol"] = 57.59;
avg_HK["L96A1"] = 59.02;
avg_HK["SR338"] = 32.06;
avg_HK["CS5"] = 51.34;
// Pistols
avg_HK["P226"] = 19.05;
avg_HK["M1911"] = 25.02;
avg_HK["M9"] = 20.56;
avg_HK["M93R"] = 18.5;
avg_HK["Taurus .44"] = 38.66;
avg_HK["QSZ92"] = 17.13;
avg_HK["MP443"] = 18.58;
avg_HK["Glock18"] = 18.57;
avg_HK["FN57"] = 18.42;
avg_HK["CZ75"] = 22.81;
avg_HK["HK45C"] = 27.67;
avg_HK["MP412Rex"] = 33.89;
avg_HK["SW40"] = 30.94;
avg_HK["Unica6"] = 28.56;
avg_HK["SaddleGun"] = 30.58;
// Dmrs
avg_HK["RFB"] = 32.98;
avg_HK["MK11"] = 32.36;
avg_HK["SKS"] = 29.36;
avg_HK["SVD-12"] = 52.13;
avg_HK["QBU88"] = 31.26;
avg_HK["M39EBR"] = 32.09;
avg_HK["GalilACE53"] = 30.41;
avg_HK["SCAR-HSV"] = 32.03;

Dictionary<String, double> norm_DPS = new Dictionary<String, double>();
// PDW
norm_DPS["MX4"] = 22.5;
norm_DPS["PP-2000"] = 22.5;
norm_DPS["UMP45"] = 30;
norm_DPS["CBJ-MS"] = 22.5;
norm_DPS["PDR"] = 24;
norm_DPS["Scorpion"] = 22.5;
norm_DPS["JS2"] = 22.5;
norm_DPS["P90"] = 21;
norm_DPS["UMP9"] = 22.5;
norm_DPS["ASVal"] = 27;
norm_DPS["MP7"] = 20;
norm_DPS["SR2"] = 23.5;
norm_DPS["ASVal"] = 27;
norm_DPS["MPX"] = 24.5;
norm_DPS["Groza-4"] = 27;
// Carabines
norm_DPS["AK5C"] = 24;
norm_DPS["ACR"] = 24;
norm_DPS["SG553LB"] = 24;
norm_DPS["AKU-12"] = 24;
norm_DPS["A91"] = 24;
norm_DPS["ACE 52"] = 33;
norm_DPS["G36C"] = 24;
norm_DPS["M4A1"] = 24;
norm_DPS["ACE 21"] = 24;
norm_DPS["Type-95B-1"] = 24;
norm_DPS["MTAR21"] = 24;
norm_DPS["Groza-1"] = 30;
// Assault
norm_DPS["AK12"] = 24.5;
norm_DPS["SCAR-H"] = 33;
norm_DPS["M416"] = 24.5;
norm_DPS["SAR-21"] = 24.5;
norm_DPS["AEK-971"] = 24.5;
norm_DPS["FAMAS"] = 24.5;
norm_DPS["Steyr AUG"] = 24.5;
norm_DPS["M16A4"] = 24.5;
norm_DPS["CZ805"] = 24.5;
norm_DPS["QBZ-95"] = 24.5;
norm_DPS["ACE 23"] = 24.5;
norm_DPS["F2000"] = 24.5;
norm_DPS["L85A2"] = 24.5;
norm_DPS["AR160"] = 24.5;
norm_DPS["Bulldog"] = 33;
norm_DPS["AN94"] = 24.5;
//Support
norm_DPS["Ultimax"] = 24.5;
norm_DPS["Type88"] = 24.5;
norm_DPS["LSAT"] = 24.5;
norm_DPS["Pecheneg"] = 33;
norm_DPS["QBB95"] = 24.5;
norm_DPS["M240"] = 33;
norm_DPS["M249"] = 24.5;
norm_DPS["MG4"] = 24.5;
norm_DPS["RPK-12"] = 24.5;
norm_DPS["M60E4"] = 33;
norm_DPS["RPK"] = 30;
norm_DPS["AWS"] = 24.5;
norm_DPS["L86A2"] = 24.5;
// Recon
norm_DPS["CS-LR4"] = 100;
norm_DPS["M40A5"] = 100;
norm_DPS["Scoutelite"] = 100;
norm_DPS["SV98"] = 100;
norm_DPS["JNG90"] = 100;
norm_DPS["SRS .338"] = 100;
norm_DPS["Model98B"] = 100;
norm_DPS["M200"] = 100;
norm_DPS["FY-JS"] = 100;
norm_DPS["Gol"] = 100;
norm_DPS["L96A1"] = 100;
norm_DPS["SR338"] = 50;
norm_DPS["CS5"] = 100;
// Pistols
norm_DPS["P226"] = 27;
norm_DPS["M1911"] = 36.6;
norm_DPS["M9"] = 27;
norm_DPS["M93R"] = 22;
norm_DPS["Taurus .44"] = 56;
norm_DPS["QSZ92"] = 22;
norm_DPS["MP443"] = 27;
norm_DPS["Glock18"] = 22;
norm_DPS["FN57"] = 22;
norm_DPS["CZ75"] = 30;
norm_DPS["HK45C"] = 36.6;
norm_DPS["MP412Rex"] = 56;
norm_DPS["SW40"] = 56;
norm_DPS["Unica6"] = 56;
norm_DPS["SaddleGun"] = 56;
// Dmrs
norm_DPS["RFB"] = 45;
norm_DPS["MK11"] = 45;
norm_DPS["SKS"] = 43;
norm_DPS["SVD-12"] = 45;
norm_DPS["QBU88"] = 43;
norm_DPS["M39EBR"] = 45;
norm_DPS["GalilACE53"] = 45;
norm_DPS["SCAR-HSV"] = 45;


List<String> cheatometer = new List<String>();
List<String> discordWeb = new List<String>();
String stuff = "";
BattlelogWeaponStatsInterface Get = null;
String DPSCOLOR = "^2";
String HSKCOLOR = "^2";
String KPMCOLOR = "^2";
String ACCCOLOR = "^2";
String BPCOLOR = "^2";
String BlackPointsCounter = player.Name + "_Weapon_BlackPoints";
String cheatedCounter = player.Name + "_Weapon_cheated";
String DPSmodifier = null;
int BlackPoints = 0;
int cheated = 0;
if (TakeAction < 20) TakeAction = 20;
if (NotifyMe >= TakeAction) NotifyMe = TakeAction - 1;

foreach (String Gun in avg_HK.Keys)
{
    Get = player.GetBattlelog(Gun);
    if (Get.Kills < 80) continue;
    Match m = Regex.Match(Gun, @"/([^/]+)$");
    String wn = Gun;
    if (m.Success) wn = m.Groups[1].Value;
    DPSCOLOR = "^2";
    HSKCOLOR = "^2";
    KPMCOLOR = "^2";
    ACCCOLOR = "^2";
    double HSmodifier = 1;
    if (avg_HK[Gun] > 25) HSmodifier = 1.2;
    double ShotsHit = Math.Round((Get.ShotsFired * (Get.Accuracy / 100)), 0);
    double DPS = Math.Round(((Get.Kills / ShotsHit) * 100), 2);
    double HeadshotsRatio = Math.Round(((Get.Headshots / Get.Kills) * 100), 2);
    double HSmodified = Math.Round(HeadshotsRatio * HSmodifier, 2);
    double MaxDPS = Math.Round((norm_DPS[Gun] * (1 + (HSmodified / 100))), 0);
    double KPM = Math.Round(Get.Kills / (Get.TimeEquipped / 60), 1);
    double Accuracy = Math.Round(Get.Accuracy, 0);
    if (DPS > (MaxDPS * 1.3) && DPS <= (MaxDPS * 1.4))
    {
        DPSCOLOR = "^3";
        server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
        if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
    }
    if (DPS > (MaxDPS * 1.4) && DPS <= (MaxDPS * 1.8))
    {
        DPSCOLOR = "^7";
        server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
        if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
    }
    if (DPS > (MaxDPS * 1.8))
    {
        DPSCOLOR = "^8";
        server.Data.setInt(cheatedCounter, 1);
    }
    if (avg_HK[Gun] <= 25)
    {
        if (DPS <= (MaxDPS * 1.3) && HeadshotsRatio < 40 && ((KPM <= 3.5 && player.Rank <= 120) || (KPM <= 4 && player.Rank > 120)) && Accuracy <= 35) continue;
        if (HeadshotsRatio >= 40 && HeadshotsRatio <= 45)
        {
            HSKCOLOR = "^3";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (HeadshotsRatio > 45 && HeadshotsRatio <= 55)
        {
            HSKCOLOR = "^7";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (HeadshotsRatio > 55)
        {
            HSKCOLOR = "^8";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 5);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 35 && Accuracy <= 40)
        {
            ACCCOLOR = "^3";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 40 && Accuracy <= 50)
        {
            ACCCOLOR = "^7";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 50)
        {
            ACCCOLOR = "^8";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
    }
    if (avg_HK[Gun] > 25)
    {
        if (DPS <= (MaxDPS * 1.3) && HeadshotsRatio < 90 && ((KPM <= 3.5 && player.Rank <= 120) || (KPM <= 4 && player.Rank > 120)) && Accuracy <= 50) continue;
        if (HeadshotsRatio >= 90 && HeadshotsRatio <= 93)
        {
            HSKCOLOR = "^3";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (HeadshotsRatio > 93 && HeadshotsRatio <= 96)
        {
            HSKCOLOR = "^7";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (HeadshotsRatio > 96)
        {
            HSKCOLOR = "^8";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 50 && Accuracy <= 60)
        {
            ACCCOLOR = "^3";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 60 && Accuracy <= 70)
        {
            ACCCOLOR = "^7";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
        if (Accuracy > 70)
        {
            ACCCOLOR = "^8";
            server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
            if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
        }
    }
    if (KPM > 5.0 && KPM <= 6.0)
    {
        KPMCOLOR = "^3";
        if (player.Rank <= 120) server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
        if (player.Rank > 120 && KPM > 4) server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
        if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
    }
    if (KPM > 6.0 && KPM <= 8.0)
    {
        KPMCOLOR = "^7";
        if (player.Rank <= 120) server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
        if (player.Rank > 120) server.Data.setInt(BlackPointsCounter, BlackPoints + 1);
        if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
    }
    if (KPM > 8.0)
    {
        KPMCOLOR = "^8";
        if (player.Rank <= 120) server.Data.setInt(BlackPointsCounter, BlackPoints + 3);
        if (player.Rank > 120) server.Data.setInt(BlackPointsCounter, BlackPoints + 2);
        if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);
    }
    cheatometer.Add("^b[" + wn + "] " + DPSCOLOR + "DPS : " + DPS + "/" + norm_DPS[Gun] + "-" + MaxDPS + " ^0|" + HSKCOLOR + " Headshot/Kill : " + HeadshotsRatio + "% ^0|" + KPMCOLOR + " Kills/minute : " + KPM + " ^0|" + ACCCOLOR + " Accuracy : " + Accuracy + "% ^0| Kills : " + Get.Kills + "^0^n");
    discordWeb.Add("[" + wn + "] " + "DPS : " + DPS + "/" + norm_DPS[Gun] + "-" + MaxDPS + " |" + " Headshot/Kill : " + HeadshotsRatio + "% |" + " Kills/minute : " + KPM + "^0^n");
}

if (cheatometer.Count == 0) return false;
if (discordWeb.Count == 0) return false;

if (server.Data.issetInt(BlackPointsCounter)) BlackPoints = server.Data.getInt(BlackPointsCounter);

if (server.Data.issetInt(cheatedCounter)) cheated = server.Data.getInt(cheatedCounter);


plugin.PRoConChat("--------------------------------------------------" + player.Name + "--------------------------------------------------");
plugin.PRoConChat("^b^2Green = normal/fine ^0| ^3Yellow = above normal ^0| ^7Pink = highly suspicious ^0 | ^8Red = 99% cheat^n^0");

foreach (String metered in cheatometer)
{
    plugin.PRoConChat(metered);
}
foreach (String boi in discordWeb)
{
    stuff = (boi);
}

if (cheated == 1)
{
    DamageModifierPlayer(player.Name);
    DPSmodifier = " ^8^b, player is damage modifier and is banned^0^n";
}

if (BlackPoints >= 1)
{
    // add any action for notifying.
    plugin.ConsoleWrite("^3^b[Evaluating]^0^n " + player.Name + " has " + BlackPoints + " Black Points");
    if (BlackPoints > 5 && BlackPoints <= 10) BPCOLOR = "^3";
    if (BlackPoints > 10 && BlackPoints <= 15) BPCOLOR = "^7";
    if (BlackPoints > 10)
    {
        try
        {
            WebRequest request = WebRequest.Create(webhookUrl);
            request.Method = "POST";
            request.ContentType = "application/json";
            String BL = "https://battlelog.battlefield.com/bf4/user/" + player.Name;
            string webhookString = "{\"content\": \"**```py\\n'HS/DMG Detection'\\n" + "\\nSuspicious Player: " + "'" + player.Name + "'" + "\nPoints: " + BlackPoints + "\n" + stuff + "\\n```**" + "BL: " + BL + "\"}";
            byte[] byteArray = Encoding.UTF8.GetBytes(webhookString);
            request.ContentLength = byteArray.Length;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
        }
        catch (Exception e)
        {
            plugin.PRoConChat("Error with posting: " + e.ToString());
            plugin.ConsoleWrite("Error with posting: " + e.ToString());
        }
    }
    if (BlackPoints > 15) BPCOLOR = "^8";
    if (BlackPoints >= TakeAction && cheated == 0)
    {
        BlackPointPlayer(player.Name);
    }
    if (BlackPoints <= 15 && cheated >= 0) plugin.PRoConChat(player.Name + " has " + BPCOLOR + BlackPoints + "^0^n black points" + DPSmodifier);
    if (BlackPoints > 15 && BlackPoints < TakeAction && cheated == 1) plugin.PRoConChat(player.Name + " has " + BPCOLOR + BlackPoints + "^0^n black points" + DPSmodifier);
    if (BlackPoints > 15 && BlackPoints < TakeAction && cheated == 0) plugin.PRoConChat(player.Name + " has " + BPCOLOR + BlackPoints + "^0^n black points, please investigate the player.");
    if (BlackPoints >= TakeAction && cheated == 1) plugin.PRoConChat(player.Name + " has " + BPCOLOR + BlackPoints + "^0^n black points" + DPSmodifier);
    if (BlackPoints >= TakeAction && cheated == 0) plugin.PRoConChat(player.Name + " has " + BPCOLOR + BlackPoints + " black points and is banned");
    plugin.SendTaskbarNotification("warning", "cheatmeter");
}
if (BlackPoints >= NotifyMe)
{
    NotifyMeAbout(player.Name);
    plugin.Log("cheat-log.log", "--------------------------------------------------" + player.Name + "--------------------------------------------------");
    foreach (String metered in cheatometer)
    {
        plugin.Log("cheat-log.log", metered);
    }
}
return false;


10. Very Basic HS live bans
It may get some false bans so I would recommend using adakts for that, however this is a simple example
OnKill
Code

int minKills = 15;

double playerKdr = Math.Round(player.KillsRound / player.DeathsRound, 2);
double playerKpm = Math.Round(player.KillsRound / (player.TimeRound / 60), 2);
string playerName = player.Name;
string discordPlayerName = playerName.Replace("_", "\\_");
double headshots = player.HeadshotsRound;
double killsNOW = player.KillsRound;
double result = Math.Round((headshots / killsNOW), 2);
result = result * 100;

string webhookUrl = ""; // Your webhook 


if ((killer.KillsRound >= minKills) && (killer.KpmRound > 2.0) && (result >= 70))
    {
	using (WebClient webClient = new WebClient())
        {
            try
            {
            string battlelogLink = "https://battlelog.battlefield.com/bf4/user/" + player.Name;
            WebRequest request = WebRequest.Create(webhookUrl);
            request.Method = "POST";
            request.ContentType = "application/json";
            string webhookString = "{\"username\": \"BF4 Report\", \"content\": \"**```diff\\n | New Report | ```**\\n**Report for server:** " + server.Name + "\\n**Reported from:** Stats checker" + "\\n**Reported player:** " + discordPlayerName + "\\n**Reason:** Cheating " + player.Kills +"/"+player.Deaths + " HS [" + result + "%]" + "\\n**Info: **" + plugin.FriendlyMapName(server.MapFileName) + "\\n**Battlelog:** " + battlelogLink + "\"}";
            byte[] byteArray = Encoding.UTF8.GetBytes(webhookString);
            request.ContentLength = byteArray.Length;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
            } catch (Exception ee)
            {
                plugin.ConsoleWrite("Error: " + ee.ToString());
            }
    	}
		plugin.PBBanPlayerWithMessage(PBBanDuration.Permanent, player.Name, 0, "You are banned for HS automatic ban "+ "[" + result + "%]");
		plugin.ConsoleWrite("^b^1Auto HS >^0^n " + player.Name + "banned for HS automatic");
		plugin.PRoConChat("^b^1Auto HS >^0^n " + player.Name + "banned for HS automatic");
        }
    

And again for any questions or errors please write them here or find me on discord Bartis#1313

Share this post


Link to post

Another fix, I have spotted that I forgot to edit the string from discordWeb list I added, here is the fixed code
 

foreach (string fetched in discordWeb)
{
    result.Add(fetched);
}

string final = string.Join("\\n", result);

if (BlackPoints >= 8)
{
    try
    {
        WebRequest request = WebRequest.Create(webhookUrl);
        request.Method = "POST";
        request.ContentType = "application/json";
        string BL = "https://battlelog.battlefield.com/bf4/user/" + player.Name;
        string webhookString = "{\"content\": \"**```py\\n'HS/DMG/KPM'\\[email protected]" + server.Name + "\\nPlayer: " + "'" + player.Name + "'" + "\\nPoints: " + BlackPoints + "\\n\\n" + final +  "\\n```**" + "BL: " + BL + "\"}";
        byte[] byteArray = Encoding.UTF8.GetBytes(webhookString);
        request.ContentLength = byteArray.Length;
        Stream dataStream = request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();
        plugin.ConsoleWrite("Post to webhook...");
    }
    catch (Exception e)
    {
        plugin.ConsoleWrite(e.ToString());
    }
}

string final should stay a global variable, and you can move this whole try catch block with code to statement at the end with NotifyMe variable 

result is list, it's:
 

List<String> result = new List<String>();

so remove: 
 

foreach (String boi in discordWeb)
{
    stuff = (boi);
}

and replace it with what is on the top of my fixed code

Edited by Bartis11313
better explanation

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Our picks

    • Added ability to disable the new API check for player country info


      Updated GeoIP database file


      Removed usage sending stats


      Added EZRCON ad banner



      If you are upgrading then you may need to add these two lines to your existing installation in the file procon.cfg. To enable these options just change False to True.

      procon.private.options.UseGeoIpFileOnly False
      procon.private.options.BlockRssFeedNews False



       
      • 1 reply
    • I wanted I let you know that I am starting to build out the foundation for the hosting services that I talked about here. The pricing model I was originally going for wasn't going to be suitable for how I want to build it. So instead I decided to offer each service as it's own product instead of a package deal. In the future, hopefully, I will be able to do this and offer discounts to those that choose it.

      Here is how the pricing is laid out for each service as well as information about each. This is as of 7/12/2020.

      Single MySQL database (up to 30 GB) is $10 USD per month.



      If you go over the 30 GB usage for the database then each additional gigabyte is charged at $0.10 USD each billing cycle. If you're under 30GB you don't need to worry about this.


      Databases are replicated across 3 zones (regions) for redundancy. One (1) on the east coast of the USA, One (1) in Frankfurt, and One (1) in Singapore. Depending on the demand, this would grow to more regions.


      Databases will also be backed up daily and retained for 7 days.




      Procon Layer will be $2 USD per month.


      Each layer will only allow one (1) game server connection. The reason behind this is for performance.


      Each layer will also come with all available plugins installed by default. This is to help facilitate faster deployments and get you up and running quickly.


      Each layer will automatically restart if Procon crashes. 


      Each layer will also automatically restart daily at midnight to make sure it stays in tip-top shape.


      Custom plugins can be installed by submitting a support ticket.




      Battlefield Admin Control Panel (BFACP) will be $5 USD per month


      As I am still working on building version 3 of the software, I will be installing the last version I did. Once I complete version 3 it will automatically be upgraded for you.





      All these services will be managed by me so you don't have to worry about the technical side of things to get up and going.

      If you would like to see how much it would cost for the services, I made a calculator that you can use. It can be found here https://ezrcon.com/calculator.html

       
      • 10 replies
    • I have pushed out a new minor release which updates the geodata pull (flags in the playerlisting). This should be way more accurate now. As always, please let me know if any problems show up.

       
      • 9 replies
×
×
  • Create New...

Important Information

Please review our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.