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 BoneEngine v1.0.2
BoneEngine.dll
Decompiled 17 hours agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [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("BoneEngine")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2+3b3d77b03712271c1770b598c924c40243616104")] [assembly: AssemblyProduct("BoneEngine")] [assembly: AssemblyTitle("BoneEngine")] [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 BoneEngine { [HarmonyPatch] internal static class EnginePatches { private static readonly Failsafe s_failsafe = new Failsafe(); public static bool Off => s_failsafe.Off; [HarmonyPatch(typeof(Ship), "CustomFixedUpdate")] [HarmonyPostfix] private static void CustomFixedUpdate(Ship __instance, float fixedDeltaTime, ZNetView ___m_nview, Rigidbody ___m_body) { if (s_failsafe.Off) { return; } try { if (!((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && !((Object)(object)___m_body == (Object)null)) { EngineState engineState = ShipEngine.State(__instance); ShipEngine.MaybeClaim(__instance, ___m_nview, engineState, fixedDeltaTime); if (!___m_nview.IsOwner()) { engineState.Pushing = false; engineState.Remaining = 0f; engineState.OwnedSeconds = 0f; } else { engineState.OwnedSeconds += fixedDeltaTime; ShipEngine.Tick(__instance, ___m_body, engineState, fixedDeltaTime); } } } catch (Exception arg) { if (s_failsafe.Trip()) { Plugin.Log.LogError((object)$"The engine failed and is off for this session (boats are vanilla): {arg}"); } } } } internal static class EngineRules { public const string FuelItem = "$item_bonefragments"; public const float EnginePower = 1.2f; public const float BurnSeconds = 15f; public const float ReferenceSailFactor = 0.05f; public const float OwnerStableSeconds = 2f; public const float HoldClosedBeforeClaimSeconds = 2f; public const float OwnedBeforeLoadSeconds = 1.5f; public const float ClaimInterval = 1f; public static float GearFraction(Speed gear) { //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_0018: Expected I4, but got Unknown switch (gear - 1) { case 0: case 1: return 1f / 3f; case 2: return 2f / 3f; case 3: return 1f; default: return 0f; } } public static int Direction(Speed gear) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)gear == 1) { return -1; } return ((int)gear > 0) ? 1 : 0; } public static float Impulse(float sailForceFactor, float fraction, float mass) { return 1.2f * sailForceFactor * fraction * mass; } public static bool RunsHere(bool localSteering, bool anyoneSteering) { if (!localSteering) { return !anyoneSteering; } return true; } public static float BoneSeconds(float sailForceFactor) { if (sailForceFactor <= 0f) { return 15f; } return 0.75f / sailForceFactor; } public static bool NeedsBone(float remaining) { return remaining <= 0f; } public static bool HasEngine(float sailForceFactor) { return sailForceFactor > 0f; } public static bool CanLoad(bool holdOpen, int bones, float ownedSeconds) { if (!holdOpen && bones > 0) { return ownedSeconds >= 1.5f; } return false; } public static float Drain(float remaining, float dt, float fraction) { if (fraction <= 0f || dt <= 0f) { return remaining; } float num = remaining - dt * fraction; if (!(num > 0f)) { return 0f; } return num; } public static bool ShouldClaim(bool steering, bool owner, float holdClosedSeconds, float ownerStableSeconds) { if (steering && !owner && holdClosedSeconds >= 2f) { return ownerStableSeconds >= 2f; } return false; } public static string CountLine(string itemName, int count) { return itemName + ": " + count; } public static string PanelLine(string itemName, int count, bool running, string goldHex) { string text = (running ? ("<color=" + goldHex + ">active</color>") : "idle"); return CountLine(itemName, count) + "\nEngine status: " + text; } } internal sealed class Failsafe { public bool Off { get; private set; } public bool Trip() { if (Off) { return false; } Off = true; return true; } } [HarmonyPatch] internal static class HoverPatches { private static readonly Failsafe s_failsafe = new Failsafe(); [HarmonyPatch(typeof(ShipControlls), "GetHoverText")] [HarmonyPostfix] private static void GetHoverText(ShipControlls __instance, ref string __result) { //IL_004d: 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) if (s_failsafe.Off || EnginePatches.Off) { return; } try { Ship ship = __instance.m_ship; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)ship == (Object)null) && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)__instance.m_attachPoint == (Object)null) && !(Vector3.Distance(((Component)localPlayer).transform.position, __instance.m_attachPoint.position) >= __instance.m_maxUseRange) && ShipEngine.HoldInventory(ship) != null && EngineRules.HasEngine(ship.m_sailForceFactor)) { __result = __result + "\n" + EngineRules.CountLine(Localization.instance.Localize("$item_bonefragments"), ShipEngine.Bones(ship)); } } catch (Exception arg) { if (s_failsafe.Trip()) { Plugin.Log.LogWarning((object)$"The rudder's bone count failed and is off for this session (the rudder text is vanilla): {arg}"); } } } } [HarmonyPatch] internal static class HudPatches { private const float LineGap = 34f; private const float LineFontSize = 20f; private static Hud s_hud; private static TMP_Text s_text; private static int s_lastCount = -1; private static bool s_lastRunning; private static bool s_off; private static string s_goldHex; private const string FallbackGoldHex = "#FFD23C"; [HarmonyPatch(typeof(Hud), "UpdateShipHud")] [HarmonyPostfix] private static void UpdateShipHud(Hud __instance, Player player) { if (s_off) { return; } try { Ship val = (((Object)(object)player != (Object)null) ? player.GetControlledShip() : null); GameObject shipHudRoot = __instance.m_shipHudRoot; if (EnginePatches.Off || !((Object)(object)val != (Object)null) || !((Object)(object)shipHudRoot != (Object)null) || !shipHudRoot.activeSelf || ShipEngine.HoldInventory(val) == null || !EngineRules.HasEngine(val.m_sailForceFactor)) { if ((Object)(object)s_text != (Object)null && ((Component)s_text).gameObject.activeSelf) { ((Component)s_text).gameObject.SetActive(false); } return; } if ((Object)(object)s_text == (Object)null || (Object)(object)s_hud != (Object)(object)__instance) { s_hud = __instance; s_text = MakeLine(__instance); s_lastCount = -1; if ((Object)(object)s_text == (Object)null) { TurnOff("The steering panel has no text to copy (a game update?): no bone count on the panel"); return; } } int num = ShipEngine.Bones(val); bool pushing = ShipEngine.State(val).Pushing; if (num != s_lastCount || pushing != s_lastRunning) { s_lastCount = num; s_lastRunning = pushing; s_text.text = EngineRules.PanelLine(Localization.instance.Localize("$item_bonefragments"), num, pushing, GoldHex()); FitToText(s_text); } if (!((Component)s_text).gameObject.activeSelf) { ((Component)s_text).gameObject.SetActive(true); } } catch (Exception arg) { TurnOff($"The steering panel's bone count failed; the panel is vanilla from here: {arg}"); } } private static string GoldHex() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (s_goldHex != null) { return s_goldHex; } InventoryGui instance = InventoryGui.instance; TMP_Text val = (((Object)(object)instance != (Object)null) ? instance.m_weight : null); s_goldHex = (((Object)(object)val != (Object)null) ? ("#" + ColorUtility.ToHtmlStringRGB(((Graphic)val).color)) : "#FFD23C"); return s_goldHex; } private static TMP_Text MakeLine(Hud hud) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) TMP_Text healthText = hud.m_healthText; RectTransform shipWindIndicatorRoot = hud.m_shipWindIndicatorRoot; RectTransform val = (RectTransform)(((Object)(object)shipWindIndicatorRoot != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)healthText == (Object)null || (Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(((Component)healthText).gameObject, (Transform)(object)val); ((Object)val2).name = "BoneEngineCount"; TMP_Text component = val2.GetComponent<TMP_Text>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return null; } RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = shipWindIndicatorRoot.anchorMin; val3.anchorMax = shipWindIndicatorRoot.anchorMax; val3.pivot = new Vector2(1f, 1f); float y = shipWindIndicatorRoot.anchoredPosition.y; Rect rect = shipWindIndicatorRoot.rect; float num = y - ((Rect)(ref rect)).height * (1f - shipWindIndicatorRoot.pivot.y); float x = shipWindIndicatorRoot.anchoredPosition.x; rect = shipWindIndicatorRoot.rect; float num2 = x + ((Rect)(ref rect)).width * (1f - shipWindIndicatorRoot.pivot.x); val3.anchoredPosition = new Vector2(num2, num - 34f); val3.sizeDelta = new Vector2(420f, 60f); ((Transform)val3).localScale = Vector3.one; ((Transform)val3).localRotation = Quaternion.identity; component.alignment = (TextAlignmentOptions)257; component.textWrappingMode = (TextWrappingModes)0; component.overflowMode = (TextOverflowModes)0; component.enableAutoSizing = false; component.fontSize = 20f; ((Graphic)component).color = Color.white; component.text = ""; return component; } private static void FitToText(TMP_Text text) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) Vector2 preferredValues = text.GetPreferredValues(); ((RectTransform)text.transform).sizeDelta = new Vector2(preferredValues.x + 2f, preferredValues.y + 2f); } private static void TurnOff(string message) { s_off = true; Plugin.Log.LogWarning((object)message); try { if ((Object)(object)s_text != (Object)null) { Object.Destroy((Object)(object)((Component)s_text).gameObject); } } catch (Exception) { } s_text = null; } } [BepInPlugin("algo7.boneengine", "BoneEngine", "1.0.2")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "algo7.boneengine"; public const string Name = "BoneEngine"; public const string PluginVersion = "1.0.2"; internal static ManualLogSource Log; private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; if (Application.isBatchMode) { Log.LogInfo((object)"BoneEngine loaded (v1.0.2): dedicated server, nothing to do"); return; } Harmony harmony = new Harmony("algo7.boneengine"); if (!TryPatch(harmony, typeof(EnginePatches), "engine hook")) { Log.LogError((object)"The engine is off: boats are vanilla"); return; } if (!TryPatch(harmony, typeof(HoverPatches), "rudder text hook")) { Log.LogWarning((object)"No bone count on the rudder (the engine still works)"); } if (!TryPatch(harmony, typeof(HudPatches), "steering panel hook")) { Log.LogWarning((object)"No bone count on the steering panel (the engine still works)"); } Log.LogInfo((object)"BoneEngine loaded (v1.0.2)"); } private static bool TryPatch(Harmony harmony, Type patches, string what) { try { harmony.PatchAll(patches); return true; } catch (Exception arg) { Log.LogError((object)$"Could not install the {what}: {arg}"); return false; } } } internal sealed class EngineState { public float Remaining; public bool Pushing; public WaterVolume Water; public Container Hold; public bool HoldLooked; public float ClaimTimer; public long LastOwner; public float OwnerStable; public float OwnedSeconds; public float HoldClosedSeconds; } internal static class ShipEngine { private static readonly ConditionalWeakTable<Ship, EngineState> s_states = new ConditionalWeakTable<Ship, EngineState>(); public static EngineState State(Ship ship) { return s_states.GetValue(ship, (Ship _) => new EngineState()); } public static Container Hold(Ship ship) { EngineState engineState = State(ship); if (!engineState.HoldLooked) { engineState.HoldLooked = true; ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { Container[] componentsInChildren = ((Component)ship).GetComponentsInChildren<Container>(true); foreach (Container val in componentsInChildren) { if (!((Object)(object)val.m_rootObjectOverride != (Object)(object)component)) { engineState.Hold = val; break; } } } } return engineState.Hold; } public static Inventory HoldInventory(Ship ship) { Container val = Hold(ship); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetInventory(); } public static int Bones(Ship ship) { Inventory val = HoldInventory(ship); if (val == null) { return 0; } return val.CountItems("$item_bonefragments", -1, false); } public static bool HoldOpen(ZNetView nview) { return nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1; } private static bool InWater(Ship ship, Rigidbody body, EngineState state) { //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) Vector3 worldCenterOfMass = body.worldCenterOfMass; float waterLevel = Floating.GetWaterLevel(worldCenterOfMass, ref state.Water); return worldCenterOfMass.y - waterLevel - ship.m_waterLevelOffset <= ship.m_disableLevel; } public static void MaybeClaim(Ship ship, ZNetView nview, EngineState state, float dt) { long owner = nview.GetZDO().GetOwner(); if (owner != state.LastOwner) { state.LastOwner = owner; state.OwnerStable = 0f; } else { state.OwnerStable += dt; } if (HoldOpen(nview)) { state.HoldClosedSeconds = 0f; } else { state.HoldClosedSeconds += dt; } state.ClaimTimer += dt; if (!(state.ClaimTimer < 1f)) { state.ClaimTimer = 0f; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)ship.m_shipControlls == (Object)null) && EngineRules.ShouldClaim(ship.m_shipControlls.GetUser() == localPlayer.GetPlayerID(), nview.IsOwner(), state.HoldClosedSeconds, state.OwnerStable)) { nview.ClaimOwnership(); state.OwnerStable = 0f; Plugin.Log.LogDebug((object)$"Took over {((Object)ship).name} for the engine (previous owner {owner})"); } } } public static void Tick(Ship ship, Rigidbody body, EngineState state, float dt) { //IL_0016: 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_001c: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_012e: 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) state.Pushing = false; if (!EngineRules.HasEngine(ship.m_sailForceFactor)) { return; } Speed speedSetting = ship.GetSpeedSetting(); float num = EngineRules.GearFraction(speedSetting); if (num <= 0f) { return; } ShipControlls shipControlls = ship.m_shipControlls; Player localPlayer = Player.m_localPlayer; bool localSteering = (Object)(object)shipControlls != (Object)null && (Object)(object)localPlayer != (Object)null && shipControlls.GetUser() == localPlayer.GetPlayerID(); bool anyoneSteering = (Object)(object)shipControlls != (Object)null && shipControlls.HaveValidUser(); if (!EngineRules.RunsHere(localSteering, anyoneSteering)) { return; } Container val = Hold(ship); Inventory val2 = (((Object)(object)val != (Object)null) ? val.GetInventory() : null); if (val2 == null || !InWater(ship, body, state)) { return; } if (EngineRules.NeedsBone(state.Remaining)) { int bones = val2.CountItems("$item_bonefragments", -1, false); if (!EngineRules.CanLoad(val.IsInUse(), bones, state.OwnedSeconds)) { return; } state.Remaining = EngineRules.BoneSeconds(ship.m_sailForceFactor); val2.RemoveItem("$item_bonefragments", 1, -1, false); } Vector3 val3 = ((Component)ship).transform.forward * (float)EngineRules.Direction(speedSetting); float num2 = EngineRules.Impulse(ship.m_sailForceFactor, num, body.mass); body.AddForceAtPosition(val3 * num2, body.worldCenterOfMass, (ForceMode)1); state.Remaining = EngineRules.Drain(state.Remaining, dt, num); state.Pushing = true; } } internal static class PluginInfo { public const string Version = "1.0.2"; } }