using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
[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("NoPassiveHealthDrain")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NoPassiveHealthDrain")]
[assembly: AssemblyTitle("NoPassiveHealthDrain")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace NoPassiveHealthDrain
{
[BepInPlugin("IngoH.HardTime.NoPassiveHealthDrain", "NoPassiveHealthDrain", "1.0.0")]
[HarmonyPatch]
public class Plugin : BaseUnityPlugin
{
internal interface CIPattern
{
bool IsMatch(CodeInstruction instruction);
}
internal class CIOpCodePattern : CIPattern
{
private readonly OpCode opCode;
public CIOpCodePattern(OpCode opCode)
{
this.opCode = opCode;
}
public bool IsMatch(CodeInstruction instruction)
{
return instruction.opcode == opCode;
}
}
internal class CIOperandPattern : CIPattern
{
private readonly object operand;
public CIOperandPattern(object operand)
{
this.operand = operand;
}
public bool IsMatch(CodeInstruction instruction)
{
return instruction.operand == operand;
}
}
internal class CIOpCodeOperandPattern : CIPattern
{
private readonly OpCode opCode;
private readonly object operand;
public CIOpCodeOperandPattern(OpCode opCode, object operand)
{
this.opCode = opCode;
this.operand = operand;
}
public bool IsMatch(CodeInstruction instruction)
{
return instruction.opcode == opCode && instruction.operand == operand;
}
}
public const string PluginGuid = "IngoH.HardTime.NoPassiveHealthDrain";
public const string PluginName = "NoPassiveHealthDrain";
public const string PluginVer = "1.0.0";
internal static ManualLogSource Log;
internal static readonly Harmony Harmony = new Harmony("IngoH.HardTime.NoPassiveHealthDrain");
internal static string PluginPath;
internal static ConfigEntry<float> HealthDrainRate;
internal static ConfigEntry<bool> StaminaAffectsDrain;
internal static ConfigEntry<float> NPCDrainRate;
private void Awake()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
HealthDrainRate = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HealthDrainRate", 0f, new ConfigDescription("The rate at which health drains passively. (Relative to the original rate, fractional) Set to negative to increase health passively.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
StaminaAffectsDrain = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "StaminaAffectsDrain", true, "Whether or not stamina affects the passive health drain/recovery rate. (Stamina decreases health drain rate if drain is positive, increases health recovery rate if drain is negative)");
NPCDrainRate = ((BaseUnityPlugin)this).Config.Bind<float>("General", "NPCDrainMultiplier", 0.1f, new ConfigDescription("The multiplier for NPC health drain. (Relative to the original rate, fractional) Set to negative to increase health passively.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
}
private void OnEnable()
{
Harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded NoPassiveHealthDrain!");
}
private void OnDisable()
{
Harmony.UnpatchSelf();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Unloaded NoPassiveHealthDrain!");
}
[HarmonyPatch(typeof(DFOGOCNBECG), "DNOMKDPFLGA")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> DFOGOCNBECG_DNOMKDPFLGA(IEnumerable<CodeInstruction> instructions)
{
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Expected O, but got Unknown
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Expected O, but got Unknown
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
List<CIPattern> list2 = new List<CIPattern>();
list2.Add(new CIOpCodePattern(OpCodes.Ldarg_0));
list2.Add(new CIOpCodePattern(OpCodes.Ldarg_0));
list2.Add(new CIOpCodeOperandPattern(OpCodes.Ldfld, typeof(DFOGOCNBECG).GetField("HLGALFAGDGC")));
list2.Add(new CIOpCodePattern(OpCodes.Ldloc_3));
list2.Add(new CIOpCodePattern(OpCodes.Sub));
list2.Add(new CIOpCodeOperandPattern(OpCodes.Stfld, typeof(DFOGOCNBECG).GetField("HLGALFAGDGC")));
List<CIPattern> list3 = list2;
int num = FindInstructions(list, 0, list3);
if (num != -1)
{
List<Label> list4 = CollectLabels(list, num, list3.Count);
list.RemoveRange(num, list3.Count);
list.InsertRange(num, new List<CodeInstruction>
{
CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Ldarg_0, (object)null), (IEnumerable<Label>)list4),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldfld, (object)typeof(DFOGOCNBECG).GetField("HLGALFAGDGC")),
new CodeInstruction(OpCodes.Call, (object)typeof(Plugin).GetMethod("AdjustHealth")),
new CodeInstruction(OpCodes.Stfld, (object)typeof(DFOGOCNBECG).GetField("HLGALFAGDGC"))
});
}
return list;
}
private static int FindInstructions(List<CodeInstruction> instructions, int startIndex, List<CIPattern> patterns)
{
for (int i = startIndex; i < instructions.Count - patterns.Count; i++)
{
bool flag = true;
for (int j = 0; j < patterns.Count; j++)
{
if (!patterns[j].IsMatch(instructions[i + j]))
{
flag = false;
break;
}
}
if (flag)
{
return i;
}
}
return -1;
}
private static List<Label> CollectLabels(List<CodeInstruction> instructions, int startIndex, int count)
{
List<Label> list = new List<Label>();
for (int i = startIndex; i < startIndex + count; i++)
{
if (instructions[i].labels != null)
{
list.AddRange(instructions[i].labels);
}
}
return list;
}
public static float AdjustHealth(DFOGOCNBECG player, float health)
{
float num = (StaminaAffectsDrain.Value ? player.HNFHLLJOFKI[5] : 99f);
float value = HealthDrainRate.Value;
if (value == 0f)
{
return health;
}
float num2 = ((!(value > 0f)) ? ((150f - (249f - num) / 2f) / 500f * MBLIOKEDHHB.MCJHGEHEPMD) : ((150f - (num + 100f) / 2f) / 500f * MBLIOKEDHHB.MCJHGEHEPMD));
if (Progress.clockSpeed > 30f)
{
num2 /= Progress.clockSpeed / 30f;
}
if (player.OJAJENJLBMF < 0)
{
num2 *= NPCDrainRate.Value;
}
return health - num2 * value;
}
}
}