Jump to content

Bartis11313

Members
  • Content Count

    6
  • Joined

  • Last visited

About Bartis11313

  • Rank
    Newbie

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. 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
  2. use IL, limits can read live tickets. public interface TeamInfoInterface { List<PlayerInfoInterface> players { get; } double KillsRound { get; } double DeathsRound { get; } double SuicidesRound { get; } double TeamKillsRound { get; } double TeamDeathsRound { get; } double HeadshotsRound { get; } double ScoreRound { get; } int TeamId { get; } double Tickets { get; } double RemainTickets { get; } double RemainTicketsPercent { get; } double StartTickets { get; } // BF4 int Faction { get; } // US = 0, RU = 1, CN = 2 } is from docs. You can check my big thread where I used RemainTicketsPercent thing, you would use just Tickets for your case. And going >400% tickets is possible only non public servers. rcon can't read flags or anything related to it, just tickets but that wouldn't be accurate since respawns can -1... tickets
  3. In 2. script I made a typo, change vip check to: if (!plugin.GetReservedSlotsList().Contains(player.Name)) return false;
  4. 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
  5. I am the author Working code: First check - Code Evaluation - OnKill Put your discord webhook channel string to make it working for your discord ////////////////////////////// // ingame kd farm limit ////////////////////////////// // SETTINGS: // set max intern KDR int maxKDR = 7; double maxKPM = 2.5; double warnKDR = maxKDR * 0.9; double warnKPM = maxKPM * 0.9; // set min kills int minKills = 30; // set max warn messages before kick int warnPlayer = 5; double playerKdr = Math.Round (player.KillsRound / player.DeathsRound, 2, MidpointRounding.AwayFromZero); double playerKpm = Math.Round (player.KillsRound / (player.TimeRound / 60), 2, MidpointRounding.AwayFromZero); string playerName = player.Name; string discordPlayerName = playerName.Replace ("_", "\\_"); bool useWhitelist = true; string webhookUrl = ""; // SETTINGS END ////////////////////////////// if (minKills > killer.KillsRound) return false; if (useWhitelist && plugin.GetReservedSlotsList ().Contains (player.Name)) return false; String kCounterWarn = killer.Name + "_killx_Count_Warn"; int showWarnings = 0; if (server.RoundData.issetInt (kCounterWarn)) showWarnings = server.RoundData.getInt (kCounterWarn); if (killer.KillsRound >= minKills && ((killer.KdrRound > warnKDR) || (killer.KpmRound > warnKPM))) { showWarnings++; server.RoundData.setInt (kCounterWarn, showWarnings); if ((showWarnings <= warnPlayer)) { String globalMessage = killer.Name + " your current round KD or KPM is too high!"; if (showWarnings + 2 >= warnPlayer) { globalMessage = globalMessage + " Change your play style / vehicle"; } if (showWarnings == 1) { plugin.PRoConChat ("^1^bKILL-FARM-LIMIT:^1^n " + killer.Name + " first warning - (DEBUG: kdr: " + playerKpm + ")"); } if (showWarnings == 1) { plugin.PRoConChat ("^1^bKILL-FARM-LIMIT:^1^n " + killer.Name + " first warning - (DEBUG: kpm: " + playerKpm + ")"); } plugin.SendPlayerYell (killer.Name, "[KILL-FARM-LIMIT] [WARNING]\n" + globalMessage, 5); plugin.SendPlayerMessage (killer.Name, "KILL-FARM-LIMIT: [WARNING] " + globalMessage + " (max. round KD: " + maxKDR + "max. round KPM: " + maxKPM + ")"); } } if ((killer.KillsRound >= minKills) && (killer.KdrRound > maxKDR)) { plugin.ConsoleWrite ("^8^bKDR LIMIT:^8^n " + killer.Name + " KICKED for KDR. (" + plugin.FriendlyMapName (server.MapFileName) + " - K/D: " + killer.KillsRound + "/" + killer.DeathsRound + " - (DEBUG: kdr: " + playerKdr + ")"); plugin.PRoConChat ("^8^bKDR LIMIT:^8^n " + killer.Name + " KICKED for KDR. (" + plugin.FriendlyMapName (server.MapFileName) + " - K/D: " + killer.KillsRound + "/" + killer.DeathsRound + " - (DEBUG: kdr: " + playerKdr + ")"); plugin.KickPlayerWithMessage (killer.Name, plugin.R ("Kicked by KDR Limit Vip is whitelisted")); using (WebClient webClient = new WebClient ()) { 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:** High KDR " + playerKdr + "\\n**Info: **" + plugin.FriendlyMapName (server.MapFileName) + " mode" + plugin.FriendlyModeName (server.NextGamemode) +"\\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 (); } } if ((killer.KillsRound >= minKills) && (killer.KpmRound > maxKPM)) { plugin.ConsoleWrite ("^8^bKPM LIMIT:^8^n " + killer.Name + " KICKED for KDR. (" + plugin.FriendlyMapName (server.MapFileName) + " - KPM: " + playerKpm + ")"); plugin.PRoConChat ("^8^bKPM LIMIT:^8^n " + killer.Name + " KICKED for KDR. (" + plugin.FriendlyMapName (server.MapFileName) + " - KPM: " + playerKpm + ")"); plugin.KickPlayerWithMessage (killer.Name, plugin.R ("Kicked by KPM Limit Vip is whitelisted")); using (WebClient webClient = new WebClient ()) { 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:** High KPM " + playerKpm + "\\n**Info: **" + plugin.FriendlyMapName (server.MapFileName) + " mode" + plugin.FriendlyModeName (server.NextGamemode) + "\\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 (); } }
  6. Custom settings on round over This allows you to use custom tickrate/tickets per game mode or per map, the code has all in one to see examples first check - Code evaluation - OnRoundOver int tickets = 100; int health = 100; int delay = 100; int bleed = 100; int tickrate = 40; 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 (3 * 1000); if (server.NextMapFileName == "MP_Prison") { //tickrate per map 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]"); } 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 = 215; } if (server.PlayerCount >= 45) { tickets = 300; } 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; Another script: Custom map by command Usage is simple, use simple regex I have put in the code so: !map dawn cql = accept (next map is Dawnbreaker with Conquest Large 1 round) Special case: !map dawn cql 2 = accept (next map is Dawnbreaker with Conquest Large 2 rounds) You may find it useful on servers without votemap, votemap can trigger the change ! So be aware of it and if you use votemap then write the command after the vote is done REMEMBER !!! Use code below map stuff for const index number to don't make your index from 10 to 20 for example... First code: map command first check - Code evaluation - OnAnyChat //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); List<String> vips = plugin.GetReservedSlotsList (); if (!vips.Contains (player.Name)) { plugin.SendPlayerMessage (player.Name, "You Can't use this command."); 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"); } Index check for map command: First check - code evaluation - OnRoundStart (no idea why those 2 starting methods don't work... in normal C# it work well) /*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 ()); Check player stats by command (regex also) usage: !check Bartis Evaluation - OnAnyChat First check - 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 + "."); } Send reports through discord webhook using WebClient C# Paste your channel discord webhook string to get it working on discord! Also script working with regex Usage: !report Bartis killing team Evaluation - OnAnyChat first check - Expression (Regex.Match(player.LastChat, @"[/[email protected]]report" ,RegexOptions.IgnoreCase).Success) Second Check - Code string webhookUrl = ""; 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; } double counter = limit.Activations(player.Name, TimeSpan.FromSeconds(60)); if(counter >1) { playerMessage = "Too many reports! Try again in 1min"; 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; Last script: Custom factions per map Evaluation - OnAnyChat first check - 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, 12); plugin.ConsoleWrite("^b^1ADMIN FACTIONS >^0^n " + msg); plugin.PRoConChat("^b^1ADMIN FACTIONS >^0^n " + msg); plugin.PRoConEvent(msg, "Insane Limits"); return false; Consider switching to C# switch cases, I made "if" because the dlcs map factions are the same on each DLC and I was also too lazy Use any script you would like to... For bugs add me on discord (Bartis#1313) or write them here
×
×
  • 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.