mirror of
https://github.com/ApeMV/AmongUsRevamped.git
synced 2026-10-19 15:51:59 +00:00
304 lines
12 KiB
C#
304 lines
12 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/Deniednames.txt";
|
|
private static string BanListPath = $"{DataPath}/AUR-DATA/Banlist.txt";
|
|
private static string BanWordPath = $"{DataPath}/AUR-DATA/Deniedwords.txt";
|
|
public static string VipListPath = $"{DataPath}/AUR-DATA/VIP.txt";
|
|
public static string ModeratorListPath = $"{DataPath}/AUR-DATA/Moderator.txt";
|
|
public static string AdminListPath = $"{DataPath}/AUR-DATA/Admin.txt";
|
|
private static string TemplatePath = $"{DataPath}/AUR-DATA/Templates.txt";
|
|
private static string StartWordsPath = $"{DataPath}/AUR-DATA/Startwords.txt";
|
|
public static Dictionary<string, string> Templates = new();
|
|
public static void Init()
|
|
{
|
|
try
|
|
{
|
|
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
|
|
|
|
CheckFile(DenyNameListPath, Translator.Get("bannameWelcome"), "DeniedNames.txt");
|
|
CheckFile(BanListPath, Translator.Get("banlistWelcome"), "Banlist.txt");
|
|
CheckFile(BanWordPath, Translator.Get("banwordWelcome"), "DeniedWords.txt");
|
|
CheckFile(VipListPath, Translator.Get("vipWelcome"), "VIP.txt");
|
|
CheckFile(ModeratorListPath, Translator.Get("moderatorWelcome"), "Moderator.txt");
|
|
CheckFile(AdminListPath, Translator.Get("adminWelcome"), "Admin.txt");
|
|
CheckFile(TemplatePath, Translator.Get("templateWelcome"), "Templates.txt");
|
|
CheckFile(StartWordsPath, Translator.Get("startWordsWelcome"), "StartWords.txt");
|
|
|
|
LoadTemplates();
|
|
|
|
}
|
|
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()))
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
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.StartsWith("#")) continue;
|
|
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).Where(x => !x.StartsWith("#"));
|
|
|
|
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 || !Options.EnableDeniedWords.GetBool()) return false;
|
|
|
|
int clientId = player.Data.ClientId;
|
|
var bannedWords = File.ReadAllLines(BanWordPath).Where(x => !x.StartsWith("#"));
|
|
|
|
if ((Options.DeniedWordsStrength.GetBool() && bannedWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Contains(code, StringComparison.OrdinalIgnoreCase))) || (!Options.DeniedWordsStrength.GetBool() && bannedWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Equals(code, StringComparison.OrdinalIgnoreCase))))
|
|
{
|
|
|
|
if (!Main.SayDeniedWordTimes.ContainsKey(clientId))
|
|
{
|
|
Main.SayDeniedWordTimes.Add(clientId, 0);
|
|
}
|
|
|
|
Main.SayDeniedWordTimes[clientId]++;
|
|
|
|
if (Main.SayDeniedWordTimes[clientId] >= Options.DeniedWordsToKick.GetInt())
|
|
{
|
|
if (Options.DeniedWordsAsBan.GetBool())
|
|
{
|
|
AmongUsClient.Instance.KickPlayer(clientId, true);
|
|
Logger.SendInGame(Translator.Get("banWordBan", player.Data.PlayerName, Options.DeniedWordsToKick.GetInt()));
|
|
}
|
|
else
|
|
{
|
|
AmongUsClient.Instance.KickPlayer(clientId, false);
|
|
Logger.SendInGame(Translator.Get("banWordKick", player.Data.PlayerName, Options.DeniedWordsToKick.GetInt()));
|
|
}
|
|
Logger.Info(Translator.Get("banWordKick", player.Data.PlayerName, Options.DeniedWordsToKick.GetInt()), "DeniedWordKick");
|
|
}
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
public static bool IsStartWord(PlayerControl player, string input)
|
|
{
|
|
if (input == "" || !AmongUsClient.Instance.AmHost || Utils.CheckAccessLevel(player.Data.FriendCode) > 0 || !Options.AutoKickStart.GetBool() || !Utils.IsLobby) return false;
|
|
|
|
int clientId = player.Data.ClientId;
|
|
var startWords = File.ReadAllLines(StartWordsPath).Where(x => !x.StartsWith("#"));
|
|
|
|
if ((Options.AutoKickStartStrength.GetBool() && startWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Contains(code, StringComparison.OrdinalIgnoreCase))) || (!Options.AutoKickStartStrength.GetBool() && startWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Equals(code, StringComparison.OrdinalIgnoreCase))))
|
|
{
|
|
if (!Main.SayStartTimes.ContainsKey(clientId))
|
|
{
|
|
Main.SayStartTimes.Add(clientId, 0);
|
|
}
|
|
|
|
Main.SayStartTimes[clientId]++;
|
|
|
|
if (Main.SayStartTimes[clientId] >= Options.AutoKickStartTimes.GetInt())
|
|
{
|
|
if (Options.AutoKickStartAsBan.GetBool())
|
|
{
|
|
AmongUsClient.Instance.KickPlayer(clientId, true);
|
|
Logger.SendInGame(Translator.Get("startWordBan", player.Data.PlayerName, Options.AutoKickStartTimes.GetInt()));
|
|
}
|
|
else
|
|
{
|
|
AmongUsClient.Instance.KickPlayer(clientId, false);
|
|
Logger.SendInGame(Translator.Get("startWordKick", player.Data.PlayerName, Options.AutoKickStartTimes.GetInt()));
|
|
}
|
|
Logger.Info(Translator.Get("startWordKick", player.Data.PlayerName, Options.AutoKickStartTimes.GetInt()), "StartWordKick");
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
|
|
public static void LoadTemplates()
|
|
{
|
|
Templates.Clear();
|
|
|
|
if (!File.Exists(TemplatePath)) return;
|
|
|
|
foreach (var line in File.ReadAllLines(TemplatePath))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(line)) continue;
|
|
if (line.StartsWith("#")) continue;
|
|
|
|
int splitIndex = line.IndexOf(':');
|
|
|
|
if (splitIndex == -1) continue;
|
|
|
|
string key = line[..splitIndex].Trim().ToLower();
|
|
string value = line[(splitIndex + 1)..].Trim();
|
|
|
|
if (!Templates.ContainsKey(key)) Templates.Add(key, value);
|
|
}
|
|
}
|
|
|
|
private static void CheckFile(string path, string defaultContent, string name)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(path))
|
|
{
|
|
Logger.Warn($"Creating a new {name} file", "BanManager");
|
|
File.WriteAllText(path, defaultContent);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Exception(ex, "BanManager");
|
|
}
|
|
}
|
|
|
|
public static string CheckTemplate(string text)
|
|
{
|
|
Dictionary<string, string> variables = new()
|
|
{
|
|
{ "ModVersion", Main.ModVersion },
|
|
{ "\\n", Environment.NewLine },
|
|
{ "FirstDeath", NormalGameEndChecker.firstDeath }
|
|
};
|
|
|
|
foreach (var kvp in variables)
|
|
{
|
|
text = text.Replace($"{{{kvp.Key}}}", kvp.Value);
|
|
}
|
|
|
|
text = text.Replace("\\n", Environment.NewLine);
|
|
|
|
return text;
|
|
}
|
|
}
|