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 StructureProtection v1.0.0
Landoria.StructureProtection.dll
Decompiled 21 hours agousing 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.Logging; using HarmonyLib; using Landoria.SharedLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Landoria.StructureProtection")] [assembly: AssemblyDescription("Protects offline structures from deliberate creature targeting and player attacks inside active wards when no authorized player is online.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Landoria")] [assembly: AssemblyProduct("Landoria.StructureProtection")] [assembly: AssemblyCopyright("Copyright © 2026 End3rbyte")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("C6FAAFDF-2D25-4CD3-BD71-59BAA98F1D20")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.0.40065")] namespace Landoria.StructureProtection { internal static class CreatorActivityPolicy { internal static HashSet<long> GetActiveCreators(IEnumerable<long> onlinePlayers) { return new HashSet<long>(onlinePlayers); } internal static bool IsCreatorActive(long creator, ISet<long> onlinePlayers) { return onlinePlayers.Contains(creator); } } internal static class CreatureProtection { [HarmonyPatch(typeof(StaticTarget), "IsPriorityTarget")] private static class PriorityTargetPatch { private static void Postfix(StaticTarget __instance, ref bool __result) { __result = CreatureProtectionPolicy.CanTarget(StructureProtectionPlugin.Settings.CreatureTargetingEnabled, __result, GetActivity(__instance)); } } [HarmonyPatch(typeof(StaticTarget), "IsRandomTarget")] private static class RandomTargetPatch { private static void Postfix(StaticTarget __instance, ref bool __result) { __result = CreatureProtectionPolicy.CanTarget(StructureProtectionPlugin.Settings.CreatureTargetingEnabled, __result, GetActivity(__instance)); } } [HarmonyPatch(typeof(BaseAI), "CanSeeTarget", new Type[] { typeof(StaticTarget) })] private static class VisibilityPatch { private static void Postfix(StaticTarget target, ref bool __result) { __result = CreatureProtectionPolicy.CanTarget(StructureProtectionPlugin.Settings.CreatureTargetingEnabled, __result, GetActivity(target)); } } private static float GetActivity(StaticTarget target) { return PieceActivity.GetMultiplier((target != null) ? ((Component)target).GetComponentInParent<Piece>() : null); } } internal static class CreatureProtectionPolicy { internal static bool CanTarget(bool enabled, bool vanillaCanTarget, float activityMultiplier) { if (vanillaCanTarget) { if (enabled) { return activityMultiplier > 0f; } return true; } return false; } } [BepInPlugin("Landoria.StructureProtection", "Landoria.StructureProtection", "1.0.0")] public sealed class StructureProtectionPlugin : LandoriaPlugin { private const string PluginGuid = "Landoria.StructureProtection"; private const string PluginName = "Landoria.StructureProtection"; private const string PluginVersion = "1.0.0"; internal static ModLog Log { get; private set; } internal static StructureProtectionSettings Settings { get; private set; } private void Awake() { Log = InitializePlugin("Landoria.StructureProtection"); Settings = new StructureProtectionSettings(); Settings.InitializeServer(Log); Log.LogInfo("Landoria.StructureProtection 1.0.0 is loaded."); } private void Update() { StructureProtectionSession.Update(); } private void OnDestroy() { StructureProtectionSession.Reset(); Log?.LogInfo("Landoria.StructureProtection 1.0.0 is unloaded."); ShutdownPlugin(); Settings = null; Log = null; } } internal static class StructureProtectionArgumentPolicy { internal static bool Resolve(string[] arguments, string name, bool defaultValue) { string text = ReadValue(arguments, name); if (text == null) { return defaultValue; } if (bool.TryParse(text, out var result)) { return result; } throw new InvalidOperationException("Command-line switch " + name + " requires true or false."); } private static string ReadValue(string[] arguments, string name) { string text = null; for (int i = 0; i < arguments.Length; i++) { if (string.Equals(arguments[i], name, StringComparison.OrdinalIgnoreCase)) { if (text != null || i + 1 >= arguments.Length) { throw new InvalidOperationException("Command-line switch " + name + " is missing or duplicated."); } text = arguments[++i]; } } return text; } } internal sealed class StructureProtectionServerConfiguration { internal bool CreatureTargetingEnabled { get; private set; } internal bool WardPlayerDamageEnabled { get; private set; } internal static StructureProtectionServerConfiguration FromArguments(string[] arguments) { return new StructureProtectionServerConfiguration { CreatureTargetingEnabled = StructureProtectionArgumentPolicy.Resolve(arguments, "--structure-protection-creature-targeting", defaultValue: true), WardPlayerDamageEnabled = StructureProtectionArgumentPolicy.Resolve(arguments, "--structure-protection-ward-player-damage", defaultValue: true) }; } } internal static class StructureProtectionSession { [HarmonyPatch(typeof(Player), "OnSpawned")] private static class PlayerSpawnPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { identityServer = 0L; Update(); } } } private const string IdentityRpc = "Landoria_StructureProtection_Identity"; private const string SnapshotRpc = "Landoria_StructureProtection_Snapshot"; private static readonly Dictionary<long, long> PeerPlayers = new Dictionary<long, long>(); private static readonly HashSet<long> OnlinePlayers = new HashSet<long>(); private static ZRoutedRpc registeredRpc; private static long identityServer; internal static void Update() { RegisterRpcs(); SendLocalIdentity(); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && RemoveDisconnectedPeers()) { BroadcastSnapshot(); } } internal static void Reset() { registeredRpc = null; identityServer = 0L; ClearState(); } private static void ClearState() { PeerPlayers.Clear(); OnlinePlayers.Clear(); StructureProtectionPlugin.Settings?.ResetClientState(); } internal static HashSet<long> GetOnlinePlayers() { return new HashSet<long>(OnlinePlayers); } private static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != registeredRpc) { instance.Register<long>("Landoria_StructureProtection_Identity", (Action<long, long>)ReceiveIdentity); instance.Register<ZPackage>("Landoria_StructureProtection_Snapshot", (Action<long, ZPackage>)ReceiveSnapshot); ClearState(); registeredRpc = instance; identityServer = 0L; } } private static void SendLocalIdentity() { ZNet instance = ZNet.instance; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)instance == (Object)null) && !((Object)(object)localPlayer == (Object)null) && !instance.IsServer() && registeredRpc != null) { ZNetPeer serverPeer = instance.GetServerPeer(); if (serverPeer != null && serverPeer.m_uid != identityServer) { identityServer = serverPeer.m_uid; registeredRpc.InvokeRoutedRPC(serverPeer.m_uid, "Landoria_StructureProtection_Identity", new object[1] { localPlayer.GetPlayerID() }); } } } private static void ReceiveIdentity(long sender, long playerId) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZNet.instance.GetPeer(sender) != null && playerId != 0L) { PeerPlayers[sender] = playerId; OnlinePlayers.Add(playerId); BroadcastSnapshot(); } } private static bool RemoveDisconnectedPeers() { bool result = false; foreach (long item in new List<long>(PeerPlayers.Keys)) { ZNetPeer peer = ZNet.instance.GetPeer(item); if (peer == null || !peer.IsReady()) { OnlinePlayers.Remove(PeerPlayers[item]); PeerPlayers.Remove(item); result = true; } } return result; } private static void BroadcastSnapshot() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown if (registeredRpc != null) { ZPackage val = new ZPackage(); WriteMappings(val); registeredRpc.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Landoria_StructureProtection_Snapshot", new object[1] { val }); } } private static void WriteMappings(ZPackage package) { StructureProtectionPlugin.Settings.WriteClientState(package); package.Write(PeerPlayers.Count); foreach (KeyValuePair<long, long> peerPlayer in PeerPlayers) { package.Write(peerPlayer.Value); } } private static void ReceiveSnapshot(long sender, ZPackage package) { if (IsTrustedServer(sender)) { StructureProtectionPlugin.Settings.ReadClientState(package); OnlinePlayers.Clear(); int num = package.ReadInt(); for (int i = 0; i < num; i++) { long item = package.ReadLong(); OnlinePlayers.Add(item); } } } private static bool IsTrustedServer(long sender) { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || instance.IsServer()) { if ((Object)(object)instance != (Object)null) { return instance.IsServer(); } return false; } ZNetPeer serverPeer = instance.GetServerPeer(); if (serverPeer == null) { return false; } return serverPeer.m_uid == sender; } } internal sealed class StructureProtectionSettings { private bool serverInitialized; internal bool CreatureTargetingEnabled { get; private set; } internal bool WardPlayerDamageEnabled { get; private set; } internal void InitializeServer(ModLog logger) { if (!serverInitialized && ServerRole.IsDedicatedServer) { StructureProtectionServerConfiguration structureProtectionServerConfiguration = StructureProtectionServerConfiguration.FromArguments(Environment.GetCommandLineArgs()); CreatureTargetingEnabled = structureProtectionServerConfiguration.CreatureTargetingEnabled; WardPlayerDamageEnabled = structureProtectionServerConfiguration.WardPlayerDamageEnabled; serverInitialized = true; logger.LogInfo("Effective structure protection settings: " + $"creatureTargeting={CreatureTargetingEnabled}, " + $"wardPlayerDamage={WardPlayerDamageEnabled}."); } } internal void WriteClientState(ZPackage package) { package.Write(CreatureTargetingEnabled); } internal void ReadClientState(ZPackage package) { CreatureTargetingEnabled = package.ReadBool(); } internal void ResetClientState() { if (!serverInitialized) { CreatureTargetingEnabled = false; WardPlayerDamageEnabled = false; } } } internal static class PieceActivity { internal static float GetMultiplier(Piece piece) { if ((Object)(object)piece == (Object)null || !piece.IsPlacedByPlayer()) { return 1f; } long creator = piece.GetCreator(); if (creator == 0L) { return 1f; } if (!CreatorActivityPolicy.IsCreatorActive(creator, StructureProtectionSession.GetOnlinePlayers())) { return 0f; } return 1f; } } internal static class WardProtection { [HarmonyPatch(typeof(PrivateArea), "Awake")] private static class WardAwakePatch { private static void Postfix(PrivateArea __instance) { Wards.Add(__instance); } } [HarmonyPatch(typeof(PrivateArea), "OnDestroy")] private static class WardDestroyPatch { private static void Prefix(PrivateArea __instance) { Wards.Remove(__instance); } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] private static class PlayerDamagePatch { private static bool Prefix(WearNTear __instance, HitData hit) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (StructureProtectionPlugin.Settings.WardPlayerDamageEnabled && hit != null && (int)hit.m_hitType == 2) { return !ShouldBlockPlayerDamage(((Component)__instance).transform.position); } return true; } } private static readonly HashSet<PrivateArea> Wards = new HashSet<PrivateArea>(); private static bool ShouldBlockPlayerDamage(Vector3 position) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) bool result = false; HashSet<long> onlinePlayers = StructureProtectionSession.GetOnlinePlayers(); foreach (PrivateArea ward in Wards) { if (TryGetWardState(ward, position, out var creator, out var permitted)) { result = true; if (WardProtectionPolicy.HasOnlineAuthorizedPlayer(creator, permitted, onlinePlayers)) { return false; } } } return result; } private static bool TryGetWardState(PrivateArea ward, Vector3 position, out long creator, out List<long> permitted) { //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) creator = 0L; permitted = null; ZNetView obj = (((Object)(object)ward != (Object)null) ? ((Component)ward).GetComponent<ZNetView>() : null); ZDO val = ((obj != null) ? obj.GetZDO() : null); if (val == null || !val.GetBool(ZDOVars.s_enabled, false) || Utils.DistanceXZ(((Component)ward).transform.position, position) >= ward.m_radius) { return false; } Piece component = ((Component)ward).GetComponent<Piece>(); creator = (((Object)(object)component != (Object)null) ? component.GetCreator() : 0); permitted = ReadPermittedPlayers(val); return creator != 0; } private static List<long> ReadPermittedPlayers(ZDO zdo) { List<long> list = new List<long>(); int num = zdo.GetInt(ZDOVars.s_permitted, 0); for (int i = 0; i < num; i++) { long num2 = zdo.GetLong("pu_id" + i, 0L); if (num2 != 0L) { list.Add(num2); } } return list; } } internal static class WardProtectionPolicy { internal static bool HasOnlineAuthorizedPlayer(long creator, IEnumerable<long> permittedPlayers, ISet<long> onlinePlayers) { if (onlinePlayers.Contains(creator)) { return true; } foreach (long permittedPlayer in permittedPlayers) { if (onlinePlayers.Contains(permittedPlayer)) { return true; } } return false; } } } 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}"); } } 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; } } } }