Skip to content

Commit

Permalink
Use Game Ban List when banned_users.json is Absent
Browse files Browse the repository at this point in the history
- Default back to using the game's banlist (in ServerSettings.xml) when banned_users.json file is missing
- This change allows admins to use the chat commands (including the offline command (!banid <steamid64> <name>)) and not have two separate banlists being maintained
- To switch over to ServerSettings.xml, simply remove any existing banned_users.json and use !banid to transfer the bans over via in-game commands or transfer offline via a text editor)
  • Loading branch information
data-bomb committed May 6, 2024
1 parent 3093faf commit ed6de9f
Showing 1 changed file with 100 additions and 73 deletions.
173 changes: 100 additions & 73 deletions Si_BasicBanlist/Si_BasicBans.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ You should have received a copy of the GNU General Public License
using System.Collections.Generic;
using System.Linq;

[assembly: MelonInfo(typeof(BasicBanlist), "Basic Banlist", "1.4.0", "databomb", "https://github.com/data-bomb/Silica")]
[assembly: MelonInfo(typeof(BasicBanlist), "Basic Banlist", "1.5.0", "databomb", "https://github.com/data-bomb/Silica")]
[assembly: MelonGame("Bohemia Interactive", "Silica")]
[assembly: MelonOptionalDependencies("Admin Mod")]

Expand All @@ -45,7 +45,7 @@ public class BasicBanlist : MelonMod
{
public class BanEntry
{
public long OffenderSteamId
public ulong OffenderSteamId
{
get;
set;
Expand Down Expand Up @@ -107,8 +107,8 @@ public override void OnInitializeMelon()
}
else
{
MelonLogger.Msg("Did not find banned_users.json file. No banlist entries loaded.");
MasterBanList = new List<BanEntry>();
MelonLogger.Msg("Did not find banned_users.json file. Will use ServerSettings.xml file.");
MasterBanList = null;
}
}
catch (Exception error)
Expand All @@ -125,7 +125,7 @@ public override void OnLateInitializeMelon()
HelperMethods.RegisterAdminCommand("kickban", banCallback, Power.Ban, "Bans target player. Usage: !kickban <player>");

HelperMethods.CommandCallback offlineBanCallback = Command_OfflineBan;
HelperMethods.RegisterAdminCommand("banid", offlineBanCallback, Power.Rcon, "Bans target player by SteamID. Usage !ban <Steam64ID> <player name>");
HelperMethods.RegisterAdminCommand("banid", offlineBanCallback, Power.Rcon, "Bans target player by SteamID. Usage !banid <Steam64ID> <player name>");

HelperMethods.CommandCallback unbanCallback = Command_Unban;
HelperMethods.RegisterAdminCommand("unban", unbanCallback, Power.Unban, "Unbans target player. Usage: !unban <playername | Steam64ID>");
Expand All @@ -145,15 +145,48 @@ public override void OnLateInitializeMelon()
#endif
}

public static void Command_OfflineBan(Player? callerPlayer, String args)
public static bool IsPlayerBanned(string name)
{
// validate banlist is available
if (MasterBanList == null)
// using banned_users.json
if (MasterBanList != null)
{
MelonLogger.Msg("Ban list unavailable. Check json syntax.");
return;
BanEntry? matchingBan = MasterBanList.Find(i => i.OffenderName == name);
if (matchingBan != null)
{
return true;
}
}
// using game XML
else
{
return NetworkServerSettings.PlayerIsBanned(name);
}

return false;
}

public static bool IsPlayerBanned(ulong steamID)
{
// using banned_users.json
if (MasterBanList != null)
{
BanEntry? matchingBan = MasterBanList.Find(i => i.OffenderSteamId == steamID);
if (matchingBan != null)
{
return true;
}
}
// using game XML
else
{
return NetworkServerSettings.PlayerIsBanned(steamID);
}

return false;
}

public static void Command_OfflineBan(Player? callerPlayer, String args)
{
string commandName = args.Split(' ')[0];

// validate argument count
Expand All @@ -167,54 +200,44 @@ public static void Command_OfflineBan(Player? callerPlayer, String args)
// validate argument contents
string targetID = args.Split(' ')[1];
string targetName = args.Split(' ', 2)[2];
bool isNumber = long.TryParse(targetID, out long steamid);
bool isNumber = ulong.TryParse(targetID, out ulong steamid);
if (!isNumber)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, commandName, ": Not a valid SteamID64");
return;
}

BanEntry? matchingBan = MasterBanList.Find(i => i.OffenderSteamId == steamid);

// did we find someone we could ban?
if (matchingBan != null)
if (IsPlayerBanned(steamid))
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, commandName, ": SteamID64 already found in the banlist");
return;
}

BanEntry thisBan = new BanEntry()
{
OffenderSteamId = steamid,
OffenderName = targetName,
UnixBanTime = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
};

if (callerPlayer == null)
if (MasterBanList == null)
{
thisBan.Comments = "banned by SERVER CONSOLE";
NetworkServerSettings.PlayerAddBan(steamid, targetName, 0, callerPlayer == null ? "offline banned by SERVER CONSOLE" : "offline banned by " + callerPlayer.PlayerName);
}
else
{
thisBan.Comments = "banned by " + callerPlayer.PlayerName;
}
BanEntry thisBan = new BanEntry()
{
OffenderSteamId = steamid,
OffenderName = targetName,
UnixBanTime = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds,
Comments = (callerPlayer == null) ? "offline banned by SERVER CONSOLE" : "offline banned by " + callerPlayer.PlayerName
};

MelonLogger.Msg("Added player name (" + thisBan.OffenderName + ") SteamID (" + thisBan.OffenderSteamId.ToString() + ") to the banlist.");
MasterBanList.Add(thisBan);
UpdateBanFile();
MasterBanList.Add(thisBan);
UpdateBanFile();
}

HelperMethods.AlertAdminAction(callerPlayer, "banned " + thisBan.OffenderName);
MelonLogger.Msg("Added player name (" + targetName + ") SteamID (" + steamid + ") to the banlist (offline).");
HelperMethods.AlertAdminAction(callerPlayer, "offline banned " + targetName);
}

public static void Command_Ban(Player? callerPlayer, String args)
{
// validate banlist is available
if (MasterBanList == null)
{
MelonLogger.Msg("Ban list unavailable. Check json syntax.");
return;
}

string commandName = args.Split(' ')[0];

// validate argument count
Expand Down Expand Up @@ -251,13 +274,6 @@ public static void Command_Ban(Player? callerPlayer, String args)

public static void Command_Unban(Player? callerPlayer, String args)
{
// validate banlist is available
if (MasterBanList == null)
{
MelonLogger.Msg("Ban list unavailable. Check json syntax.");
return;
}

string commandName = args.Split(' ')[0];

// validate argument count
Expand All @@ -269,59 +285,70 @@ public static void Command_Unban(Player? callerPlayer, String args)
}

// grab everything after !unban for the target string
String sTarget = args.Split(' ', 2)[1];
String unbanTarget = args.Split(' ', 2)[1];

if (!UnbanPlayer(unbanTarget, callerPlayer))
{
HelperMethods.ReplyToCommand(args.Split(' ')[0] + ": Unable to find " + unbanTarget + " on banlist");
return;
}
}

public static bool UnbanPlayer(String target, Player? adminPlayer)
{
// accept target of either steamid64 or name
bool isNumber = long.TryParse(sTarget, out long steamid);
bool isNumber = ulong.TryParse(target, out ulong steamid);

BanEntry? matchingBan;
// assume it's a steamid64
if (isNumber)
if (MasterBanList == null)
{
matchingBan = MasterBanList.Find(i => i.OffenderSteamId == steamid);
NetworkBannedPlayer? bannedPlayer = isNumber ? NetworkServerSettings.GetPlayerBan(steamid) : NetworkServerSettings.GetPlayerBan(target);
if (bannedPlayer == null)
{
return false;
}

NetworkServerSettings.PlayerRemoveBan(bannedPlayer.m_ID);
MelonLogger.Msg("Removed player name (" + bannedPlayer.m_Name + ") SteamID (" + bannedPlayer.m_ID.ToString() + ") from the banlist.");
HelperMethods.AlertAdminAction(adminPlayer, "unbanned " + bannedPlayer.m_Name);
return true;
}
// assume it's a name
else
{
matchingBan = MasterBanList.Find(i => i.OffenderName == sTarget);
}
BanEntry? bannedPlayer = isNumber ? MasterBanList.Find(i => i.OffenderSteamId == steamid) : MasterBanList.Find(i => i.OffenderName == target);
if (bannedPlayer == null)
{
return false;
}

// did we find someone we could unban?
if (matchingBan == null)
{
String targetType = isNumber ? "steamid" : "name";
HelperMethods.ReplyToCommand(args.Split(' ')[0] + ": Unable to find " + targetType + " on banlist");
return;
MasterBanList.Remove(bannedPlayer);
UpdateBanFile();
MelonLogger.Msg("Removed player name (" + bannedPlayer.OffenderName + ") SteamID (" + bannedPlayer.OffenderSteamId.ToString() + ") from the banlist.");
HelperMethods.AlertAdminAction(adminPlayer, "unbanned " + bannedPlayer.OffenderName);
return true;
}

MelonLogger.Msg("Removed player name (" + matchingBan.OffenderName + ") SteamID (" + matchingBan.OffenderSteamId.ToString() + ") from the banlist.");
MasterBanList.Remove(matchingBan);
UpdateBanFile();

HelperMethods.AlertAdminAction(callerPlayer, "unbanned " + matchingBan.OffenderName);
}

public static void BanPlayer(Player playerToBan, Player? adminPlayer)
{
if (MasterBanList == null)
// are we already banned?
if (IsPlayerBanned(playerToBan.PlayerID.m_SteamID))
{
MelonLogger.Warning("Player name (" + playerToBan.PlayerName + ") SteamID (" + playerToBan.PlayerID.m_SteamID.ToString() + ") already on banlist.");
return;
}

BanEntry thisBan = GenerateBanEntry(playerToBan, adminPlayer);

// are we already banned?
if (MasterBanList.Find(i => i.OffenderSteamId == thisBan.OffenderSteamId) != null)
if (MasterBanList == null)
{
MelonLogger.Msg("Player name (" + thisBan.OffenderName + ") SteamID (" + thisBan.OffenderSteamId.ToString() + ") already on banlist.");
NetworkServerSettings.PlayerAddBan(playerToBan.PlayerID.m_SteamID, playerToBan.PlayerName, 0, adminPlayer == null ? "banned by SERVER CONSOLE" : "banned by " + adminPlayer.PlayerName);
}
else
{
MelonLogger.Msg("Added player name (" + thisBan.OffenderName + ") SteamID (" + thisBan.OffenderSteamId.ToString() + ") to the banlist.");
BanEntry thisBan = GenerateBanEntry(playerToBan, adminPlayer);
MasterBanList.Add(thisBan);
UpdateBanFile();
}

MelonLogger.Msg("Added player name (" + playerToBan.PlayerName + ") SteamID (" + playerToBan.PlayerID.m_SteamID.ToString() + ") to the banlist.");
NetworkGameServer.KickPlayer(playerToBan);
HelperMethods.AlertAdminActivity(adminPlayer, playerToBan, "banned");
}
Expand All @@ -330,7 +357,7 @@ public static BanEntry GenerateBanEntry(Player player, Player? admin)
{
BanEntry thisBan = new BanEntry()
{
OffenderSteamId = long.Parse(player.ToString().Split('_')[1]),
OffenderSteamId = ulong.Parse(player.ToString().Split('_')[1]),
OffenderName = player.PlayerName,
UnixBanTime = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
};
Expand Down Expand Up @@ -403,7 +430,7 @@ public static void Postfix(GameMode __instance, Player __0)
if (__0 != null)
{
// check if player was previously banned
long JoiningPlayerSteamId = long.Parse(__0.ToString().Split('_')[1]);
ulong JoiningPlayerSteamId = ulong.Parse(__0.ToString().Split('_')[1]);
if (MasterBanList.Find(i => i.OffenderSteamId == JoiningPlayerSteamId) != null)
{
MelonLogger.Msg("Kicking " + __0.ToString() + " for matching an entry in the banlist.");
Expand Down

0 comments on commit ed6de9f

Please sign in to comment.