using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LethalDebt.NetcodePatcher; using LethalDebt.Patches; using Microsoft.CodeAnalysis; using MoreShipUpgrades.API; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalDebt")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+eea6e6fa970cba31d8e1e3ac48598f64b6be1381")] [assembly: AssemblyProduct("LethalDebt")] [assembly: AssemblyTitle("LethalDebt")] [assembly: AssemblyVersion("1.0.0.0")] [module: NetcodePatchedAssembly] 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; } } } namespace LethalDebt { internal class LGUHandler { [MethodImpl(MethodImplOptions.NoInlining)] public static void AllowOverspending() { UpgradeApi.TurnOnOverspending(); } [MethodImpl(MethodImplOptions.NoInlining)] public static void DisallowOverspending() { UpgradeApi.TurnOffOverspending(); } } internal class NetworkHelper : NetworkBehaviour { public static NetworkHelper Instance; private void Start() { Instance = this; } [ClientRpc] public void EnableClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2401801619u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2401801619u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; Plugin.mls.LogDebug((object)"The host has Lethal Debt!"); Plugin.Instance.enabled = true; if (Chainloader.PluginInfos.ContainsKey("com.malco.lethalcompany.moreshipupgrades")) { LGUHandler.AllowOverspending(); } } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(2401801619u, new RpcReceiveHandler(__rpc_handler_2401801619), "EnableClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_2401801619(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((NetworkHelper)(object)target).EnableClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "NetworkHelper"; } } [BepInPlugin("JS03.LethalDebt", "Lethal Debt", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private const string modGUID = "JS03.LethalDebt"; private const string modName = "Lethal Debt"; private const string modVersion = "1.1.0"; private readonly Harmony harmony = new Harmony("JS03.LethalDebt"); public static Plugin Instance; internal static ManualLogSource mls; public bool enabled; public int deadline; public const int DEBT_LIMIT = -2147483647; public ConfigEntry debtColor; public ConfigEntry debtMultiplier; public ConfigEntry quotaDeadline; public ConfigEntry applyDeathPenaltyDebt; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } mls = Logger.CreateLogSource("JS03.LethalDebt"); mls.LogInfo((object)"Lethal Debt is awake"); enabled = true; if (Chainloader.PluginInfos.ContainsKey("com.malco.lethalcompany.moreshipupgrades")) { LGUHandler.AllowOverspending(); } Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { if (type.Name == "LGUPatches") { continue; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } GenerateConfig(); ApplyPatches(); } private void ApplyPatches() { harmony.PatchAll(typeof(TerminalPatches)); harmony.PatchAll(typeof(StartOfRoundPatches)); harmony.PatchAll(typeof(TimeOfDayPatches)); harmony.PatchAll(typeof(HUDManagerPatches)); harmony.PatchAll(typeof(GameNetworkManagerPatches)); mls.LogInfo((object)"Patches applied!"); } private void GenerateConfig() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown debtColor = ((BaseUnityPlugin)this).Config.Bind("Customization", "Debt Color", "#ff0000", "Changes the color of the displayed credits in the terminal when they're in the negatives.\nMake sure you separate the different values with a comma and a blank space."); debtColor.SettingChanged += delegate { Utils.SetCreditsColorToDebt(); }; debtMultiplier = ((BaseUnityPlugin)this).Config.Bind("Customization", "Debt multiplier", 1f, new ConfigDescription("How much money do you want to owe the Company?", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 4f), Array.Empty())); quotaDeadline = ((BaseUnityPlugin)this).Config.Bind("Customization", "Quota deadline", 1, new ConfigDescription("By which quota do you have to pay off your debt?", (AcceptableValueBase)(object)new AcceptableValueRange(1, 3), Array.Empty())); applyDeathPenaltyDebt = ((BaseUnityPlugin)this).Config.Bind("Customization", "Death penalty counts towards debt", true, "Can the amount subtracted by the death penalty make you go into debt?"); } } internal class Utils { internal class CoroutineManagerBehaviour : MonoBehaviour { } private static MonoBehaviour _corroutineInstance; private static MonoBehaviour CorroutineInstance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_corroutineInstance == (Object)null) { _corroutineInstance = (MonoBehaviour)(object)new GameObject("CoroutineManager").AddComponent(); } return _corroutineInstance; } } public static void SetCreditsColorToDebt() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (TerminalPatches.terminal.groupCredits < 0) { Color color = default(Color); ColorUtility.TryParseHtmlString(Plugin.Instance.debtColor.Value, ref color); ((Graphic)TerminalPatches.terminal.topRightText).color = color; } } public static Coroutine StartCoroutine(IEnumerator routine) { return CorroutineInstance.StartCoroutine(routine); } } } namespace LethalDebt.Patches { internal class GameNetworkManagerPatches { [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void StartPatch(GameNetworkManager __instance) { ((Component)__instance).gameObject.AddComponent(); ((Component)__instance).gameObject.AddComponent(); Plugin.mls.LogDebug((object)"Network Helper has been added"); } [HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")] [HarmonyPostfix] private static void SaveDeadline(GameNetworkManager __instance) { ES3.Save("LethalDebt_Deadline", Plugin.Instance.deadline, __instance.currentSaveFileName); } [HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")] [HarmonyPostfix] private static void ResetDeadline(GameNetworkManager __instance) { ES3.Save("LethalDebt_Deadline", Plugin.Instance.quotaDeadline.Value, __instance.currentSaveFileName); } } [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerPatches { [HarmonyPatch("ApplyPenalty")] [HarmonyPrefix] private static bool CalculatePenaltyWithDebt(HUDManager __instance, int playersDead, int bodiesInsured) { if (Plugin.Instance.applyDeathPenaltyDebt.Value) { float num = 0.2f; int groupCredits = TerminalPatches.terminal.groupCredits; bodiesInsured = Mathf.Max(bodiesInsured, 0); for (int i = 0; i < playersDead - bodiesInsured; i++) { Terminal terminal = TerminalPatches.terminal; terminal.groupCredits += (int)((float)groupCredits * num); } for (int j = 0; j < bodiesInsured; j++) { Terminal terminal2 = TerminalPatches.terminal; terminal2.groupCredits += (int)((float)groupCredits * (num / 2.5f)); } ((TMP_Text)__instance.statsUIElements.penaltyAddition).text = $"{playersDead} casualties: -{500f * (float)(playersDead - bodiesInsured)}%\n({bodiesInsured} bodies recovered)"; ((TMP_Text)__instance.statsUIElements.penaltyTotal).text = $"DUE: ${groupCredits - TerminalPatches.terminal.groupCredits}"; Plugin.mls.LogDebug((object)$"New group credits after penalty: {TerminalPatches.terminal.groupCredits}"); return false; } return true; } } internal class StartOfRoundPatches { [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] [HarmonyPrefix] private static void DisableClient(StartOfRound __instance) { if (!((NetworkBehaviour)__instance).IsHost) { Plugin.Instance.enabled = false; if (Chainloader.PluginInfos.ContainsKey("com.malco.lethalcompany.moreshipupgrades")) { LGUHandler.DisallowOverspending(); } } } [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] [HarmonyPostfix] private static void EnableClientDebt(StartOfRound __instance) { NetworkHelper.Instance.EnableClientRpc(); } [HarmonyPatch(typeof(StartOfRound), "SetTimeAndPlanetToSavedSettings")] [HarmonyPostfix] private static void LoadDeadline() { Plugin.Instance.deadline = ES3.Load("LethalDebt_Deadline", GameNetworkManager.Instance.currentSaveFileName, Plugin.Instance.quotaDeadline.Value); } } [HarmonyPatch(typeof(Terminal))] internal class TerminalPatches { public static Terminal terminal; private static Color terminalCreditsColor; [HarmonyPatch("Start")] [HarmonyPostfix] private static void GetTerminal(Terminal __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) terminal = __instance; terminalCreditsColor = ((Graphic)terminal.topRightText).color; Utils.SetCreditsColorToDebt(); } [HarmonyPatch("LoadNewNodeIfAffordable")] [HarmonyPostfix] private static void ShowDebtWithMultiplier(Terminal __instance) { __instance.groupCredits = (int)((__instance.groupCredits < 0) ? ((float)__instance.groupCredits * Plugin.Instance.debtMultiplier.Value) : ((float)__instance.groupCredits)); } [HarmonyPatch("LoadNewNodeIfAffordable")] [HarmonyTranspiler] private static IEnumerable Transpiler(IEnumerable instructions) { List list = new List(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldarg_0 && list[i + 1].opcode == OpCodes.Ldfld && list[i + 1].operand.ToString().Contains("groupCredits")) { for (int j = 0; j < 20; j++) { list[i + j].opcode = OpCodes.Nop; } Plugin.mls.LogDebug((object)"Purchasing restrictions removed"); break; } } for (int k = 0; k < list.Count; k++) { if (list[k].opcode == OpCodes.Ldc_I4_0 && list[k + 1].opcode == OpCodes.Ldc_I4 && Convert.ToInt64(list[k + 1].operand) == 10000000) { list[k].opcode = OpCodes.Ldc_I4; list[k].operand = -2147483647; Plugin.mls.LogDebug((object)"New min credit limit set"); } } return list.AsEnumerable(); } [HarmonyPatch("LoadNewNodeIfAffordable")] [HarmonyPrefix] private static bool PreventGriefing(TerminalNode node, Terminal __instance, ref int ___totalCostOfItems) { if (!Plugin.Instance.enabled && __instance.groupCredits < ___totalCostOfItems && (node.buyVehicleIndex == -1 || !__instance.hasWarrantyTicket)) { __instance.LoadNewNode(__instance.terminalNodes.specialNodes[2]); return false; } if (__instance.groupCredits - ___totalCostOfItems <= -2147483647) { __instance.LoadNewNode(__instance.terminalNodes.specialNodes[2]); return false; } return true; } [HarmonyPatch("LoadNewNodeIfAffordable")] [HarmonyPostfix] private static void ChangeCreditsColorAfterPurchase() { Utils.SetCreditsColorToDebt(); } [HarmonyPatch("BeginUsingTerminal")] [HarmonyPostfix] private static void ChangeCreditsColorOnTerminalOpen(Terminal __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (__instance.groupCredits >= 0) { ((Graphic)__instance.topRightText).color = terminalCreditsColor; } Utils.SetCreditsColorToDebt(); } [HarmonyPatch(typeof(DepositItemsDesk), "SellItemsClientRpc")] [HarmonyPostfix] private static void ChangeCreditsColorAfterSellingClientRpc() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (terminal.groupCredits >= 0) { Plugin.mls.LogDebug((object)"Credits color reverted to default"); ((Graphic)terminal.topRightText).color = terminalCreditsColor; } } } internal class TimeOfDayPatches { [CompilerGenerated] private sealed class d__2 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TimeOfDay Instance; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; case 1: <>1__state = -1; HUDManager.Instance.DisplayTip("REMINDER", $"You have {Plugin.Instance.quotaDeadline.Value - Instance.timesFulfilledQuota} quota(s) left to pay off your debt!\nYou currently owe ${Mathf.Abs(TerminalPatches.terminal.groupCredits)}", false, false, "LC_Tip1"); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] [HarmonyPrefix] private static bool FirePlayers(TimeOfDay __instance) { if (Plugin.Instance.enabled && TerminalPatches.terminal.groupCredits < 0 && __instance.timesFulfilledQuota == Plugin.Instance.deadline - 1) { GameNetworkManager.Instance.gameHasStarted = true; StartOfRound.Instance.firingPlayersCutsceneRunning = true; StartOfRound.Instance.FirePlayersAfterDeadlineClientRpc(new int[4] { StartOfRound.Instance.gameStats.daysSpent, StartOfRound.Instance.gameStats.scrapValueCollected, StartOfRound.Instance.gameStats.deaths, StartOfRound.Instance.gameStats.allStepsTaken }, false); return false; } if (TerminalPatches.terminal.groupCredits >= 0) { Plugin.Instance.deadline += __instance.timesFulfilledQuota; } return true; } [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] [HarmonyPostfix] private static void DisplayTip(TimeOfDay __instance) { if (__instance.timesFulfilledQuota != Plugin.Instance.deadline - 1 && TerminalPatches.terminal.groupCredits < 0) { Utils.StartCoroutine(DisplayDebtReminder(__instance)); } } [IteratorStateMachine(typeof(d__2))] private static IEnumerator DisplayDebtReminder(TimeOfDay Instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0) { Instance = Instance }; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace LethalDebt.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }