Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Moderator v1.0.11
Landoria.Moderator.dll
Decompiled 6 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Landoria.SharedLib; using Splatform; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Landoria.Moderator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Landoria.Moderator")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("CA2ABD79-CB95-41E2-999B-52AE9310670C")] [assembly: AssemblyFileVersion("1.0.11")] [assembly: AssemblyInformationalVersion("1.0.11")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.11.13998")] namespace Landoria.Moderator { internal static class AdminAccess { private const string RequestRpc = "Landoria_Moderator_AdminRequest"; private const string ResponseRpc = "Landoria_Moderator_AdminResponse"; private static ZRoutedRpc _registeredRpc; private static bool _serverConfirmedAdmin; private static bool _requestSent; internal static bool LocalPlayerIsAdminOrHost() { if ((Object)(object)ZNet.instance != (Object)null) { if (!ZNet.instance.IsServer()) { return _serverConfirmedAdmin; } return true; } return false; } internal static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register("Landoria_Moderator_AdminRequest", (Action<long>)ReceiveRequest); instance.Register<bool>("Landoria_Moderator_AdminResponse", (Action<long, bool>)ReceiveResponse); _registeredRpc = instance; ModeratorPlugin.ModLogger.LogDebug("Administrator validation RPCs registered."); } } internal static void RequestStatus() { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZRoutedRpc.instance != null && !_requestSent) { _serverConfirmedAdmin = false; _requestSent = true; ZRoutedRpc.instance.InvokeRoutedRPC("Landoria_Moderator_AdminRequest", Array.Empty<object>()); ModeratorPlugin.ModLogger.LogDebug("Requested administrator validation from the server."); } } internal static void ResetSession() { _registeredRpc = null; _serverConfirmedAdmin = false; _requestSent = false; } private static void ReceiveRequest(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZRoutedRpc.instance != null) { ZNetPeer peer = ZNet.instance.GetPeer(sender); bool flag = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Landoria_Moderator_AdminResponse", new object[1] { flag }); ModeratorPlugin.ModLogger.LogDebug($"Administrator validation completed for peer {sender}: {flag}."); } } private static void ReceiveResponse(long sender, bool isAdmin) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZNet.instance.GetPeer(sender) != null) { _serverConfirmedAdmin = isAdmin; if (!isAdmin) { ModeratorState.SetEnabled(active: false); } ModeratorPlugin.ModLogger.LogDebug($"Server administrator validation received: {isAdmin}."); } } } internal static class AdminPlayerModes { internal static void Apply(bool enabled) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { localPlayer.SetGodMode(enabled); localPlayer.SetGhostMode(enabled); ModeratorPlugin.ModLogger.LogDebug($"Administrator god and ghost modes set to {enabled}."); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class CommandRegistrationPatch { private static void Postfix() { ModeratorPlugin.RegisterCommands(); ModeratorPlugin.ModLogger.LogDebug("Custom commands were registered after vanilla terminal initialization."); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class ConsoleEventCommandConstructorPatch { private static bool Prefix(string command) { return !string.Equals(command, "devcommands", StringComparison.OrdinalIgnoreCase); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class FailableCommandConstructorPatch { private static bool Prefix(string command) { return !string.Equals(command, "devcommands", StringComparison.OrdinalIgnoreCase); } } [HarmonyPatch(typeof(ConsoleCommand), "ShowCommand")] internal static class HideDevCommandsPatch { private static void Postfix(ConsoleCommand __instance, ref bool __result) { if (__instance.IsCheat) { __result = false; } } } [HarmonyPatch(typeof(ConsoleCommand), "RunAction")] internal static class BlockDevCommandsPatch { private static bool Prefix(ConsoleCommand __instance) { return !__instance.IsCheat; } } internal static class EventControlRpc { private const string StartRpc = "Landoria_Moderator_StartEvent"; private const string StopRpc = "Landoria_Moderator_StopEvent"; private static ZRoutedRpc _registeredRpc; internal static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register<string>("Landoria_Moderator_StartEvent", (Action<long, string>)ReceiveStartRequest); instance.Register("Landoria_Moderator_StopEvent", (Action<long>)ReceiveStopRequest); _registeredRpc = instance; ModeratorPlugin.ModLogger.LogDebug("Event control RPCs registered."); } } internal static void RequestStart(string eventName) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Landoria_Moderator_StartEvent", new object[1] { eventName }); } } internal static void RequestStop() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Landoria_Moderator_StopEvent", Array.Empty<object>()); } } internal static void ResetSession() { _registeredRpc = null; } private static void ReceiveStartRequest(long sender, string eventName) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) ZNetPeer authorizedModerator = GetAuthorizedModerator(sender); if (authorizedModerator != null && !((Object)(object)RandEventSystem.instance == (Object)null)) { if (!RandEventSystem.instance.HaveEvent(eventName)) { ModeratorPlugin.ModLogger.LogWarning("Unknown event '" + eventName + "' rejected."); return; } RandEventSystem.instance.SetRandomEventByName(eventName, authorizedModerator.m_refPos); ModeratorPlugin.ModLogger.LogInfo($"Moderator started event '{eventName}' for peer {sender}."); } } private static void ReceiveStopRequest(long sender) { if (GetAuthorizedModerator(sender) != null && !((Object)(object)RandEventSystem.instance == (Object)null)) { RandEventSystem.instance.ResetRandomEvent(); ModeratorPlugin.ModLogger.LogInfo($"Moderator stopped the active event for peer {sender}."); } } private static ZNetPeer GetAuthorizedModerator(long sender) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return null; } ZNetPeer peer = ZNet.instance.GetPeer(sender); bool num = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); object obj; if (peer == null) { obj = null; } else { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(peer.m_characterID) : null); } bool flag = obj != null && ((ZDO)obj).GetBool("Landoria.Moderator.Active", false); if (num && flag) { return peer; } ModeratorPlugin.ModLogger.LogWarning($"Unauthorized event request rejected for peer {sender}."); return null; } } internal static class NextDayControlRpc { private const string NextDayRpc = "Landoria_Moderator_NextDay"; private static ZRoutedRpc _registeredRpc; internal static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register("Landoria_Moderator_NextDay", (Action<long>)ReceiveRequest); _registeredRpc = instance; ModeratorPlugin.ModLogger.LogDebug("Next-day control RPC registered."); } } internal static void Request() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Landoria_Moderator_NextDay", Array.Empty<object>()); } } internal static void ResetSession() { _registeredRpc = null; } private static void ReceiveRequest(long sender) { if (GetAuthorizedModerator(sender) != null && !((Object)(object)EnvMan.instance == (Object)null)) { EnvMan.instance.SkipToMorning(); ModeratorPlugin.ModLogger.LogInfo($"Moderator skipped to the next morning for peer {sender}."); } } private static ZNetPeer GetAuthorizedModerator(long sender) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return null; } ZNetPeer peer = ZNet.instance.GetPeer(sender); bool num = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); object obj; if (peer == null) { obj = null; } else { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(peer.m_characterID) : null); } bool flag = obj != null && ((ZDO)obj).GetBool("Landoria.Moderator.Active", false); if (num && flag) { return peer; } ModeratorPlugin.ModLogger.LogWarning($"Unauthorized next-day request rejected for peer {sender}."); return null; } } internal static class WeatherControlRpc { private const string SetWeatherRpc = "Landoria_Moderator_SetWeather"; private const string ApplyWeatherRpc = "Landoria_Moderator_ApplyWeather"; private static ZRoutedRpc _registeredRpc; internal static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register<string>("Landoria_Moderator_SetWeather", (Action<long, string>)ReceiveRequest); instance.Register<string>("Landoria_Moderator_ApplyWeather", (Action<long, string>)ReceiveAppliedWeather); _registeredRpc = instance; } } internal static void Request(string environment) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Landoria_Moderator_SetWeather", new object[1] { environment ?? "" }); } } internal static void ResetSession() { _registeredRpc = null; } private static void ReceiveRequest(long sender, string environment) { if (IsAuthorizedModerator(sender) && !((Object)(object)EnvMan.instance == (Object)null)) { if (!string.IsNullOrEmpty(environment) && !EnvironmentExists(environment)) { ModeratorPlugin.ModLogger.LogWarning($"Unknown environment '{environment}' rejected for peer {sender}."); return; } EnvMan.instance.m_debugEnv = environment; ZRoutedRpc.instance.InvokeRoutedRPC(0L, "Landoria_Moderator_ApplyWeather", new object[1] { environment }); ModeratorPlugin.ModLogger.LogInfo(string.IsNullOrEmpty(environment) ? $"Moderator reset the weather for peer {sender}." : $"Moderator set weather to '{environment}' for peer {sender}."); } } private static void ReceiveAppliedWeather(long sender, string environment) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZNet.instance.GetPeer(sender) != null && !((Object)(object)EnvMan.instance == (Object)null)) { EnvMan.instance.m_debugEnv = environment; ModeratorPlugin.ModLogger.LogInfo(string.IsNullOrEmpty(environment) ? "Server reset the local weather override." : ("Server applied local weather override '" + environment + "'.")); } } private static bool EnvironmentExists(string environment) { return EnvMan.instance.m_environments.Exists((EnvSetup candidate) => string.Equals(candidate.m_name, environment, StringComparison.OrdinalIgnoreCase)); } private static bool IsAuthorizedModerator(long sender) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return false; } ZNetPeer peer = ZNet.instance.GetPeer(sender); bool num = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); object obj; if (peer == null) { obj = null; } else { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(peer.m_characterID) : null); } bool flag = obj != null && ((ZDO)obj).GetBool("Landoria.Moderator.Active", false); if (num && flag) { return true; } ModeratorPlugin.ModLogger.LogWarning($"Unauthorized weather request rejected for peer {sender}."); return false; } } internal static class ExploreMapCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("exploremap", "Explores the entire map.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { if ((Object)(object)Minimap.instance == (Object)null) { ModeratorPlugin.ModLogger.LogError("Exploremap command failed because the map is not available."); args.Context.AddString("The map is not available yet."); return; } Minimap.instance.ExploreAll(); ModeratorMapSharing.Enable(); args.Context.AddString("The entire map has been explored and connected players are visible."); ModeratorPlugin.ModLogger.LogDebug("Exploremap command revealed the local map and enabled player tracking."); } } internal static class EventCommands { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: 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_0051: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("event", "[name]", ModeratorCommandAudit.Wrap(new ConsoleEvent(Start)), false, false, false, false, true, false, new ConsoleOptionsFetcher(GetEventNames), false, false, true); new ConsoleCommand("stopevent", "", ModeratorCommandAudit.Wrap(new ConsoleEvent(Stop)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Start(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString("Usage: event <name>"); return; } EventControlRpc.RequestStart(args[1]); args.Context.AddString("Event start requested: " + args[1]); } private static void Stop(ConsoleEventArgs args) { EventControlRpc.RequestStop(); args.Context.AddString("Event stop requested."); } private static List<string> GetEventNames() { List<string> list = new List<string>(); if ((Object)(object)RandEventSystem.instance == (Object)null) { return list; } foreach (RandomEvent @event in RandEventSystem.instance.m_events) { if (@event.m_enabled) { list.Add(@event.m_name); } } return list; } } internal static class NextDayCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("nextday", "Advance to the next morning.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { NextDayControlRpc.Request(); args.Context.AddString("Skip to the next morning requested."); } } internal static class WeatherCommands { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: 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_0051: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("env", "[environment] - Override the weather.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Set)), false, false, false, false, true, false, new ConsoleOptionsFetcher(GetEnvironments), false, false, true); new ConsoleCommand("resetenv", "Restore automatic weather.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Reset)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Set(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString("Usage: env <environment>"); return; } string text = string.Join(" ", args.Args, 1, args.Args.Length - 1); WeatherControlRpc.Request(text); args.Context.AddString("Weather change requested: " + text); } private static void Reset(ConsoleEventArgs args) { WeatherControlRpc.Request(""); args.Context.AddString("Weather reset requested."); } private static List<string> GetEnvironments() { List<string> list = new List<string>(); if ((Object)(object)EnvMan.instance == (Object)null) { return list; } foreach (EnvSetup environment in EnvMan.instance.m_environments) { list.Add(environment.m_name); } return list; } } internal static class GotoCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("goto", "[player] - Teleports you to a player.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { if ((Object)(object)Player.m_localPlayer == (Object)null || args.Length != 2) { Fail(args, "Usage: goto <player>"); } else if (!PlayerPositionRpc.Request(args[1], delegate(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Teleport(position, args.Context); })) { Fail(args, "No matching player was found."); } } private static void Teleport(Vector3 destination, Terminal context) { //IL_0013: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ((Character)Player.m_localPlayer).TeleportTo(destination, ((Component)Player.m_localPlayer).transform.rotation, true); context.AddString($"Teleported to: {destination}"); ModeratorPlugin.ModLogger.LogDebug($"Goto command teleported the local player to {destination}."); } } private static void Fail(ConsoleEventArgs args, string message) { ModeratorPlugin.ModLogger.LogError("Goto command failed: " + message); args.Context.AddString(message); } } internal static class ItemSetCommand { private const string Usage = "Usage: itemset <meadows|blackforest|swamp|mountain|plains>"; internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("itemset", "[biome] - Replaces current items with a biome item set.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { string text = ((args.Length == 2) ? GetItemSet(args[1]) : null); if (text == null) { args.Context.AddString("Usage: itemset <meadows|blackforest|swamp|mountain|plains>"); return; } if ((Object)(object)ItemSets.instance == (Object)null || !ItemSets.instance.TryGetSet(text, true, -1, -1)) { Fail(args, text); return; } args.Context.AddString("Applied the " + text + " item set."); ModeratorPlugin.ModLogger.LogDebug("The " + text + " item set was applied."); } private static string GetItemSet(string biome) { return biome.ToLowerInvariant() switch { "meadows" => "Meadows", "blackforest" => "BlackForest", "swamp" => "Swamps", "mountain" => "Mountains", "plains" => "Plains", _ => null, }; } private static void Fail(ConsoleEventArgs args, string itemSet) { string text = "The " + itemSet + " item set could not be applied."; args.Context.AddString(text); ModeratorPlugin.ModLogger.LogError(text); } } internal static class ModeratorCommandAudit { internal static ConsoleEvent Wrap(ConsoleEvent execute) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return (ConsoleEvent)delegate(ConsoleEventArgs args) { Player localPlayer = Player.m_localPlayer; string text = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "unknown"; ModeratorPlugin.ModLogger.LogInfo("Moderator command invoked by '" + text + "': " + args.FullLine); execute.Invoke(args); }; } } internal static class ModeratorModeCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("moderator", "Toggles moderator mode.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { bool num = !ModeratorState.IsActive; ModeratorState.SetEnabled(num); string text = (num ? "enabled" : "disabled"); Terminal context = args.Context; if (context != null) { context.AddString("Moderator mode " + text + "."); } ModeratorPlugin.ModLogger.LogInfo("Moderator mode " + text + "."); } } internal static class PlayerCommandUtility { internal static bool TryFindPlayer(string name, out Vector3 position, out ZDOID characterId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0061: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; characterId = ZDOID.None; if ((Object)(object)ZNet.instance == (Object)null) { return false; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (player.m_name.Equals(name, StringComparison.OrdinalIgnoreCase)) { position = player.m_position; characterId = player.m_characterID; return true; } } return false; } internal static void Teleport(ZDOID characterId, Vector3 position, Quaternion rotation) { //IL_0007: 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_001e: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(0L, characterId, "RPC_TeleportTo", new object[3] { position, rotation, true }); } } internal static class PlayerListCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("playerlist", "Prints online players.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { //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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null) { ModeratorPlugin.ModLogger.LogError("Playerlist command failed because ZNet is unavailable."); args.Context.AddString("The player list is not available."); return; } List<string> list = new List<string>(); foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { string text = (IsAdmin(player) ? " <color=#00A000>[Moderator]</color>" : string.Empty); list.Add(player.m_name + text); } args.Context.AddString(string.Join("\n", list)); ModeratorPlugin.ModLogger.LogDebug($"Playerlist command returned {list.Count} online player entries."); } private static bool IsAdmin(PlayerInfo player) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string text = PlatformPlayerIdentity.Resolve(player); if (string.IsNullOrWhiteSpace(text)) { return false; } if (ZNet.instance.IsAdmin(text)) { return true; } if (ZNet.instance.IsServer()) { return text == ((object)Unsafe.As<PlatformUserID, PlatformUserID>(ref UserInfo.GetLocalUser().UserId)/*cast due to .constrained prefix*/).ToString(); } return false; } } internal static class SummonCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("summon", "[player] - Teleports a player to you.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || args.Length < 2 || !PlayerCommandUtility.TryFindPlayer(args[1], out var _, out var characterId)) { ModeratorPlugin.ModLogger.LogError("Summon command failed because the player was not found."); args.Context.AddString("Usage: summon <player>"); } else { PlayerCommandUtility.Teleport(characterId, ((Component)Player.m_localPlayer).transform.position, ((Component)Player.m_localPlayer).transform.rotation); args.Context.AddString("Summoned player: " + args[1]); ModeratorPlugin.ModLogger.LogDebug("Summon command teleported '" + args[1] + "' to the local player."); } } } internal static class ResetMapCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("resetmap", "Hides the entire explored map.", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, true); } private static void Execute(ConsoleEventArgs args) { if ((Object)(object)Minimap.instance == (Object)null) { ModeratorPlugin.ModLogger.LogError("Resetmap command failed because the map is unavailable."); args.Context.AddString("The map is not available yet."); return; } Minimap.instance.Reset(); ModeratorMapSharing.Disable(); args.Context.AddString("The entire map exploration has been reset."); ModeratorPlugin.ModLogger.LogDebug("Resetmap command cleared the local map exploration."); } } internal static class SpawnCommand { internal static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("spawn", "[prefab] [amount=1] [level=1] [radius=0.5]", ModeratorCommandAudit.Wrap(new ConsoleEvent(Execute)), false, false, false, false, true, false, new ConsoleOptionsFetcher(GetPrefabNames), false, false, true); } private static void Execute(ConsoleEventArgs args) { if (args.Length < 2 || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { Fail(args, "Usage: spawn <prefab> [amount] [level] [radius]"); return; } GameObject prefab = ZNetScene.instance.GetPrefab(args[1]); if ((Object)(object)prefab == (Object)null) { Fail(args, "Prefab not found: " + args[1]); return; } Spawn(prefab, args.TryParameterInt(2, 1), args.TryParameterInt(3, 1), args.TryParameterFloat(4, 0.5f)); args.Context.AddString("Spawned prefab: " + args[1]); ModeratorPlugin.ModLogger.LogDebug("Spawn command created prefab '" + args[1] + "'."); } private static void Spawn(GameObject prefab, int amount, int level, float radius) { //IL_0010: 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_0026: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) amount = Mathf.Max(1, amount); for (int i = 0; i < amount; i++) { Vector3 val = Random.insideUnitSphere * radius; Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + val; GameObject obj = Object.Instantiate<GameObject>(prefab, val2, Quaternion.identity); ItemDrop.OnCreateNew(obj, false); Character component = obj.GetComponent<Character>(); if (component != null) { component.SetLevel(Mathf.Clamp(level, 1, 9)); } ItemDrop component2 = obj.GetComponent<ItemDrop>(); if (component2 != null) { component2.SetQuality(Mathf.Clamp(level, 1, 4)); } } } private static List<string> GetPrefabNames() { if (!((Object)(object)ZNetScene.instance == (Object)null)) { return ZNetScene.instance.GetPrefabNames(); } return new List<string>(); } private static void Fail(ConsoleEventArgs args, string message) { ModeratorPlugin.ModLogger.LogError("Spawn command failed: " + message); args.Context.AddString(message); } } [BepInPlugin("Landoria.Moderator", "Landoria.Moderator", "1.0.11")] public sealed class ModeratorPlugin : LandoriaPlugin { private static readonly HashSet<string> CommandsRequiringModerator = new HashSet<string> { "exploremap", "goto", "itemset", "playerlist", "summon", "resetmap", "spawn", "event", "stopevent", "env", "resetenv", "nextday" }; private const string PluginGuid = "Landoria.Moderator"; private const string PluginName = "Landoria.Moderator"; private const string PluginVersion = "1.0.11"; internal static ModLog ModLogger { get; private set; } private void Awake() { ModLogger = InitializePlugin("Landoria.Moderator"); RegisterCommands(); ModLogger.LogInfo("Landoria.Moderator 1.0.11 is loaded."); } private void OnDestroy() { ModeratorMapSharing.Disable(); ModLogger?.LogInfo("Landoria.Moderator 1.0.11 is unloaded."); ShutdownPlugin(); ModLogger = null; } private void Update() { PlayerPositionRpc.Update(); ModeratorMapSharing.Update(); } internal static void RegisterCommands() { ModeratorModeCommand.Register(); ExploreMapCommand.Register(); GotoCommand.Register(); ItemSetCommand.Register(); PlayerListCommand.Register(); SummonCommand.Register(); ResetMapCommand.Register(); SpawnCommand.Register(); EventCommands.Register(); WeatherCommands.Register(); NextDayCommand.Register(); } internal static bool RequiresEnabledModerator(string command) { return CommandsRequiringModerator.Contains(command); } } internal static class ModeratorMapSharing { private const float RefreshInterval = 30f; private static readonly Dictionary<ZDOID, PlayerInfo> Players = new Dictionary<ZDOID, PlayerInfo>(); private static float _nextRefresh; private static bool _enabled; internal static void Enable() { _enabled = true; _nextRefresh = 0f; ModeratorPlugin.ModLogger.LogDebug("Moderator map player tracking enabled."); } internal static void Disable() { if (_enabled || Players.Count > 0) { ModeratorPlugin.ModLogger.LogDebug("Moderator map player tracking disabled."); } _enabled = false; Players.Clear(); } internal static void Update() { if (_enabled && ModeratorState.IsActive && !((Object)(object)ZNet.instance == (Object)null) && !(Time.unscaledTime < _nextRefresh)) { _nextRefresh = Time.unscaledTime + 30f; RefreshPlayers(); } } internal static void AddPlayers(List<PlayerInfo> players) { //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_002a: 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_0038: Unknown result type (might be due to invalid IL or missing references) if (!_enabled || !ModeratorState.IsActive) { return; } foreach (PlayerInfo value in Players.Values) { if (!Contains(players, value.m_characterID)) { players.Add(value); } } } private static void RefreshPlayers() { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003e: 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_004a: Unknown result type (might be due to invalid IL or missing references) HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (!IsLocalPlayer(player.m_characterID)) { ZDOID characterID = player.m_characterID; if (!((ZDOID)(ref characterID)).IsNone()) { hashSet.Add(player.m_characterID); RequestPosition(player); } } } RemoveDisconnected(hashSet); } private static void RequestPosition(PlayerInfo player) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) ZDOID characterId = player.m_characterID; string playerName = player.m_name; PlayerPositionRpc.Request(characterId, playerName, delegate(Vector3 position) { //IL_0014: 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_0025: 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) if (_enabled && ModeratorState.IsActive) { Players[characterId] = CreatePlayerInfo(playerName, characterId, position); } }); } private static PlayerInfo CreatePlayerInfo(string name, ZDOID characterId, Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) //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) return new PlayerInfo { m_name = name, m_characterID = characterId, m_publicPosition = true, m_position = position }; } private static void RemoveDisconnected(HashSet<ZDOID> connected) { //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_0021: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) List<ZDOID> list = new List<ZDOID>(); foreach (ZDOID key in Players.Keys) { if (!connected.Contains(key)) { list.Add(key); } } foreach (ZDOID item in list) { Players.Remove(item); } } private static bool Contains(List<PlayerInfo> players, ZDOID characterId) { //IL_000b: 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) foreach (PlayerInfo player in players) { if (player.m_characterID == characterId) { return true; } } return false; } private static bool IsLocalPlayer(ZDOID characterId) { //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) return ZNet.instance.LocalPlayerCharacterID == characterId; } } internal static class ModeratorState { internal const string ModeratorZdoKey = "Landoria.Moderator.Active"; internal const string ModeratorLabel = "<color=#00A000>[Moderator]</color>"; internal static bool IsActive { get; private set; } internal static void SetEnabled(bool active) { IsActive = active; if (!active) { ModeratorMapSharing.Disable(); } AdminPlayerModes.Apply(active); Player localPlayer = Player.m_localPlayer; ZNetView obj = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).GetComponent<ZNetView>() : null); ZDO val = ((obj != null) ? obj.GetZDO() : null); if (val != null && val.IsOwner()) { val.Set("Landoria.Moderator.Active", active); } } } [HarmonyPatch(typeof(ZNet), "GetOtherPublicPlayers")] internal static class ShowPlayersToModeratorOnMapPatch { private static void Postfix(List<PlayerInfo> playerList) { ModeratorMapSharing.AddPlayers(playerList); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class LocalModeratorStatePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ModeratorState.SetEnabled(active: false); AdminAccess.RequestStatus(); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class AdminRpcRegistrationPatch { private static void Postfix() { AdminAccess.RegisterRpcs(); PlayerPositionRpc.RegisterResponseRpc(); EventControlRpc.RegisterRpcs(); WeatherControlRpc.RegisterRpcs(); NextDayControlRpc.RegisterRpcs(); } } [HarmonyPatch(typeof(Player), "Awake")] internal static class PlayerPositionRpcRegistrationPatch { private static void Postfix(Player __instance, ZNetView ___m_nview) { PlayerPositionRpc.RegisterPlayerRpc(__instance, ___m_nview); } } [HarmonyPatch(typeof(Player), "GetHoverName")] internal static class ModeratorHoverNamePatch { private static void Postfix(Player __instance, ref string __result) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (component != null) { ZDO zDO = component.GetZDO(); if (((zDO != null) ? new bool?(zDO.GetBool("Landoria.Moderator.Active", false)) : ((bool?)null)) == true) { __result += " <color=#00A000>[Moderator]</color>"; } } } } [HarmonyPatch(typeof(ConsoleCommand), "IsValid")] internal static class ModeratorCommandValidationPatch { private static void Postfix(ConsoleCommand __instance, ref bool __result) { if (__instance.OnlyAdmin) { bool num = AdminAccess.LocalPlayerIsAdminOrHost(); bool flag = ModeratorPlugin.RequiresEnabledModerator(__instance.Command) && !ModeratorState.IsActive; if (!num || flag) { __result = false; } } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] internal static class ModeratorDisconnectPatch { private static void Postfix() { ModeratorState.SetEnabled(active: false); AdminAccess.ResetSession(); PlayerPositionRpc.ResetSession(); EventControlRpc.ResetSession(); WeatherControlRpc.ResetSession(); NextDayControlRpc.ResetSession(); } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] internal static class MapTeleportPatch { private static bool Prefix(Minimap __instance) { //IL_001a: 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_0037: 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_005b: Unknown result type (might be due to invalid IL or missing references) if (!CanTeleport() || !TryGetMapPosition(__instance, out var position)) { return true; } position.y = WorldGenerator.instance.GetHeight(position.x, position.z); Player localPlayer = Player.m_localPlayer; ((Character)localPlayer).TeleportTo(position, ((Component)localPlayer).transform.rotation, true); __instance.SetMapMode((MapMode)1); ModeratorPlugin.ModLogger.LogDebug($"Map teleport moved the local player to {position}."); return false; } private static bool CanTeleport() { if ((Object)(object)Player.m_localPlayer != (Object)null && WorldGenerator.instance != null && ModeratorState.IsActive) { return ZInput.GetKey((KeyCode)304, true); } return false; } private static bool TryGetMapPosition(Minimap map, out Vector3 position) { //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_001b: 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_003d: 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_004f: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)map.m_mapImageLarge).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Vector2 val2 = default(Vector2); if ((Object)(object)val == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.op_Implicit(ZInput.pointerPosition), (Camera)null, ref val2)) { position = Vector3.zero; return false; } Vector2 val3 = Rect.PointToNormalized(val.rect, val2); Rect uvRect = map.m_mapImageLarge.uvRect; float num = ((Rect)(ref uvRect)).xMin + val3.x * ((Rect)(ref uvRect)).width; float num2 = ((Rect)(ref uvRect)).yMin + val3.y * ((Rect)(ref uvRect)).height; float num3 = (float)map.m_textureSize / 2f; position = new Vector3((num * (float)map.m_textureSize - num3) * map.m_pixelSize, 0f, (num2 * (float)map.m_textureSize - num3) * map.m_pixelSize); return true; } } internal static class PlayerPositionRpc { private sealed class PendingRequest { internal Action<Vector3> Callback; internal float ExpiresAt; internal bool LogResponse; } private const string RequestRpc = "Landoria_Moderator_PositionRequest"; private const string ResponseRpc = "Landoria_Moderator_PositionResponse"; private const float RequestTimeout = 5f; private static readonly Dictionary<int, PendingRequest> PendingRequests = new Dictionary<int, PendingRequest>(); private static ZRoutedRpc _registeredRpc; private static int _nextRequestId; internal static void RegisterResponseRpc() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register<int, Vector3>("Landoria_Moderator_PositionResponse", (Action<long, int, Vector3>)ReceiveResponse); _registeredRpc = instance; ModeratorPlugin.ModLogger.LogDebug("Player position response RPC registered."); } } internal static void RegisterPlayerRpc(Player player, ZNetView netView) { if (((netView != null) ? netView.GetZDO() : null) != null) { netView.Register<int>("Landoria_Moderator_PositionRequest", (Action<long, int>)delegate(long sender, int requestId) { SendResponse(player, sender, requestId); }); } } internal static bool Request(string playerName, Action<Vector3> callback) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!PlayerCommandUtility.TryFindPlayer(playerName, out var _, out var characterId) || ZRoutedRpc.instance == null) { return false; } return Request(characterId, playerName, callback, logRequest: true); } internal static bool Request(ZDOID characterId, string playerName, Action<Vector3> callback, bool logRequest = false) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref characterId)).IsNone() || ZRoutedRpc.instance == null) { return false; } int num = ++_nextRequestId; PendingRequests[num] = new PendingRequest { Callback = callback, ExpiresAt = Time.unscaledTime + 5f, LogResponse = logRequest }; ZRoutedRpc.instance.InvokeRoutedRPC(0L, characterId, "Landoria_Moderator_PositionRequest", new object[1] { num }); if (logRequest) { ModeratorPlugin.ModLogger.LogDebug($"Requested the private position of '{playerName}' with request {num}."); } return true; } internal static void Update() { List<int> list = new List<int>(); foreach (KeyValuePair<int, PendingRequest> pendingRequest in PendingRequests) { if (Time.unscaledTime >= pendingRequest.Value.ExpiresAt) { list.Add(pendingRequest.Key); } } foreach (int item in list) { PendingRequests.Remove(item); } } internal static void ResetSession() { _registeredRpc = null; _nextRequestId = 0; PendingRequests.Clear(); } private static void SendResponse(Player player, long sender, int requestId) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Landoria_Moderator_PositionResponse", new object[2] { requestId, ((Component)player).transform.position }); } } private static void ReceiveResponse(long sender, int requestId, Vector3 position) { //IL_0022: 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) if (PendingRequests.TryGetValue(requestId, out var value)) { PendingRequests.Remove(requestId); value.Callback(position); if (value.LogResponse) { ModeratorPlugin.ModLogger.LogDebug($"Received private player position {position} for request {requestId} from peer {sender}."); } } } } } namespace Landoria.SharedLib { public abstract class LandoriaPlugin : BaseUnityPlugin { private Harmony _harmony; private bool _patchesApplied; protected ModLog InitializePlugin(string pluginGuid) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger); Version version = ((object)this).GetType().Assembly.GetName().Version; modLog.LogInfo($"AssemblyVersion: {version}."); EnsureSharedPatches(modLog); _harmony = new Harmony(pluginGuid); PatchOwnNamespace(modLog); return modLog; } protected ModLog InitializePlugin(string pluginGuid, Type[] patchTypes) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger); Version version = ((object)this).GetType().Assembly.GetName().Version; modLog.LogInfo($"AssemblyVersion: {version}."); EnsureSharedPatches(modLog); _harmony = new Harmony(pluginGuid); foreach (Type type in patchTypes) { _harmony.CreateClassProcessor(type).Patch(); modLog.LogInfo("Server patch: " + type.Name); } _patchesApplied = true; return modLog; } private static void EnsureSharedPatches(ModLog log) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) lock (AppDomain.CurrentDomain) { if (AppDomain.CurrentDomain.GetData("Landoria.SharedLib.ConnectionFailureMenuPatch.v1") == null) { new Harmony("Landoria.SharedLib").CreateClassProcessor(typeof(ConnectionFailureMenuPatch)).Patch(); AppDomain.CurrentDomain.SetData("Landoria.SharedLib.ConnectionFailureMenuPatch.v1", true); log.LogDebug("Shared connection failure menu patch was applied."); } } } protected void PatchOwnNamespace(ModLog log) { if (_patchesApplied) { log.LogDebug("Harmony patches are already active; skipping registration."); return; } string text = ((object)this).GetType().Namespace; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { if (type.Namespace == text) { _harmony.CreateClassProcessor(type).Patch(); } } _patchesApplied = true; log.LogDebug("Harmony patches were applied for the plugin namespace."); } protected void ShutdownPlugin() { if (_patchesApplied) { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _patchesApplied = false; } } } public static class ConnectionFailureMessages { private const string StateKey = "Landoria.SharedLib.ConnectionFailureMessages.v1"; private static readonly ManualLogSource Log = Logger.CreateLogSource("Landoria.ConnectionFailureMessages"); public static void Push(string source, string message) { Push(source, message, (string)null); } public static void Push(string source, string userMessage, string systemMessage) { Push(source, userMessage, systemMessage, null); } public static void Push(string source, string userMessage, Exception exception) { Push(source, userMessage, exception?.Message, exception); } public static void Push(string source, string userMessage, string systemMessage, Exception exception) { string text = DisplayMessage(userMessage, systemMessage ?? exception?.Message); if (string.IsNullOrWhiteSpace(source) || text == null) { return; } bool flag = false; lock (AppDomain.CurrentDomain) { Stack<Tuple<string, string, string>> messages = GetMessages(); Tuple<string, string, string> item = Tuple.Create(source, text, systemMessage); if (!messages.Contains(item)) { messages.Push(item); flag = true; } } if (flag) { LogQueued(source, text, systemMessage, exception); } } public static void Clear(string source) { if (string.IsNullOrWhiteSpace(source)) { return; } lock (AppDomain.CurrentDomain) { Stack<Tuple<string, string, string>> messages = GetMessages(); Stack<Tuple<string, string, string>> stack = new Stack<Tuple<string, string, string>>(); while (messages.Count > 0) { Tuple<string, string, string> tuple = messages.Pop(); if (tuple.Item1 != source) { stack.Push(tuple); } } while (stack.Count > 0) { messages.Push(stack.Pop()); } } } internal static bool TryPopAll(out string message) { lock (AppDomain.CurrentDomain) { Stack<Tuple<string, string, string>> messages = GetMessages(); if (messages.Count > 0) { List<string> list = new List<string>(); while (messages.Count > 0) { list.Add(messages.Pop().Item2); } message = string.Join("\n", list); return true; } } message = null; return false; } private static Stack<Tuple<string, string, string>> GetMessages() { if (AppDomain.CurrentDomain.GetData("Landoria.SharedLib.ConnectionFailureMessages.v1") is Stack<Tuple<string, string, string>> result) { return result; } Stack<Tuple<string, string, string>> stack = new Stack<Tuple<string, string, string>>(); AppDomain.CurrentDomain.SetData("Landoria.SharedLib.ConnectionFailureMessages.v1", stack); return stack; } private static string DisplayMessage(string userMessage, string systemMessage) { if (!string.IsNullOrWhiteSpace(userMessage)) { return userMessage; } if (!string.IsNullOrWhiteSpace(systemMessage)) { return systemMessage; } return null; } private static void LogQueued(string source, string userMessage, string systemMessage, Exception exception) { string text = exception?.ToString() ?? Environment.StackTrace; if (string.IsNullOrWhiteSpace(systemMessage) || systemMessage == userMessage) { Log.LogWarning((object)("Queued connection failure message from " + source + ": " + userMessage + "\nDiagnostic stack:\n" + text)); } else { Log.LogWarning((object)("Queued connection failure message from " + source + ": userMessage=" + userMessage + "; systemMessage=" + systemMessage + "\nDiagnostic stack:\n" + text)); } } } [HarmonyPatch] internal static class ConnectionFailureMenuPatch { [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static void ShowConnectError(TMP_Text ___m_connectionFailedError) { if (ConnectionFailureMessages.TryPopAll(out var message)) { ___m_connectionFailedError.text = message; } } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "Start")] private static void Start(GameObject ___m_connectionFailedPanel, TMP_Text ___m_connectionFailedError) { ShowNext(___m_connectionFailedPanel, ___m_connectionFailedError); } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "OnConnectionFailedOk")] private static void OnConnectionFailedOk(GameObject ___m_connectionFailedPanel, TMP_Text ___m_connectionFailedError) { ShowNext(___m_connectionFailedPanel, ___m_connectionFailedError); } private static void ShowNext(GameObject panel, TMP_Text text) { if (ConnectionFailureMessages.TryPopAll(out var message)) { text.text = message; panel.SetActive(true); } } } public sealed class ModLog { private readonly ManualLogSource _logger; public ModLog(ManualLogSource logger) { _logger = logger; } public void LogFatal(object message) { Write((LogLevel)1, message); } public void LogError(object message) { Write((LogLevel)2, message); } public void LogWarning(object message) { Write((LogLevel)4, message); } public void LogMessage(object message) { Write((LogLevel)8, message); } public void LogInfo(object message) { Write((LogLevel)16, message); } public void LogDebug(object message) { Write((LogLevel)32, message); } public void Log(LogLevel level, object message) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Write(level, message); } private void Write(LogLevel level, object message) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) string arg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); _logger.Log(level, (object)$"[{arg}] {message}"); } } public static class PlatformPlayerIdentity { public unsafe static string Resolve(PlayerInfo player) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) string text = ((object)(*(PlatformUserID*)(&player.m_userInfo.m_id))/*cast due to .constrained prefix*/).ToString(); if (!string.IsNullOrWhiteSpace(text)) { return text; } ZNetPeer obj = FindPeer(player); if (obj == null) { return null; } ISocket socket = obj.m_socket; if (socket == null) { return null; } return socket.GetHostName(); } public static ZNetPeer FindPeer(PlayerInfo player) { //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) if ((Object)(object)ZNet.instance == (Object)null || ((ZDOID)(ref player.m_characterID)).IsNone()) { return null; } return ((IEnumerable<ZNetPeer>)ZNet.instance.GetPeers()).FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer peer) => peer != null && ((ZDOID)(ref peer.m_characterID)).Equals(player.m_characterID))); } } public static class ServerRole { public static bool IsDedicatedServer { get { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return ZNet.instance.IsDedicated(); } return false; } } } }