using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using IronLabs.SharedLib; using NetworkingUtils; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("IronLabs.WardenGameMode")] [assembly: AssemblyDescription("Adds enforced PvP with Warden safe zones.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("IronLabs.WardenGameMode")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("86006976-5150-4F0A-9A91-2104A9AC5C00")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.25081")] namespace IronLabs.WardenGameMode { [BepInPlugin("IronLabs.WardenGameMode", "IronLabs.WardenGameMode", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [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 sealed class WardenGameModePlugin : IronLabsPlugin { private const string PluginGuid = "IronLabs.WardenGameMode"; private const string PluginName = "IronLabs.WardenGameMode"; private const string PluginVersion = "1.0.0"; private bool? lastSafeZone; private TextMeshProUGUI safeZoneLabel; internal static ModLog Log { get; private set; } private void Awake() { Log = InitializePlugin("IronLabs.WardenGameMode"); Log.LogInfo("IronLabs.WardenGameMode 1.0.0 is loaded."); } private void Update() { SafeZoneService.Update(); InitialSpawnSelector.Update(); GroupRegistry.Update(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ResetTracking(); } else { UpdatePlayer(localPlayer); } } private void UpdatePlayer(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) bool flag = SafeZoneService.Contains(((Component)player).transform.position); UpdateSafeZoneLabel(flag); SetPvpState(player, !flag); LogTransition(flag); } private static void SetPvpState(Player player, bool enabled) { if (((Character)player).IsPVPEnabled() != enabled) { player.SetPVP(enabled); } } private void LogTransition(bool inside) { if (lastSafeZone != inside) { Log.LogDebug(inside ? "Player entered a PvP safe zone." : "Player left a PvP safe zone."); lastSafeZone = inside; } } private void UpdateSafeZoneLabel(bool visible) { if ((Object)(object)safeZoneLabel == (Object)null && visible) { CreateSafeZoneLabel(); } if ((Object)(object)safeZoneLabel != (Object)null) { ((Component)safeZoneLabel).gameObject.SetActive(visible); } } private void CreateSafeZoneLabel() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown Minimap instance = Minimap.instance; if (!((Object)(object)instance?.m_mapImageSmall == (Object)null) && !((Object)(object)instance.m_biomeNameSmall == (Object)null)) { GameObject val = new GameObject("WardenSafeZoneLabel", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(instance.m_smallRoot.transform, false); ConfigureLabel(val.GetComponent(), instance); } } private void ConfigureLabel(RectTransform rect, Minimap minimap) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_003f: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_007e: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0.5f, 1f); rect.sizeDelta = new Vector2(240f, 30f); RectTransform rectTransform = ((Graphic)minimap.m_mapImageSmall).rectTransform; Rect rect2 = rectTransform.rect; float x = ((Rect)(ref rect2)).center.x; rect2 = rectTransform.rect; ((Transform)rect).position = ((Transform)rectTransform).TransformPoint(new Vector3(x, ((Rect)(ref rect2)).yMin - 8f)); safeZoneLabel = ((Component)rect).gameObject.AddComponent(); ((TMP_Text)safeZoneLabel).text = "Safe Zone"; ((TMP_Text)safeZoneLabel).font = minimap.m_biomeNameSmall.font; ((TMP_Text)safeZoneLabel).fontSize = minimap.m_biomeNameSmall.fontSize; ((TMP_Text)safeZoneLabel).fontStyle = (FontStyles)1; ((TMP_Text)safeZoneLabel).alignment = (TextAlignmentOptions)514; } private void ResetTracking() { lastSafeZone = null; UpdateSafeZoneLabel(visible: false); } private void OnDestroy() { if ((Object)(object)safeZoneLabel != (Object)null) { Object.Destroy((Object)(object)((Component)safeZoneLabel).gameObject); } SafeZoneService.Reset(); GroupRegistry.Reset(); ResetTracking(); ShutdownPlugin(); Log = null; } } [HarmonyPatch(typeof(Minimap), "ExploreAll")] internal static class RevealWardensWithExploreMapPatch { private static void Postfix() { int num = SafeZoneService.RevealAllPositions(); WardenGameModePlugin.Log.LogDebug($"Explore map revealed {num} additional Warden markers."); } } [HarmonyPatch(typeof(Minimap), "Reset")] internal static class HideWardensWithResetMapPatch { private static void Postfix() { int num = SafeZoneService.HideAllPositions(); WardenGameModePlugin.Log.LogDebug($"Reset map hid {num} Warden markers."); } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] internal static class WardenSafeZoneMapOverlayPatch { private sealed class Marker { internal Vector3 Position; internal RectTransform Small; internal RectTransform Large; } private const float LargeMarkerSize = 10f; private const float SmallMarkerSize = 5f; private static readonly Dictionary Markers = new Dictionary(); private static Minimap owner; private static int lastLoggedCount = -1; private static void Postfix(Minimap __instance) { if ((Object)(object)owner != (Object)(object)__instance) { SetOwner(__instance); } HashSet hashSet = UpdateMarkers(__instance); RemoveObsolete(hashSet); if (lastLoggedCount != hashSet.Count) { lastLoggedCount = hashSet.Count; WardenGameModePlugin.Log.LogDebug($"Warden map markers active: {hashSet.Count}."); } } private static void SetOwner(Minimap minimap) { foreach (Marker value in Markers.Values) { DestroyMarker(value); } Markers.Clear(); owner = minimap; lastLoggedCount = -1; } private static HashSet UpdateMarkers(Minimap minimap) { //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_001b: 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_0040: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); foreach (Vector3 discoveredPosition in SafeZoneService.GetDiscoveredPositions()) { long key = GetKey(discoveredPosition); hashSet.Add(key); if (!Markers.TryGetValue(key, out var value)) { value = new Marker { Position = discoveredPosition }; Markers.Add(key, value); } UpdateMarker(minimap, value); } return hashSet; } private static void RemoveObsolete(HashSet active) { List list = new List(); foreach (KeyValuePair marker in Markers) { if (!active.Contains(marker.Key)) { DestroyMarker(marker.Value); list.Add(marker.Key); } } foreach (long item in list) { Markers.Remove(item); } } private static void UpdateMarker(Minimap minimap, Marker marker) { float num = marker.Position.x / minimap.m_pixelSize + (float)minimap.m_textureSize / 2f; float num2 = marker.Position.z / minimap.m_pixelSize + (float)minimap.m_textureSize / 2f; num /= (float)minimap.m_textureSize; num2 /= (float)minimap.m_textureSize; UpdateOnMap(ref marker.Small, minimap.m_pinRootSmall, minimap.m_mapImageSmall, "WardenSafeZoneSmall", num, num2, 5f); UpdateOnMap(ref marker.Large, minimap.m_pinRootLarge, minimap.m_mapImageLarge, "WardenSafeZoneLarge", num, num2, 10f); } private static void UpdateOnMap(ref RectTransform marker, RectTransform parent, RawImage map, string name, float mx, float my, float size) { //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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) Rect uvRect = map.uvRect; bool flag = mx > ((Rect)(ref uvRect)).xMin && mx < ((Rect)(ref uvRect)).xMax && my > ((Rect)(ref uvRect)).yMin && my < ((Rect)(ref uvRect)).yMax; if (flag && (Object)(object)marker == (Object)null) { marker = CreateMarker(parent, name, size); } if (!((Object)(object)marker == (Object)null)) { ((Component)marker).gameObject.SetActive(flag); if (flag) { ((Transform)marker).SetAsFirstSibling(); marker.anchoredPosition = GetMapPosition(map, uvRect, mx, my); } } } private static RectTransform CreateMarker(RectTransform parent, string name, float size) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //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_004a: 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_0061: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)parent, false); Vector2 anchorMin = (component.anchorMax = Vector2.zero); component.anchorMin = anchorMin; component.pivot = new Vector2(0.5f, 0.5f); component.SetSizeWithCurrentAnchors((Axis)0, size); component.SetSizeWithCurrentAnchors((Axis)1, size); ConfigureImage(val, size / 10f); return component; } private static void ConfigureImage(GameObject gameObject, float scale) { //IL_001b: 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_0041: 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_0061: Unknown result type (might be due to invalid IL or missing references) Image component = gameObject.GetComponent(); ((Graphic)component).color = new Color(0.9333333f, 0.9333333f, 0.9333333f, 1f); ((Graphic)component).raycastTarget = false; AddOutline(gameObject, 0.25f, new Vector2(2f, -2f) * scale); AddOutline(gameObject, 1f, new Vector2(1f, -1f) * scale); } private static void AddOutline(GameObject target, float alpha, Vector2 distance) { //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) Outline obj = target.AddComponent(); ((Shadow)obj).effectColor = new Color(0.2f, 0.2f, 0.2f, alpha); ((Shadow)obj).effectDistance = distance; ((Shadow)obj).useGraphicAlpha = true; } private static Vector2 GetMapPosition(RawImage map, Rect uv, float mx, float my) { //IL_0006: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Rect rect = ((Graphic)map).rectTransform.rect; return new Vector2((mx - ((Rect)(ref uv)).xMin) / ((Rect)(ref uv)).width * ((Rect)(ref rect)).width, (my - ((Rect)(ref uv)).yMin) / ((Rect)(ref uv)).height * ((Rect)(ref rect)).height); } private static long GetKey(Vector3 position) { //IL_0000: 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) int num = Mathf.RoundToInt(position.x * 10f); int num2 = Mathf.RoundToInt(position.z * 10f); return ((long)num << 32) | (uint)num2; } private static void DestroyMarker(Marker marker) { if ((Object)(object)marker.Small != (Object)null) { Object.Destroy((Object)(object)((Component)marker.Small).gameObject); } if ((Object)(object)marker.Large != (Object)null) { Object.Destroy((Object)(object)((Component)marker.Large).gameObject); } } } [HarmonyPatch(typeof(Player), "SetPVP")] internal static class ForcePvpStatePatch { private static void Prefix(Player __instance, ref bool enabled) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { enabled = !SafeZoneService.Contains(((Component)__instance).transform.position); } } } [HarmonyPatch(typeof(InventoryGui), "Awake")] internal static class HidePvpTogglePatch { private static void Postfix(InventoryGui __instance) { if ((Object)(object)__instance.m_pvp != (Object)null) { ((Component)__instance.m_pvp).gameObject.SetActive(false); } } } internal static class StructureProtection { internal static Piece GetPiece(Component component) { if (!((Object)(object)component != (Object)null)) { return null; } return component.GetComponentInParent(); } internal static bool IsProtectedFrom(Piece piece, Player player) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || (Object)(object)player == (Object)null || !piece.IsPlacedByPlayer()) { return false; } long creator = piece.GetCreator(); long playerID = player.GetPlayerID(); if (creator != playerID && !GroupRegistry.AreTogether(creator, playerID)) { return SafeZoneService.Contains(((Component)piece).transform.position); } return false; } internal static bool IsProtectedFromDamage(Piece piece, Character attacker) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || !piece.IsPlacedByPlayer() || !SafeZoneService.Contains(((Component)piece).transform.position)) { return false; } Player val = (Player)(object)((attacker is Player) ? attacker : null); if (!((Object)(object)val == (Object)null)) { return IsProtectedFrom(piece, val); } return (Object)(object)attacker != (Object)null; } internal static string GetOwnerName(Piece piece) { ZNetView component = ((Component)piece).GetComponent(); string text = ((((component != null) ? component.GetZDO() : null) != null) ? component.GetZDO().GetString(ZDOVars.s_creatorName, "") : ""); if (string.IsNullOrEmpty(text)) { Player player = Player.GetPlayer(piece.GetCreator()); if ((Object)(object)player != (Object)null) { text = player.GetPlayerName(); } } if (!string.IsNullOrEmpty(text)) { return text; } return "Unknown owner"; } } [HarmonyPatch(typeof(Character), "RPC_Damage")] internal static class DisableGroupFriendlyFirePatch { private static bool Prefix(Character __instance, HitData hit) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { Character attacker = hit.GetAttacker(); Player val2 = (Player)(object)((attacker is Player) ? attacker : null); if (val2 != null) { return !GroupRegistry.AreTogether(val.GetPlayerID(), val2.GetPlayerID()); } } return true; } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] internal static class ProtectStructuresFromDamagePatch { private static bool Prefix(WearNTear __instance, HitData hit) { if (WardenManager.IsManaged((Component)(object)__instance)) { return false; } return !StructureProtection.IsProtectedFromDamage(((Component)__instance).GetComponent(), hit.GetAttacker()); } } [HarmonyPatch(typeof(WearNTear), "Repair")] internal static class ProtectStructuresFromRepairPatch { private static bool Prefix(WearNTear __instance, ref bool __result) { if (WardenManager.IsManaged((Component)(object)__instance) || StructureProtection.IsProtectedFrom(((Component)__instance).GetComponent(), Player.m_localPlayer)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] internal static class ProtectStructuresFromRemovalPatch { private static bool Prefix(Player __instance, Piece piece, ref bool __result) { if (!WardenManager.IsManaged((Component)(object)piece) && !StructureProtection.IsProtectedFrom(piece, __instance)) { return true; } __result = false; return false; } } internal static class GroupRegistry { private const string RequestRpc = "IronLabs_WardenGameMode_RequestGroups"; private const string SyncRpc = "IronLabs_WardenGameMode_SyncGroups"; private static readonly Dictionary Memberships = new Dictionary(); private static ZRoutedRpc registeredRpc; private static float nextRequest; private static bool hasSnapshot; internal static void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { if (registeredRpc != instance) { instance.Register("IronLabs_WardenGameMode_SyncGroups", (Action)RPC_SyncGroups); registeredRpc = instance; Memberships.Clear(); hasSnapshot = false; nextRequest = 0f; } RequestIfNeeded(); } } internal static bool AreTogether(long first, long second) { if (first != 0L && second != 0L && Memberships.TryGetValue(first, out var value) && Memberships.TryGetValue(second, out var value2)) { return value == value2; } return false; } internal static void Reset() { registeredRpc = null; Memberships.Clear(); hasSnapshot = false; nextRequest = 0f; } private static void RequestIfNeeded() { if (!hasSnapshot && !(Time.unscaledTime < nextRequest) && !((Object)(object)ZNet.instance == (Object)null) && ZRoutedRpc.instance != null) { long num = (ZNet.instance.IsServer() ? ZRoutedRpc.Everybody : (ZNet.instance.GetServerPeer()?.m_uid ?? 0)); if (num != 0L) { nextRequest = Time.unscaledTime + 2f; ZRoutedRpc.instance.InvokeRoutedRPC(num, "IronLabs_WardenGameMode_RequestGroups", Array.Empty()); } } } private static void RPC_SyncGroups(long sender, ZPackage package) { Memberships.Clear(); int num = package.ReadInt(); for (int i = 0; i < num; i++) { Memberships[package.ReadLong()] = package.ReadInt(); } hasSnapshot = true; WardenGameModePlugin.Log.LogDebug($"Received {num} Socialize group memberships from peer {sender}."); } } internal static class ProtectedHoverText { internal static void Apply(Component target, ref string text) { Piece piece = StructureProtection.GetPiece(target); if (StructureProtection.IsProtectedFrom(piece, Player.m_localPlayer)) { int num = text.IndexOf('\n'); string text2 = ((num >= 0) ? text.Substring(0, num) : text); Container val = (Container)(object)((target is Container) ? target : null); if (val != null) { text2 = Localization.instance.Localize(val.GetHoverName()); } text = text2 + "\n" + StructureProtection.GetOwnerName(piece) + ""; } } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class ProtectedContainerHoverPatch { private static void Postfix(Container __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(Door), "GetHoverText")] internal static class ProtectedDoorHoverPatch { private static void Postfix(Door __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(CraftingStation), "GetHoverText")] internal static class ProtectedStationHoverPatch { private static void Postfix(CraftingStation __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(Fermenter), "GetHoverText")] internal static class ProtectedFermenterHoverPatch { private static void Postfix(Fermenter __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(ItemStand), "GetHoverText")] internal static class ProtectedItemStandHoverPatch { private static void Postfix(ItemStand __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(Bed), "GetHoverText")] internal static class ProtectedBedHoverPatch { private static void Postfix(Bed __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(Sign), "GetHoverText")] internal static class ProtectedSignHoverPatch { private static void Postfix(Sign __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] internal static class ProtectedPortalHoverPatch { private static void Postfix(TeleportWorld __instance, ref string __result) { ProtectedHoverText.Apply((Component)(object)__instance, ref __result); } } internal static class InteractionProtection { internal static bool AllowInteract(Component target, Humanoid humanoid, ref bool result) { if (!StructureProtection.IsProtectedFrom(StructureProtection.GetPiece(target), (Player)(object)((humanoid is Player) ? humanoid : null))) { return true; } result = false; return false; } internal static bool AllowUseItem(Component target, Humanoid humanoid, ref bool result) { if (!StructureProtection.IsProtectedFrom(StructureProtection.GetPiece(target), (Player)(object)((humanoid is Player) ? humanoid : null))) { return true; } result = true; return false; } } [HarmonyPatch(typeof(Container), "Interact")] internal static class ProtectContainerInteractionPatch { private static bool Prefix(Container __instance, Humanoid character, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, character, ref __result); } } [HarmonyPatch(typeof(Door), "Interact")] internal static class ProtectDoorInteractionPatch { private static bool Prefix(Door __instance, Humanoid character, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, character, ref __result); } } [HarmonyPatch(typeof(CraftingStation), "Interact")] internal static class ProtectStationInteractionPatch { private static bool Prefix(CraftingStation __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Fermenter), "Interact")] internal static class ProtectFermenterInteractionPatch { private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(ItemStand), "Interact")] internal static class ProtectItemStandInteractionPatch { private static bool Prefix(ItemStand __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Bed), "Interact")] internal static class ProtectBedInteractionPatch { private static bool Prefix(Bed __instance, Humanoid human, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, human, ref __result); } } [HarmonyPatch(typeof(Sign), "Interact")] internal static class ProtectSignInteractionPatch { private static bool Prefix(Sign __instance, Humanoid character, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, character, ref __result); } } [HarmonyPatch(typeof(TeleportWorld), "Interact")] internal static class ProtectPortalInteractionPatch { private static bool Prefix(TeleportWorld __instance, Humanoid human, ref bool __result) { return InteractionProtection.AllowInteract((Component)(object)__instance, human, ref __result); } } [HarmonyPatch(typeof(Container), "UseItem")] internal static class ProtectContainerUseItemPatch { private static bool Prefix(Container __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Door), "UseItem")] internal static class ProtectDoorUseItemPatch { private static bool Prefix(Door __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(CraftingStation), "UseItem")] internal static class ProtectStationUseItemPatch { private static bool Prefix(CraftingStation __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Fermenter), "UseItem")] internal static class ProtectFermenterUseItemPatch { private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(ItemStand), "UseItem")] internal static class ProtectItemStandUseItemPatch { private static bool Prefix(ItemStand __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Bed), "UseItem")] internal static class ProtectBedUseItemPatch { private static bool Prefix(Bed __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Sign), "UseItem")] internal static class ProtectSignUseItemPatch { private static bool Prefix(Sign __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(TeleportWorld), "UseItem")] internal static class ProtectPortalUseItemPatch { private static bool Prefix(TeleportWorld __instance, Humanoid user, ref bool __result) { return InteractionProtection.AllowUseItem((Component)(object)__instance, user, ref __result); } } [HarmonyPatch(typeof(Game), "FindSpawnPoint")] internal static class SelectInitialWardenSpawnPatch { private static bool Prefix(PlayerProfile ___m_playerProfile, bool ___m_respawnAfterDeath, ref Vector3 point, ref bool usedLogoutPoint, ref bool __result) { if (!ShouldUseWardenSpawn(___m_playerProfile, ___m_respawnAfterDeath)) { return true; } return InitialSpawnSelector.Handle(___m_playerProfile, ref point, ref usedLogoutPoint, ref __result); } private static bool ShouldUseWardenSpawn(PlayerProfile profile, bool respawnAfterDeath) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (profile == null || profile.HaveCustomSpawnPoint()) { return false; } if (!respawnAfterDeath && profile.HaveLogoutPoint()) { return false; } if (!(InitialSpawnSelector.HasActiveSelection(profile) || respawnAfterDeath) && !profile.m_firstSpawn) { return profile.GetHomePoint() == Vector3.zero; } return true; } } internal static class InitialSpawnSelector { private const int SpawnCount = 5; private const string RequestRpc = "IronLabs_Warden_RequestSpawnAssignment"; private const string ReceiveRpc = "IronLabs_Warden_ReceiveSpawnAssignment"; private const string LastAssignmentKey = "IronLabs_Warden_LastSpawnAssignment"; private static long selectionKey; private static WardenSpawnTarget selectedSpawn; private static bool spawnSelected; private static bool pendingRotation; private static float rotationDeadline; private static bool assignmentRequested; private static int assignedSpawnIndex = -1; private static ZRoutedRpc registeredRpc; private static void RPC_RequestSpawnAssignment(long sender, ZPackage package) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZRoutedRpc.instance != null) { long playerId = package.ReadLong(); long key = package.ReadLong(); ZDO primaryWardZdo = SafeZoneService.GetPrimaryWardZdo(); int index = ((primaryWardZdo == null) ? (-1) : (GetOrCreateAssignment(primaryWardZdo, playerId) - 1)); SendSpawnAssignment(sender, key, index); } } private static void RPC_ReceiveSpawnAssignment(long sender, ZPackage package) { long num = package.ReadLong(); int num2 = package.ReadInt(); assignmentRequested = false; if (num == selectionKey && num2 >= 0 && num2 < 5) { assignedSpawnIndex = num2; WardenGameModePlugin.Log.LogDebug($"Received initial spawn assignment {num2 + 1} from peer {sender}."); } } internal static void Update() { RegisterRpcs(); ApplyPendingRotation(); } internal static bool HasActiveSelection(PlayerProfile profile) { if (profile != null && (Object)(object)ZNet.instance != (Object)null && selectionKey == (profile.GetPlayerID() ^ ZNet.instance.GetWorldUID())) { return assignedSpawnIndex >= 0; } return false; } internal static bool TryGetAssignedSpawnPoint(out Vector3 position) { //IL_0006: 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) position = selectedSpawn.Position; return spawnSelected; } internal static bool Handle(PlayerProfile profile, ref Vector3 point, ref bool usedLogoutPoint, ref bool result) { List basePositions = SafeZoneService.GetBasePositions(); SetPendingResult(ref point, ref usedLogoutPoint, ref result); if (basePositions.Count < 5) { return false; } long key = profile.GetPlayerID() ^ ZNet.instance.GetWorldUID(); ResetSelectionIfNeeded(key); if (assignedSpawnIndex < 0) { RequestAssignment(profile.GetPlayerID(), key); return false; } if (!spawnSelected) { SelectSpawn(basePositions); } return ResolveSpawn(ref point, ref result); } private static bool ResolveSpawn(ref Vector3 point, ref bool result) { //IL_000a: 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_0031: 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) //IL_004f: Unknown result type (might be due to invalid IL or missing references) ZNet.instance.SetReferencePosition(selectedSpawn.Position); if (!ZNetScene.instance.IsAreaReady(selectedSpawn.Position)) { return false; } if (!WardenSpawnPlacement.TryCreateTarget(selectedSpawn.Warden, out var target)) { return true; } selectedSpawn = target; point = target.Position; result = true; pendingRotation = true; rotationDeadline = Time.time + 5f; return false; } private static void SelectSpawn(List wards) { //IL_0016: 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_0060: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(assignedSpawnIndex, 0, wards.Count - 1); selectedSpawn = WardenSpawnPlacement.CreateDefaultTarget(wards[num]); spawnSelected = true; WardenGameModePlugin.Log.LogInfo($"Selected initial Warden spawn {num + 1} at " + $"X={selectedSpawn.Position.x:0.0}, Z={selectedSpawn.Position.z:0.0}."); } private static void ResetSelectionIfNeeded(long key) { if (selectionKey != key) { selectionKey = key; spawnSelected = false; pendingRotation = false; assignmentRequested = false; assignedSpawnIndex = -1; } } private static void RequestAssignment(long playerId, long key) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown RegisterRpcs(); if (!assignmentRequested && ZRoutedRpc.instance != null) { assignmentRequested = true; ZPackage val = new ZPackage(); val.Write(playerId); val.Write(key); ZRoutedRpc.instance.InvokeRoutedRPC("IronLabs_Warden_RequestSpawnAssignment", new object[1] { val }); WardenGameModePlugin.Log.LogDebug($"Requested an initial spawn assignment for player {playerId}."); } } private static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && registeredRpc != instance) { instance.Register("IronLabs_Warden_RequestSpawnAssignment", (Action)RPC_RequestSpawnAssignment); instance.Register("IronLabs_Warden_ReceiveSpawnAssignment", (Action)RPC_ReceiveSpawnAssignment); registeredRpc = instance; assignmentRequested = false; } } private static int GetOrCreateAssignment(ZDO ward, long playerId) { int stableHashCode = StringExtensionMethods.GetStableHashCode("IronLabs_Warden_SpawnAssignment_" + playerId); int num = ward.GetInt(stableHashCode, 0); if (num >= 1 && num <= 5) { return num; } num = ward.GetInt(StringExtensionMethods.GetStableHashCode("IronLabs_Warden_LastSpawnAssignment"), 0) % 5 + 1; ward.Set(stableHashCode, num, false); ward.Set(StringExtensionMethods.GetStableHashCode("IronLabs_Warden_LastSpawnAssignment"), num, false); WardenGameModePlugin.Log.LogInfo($"Assigned initial Warden spawn {num} to player {playerId}."); return num; } private static void SendSpawnAssignment(long peer, long key, int index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(key); val.Write(index); ZRoutedRpc.instance.InvokeRoutedRPC(peer, "IronLabs_Warden_ReceiveSpawnAssignment", new object[1] { val }); } private static void SetPendingResult(ref Vector3 point, ref bool usedLogoutPoint, ref bool result) { //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) point = Vector3.zero; usedLogoutPoint = false; result = false; } private static void ApplyPendingRotation() { //IL_0030: 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_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) Player localPlayer = Player.m_localPlayer; if (!pendingRotation || (Object)(object)localPlayer == (Object)null) { return; } if (Time.time > rotationDeadline) { pendingRotation = false; return; } Vector3 val = ((Component)localPlayer).transform.position - selectedSpawn.Position; if (!(((Vector3)(ref val)).sqrMagnitude > 100f)) { WardenSpawnPlacement.AlignPlayer(localPlayer, selectedSpawn); pendingRotation = false; } } } internal static class WardBuildMenu { internal static void RemoveWard(ObjectDB objectDb) { HashSet hashSet = new HashSet(); foreach (GameObject item in objectDb.m_items) { ItemDrop component = item.GetComponent(); PieceTable val = (((Object)(object)component != (Object)null) ? component.m_itemData.m_shared.m_buildPieces : null); if (!((Object)(object)val == (Object)null) && hashSet.Add(val)) { val.m_pieces.RemoveAll(WardenManager.IsWardPrefab); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class RemoveWardOnObjectDbAwakePatch { private static void Postfix(ObjectDB __instance) { WardBuildMenu.RemoveWard(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] internal static class RemoveWardOnObjectDbCopyPatch { private static void Postfix(ObjectDB __instance) { WardBuildMenu.RemoveWard(__instance); } } internal static class SafeZoneService { private readonly struct SafeZonePoint { internal Vector3 Position { get; } internal float Radius { get; } internal SafeZonePoint(Vector3 position, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Position = position; Radius = radius; } } private const float DiscoveryRadius = 50f; private const string DiscoveryKeyPrefix = "IronLabs.WardenGameMode.Discovered."; private static readonly HashSet DiscoveredZones = new HashSet(); private static Player discoveryPlayer; private static long discoveryWorld; private const string RequestRpc = "IronLabs_WardenGameMode_RequestZones"; private const string SyncRpc = "IronLabs_WardenGameMode_SyncZones"; private const float RetryDelay = 2f; private const float GridSize = 500f; private const float WorldRadius = 10000f; private const float BaseRadius = 50f; private const float RegularRadius = 30f; private static readonly List ServerZones = new List(); private static readonly List ClientZones = new List(); private static ZRoutedRpc registeredRpc; private static long generatedWorld; private static float nextRequest; private static bool wardsCreated; private const Biome AllowedBiomes = (Biome)31; private static void RequestZonesIfNeeded() { if (ClientZones.Count <= 0 && !(Time.unscaledTime < nextRequest)) { ZNet instance = ZNet.instance; if (((instance != null) ? instance.GetServerPeer() : null) != null) { nextRequest = Time.unscaledTime + 2f; ZRoutedRpc.instance.InvokeRoutedRPC(ZNet.instance.GetServerPeer().m_uid, "IronLabs_WardenGameMode_RequestZones", Array.Empty()); } } } private static void RPC_RequestZones(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { EnsureGenerated(); SendZonesToPeer(sender); } } private static void RPC_SyncZones(long sender, ZPackage package) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { ClientZones.Clear(); int num = package.ReadInt(); for (int i = 0; i < num; i++) { ClientZones.Add(new SafeZonePoint(package.ReadVector3(), package.ReadSingle())); } WardenGameModePlugin.Log.LogInfo($"Received {num} PvP safe zones from peer {sender}."); } } private static void BroadcastZones() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "IronLabs_WardenGameMode_SyncZones", new object[1] { CreatePackage() }); } } private static void SendZonesToPeer(long peer) { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(peer, "IronLabs_WardenGameMode_SyncZones", new object[1] { CreatePackage() }); } } private static ZPackage CreatePackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(ServerZones.Count); foreach (SafeZonePoint serverZone in ServerZones) { val.Write(serverZone.Position); val.Write(serverZone.Radius); } return val; } internal static List GetDiscoveredPositions() { //IL_0027: 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) EnsureDiscoveryLoaded(); List list = new List(); foreach (SafeZonePoint currentZone in GetCurrentZones()) { if (DiscoveredZones.Contains(GetPositionKey(currentZone.Position))) { list.Add(currentZone.Position); } } return list; } internal static int RevealAllPositions() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) EnsureDiscoveryLoaded(); if ((Object)(object)discoveryPlayer == (Object)null) { return 0; } int num = 0; foreach (SafeZonePoint currentZone in GetCurrentZones()) { if (DiscoveredZones.Add(GetPositionKey(currentZone.Position))) { num++; } } if (num > 0) { SaveDiscovery(); } return num; } internal static int HideAllPositions() { EnsureDiscoveryLoaded(); if ((Object)(object)discoveryPlayer == (Object)null) { return 0; } int count = DiscoveredZones.Count; if (count == 0) { return 0; } DiscoveredZones.Clear(); SaveDiscovery(); return count; } private static void UpdateDiscovery() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } EnsureDiscoveryLoaded(); bool flag = false; float num = 2500f; foreach (SafeZonePoint currentZone in GetCurrentZones()) { Vector3 val = currentZone.Position - ((Component)localPlayer).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude <= num) { flag |= DiscoveredZones.Add(GetPositionKey(currentZone.Position)); } } if (flag) { SaveDiscovery(); } } private static void EnsureDiscoveryLoaded() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return; } long worldUID = ZNet.instance.GetWorldUID(); if (!((Object)(object)discoveryPlayer == (Object)(object)localPlayer) || discoveryWorld != worldUID) { discoveryPlayer = localPlayer; discoveryWorld = worldUID; DiscoveredZones.Clear(); if (localPlayer.m_customData.TryGetValue(GetDiscoveryKey(worldUID), out var value)) { LoadDiscovery(value); } } } private static void LoadDiscovery(string serialized) { string[] array = serialized.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { if (long.TryParse(array[i], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { DiscoveredZones.Add(result); } } } private static void SaveDiscovery() { List list = new List(); foreach (long discoveredZone in DiscoveredZones) { list.Add(discoveredZone.ToString("X16", CultureInfo.InvariantCulture)); } discoveryPlayer.m_customData[GetDiscoveryKey(discoveryWorld)] = string.Join(",", list.ToArray()); WardenGameModePlugin.Log.LogDebug($"Discovered Warden safe zones: {DiscoveredZones.Count}."); } private static List GetCurrentZones() { if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { return ClientZones; } return ServerZones; } private static long GetPositionKey(Vector3 position) { //IL_0000: 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) int num = Mathf.RoundToInt(position.x * 10f); int num2 = Mathf.RoundToInt(position.z * 10f); return ((long)num << 32) | (uint)num2; } private static string GetDiscoveryKey(long world) { return "IronLabs.WardenGameMode.Discovered." + world.ToString("X16", CultureInfo.InvariantCulture); } private static void ResetDiscovery() { discoveryPlayer = null; discoveryWorld = 0L; DiscoveredZones.Clear(); } internal static void Update() { RegisterRpcs(); UpdateDiscovery(); if (!((Object)(object)ZNet.instance == (Object)null)) { if (ZNet.instance.IsServer()) { EnsureGenerated(); EnsureWards(); } else { RequestZonesIfNeeded(); } } } internal static bool Contains(Vector3 point) { //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_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) foreach (SafeZonePoint item in ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) ? ServerZones : ClientZones) { Vector3 val = item.Position - point; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude <= item.Radius * item.Radius) { return true; } } return false; } internal static List GetBasePositions() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) List obj = (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) ? ServerZones : ClientZones); List list = new List(); foreach (SafeZonePoint item in obj) { if (Mathf.Approximately(item.Radius, 50f)) { list.Add(item.Position); } } return list; } internal static ZDO GetPrimaryWardZdo() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!EnsureGenerated() || ServerZones.Count == 0) { return null; } EnsureWards(); return WardenManager.GetWard(ServerZones[0].Position); } internal static void Reset() { registeredRpc = null; generatedWorld = 0L; ServerZones.Clear(); ClientZones.Clear(); nextRequest = 0f; wardsCreated = false; ResetDiscovery(); } private static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && registeredRpc != instance) { instance.Register("IronLabs_WardenGameMode_RequestZones", (Action)RPC_RequestZones); instance.Register("IronLabs_WardenGameMode_SyncZones", (Action)RPC_SyncZones); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { instance.m_onNewPeer = (Action)Delegate.Combine(instance.m_onNewPeer, new Action(SendZonesToPeer)); } registeredRpc = instance; ClientZones.Clear(); } } private static bool EnsureGenerated() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!CanGenerate(out var start)) { return false; } long worldUID = ZNet.instance.GetWorldUID(); if (generatedWorld == worldUID && ServerZones.Count > 0) { return true; } Generate(worldUID, start); BroadcastZones(); return true; } private static bool CanGenerate(out Vector3 start) { //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) start = Vector3.zero; if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && (Object)(object)ZoneSystem.instance != (Object)null && WorldGenerator.instance != null) { return ZoneSystem.instance.GetLocationIcon("StartTemple", ref start); } return false; } private static void Generate(long world, Vector3 start) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) ServerZones.Clear(); Random random = new Random((int)(world ^ (world >> 32))); GenerateBaseZones(random, start); GenerateGridZones(random, start); generatedWorld = world; wardsCreated = false; WardenGameModePlugin.Log.LogInfo($"Generated {ServerZones.Count} PvP safe zones."); } private static void GenerateBaseZones(Random random, Vector3 start) { //IL_0001: 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) GenerateBaseZones(random, start, requireClearing: true); if (CountZones(50f) < 5) { WardenGameModePlugin.Log.LogDebug("Fewer than five spawn Wardens fit in clearings; using regular Meadows."); GenerateBaseZones(random, start, requireClearing: false); } } private static void GenerateBaseZones(Random random, Vector3 start, bool requireClearing) { //IL_0038: 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) for (int i = 0; i < 20000; i++) { if (CountZones(50f) >= 5) { break; } double num = random.NextDouble() * Math.PI * 2.0; float num2 = Mathf.Sqrt((float)random.NextDouble()) * 1000f + 500f; TryAddBaseZone(start + new Vector3(Mathf.Cos((float)num) * num2, 0f, Mathf.Sin((float)num) * num2), requireClearing); } } private static void TryAddBaseZone(Vector3 point, bool requireClearing) { //IL_0005: 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: Invalid comparison between Unknown and I4 //IL_000e: 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_0029: 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_003e: 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_0059: Unknown result type (might be due to invalid IL or missing references) if ((int)WorldGenerator.instance.GetBiome(point) == 1 && IsAboveWater(point) && IsFlatEnough(point) && (!requireClearing || IsClearing(point)) && !HasZoneNear(point, 400f)) { point.y = WorldGenerator.instance.GetHeight(point.x, point.z); ServerZones.Add(new SafeZonePoint(point, 50f)); } } private static bool IsAboveWater(Vector3 point) { //IL_0005: 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) return WorldGenerator.instance.GetHeight(point.x, point.z) > ZoneSystem.instance.m_waterLevel + 1f; } private static bool IsFlatEnough(Vector3 point) { //IL_0005: 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) //IL_0025: 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_0031: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) float num2; float num = (num2 = WorldGenerator.instance.GetHeight(point.x, point.z)); Vector3[] flatnessOffsets = GetFlatnessOffsets(); foreach (Vector3 val in flatnessOffsets) { float height = WorldGenerator.instance.GetHeight(point.x + val.x, point.z + val.z); num2 = Mathf.Min(num2, height); num = Mathf.Max(num, height); } return num - num2 <= 2f; } private static Vector3[] GetFlatnessOffsets() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_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_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) return (Vector3[])(object)new Vector3[4] { new Vector3(4f, 0f, 0f), new Vector3(-4f, 0f, 0f), new Vector3(0f, 0f, 4f), new Vector3(0f, 0f, -4f) }; } private static bool IsClearing(Vector3 point) { //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_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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0026: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3[] clearingOffsets = GetClearingOffsets(); foreach (Vector3 val in clearingOffsets) { Vector3 val2 = point + val; if ((int)WorldGenerator.instance.GetBiome(val2) != 1 || WorldGenerator.InForest(val2)) { return false; } } return true; } private static Vector3[] GetClearingOffsets() { //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_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_003e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0079: Unknown result type (might be due to invalid IL or missing references) return (Vector3[])(object)new Vector3[5] { Vector3.zero, new Vector3(12f, 0f, 0f), new Vector3(-12f, 0f, 0f), new Vector3(0f, 0f, 12f), new Vector3(0f, 0f, -12f) }; } private static int CountZones(float radius) { int num = 0; foreach (SafeZonePoint serverZone in ServerZones) { if (Mathf.Approximately(serverZone.Radius, radius)) { num++; } } return num; } private static void GenerateGridZones(Random random, Vector3 start) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) float num = -9750f; for (float num2 = num; num2 < 10000f; num2 += 500f) { for (float num3 = num; num3 < 10000f; num3 += 500f) { TryAddGridZone(random, start, num2, num3); } } } private static void TryAddGridZone(Random random, Vector3 start, float x, float z) { //IL_003a: 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_0048: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); for (int i = 0; i < 20; i++) { ((Vector3)(ref val))..ctor(x - 150f + (float)random.NextDouble() * 300f, 0f, z - 150f + (float)random.NextDouble() * 300f); if (DistanceSquared(val, start) >= 40000f && TryAddZone(val, 30f, (Biome)31, 60f)) { break; } } } private static bool TryAddZone(Vector3 point, float radius, Biome biomes, float spacing) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_002a: 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_0040: 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_0068: Unknown result type (might be due to invalid IL or missing references) if (DistanceSquared(point, Vector3.zero) > 100000000f || (WorldGenerator.instance.GetBiome(point) & biomes) == 0) { return false; } point.y = WorldGenerator.instance.GetHeight(point.x, point.z); if (point.y <= ZoneSystem.instance.m_waterLevel + 1f || HasZoneNear(point, spacing)) { return false; } ServerZones.Add(new SafeZonePoint(point, radius)); return true; } private static bool HasZoneNear(Vector3 point, float distance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) foreach (SafeZonePoint serverZone in ServerZones) { if (DistanceSquared(serverZone.Position, point) < distance * distance) { return true; } } return false; } private static float DistanceSquared(Vector3 first, Vector3 second) { //IL_0000: 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_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) float num = first.x - second.x; float num2 = first.z - second.z; return num * num + num2 * num2; } private static void EnsureWards() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (wardsCreated || ServerZones.Count <= 0) { return; } wardsCreated = WardenManager.EnsureReady(); if (!wardsCreated) { return; } foreach (SafeZonePoint serverZone in ServerZones) { WardenManager.EnsureWard(serverZone.Position); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class AddAssignedWardenSpawnPinPatch { private const string PinCreatedKeyPrefix = "IronLabs.WardenGameMode.StartPin."; private static void Postfix(Player __instance) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)Minimap.instance == (Object)null) && !((Object)(object)ZNet.instance == (Object)null) && InitialSpawnSelector.TryGetAssignedSpawnPoint(out var position)) { string key = "IronLabs.WardenGameMode.StartPin." + ZNet.instance.GetWorldUID(); if (!__instance.m_customData.ContainsKey(key)) { Minimap.instance.AddPin(position, (PinType)3, "START", true, false, 0L, default(PlatformUserID)); __instance.m_customData[key] = bool.TrueString; WardenGameModePlugin.Log.LogDebug($"Added removable Warden start pin at {position}."); } } } } internal static class TemporaryFavoriteServerPatches { [HarmonyPatch(typeof(LocalServerList), "GetFilteredListInternal")] private static class FilteredListPatch { private static void Postfix(LocalServerList __instance, List resultOutput) { //IL_0013: 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) if (__instance.DisplayName == "$menu_favorite" && !resultOutput.Contains(Server)) { resultOutput.Add(Server); } } } [HarmonyPatch(typeof(SteamworksMatchmaking), "OnServerPingCompleted")] private static class PingCompletedPatch { private static void Prefix(ServerData serverData, ref ServerJoinData ___m_activeDedicatedSearch) { //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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0047: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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) if (((ServerJoinData)(ref ___m_activeDedicatedSearch)).IsValid && !(___m_activeDedicatedSearch == serverData.m_joinData)) { if (HasSameResolvedEndpoint(___m_activeDedicatedSearch, serverData.m_joinData)) { ___m_activeDedicatedSearch = serverData.m_joinData; } else { WardenGameModePlugin.Log.LogWarning($"Steam ping mismatch: active '{___m_activeDedicatedSearch}', " + $"callback '{serverData.m_joinData}'."); } } } private static bool HasSameResolvedEndpoint(ServerJoinData active, ServerJoinData callback) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: 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_0010: Invalid comparison between Unknown and I4 //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_002e: 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_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) IPv6Address? val = default(IPv6Address?); if ((int)active.m_type == 3 && (int)callback.m_type == 3 && ((ServerJoinData)(ref active)).Dedicated.m_port == ((ServerJoinData)(ref callback)).Dedicated.m_port && MultiBackendMatchmaking.GetServerIPCached(((ServerJoinData)(ref active)).Dedicated, ref val) && val.HasValue) { ServerJoinDataDedicated dedicated = ((ServerJoinData)(ref callback)).Dedicated; IPv6Address val2 = default(IPv6Address); if (((ServerJoinDataDedicated)(ref dedicated)).TryGetIPAddress(ref val2)) { return val.Value == val2; } } return false; } } private const string FavoriteListName = "$menu_favorite"; private const uint ServerAddress = 1424627151u; private const ushort ServerPort = 2456; private static readonly ServerJoinData Server = new ServerJoinData(new ServerJoinDataDedicated(1424627151u, (ushort)2456)); } internal static class WardenManager { internal const string MarkerKey = "IronLabs.WardenGameMode.ManagedWard"; private const string PrefabName = "guard_stone"; private const float VisualScale = 3f; private static readonly List SectorObjects = new List(); internal static bool EnsureReady() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZDOMan.instance != null && (Object)(object)ZNetScene.instance != (Object)null && WorldGenerator.instance != null) { return (Object)(object)ZNetScene.instance.GetPrefab("guard_stone") != (Object)null; } return false; } internal static void EnsureWard(Vector3 position) { //IL_0007: 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_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) position.y = WorldGenerator.instance.GetHeight(position.x, position.z) + 0.05f; if (FindWard(position) == null) { CreateWard(position); } } internal static ZDO GetWard(Vector3 position) { //IL_0007: 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_0023: Unknown result type (might be due to invalid IL or missing references) position.y = WorldGenerator.instance.GetHeight(position.x, position.z) + 0.05f; return FindWard(position); } internal static bool IsManaged(Component component) { ZNetView val = (((Object)(object)component != (Object)null) ? component.GetComponentInParent() : null); if (((val != null) ? val.GetZDO() : null) != null) { return val.GetZDO().GetBool("IronLabs.WardenGameMode.ManagedWard", false); } return false; } internal static bool IsWardPrefab(GameObject prefab) { if ((Object)(object)prefab != (Object)null) { return string.Equals(((Object)prefab).name, "guard_stone", StringComparison.OrdinalIgnoreCase); } return false; } internal static void ApplyVisualScale(Component component) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (IsManaged(component)) { ((Component)component.GetComponentInParent()).transform.localScale = Vector3.one * 3f; } } private static ZDO FindWard(Vector3 position) { //IL_000f: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) SectorObjects.Clear(); ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(position), 0, 0, SectorObjects, (List)null); foreach (ZDO sectorObject in SectorObjects) { if (sectorObject.GetBool("IronLabs.WardenGameMode.ManagedWard", false)) { Vector3 val = sectorObject.GetPosition() - position; if (((Vector3)(ref val)).sqrMagnitude < 4f) { return sectorObject; } } } return null; } private static void CreateWard(Vector3 position) { //IL_0028: 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_0056: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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) GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone"); int prefabHash = ZNetScene.instance.GetPrefabHash(prefab); ZNetView component = prefab.GetComponent(); ZDO obj = ZDOMan.instance.CreateNewZDO(position, prefabHash); obj.Persistent = true; obj.Type = component.m_type; obj.Distant = component.m_distant; obj.SetPrefab(prefabHash); obj.SetRotation(Quaternion.identity); obj.Set("IronLabs.WardenGameMode.ManagedWard", true); obj.Set(ZDOVars.s_enabled, false); obj.Set(ZDOVars.s_creator, 0L); obj.Set(ZDOVars.s_scaleHash, Vector3.one * 3f); obj.Set(ZDOVars.s_scaleScalarHash, 3f); WardenGameModePlugin.Log.LogDebug($"Created persistent Warden at X={position.x:0.0}, Z={position.z:0.0}."); } } [HarmonyPatch(typeof(PrivateArea), "Awake")] internal static class DisableManagedWardenPatch { private static void Postfix(PrivateArea __instance, ZNetView ___m_nview) { if (WardenManager.IsManaged((Component)(object)__instance)) { WardenManager.ApplyVisualScale((Component)(object)__instance); if (___m_nview.IsOwner()) { ___m_nview.GetZDO().Set(ZDOVars.s_enabled, false); } ((MonoBehaviour)__instance).CancelInvoke(); ((Behaviour)__instance).enabled = false; SetActive(__instance.m_enabledEffect, active: false); SetActive(__instance.m_inRangeEffect, active: false); if ((Object)(object)__instance.m_areaMarker != (Object)null) { ((Component)__instance.m_areaMarker).gameObject.SetActive(false); } } } private static void SetActive(GameObject target, bool active) { if ((Object)(object)target != (Object)null) { target.SetActive(active); } } } [HarmonyPatch(typeof(PrivateArea), "UseItem")] internal static class BlockManagedWardenItemsPatch { private static bool Prefix(PrivateArea __instance, ref bool __result) { if (!WardenManager.IsManaged((Component)(object)__instance)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(PrivateArea), "Interact")] internal static class ManagedWardenInteractionPatch { private static readonly Dictionary LastMessageByWarden = new Dictionary(); private static readonly string[] Messages = new string[6] { "Sorry to find you in this place, valiant wanderer. I am a Warden; perhaps we may yet be allies.", "Build beneath my watch, and the night will find fewer cracks.", "We are many; you will find others like me.", "Wood and stone are humble gifts, but they become shelter.", "A fallen power leaves a trophy behind; offer it at the stones, and its strength may become yours.", "This land is a prison for Odin's old enemies, bound here after a war older than memory." }; private static bool Prefix(PrivateArea __instance, Humanoid human, bool hold, ref bool __result) { if (!WardenManager.IsManaged((Component)(object)__instance)) { return true; } if (!hold && human is Player) { ShowMessage(__instance); } __result = true; return false; } private static void ShowMessage(PrivateArea warden) { //IL_0019: 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) if (!((Object)(object)Chat.instance == (Object)null)) { Chat.instance.SetNpcText(((Component)warden).gameObject, Vector3.up * 3f, 25f, 5f, "Warden", GetMessage(warden), false); } } private static string GetMessage(PrivateArea warden) { int instanceID = ((Object)warden).GetInstanceID(); int value; int num = (LastMessageByWarden.TryGetValue(instanceID, out value) ? GetDifferentIndex(value) : Random.Range(0, Messages.Length)); LastMessageByWarden[instanceID] = num; return Messages[num]; } private static int GetDifferentIndex(int previous) { int num = Random.Range(0, Messages.Length - 1); if (num < previous) { return num; } return num + 1; } } [HarmonyPatch(typeof(PrivateArea), "GetHoverText")] internal static class ManagedWardenHoverPatch { private static bool Prefix(PrivateArea __instance, ref string __result) { if (!WardenManager.IsManaged((Component)(object)__instance)) { return true; } __result = Localization.instance.Localize("Warden\n[$KEY_Use] Talk"); return false; } } [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] internal static class BlockManagedWardenDamagePatch { private static bool Prefix(WearNTear __instance, ref bool __result) { if (!WardenManager.IsManaged((Component)(object)__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(WearNTear), "Damage")] internal static class BlockManagedWardenDirectDamagePatch { private static bool Prefix(WearNTear __instance) { return !WardenManager.IsManaged((Component)(object)__instance); } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] internal static class BlockManagedWardenWearPatch { private static bool Prefix(WearNTear __instance) { return !WardenManager.IsManaged((Component)(object)__instance); } } internal readonly struct WardenSpawnTarget { internal Vector3 Warden { get; } internal Vector3 Position { get; } internal Quaternion Rotation { get; } internal WardenSpawnTarget(Vector3 warden, Vector3 position, Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0009: 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) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Warden = warden; Position = position; Rotation = rotation; } } internal static class WardenSpawnPlacement { private const float PreferredDistance = 4f; private const float PlayerClearanceRadius = 0.6f; private const float PlayerClearanceHeight = 1.8f; private const float WardenEyeHeight = 2.4f; private static readonly int SpawnBlockMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "piece", "character", "character_net", "vehicle" }); internal static WardenSpawnTarget CreateDefaultTarget(Vector3 warden) { //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) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0034: 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) Vector3 val = CreateCandidate(warden, 4f, 0f); val.y = WorldGenerator.instance.GetHeight(val.x, val.z) + 0.5f; return CreateTarget(warden, val); } internal static bool TryCreateTarget(Vector3 warden, out WardenSpawnTarget target) { //IL_0000: 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) //IL_001e: 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) foreach (Vector3 candidate in GetCandidates(warden)) { if (TryGround(candidate, out var position)) { target = CreateTarget(warden, position); return true; } } target = default(WardenSpawnTarget); return false; } internal static void AlignPlayer(Player player, WardenSpawnTarget target) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0041: 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) //IL_004b: 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) ((Component)player).transform.rotation = target.Rotation; if ((Object)(object)((Character)player).m_eye != (Object)null) { Vector3 direction = target.Warden + Vector3.up * 2.4f - ((Character)player).m_eye.position; if (ApplyLookDirection(player, target, direction)) { return; } } player.SetMouseLookForward(true); player.SetMouseLook(Vector2.zero); player.FaceLookDirection(); } private static bool ApplyLookDirection(Player player, WardenSpawnTarget target, Vector3 direction) { //IL_0012: 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_001c: 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_0042: 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 (((Vector3)(ref direction)).sqrMagnitude <= 0.001f) { return false; } Quaternion val = Quaternion.LookRotation(((Vector3)(ref direction)).normalized); float num = ((Quaternion)(ref val)).eulerAngles.x; if (num > 180f) { num -= 360f; } ((Component)player).transform.rotation = target.Rotation; player.SetMouseLookForward(true); player.SetMouseLook(new Vector2(0f, 0f - num)); player.FaceLookDirection(); return true; } private static WardenSpawnTarget CreateTarget(Vector3 warden, Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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) //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_0035: 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_003a: 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_003c: 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) Vector3 val = warden - position; val.y = 0f; Quaternion rotation = ((((Vector3)(ref val)).sqrMagnitude > 0.001f) ? Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up) : Quaternion.identity); return new WardenSpawnTarget(warden, position, rotation); } private static bool TryGround(Vector3 candidate, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_003a: 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_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_0059: Unknown result type (might be due to invalid IL or missing references) position = candidate; if (!ZNetScene.instance.IsAreaReady(candidate)) { return false; } Vector3 val = default(Vector3); Biome val2 = default(Biome); BiomeArea val3 = default(BiomeArea); Heightmap val4 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref position, ref val, ref val2, ref val3, ref val4); if ((Object)(object)val4 == (Object)null || (int)val2 != 1) { return false; } position += Vector3.up * 0.5f; return IsClear(position); } private static bool IsClear(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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) //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_0016: 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_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) Vector3 val = position + Vector3.up * 0.6f; Vector3 val2 = position + Vector3.up * 1.8f; return !Physics.CheckCapsule(val, val2, 0.6f, SpawnBlockMask, (QueryTriggerInteraction)1); } private static IEnumerable GetCandidates(Vector3 warden) { //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) float[] array = new float[3] { 4f, 3f, 5f }; float[] angles = new float[16] { 0f, 15f, -15f, 30f, -30f, 45f, -45f, 60f, -60f, 90f, -90f, 120f, -120f, 150f, -150f, 180f }; float[] array2 = array; foreach (float distance in array2) { float[] array3 = angles; foreach (float angle in array3) { yield return CreateCandidate(warden, distance, angle); } } } private static Vector3 CreateCandidate(Vector3 warden, float distance, float angle) { //IL_0000: 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_001c: 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) return warden + Quaternion.Euler(0f, angle, 0f) * Vector3.forward * distance; } } [HarmonyPatch(typeof(ZoneSystem), "Start")] internal static class EnablePlayerEventsPatch { private static void Postfix(ZoneSystem __instance) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !__instance.GetGlobalKey((GlobalKeys)13)) { __instance.SetGlobalKey((GlobalKeys)13); WardenGameModePlugin.Log.LogInfo("Enabled the PlayerEvents world key."); } } } } namespace IronLabs.SharedLib { public abstract class IronLabsPlugin : 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}"); } } }