using System;
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.3")]
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.3";
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;
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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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.");
_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_01e3: Unknown result type (might be due to invalid IL or missing references)
ILCursor val = new ILCursor(il);
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;
});
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;
});
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)
{
float value = 100f * (1f - (float)Object.FindAnyObjectByType<Terminal>().groupCredits / (float)groupCredits);
value = Math.Clamp(value, 0f, 100f);
return float.IsNaN(value) ? 0f : value;
});
Debug.Log((object)((object)il).ToString());
}
}
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)
{
}
}
}