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:
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:
Changelog:
Credits:
@Nukem - For such a great code base to work with
@Pozzuh - For the permissions plugin
Source:
Thanks for reading and hope you enjoy it!
Unbanner-v1.2.zip (Size: 4.46 KB / Downloads: 195)
Unbanner-v1.1.zip (Size: 4.17 KB / Downloads: 67)
Unbanner-v1.0.zip (Size: 3.44 KB / Downloads: 50)
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:
v1.2 (Click to View)
v1.1 (Click to View)
Credits:
@Nukem - For such a great code base to work with
@Pozzuh - For the permissions plugin
Source:
Code:
using System;
using System.Collections.Generic;
using System.IO;
using Addon;
namespace Unbanner
{
public class Unbanner : CPlugin
{
public delegate void Del(KeyValuePair<int, string> player);
// The array were all the bans will be stored
public Dictionary<int, string> bans = new Dictionary<int, string>();
public Dictionary<int, string> players = new Dictionary<int, string>();
// General variables
public string player;
public ServerClient client;
public string[] lastPlayer;
/// <summary>
/// Executes when the MW3 server starts up
/// </summary>
public override void OnServerLoad()
{
ServerPrint("Unbanner plugin loaded. Author: SgtLegend. Version 1.2");
}
/// <summary>
/// Listens for when a client types in the chat, currently it listens for "!unban, !unbanc, !banlist"
/// which is a pre-defined chat command that can be assigned using the permissions plugin otherwise
/// everyone will be able to use it.
/// </summary>
/// <param name="Message"></param>
/// <param name="Client"></param>
/// <param name="Teamchat"></param>
/// <returns></returns>
public override ChatType OnSay(string Message, ServerClient Client, bool Teamchat)
{
// Set the client
client = Client;
// Split the contents of the message
string[] split = Message.Split(' ');
// Get all of the currently banned players
try
{
getBanFileContents();
}
catch (Exception e)
{
TellClient(Client.ClientNum, "^1An error occurred while trying to open the banned players list!", true);
return ChatType.ChatNone;
}
// Check if there are any banned players in the file
if (bans.Count == 0)
{
TellClient(Client.ClientNum, "^1No players were found to be banned on the server", true);
return ChatType.ChatNone;
}
#region !unbanc
if (Message.StartsWith("!unbanc"))
{
// Do we have enough arguments?
if (split.Length < 2)
{
TellClient(Client.ClientNum, "^1Usage: ^7!unbanc <ban ID>", true);
return ChatType.ChatNone;
}
// Check if a valid ban ID was entered
int banID = -1;
if (Int32.TryParse(split[1], out banID) && bans.ContainsKey(banID))
{
playerMatchedToXUIDOrName(bans[banID]);
}
else
{
TellClient(Client.ClientNum, "^1Please enter a valid ban ID!", true);
}
return ChatType.ChatNone;
}
#endregion
#region !unban
if (Message.StartsWith("!unban"))
{
// Do we have enough arguments?
if (split.Length < 2)
{
TellClient(Client.ClientNum, "^1Usage: ^7!unban <player name> ^1OR ^7!unban <xuid>", true);
return ChatType.ChatNone;
}
// Check if the player XUID/Name entered is valid
if (string.IsNullOrEmpty(split[1]))
{
TellClient(Client.ClientNum, "^1Please enter a valid XUID/Player name!", true);
return ChatType.ChatNone;
}
else
{
player = split[1];
}
// Now the fun part, we need to assume the client who entered this command hasn't used a full
// player name so we need to ensure there is only one client otherwise alert him/her to add
// more characters to the name or use the XUID
checkPlayerAgainstBansList(
2,
"^5Multiple clients were found, please try to be more specific!",
1,
playerMatchedToXUIDOrName
);
return ChatType.ChatNone;
}
#endregion
#region !undolast
if (Message.StartsWith("!undolast"))
{
string message;
if (lastPlayer != null)
{
message = modifyBansFile(lastPlayer, true) ?
"^2The player ^7" + lastPlayer[1] + " ^2has been banned again successfully!" :
"^1The player ^7" + lastPlayer[1] + " ^1couldn't be banned again due to an error!";
// Reset the last player variable
lastPlayer = null;
}
else
{
message = "^:You haven't unbanned anyone recently!";
}
TellClient(Client.ClientNum, message, true);
return ChatType.ChatNone;
}
#endregion
#region !banlist
if (Message.StartsWith("!banlist"))
{
// Do we have enough arguments?
if (split.Length < 2)
{
TellClient(Client.ClientNum, "^1Usage: ^7!banlist <filter name>. ^2E.g. ^3!banlist Sgt", true);
return ChatType.ChatNone;
}
// Check if the player XUID/Name entered is valid
if (string.IsNullOrEmpty(split[1]) || split[1].Length < 2)
{
TellClient(Client.ClientNum, "^1Please enter at least 2 characters for the search!", true);
return ChatType.ChatNone;
}
else
{
player = split[1];
}
// Now the fun part, we need to ensure the characters the client entered match a player in the
// the bans list, if 3 or more clients are found let the client know they need to adjust the
// search criteria to be more specific
checkPlayerAgainstBansList(
4,
"^5More then 3 clients were found, please adjust your search criteria to be more specific!",
3,
playerMatchedToName
);
return ChatType.ChatNone;
}
#endregion
return ChatType.ChatContinue;
}
/// <summary>
/// Collects the file contents for "main/permanent.ban"
/// </summary>
private void getBanFileContents()
{
// Clear the current bans list
bans.Clear();
// Open a new file stream to the bans file
StreamReader file = new StreamReader(@"main\permanent.ban");
string line;
int counter = 0;
while ((line = file.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line))
{
bans.Add(counter, string.Join(":", line.Split(' ')));
counter++;
}
}
// Close the file stream
file.Close();
}
/// <summary>
/// Checks the found player against the known bans
/// </summary>
/// <param name="totalClients"></param>
/// <param name="totalClientsMessage"></param>
/// <param name="totalForList"></param>
/// <param name="callback"></param>
private void checkPlayerAgainstBansList(int totalClients, string totalClientsMessage, int totalForList, Del callback)
{
// Clear the players list
players.Clear();
foreach (KeyValuePair<int, string> ban in bans)
{
string[] _player = ban.Value.Split(':');
if (_player[0] == player || _player[1].ToLower() == player.ToLower() || _player[1].ToLower().Contains(player.ToLower()))
{
players.Add(ban.Key, ban.Value);
}
}
// Is there more than the total amount of players we can display?
if (players.Count >= totalClients)
{
TellClient(client.ClientNum, totalClientsMessage, true);
}
// Do we have at least one matched player?
else if (players.Count > 0 && players.Count <= totalForList)
{
foreach (KeyValuePair<int, string> player in players)
{
callback(player);
}
}
// No players have been matched
else
{
TellClient(client.ClientNum, "^1No players matched your query!", true);
}
}
/// <summary>
/// Attempts to unban the specified player from the server
/// </summary>
/// <param name="player"></param>
/// <returns></returns>
private void playerMatchedToXUIDOrName(KeyValuePair<int, string> player)
{
playerMatchedToXUIDOrName(player.Value);
}
/// <summary>
/// Attempts to unban the specified player from the server
/// </summary>
/// <param name="player"></param>
private void playerMatchedToXUIDOrName(string player)
{
// Split the player details
string[] _player = player.Split(':');
// Attempt to unban the player
ServerCommand("unban " + _player[1]);
// Confirm the user was unbanned from the server
string message = confirmPlayerWasUnbanned(_player) ?
"^2The player ^7" + _player[1] + " ^2has been unbanned!" :
"^1The player ^7" + _player[1] + " ^1couldn't be unbanned due to an error!";
TellClient(client.ClientNum, message, true);
}
/// <summary>
/// Lists out all the banned players by there banned ID, this allows for players to be unbanned very
/// quickly using the !unbanc command
/// </summary>
private void playerMatchedToName(KeyValuePair<int, string> player)
{
TellClient(client.ClientNum, string.Format("^1Ban ID: ^7{0} ^:| ^1Player: ^7{1}", player.Key.ToString(), player.Value.Split(':')[1]), true);
}
/// <summary>
/// Gets the contents of the ban file and confirms the specified user was unbanned otherwise manual
/// action on the file will be taken out to ensure the user gets unbanned.
/// </summary>
/// <param name="player"></param>
/// <returns></returns>
private bool confirmPlayerWasUnbanned(string[] player)
{
// Get all of the currently banned players
getBanFileContents();
if (bans.Count > 0)
{
foreach (KeyValuePair<int, string> ban in bans)
{
string[] _player = ban.Value.Split(':');
if (_player[0] == player[0] && _player[1] == player[1] && modifyBansFile(player, false))
{
return true;
}
}
}
return false;
}
/// <summary>
/// Manually attempts to modify the bans file to either remove or add a player
/// </summary>
/// <param name="player"></param>
/// <param name="ban"></param>
/// <returns></returns>
private bool modifyBansFile(string[] player, bool ban)
{
string type = (ban) ? "banned" : "unbanned";
// Before we do anything lets make sure a backup of the current file exists so server admins
// can easily roll back any changes
if (!Directory.Exists("bans_backup"))
{
Directory.CreateDirectory("bans_backup");
}
try
{
// File paths
string inptuFileName = @"main\permanent.ban";
string backupFileName = string.Format(@"bans_backup\permanent_{0:dd_MM_yyyy_HH_mm_ss}.ban", DateTime.Now);
// Backup the bans file now
File.Copy(inptuFileName, backupFileName, false);
// Unban the player
if (!ban)
{
string tempFileName = Path.GetTempFileName();
try
{
using (StreamReader streamReader = new StreamReader(inptuFileName))
{
using (StreamWriter streamWriter = new StreamWriter(tempFileName, true))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line) && !line.Contains(player[0]) && !line.Contains(player[1]))
streamWriter.WriteLine(line);
}
}
}
// Overwrite the current bans file with the temporary file
File.Copy(tempFileName, inptuFileName, true);
// Delete the temporary file that was just created
File.Delete(tempFileName);
// Set the last player so the unban can be reverted after
lastPlayer = player;
return true;
}
catch (Exception)
{
TellClient(client.ClientNum, "^1The player ^7" + player[1] + " ^1couldn't be unbanned due to an error!", true);
}
}
else
{
try
{
using (StreamWriter file = new StreamWriter(inptuFileName, true))
{
file.WriteLine(player[0] + " " + player[1]);
}
return true;
}
catch (Exception)
{
return false;
}
}
}
catch (Exception)
{
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);
}
return false;
}
}
}Thanks for reading and hope you enjoy it!
Unbanner-v1.2.zip (Size: 4.46 KB / Downloads: 195)
Unbanner-v1.1.zip (Size: 4.17 KB / Downloads: 67)
Unbanner-v1.0.zip (Size: 3.44 KB / Downloads: 50)
I now host all my MW3 projects on my private GIT repo




this plugin is realy nice & very useful.