Decompiled source of CreditLossOnDeathConfigurator v1.0.5

CreditLossOnDeathConfigurator.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using UnityEngine;

[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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("CreditLossOnDeathConfigurator")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.5.1.0")]
[assembly: AssemblyInformationalVersion("1.5.1")]
[assembly: AssemblyProduct("CreditLossOnDeathConfigurator")]
[assembly: AssemblyTitle("CreditLossOnDeathConfigurator")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.1.0")]
[module: UnverifiableCode]
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 CreditLossOnDeathConfigurator
{
	[BepInPlugin("GiGaGon.CreditLossOnDeathConfigurator", "CreditLossOnDeathConfigurator", "1.0.4")]
	public class CreditLossOnDeathConfigurator : BaseUnityPlugin
	{
		public const string PluginGUID = "GiGaGon.CreditLossOnDeathConfigurator";

		public const string PluginAuthor = "GiGaGon";

		public const string PluginName = "CreditLossOnDeathConfigurator";

		public const string PluginVersion = "1.0.4";

		private static ILHook _hook;

		public static ConfigFile configFile;

		public static ConfigEntry<float> creditPercentageLostPerUnrecoveredBody;

		public static ConfigEntry<float> creditPercentageLostPerRecoveredBody;

		public static ConfigEntry<bool> disableCreditLossAtCompany;

		public static ConfigEntry<bool> scaleCreditLossByLobbySize;

		public static ConfigEntry<bool> roundCreditLossPercentage;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "CreditLossOnDeathConfigurator.cfg"), true);
			creditPercentageLostPerUnrecoveredBody = configFile.Bind<float>("General", "Credit Percentage Lost Per Unrecovered Body", 0.2f, "");
			creditPercentageLostPerRecoveredBody = configFile.Bind<float>("General", "Credit Percentage Lost Per Recovered Body", 0.08f, "By default 8% is lost on recovered bodies, though in vanilla it is not stated nor displayed on the end card.");
			disableCreditLossAtCompany = configFile.Bind<bool>("General", "Disable Credit Loss At Company", false, "Stops all credit loss from recovered/unrecovered bodies while at the company.");
			scaleCreditLossByLobbySize = configFile.Bind<bool>("General", "Scale Credit Loss By Lobby Size", false, "Scales based on a 4 player lobby to make it so that if all players die, the credit loss is the same accross all sizes.\nExample: 4 player lobby with 20% unrecovered, max is 20% * 4 = 80%. \nA five player lobby would be 20% * 4 (base max) / 5 (max unrecoverable) = 16% per body, since 16% * 5 = 80%. \nA 3 player lobby would be 20% * 4 / 3 = 26% per.\nThe same math applies to the recovered body percentage.");
			roundCreditLossPercentage = configFile.Bind<bool>("General", "Round Credit Loss Percentage", true, "If enabled, will round the displayed Credit Loss percent up to the nearest whole number to prevent confusion. Disable if you liked the old fully accurate display.");
			_hook = new ILHook((MethodBase)typeof(HUDManager).GetMethod("ApplyPenalty", BindingFlags.Instance | BindingFlags.Public), new Manipulator(SetBodyCreditReductionMultipliers));
		}

		private static void Unhook()
		{
			ILHook hook = _hook;
			if (hook != null)
			{
				hook.Dispose();
			}
		}

		public void SetBodyCreditReductionMultipliers(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			try
			{
				val.GotoNext(new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.2f),
					(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 0)
				});
				val.Remove();
				val.EmitDelegate<Func<float>>((Func<float>)delegate
				{
					configFile.Reload();
					if (disableCreditLossAtCompany.Value && StartOfRound.Instance.currentLevel.sceneName == "CompanyBuilding")
					{
						return 0f;
					}
					return scaleCreditLossByLobbySize.Value ? (creditPercentageLostPerUnrecoveredBody.Value * (4f / ((float)StartOfRound.Instance.connectedPlayersAmount + 1f))) : creditPercentageLostPerUnrecoveredBody.Value;
				});
			}
			catch (KeyNotFoundException)
			{
				Debug.LogError((object)"CreditLossOnDeathConfigurator - A different mod already patched unrecovered body percentage, config will not apply");
			}
			try
			{
				val.GotoNext(new Func<Instruction, bool>[4]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 2),
					(Instruction x) => ILPatternMatchingExt.MatchConvR4(x),
					(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 2.5f)
				});
				val.Index += 2;
				val.RemoveRange(3);
				val.EmitDelegate<Func<float>>((Func<float>)delegate
				{
					if (disableCreditLossAtCompany.Value && StartOfRound.Instance.currentLevel.sceneName == "CompanyBuilding")
					{
						return 0f;
					}
					return scaleCreditLossByLobbySize.Value ? (creditPercentageLostPerRecoveredBody.Value * (4f / ((float)StartOfRound.Instance.connectedPlayersAmount + 1f))) : creditPercentageLostPerRecoveredBody.Value;
				});
			}
			catch (KeyNotFoundException)
			{
				Debug.LogError((object)"CreditLossOnDeathConfigurator - A different mod already patched recovered body percentage, config will not apply");
			}
			try
			{
				val.GotoNext(new Func<Instruction, bool>[3]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
					(Instruction x) => ILPatternMatchingExt.MatchBox<int>(x),
					(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0)
				});
				val.Index += 2;
				val.RemoveRange(8);
				val.Emit(OpCodes.Ldloc_2);
				val.EmitDelegate<Func<int, float>>((Func<int, float>)delegate(int groupCredits)
				{
					configFile.Reload();
					float value = 100f * (1f - (float)Object.FindAnyObjectByType<Terminal>().groupCredits / (float)groupCredits);
					value = Math.Clamp(value, 0f, 100f);
					value = (float.IsNaN(value) ? 0f : value);
					if (roundCreditLossPercentage.Value)
					{
						value = (float)Math.Ceiling(value);
					}
					return value;
				});
			}
			catch (KeyNotFoundException)
			{
				Debug.LogError((object)"CreditLossOnDeathConfigurator - A different mod already patched credit penalty percentage text");
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CreditLossOnDeathConfigurator";

		public const string PLUGIN_NAME = "CreditLossOnDeathConfigurator";

		public const string PLUGIN_VERSION = "1.5.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}