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 WardenPvPGameMode v1.0.0
IronLabs.WardenGameMode.dll
Decompiled a day agousing 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<RectTransform>(), 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<TextMeshProUGUI>(); ((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<long, Marker> Markers = new Dictionary<long, Marker>(); 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<long> 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<long> 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<long> hashSet = new HashSet<long>(); 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<long> active) { List<long> list = new List<long>(); foreach (KeyValuePair<long, Marker> 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<RectTransform>(); ((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<Image>(); ((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<Outline>(); ((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<Piece>(); } 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<ZNetView>(); 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<Piece>(), 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<Piece>(), 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<long, int> Memberships = new Dictionary<long, int>(); 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<ZPackage>("IronLabs_WardenGameMode_SyncGroups", (Action<long, ZPackage>)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<object>()); } } } 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<color=yellow><b>" + StructureProtection.GetOwnerName(piece) + "</b></color>"; } } } [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<Vector3> 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<Vector3> 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<ZPackage>("IronLabs_Warden_RequestSpawnAssignment", (Action<long, ZPackage>)RPC_RequestSpawnAssignment); instance.Register<ZPackage>("IronLabs_Warden_ReceiveSpawnAssignment", (Action<long, ZPackage>)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<PieceTable> hashSet = new HashSet<PieceTable>(); foreach (GameObject item in objectDb.m_items) { ItemDrop component = item.GetComponent<ItemDrop>(); 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<long> DiscoveredZones = new HashSet<long>(); 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<SafeZonePoint> ServerZones = new List<SafeZonePoint>(); private static readonly List<SafeZonePoint> ClientZones = new List<SafeZonePoint>(); 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<object>()); } } } 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<Vector3> 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<Vector3> list = new List<Vector3>(); 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<string> list = new List<string>(); 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<SafeZonePoint> 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<Vector3> GetBasePositions() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) List<SafeZonePoint> obj = (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) ? ServerZones : ClientZones); List<Vector3> list = new List<Vector3>(); 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<long>)RPC_RequestZones); instance.Register<ZPackage>("IronLabs_WardenGameMode_SyncZones", (Action<long, ZPackage>)RPC_SyncZones); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { instance.m_onNewPeer = (Action<long>)Delegate.Combine(instance.m_onNewPeer, new Action<long>(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<ServerJoinData> 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<ZDO> SectorObjects = new List<ZDO>(); 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<ZNetView>() : 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<ZNetView>()).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<ZDO>)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<ZNetView>(); 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<int, int> LastMessageByWarden = new Dictionary<int, int>(); 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[<color=yellow><b>$KEY_Use</b></color>] 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<Vector3> 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}"); } } }