• 2 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Release Unbanner
#1
Hi again guys/girls,

To introduce this plugin a little bit I will start with a brief story, essentially I have found unbanning players while in-game is quite difficult and doesn't actually work for me most of the time so I thought why not create a small plugin that allows players to be unbanned while you're in game by using their XUID or name.

The plugin works by making use of the server command "unban" which as I said doesn't always work as it should and it also has some extra functionality that will manually edit the bans file for you if the server command file to remove it automatically, now you have nothing to worry about if you do use this plugin as I have put in error handing and checks to ensure the current file on the server gets backed up to prevent unexpected behavior while using the plugin.

In a nutshell this is how it works:
  • The client uses the !unban command, E.g. !unban <player name>
  • The plugin then opens the bans list file and extracts all the XUIDs and player names from it
  • Once an array of valid players are found the XUID or player name given is matched against those players
  • The server command unban then gets run
  • An extra check gets run after the server command that ensures the player has been unbanned otherwise it will manually execute a function that removes the player from the banned players file

Like I said before if a manual removal has to be executed your currently active bans file will be backed up in a folder called "bans_backup" to ensure server admins can easily rollback any changes that have recently been made, the backup files are marked with the date and time of the command execution so you can find the latest one easier.

Usage:
Code:
!unban <player name>
!unban <player xuid>
!unbanc <ban id>
!banlist <player name>
!undolast

Examples:
!unban SgtLegend
!unban 01100000000000aa
!unbanc 0
!banlist leg

NOTE: When using the player name you don't need to type it completely as it will attempt to guess the player you're talking about.

Changelog:

Credits:
@Nukem - For such a great code base to work with
@Pozzuh - For the permissions plugin

Source:
CSHARP Code
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using Addon;
  5.  
  6. namespace Unbanner
  7. {
  8. public class Unbanner : CPlugin
  9. {
  10. public delegate void Del(KeyValuePair<int, string> player);
  11.  
  12. // The array were all the bans will be stored
  13. public Dictionary<int, string> bans = new Dictionary<int, string>();
  14. public Dictionary<int, string> players = new Dictionary<int, string>();
  15.  
  16. // General variables
  17. public string player;
  18. public ServerClient client;
  19. public string[] lastPlayer;
  20.  
  21. /// <summary>
  22. /// Executes when the MW3 server starts up
  23. /// </summary>
  24. public override void OnServerLoad()
  25. {
  26. ServerPrint("Unbanner plugin loaded. Author: SgtLegend. Version 1.2");
  27. }
  28.  
  29. /// <summary>
  30. /// Listens for when a client types in the chat, currently it listens for "!unban, !unbanc, !banlist"
  31. /// which is a pre-defined chat command that can be assigned using the permissions plugin otherwise
  32. /// everyone will be able to use it.
  33. /// </summary>
  34. /// <param name="Message"></param>
  35. /// <param name="Client"></param>
  36. /// <param name="Teamchat"></param>
  37. /// <returns></returns>
  38. public override ChatType OnSay(string Message, ServerClient Client, bool Teamchat)
  39. {
  40. // Set the client
  41. client = Client;
  42.  
  43. // Split the contents of the message
  44. string[] split = Message.Split(' ');
  45.  
  46. // Get all of the currently banned players
  47. try
  48. {
  49. getBanFileContents();
  50. }
  51. catch (Exception e)
  52. {
  53. TellClient(Client.ClientNum, "^1An error occurred while trying to open the banned players list!", true);
  54. return ChatType.ChatNone;
  55. }
  56.  
  57. // Check if there are any banned players in the file
  58. if (bans.Count == 0)
  59. {
  60. TellClient(Client.ClientNum, "^1No players were found to be banned on the server", true);
  61. return ChatType.ChatNone;
  62. }
  63.  
  64. #region !unbanc
  65. if (Message.StartsWith("!unbanc"))
  66. {
  67. // Do we have enough arguments?
  68. if (split.Length < 2)
  69. {
  70. TellClient(Client.ClientNum, "^1Usage: ^7!unbanc <ban ID>", true);
  71. return ChatType.ChatNone;
  72. }
  73.  
  74. // Check if a valid ban ID was entered
  75. int banID = -1;
  76.  
  77. if (Int32.TryParse(split[1], out banID) && bans.ContainsKey(banID))
  78. {
  79. playerMatchedToXUIDOrName(bans[banID]);
  80. }
  81. else
  82. {
  83. TellClient(Client.ClientNum, "^1Please enter a valid ban ID!", true);
  84. }
  85.  
  86. return ChatType.ChatNone;
  87. }
  88. #endregion
  89.  
  90. #region !unban
  91. if (Message.StartsWith("!unban"))
  92. {
  93. // Do we have enough arguments?
  94. if (split.Length < 2)
  95. {
  96. TellClient(Client.ClientNum, "^1Usage: ^7!unban <player name> ^1OR ^7!unban <xuid>", true);
  97. return ChatType.ChatNone;
  98. }
  99.  
  100. // Check if the player XUID/Name entered is valid
  101. if (string.IsNullOrEmpty(split[1]))
  102. {
  103. TellClient(Client.ClientNum, "^1Please enter a valid XUID/Player name!", true);
  104. return ChatType.ChatNone;
  105. }
  106. else
  107. {
  108. player = split[1];
  109. }
  110.  
  111. // Now the fun part, we need to assume the client who entered this command hasn't used a full
  112. // player name so we need to ensure there is only one client otherwise alert him/her to add
  113. // more characters to the name or use the XUID
  114. checkPlayerAgainstBansList(
  115. 2,
  116. "^5Multiple clients were found, please try to be more specific!",
  117. 1,
  118. playerMatchedToXUIDOrName
  119. );
  120.  
  121. return ChatType.ChatNone;
  122. }
  123. #endregion
  124.  
  125. #region !undolast
  126. if (Message.StartsWith("!undolast"))
  127. {
  128. string message;
  129.  
  130. if (lastPlayer != null)
  131. {
  132. message = modifyBansFile(lastPlayer, true) ?
  133. "^2The player ^7" + lastPlayer[1] + " ^2has been banned again successfully!" :
  134. "^1The player ^7" + lastPlayer[1] + " ^1couldn't be banned again due to an error!";
  135.  
  136. // Reset the last player variable
  137. lastPlayer = null;
  138. }
  139. else
  140. {
  141. message = "^:You haven't unbanned anyone recently!";
  142. }
  143.  
  144. TellClient(Client.ClientNum, message, true);
  145. return ChatType.ChatNone;
  146. }
  147. #endregion
  148.  
  149. #region !banlist
  150. if (Message.StartsWith("!banlist"))
  151. {
  152. // Do we have enough arguments?
  153. if (split.Length < 2)
  154. {
  155. TellClient(Client.ClientNum, "^1Usage: ^7!banlist <filter name>. ^2E.g. ^3!banlist Sgt", true);
  156. return ChatType.ChatNone;
  157. }
  158.  
  159. // Check if the player XUID/Name entered is valid
  160. if (string.IsNullOrEmpty(split[1]) || split[1].Length < 2)
  161. {
  162. TellClient(Client.ClientNum, "^1Please enter at least 2 characters for the search!", true);
  163. return ChatType.ChatNone;
  164. }
  165. else
  166. {
  167. player = split[1];
  168. }
  169.  
  170. // Now the fun part, we need to ensure the characters the client entered match a player in the
  171. // the bans list, if 3 or more clients are found let the client know they need to adjust the
  172. // search criteria to be more specific
  173. checkPlayerAgainstBansList(
  174. 4,
  175. "^5More then 3 clients were found, please adjust your search criteria to be more specific!",
  176. 3,
  177. playerMatchedToName
  178. );
  179.  
  180. return ChatType.ChatNone;
  181. }
  182. #endregion
  183.  
  184. return ChatType.ChatContinue;
  185. }
  186.  
  187. /// <summary>
  188. /// Collects the file contents for "main/permanent.ban"
  189. /// </summary>
  190. private void getBanFileContents()
  191. {
  192. // Clear the current bans list
  193. bans.Clear();
  194.  
  195. // Open a new file stream to the bans file
  196. StreamReader file = new StreamReader(@"main\permanent.ban");
  197. string line;
  198. int counter = 0;
  199.  
  200. while ((line = file.ReadLine()) != null)
  201. {
  202. if (!string.IsNullOrEmpty(line))
  203. {
  204. bans.Add(counter, string.Join(":", line.Split(' ')));
  205. counter++;
  206. }
  207. }
  208.  
  209. // Close the file stream
  210. file.Close();
  211. }
  212.  
  213. /// <summary>
  214. /// Checks the found player against the known bans
  215. /// </summary>
  216. /// <param name="totalClients"></param>
  217. /// <param name="totalClientsMessage"></param>
  218. /// <param name="totalForList"></param>
  219. /// <param name="callback"></param>
  220. private void checkPlayerAgainstBansList(int totalClients, string totalClientsMessage, int totalForList, Del callback)
  221. {
  222. // Clear the players list
  223. players.Clear();
  224.  
  225. foreach (KeyValuePair<int, string> ban in bans)
  226. {
  227. string[] _player = ban.Value.Split(':');
  228.  
  229. if (_player[0] == player || _player[1].ToLower() == player.ToLower() || _player[1].ToLower().Contains(player.ToLower()))
  230. {
  231. players.Add(ban.Key, ban.Value);
  232. }
  233. }
  234.  
  235. // Is there more than the total amount of players we can display?
  236. if (players.Count >= totalClients)
  237. {
  238. TellClient(client.ClientNum, totalClientsMessage, true);
  239. }
  240.  
  241. // Do we have at least one matched player?
  242. else if (players.Count > 0 && players.Count <= totalForList)
  243. {
  244. foreach (KeyValuePair<int, string> player in players)
  245. {
  246. callback(player);
  247. }
  248. }
  249.  
  250. // No players have been matched
  251. else
  252. {
  253. TellClient(client.ClientNum, "^1No players matched your query!", true);
  254. }
  255. }
  256.  
  257. /// <summary>
  258. /// Attempts to unban the specified player from the server
  259. /// </summary>
  260. /// <param name="player"></param>
  261. /// <returns></returns>
  262. private void playerMatchedToXUIDOrName(KeyValuePair<int, string> player)
  263. {
  264. playerMatchedToXUIDOrName(player.Value);
  265. }
  266.  
  267. /// <summary>
  268. /// Attempts to unban the specified player from the server
  269. /// </summary>
  270. /// <param name="player"></param>
  271. private void playerMatchedToXUIDOrName(string player)
  272. {
  273. // Split the player details
  274. string[] _player = player.Split(':');
  275.  
  276. // Attempt to unban the player
  277. ServerCommand("unban " + _player[1]);
  278.  
  279. // Confirm the user was unbanned from the server
  280. string message = confirmPlayerWasUnbanned(_player) ?
  281. "^2The player ^7" + _player[1] + " ^2has been unbanned!" :
  282. "^1The player ^7" + _player[1] + " ^1couldn't be unbanned due to an error!";
  283.  
  284. TellClient(client.ClientNum, message, true);
  285. }
  286.  
  287. /// <summary>
  288. /// Lists out all the banned players by there banned ID, this allows for players to be unbanned very
  289. /// quickly using the !unbanc command
  290. /// </summary>
  291. private void playerMatchedToName(KeyValuePair<int, string> player)
  292. {
  293. TellClient(client.ClientNum, string.Format("^1Ban ID: ^7{0} ^:| ^1Player: ^7{1}", player.Key.ToString(), player.Value.Split(':')[1]), true);
  294. }
  295.  
  296. /// <summary>
  297. /// Gets the contents of the ban file and confirms the specified user was unbanned otherwise manual
  298. /// action on the file will be taken out to ensure the user gets unbanned.
  299. /// </summary>
  300. /// <param name="player"></param>
  301. /// <returns></returns>
  302. private bool confirmPlayerWasUnbanned(string[] player)
  303. {
  304. // Get all of the currently banned players
  305. getBanFileContents();
  306.  
  307. if (bans.Count > 0)
  308. {
  309. foreach (KeyValuePair<int, string> ban in bans)
  310. {
  311. string[] _player = ban.Value.Split(':');
  312.  
  313. if (_player[0] == player[0] && _player[1] == player[1] && modifyBansFile(player, false))
  314. {
  315. return true;
  316. }
  317. }
  318. }
  319.  
  320. return false;
  321. }
  322.  
  323. /// <summary>
  324. /// Manually attempts to modify the bans file to either remove or add a player
  325. /// </summary>
  326. /// <param name="player"></param>
  327. /// <param name="ban"></param>
  328. /// <returns></returns>
  329. private bool modifyBansFile(string[] player, bool ban)
  330. {
  331. string type = (ban) ? "banned" : "unbanned";
  332.  
  333. // Before we do anything lets make sure a backup of the current file exists so server admins
  334. // can easily roll back any changes
  335. if (!Directory.Exists("bans_backup"))
  336. {
  337. Directory.CreateDirectory("bans_backup");
  338. }
  339.  
  340. try
  341. {
  342. // File paths
  343. string inptuFileName = @"main\permanent.ban";
  344. string backupFileName = string.Format(@"bans_backup\permanent_{0:dd_MM_yyyy_HH_mm_ss}.ban", DateTime.Now);
  345.  
  346. // Backup the bans file now
  347. File.Copy(inptuFileName, backupFileName, false);
  348.  
  349. // Unban the player
  350. if (!ban)
  351. {
  352. string tempFileName = Path.GetTempFileName();
  353.  
  354. try
  355. {
  356. using (StreamReader streamReader = new StreamReader(inptuFileName))
  357. {
  358. using (StreamWriter streamWriter = new StreamWriter(tempFileName, true))
  359. {
  360. string line;
  361.  
  362. while ((line = streamReader.ReadLine()) != null)
  363. {
  364. if (!string.IsNullOrEmpty(line) && !line.Contains(player[0]) && !line.Contains(player[1]))
  365. streamWriter.WriteLine(line);
  366. }
  367. }
  368. }
  369.  
  370. // Overwrite the current bans file with the temporary file
  371. File.Copy(tempFileName, inptuFileName, true);
  372.  
  373. // Delete the temporary file that was just created
  374. File.Delete(tempFileName);
  375.  
  376. // Set the last player so the unban can be reverted after
  377. lastPlayer = player;
  378.  
  379. return true;
  380. }
  381. catch (Exception)
  382. {
  383. TellClient(client.ClientNum, "^1The player ^7" + player[1] + " ^1couldn't be unbanned due to an error!", true);
  384. }
  385. }
  386. else
  387. {
  388. try
  389. {
  390. using (StreamWriter file = new StreamWriter(inptuFileName, true))
  391. {
  392. file.WriteLine(player[0] + " " + player[1]);
  393. }
  394.  
  395. return true;
  396. }
  397. catch (Exception)
  398. {
  399. return false;
  400. }
  401. }
  402. }
  403. catch (Exception)
  404. {
  405. TellClient(client.ClientNum, "^1An error occurred while attempting to backup the bans file, the player ^7" + player[1] + " ^1can't be " + type + " at this time!", true);
  406. }
  407.  
  408. return false;
  409. }
  410. }
  411. }


Thanks for reading and hope you enjoy it!

.zip   Unbanner-v1.2.zip (Size: 4.46 KB / Downloads: 160)
.zip   Unbanner-v1.1.zip (Size: 4.17 KB / Downloads: 28)
.zip   Unbanner-v1.0.zip (Size: 3.44 KB / Downloads: 15)
I now host all my MW3 projects on my private GIT repo
[-] The following 12 users say Thank You to SgtLegend for this post:
  • 4nonymous, 8q4s8, 99IRock, Arteq, DidUknowiPwn, JariZ, moosa67, Nekochan, Nukem, OzonE, Pozzuh, surtek
  Reply
#2
useful plugin for the people who don't know where the ban file is. Tongue
This won't remove a tempban/rcon kick, right?
Good job though
[-] The following 1 user says Thank You to 8q4s8 for this post:
  • SgtLegend
  Reply
#3
(01-11-2013, 18:29)8q4s8 Wrote: useful plugin for the people who don't know where the ban file is. Tongue

I designed it so non server owners can unban clients without needing direct access to the bans file.

(01-11-2013, 18:29)8q4s8 Wrote: This won't remove a tempban/rcon kick, right?

No, temp bans are of course time based there for there is no reason for them to be removed as that would defeat the purpose of having them.
I now host all my MW3 projects on my private GIT repo
  Reply
#4
(01-11-2013, 19:31)SirGravzy Wrote: Nice job, maybe you could also add a !banlist command which shows the current banned player and also give each name a number, so instead of using a name then can type !unban 98 and it will unban the 98th player.

Nice job again Smile

That's actually a great idea, I will add that in the next update.
I now host all my MW3 projects on my private GIT repo
[-] The following 1 user says Thank You to SgtLegend for this post:
  • JariZ
  Reply
#5
(01-11-2013, 19:31)SirGravzy Wrote: Nice job, maybe you could also add a !banlist command which shows the current banned player and also give each name a number, so instead of using a name then can type !unban 98 and it will unban the 98th player.

Nice job again Smile

Cool idea but how do you want to display 100 names at once? Even 10 at once would be huge and it would still take a lot of time to finish displaying 100. Maybe it is better to display the latest 10 or something like: !banlist <first_character>. This will display all players that are banned with that first character.
  Reply
#6
(01-11-2013, 21:05)surtek Wrote:
(01-11-2013, 19:31)SirGravzy Wrote: Nice job, maybe you could also add a !banlist command which shows the current banned player and also give each name a number, so instead of using a name then can type !unban 98 and it will unban the 98th player.

Nice job again Smile

Cool idea but how do you want to display 100 names at once? Even 10 at once would be huge and it would still take a lot of time to finish displaying 100. Maybe it is better to display the latest 10 or something like: !banlist <first_character>. This will display all players that are banned with that first character.

Already thought about that and the requirement will be at least 2 characters, if more then 3 names are matched you will be asked to enter at least another 2 characters to get the results down and keep getting asked until the results are more generalized to the player you're searching for.
I now host all my MW3 projects on my private GIT repo
[-] The following 1 user says Thank You to SgtLegend for this post:
  • surtek
  Reply
#7
(01-11-2013, 21:05)surtek Wrote:
(01-11-2013, 19:31)SirGravzy Wrote: Nice job, maybe you could also add a !banlist command which shows the current banned player and also give each name a number, so instead of using a name then can type !unban 98 and it will unban the 98th player.

Nice job again Smile

Cool idea but how do you want to display 100 names at once? Even 10 at once would be huge and it would still take a lot of time to finish displaying 100. Maybe it is better to display the latest 10 or something like: !banlist <first_character>. This will display all players that are banned with that first character.

I don't always play CoD, but when I do, I like my HUD covered in text.

Anyways, another thing to think about is players who have Russian, Asian, etc names that don't show up correctly on some systems.

EDIT:
For example : Òîâàðèù Õðóùåâ (idk who it is, they've connected to my server though). I've never had to ban someone with a name with the characters above which in my opinion is surprising.
  Reply
#8
(01-11-2013, 21:30)yokai134 Wrote:
(01-11-2013, 21:05)surtek Wrote:
(01-11-2013, 19:31)SirGravzy Wrote: Nice job, maybe you could also add a !banlist command which shows the current banned player and also give each name a number, so instead of using a name then can type !unban 98 and it will unban the 98th player.

Nice job again Smile

Cool idea but how do you want to display 100 names at once? Even 10 at once would be huge and it would still take a lot of time to finish displaying 100. Maybe it is better to display the latest 10 or something like: !banlist <first_character>. This will display all players that are banned with that first character.

I don't always play CoD, but when I do, I like my HUD covered in text.

Anyways, another thing to think about is players who have Russian, Asian, etc names that don't show up correctly on some systems.

Windows servers are usually pretty good with handling characters in UTF-8 so it shouldn't be an issue but for those who like to run their server on linux using wine it may be a bit of an issue since it doesn't come pre-packaged with all the latin1 character sets.
I now host all my MW3 projects on my private GIT repo
  Reply
#9
tnx manWink this plugin is realy nice & very useful.
[-] The following 1 user says Thank You to moosa67 for this post:
  • SgtLegend
  Reply
#10
anyway to stop the current ban list= permanent.ban from getting messed up when you ban someone?

It will put xuids on one line instead of a separate line hence they can rejoin untilyou manually edit the ban file.
[Image: b_560_95_1.png]


[Image: b_560_95_1.png]

  Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)