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 WindheimShips v0.1.1
plugins\Windheim.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Managers; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using Windheim.Config; using Windheim.ShipRecall; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Windheim")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Windheim")] [assembly: AssemblyTitle("Windheim")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Windheim { [BepInPlugin("com.TAIJI.windheim", "WindheimShips", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class WindheimPlugin : BaseUnityPlugin { public const string PluginGUID = "com.TAIJI.windheim"; public const string PluginName = "WindheimShips"; public const string PluginVersion = "0.1.0"; public static WindheimPlugin Instance { get; private set; } private void Awake() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Instance = this; GeneralConfig.Bind(((BaseUnityPlugin)this).Config); FleetConfig.Bind(((BaseUnityPlugin)this).Config); RecallConfig.Bind(((BaseUnityPlugin)this).Config); MapConfig.Bind(((BaseUnityPlugin)this).Config); UIConfig.Bind(((BaseUnityPlugin)this).Config); PersistenceConfig.Bind(((BaseUnityPlugin)this).Config); CompatibilityConfig.Bind(((BaseUnityPlugin)this).Config); DebugConfig.Bind(((BaseUnityPlugin)this).Config); ExperimentalConfig.Bind(((BaseUnityPlugin)this).Config); InputManager.Instance.AddButton("com.TAIJI.windheim", new ButtonConfig { Name = "WH_ShipRecall", Key = RecallConfig.RecallKey.Value, HintToken = "Recall Ship" }); new Harmony("com.TAIJI.windheim").PatchAll(); GameObject val = new GameObject("Windheim_Host"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<ShipRegistry>(); val.AddComponent<ShipRecallSystem>(); val.AddComponent<QuickRecallUI>(); if (GeneralConfig.ShowWelcomeMessage.Value) { Logger.LogInfo((object)"WindheimShips 0.1.0 loaded."); } } private void Update() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { QuickRecallUI instance = QuickRecallUI.Instance; if ((instance == null || !instance.IsOpen) && !IsTyping() && Input.GetKeyDown(RecallConfig.RecallKey.Value)) { ShipRecallSystem.Instance?.TrySummon(); } } } private static bool IsTyping() { try { EventSystem current = EventSystem.current; if ((Object)(object)current == (Object)null) { return false; } GameObject currentSelectedGameObject = current.currentSelectedGameObject; InputField val = default(InputField); return (Object)(object)currentSelectedGameObject != (Object)null && currentSelectedGameObject.TryGetComponent<InputField>(ref val); } catch { return false; } } } [HarmonyPatch(typeof(Ship), "Awake")] internal static class Patch_Ship_Awake { private static void Postfix(Ship __instance) { ShipRegistry.Instance?.RegisterShip(__instance); } } } namespace Windheim.ShipRecall { public class QuickRecallUI : MonoBehaviour { private Canvas _canvas; private CanvasGroup _group; private GameObject _root; private const float W = 460f; private const float CARD_W = 310f; private const float CARD_H = 52f; private const float ICON_W = 44f; private const float PAD_TOP = 28f; private const float TITLE_H = 54f; private const float SUB_H = 22f; private const float GAP = 44f; private const float CARD_GAP = 10f; private const float PAD_BOT = 28f; private static readonly Color C_Title = new Color(0.97f, 0.94f, 0.83f, 1f); private static readonly Color C_Sub = new Color(0.78f, 0.72f, 0.58f, 1f); private static readonly Color C_CardBg = new Color(0.04f, 0.04f, 0.03f, 0.84f); private static readonly Color C_CardHov = new Color(0.16f, 0.12f, 0.05f, 0.92f); private static readonly Color C_CardPrs = new Color(0.26f, 0.18f, 0.06f, 0.96f); private static readonly Color C_Name = new Color(0.97f, 0.93f, 0.82f, 1f); private static readonly Color C_NameNone = new Color(0.6f, 0.54f, 0.44f, 1f); private static readonly Color C_IconPri = new Color(0.97f, 0.8f, 0.24f, 1f); private static readonly Color C_IconSec = new Color(0.86f, 0.9f, 0.96f, 1f); private static readonly Color C_Overlay = new Color(0f, 0f, 0f, 0.42f); private static readonly Color C_Border = new Color(0.58f, 0.46f, 0.18f, 0.85f); public static QuickRecallUI Instance { get; private set; } public bool IsOpen { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } private static Font NorseFont { get { GUIManager instance = GUIManager.Instance; return ((instance != null) ? instance.NorseBold : null) ?? Resources.GetBuiltinResource<Font>("Arial.ttf"); } } private static Font BodyFont { get { GUIManager instance = GUIManager.Instance; object obj = ((instance != null) ? instance.AveriaSerifBold : null); if (obj == null) { GUIManager instance2 = GUIManager.Instance; obj = ((instance2 != null) ? instance2.AveriaSerif : null) ?? Resources.GetBuiltinResource<Font>("Arial.ttf"); } return (Font)obj; } } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } GUIManager.BlockInput(false); } private void LateUpdate() { if (IsOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)2; if (Input.GetKeyDown((KeyCode)27)) { Close(); } } } public void Open() { EnsureCanvas(); Rebuild(); _root.SetActive(true); GUIManager.BlockInput(true); ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(FadeIn()); } public void Close() { if (IsOpen) { ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(FadeClose()); } } private IEnumerator FadeIn() { if (!((Object)(object)_group == (Object)null)) { _group.alpha = 0f; float t = 0f; while (t < 0.2f) { t += Time.unscaledDeltaTime; _group.alpha = Mathf.Clamp01(t / 0.2f); yield return null; } _group.alpha = 1f; } } private IEnumerator FadeClose() { if ((Object)(object)_group != (Object)null) { float s = _group.alpha; float t = 0f; while (t < 0.14f) { t += Time.unscaledDeltaTime; _group.alpha = Mathf.Lerp(s, 0f, t / 0.14f); yield return null; } _group.alpha = 0f; } if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } GUIManager.BlockInput(false); } private void Rebuild() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } ShipRegistry instance = ShipRegistry.Instance; if (!((Object)(object)instance == (Object)null)) { float num = 290f; float leftX = 75f; _root = new GameObject("WH_QR_Root"); _root.transform.SetParent(((Component)_canvas).transform, false); RectTransform obj = _root.AddComponent<RectTransform>(); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); obj.anchorMax = val; obj.anchorMin = val; obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = Vector2.zero; obj.sizeDelta = new Vector2(460f, num); _group = _root.AddComponent<CanvasGroup>(); GameObject obj2 = MakeGo("Bg", _root.transform); ((Graphic)obj2.AddComponent<Image>()).color = C_Overlay; Fill(obj2.GetComponent<RectTransform>()); float num2 = -28f; GameObject obj3 = MakeGo("Title", _root.transform); Text obj4 = obj3.AddComponent<Text>(); obj4.font = NorseFont; obj4.fontSize = 36; obj4.fontStyle = (FontStyle)1; ((Graphic)obj4).color = C_Title; obj4.alignment = (TextAnchor)4; obj4.supportRichText = true; obj4.text = "<color=#C09040>∾∾</color> Windheim Fleet <color=#C09040>∾∾</color>"; obj4.horizontalOverflow = (HorizontalWrapMode)1; obj4.verticalOverflow = (VerticalWrapMode)1; PinRT(obj3.GetComponent<RectTransform>(), 0f, num2, 460f, 54f); num2 -= 54f; GameObject obj5 = MakeGo("Sub", _root.transform); Text obj6 = obj5.AddComponent<Text>(); obj6.font = BodyFont; obj6.fontSize = 12; ((Graphic)obj6).color = C_Sub; obj6.alignment = (TextAnchor)4; obj6.text = "Choose a ship to recall"; obj6.horizontalOverflow = (HorizontalWrapMode)1; obj6.verticalOverflow = (VerticalWrapMode)1; PinRT(obj5.GetComponent<RectTransform>(), 0f, num2, 460f, 22f); num2 -= 66f; Game instance2 = Game.instance; object obj7; if (instance2 == null) { obj7 = null; } else { PlayerProfile playerProfile = instance2.GetPlayerProfile(); obj7 = ((playerProfile != null) ? playerProfile.GetName() : null); } if (obj7 == null) { Player localPlayer = Player.m_localPlayer; obj7 = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Wanderer"; } string playerName = (string)obj7; BuildCard(_root.transform, instance.Primary, isPrimary: true, leftX, num2, playerName); num2 -= 62f; BuildCard(_root.transform, instance.Secondary, isPrimary: false, leftX, num2, playerName); } } private void BuildCard(Transform parent, ShipRecord rec, bool isPrimary, float leftX, float topY, string playerName) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown float num = 308f; float num2 = 50f; GameObject val = MakeGo("Border", parent); ((Graphic)val.AddComponent<Image>()).color = C_Border; PinRT(val.GetComponent<RectTransform>(), leftX, topY, 310f, 52f); GameObject val2 = MakeGo("Fill", val.transform); Image val3 = val2.AddComponent<Image>(); ((Graphic)val3).color = C_CardBg; PinRT(val2.GetComponent<RectTransform>(), 1f, -1f, num, num2); GameObject obj = MakeGo("IconBg", val2.transform); ((Graphic)obj.AddComponent<Image>()).color = new Color(0.07f, 0.06f, 0.04f, 0.72f); PinRT(obj.GetComponent<RectTransform>(), 0f, 0f, 44f, num2); float num3 = 24f; BuildIconCell(x: (44f - num3) * 0.5f, y: 0f - Mathf.Floor((num2 - num3) * 0.5f), parent: obj.transform, rec: rec, isPrimary: isPrimary, size: num3); GameObject obj2 = MakeGo("Div", val2.transform); ((Graphic)obj2.AddComponent<Image>()).color = new Color(0.5f, 0.4f, 0.16f, 0.6f); PinRT(obj2.GetComponent<RectTransform>(), 44f, -8f, 1f, num2 - 16f); float num4 = 58f; float w = num - num4 - 10f; float num5 = 22f; float y = 0f - Mathf.Floor((num2 - num5) * 0.5f); string text = ((rec == null) ? (isPrimary ? "No Flagship" : "No Boat") : (isPrimary ? "Flagship" : "Boat")); GameObject obj3 = MakeGo("Name", val2.transform); Text obj4 = obj3.AddComponent<Text>(); obj4.font = NorseFont; obj4.fontSize = 16; ((Graphic)obj4).color = ((rec != null) ? C_Name : C_NameNone); obj4.alignment = (TextAnchor)3; obj4.text = text; obj4.horizontalOverflow = (HorizontalWrapMode)1; obj4.verticalOverflow = (VerticalWrapMode)1; PinRT(obj3.GetComponent<RectTransform>(), num4, y, w, num5); if (rec != null) { Button obj5 = val.AddComponent<Button>(); ((Selectable)obj5).targetGraphic = (Graphic)(object)val3; ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = C_CardBg; ((ColorBlock)(ref defaultColorBlock)).highlightedColor = C_CardHov; ((ColorBlock)(ref defaultColorBlock)).pressedColor = C_CardPrs; ((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.1f; ((Selectable)obj5).colors = defaultColorBlock; ShipRecord captured = rec; ((UnityEvent)obj5.onClick).AddListener((UnityAction)delegate { ShipRecallSystem.Instance?.PerformSummon(captured); }); } } internal static void BuildIconCell(Transform parent, ShipRecord rec, bool isPrimary, float x, float y, float size) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Sprite val = ((rec != null) ? GetSpriteByName(isPrimary ? "mapicon_hammer" : "mapicon_pin") : null); if ((Object)(object)val != (Object)null) { Image obj = MakeGo("Spr", parent).AddComponent<Image>(); obj.sprite = val; obj.type = (Type)0; obj.preserveAspect = true; ((Graphic)obj).color = rec.MapIconColor; PinRT(((Graphic)obj).rectTransform, x, y, size, size); return; } Image obj2 = MakeGo("Dot", parent).AddComponent<Image>(); ((Graphic)obj2).color = (Color)((rec != null) ? C_IconSec : new Color(0.38f, 0.34f, 0.26f, 0.55f)); PinRT(((Graphic)obj2).rectTransform, x, y, size, size); GameObject obj3 = MakeGo("Abbr", parent); Text obj4 = obj3.AddComponent<Text>(); obj4.font = NorseFont; obj4.fontSize = 12; obj4.fontStyle = (FontStyle)1; ((Graphic)obj4).color = new Color(0.06f, 0.04f, 0.02f, 1f); obj4.alignment = (TextAnchor)4; obj4.text = ShipAbbr(rec, isPrimary); obj4.horizontalOverflow = (HorizontalWrapMode)1; obj4.verticalOverflow = (VerticalWrapMode)1; PinRT(obj3.GetComponent<RectTransform>(), x, y, size, size); } private void EnsureCanvas() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvas != (Object)null)) { GameObject val = new GameObject("WH_QuickRecall_Canvas"); Object.DontDestroyOnLoad((Object)(object)val); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 200; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); } } internal static Sprite GetPinSprite(PinType pinType) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null) { return null; } List<SpriteData> icons = Minimap.instance.m_icons; if (icons == null) { return null; } foreach (SpriteData item in icons) { if (item.m_name == pinType) { return item.m_icon; } } return null; } internal static Sprite GetSpriteByName(string spriteName) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) if (Minimap.instance?.m_icons != null) { foreach (SpriteData icon in Minimap.instance.m_icons) { if ((Object)(object)icon.m_icon != (Object)null && ((Object)icon.m_icon).name == spriteName) { return icon.m_icon; } } } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == spriteName) { return val; } } return null; } private static string ShipAbbr(ShipRecord rec, bool isPrimary) { if (rec == null) { if (!isPrimary) { return "S"; } return "P"; } return rec.Type switch { "Karve" => "K", "Longship" => "L", "Drakkar" => "D", _ => "R", }; } private static string TitleCase(string s) { if (string.IsNullOrEmpty(s)) { return s; } char[] array = s.ToLower().ToCharArray(); array[0] = char.ToUpper(array[0]); for (int i = 1; i < array.Length; i++) { if (array[i - 1] == ' ') { array[i] = char.ToUpper(array[i]); } } return new string(array); } internal static GameObject MakeGo(string name, Transform parent) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown GameObject val = new GameObject(name); val.AddComponent<RectTransform>(); val.transform.SetParent(parent, false); return val; } internal static void PinRT(RectTransform rt, float x, float y, float w, float h) { //IL_000b: 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_0035: 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_0050: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = new Vector2(0f, 1f); rt.anchorMax = new Vector2(0f, 1f); rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, y); rt.sizeDelta = new Vector2(w, h); } internal static void Fill(RectTransform rt) { //IL_0001: 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_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) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.anchoredPosition = Vector2.zero; rt.sizeDelta = Vector2.zero; } } [HarmonyPatch(typeof(ShipControlls), "Interact")] internal static class Patch_ShipControlls_SetPrimary { [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(ShipControlls), "Interact", new Type[3] { typeof(Humanoid), typeof(bool), typeof(bool) }, (Type[])null) != null; } private static void Postfix(ShipControlls __instance) { HelmHelper.DoSetPrimary(__instance); } } [HarmonyPatch(typeof(ShipControlls), "TryInteract")] internal static class Patch_ShipControlls_SetPrimary_TryInteract { [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(ShipControlls), "TryInteract", new Type[3] { typeof(Humanoid), typeof(bool), typeof(bool) }, (Type[])null) != null; } private static void Postfix(ShipControlls __instance) { HelmHelper.DoSetPrimary(__instance); } } internal static class HelmHelper { internal static void DoSetPrimary(ShipControlls controls) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } Ship componentInParent = ((Component)controls).GetComponentInParent<Ship>(); if ((Object)(object)componentInParent == (Object)null) { return; } ShipRegistry.Instance?.RegisterShip(componentInParent); ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO == null) { return; } long ownerID = ShipRegistry.GetOwnerID(); long myUID = ShipRegistry.GetMyUID(); long num = zDO.GetLong("WH_Owner", 0L); if (num == 0L && component.IsOwner()) { zDO.Set("WH_Owner", ownerID); num = ownerID; } else if (num == myUID && num != ownerID && component.IsOwner()) { zDO.Set("WH_Owner", ownerID); num = ownerID; } if (num == ownerID) { ShipRecord shipRecord = ShipRegistry.Instance?.GetOwnedRecord(zDO.m_uid); if (shipRecord != null && !shipRecord.IsSecondary) { ShipRegistry.Instance?.SetPrimary(shipRecord); } } } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] internal static class Patch_Minimap_UpdatePins_ApplyColors { private static Sprite _hammerSprite; private static Sprite _pinSprite; [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(Minimap), "UpdatePins", (Type[])null, (Type[])null) != null; } private static void EnsureSprites() { if ((Object)(object)_hammerSprite != (Object)null && (Object)(object)_pinSprite != (Object)null) { return; } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if (!((Object)(object)val == (Object)null)) { if (((Object)val).name == "mapicon_hammer") { _hammerSprite = val; } else if (((Object)val).name == "mapicon_pin") { _pinSprite = val; } if ((Object)(object)_hammerSprite != (Object)null && (Object)(object)_pinSprite != (Object)null) { break; } } } } private static void Postfix() { //IL_0026: 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_0047: 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_006c: 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) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) ShipRegistry instance = ShipRegistry.Instance; if ((Object)(object)instance == (Object)null) { return; } EnsureSprites(); ZDOID val = instance.Primary?.ID ?? ZDOID.None; foreach (ShipRecord item in instance.GetOwnedByLocalPlayer()) { PinData pinData = instance.GetPinData(item.ID); if ((Object)(object)pinData?.m_uiElement == (Object)null) { continue; } Sprite val2 = ((val != ZDOID.None && item.ID == val) ? _hammerSprite : _pinSprite); Color mapIconColor = item.MapIconColor; try { Image componentInChildren = ((Component)pinData.m_uiElement).GetComponentInChildren<Image>(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)val2 != (Object)null) { componentInChildren.sprite = val2; } Image[] componentsInChildren = ((Component)pinData.m_uiElement).GetComponentsInChildren<Image>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Graphic)componentsInChildren[i]).color = mapIconColor; } } catch { } } } } [HarmonyPatch(typeof(Minimap), "SetMapMode")] internal static class Patch_Minimap_SetMapMode_EnsurePins { [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(Minimap), "SetMapMode", (Type[])null, (Type[])null) != null; } private static void Postfix(MapMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)mode == 2) { ShipRegistry.Instance?.EnsurePinsOnMap(); } } } [HarmonyPatch(typeof(Minimap), "ClearPins")] internal static class Patch_Minimap_ClearPins_RestoreShipPins { [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(Minimap), "ClearPins", (Type[])null, (Type[])null) != null; } private static void Postfix() { ShipRegistry.Instance?.RestorePins(); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class Patch_Player_ShipRecallSpawn { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ShipRegistry.Instance?.OnPlayerSpawned(); } } } [HarmonyPatch(typeof(WearNTear), "Damage")] internal static class Patch_WearNTear_SecondaryIndestructible { [HarmonyPrepare] private static bool Prepare() { return AccessTools.Method(typeof(WearNTear), "Damage", (Type[])null, (Type[])null) != null; } private static bool Prefix(WearNTear __instance) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Component)__instance).GetComponent<Ship>() == (Object)null) { return true; } ShipRegistry instance = ShipRegistry.Instance; if ((Object)(object)instance == (Object)null) { return true; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } ZDO zDO = component.GetZDO(); if (zDO != null) { return !instance.IsSecondaryShip(zDO.m_uid); } return true; } } public class ShipRecallSystem : MonoBehaviour { private float _cooldown; private bool _spawnInProgress; public static ShipRecallSystem Instance { get; private set; } public bool OnCooldown => _cooldown > 0f; public float CooldownRemaining => _cooldown; private static float PrimaryMaxRadius => Mathf.Max(RecallConfig.RadiusMin.Value, RecallConfig.RadiusMax.Value - 20f); private static float SecondaryMaxRadius => Mathf.Max(RecallConfig.RadiusMin.Value, RecallConfig.RadiusMax.Value - 40f); private static float SecondaryMinDepth => 1.2f; private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { if (!(_cooldown <= 0f)) { _cooldown -= Time.deltaTime; if (_cooldown < 0f) { _cooldown = 0f; } } } public void TrySummon() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (OnCooldown) { if (RecallConfig.ShowCooldownMessage.Value) { ((Character)localPlayer).Message((MessageType)2, $"Ship Recall: {_cooldown:F0}s", 0, (Sprite)null); } return; } ShipRegistry.Instance?.ScanLoaded(); ShipRegistry instance = ShipRegistry.Instance; if ((Object)(object)instance != (Object)null && !instance.HasPrimary && !instance.HasSecondary) { ((Character)localPlayer).Message((MessageType)2, "No ships assigned. Build a ship and take the helm to set your Primary.", 0, (Sprite)null); } else { QuickRecallUI.Instance?.Open(); } } public void PerformSummon(ShipRecord record) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (record.IsSecondary && !record.IsDeployed) { if (_spawnInProgress) { ((Character)localPlayer).Message((MessageType)2, "Boat is already being summoned.", 0, (Sprite)null); return; } QuickRecallUI.Instance?.Close(); ((MonoBehaviour)this).StartCoroutine(SpawnStoredSecondary()); return; } if ((Object)(object)record.Ship == (Object)null) { RecoverShipRef(record); } if ((Object)(object)record.Ship == (Object)null) { long ownerID = ShipRegistry.GetOwnerID(); ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(record.ID) : null); if (val != null) { bool num = val.GetLong("WH_Owner", 0L) == ownerID; bool flag = (record.IsSecondary ? val.GetBool("WH_IsSec", false) : val.GetBool("WH_IsPri", false)); if (!num || !flag) { val = null; } } if (val == null) { val = FindShipZDO(record, ownerID); if (val != null) { ShipRegistry.Instance?.UpdateShipZDOID(record, val.m_uid); } } if (val == null) { if (record.IsSecondary) { ShipRegistry.Instance?.ReturnSecondaryToStorage(); QuickRecallUI.Instance?.Close(); ((MonoBehaviour)this).StartCoroutine(SpawnStoredSecondary()); } else { ((Character)localPlayer).Message((MessageType)2, "Ship not found.", 0, (Sprite)null); } return; } float maxRadius = (record.IsSecondary ? SecondaryMaxRadius : PrimaryMaxRadius); float minDepth = (record.IsSecondary ? SecondaryMinDepth : RecallConfig.MinDepth.Value); WaterScanner.ScanResult scanResult = WaterScanner.FindSummonPosition(((Component)localPlayer).transform.position, FlatForward(localPlayer), RecallConfig.RadiusMin.Value, maxRadius, minDepth); Vector3 position = (scanResult.Found ? scanResult.Position : (((Component)localPlayer).transform.position + FlatForward(localPlayer) * 15f)); position.y = WaterLevel(); val.SetOwner(ZNet.GetUID()); val.SetPosition(position); record.Position = position; ShipRegistry.Instance?.ClearStaleRoleFlags(record.IsSecondary, val.m_uid, ownerID); ((Character)localPlayer).Message((MessageType)1, record.DisplayName + " is on its way.", 0, (Sprite)null); BeginCooldown(); ShipRegistry.Instance?.TouchLastUsed(record); QuickRecallUI.Instance?.Close(); } else if (IsOccupied(record.Ship) && FleetConfig.OccupiedShipMode?.Value == "block") { ((Character)localPlayer).Message((MessageType)2, "That ship is currently occupied.", 0, (Sprite)null); } else { float maxRadius2 = (record.IsSecondary ? SecondaryMaxRadius : PrimaryMaxRadius); float minDepth2 = (record.IsSecondary ? SecondaryMinDepth : RecallConfig.MinDepth.Value); WaterScanner.ScanResult scanResult2 = WaterScanner.FindSummonPosition(((Component)localPlayer).transform.position, FlatForward(localPlayer), RecallConfig.RadiusMin.Value, maxRadius2, minDepth2, record.Ship); if (!scanResult2.Found) { ((Character)localPlayer).Message((MessageType)2, "No valid water location found nearby.", 0, (Sprite)null); return; } TeleportShip(record.Ship, scanResult2.Position, scanResult2.Rotation); ShipRegistry.Instance?.TouchLastUsed(record); BeginCooldown(); QuickRecallUI.Instance?.Close(); ((Character)localPlayer).Message((MessageType)1, record.DisplayName + " recalled.", 0, (Sprite)null); } } private IEnumerator SpawnStoredSecondary() { if (_spawnInProgress) { yield break; } _spawnInProgress = true; try { Player player = Player.m_localPlayer; if ((Object)(object)player == (Object)null) { yield break; } ShipRegistry reg = ShipRegistry.Instance; if ((Object)(object)reg == (Object)null || !reg.HasSecondary) { yield break; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(reg.SecondaryType) : null); if ((Object)(object)val == (Object)null) { ((Character)player).Message((MessageType)2, "Could not find ship prefab (" + reg.SecondaryType + ").", 0, (Sprite)null); yield break; } WaterScanner.ScanResult scanResult = WaterScanner.FindSummonPosition(((Component)player).transform.position, FlatForward(player), RecallConfig.RadiusMin.Value, SecondaryMaxRadius, SecondaryMinDepth); if (!scanResult.Found) { ((Character)player).Message((MessageType)2, "No valid water location found nearby.", 0, (Sprite)null); yield break; } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(scanResult.Position.x, WaterLevel(), scanResult.Position.z); GameObject raftGo = Object.Instantiate<GameObject>(val, val2, scanResult.Rotation); if ((Object)(object)raftGo == (Object)null) { yield break; } ZNetView nv = raftGo.GetComponent<ZNetView>(); for (int i = 0; i < 60; i++) { if (!((Object)(object)nv == (Object)null) && nv.IsValid()) { break; } yield return null; if ((Object)(object)nv == (Object)null) { nv = raftGo.GetComponent<ZNetView>(); } } Ship component = raftGo.GetComponent<Ship>(); if ((Object)(object)component != (Object)null) { reg.DeploySecondary(component); } BeginCooldown(); ((Character)player).Message((MessageType)1, "Boat deployed nearby.", 0, (Sprite)null); } finally { _spawnInProgress = false; } } private void TeleportShip(Ship ship, Vector3 scanPos, Quaternion rot) { //IL_0021: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)ship).GetComponent<ZNetView>(); Rigidbody component2 = ((Component)ship).GetComponent<Rigidbody>(); if (component != null) { component.ClaimOwnership(); } float num = WaterLevel(); Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(scanPos.x, num, scanPos.z); if ((Object)(object)component2 != (Object)null) { component2.linearVelocity = Vector3.zero; component2.angularVelocity = Vector3.zero; component2.position = position; component2.rotation = rot; } ((Component)ship).transform.position = position; ((Component)ship).transform.rotation = rot; Physics.SyncTransforms(); if (component != null) { ZDO zDO = component.GetZDO(); if (zDO != null) { zDO.SetPosition(position); } } if ((Object)(object)component2 != (Object)null) { ((MonoBehaviour)this).StartCoroutine(PinY(component2)); } } private static IEnumerator PinY(Rigidbody rb) { if (!((Object)(object)rb == (Object)null)) { RigidbodyConstraints saved = rb.constraints; rb.constraints = (RigidbodyConstraints)(saved | 4); yield return (object)new WaitForSeconds(1f); if (!((Object)(object)rb == (Object)null)) { Vector3 linearVelocity = rb.linearVelocity; linearVelocity.y = 0f; rb.linearVelocity = linearVelocity; rb.constraints = saved; } } } private static void RecoverShipRef(ShipRecord record) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); foreach (ZNetView val in array) { ZDOID? val2 = val.GetZDO()?.m_uid; ZDOID iD = record.ID; if (val2.HasValue && !(val2.GetValueOrDefault() != iD)) { record.Ship = ((Component)val).GetComponent<Ship>(); record.IsLoaded = (Object)(object)record.Ship != (Object)null; if ((Object)(object)record.Ship != (Object)null) { return; } } } int typeHash = ShipRegistry.GetTypeHash(record.Type); if (typeHash == 0) { return; } Ship val3 = null; ZDOID iD2 = ZDOID.None; float num = 50f; array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); foreach (ZNetView val4 in array) { Ship component = ((Component)val4).GetComponent<Ship>(); if ((Object)(object)component == (Object)null) { continue; } ZDO zDO = val4.GetZDO(); if (zDO != null && zDO.GetPrefab() == typeHash) { float num2 = Vector3.Distance(((Component)component).transform.position, record.Position); if (num2 < num) { val3 = component; num = num2; iD2 = zDO.m_uid; } } } if ((Object)(object)val3 != (Object)null) { record.Ship = val3; record.IsLoaded = true; record.ID = iD2; } } private static ZDO FindShipZDO(ShipRecord record, long ownerID) { if (ZDOMan.instance == null) { return null; } string text = ShipRegistry.TypeToPrefabName((!record.IsSecondary) ? record.Type : (ShipRegistry.Instance?.SecondaryType ?? "Raft")); string text2 = (record.IsSecondary ? "WH_IsSec" : "WH_IsPri"); List<ZDO> list = new List<ZDO>(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(text, list, ref num)) { } foreach (ZDO item in list) { if (item.GetLong("WH_Owner", 0L) == ownerID && item.GetBool(text2, false)) { return item; } } return null; } private void BeginCooldown() { _cooldown = RecallConfig.Cooldown.Value; } private static bool IsOccupied(Ship ship) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) try { int mask = LayerMask.GetMask(new string[1] { "character" }); Collider[] array = Physics.OverlapSphere(((Component)ship).transform.position, 8f, mask); for (int i = 0; i < array.Length; i++) { Player component = ((Component)array[i]).GetComponent<Player>(); if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)Player.m_localPlayer) { return true; } } } catch { } return false; } private static float WaterLevel() { if (!((Object)(object)ZoneSystem.instance != (Object)null) || !(ZoneSystem.instance.m_waterLevel > 1f)) { return 30f; } return ZoneSystem.instance.m_waterLevel; } private static Vector3 FlatForward(Player player) { //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_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_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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(((Component)player).transform.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; if (!(((Vector3)(ref normalized)).sqrMagnitude > 0.01f)) { return Vector3.forward; } return normalized; } } public class ShipRecord { public ZDOID ID; public string Type; public string CustomName; public long OwnerID; public Vector3 Position; public Quaternion Rotation; public DateTime LastUsed; public bool IsLoaded; public bool IsSecondary; public Color MapIconColor = Color.white; public PinType MapIconType; public Ship Ship; public bool IsDeployed => ID != ZDOID.None; public string DisplayName { get { if (!string.IsNullOrEmpty(CustomName)) { return CustomName; } return Type; } } public string DisplayNameWithOwner(string ownerName) { return DisplayName + " (" + ownerName + ")"; } public float DistanceTo(Vector3 pos) { //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) return Vector3.Distance(Position, pos); } public float HealthPercent() { try { Ship ship = Ship; float? obj; if (ship == null) { obj = null; } else { WearNTear component = ((Component)ship).GetComponent<WearNTear>(); obj = ((component != null) ? new float?(component.GetHealthPercentage()) : ((float?)null)); } return obj ?? 1f; } catch { return 1f; } } } public class ShipRegistry : MonoBehaviour { private readonly Dictionary<ZDOID, ShipRecord> _records = new Dictionary<ZDOID, ShipRecord>(); private readonly Dictionary<ZDOID, PinData> _pins = new Dictionary<ZDOID, PinData>(); internal const string ZDO_OWNER = "WH_Owner"; internal const string ZDO_NAME = "WH_Name"; private const string ZDO_LASTUSED = "WH_LastUsed"; internal const string ZDO_ISSEC = "WH_IsSec"; internal const string ZDO_ISPRI = "WH_IsPri"; private static readonly PinType ShipPinType = (PinType)0; public static readonly int HashRaft = StableHash("Raft"); public static readonly int HashKarve = StableHash("Karve"); public static readonly int HashVikingShip = StableHash("VikingShip"); public static readonly int HashDrakkar = StableHash("Drakkar"); private ZDOID _primaryID = ZDOID.None; private ZDOID _secondaryID = ZDOID.None; private bool _hasSecondary; private string _secondaryType = "Raft"; private string _secondaryCustomName = "Boat"; private bool _sessionLoaded; private bool _miniPinsEnsured; private bool _dirty; private float _pruneTimer = 5f; private bool _pendingSpawn; private float _diagTriggerTimer; private float _diagScanCountdown = -1f; private bool _diagScanDone; private const int SAVE_VERSION = 5; public static ShipRegistry Instance { get; private set; } public ShipRecord Primary => GetRecord(_primaryID); public bool HasPrimary => Primary != null; public bool HasSecondary => _hasSecondary; public bool SecondaryDeployed { get { //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) if (_hasSecondary) { return _secondaryID != ZDOID.None; } return false; } } public string SecondaryType => _secondaryType; public ShipRecord Secondary { get { //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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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 (!_hasSecondary) { return null; } if (_secondaryID != ZDOID.None && _records.TryGetValue(_secondaryID, out var value)) { return value; } return new ShipRecord { ID = ZDOID.None, Type = _secondaryType, CustomName = "Boat", OwnerID = GetOwnerID(), IsSecondary = true, MapIconColor = Color.white, MapIconType = ShipPinType, LastUsed = DateTime.UtcNow }; } } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } ClearAllPins(); } private void Update() { if (_sessionLoaded && (Object)(object)ZNet.instance == (Object)null) { ResetSession(); return; } if (!_sessionLoaded && (Object)(object)ZNet.instance != (Object)null) { _diagTriggerTimer -= Time.deltaTime; if (_diagTriggerTimer <= 0f) { _diagTriggerTimer = 2f; long myUID = GetMyUID(); Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } long? num = obj; long valueOrDefault = num.GetValueOrDefault(); long worldUID = GetWorldUID(); Logger.LogInfo((object)$"[WH Trigger] waiting — myUID={myUID} profileID={valueOrDefault} worldUID={worldUID}"); } } if (!_sessionLoaded && (Object)(object)ZNet.instance != (Object)null && GetMyUID() != 0L) { Game instance2 = Game.instance; long? obj2; if (instance2 == null) { obj2 = null; } else { PlayerProfile playerProfile2 = instance2.GetPlayerProfile(); obj2 = ((playerProfile2 != null) ? new long?(playerProfile2.GetPlayerID()) : ((long?)null)); } long? num = obj2; if (num.GetValueOrDefault() != 0L && GetWorldUID() != 0L) { Game instance3 = Game.instance; long? obj3; if (instance3 == null) { obj3 = null; } else { PlayerProfile playerProfile3 = instance3.GetPlayerProfile(); obj3 = ((playerProfile3 != null) ? new long?(playerProfile3.GetPlayerID()) : ((long?)null)); } num = obj3; long valueOrDefault2 = num.GetValueOrDefault(); Logger.LogInfo((object)($"[WH Trigger] FIRED — myUID={GetMyUID()} profileID={valueOrDefault2} worldUID={GetWorldUID()} pendingSpawn={_pendingSpawn}\n" + " path=" + SavePath())); _sessionLoaded = true; _diagScanCountdown = 4f; LoadRegistry(); if (_pendingSpawn) { EnsureSecondaryEntry(); } } } if (_sessionLoaded && !_miniPinsEnsured && (Object)(object)Minimap.instance != (Object)null) { _miniPinsEnsured = true; EnsurePinsOnMap(); } if (_sessionLoaded && !_diagScanDone && _diagScanCountdown > 0f) { _diagScanCountdown -= Time.deltaTime; if (_diagScanCountdown <= 0f) { _diagScanDone = true; DiagnosticWorldScan(); } } _pruneTimer -= Time.deltaTime; if (!(_pruneTimer > 0f)) { _pruneTimer = 5f; PruneGone(); UpdateLoadedPositions(); if (_dirty) { SaveRegistry(); _dirty = false; } } } public void RegisterShip(Ship ship) { //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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ship == (Object)null) { return; } ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO == null) { return; } int prefab = zDO.GetPrefab(); if (prefab == 0) { return; } ZDOID uid = zDO.m_uid; long ownerID = GetOwnerID(); long myUID = GetMyUID(); long num = zDO.GetLong("WH_Owner", 0L); if (component.IsOwner()) { if (num == 0L) { zDO.Set("WH_Owner", ownerID); num = ownerID; _dirty = true; } else if (num == myUID && num != ownerID) { zDO.Set("WH_Owner", ownerID); num = ownerID; _dirty = true; } } bool flag = ownerID != 0L && num == ownerID; ShipRecord value; bool flag2 = !_records.TryGetValue(uid, out value); if (flag2) { value = new ShipRecord { ID = uid, Type = TypeName(prefab), OwnerID = num, LastUsed = DateTime.UtcNow }; _records[uid] = value; if (flag) { _dirty = true; } } Logger.LogInfo((object)($"[WH Ship] {TypeName(prefab)} zdoid={uid} zdoOwner={num} ownerID={ownerID} " + $"isNew={flag2} recOwner={value.OwnerID} ownedByMe={flag}")); value.Ship = ship; value.IsLoaded = true; value.Position = ((Component)ship).transform.position; value.Rotation = ((Component)ship).transform.rotation; value.CustomName = zDO.GetString("WH_Name", ""); value.MapIconType = ShipPinType; long num2 = zDO.GetLong("WH_LastUsed", 0L); if (num2 > 0) { value.LastUsed = new DateTime(num2, DateTimeKind.Utc); } if (!flag) { return; } value.OwnerID = ownerID; if (zDO.GetBool("WH_IsPri", false)) { if (_primaryID != ZDOID.None && _primaryID != uid) { RemovePin(_primaryID); _records.Remove(_primaryID); } _primaryID = uid; } if (zDO.GetBool("WH_IsSec", false)) { if (_secondaryID != ZDOID.None && _secondaryID != uid) { RemovePin(_secondaryID); _records.Remove(_secondaryID); } _secondaryID = uid; value.IsSecondary = true; } else if (uid == _secondaryID) { value.IsSecondary = true; } AddOrUpdatePin(value); } public void UnregisterShip(ZDOID id) { //IL_0000: 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_0019: 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_000f: 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_003d: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (id == _primaryID) { _primaryID = ZDOID.None; } if (id == _secondaryID) { _secondaryID = ZDOID.None; Logger.LogInfo((object)"Windheim: secondary destroyed — returned to storage."); } RemovePin(id); _records.Remove(id); _dirty = true; } public void SetPrimary(ShipRecord rec) { //IL_0004: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_0030: 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) if (rec == null || rec.ID == _primaryID) { return; } if (_primaryID != ZDOID.None && _records.TryGetValue(_primaryID, out var value)) { Ship ship = value.Ship; object obj; if (ship == null) { obj = null; } else { ZNetView component = ((Component)ship).GetComponent<ZNetView>(); obj = ((component != null) ? component.GetZDO() : null); } if (obj == null) { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(value.ID) : null); } ZDO val = (ZDO)obj; if (val != null) { try { val.SetOwner(ZNet.GetUID()); val.Set("WH_IsPri", false); } catch { } } } _primaryID = rec.ID; try { Ship ship2 = rec.Ship; if (ship2 != null) { ZNetView component2 = ((Component)ship2).GetComponent<ZNetView>(); if (component2 != null) { ZDO zDO = component2.GetZDO(); if (zDO != null) { zDO.Set("WH_IsPri", true); } } } } catch { } _dirty = true; AddOrUpdatePin(rec); if (_sessionLoaded) { SaveRegistry(); } Logger.LogInfo((object)("Windheim: primary → " + rec.DisplayName + " (" + rec.Type + ")")); } public void EnsureSecondaryEntry() { if (!_hasSecondary) { _hasSecondary = true; _secondaryType = "Raft"; _secondaryCustomName = "Boat"; _dirty = true; if (_sessionLoaded) { SaveRegistry(); } Logger.LogInfo((object)"Windheim: secondary entry created (stored)."); } } public void DeploySecondary(Ship ship) { //IL_0065: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ship == (Object)null || !_hasSecondary) { return; } ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO != null) { long ownerID = GetOwnerID(); zDO.Set("WH_Owner", ownerID); zDO.Set("WH_Name", "Boat"); zDO.Set("WH_IsSec", true); ZDOID uid = zDO.m_uid; ShipRecord shipRecord = new ShipRecord { ID = uid, Type = _secondaryType, CustomName = "Boat", OwnerID = ownerID, Position = ((Component)ship).transform.position, Rotation = ((Component)ship).transform.rotation, IsSecondary = true, IsLoaded = true, Ship = ship, LastUsed = DateTime.UtcNow, MapIconColor = Color.white, MapIconType = ShipPinType }; _records[uid] = shipRecord; _secondaryID = uid; _dirty = true; ClearStaleRoleFlags(isSecondary: true, uid, ownerID); AddOrUpdatePin(shipRecord); if (_sessionLoaded) { SaveRegistry(); } Logger.LogInfo((object)$"Windheim: secondary deployed ({uid})"); } } public void ReturnSecondaryToStorage() { //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_001a: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (_secondaryID == ZDOID.None) { return; } if (_records.TryGetValue(_secondaryID, out var value)) { Ship ship = value.Ship; object obj; if (ship == null) { obj = null; } else { ZNetView component = ((Component)ship).GetComponent<ZNetView>(); obj = ((component != null) ? component.GetZDO() : null); } if (obj == null) { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(value.ID) : null); } ZDO val = (ZDO)obj; if (val != null) { try { val.SetOwner(ZNet.GetUID()); val.Set("WH_IsSec", false); } catch { } } } ClearStaleRoleFlags(isSecondary: true, ZDOID.None, GetOwnerID()); RemovePin(_secondaryID); _records.Remove(_secondaryID); _secondaryID = ZDOID.None; _dirty = true; if (_sessionLoaded) { SaveRegistry(); } Logger.LogInfo((object)"Windheim: secondary returned to storage."); } internal PinData GetPinData(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _pins.TryGetValue(id, out var value); return value; } public void RestorePins() { if (_sessionLoaded && !((Object)(object)Minimap.instance == (Object)null)) { _pins.Clear(); EnsurePinsOnMap(); } } public void EnsurePinsOnMap() { //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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null) { return; } long ownerID = GetOwnerID(); int num = 0; foreach (ShipRecord value in _records.Values) { if (value.ID != ZDOID.None && value.OwnerID == ownerID) { num++; } } Logger.LogInfo((object)$"[WH Pins] EnsurePinsOnMap — ownerID={ownerID} totalRecords={_records.Count} owned={num}"); foreach (ShipRecord value2 in _records.Values) { if (value2.ID != ZDOID.None && value2.OwnerID == ownerID) { AddOrUpdatePin(value2); } } } public ShipRecord GetRecord(ZDOID id) { //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_0015: Unknown result type (might be due to invalid IL or missing references) if (id == ZDOID.None) { return null; } _records.TryGetValue(id, out var value); return value; } public ShipRecord GetOwnedRecord(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!_records.TryGetValue(id, out var value)) { return null; } if (value.OwnerID != GetOwnerID()) { return null; } return value; } public bool IsSecondaryShip(ZDOID id) { //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_000d: 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) if (id != ZDOID.None) { return id == _secondaryID; } return false; } public List<ShipRecord> GetOwnedByLocalPlayer() { long ownerID = GetOwnerID(); List<ShipRecord> list = new List<ShipRecord>(); foreach (ShipRecord value in _records.Values) { if (value.OwnerID == ownerID) { list.Add(value); } } return list; } public void TouchLastUsed(ShipRecord rec) { //IL_0004: 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) if (rec == null || rec.ID == ZDOID.None) { return; } rec.LastUsed = DateTime.UtcNow; _dirty = true; try { Ship ship = rec.Ship; if (ship == null) { return; } ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if (component != null) { ZDO zDO = component.GetZDO(); if (zDO != null) { zDO.Set("WH_LastUsed", rec.LastUsed.Ticks); } } } catch { } } public void ScanLoaded() { ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Ship component = ((Component)array[i]).GetComponent<Ship>(); if ((Object)(object)component != (Object)null) { RegisterShip(component); } } } public void MarkDirty() { _dirty = true; } public void OnPlayerSpawned() { Logger.LogInfo((object)$"[WH Timing] OnPlayerSpawned — sessionLoaded={_sessionLoaded} time={Time.time:F1}"); _pendingSpawn = true; if (_sessionLoaded) { EnsureSecondaryEntry(); } } private void SaveRegistry() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0015: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) try { long ownerID = GetOwnerID(); ZPackage val = new ZPackage(); val.Write(5); val.Write(_primaryID); val.Write(_secondaryID); val.Write(_hasSecondary); val.Write(_secondaryType ?? "Raft"); val.Write(_secondaryCustomName ?? "Boat"); int num = 0; foreach (ShipRecord value in _records.Values) { if (value.OwnerID == ownerID) { num++; } } val.Write(num); foreach (ShipRecord value2 in _records.Values) { if (value2.OwnerID == ownerID) { val.Write(value2.ID); val.Write(value2.Type ?? ""); val.Write(value2.CustomName ?? ""); val.Write(value2.Position); val.Write(value2.LastUsed.Ticks); val.Write(value2.IsSecondary); } } string text = SavePath(); Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } long? num2 = obj; long valueOrDefault = num2.GetValueOrDefault(); long worldUID = GetWorldUID(); Logger.LogInfo((object)($"[WH Save] CharUID={valueOrDefault} WorldUID={worldUID}\n" + " Path=" + text + "\n" + $" Primary={_primaryID} Secondary={_secondaryID} HasSec={_hasSecondary} Count={num}")); string @base = val.GetBase64(); Directory.CreateDirectory(Path.GetDirectoryName(text)); File.WriteAllText(text, @base); Logger.LogInfo((object)$"[WH Save] done — exists={File.Exists(text)} bytes={new FileInfo(text).Length}"); } catch (Exception ex) { Logger.LogWarning((object)("Windheim: ship save error: " + ex.Message)); } } private void LoadRegistry() { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) string text = SavePath(); Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } long? num = obj; long valueOrDefault = num.GetValueOrDefault(); long worldUID = GetWorldUID(); bool flag = File.Exists(text); Logger.LogInfo((object)($"[WH Load] CharUID={valueOrDefault} WorldUID={worldUID}\n" + " Path=" + text + "\n" + $" Exists={flag} Size={(flag ? new FileInfo(text).Length : 0)}B")); if (!flag) { TryMigrateV1(); return; } try { string text2 = File.ReadAllText(text).Trim(); if (string.IsNullOrEmpty(text2)) { return; } ZPackage val = new ZPackage(text2); int num2 = val.ReadInt(); if (num2 < 2) { Logger.LogWarning((object)"Windheim: ship save too old."); return; } _primaryID = val.ReadZDOID(); _secondaryID = val.ReadZDOID(); if (num2 >= 4) { _hasSecondary = val.ReadBool(); _secondaryType = val.ReadString(); val.ReadString(); _secondaryCustomName = "Boat"; if (num2 == 4) { val.ReadInt(); val.ReadInt(); val.ReadInt(); val.ReadInt(); } } else { _hasSecondary = _secondaryID != ZDOID.None; _secondaryType = "Raft"; } int num3 = val.ReadInt(); long ownerID = GetOwnerID(); for (int i = 0; i < num3; i++) { ZDOID val2 = val.ReadZDOID(); string type = val.ReadString(); string text3 = val.ReadString(); Vector3 position = val.ReadVector3(); long num4 = val.ReadLong(); bool flag2 = val.ReadBool(); if (num2 < 5) { val.ReadInt(); val.ReadInt(); val.ReadInt(); if (num2 >= 3) { val.ReadInt(); } } if (_records.TryGetValue(val2, out var value)) { value.OwnerID = ownerID; value.IsSecondary = flag2; value.MapIconType = ShipPinType; AddOrUpdatePin(value); continue; } _records[val2] = new ShipRecord { ID = val2, Type = type, CustomName = (flag2 ? "Boat" : text3), OwnerID = ownerID, Position = position, Rotation = Quaternion.identity, LastUsed = ((num4 > 0) ? new DateTime(num4, DateTimeKind.Utc) : DateTime.UtcNow), IsSecondary = flag2, MapIconColor = Color.white, MapIconType = ShipPinType }; AddOrUpdatePin(_records[val2]); } Logger.LogInfo((object)($"Windheim: loaded {num3} ship(s). " + $"P={_primaryID} S={_secondaryID} hasSecondary={_hasSecondary}")); } catch (Exception ex) { Logger.LogWarning((object)("Windheim: ship load error: " + ex.Message)); } } private void TryMigrateV1() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) ZNet instance = ZNet.instance; string text = ((instance != null) ? instance.GetWorldName() : null) ?? "world"; Game instance2 = Game.instance; object obj; if (instance2 == null) { obj = null; } else { PlayerProfile playerProfile = instance2.GetPlayerProfile(); obj = ((playerProfile != null) ? playerProfile.GetName() : null); } if (obj == null) { Player localPlayer = Player.m_localPlayer; obj = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "player"; } string text2 = (string)obj; string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)WindheimPlugin.Instance).Config.ConfigFilePath), "windheim_ships_" + text2 + "_" + text + ".dat"); if (!File.Exists(path)) { return; } try { string text3 = File.ReadAllText(path).Trim(); if (!string.IsNullOrEmpty(text3)) { ZPackage val = new ZPackage(text3); int num = val.ReadInt(); long ownerID = GetOwnerID(); for (int i = 0; i < num; i++) { ZDOID val2 = val.ReadZDOID(); string type = val.ReadString(); string text4 = val.ReadString(); Vector3 position = val.ReadVector3(); long num2 = val.ReadLong(); bool isSecondary = text4 == "Boat"; _records[val2] = new ShipRecord { ID = val2, Type = type, CustomName = text4, OwnerID = ownerID, Position = position, IsSecondary = isSecondary, MapIconColor = Color.white, MapIconType = ShipPinType, LastUsed = ((num2 > 0) ? new DateTime(num2, DateTimeKind.Utc) : DateTime.UtcNow) }; AddOrUpdatePin(_records[val2]); } _dirty = true; Logger.LogInfo((object)$"Windheim: migrated {num} ship(s) from v1."); } } catch (Exception ex) { Logger.LogWarning((object)("Windheim: v1 migration error: " + ex.Message)); } } private string SavePath() { string? directoryName = Path.GetDirectoryName(((BaseUnityPlugin)WindheimPlugin.Instance).Config.ConfigFilePath); Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } long? num = obj; long valueOrDefault = num.GetValueOrDefault(); return Path.Combine(directoryName, string.Format(arg1: GetWorldUID(), format: "windheim_ships_v3_{0}_{1}.dat", arg0: valueOrDefault)); } private static long GetWorldUID() { if ((Object)(object)ZNet.instance == (Object)null) { return 0L; } try { MethodInfo method = typeof(ZNet).GetMethod("GetWorldUID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { return (long)method.Invoke(ZNet.instance, null); } } catch { } try { object obj2 = typeof(ZNet).GetField("m_world", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(ZNet.instance); if (obj2 == null) { return 0L; } FieldInfo field = obj2.GetType().GetField("m_uid", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (field != null) ? ((long)field.GetValue(obj2)) : 0; } catch { return 0L; } } private void ResetSession() { //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_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) _sessionLoaded = false; _miniPinsEnsured = false; _dirty = false; _pendingSpawn = false; _hasSecondary = false; _secondaryType = "Raft"; _secondaryCustomName = "Boat"; _primaryID = ZDOID.None; _secondaryID = ZDOID.None; _records.Clear(); ClearAllPins(); _diagTriggerTimer = 0f; _diagScanCountdown = -1f; _diagScanDone = false; } private void DiagnosticWorldScan() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) long myUID = GetMyUID(); Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } long? num = obj; long valueOrDefault = num.GetValueOrDefault(); long worldUID = GetWorldUID(); Ship[] array = Object.FindObjectsByType<Ship>((FindObjectsSortMode)0); Logger.LogInfo((object)($"[WH WorldScan] myUID={myUID} profileID={valueOrDefault} worldUID={worldUID}\n" + $" Ships in scene={array.Length} registry records={_records.Count}\n" + $" primary={_primaryID} secondary={_secondaryID} hasSecondary={_hasSecondary}")); int num2 = 0; Ship[] array2 = array; foreach (Ship val in array2) { num2++; ZNetView component = ((Component)val).GetComponent<ZNetView>(); ZDO obj2 = ((component != null) ? component.GetZDO() : null); ZDOID val2 = obj2?.m_uid ?? ZDOID.None; int hash = ((obj2 != null) ? obj2.GetPrefab() : 0); long num3 = ((obj2 != null) ? obj2.GetLong("WH_Owner", 0L) : 0); bool flag = _records.ContainsKey(val2); bool flag2 = flag && _records[val2].OwnerID == myUID; Logger.LogInfo((object)($"[WH WorldScan] #{num2}: {TypeName(hash)} zdoid={val2}\n" + $" pos={((Component)val).transform.position:F0} nvValid={component != null && component.IsValid()}\n" + $" zdoOwner={num3} inRegistry={flag} ownedByMe={flag2}")); } foreach (KeyValuePair<ZDOID, ShipRecord> record in _records) { ShipRecord value = record.Value; Logger.LogInfo((object)($"[WH WorldScan] reg: {value.Type} zdoid={record.Key} owner={value.OwnerID} " + string.Format("isLoaded={0} isSec={1} ship={2}", value.IsLoaded, value.IsSecondary, ((Object)(object)value.Ship != (Object)null) ? "ref" : "null"))); } } internal void ClearStaleRoleFlags(bool isSecondary, ZDOID keepID, long ownerID) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null) { return; } string text = (isSecondary ? "WH_IsSec" : "WH_IsPri"); string[] obj = new string[4] { "Raft", "Karve", "VikingShip", "Drakkar" }; List<ZDO> list = new List<ZDO>(); string[] array = obj; foreach (string text2 in array) { list.Clear(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(text2, list, ref num)) { } foreach (ZDO item in list) { if (!(item.m_uid == keepID) && item.GetLong("WH_Owner", 0L) == ownerID && item.GetBool(text, false)) { item.SetOwner(ZNet.GetUID()); item.Set(text, false); Logger.LogInfo((object)$"[WH Cleanup] Cleared stale {text} on zdoid={item.m_uid}"); } } } } private void AddOrUpdatePin(ShipRecord rec) { //IL_000e: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null || rec.ID == ZDOID.None) { object arg = rec?.ID; object arg2 = (Object)(object)Minimap.instance != (Object)null; ZDOID? val = rec?.ID; ZDOID none = ZDOID.None; Logger.LogInfo((object)$"[WH Pin] SKIP {arg} — minimap={arg2} validID={!val.HasValue || val.GetValueOrDefault() != none}"); return; } Color white = Color.white; string text = ((rec.ID == _primaryID) ? "Flagship" : (rec.IsSecondary ? "Boat" : rec.DisplayName)); rec.MapIconColor = white; rec.MapIconType = ShipPinType; if (_pins.TryGetValue(rec.ID, out var value)) { if (value.m_type != rec.MapIconType) { RemovePin(rec.ID); AddOrUpdatePin(rec); return; } value.m_pos = rec.Position; value.m_name = text; TryApplyPinColor(value, white); Logger.LogInfo((object)$"[WH Pin] UPDATE '{text}' zdoid={rec.ID} pos={rec.Position:F0}"); return; } try { value = Minimap.instance.AddPin(rec.Position, rec.MapIconType, text, false, false, 0L, default(PlatformUserID)); _pins[rec.ID] = value; TryApplyPinColor(value, white); Logger.LogInfo((object)$"[WH Pin] ADD '{text}' zdoid={rec.ID} pos={rec.Position:F0}"); } catch (Exception ex) { Logger.LogWarning((object)("Windheim: pin error: " + ex.Message)); } } private static void TryApplyPinColor(PinData pin, Color color) { //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_0048: Unknown result type (might be due to invalid IL or missing references) if (color == Color.white || (Object)(object)pin?.m_uiElement == (Object)null) { return; } try { Image val = ((Component)pin.m_uiElement).GetComponent<Image>() ?? ((Component)pin.m_uiElement).GetComponentInChildren<Image>(); if ((Object)(object)val != (Object)null) { ((Graphic)val).color = color; } } catch { } } private void RemovePin(ZDOID id) { //IL_0006: 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) if (!_pins.TryGetValue(id, out var value)) { return; } try { Minimap instance = Minimap.instance; if (instance != null) { instance.RemovePin(value); } } catch { } _pins.Remove(id); } private void ClearAllPins() { foreach (PinData value in _pins.Values) { try { Minimap instance = Minimap.instance; if (instance != null) { instance.RemovePin(value); } } catch { } } _pins.Clear(); } private void PruneGone() { foreach (ShipRecord value in _records.Values) { if (value.IsLoaded && (Object)(object)value.Ship == (Object)null) { value.IsLoaded = false; } } } private void UpdateLoadedPositions() { //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_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) //IL_005b: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) long ownerID = GetOwnerID(); bool flag = false; foreach (ShipRecord value in _records.Values) { if (!value.IsLoaded || (Object)(object)value.Ship == (Object)null) { continue; } Vector3 position = ((Component)value.Ship).transform.position; if (!(position == value.Position)) { value.Position = position; value.Rotation = ((Component)value.Ship).transform.rotation; flag = true; if (value.OwnerID == ownerID) { AddOrUpdatePin(value); } } } if (flag) { _dirty = true; } } public static int GetTypeHash(string type) { return type switch { "Raft" => HashRaft, "Karve" => HashKarve, "Longship" => HashVikingShip, "Drakkar" => HashDrakkar, _ => 0, }; } internal static string TypeToPrefabName(string type) { object obj; if (!(type == "Longship")) { obj = type; if (obj == null) { return "Raft"; } } else { obj = "VikingShip"; } return (string)obj; } public void UpdateShipZDOID(ShipRecord record, ZDOID newID) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) //IL_0040: 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_002c: 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_005a: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) ZDOID iD = record.ID; if (!(iD == newID)) { if (_records.ContainsKey(iD)) { RemovePin(iD); _records.Remove(iD); } record.ID = newID; _records[newID] = record; if (record.IsSecondary) { _secondaryID = newID; } else if (iD == _primaryID) { _primaryID = newID; } _dirty = true; AddOrUpdatePin(record); } } private static int ShipRank(int hash) { if (hash == HashRaft) { return 0; } if (hash == HashKarve) { return 1; } if (hash == HashVikingShip) { return 2; } if (hash == HashDrakkar) { return 3; } return -1; } private static string TypeName(int hash) { if (hash == HashRaft) { return "Raft"; } if (hash == HashKarve) { return "Karve"; } if (hash == HashVikingShip) { return "Longship"; } if (hash == HashDrakkar) { return "Drakkar"; } return "Ship"; } internal static long GetMyUID() { try { return ZNet.GetUID(); } catch { return 0L; } } internal static long GetOwnerID() { Game instance = Game.instance; long? obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null)); } return obj ?? GetMyUID(); } private static int StableHash(string s) { int num = 5381; int num2 = num; for (int i = 0; i < s.Length && s[i] != 0; i += 2) { num = ((num << 5) + num) ^ s[i]; if (i + 1 < s.Length && s[i + 1] != 0) { num2 = ((num2 << 5) + num2) ^ s[i + 1]; } } return num + num2 * 1566083941; } } public static class WaterScanner { public struct ScanResult { public bool Found; public Vector3 Position; public Quaternion Rotation; public float Score; } private static readonly int ObstacleMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "piece", "character", "vehicle" }); public static ScanResult FindSummonPosition(Vector3 playerPos, Vector3 playerFwd, float minRadius, float maxRadius, float minDepth, Ship excludeShip = null) { //IL_0014: 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_0026: 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_002d: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) float water = WaterLevel(); ScanResult result = default(ScanResult); float num = -1f; foreach (Vector3 item in GenerateCandidates(playerPos, playerFwd, minRadius, maxRadius)) { float num2 = WaterDepthAt(item, water); if (!(num2 < minDepth) && IsOpen(item, water, minDepth) && !HasObstacle(item, excludeShip)) { float num3 = Score(item, playerPos, playerFwd, maxRadius, num2); if (num3 > num) { num = num3; result = new ScanResult { Found = true, Position = item, Rotation = RotationAwayFrom(item, playerPos), Score = num3 }; } } } return result; } private static IEnumerable<Vector3> GenerateCandidates(Vector3 origin, Vector3 fwd, float minR, float maxR) { //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) float water = WaterLevel(); float step = (maxR - minR) / 4f; for (int ring = 0; ring < 5; ring++) { float r = minR + step * (float)ring; for (int a = -5; a <= 5; a++) { Vector3 val = Quaternion.AngleAxis((float)a * 15f, Vector3.up) * fwd; Vector3 val2 = origin + val * r; val2.y = water; yield return val2; } } for (int ring = 0; ring < 24; ring++) { Vector3 val3 = Quaternion.AngleAxis((float)ring * 15f, Vector3.up) * fwd; Vector3 val4 = origin + val3 * maxR; val4.y = water; yield return val4; } } private static float WaterDepthAt(Vector3 pos, float water) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float num = TerrainHeightAt(pos); return water - num; } private static bool IsOpen(Vector3 center, float water, float minDepth) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) /