Please disclose if your mod was created primarily 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 Ship Stats v1.0.6
ShipStats.dll
Decompiled 5 months agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ShipStats")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("ShipStats")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.6")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 ShipStats { [HarmonyPatch(typeof(Hud), "Awake")] internal static class HudAwakePatch { public static GameObject Go; public static GameObject Go2; public static TextMeshProUGUI contentText; public static TextMeshProUGUI contentText2; private static void Postfix(Hud __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Hud.Awake Postfix started"); Go = new GameObject("AzuShipStatsPlayerControlled"); Go.transform.SetParent(Utils.FindChild(__instance.m_shipHudRoot.transform, "Controls", (IterativeSearchType)0), false); Go2 = Object.Instantiate<GameObject>(Go, Hud.instance.m_rootObject.transform, false); ((Object)Go2).name = "AzuShipStatsPlayerOnBoard"; AddTheComponents(Go); AddTheComponents(Go2); ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("UI elements created and components added"); } public static void AddTheComponents(GameObject gameObject) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0121: 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_018a: Unknown result type (might be due to invalid IL or missing references) ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Adding components to " + ((Object)gameObject).name); RectTransform obj = gameObject.AddComponent<RectTransform>(); ((Graphic)gameObject.AddComponent<Image>()).color = ShipStatsPlugin.PanelColor.Value; VerticalLayoutGroup val = gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val).padding = new RectOffset(5, 5, 5, 5); ContentSizeFitter obj2 = gameObject.AddComponent<ContentSizeFitter>(); obj2.horizontalFit = (FitMode)2; obj2.verticalFit = (FitMode)2; GameObject val2 = new GameObject(((Object)gameObject).name + "Content"); val2.transform.SetParent(((Component)val).transform); if (((Object)gameObject).name.EndsWith("PlayerControlled", StringComparison.Ordinal)) { contentText = val2.AddComponent<TextMeshProUGUI>(); ((Graphic)contentText).color = ShipStatsPlugin.TextColor.Value; ((TMP_Text)contentText).font = MessageHud.instance.m_messageCenterText.font; ((TMP_Text)contentText).overflowMode = (TextOverflowModes)0; ((TMP_Text)contentText).fontSize = ShipStatsPlugin.FontSize.Value; ((Behaviour)contentText).enabled = true; ((TMP_Text)contentText).alignment = (TextAlignmentOptions)514; } else { contentText2 = val2.AddComponent<TextMeshProUGUI>(); ((Graphic)contentText2).color = ShipStatsPlugin.TextColor.Value; ((TMP_Text)contentText2).font = MessageHud.instance.m_messageCenterText.font; ((TMP_Text)contentText2).overflowMode = (TextOverflowModes)0; ((TMP_Text)contentText2).fontSize = ShipStatsPlugin.FontSize.Value; ((Behaviour)contentText2).enabled = true; ((TMP_Text)contentText2).alignment = (TextAlignmentOptions)514; } gameObject.AddComponent<UIUpdater>(); obj.anchoredPosition = ShipStatsPlugin.AnchoredPosition.Value; gameObject.SetActive(false); ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Components added to " + ((Object)gameObject).name); } } [HarmonyPatch(typeof(Ship), "OnTriggerEnter")] internal static class ShipOnTriggerEnterPatch { private static void Postfix(Ship __instance, Collider collider) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Ship.OnTriggerEnter started"); Player component = ((Component)collider).GetComponent<Player>(); if (!Object.op_Implicit((Object)(object)component)) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("No player component found"); return; } if (!((Object)(object)component == (Object)(object)Player.m_localPlayer)) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Player is not local player"); return; } HudAwakePatch.Go.SetActive(true); ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("AzuShipStatsPlayerControlled UI set active"); } } [HarmonyPatch(typeof(Ship))] internal static class ShipOnTriggerExitDestroyedPatch { [HarmonyPostfix] [HarmonyPatch("OnTriggerExit")] private static void Postfix1(Ship __instance, Collider collider) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Ship.OnTriggerExit started"); Player component = ((Component)collider).GetComponent<Player>(); if (!Object.op_Implicit((Object)(object)component)) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("No player component found"); return; } if (!((Object)(object)component == (Object)(object)Player.m_localPlayer)) { ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("Player is not local player"); return; } HudAwakePatch.Go.SetActive(false); HudAwakePatch.Go2.SetActive(false); ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("UI elements set inactive"); } [HarmonyPostfix] [HarmonyPatch("OnDestroyed")] private static void Postfix2() { HudAwakePatch.Go.SetActive(false); HudAwakePatch.Go2.SetActive(false); ShipStatsPlugin.ShipStatsLogger.LogDebugIfBuildDebug("UI elements set inactive on ship destruction"); } } public class UIUpdater : MonoBehaviour { internal Vector3 size; internal Vector2 offset; internal Transform rectransform; private const float knotsMultiplier = 1.94384f; private const float mphMultiplier = 2.237f; private const float kmhMultiplier = 3.6f; private void Start() { rectransform = (Transform)(object)((Component)this).GetComponent<RectTransform>(); } private void Update() { //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_016a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { ((TMP_Text)HudAwakePatch.contentText).text = ""; ((TMP_Text)HudAwakePatch.contentText2).text = ""; return; } Ship val = (((Object)(object)Player.m_localPlayer.GetControlledShip() != (Object)null) ? Player.m_localPlayer.GetControlledShip() : (((Object)(object)((Character)Player.m_localPlayer).GetStandingOnShip() != (Object)null) ? ((Character)Player.m_localPlayer).GetStandingOnShip() : null)); if ((Object)(object)val == (Object)null) { ((TMP_Text)HudAwakePatch.contentText).text = ""; ((TMP_Text)HudAwakePatch.contentText2).text = ""; return; } float num = EnvMan.instance.GetWindIntensity() * 1.94384f * 10f; float num2 = Mathf.Abs(val.GetSpeed()); float num3 = Mathf.Abs(num2 * 2.237f); float num4 = Mathf.Abs(num2 * 3.6f); float num5 = Mathf.Abs(num2 * 1.94384f); float num6 = 0f; float num7 = 0f; WearNTear val2 = default(WearNTear); ((Component)val).TryGetComponent<WearNTear>(ref val2); if (Object.op_Implicit((Object)(object)val2) && val.m_nview.IsValid() && !((double)val.m_nview.GetZDO().GetFloat("health", val2.m_health) <= 0.0)) { num7 = val2.m_health; num6 = val.m_nview.GetZDO().GetFloat("health", val2.m_health); } Vector3 windDir = EnvMan.instance.GetWindDir(); float num8 = Mathf.Atan2(windDir.x, windDir.z) * 57.29578f + 180f; string text = (((double)num8 >= 337.5 || (double)num8 < 22.5) ? "N" : (((double)num8 < 67.5) ? "NE" : (((double)num8 < 112.5) ? "E" : (((double)num8 < 157.5) ? "SE" : (((double)num8 < 202.5) ? "S" : (((double)num8 < 247.5) ? "SW" : ((!((double)num8 < 292.5)) ? "NW" : "W"))))))); Inventory val3 = ((Component)val).GetComponentInChildren<Container>()?.m_inventory; string text2; try { text2 = string.Format(ShipStatsPlugin.TextFormat.Value, num5, num3, num4, num, num8, text, (val3 == null) ? "" : $"Ship Inventory: {val3?.m_inventory.Count}/{val3?.m_width * val3?.m_height} ({((val3 != null) ? new float?(val3.SlotsUsedPercentage()) : null):0.#}%)", (num6 > 0f) ? $"Ship Health: {num6:0}/{num7:0}" : ""); } catch { text2 = "Error in Text Format"; } ((TMP_Text)HudAwakePatch.contentText).text = text2; ((TMP_Text)HudAwakePatch.contentText2).text = text2; Camera mainCamera = Utils.GetMainCamera(); if (!((Object)(object)mainCamera == (Object)null)) { HudAwakePatch.Go2.transform.position = mainCamera.WorldToScreenPoint(val.m_controlGuiPos.position); } } } [BepInPlugin("Azumatt.ShipStats", "ShipStats", "1.0.6")] public class ShipStatsPlugin : BaseUnityPlugin { private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; } internal const string ModName = "ShipStats"; internal const string ModVersion = "1.0.6"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.ShipStats"; private static string ConfigFileName = "Azumatt.ShipStats.cfg"; private static string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("Azumatt.ShipStats"); public static readonly ManualLogSource ShipStatsLogger; public static ConfigEntry<int> FontSize; public static ConfigEntry<Color> TextColor; public static ConfigEntry<string> TextFormat; public static ConfigEntry<Vector2> AnchoredPosition; public static ConfigEntry<Color> PanelColor; public void Awake() { //IL_003b: 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_00b6: Unknown result type (might be due to invalid IL or missing references) FontSize = config("1 - Text", "Stats Font Size", 15, "Font Size of the stats text. Default is 15."); TextColor = config<Color>("1 - Text", "Stats Text Color", new Color(1f, 1f, 1f, 1f), "Color of the stats text. Default is white."); TextFormat = TextEntryConfig("1 - Text", "Stats Text Format", "Ship Speed:\n\t{0:0.#} knots\n\t{1:0.#} mph\n\t{2:0.#} km/h\nWind Speed: {3:0.#} knots\nWind Direction: {4:0.#}° {5}\n{6}\n{7}", "{0} is ship speed in knots\n{1} is ship speed in mph\n{2} is ship speed in km/h\n{3} is wind speed in knots\n{4} is wind direction in degrees\n{5} is wind direction in cardinal directions\n{6} is ship inventory count and percent\n{7} is the ship health"); AnchoredPosition = config<Vector2>("2 - UI", "Stats Anchored Position", new Vector2(200f, -27f), "Anchored position of the stats text. Please note that this is relative to the rudder icon. Default is 200,-27."); PanelColor = config<Color>("2 - UI", "UI Background Color", new Color(0f, 0f, 0f, 0.5f), "Color of panel background. Default is black with half transparency."); FontSize.SettingChanged += delegate { UIElementChanged(); }; TextColor.SettingChanged += delegate { UIElementChanged(); }; AnchoredPosition.SettingChanged += delegate { UIElementChanged(); }; PanelColor.SettingChanged += delegate { UIElementChanged(); }; Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); } private void UIElementChanged() { //IL_002c: 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_0088: 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) if ((Object)(object)HudAwakePatch.contentText != (Object)null) { ((TMP_Text)HudAwakePatch.contentText).fontSize = FontSize.Value; ((Graphic)HudAwakePatch.contentText).color = TextColor.Value; } if ((Object)(object)HudAwakePatch.contentText2 != (Object)null) { ((TMP_Text)HudAwakePatch.contentText2).fontSize = FontSize.Value; ((Graphic)HudAwakePatch.contentText2).color = TextColor.Value; } if (Object.op_Implicit((Object)(object)HudAwakePatch.Go)) { ((Graphic)HudAwakePatch.Go.GetComponent<Image>()).color = PanelColor.Value; HudAwakePatch.Go.GetComponent<RectTransform>().anchoredPosition = AnchoredPosition.Value; } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { ShipStatsLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { ShipStatsLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); ShipStatsLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description) { return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); } private ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } private ConfigEntry<T> TextEntryConfig<T>(string group, string name, T value, string desc) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { CustomDrawer = TextAreaDrawer }; return config(group, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); } internal static void TextAreaDrawer(ConfigEntryBase entry) { GUILayout.ExpandHeight(true); GUILayout.ExpandWidth(true); entry.BoxedValue = GUILayout.TextArea((string)entry.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true) }); } static ShipStatsPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; ShipStatsLogger = Logger.CreateLogSource("ShipStats"); FontSize = null; TextColor = null; TextFormat = null; AnchoredPosition = null; PanelColor = null; } } public static class LoggerExtentions { public static void LogDebugIfBuildDebug(this ManualLogSource logger, string message) { } public static void LogWarningIfBuildDebug(this ManualLogSource logger, string message) { } public static void LogErrorIfBuildDebug(this ManualLogSource logger, string message) { } } }