using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Landoria.SharedLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Landoria.HammerFreedom")] [assembly: AssemblyDescription("Adds server-authorized creative freedoms to Hammer worlds.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Landoria")] [assembly: AssemblyProduct("Landoria.HammerFreedom")] [assembly: AssemblyCopyright("Copyright © 2026 End3rbyte")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("DDA10461-612F-42CD-A050-B2634758E942")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.0.28145")] namespace Landoria.HammerFreedom { internal static class FlyCommand { private static ConsoleCommand _command; internal static void Register() { //IL_0011: 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_002f: Expected O, but got Unknown //IL_002f: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown _command = new ConsoleCommand("fly", "[on|off] toggles server-authorized vanilla flight.", new ConsoleEventFailable(Run), false, false, false, false, false, new ConsoleOptionsFetcher(Options), false, false, false); } internal static bool IsCommand(ConsoleCommand command) { return command == _command; } private static object Run(ConsoleEventArgs args) { if (!HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.Flight)) { return "Flight is not authorized by this server."; } if (args.Length == 1) { FlyController.Toggle(); return true; } string text = args[1].ToLowerInvariant(); if (text != "on" && text != "off") { return "Use fly, fly on, or fly off."; } FlyController.SetEnabled(text == "on"); return true; } private static List Options() { return new List { "on", "off" }; } } internal static class FlyController { internal static void Toggle() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.Flight)) { SetEnabled(!((Character)localPlayer).IsDebugFlying()); } } internal static void SetEnabled(bool enabled) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && (!enabled || HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.Flight)) && ((Character)localPlayer).IsDebugFlying() != enabled) { localPlayer.ToggleDebugFly(); } } internal static void OnAuthorizationChanged(bool allowed) { if (!allowed) { SetEnabled(enabled: false); } } } internal static class FlyInput { internal static bool IsAvailable() { if (HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.Flight) && (Object)(object)Player.m_localPlayer != (Object)null && !Console.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible()) { if (!((Object)(object)Chat.instance == (Object)null)) { return !Chat.instance.HasFocus(); } return true; } return false; } } internal static class HammerFreedomAuthorization { private const string RequestRpc = "Landoria_HammerFreedom_Request"; private const string ResponseRpc = "Landoria_HammerFreedom_Response"; private const float RetrySeconds = 2f; private static ZRoutedRpc _registeredRpc; private static ZNetPeer _serverPeer; private static HammerFreedomCapabilities? _serverCapabilities; private static float _nextRequestAt; private static HammerFreedomCapabilities _authorizedCapabilities; internal static bool IsAuthorized(HammerFreedomCapabilities capability) { return (_authorizedCapabilities & capability) == capability; } internal static void Update() { RegisterRpcs(); if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { ResetConnection(); } else if (ZNet.instance.IsServer()) { UpdateServerAuthorization(); } else { UpdateClientAuthorization(); } } internal static void ResetSession() { _serverCapabilities = null; ResetConnection(); } private static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredRpc) { instance.Register("Landoria_HammerFreedom_Request", (Action)ReceiveRequest); instance.Register("Landoria_HammerFreedom_Response", (Action)ReceiveResponse); _registeredRpc = instance; } } private static void UpdateServerAuthorization() { HammerFreedomCapabilities hammerFreedomCapabilities = ResolveServerCapabilities(); SetAuthorized(hammerFreedomCapabilities); if (_serverCapabilities != hammerFreedomCapabilities) { _serverCapabilities = hammerFreedomCapabilities; ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Landoria_HammerFreedom_Response", new object[1] { (int)hammerFreedomCapabilities }); HammerFreedomPlugin.ModLogger.LogInfo($"Server HammerFreedom capabilities changed to {hammerFreedomCapabilities}."); } } private static void UpdateClientAuthorization() { if (!IsAuthorized(HammerFreedomCapabilities.Flight)) { FlyController.SetEnabled(enabled: false); } ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != _serverPeer) { ResetConnection(); _serverPeer = serverPeer; } if (_serverPeer != null && _authorizedCapabilities == HammerFreedomCapabilities.None && Time.unscaledTime >= _nextRequestAt) { _nextRequestAt = Time.unscaledTime + 2f; ZRoutedRpc.instance.InvokeRoutedRPC(_serverPeer.m_uid, "Landoria_HammerFreedom_Request", Array.Empty()); } } private static void ReceiveRequest(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZNet.instance.GetPeer(sender) != null && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Landoria_HammerFreedom_Response", new object[1] { (int)ResolveServerCapabilities() }); } } private static void ReceiveResponse(long sender, int capabilities) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && _serverPeer != null && _serverPeer.m_uid == sender) { SetAuthorized((HammerFreedomCapabilities)capabilities); } } private static HammerFreedomCapabilities ResolveServerCapabilities() { bool hammerWorld = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)19) && ZoneSystem.instance.GetGlobalKey((GlobalKeys)25); HammerFreedomSettings settings = HammerFreedomPlugin.Settings; return HammerFreedomCapabilityPolicy.Resolve(hammerWorld, settings?.Flight ?? false, settings?.FallDamageImmunity ?? false, settings?.UnlimitedStamina ?? false); } private static void ResetConnection() { _serverPeer = null; _nextRequestAt = 0f; FlyController.SetEnabled(enabled: false); SetAuthorized(HammerFreedomCapabilities.None); } private static void SetAuthorized(HammerFreedomCapabilities capabilities) { if (_authorizedCapabilities != capabilities) { _authorizedCapabilities = capabilities; FlyController.OnAuthorizationChanged(IsAuthorized(HammerFreedomCapabilities.Flight)); HammerFreedomPlugin.ModLogger?.LogInfo($"HammerFreedom authorization is now {capabilities}."); } } } internal static class HammerFreedomArgumentPolicy { internal static bool Resolve(string[] arguments, string name, out bool valid) { for (int i = 0; i < arguments.Length; i++) { if (string.Equals(arguments[i], name, StringComparison.OrdinalIgnoreCase)) { bool result = true; valid = i + 1 < arguments.Length && bool.TryParse(arguments[i + 1], out result); if (!valid) { return true; } return result; } } valid = true; return true; } } internal static class HammerFreedomBehaviorPolicy { internal static bool ShouldApplyDamage(bool isLocalPlayer, bool isFallDamage, bool fallImmunityAuthorized) { if (isLocalPlayer && isFallDamage) { return !fallImmunityAuthorized; } return true; } internal static bool ShouldConsumeStamina(bool isLocalPlayer, bool unlimitedStaminaAuthorized) { if (isLocalPlayer) { return !unlimitedStaminaAuthorized; } return true; } } [Flags] internal enum HammerFreedomCapabilities { None = 0, Flight = 1, FallDamageImmunity = 2, UnlimitedStamina = 4 } internal static class HammerFreedomCapabilityPolicy { internal static HammerFreedomCapabilities Resolve(bool hammerWorld, bool flight, bool fallDamageImmunity, bool unlimitedStamina) { if (!hammerWorld) { return HammerFreedomCapabilities.None; } HammerFreedomCapabilities hammerFreedomCapabilities = HammerFreedomCapabilities.None; if (flight) { hammerFreedomCapabilities |= HammerFreedomCapabilities.Flight; } if (fallDamageImmunity) { hammerFreedomCapabilities |= HammerFreedomCapabilities.FallDamageImmunity; } if (unlimitedStamina) { hammerFreedomCapabilities |= HammerFreedomCapabilities.UnlimitedStamina; } return hammerFreedomCapabilities; } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class FlyCommandRegistrationPatch { private static void Postfix() { FlyCommand.Register(); } } [HarmonyPatch(typeof(ConsoleCommand), "IsValid")] internal static class FlyCommandValidationPatch { private static void Postfix(ConsoleCommand __instance, ref bool __result) { if (FlyCommand.IsCommand(__instance) && !HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.Flight)) { __result = false; } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class FallDamagePatch { private static bool Prefix(Character __instance, HitData hit) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 return HammerFreedomBehaviorPolicy.ShouldApplyDamage((Object)(object)__instance == (Object)(object)Player.m_localPlayer, (int)hit.m_hitType == 3, HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.FallDamageImmunity)); } } [HarmonyPatch(typeof(Player), "UseStamina")] internal static class StaminaConsumptionPatch { private static bool Prefix(Player __instance) { return HammerFreedomBehaviorPolicy.ShouldConsumeStamina((Object)(object)__instance == (Object)(object)Player.m_localPlayer, HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.UnlimitedStamina)); } } [HarmonyPatch(typeof(Player), "RPC_UseStamina")] internal static class StaminaApplicationPatch { private static bool Prefix(Player __instance) { return HammerFreedomBehaviorPolicy.ShouldConsumeStamina((Object)(object)__instance == (Object)(object)Player.m_localPlayer, HammerFreedomAuthorization.IsAuthorized(HammerFreedomCapabilities.UnlimitedStamina)); } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] internal static class HammerFreedomDisconnectPatch { private static void Prefix() { HammerFreedomAuthorization.ResetSession(); } } [BepInPlugin("Landoria.HammerFreedom", "Landoria.HammerFreedom", "1.0.0")] public sealed class HammerFreedomPlugin : LandoriaPlugin { internal const string PluginGuid = "Landoria.HammerFreedom"; internal const string PluginName = "Landoria.HammerFreedom"; internal const string PluginVersion = "1.0.0"; private static readonly KeyboardShortcut ToggleShortcut = new KeyboardShortcut((KeyCode)122, Array.Empty()); internal static ModLog ModLogger { get; private set; } internal static HammerFreedomSettings Settings { get; private set; } private void Awake() { ModLogger = InitializePlugin("Landoria.HammerFreedom"); Settings = HammerFreedomSettings.FromArguments(Environment.GetCommandLineArgs(), ModLogger); FlyCommand.Register(); ModLogger.LogInfo("Landoria.HammerFreedom 1.0.0 is loaded; " + $"flight={Settings.Flight}, fall damage immunity={Settings.FallDamageImmunity}, " + $"unlimited stamina={Settings.UnlimitedStamina}."); } private void Update() { HammerFreedomAuthorization.Update(); HandleShortcuts(); } private void HandleShortcuts() { //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) if (FlyInput.IsAvailable()) { KeyboardShortcut toggleShortcut = ToggleShortcut; if (((KeyboardShortcut)(ref toggleShortcut)).IsDown()) { FlyController.Toggle(); } } } private void OnDestroy() { HammerFreedomAuthorization.ResetSession(); ModLogger?.LogInfo("Landoria.HammerFreedom 1.0.0 is unloaded."); ShutdownPlugin(); Settings = null; ModLogger = null; } } internal sealed class HammerFreedomSettings { private const string FlightArgument = "--hammerfreedom-fly"; private const string FallDamageArgument = "--hammerfreedom-fall-damage-immunity"; private const string StaminaArgument = "--hammerfreedom-unlimited-stamina"; internal bool Flight { get; private set; } = true; internal bool FallDamageImmunity { get; private set; } = true; internal bool UnlimitedStamina { get; private set; } = true; internal static HammerFreedomSettings FromArguments(string[] arguments, ModLog logger) { return new HammerFreedomSettings { Flight = Read(arguments, "--hammerfreedom-fly", logger), FallDamageImmunity = Read(arguments, "--hammerfreedom-fall-damage-immunity", logger), UnlimitedStamina = Read(arguments, "--hammerfreedom-unlimited-stamina", logger) }; } private static bool Read(string[] arguments, string name, ModLog logger) { bool valid; bool result = HammerFreedomArgumentPolicy.Resolve(arguments, name, out valid); if (!valid) { logger.LogWarning("Invalid " + name + " value; using true."); } return result; } } } namespace Landoria.SharedLib { public abstract class LandoriaPlugin : BaseUnityPlugin { private Harmony _harmony; private bool _patchesApplied; protected ModLog InitializePlugin(string pluginGuid) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger); Version version = ((object)this).GetType().Assembly.GetName().Version; modLog.LogInfo($"AssemblyVersion: {version}."); _harmony = new Harmony(pluginGuid); PatchOwnNamespace(modLog); return modLog; } 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 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}"); } } }