Files
AmongUsRevamped/Modules/BanManager.cs
T

217 lines
8.3 KiB
C#

using InnerNet;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using UnityEngine;
// https://github.com/EnhancedNetwork/TownofHost-Enhanced/blob/main/Modules/BanManager.cs
namespace AmongUsRevamped;
public static class BanManager
{
public static readonly string DataPath =
#if ANDROID
Application.persistentDataPath;
#else
".";
#endif
public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", "");
private static readonly string DenyNameListPath = $"{DataPath}/AUR-DATA/DenyNameList.txt";
private static string BanListPath = $"{DataPath}/AUR-DATA/Banlist.txt";
private static string BanWordPath = $"{DataPath}/AUR-DATA/Bannedwords.txt";
private static string VipListPath = $"{DataPath}/AUR-DATA/VIP.txt";
private static string ModeratorListPath = $"{DataPath}/AUR-DATA/Moderator.txt";
private static string AdminListPath = $"{DataPath}/AUR-DATA/Admin.txt";
public static List<string> TempBanWhiteList = [];
public static void Init()
{
try
{
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(DenyNameListPath))
{
Logger.Warn("Creating a new DenyNameList.txt file", "BanManager");
File.Create(DenyNameListPath).Close();
}
if (!File.Exists(BanListPath))
{
Logger.Warn("Creating a new Banlist.txt file", "BanManager");
File.Create(BanListPath).Close();
}
if (!File.Exists(BanWordPath))
{
Logger.Warn("Creating a new Banlist.txt file", "BanManager");
File.Create(BanWordPath).Close();
}
if (!File.Exists(VipListPath))
{
Logger.Warn("Creating a new VIP.txt file", "BanManager");
File.Create(VipListPath).Close();
}
if (!File.Exists(ModeratorListPath))
{
Logger.Warn("Creating a new Moderator.txt file", "BanManager");
File.Create(ModeratorListPath).Close();
}
if (!File.Exists(AdminListPath))
{
Logger.Warn("Creating a new Admin.txt file", "BanManager");
File.Create(AdminListPath).Close();
}
}
catch (Exception ex)
{
Logger.Exception(ex, "BanManager");
}
}
private static string GetResourcesTxt(string path)
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
stream.Position = 0;
using StreamReader reader = new(stream, Encoding.UTF8);
return reader.ReadToEnd();
}
public static string GetHashedPuid(this ClientData player)
{
if (player == null) return "";
string puid = player.ProductUserId;
return GetHashedPuid(puid);
}
public static string GetHashedPuid(string puid)
{
using SHA256 sha256 = SHA256.Create();
// get sha-256 hash
byte[] sha256Bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(puid));
string sha256Hash = BitConverter.ToString(sha256Bytes).Replace("-", "").ToLower();
// pick front 5 and last 4
return string.Concat(sha256Hash.AsSpan(0, 5), sha256Hash.AsSpan(sha256Hash.Length - 4));
}
public static void AddBanPlayer(ClientData player)
{
if (!AmongUsClient.Instance.AmHost || player == null) return;
if (!CheckBanList(player?.FriendCode, player?.GetHashedPuid()) && !TempBanWhiteList.Contains(player?.GetHashedPuid()))
{
if (player?.GetHashedPuid() != "" && player?.GetHashedPuid() != null && player?.GetHashedPuid() != "e3b0cb855")
{
var additionalInfo = "";
File.AppendAllText(BanListPath, $"{player?.FriendCode},{player?.GetHashedPuid()},{player.PlayerName.RemoveHtmlTags()}{additionalInfo}\n");
Logger.SendInGame($"Added {player?.PlayerName.RemoveHtmlTags()}/{player?.FriendCode}/{player?.GetHashedPuid()} to the BanList");
}
else Logger.Info($"Failed to add player {player?.PlayerName.RemoveHtmlTags()}/{player?.FriendCode}/{player?.GetHashedPuid()} to the BanList", "AddBanPlayer");
}
}
public static void CheckBanPlayer(ClientData player)
{
if (!AmongUsClient.Instance.AmHost) return;
string friendcode = player?.FriendCode;
// Check file BanList.txt
if (CheckBanList(friendcode, player?.GetHashedPuid()))
{
AmongUsClient.Instance.KickPlayer(player.Id, true);
Logger.Info($"{player.PlayerName} was in the BanList and has been banned", "BanListBan");
return;
}
if (TempBanWhiteList.Contains(player?.GetHashedPuid()))
{
AmongUsClient.Instance.KickPlayer(player.Id, true);
//This should not happen
Logger.Info($"{player.PlayerName} was in the Temporary BanList", "TempBan");
return;
}
}
public static bool CheckBanList(string code, string hashedpuid = "")
{
bool OnlyCheckPuid = false;
if (code == "" && hashedpuid != "") OnlyCheckPuid = true;
else if (code == "") return false;
string noDiscrim = "";
if (code.Contains('#'))
{
int index = code.IndexOf('#');
noDiscrim = code[..index];
}
try
{
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(BanListPath)) File.Create(BanListPath).Close();
using StreamReader sr = new(BanListPath);
string line;
while ((line = sr.ReadLine()) != null)
{
if (line == "") continue;
if (!OnlyCheckPuid)
{
if (line.Contains(code)) return true;
if (!string.IsNullOrEmpty(noDiscrim) && !line.Contains('#') && line.Contains(noDiscrim)) return true;
}
if (line.Contains(hashedpuid)) return true;
}
}
catch (Exception ex)
{
Logger.Exception(ex, "CheckBanList");
}
return false;
}
public static bool IsPlayerInDenyName(ClientData client, string name)
{
if (name == "" || !AmongUsClient.Instance.AmHost) return false;
var deniedNames = File.ReadAllLines(DenyNameListPath);
if (deniedNames.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => name.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(client.Id, false);
Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick");
Logger.SendInGame($"{name} was kicked because their name was in DenyNameList.txt");
return true;
}
else return false;
}
public static bool IsWordBanned(PlayerControl player, string input)
{
if (input == "" || !AmongUsClient.Instance.AmHost || Utils.CheckAccessLevel(player.Data.FriendCode) > 0) return false;
var bannedWords = File.ReadAllLines(BanWordPath);
if (bannedWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(player.Data.ClientId, false);
Logger.Info($" {player.Data.PlayerName} was kicked because they sent a banned word", "Kick");
Logger.SendInGame($"{player.Data.PlayerName} was kicked because they sent a banned word");
return true;
}
else return false;
}
[HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))]
class BanMenuSelectPatch
{
public static void Postfix(BanMenu __instance, int clientId)
{
ClientData recentClient = AmongUsClient.Instance.GetRecentClient(clientId);
if (recentClient == null) return;
if (!BanManager.CheckBanList(recentClient?.FriendCode, recentClient?.GetHashedPuid()))
__instance.BanButton.GetComponent<ButtonRolloverHandler>().SetEnabledColors();
}
}
}