The current BepInExPack is broken due to the Oakveil update, and mods installed through a mod manager may not work. Join the modding Discord for more information.
Decompiled source of CrimsonBanned v1.3.3
CrimsonBanned.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CrimsonBanned.Commands; using CrimsonBanned.Structs; using CrimsonBanned.Utilities; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Network; using Stunlock.Network; using Unity.Collections; using Unity.Entities; using Unity.Jobs; using UnityEngine; using VAMP; using VAMP.Models; using VAMP.Services; using VAMP.Structs; using VAMP.Utilities; using VampireCommandFramework; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("CrimsonBanned")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Created with VRising.ModTemplate, you should edit this.")] [assembly: AssemblyFileVersion("1.3.3.0")] [assembly: AssemblyInformationalVersion("1.3.3+Branch.master.Sha.705b40dbc049e91739ff631446044371a95429e1.705b40dbc049e91739ff631446044371a95429e1")] [assembly: AssemblyProduct("CrimsonBanned")] [assembly: AssemblyTitle("CrimsonBanned")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public struct MessagePair { public string Key { get; set; } public string Value { get; set; } public MessagePair(string key, string value) { Key = key; Value = value; } public string ToString(Ban ban, BanDetails details = null) { string value = Value; value = ((!string.IsNullOrEmpty(ban.PlayerName)) ? value.Replace("{player}", ban.PlayerName) : value.Replace("{player}", "<i>Unknown</i>")); value = value.Replace("{id}", ban.PlayerID.ToString()); value = value.Replace("{issued}", ban.Issued.ToLocalTime().ToString("MM/dd/yy HH:mm")); value = ((!(ban.Reason == "") && !string.IsNullOrEmpty(ban.Reason)) ? value.Replace("{reason}", ban.Reason) : value.Replace("{reason}", "(None Provided)")); value = value.Replace("{by}", ban.IssuedBy); value = value.Replace("{local}", ban.LocalBan.ToString()); value = ((details == null) ? value.Replace("{type}", "") : value.Replace("{type}", details.BanType)); if (TimeUtility.IsPermanent(ban.TimeUntil)) { value = value.Replace("{until}", "Permanent"); return value.Replace("{remainder}", "Permanent"); } value = value.Replace("{until}", ban.TimeUntil.ToLocalTime().ToString("MM/dd/yy HH:mm")); return value.Replace("{remainder}", TimeUtility.FormatRemainder(ban.TimeUntil.ToLocalTime())); } } public class Trust { public string Alias { get; set; } public string Command { get; set; } public Trust(string alias, string command) { Alias = alias; Command = command; } } namespace CrimsonBanned { [BepInPlugin("CrimsonBanned", "CrimsonBanned", "1.3.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private Harmony _harmony; public static Settings Settings; public static bool LogLoaded; internal static Plugin Instance { get; private set; } public static Harmony Harmony => Instance._harmony; public static ManualLogSource LogInstance => ((BasePlugin)Instance).Log; public static string ConfigFiles => Path.Combine(Paths.ConfigPath, "CrimsonBanned"); public static Database Database { get; private set; } public override void Load() { Instance = this; Settings = default(Settings); Settings.InitConfig(); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); CommandRegistry.RegisterAll(); foreach (KeyValuePair<string, PluginInfo> plugin in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins) { if (plugin.Value.Metadata.GUID.Equals("CrimsonLog")) { LogLoaded = true; break; } } Plugin.OnCoreLoaded = (Action)Delegate.Combine(Plugin.OnCoreLoaded, new Action(Loaded)); } public void Loaded() { Database = new Database(); } public override bool Unload() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } public static void LogMessage(string message, bool console = false) { if (LogLoaded && !console) { Type type = Type.GetType("CrimsonLog.Systems.Logger, CrimsonLog"); if (type != null) { type.GetMethod("Record").Invoke(null, new object[3] { "Banned", "bans", message + "\n" }); return; } } LogInstance.LogInfo((object)message); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "CrimsonBanned"; public const string PLUGIN_NAME = "CrimsonBanned"; public const string PLUGIN_VERSION = "1.3.3"; } } namespace CrimsonBanned.Utilities { internal static class EntityUtilities { private static EntityManager EntityManager => Core.EntityManager; public static IEnumerable<Entity> GetEntitiesEnumerable(EntityQuery entityQuery) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) NativeArray<Entity> entities; JobHandle entities2 = GetEntities(entityQuery, out entities, (Allocator)3); ((JobHandle)(ref entities2)).Complete(); try { Enumerator<Entity> enumerator = entities.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; EntityManager entityManager = EntityManager; if (((EntityManager)(ref entityManager)).Exists(current)) { yield return current; } } } finally { entities.Dispose(); } } private static JobHandle GetEntities(EntityQuery entityQuery, out NativeArray<Entity> entities, Allocator allocator = 3) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) entities = ((EntityQuery)(ref entityQuery)).ToEntityArray(AllocatorHandle.op_Implicit(allocator)); return default(JobHandle); } } public static class SQLConflict { public static async Task ResolveOfflines(List<Ban> list) { List<Ban> list2 = list.FindAll((Ban x) => x.DatabaseId == -1); foreach (Ban item in list2) { int num = SQLlink.AddBan(item, list); if (num >= 0) { item.DatabaseId = num; } else { await ResolveConflict(item, list); } } } public static async Task<int> ResolveConflict(Ban ban, List<Ban> list) { Ban ban2 = SQLlink.GetBan(ban.PlayerID, list); if (ban2 == null) { ManualLogSource logInstance = Plugin.LogInstance; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not find ban for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(ban.PlayerID); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in the database."); } logInstance.LogError(val); return -1000; } if (ban.DatabaseId != -1 && ban2.DatabaseId != -1 && ban.DatabaseId == ban2.DatabaseId) { list.Remove(ban); return 4; } if (ban.TimeUntil == ban2.TimeUntil) { list.Remove(ban); Database.AddBan(ban2, list); if (TimeUtility.IsPermanent(ban2.TimeUntil) && TimeUtility.IsPermanent(ban.TimeUntil)) { return 0; } return 4; } if (TimeUtility.IsPermanent(ban2.TimeUntil)) { list.Remove(ban); Database.AddBan(ban2, list); return 0; } if (IsExpiredBan(ban2)) { return await ReplaceExistingBan(ban2, ban, list); } if (!TimeUtility.IsPermanent(ban2.TimeUntil) && TimeUtility.IsPermanent(ban.TimeUntil)) { return await ReplaceExistingBan(ban2, ban, list); } if (ban.TimeUntil > ban2.TimeUntil) { return await ReplaceExistingBan(ban2, ban, list); } list.Remove(ban); Database.AddBan(ban2, list); return 1; } private static bool IsExpiredBan(Ban ban) { if (ban.TimeUntil < DateTime.UtcNow) { return !TimeUtility.IsPermanent(ban.TimeUntil); } return false; } private static async Task<int> ReplaceExistingBan(Ban oldBan, Ban newBan, List<Ban> list) { SQLlink.DeleteBan(oldBan, list); int databaseId = SQLlink.AddBan(newBan, list); newBan.DatabaseId = databaseId; Database.AddBan(newBan, list); return 2; } } public static class SQLUtility { private static bool IsSyncing; public static bool TrySQL() { return Database.SQL != null && Settings.UseSQL.Value && SQLlink.Connect(); } public static async void SyncDB() { if (!TrySQL() || !SQLlink.Connect() || IsSyncing) { return; } IsSyncing = true; foreach (DeleteLater delete in Database.Deletes) { SQLlink.DeleteBan(delete.ID, delete.TableName); } Database.Deletes.Clear(); if (File.Exists(Database.DeleteFile)) { File.Delete(Database.DeleteFile); } await SyncTable(Database.ChatBans, "ChatBans"); await SyncTable(Database.VoiceBans, "VoiceBans"); await SyncTable(Database.Banned, "ServerBans"); Database.SaveDatabases(); IsSyncing = false; } private static async Task SyncTable(List<Ban> list, string tableName) { if (ValidateSync(list, tableName)) { await SQLConflict.ResolveOfflines(list); DataTable sortedTableFromDatabase = GetSortedTableFromDatabase(tableName); HandleRemovedBans(list, sortedTableFromDatabase); RemoveExpiredBans(sortedTableFromDatabase, tableName); SyncMissingBans(list, sortedTableFromDatabase); } } private static DataTable GetSortedTableFromDatabase(string tableName) { DataView defaultView = ((DataTable)Database.SQL.Select(tableName)).DefaultView; defaultView.Sort = "Id ASC"; return defaultView.ToTable(); } private static void HandleRemovedBans(List<Ban> list, DataTable sortedTable) { HashSet<int> bansByID = new HashSet<int>(from DataRow row in sortedTable.Rows select Convert.ToInt32(row["Id"])); list.RemoveAll((Ban ban) => !bansByID.Contains(ban.DatabaseId) && ban.DatabaseId != -1); if (list == Database.Banned) { Database.BanListFix(list.Where((Ban ban) => !bansByID.Contains(ban.DatabaseId) && ban.DatabaseId != -1).ToList()); } } private static void RemoveExpiredBans(DataTable sortedTable, string tableName) { foreach (DataRow row in sortedTable.Rows) { DateTime dateTime = Convert.ToDateTime(row["TimeUntil"]); if (dateTime < DateTime.UtcNow && !TimeUtility.IsPermanent(dateTime)) { SQLlink.DeleteBan(Convert.ToInt32(row["Id"]), tableName); } } } private static void SyncMissingBans(List<Ban> list, DataTable sortedTable) { foreach (DataRow row in sortedTable.Rows) { Ban ban = CreateBanFromRow(row); if (list.Any((Ban x) => x.DatabaseId == ban.DatabaseId)) { continue; } if (IsPlayerAlreadyBanned(ban, list, out var existingBan)) { if (TimeUtility.IsPermanent(ban.TimeUntil)) { list.Remove(existingBan); AddBanToList(list, ban); continue; } if (TimeUtility.IsPermanent(existingBan.TimeUntil)) { SQLlink.DeleteBan(ban, list); AddBanToList(list, existingBan); break; } if (ban.TimeUntil > existingBan.TimeUntil) { list.Remove(existingBan); AddBanToList(list, ban); } else { SQLlink.DeleteBan(ban, list); AddBanToList(list, existingBan); } } else { AddBanToList(list, ban); } } } private static bool IsPlayerAlreadyBanned(Ban ban, List<Ban> list, out Ban existingBan) { existingBan = list.Find((Ban x) => x.PlayerID == ban.PlayerID || (x.DatabaseId != -1 && x.DatabaseId == ban.DatabaseId)); return existingBan != null; } private static Ban CreateBanFromRow(DataRow row) { return new Ban(row["PlayerName"].ToString(), Convert.ToUInt64(row["PlayerID"]), Convert.ToDateTime(row["TimeUntil"]), row["Reason"].ToString(), row["IssuedBy"].ToString()) { Issued = Convert.ToDateTime(row["Issued"]), DatabaseId = Convert.ToInt32(row["Id"]) }; } private static void AddBanToList(List<Ban> list, Ban ban) { list.Add(ban); if (list == Database.Banned) { HandleServerBan(ban); } } private static void HandleServerBan(Ban ban) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (PlayerService.TryFindBySteam(ban.PlayerID, ref val) && EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity).IsConnected) { Core.StartCoroutine(BanCommands.DelayKick(PlayerService.PlayerFromData(val))); } if (File.Exists(Settings.BanFilePath.Value)) { UpdateBanFile(ban); } } private static void UpdateBanFile(Ban ban) { if (!File.ReadAllLines(Settings.BanFilePath.Value).Contains(ban.PlayerID.ToString())) { File.AppendAllText(Settings.BanFilePath.Value, ban.PlayerID + Environment.NewLine); } } private static bool ValidateSync(List<Ban> list, string tableName) { if (Database.SQL == null) { return false; } if (!SQLlink.Connect()) { return false; } if (list == null) { return false; } if (string.IsNullOrEmpty(tableName)) { return false; } return true; } } public static class TimeUtility { public static readonly DateTime MinValueUtc = new DateTime(0L, DateTimeKind.Utc); public static string FormatRemainder(DateTime date) { return FormatRemainder(date - DateTime.Now); } public static string FormatRemainder(TimeSpan remainder) { string text = string.Empty; if (remainder.Days > 0) { text += $"{remainder.Days} day{((remainder.Days > 1) ? "s" : "")}, "; } if (remainder.Hours > 0) { text += $"{remainder.Hours} hour{((remainder.Hours > 1) ? "s" : "")}, "; } if (remainder.Minutes > 0) { text += $"{remainder.Minutes} minute{((remainder.Minutes > 1) ? "s" : "")}"; } if (text.EndsWith(", ")) { text = text.Substring(0, text.Length - 2); } return text; } public static TimeSpan LengthParse(int length, string denomination) { denomination = denomination.ToLower(); string[] source = new string[5] { "minute", "minutes", "min", "mins", "m" }; string[] source2 = new string[5] { "hour", "hours", "hrs", "hr", "h" }; string[] source3 = new string[3] { "day", "days", "d" }; denomination = (source.Contains(denomination) ? "m" : (source2.Contains(denomination) ? "h" : ((!source3.Contains(denomination)) ? "m" : "d"))); return denomination switch { "m" => TimeSpan.FromMinutes(length), "h" => TimeSpan.FromHours(length), "d" => TimeSpan.FromDays(length), _ => TimeSpan.FromMinutes(length), }; } public static bool IsPermanent(DateTime date) { if (date == DateTime.MinValue) { return true; } if (date == DateTime.MinValue.ToUniversalTime()) { return true; } if (date == DateTime.MinValue.ToLocalTime()) { return true; } if (date == MinValueUtc) { return true; } return false; } } } namespace CrimsonBanned.Structs { public class Ban { public string PlayerName { get; set; } public ulong PlayerID { get; set; } [JsonConverter(typeof(JsonDateTimeConverter))] public DateTime TimeUntil { get; set; } public string Reason { get; set; } public string IssuedBy { get; set; } [JsonConverter(typeof(JsonDateTimeConverter))] public DateTime Issued { get; set; } public int DatabaseId { get; set; } public bool LocalBan { get; set; } public Ban(string playerName, ulong playerID, DateTime timeUntil, string reason, string issuedBy) { PlayerName = playerName; PlayerID = playerID; TimeUntil = new DateTime(timeUntil.Year, timeUntil.Month, timeUntil.Day, timeUntil.Hour, timeUntil.Minute, timeUntil.Second, DateTimeKind.Utc); Reason = reason; DateTime utcNow = DateTime.UtcNow; Issued = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, utcNow.Hour, utcNow.Minute, utcNow.Second); IssuedBy = issuedBy; } } public class JsonDateTimeConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { DateTime dateTime = new DateTime(reader.GetDateTime().Ticks / 10000000 * 10000000); if (dateTime.Kind != DateTimeKind.Utc) { return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); } return dateTime; } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ssZ")); } } public class Database { public static readonly JsonSerializerOptions prettyJsonOptions = new JsonSerializerOptions { WriteIndented = true, IncludeFields = true }; public static string BannedFile = Path.Combine(Plugin.ConfigFiles, "bans_server.json"); public static string ChatBanFile = Path.Combine(Plugin.ConfigFiles, "bans_chat.json"); public static string VoiceBanFile = Path.Combine(Plugin.ConfigFiles, "bans_voice.json"); public static string MessageFile = Path.Combine(Plugin.ConfigFiles, "messages.json"); public static string DeleteFile = Path.Combine(Plugin.ConfigFiles, "ignore.json"); public static string TrustedFile = Path.Combine(Plugin.ConfigFiles, "trusted.json"); public static string TrustFile = Path.Combine(Plugin.ConfigFiles, "trust.json"); public static List<Ban> Banned; public static List<Ban> ChatBans; public static List<Ban> VoiceBans; public static List<MessagePair> Messages; public static List<DeleteLater> Deletes; public static List<ulong> TrustedUsers; public static List<Trust> TrustCommands; public static dynamic SQL { get { if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("CrimsonSQL", out var value)) { return null; } return value.Instance.GetType().GetProperty("SQLService").GetValue(value.Instance); } } public Database() { LoadDatabases(); } private static void LoadDatabases() { if (!Directory.Exists(Plugin.ConfigFiles)) { Directory.CreateDirectory(Plugin.ConfigFiles); } if (File.Exists(ChatBanFile)) { ChatBans = JsonSerializer.Deserialize<List<Ban>>(File.ReadAllText(ChatBanFile), prettyJsonOptions); } else { ChatBans = new List<Ban>(); } if (File.Exists(VoiceBanFile)) { VoiceBans = JsonSerializer.Deserialize<List<Ban>>(File.ReadAllText(VoiceBanFile), prettyJsonOptions); } else { VoiceBans = new List<Ban>(); } if (File.Exists(BannedFile)) { Banned = JsonSerializer.Deserialize<List<Ban>>(File.ReadAllText(BannedFile), prettyJsonOptions); } else { Banned = new List<Ban>(); } if (File.Exists(DeleteFile)) { Deletes = JsonSerializer.Deserialize<List<DeleteLater>>(File.ReadAllText(DeleteFile), prettyJsonOptions); } else { Deletes = new List<DeleteLater>(); } if (File.Exists(MessageFile)) { Messages = JsonSerializer.Deserialize<List<MessagePair>>(File.ReadAllText(MessageFile), prettyJsonOptions); } else { Messages = new List<MessagePair>(4) { new MessagePair("CheckHeader", "\n{player}'s ({id}) Bans:"), new MessagePair("CheckBanLine", "\n{type} Ban\nIssued: {issued}\nRemaining: {remainder}\nReason: {reason}"), new MessagePair("ListBan", "\n{player} ({id}) - {remainder}"), new MessagePair("AppendedNotification", "") }; string contents = JsonSerializer.Serialize(Messages, prettyJsonOptions); File.WriteAllText(MessageFile, contents); } if (SQL != null && Settings.UseSQL.Value && SQLlink.Connect()) { StartSQLConnection(); } if (Settings.Trusted.Value) { if (File.Exists(TrustedFile)) { TrustedUsers = JsonSerializer.Deserialize<List<ulong>>(File.ReadAllText(TrustedFile), prettyJsonOptions); } else { TrustedUsers = new List<ulong>(); string contents2 = JsonSerializer.Serialize(TrustedUsers, prettyJsonOptions); File.WriteAllText(TrustedFile, contents2); } if (File.Exists(TrustFile)) { TrustCommands = JsonSerializer.Deserialize<List<Trust>>(File.ReadAllText(TrustFile), prettyJsonOptions); } else { TrustCommands = new List<Trust>(10) { new Trust("?mute {playerName} {reason}", ".ban mute {playerName} 30 min {reason}"), new Trust("?ban {playerName} {reason}", ".ban server {playerName} 30 min {reason}"), new Trust("?chat {playerName} {reason}", ".ban chat {playerName} 30 min {reason}"), new Trust("?voice {playerName} {reason}", ".ban voice {playerName} 30 min {reason}"), new Trust("?unmute {playerName}", ".unban mute {playerName}"), new Trust("?unban {playerName}", ".unban server {playerName}"), new Trust("?unbanchat {playerName}", ".unban chat {playerName}"), new Trust("?unbanvoice {playerName}", ".unban voice {playerName}"), new Trust("?list {banType} {show} {page}", ".banned list {banType} {show} {page}"), new Trust("?check {playerName}", ".banned check {playerName}") }; string contents3 = JsonSerializer.Serialize(TrustCommands, prettyJsonOptions); File.WriteAllText(TrustFile, contents3); } } Core.StartCoroutine(Clean()); } public static bool AddTrusted(ulong id) { if (TrustedUsers.Contains(id)) { return false; } TrustedUsers.Add(id); SaveTrusted(); return true; } public static bool RemoveTrusted(ulong id) { return TrustedUsers.Remove(id); } private static void SaveTrusted() { string contents = JsonSerializer.Serialize(TrustedUsers, prettyJsonOptions); File.WriteAllText(TrustedFile, contents); } private static async void StartSQLConnection() { SQLlink.InitializeBanTables(); await Task.Yield(); SQLUtility.SyncDB(); Core.StartCoroutine(SyncLoop()); } public static void AddBan(Ban ban, List<Ban> list) { if (list.Exists((Ban x) => x.DatabaseId == ban.DatabaseId)) { return; } string empty = string.Empty; if (list == ChatBans) { empty = "Chat"; ChatBans.Add(ban); } else if (list == VoiceBans) { empty = "Voice"; VoiceBans.Add(ban); } else { empty = "Server"; Banned.Add(ban); if (File.Exists(Settings.BanFilePath.Value) && !File.ReadAllLines(Settings.BanFilePath.Value).Contains(ban.PlayerID.ToString())) { File.AppendAllText(Settings.BanFilePath.Value, ban.PlayerID + Environment.NewLine); } } string empty2 = string.Empty; string value = TimeUtility.FormatRemainder(ban.TimeUntil - ban.Issued); empty2 = ((!ban.LocalBan) ? $"A player with ID: {ban.PlayerID} has had their {empty} ban synced from SQL. Originally issued by {ban.IssuedBy} with {value} remaining." : $"{ban.PlayerName} with ID: {ban.PlayerID} has been {empty} banned. Issued by {ban.IssuedBy} for {value}."); Plugin.LogMessage(empty2); SaveDatabases(); } public static void DeleteBan(Ban ban, List<Ban> list) { string empty = string.Empty; if (list == ChatBans) { empty = "Chat"; ChatBans.Remove(ban); } else if (list == VoiceBans) { empty = "Voice"; VoiceBans.Remove(ban); } else { empty = "Server"; Banned.Remove(ban); if (File.Exists(Settings.BanFilePath.Value)) { List<string> list2 = File.ReadAllLines(Settings.BanFilePath.Value).ToList(); list2.RemoveAll((string line) => line.Trim() == ban.PlayerID.ToString()); File.WriteAllLines(Settings.BanFilePath.Value, list2); } } string empty2 = string.Empty; empty2 = ((!ban.LocalBan) ? $"{empty} ban has ended for synced player ID: {ban.PlayerID}." : (empty + " ban has ended for " + ban.PlayerName + ".")); Plugin.LogMessage(empty2); if (SQLUtility.TrySQL()) { SQLlink.DeleteBan(ban, list); } else if (SQL != null) { Deletes.Add(new DeleteLater(ban.DatabaseId, empty + "Bans")); } SaveDatabases(); } public static void SaveDatabases() { if (ChatBans.Count > 0 || File.Exists(ChatBanFile)) { string contents = JsonSerializer.Serialize(ChatBans, prettyJsonOptions); File.WriteAllText(ChatBanFile, contents); } if (VoiceBans.Count > 0 || File.Exists(VoiceBanFile)) { string contents2 = JsonSerializer.Serialize(VoiceBans, prettyJsonOptions); File.WriteAllText(VoiceBanFile, contents2); } if (Banned.Count > 0 || File.Exists(BannedFile)) { string contents3 = JsonSerializer.Serialize(Banned, prettyJsonOptions); File.WriteAllText(BannedFile, contents3); } if (Deletes.Count > 0 || File.Exists(DeleteFile)) { string contents4 = JsonSerializer.Serialize(Deletes, prettyJsonOptions); File.WriteAllText(DeleteFile, contents4); } } private static IEnumerator SyncLoop() { while (true) { BanListFix(); yield return (object)new WaitForSeconds((float)(Settings.SyncInterval.Value * 60 + Random.Range(-10, 20))); SQLUtility.SyncDB(); } } public static void BanListFix(List<Ban> additional = null) { List<Ban> list = Banned.Where((Ban ban) => !TimeUtility.IsPermanent(ban.TimeUntil) && ban.TimeUntil < DateTime.UtcNow).ToList(); if (additional != null) { list = list.Concat(additional).ToList(); } foreach (Ban ban2 in list) { DeleteBan(ban2, Banned); if (File.Exists(Settings.BanFilePath.Value)) { List<string> list2 = File.ReadAllLines(Settings.BanFilePath.Value).ToList(); list2.RemoveAll((string line) => line.Trim() == ban2.PlayerID.ToString()); File.WriteAllLines(Settings.BanFilePath.Value, list2); } } } private static IEnumerator Clean() { while (true) { yield return (object)new WaitForSeconds(60f); List<Ban> list = Banned.Where((Ban ban) => !TimeUtility.IsPermanent(ban.TimeUntil) && ban.TimeUntil < DateTime.UtcNow).ToList(); List<Ban> list2 = ChatBans.Where((Ban ban) => !TimeUtility.IsPermanent(ban.TimeUntil) && ban.TimeUntil < DateTime.UtcNow).ToList(); List<Ban> list3 = VoiceBans.Where((Ban ban) => !TimeUtility.IsPermanent(ban.TimeUntil) && ban.TimeUntil < DateTime.UtcNow).ToList(); foreach (Ban item in list) { DeleteBan(item, Banned); } foreach (Ban item2 in list2) { DeleteBan(item2, ChatBans); } foreach (Ban item3 in list3) { DeleteBan(item3, VoiceBans); } } } } public struct DeleteLater { public int ID { get; set; } public string TableName { get; set; } public DeleteLater(int id, string tableName) { ID = id; TableName = tableName; } } [StructLayout(LayoutKind.Sequential, Size = 1)] public readonly struct Settings { private const string ConfigHeader = "_Config"; private const string ServerHeader = "ServerConnection"; private static readonly List<string> directoryPaths = new List<string>(1) { Plugin.ConfigFiles }; public static ConfigEntry<bool> ShadowBan { get; private set; } public static ConfigEntry<string> BanFilePath { get; private set; } public static ConfigEntry<bool> Trusted { get; private set; } public static ConfigEntry<bool> UseSQL { get; private set; } public static ConfigEntry<int> SyncInterval { get; private set; } public static void InitConfig() { foreach (string directoryPath in directoryPaths) { CreateDirectories(directoryPath); } ShadowBan = InitConfigEntry("_Config", "ShadowBan", defaultValue: false, "If this is set to true, the player will never be notified when chat or voice banned."); BanFilePath = InitConfigEntry("_Config", "BanFilePath", "save-data/Settings/banlist.txt", "The path from root to the banlist.txt file"); Trusted = InitConfigEntry("_Config", "Trusted", defaultValue: false, "If this is set to true, you can assign trusted members to moderate using predefined commands from trust.json"); if (Database.SQL != null) { UseSQL = InitConfigEntry("ServerConnection", "UseSQL", defaultValue: false, "If this is set to true, the plugin will use CrimsonSQL to store bans."); SyncInterval = InitConfigEntry("ServerConnection", "SyncInterval", 60, "The interval in minutes to sync the database."); } } private static ConfigEntry<T> InitConfigEntry<T>(string section, string key, T defaultValue, string description) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<T> val = ((BasePlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, description); string text = Path.Combine(Paths.ConfigPath, "CrimsonBanned.cfg"); ConfigEntry<T> val2 = default(ConfigEntry<T>); if (File.Exists(text) && new ConfigFile(text, true).TryGetEntry<T>(section, key, ref val2)) { val.Value = val2.Value; } return val; } private static void CreateDirectories(string path) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } public static class SQLlink { public static void InitializeBanTables() { Dictionary<string, string> dictionary = new Dictionary<string, string> { ["Id"] = "INT AUTO_INCREMENT PRIMARY KEY", ["PlayerName"] = "VARCHAR(255)", ["PlayerID"] = "BIGINT UNSIGNED NOT NULL UNIQUE", ["TimeUntil"] = "DATETIME NOT NULL", ["Reason"] = "TEXT", ["Issued"] = "DATETIME NOT NULL", ["IssuedBy"] = "VARCHAR(255)" }; Database.SQL.CreateTable("ServerBans", dictionary); Database.SQL.CreateTable("ChatBans", dictionary); Database.SQL.CreateTable("VoiceBans", dictionary); } public static int AddBan(Ban ban, List<Ban> list) { Dictionary<string, object> dictionary = new Dictionary<string, object> { ["PlayerName"] = ban.PlayerName, ["PlayerID"] = ban.PlayerID, ["TimeUntil"] = ban.TimeUntil, ["Reason"] = ban.Reason, ["Issued"] = ban.Issued, ["IssuedBy"] = ban.IssuedBy }; string text = ((list == Database.ChatBans) ? "ChatBans" : ((list == Database.VoiceBans) ? "VoiceBans" : "ServerBans")); List<int> list2 = new List<int> { -1062, -1042 }; int num = Database.SQL.Insert(text, dictionary, list2); if (num == -1042) { num = -1; } return num; } public static void DeleteBan(Ban ban, List<Ban> list) { Dictionary<string, object> dictionary = new Dictionary<string, object> { ["Id"] = ban.DatabaseId }; string text = ((list == Database.ChatBans) ? "ChatBans" : ((list == Database.VoiceBans) ? "VoiceBans" : "ServerBans")); Database.SQL.Delete(text, dictionary); } public static void DeleteBan(int id, string tableName) { Dictionary<string, object> dictionary = new Dictionary<string, object> { ["Id"] = id }; Database.SQL.Delete(tableName, dictionary); } public static Ban GetBan(ulong playerID, List<Ban> list) { Dictionary<string, object> dictionary = new Dictionary<string, object> { ["PlayerID"] = playerID }; string text = ((list == Database.ChatBans) ? "ChatBans" : ((list == Database.VoiceBans) ? "VoiceBans" : "ServerBans")); dynamic val = Database.SQL.Select(text, new string[1] { "*" }, dictionary); if (val != null && val.Rows.Count > 0) { dynamic val2 = val.Rows[0]; Ban ban = new Ban(val2["PlayerName"].ToString(), Convert.ToUInt64(val2["PlayerID"]), Convert.ToDateTime(val2["TimeUntil"]), val2["Reason"].ToString(), val2["IssuedBy"].ToString()); ban.DatabaseId = Convert.ToInt32(val2["Id"]); ban.Issued = Convert.ToDateTime(val2["Issued"]); return ban; } return null; } public static bool Connect() { if (Database.SQL == null) { return false; } return Database.SQL.Connect(); } } } namespace CrimsonBanned.Patches { [HarmonyPatch] public static class ChatMessagePatch { [HarmonyPatch(typeof(ChatMessageSystem), "OnUpdate")] public static bool Prefix(ChatMessageSystem __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) _ = __instance.__query_661171423_0; EntityQuery _query_661171423_ = __instance.__query_661171423_0; Enumerator<Entity> enumerator = ((EntityQuery)(ref _query_661171423_)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)).GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; FromCharacter componentData = ((EntityManager)(ref entityManager)).GetComponentData<FromCharacter>(current); entityManager = ((ComponentSystemBase)__instance).EntityManager; User userData = ((EntityManager)(ref entityManager)).GetComponentData<User>(componentData.User); entityManager = ((ComponentSystemBase)__instance).EntityManager; ChatMessageEvent componentData2 = ((EntityManager)(ref entityManager)).GetComponentData<ChatMessageEvent>(current); string messageText = ((object)(FixedString512Bytes)(ref componentData2.MessageText)).ToString(); if ((int)componentData2.MessageType == 5) { continue; } if (HandleTrustedCommand(userData, messageText)) { entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(current); } else if (HandleTrustedHelp(userData, messageText)) { entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(current); } else if (Database.Banned.Exists((Ban x) => x.PlayerID == userData.PlatformId)) { entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(current); } else if (Database.ChatBans.Exists((Ban x) => x.PlayerID == userData.PlatformId)) { Ban ban = Database.ChatBans.First((Ban x) => x.PlayerID == userData.PlatformId); if (DateTime.UtcNow > ban.TimeUntil && !TimeUtility.IsPermanent(ban.TimeUntil)) { Database.ChatBans.Remove(ban); ChatUtil.SystemSendUser(userData, "Your chat ban has ended."); } else { entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(current); } } } return true; } private static bool HandleTrustedHelp(User userData, string messageText) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (Database.TrustedUsers == null || Database.TrustedUsers.Count == 0) { return false; } if (Database.TrustedUsers.Contains(userData.PlatformId)) { if (Database.TrustCommands == null || Database.TrustCommands.Count == 0) { return false; } if (messageText.StartsWith($"{Database.TrustCommands[0].Alias[0]}modhelp")) { string text = "\n"; foreach (Trust trustCommand in Database.TrustCommands) { text = text + trustCommand.Alias + " \n"; } ChatUtil.SystemSendUser(userData, text); return true; } } return false; } private static bool HandleTrustedCommand(User userData, string messageText) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) if (Database.TrustedUsers == null || Database.TrustedUsers.Count == 0) { return false; } if (Database.TrustedUsers.Contains(userData.PlatformId)) { if (Database.TrustCommands == null || Database.TrustCommands.Count == 0) { return false; } foreach (Trust trustCommand in Database.TrustCommands) { string[] array = messageText.Split(' '); string[] array2 = trustCommand.Alias.Split(' '); if (array.Length < array2.Length) { continue; } bool flag = true; string newValue = ""; string newValue2 = ""; string newValue3 = ""; string newValue4 = ""; string newValue5 = ""; for (int i = 0; i < array2.Length; i++) { if (array2[i] == "{playerName}") { newValue = array[i]; continue; } if (array2[i] == "{reason}") { newValue2 = string.Join(" ", array.Skip(i)); newValue2 = newValue2.Trim('"'); break; } if (array2[i] == "{banType}") { newValue3 = array[i]; } else if (array2[i] == "{show}") { newValue4 = array[i]; } else if (array2[i] == "{page}") { newValue5 = array[i]; } else if (array2[i] != array[i]) { flag = false; break; } } if (!flag) { continue; } string[] array3 = trustCommand.Command.Replace("{playerName}", newValue).Replace("{reason}", newValue2).Replace("{banType}", newValue3) .Replace("{show}", newValue4) .Replace("{page}", newValue5) .Split(' '); if (array3[0] == ".ban") { switch (array3[1].ToLower()) { case "mute": BanCommands.Mute(userData, array3[2], int.Parse(array3[3]), array3[4], string.Join(" ", array3.Skip(5))); return true; case "chat": BanCommands.BanFromChat(userData, array3[2], int.Parse(array3[3]), array3[4], string.Join(" ", array3.Skip(5))); return true; case "voice": BanCommands.BanFromVoice(userData, array3[2], int.Parse(array3[3]), array3[4], string.Join(" ", array3.Skip(5))); return true; case "server": BanCommands.Ban(userData, array3[2], int.Parse(array3[3]), array3[4], string.Join(" ", array3.Skip(5))); return true; } } else if (array3[0] == ".unban") { switch (array3[1].ToLower()) { case "mute": UnbanCommands.Unmute(userData, array3[2]); return true; case "chat": UnbanCommands.UnbanFromChat(userData, array3[2]); return true; case "voice": UnbanCommands.UnbanFromVoice(userData, array3[2]); return true; case "server": UnbanCommands.Unban(userData, array3[2]); return true; } } else { if (!(array3[0] == ".banned")) { continue; } string text = array3[1].ToLower(); if (text == "list") { if (int.TryParse(array3[4], out var result)) { if (result < 1) { result = 1; } BannedCommands.List(userData, array3[2], array3[3], result); } else { BannedCommands.List(userData, array3[2], array3[3]); } return true; } if (text == "check") { BannedCommands.Check(userData, array3[2]); return true; } } } } return false; } } [HarmonyPatch(typeof(ServerBootstrapSystem), "OnUserConnected")] public static class OnUserConnectedPatcch { public static void Postfix(ServerBootstrapSystem __instance, NetConnectionId netConnectionId) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) try { _ = ((ComponentSystemBase)__instance).EntityManager; int num = __instance._NetEndPointToApprovedUserIndex[netConnectionId]; Entity userEntity = ((Il2CppArrayBase<ServerClient>)(object)__instance._ApprovedUsersLookup)[num].UserEntity; EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; User userData = ((EntityManager)(ref entityManager)).GetComponentData<User>(userEntity); _ = ((FixedString64Bytes)(ref userData.CharacterName)).IsEmpty; if (Database.Banned.Exists((Ban x) => x.PlayerID == userData.PlatformId)) { Ban ban = Database.Banned.First((Ban x) => x.PlayerID == userData.PlatformId); if (DateTime.UtcNow > ban.TimeUntil) { Database.DeleteBan(ban, Database.Banned); return; } entityManager = Core.EntityManager; Entity val = ((EntityManager)(ref entityManager)).CreateEntity((ComponentType[])(object)new ComponentType[3] { ComponentType.ReadOnly<NetworkEventType>(), ComponentType.ReadOnly<SendEventToUser>(), ComponentType.ReadOnly<KickEvent>() }); EntityUtil.Write<KickEvent>(val, new KickEvent { PlatformId = userData.PlatformId }); EntityUtil.Write<SendEventToUser>(val, new SendEventToUser { UserIndex = userData.Index }); EntityUtil.Write<NetworkEventType>(val, new NetworkEventType { EventId = NetworkEvents.EventId_KickEvent, IsAdminEvent = false, IsDebugEvent = false }); } } catch (Exception ex) { ManualLogSource logInstance = Plugin.LogInstance; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(51, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failure in "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("OnUserConnected"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\nMessage: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Inner:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.InnerException?.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\n\nStack: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.StackTrace); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\nInner Stack: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.InnerException?.StackTrace); } logInstance.LogError(val2); } } } [HarmonyPatch] public static class VivoxPatch { [HarmonyPatch(typeof(VivoxConnectionSystem), "OnUpdate")] public static void Prefix(VivoxConnectionSystem __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) ProcessEntities(__instance.__query_337126773_0); ProcessEntities(__instance.__query_337126773_1); ProcessEntities(__instance.__query_337126773_2); ProcessEntities(__instance.__query_337126773_3); } private static void ProcessEntities(EntityQuery query) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) NativeArray<Entity> val = ((EntityQuery)(ref query)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator<Entity> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (EntityUtil.Has<FromCharacter>(current)) { User user = EntityUtil.Read<User>(EntityUtil.Read<FromCharacter>(current).User); HandleUser(current, user); } } val.Dispose(); } private static void HandleUser(Entity entity, User user) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager; if (Database.VoiceBans.Exists((Ban x) => x.PlayerID == user.PlatformId)) { Ban ban = Database.VoiceBans.First((Ban x) => x.PlayerID == user.PlatformId); if (!(DateTime.UtcNow > ban.TimeUntil) || TimeUtility.IsPermanent(ban.TimeUntil)) { if (EntityUtil.Has<ClientEvent>(entity)) { ClientEvent val = EntityUtil.Read<ClientEvent>(entity); val.Type = (VivoxRequestType)0; EntityUtil.Write<ClientEvent>(entity, val); } if (EntityUtil.Has<ClientStateEvent>(entity)) { ClientStateEvent val2 = EntityUtil.Read<ClientStateEvent>(entity); val2.IsSpeaking = false; EntityUtil.Write<ClientStateEvent>(entity, val2); } entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(entity); return; } Database.DeleteBan(ban, Database.VoiceBans); if (!Settings.ShadowBan.Value) { ChatUtil.SystemSendUser(user, "Your voice ban has expired. Please verify in your social settings that Voice Proximity is re-enabled."); } } if (Database.Banned.Exists((Ban x) => x.PlayerID == user.PlatformId)) { entityManager = Core.EntityManager; ((EntityManager)(ref entityManager)).DestroyEntity(entity); } } } } namespace CrimsonBanned.Commands { [CommandGroup("ban", null)] internal static class BanCommands { [Command("server", "s", null, null, null, true)] public static void Ban(ChatCommandContext ctx, string name, int length = 0, string timeunit = "day", string reason = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Task<(bool, Player)> task = HandleBanOperation(ctx.User, name, length, timeunit, Database.Banned, "banned from the server", isGameBan: true, reason); if (task.Result.Item1) { if (length > 0) { Core.StartCoroutine(DelayKick(task.Result.Item2)); } else { Kick(task.Result.Item2); } } } public static void Ban(User user, string name, int length, string timeunit, string reason) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Task<(bool, Player)> task = HandleBanOperation(user, name, length, timeunit, Database.Banned, "banned from the server", isGameBan: true, reason); if (task.Result.Item1) { if (length > 0) { Core.StartCoroutine(DelayKick(task.Result.Item2)); } else { Kick(task.Result.Item2); } } } [Command("chat", "c", null, null, null, true)] public static void BanFromChat(ChatCommandContext ctx, string name, int length = 30, string timeunit = "min", string reason = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleBanOperation(ctx.User, name, length, timeunit, Database.ChatBans, "banned from chat", isGameBan: false, reason); } public static void BanFromChat(User user, string name, int length = 30, string timeunit = "min", string reason = "") { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleBanOperation(user, name, length, timeunit, Database.ChatBans, "banned from chat", isGameBan: false, reason); } [Command("voice", "v", null, null, null, true)] public static void BanFromVoice(ChatCommandContext ctx, string name, int length = 30, string timeunit = "min", string reason = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleBanOperation(ctx.User, name, length, timeunit, Database.VoiceBans, "banned from voice chat", isGameBan: false, reason); } public static void BanFromVoice(User user, string name, int length = 30, string timeunit = "min", string reason = "") { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleBanOperation(user, name, length, timeunit, Database.VoiceBans, "banned from voice chat", isGameBan: false, reason); } [Command("mute", "m", null, null, null, true)] public static void Mute(ChatCommandContext ctx, string name, int length = 30, string timeunit = "min", string reason = "") { BanFromChat(ctx, name, length, timeunit, reason); BanFromVoice(ctx, name, length, timeunit, reason); } public static void Mute(User user, string name, int length = 30, string timeunit = "min", string reason = "") { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) BanFromChat(user, name, length, timeunit, reason); BanFromVoice(user, name, length, timeunit, reason); } [Command("kick", "k", null, null, null, true)] public static void KickPlayer(ChatCommandContext ctx, string name) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindByName(name, ref val)) { ctx.Reply("Could not find player with the name " + name + "."); } else if (EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity) == ctx.User) { ctx.Reply("You cannot kick yourself."); } else { Kick(PlayerService.PlayerFromData(val)); } } private static async Task<(bool Success, Player PlayerInfo)> HandleBanOperation(User ctx, string name, int length, string timeunit, List<Ban> banList, string banType, bool isGameBan = false, string reason = "") { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindByName(name, ref val)) { ChatUtil.SystemSendUser(ctx, "Could not find player with the name " + name + "."); return (false, null); } Player player = PlayerService.PlayerFromData(val); User user = EntityUtil.Read<User>(player.User); if (player.IsAdmin) { ChatUtil.SystemSendUser(ctx, "You cannot ban an admin."); return (false, null); } if (user == ctx) { ChatUtil.SystemSendUser(ctx, "You cannot ban yourself."); return (false, null); } if (length < 0) { ChatUtil.SystemSendUser(ctx, "Please input a valid length of time."); return (false, null); } TimeSpan timeSpan = TimeUtility.LengthParse(length, timeunit); DateTime dateTime = DateTime.UtcNow + timeSpan; if (reason == "") { reason = ""; } if (length == 0) { dateTime = TimeUtility.MinValueUtc; } if (banList.Exists((Ban x) => x.PlayerID == user.PlatformId)) { Ban ban2 = banList.First((Ban x) => x.PlayerID == user.PlatformId); if (TimeUtility.IsPermanent(ban2.TimeUntil)) { ChatUtil.SystemSendUser(ctx, name + " is already permanently " + banType + "."); return (false, null); } if (ban2.TimeUntil > dateTime) { ChatUtil.SystemSendUser(ctx, name + " is already " + banType + "."); return (false, null); } Database.DeleteBan(ban2, banList); } Ban ban = new Ban(((object)(FixedString64Bytes)(ref user.CharacterName)).ToString(), user.PlatformId, dateTime, reason, ((object)(FixedString64Bytes)(ref ctx.CharacterName)).ToString()) { LocalBan = true }; if (Database.SQL != null && Settings.UseSQL.Value) { if (SQLlink.Connect()) { int num = SQLlink.AddBan(ban, banList); if (num >= 0 || num == -1) { ban.DatabaseId = num; } else { switch (await SQLConflict.ResolveConflict(ban, banList)) { case 0: ChatUtil.SystemSendUser(ctx, name + " is already permanently " + banType + "."); return (false, null); case 1: ChatUtil.SystemSendUser(ctx, name + " already has an active ban with a longer length."); return (true, player); case 2: ChatUtil.SystemSendUser(ctx, $"{name} has been {banType} {((length == 0) ? "permanent" : ("for " + TimeUtility.FormatRemainder(timeSpan)))}"); return (true, player); case 4: ChatUtil.SystemSendUser(ctx, name + " is already " + banType + "."); return (false, null); } } } else { ban.DatabaseId = -1; } } else { ban.DatabaseId = -1; } Database.AddBan(ban, banList); ChatUtil.SystemSendUser(ctx, $"{name} has been {banType} {((length == 0) ? "permanently." : ("for " + TimeUtility.FormatRemainder(timeSpan)))}"); if (!Settings.ShadowBan.Value || isGameBan) { string text = (isGameBan ? $"You have been {banType} {((length == 0) ? "permanently" : ("for " + TimeUtility.FormatRemainder(timeSpan)))}." : $"You have been {banType} {((length == 0) ? "permanently" : ("for " + TimeUtility.FormatRemainder(timeSpan)))}."); ChatUtil.SystemSendUser(user, text + Database.Messages[3].ToString(ban)); } return (true, player); } public static IEnumerator DelayKick(Player player) { yield return (object)new WaitForSeconds(5f); Kick(player); } private static void Kick(Player player) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = Core.Server.EntityManager; User val = EntityUtil.Read<User>(player.User); if (val.PlatformId != 0L) { Entity val2 = ((EntityManager)(ref entityManager)).CreateEntity((ComponentType[])(object)new ComponentType[3] { ComponentType.ReadOnly<NetworkEventType>(), ComponentType.ReadOnly<SendEventToUser>(), ComponentType.ReadOnly<KickEvent>() }); EntityUtil.Write<KickEvent>(val2, new KickEvent { PlatformId = val.PlatformId }); EntityUtil.Write<SendEventToUser>(val2, new SendEventToUser { UserIndex = val.Index }); EntityUtil.Write<NetworkEventType>(val2, new NetworkEventType { EventId = NetworkEvents.EventId_KickEvent, IsAdminEvent = false, IsDebugEvent = false }); } } } [CommandGroup("banid", null)] internal static class BanIDCommands { [Command("server", "s", null, null, null, true)] public static void Ban(ChatCommandContext ctx, ulong id, int length = 0, string timeunit = "day", string reason = "") { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleBanOperation(ctx, id, length, timeunit, Database.Banned, "banned from the server", isServerBan: true, reason); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); BanCommands.Ban(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString(), length, timeunit, reason); } [Command("chat", "c", null, null, null, true)] public static void BanFromChat(ChatCommandContext ctx, ulong id, int length = 30, string timeunit = "min", string reason = "") { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleBanOperation(ctx, id, length, timeunit, Database.ChatBans, "banned from chat", isServerBan: false, reason); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); BanCommands.BanFromChat(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString(), length, timeunit, reason); } [Command("voice", "v", null, null, null, true)] public static void BanFromVoice(ChatCommandContext ctx, ulong id, int length = 30, string timeunit = "min", string reason = "") { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleBanOperation(ctx, id, length, timeunit, Database.VoiceBans, "banned from voice chat", isServerBan: false, reason); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); BanCommands.BanFromVoice(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString(), length, timeunit, reason); } [Command("mute", "m", null, null, null, true)] public static void Mute(ChatCommandContext ctx, ulong id, int length = 30, string timeunit = "min", string reason = "") { BanFromChat(ctx, id, length, timeunit, reason); BanFromVoice(ctx, id, length, timeunit, reason); } private static async void HandleBanOperation(ChatCommandContext ctx, ulong id, int length, string timeunit, List<Ban> list, string banType, bool isServerBan, string reason) { TimeSpan timeSpan = TimeUtility.LengthParse(length, timeunit); DateTime dateTime = DateTime.UtcNow + timeSpan; if (list.Exists((Ban x) => x.PlayerID == id)) { ctx.Reply($"Player {id} is already {banType}."); return; } if (length < 0) { ctx.Reply("Please input a valid length of time."); return; } if (length == 0) { dateTime = TimeUtility.MinValueUtc; } if (reason == "") { reason = ""; } string empty = string.Empty; ulong playerID = id; DateTime timeUntil = dateTime; string reason2 = reason; User user = ctx.User; Ban ban = new Ban(empty, playerID, timeUntil, reason2, ((object)(FixedString64Bytes)(ref user.CharacterName)).ToString()) { LocalBan = true }; if (Database.SQL != null && Settings.UseSQL.Value) { if (SQLlink.Connect()) { int num = SQLlink.AddBan(ban, list); if (num >= 0) { ban.DatabaseId = num; } else { switch (await SQLConflict.ResolveConflict(ban, list)) { case 0: ctx.Reply($"{id} is already permanently {banType}."); return; case 1: ctx.Reply($"{id} has had their previous ban imported from SQL with a longer duration."); return; case 2: ctx.Reply($"{id} has been {banType} {((length == 0) ? "permanently." : ("for " + TimeUtility.FormatRemainder(timeSpan) + "."))}"); return; } } } else { ban.DatabaseId = -1; } } else { ban.DatabaseId = -1; } Database.AddBan(ban, list); ctx.Reply($"Player {id} has been {banType}."); } } [CommandGroup("banned", null)] internal static class BannedCommands { private const int MESSAGE_LIMIT = 460; private const int MESSAGES_PER_PAGE = 2; [Command("list", "l", null, null, null, true)] public static void List(ChatCommandContext ctx, string banType = "server", string show = "perma/temp", int page = 1) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) List(ctx.User, banType, show, page); } public static void List(User ctx, string banType = "server", string show = "perma/temp", int page = 1) { //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) banType = banType.ToLower() switch { "server" => "Server", "s" => "Server", "chat" => "Chat", "c" => "Chat", "voice" => "Voice", "v" => "Voice", _ => "Server", }; List<Ban> list = banType switch { "Server" => Database.Banned, "Chat" => Database.ChatBans, "Voice" => Database.VoiceBans, _ => new List<Ban>(), }; show = show switch { "perma" => "perma", "temp" => "temp", "p" => "perma", "t" => "temp", _ => "perma/temp", }; if (show == "temp") { list = list.FindAll((Ban x) => !TimeUtility.IsPermanent(x.TimeUntil)); } else if (show == "perma") { list = list.FindAll((Ban x) => TimeUtility.IsPermanent(x.TimeUntil)); } if (list.Count == 0) { ChatUtil.SystemSendUser(ctx, "No players in this ban list."); return; } list.Sort((Ban x, Ban y) => y.Issued.CompareTo(x.Issued)); string item = "\n" + banType + " Bans:\n"; List<string> list2 = new List<string> { item }; int num = 0; foreach (Ban item2 in list) { string text = Database.Messages[2].ToString(item2); if (list2[num].Length + text.Length > 460) { num++; list2.Add(text); } else { list2[num] += text; } } int num2 = (int)Math.Ceiling((double)list2.Count / 2.0); if (page < 1 || page > num2) { page = 1; } int num3 = (page - 1) * 2; int num4 = Math.Min(num3 + 2, list2.Count); if (num2 > 1) { ChatUtil.SystemSendUser(ctx, $"Page {page} of {num2}:"); } for (int i = num3; i < num4; i++) { ChatUtil.SystemSendUser(ctx, list2[i]); } } [Command("loaduntracked", null, null, null, null, true)] public static void Backlog(ChatCommandContext ctx) { SQLUtility.SyncDB(); if (File.Exists(Settings.BanFilePath.Value)) { string[] array = File.ReadAllLines(Settings.BanFilePath.Value); foreach (string line in array) { if (!Database.Banned.Exists((Ban x) => x.PlayerID == Convert.ToUInt64(line))) { Database.AddBan(new Ban(string.Empty, Convert.ToUInt64(line), TimeUtility.MinValueUtc, "", "banlist.txt") { LocalBan = true, DatabaseId = -1 }, Database.Banned); } } ctx.Reply("Untracked server bans in banlist.txt imported and added to tracking."); } else { ctx.Reply("Local banlist.txt not found. Please specify the file path."); } } [Command("sync", null, null, null, null, true)] public static void Sync(ChatCommandContext ctx) { if (Database.SQL == null) { ctx.Reply("MySQL is not configured. Please configure MySQL using CrimsonSQL."); return; } if (!Settings.UseSQL.Value) { ctx.Reply("You are not using CrimsonSQL. Ensure it is installed and the setting is set to true."); return; } if (!SQLlink.Connect()) { ctx.Reply("Connection could not be established with the SQL database."); return; } SQLUtility.SyncDB(); ctx.Reply("Bans have been synced with SQL Database."); } [Command("checkid", null, null, null, null, true)] public static void CheckID(ChatCommandContext ctx, string id) { //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) ulong ID = Convert.ToUInt64(id); List<(Ban, BanDetails)> list = new List<(Ban, BanDetails)>(); List<Ban> list2 = new List<Ban>(); Ban ban = Database.Banned?.Find((Ban x) => x.PlayerID == ID); if (ban != null) { list2.Add(ban); } Ban ban2 = Database.ChatBans?.Find((Ban x) => x.PlayerID == ID); if (ban2 != null) { list2.Add(ban2); } Ban ban3 = Database.VoiceBans?.Find((Ban x) => x.PlayerID == ID); if (ban3 != null) { list2.Add(ban3); } if (list2.Count == 0) { ctx.Reply($"No bans found for ID {ID}."); return; } bool flag = false; foreach (Ban item3 in list2) { if (item3 == null) { continue; } if (!item3.LocalBan) { flag = true; } Ban ban4 = item3; List<Ban> list3; if (Database.Banned.Contains(ban4)) { list3 = Database.Banned; } else { Ban item = ban4; if (Database.ChatBans.Contains(item)) { list3 = Database.ChatBans; } else { Ban item2 = ban4; list3 = ((!Database.VoiceBans.Contains(item2)) ? null : Database.VoiceBans); } } List<Ban> list4 = list3; if (list4 != null && GetBanDetails(item3, list4, out var details)) { list.Add((item3, details)); } } if (list.Count == 0) { ctx.Reply($"No bans found for ID {ID}."); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(Database.Messages[0].ToString(list[0].Item1, list[0].Item2)); PlayerData val = default(PlayerData); if (PlayerService.TryFindBySteam(ID, ref val) && flag) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(19, 1, stringBuilder2); handler.AppendLiteral("Local server name: "); User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); handler.AppendFormatted(((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString()); stringBuilder2.AppendLine(ref handler); } foreach (var item4 in list) { stringBuilder.AppendLine(Database.Messages[1].ToString(item4.Item1, item4.Item2)); } ctx.Reply(stringBuilder.ToString()); } [Command("check", null, null, null, null, true)] public static void Check(ChatCommandContext ctx, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Check(ctx.User, name); } public static void Check(User ctx, string name) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindByName(name, ref val)) { ChatUtil.SystemSendUser(ctx, "Could not find player with the name " + name + "."); return; } Player val2 = PlayerService.PlayerFromData(val); User user = EntityUtil.Read<User>(val2.User); List<(Ban, BanDetails)> list = new List<(Ban, BanDetails)>(); foreach (Ban item3 in new List<Ban> { Database.ChatBans.Find((Ban x) => x.PlayerID == user.PlatformId), Database.VoiceBans.Find((Ban x) => x.PlayerID == user.PlatformId), Database.Banned.Find((Ban x) => x.PlayerID == user.PlatformId) }) { if (item3 == null) { continue; } Ban ban = item3; List<Ban> list2; if (Database.Banned.Contains(ban)) { list2 = Database.Banned; } else { Ban item = ban; if (Database.ChatBans.Contains(item)) { list2 = Database.ChatBans; } else { Ban item2 = ban; list2 = ((!Database.VoiceBans.Contains(item2)) ? null : Database.VoiceBans); } } List<Ban> list3 = list2; if (list3 != null && GetBanDetails(item3, list3, out var details)) { list.Add((item3, details)); } } if (list.Count == 0) { ChatUtil.SystemSendUser(ctx, name + " is not banned."); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(Database.Messages[0].ToString(list[0].Item1, list[0].Item2)); foreach (var item4 in list) { stringBuilder.AppendLine(Database.Messages[1].ToString(item4.Item1, item4.Item2)); } ChatUtil.SystemSendUser(ctx, stringBuilder.ToString()); } internal static bool GetBanDetails(Ban ban, List<Ban> list, out BanDetails details) { if (!TimeUtility.IsPermanent(ban.TimeUntil) && DateTime.UtcNow > ban.TimeUntil) { details = null; Database.DeleteBan(ban, list); return false; } details = new BanDetails(); details.Ban = ban; details.IssuedOn = ban.Issued.ToLocalTime().ToString("MM/dd/yy HH:mm"); if (list == Database.Banned) { details.BanType = "Server"; } else if (list == Database.ChatBans) { details.BanType = "Chat"; } else if (list == Database.VoiceBans) { details.BanType = "Voice"; } if (TimeUtility.IsPermanent(ban.TimeUntil)) { details.RemainingTime = "Permanent"; } else { details.RemainingTime = $"Expires in {ban.TimeUntil - DateTime.UtcNow}"; } return true; } } public class BanDetails { public Ban Ban { get; set; } public string BanType { get; set; } public string IssuedOn { get; set; } public string RemainingTime { get; set; } } [CommandGroup("trusted", null)] internal static class TrustCommands { [Command("add", "a", null, null, null, true)] public static void Add(ChatCommandContext ctx, string playerName) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) PlayerData playerInfo = default(PlayerData); if (!PlayerService.TryFindByName(playerName, ref playerInfo)) { ctx.Reply("Could not find player with the name " + playerName + "."); return; } if (Database.TrustedUsers.Any((ulong t) => t == EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId)) { ctx.Reply(playerName + " is already trusted."); return; } Database.AddTrusted(EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId); ctx.Reply(playerName + " has been added to the trusted list."); } [Command("remove", "r", null, null, null, true)] public static void Remove(ChatCommandContext ctx, string playerName) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) PlayerData playerInfo = default(PlayerData); if (!PlayerService.TryFindByName(playerName, ref playerInfo)) { ctx.Reply("Could not find player with the name " + playerName + "."); return; } if (!Database.TrustedUsers.Any((ulong t) => t == EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId)) { ctx.Reply(playerName + " is not on the trusted list."); return; } Database.RemoveTrusted(EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId); ctx.Reply(playerName + " has been removed from the trusted list."); } } [CommandGroup("unban", null)] internal static class UnbanCommands { [Command("server", "s", null, null, null, true)] public static void Unban(ChatCommandContext ctx, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(ctx.User, name, Database.Banned, "unbanned from the server", "the server"); } public static void Unban(User user, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(user, name, Database.Banned, "unbanned from the server", "the server"); } [Command("chat", "c", null, null, null, true)] public static void UnbanFromChat(ChatCommandContext ctx, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(ctx.User, name, Database.ChatBans, "unbanned from chat", "chat"); } public static void UnbanFromChat(User user, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(user, name, Database.ChatBans, "unbanned from chat", "chat"); } [Command("voice", "v", null, null, null, true)] public static void UnbanFromVoice(ChatCommandContext ctx, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(ctx.User, name, Database.VoiceBans, "unbanned from voice chat", "voice chat"); } public static void UnbanFromVoice(User user, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleUnbanOperation(user, name, Database.VoiceBans, "unbanned from voice chat", "voice chat"); } [Command("mute", "m", null, null, null, true)] public static void Unmute(ChatCommandContext ctx, string name) { UnbanFromChat(ctx, name); UnbanFromVoice(ctx, name); } public static void Unmute(User user, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) UnbanFromChat(user, name); UnbanFromVoice(user, name); } private static void HandleUnbanOperation(User ctx, string name, List<Ban> banList, string unbanType, string noneFound) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) PlayerData playerInfo = default(PlayerData); if (!PlayerService.TryFindByName(name, ref playerInfo)) { ChatUtil.SystemSendUser(ctx, "Could not find player with the name " + name + "."); return; } if (!banList.Exists((Ban x) => x.PlayerID == EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId)) { ChatUtil.SystemSendUser(ctx, name + " is not banned from " + noneFound + "."); return; } Ban ban = banList.First((Ban x) => x.PlayerID == EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity).PlatformId); if (!ctx.IsAdmin && Database.TrustedUsers.Contains(ctx.PlatformId) && ban.IssuedBy != ((object)(FixedString64Bytes)(ref ctx.CharacterName)).ToString()) { ChatUtil.SystemSendUser(ctx, $"You are not allowed to unban {name} from {noneFound}."); return; } Database.DeleteBan(ban, banList); ChatUtil.SystemSendUser(ctx, name + " has been " + unbanType + "."); if (!unbanType.Contains("server") && !Settings.ShadowBan.Value) { ChatUtil.SystemSendUser(EntityUtil.Read<User>(((PlayerData)(ref playerInfo)).UserEntity), "You have been " + unbanType + "."); } if (unbanType.Contains("server") && File.Exists(Settings.BanFilePath.Value)) { List<string> list = File.ReadAllLines(Settings.BanFilePath.Value).ToList(); list.RemoveAll((string line) => line.Trim() == ban.PlayerID.ToString()); File.WriteAllLines(Settings.BanFilePath.Value, list); } } } [CommandGroup("unbanid", null)] internal static class UnbanIDCommands { [Command("server", "s", null, null, null, true)] public static void Unban(ChatCommandContext ctx, ulong id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleUnbanOperation(ctx, id, Database.Banned, "unbanned from the server", "the server"); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); UnbanCommands.Unban(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString()); } [Command("chat", "c", null, null, null, true)] public static void UnbanFromChat(ChatCommandContext ctx, ulong id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleUnbanOperation(ctx, id, Database.ChatBans, "unbanned from chat", "chat"); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); UnbanCommands.UnbanFromChat(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString()); } [Command("voice", "v", null, null, null, true)] public static void UnbanFromVoice(ChatCommandContext ctx, ulong id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) PlayerData val = default(PlayerData); if (!PlayerService.TryFindBySteam(id, ref val)) { HandleUnbanOperation(ctx, id, Database.VoiceBans, "unbanned from voice chat", "voice chat"); return; } User val2 = EntityUtil.Read<User>(((PlayerData)(ref val)).UserEntity); UnbanCommands.UnbanFromVoice(ctx, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString()); } [Command("mute", "m", null, null, null, true)] public static void Unmute(ChatCommandContext ctx, ulong id) { UnbanFromChat(ctx, id); UnbanFromVoice(ctx, id); } private static void HandleUnbanOperation(ChatCommandContext ctx, ulong id, List<Ban> banList, string unbanType, string noneFound) { if (!banList.Exists((Ban x) => x.PlayerID == id)) { ctx.Reply($"{id} is not banned from {noneFound}."); return; } Ban ban = banList.First((Ban x) => x.PlayerID == id); Database.DeleteBan(ban, banList); ctx.Reply($"{id} has been {unbanType}."); if (unbanType.Contains("server") && File.Exists(Settings.BanFilePath.Value)) { List<string> list = File.ReadAllLines(Settings.BanFilePath.Value).ToList(); list.RemoveAll((string line) => line.Trim() == ban.PlayerID.ToString()); File.WriteAllLines(Settings.BanFilePath.Value, list); } } } }