Decompiled source of LaRavenia v0.3.0

BepInEx/patchers/MidgardSpeedItUpPicard.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Preloader;
using HarmonyLib;
using HarmonyLib.Public.Patching;
using Microsoft.CodeAnalysis;
using MidgardAntiCheat;
using Mono.Cecil;
using Mono.Cecil.Cil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MidgardSpeedItUpPicard")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MidgardSpeedItUpPicard")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("970A588D-9A2E-4CCF-B66B-397AEAD75715")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.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;
		}
	}
	[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 MidgardSpeedItUpPicard
{
	public static class MidgardSpeedItUpPicard
	{
		private enum Toggle
		{
			On,
			Off
		}

		[HarmonyPatch]
		private static class Patch_Preloader_PatchEntrypoint
		{
			private static readonly MethodInfo ChainloaderFinishedCallInstructionAdder = AccessTools.DeclaredMethod(typeof(Patch_Preloader_PatchEntrypoint), "AddChainloaderFinishedCall", (Type[])null, (Type[])null);

			private static readonly MethodInfo ChainloaderStart = AccessTools.DeclaredMethod(typeof(Patch_Preloader_PatchEntrypoint), "PreChainloader", (Type[])null, (Type[])null);

			private static readonly MethodInfo ILInstructionInserter = AccessTools.DeclaredMethod(typeof(ILProcessor), "InsertBefore", (Type[])null, (Type[])null);

			private static bool patched = false;

			private static IEnumerable<MethodInfo> TargetMethods()
			{
				return new MethodInfo[1] { AccessTools.DeclaredMethod(typeof(EnvVars).Assembly.GetType("BepInEx.Preloader.Preloader"), "PatchEntrypoint", (Type[])null, (Type[])null) };
			}

			private static void AddChainloaderFinishedCall(ILProcessor ilProcessor, Instruction instruction, AssemblyDefinition assembly)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				ilProcessor.InsertBefore(instruction, ilProcessor.Create(OpCodes.Call, assembly.MainModule.ImportReference((MethodBase)ChainloaderStart)));
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				bool foundInitMethod = false;
				foreach (CodeInstruction instruction in instructions)
				{
					yield return instruction;
					if (instruction.opcode == OpCodes.Ldloc_S && instruction.operand is LocalBuilder localBuilder && localBuilder.LocalIndex == 6)
					{
						foundInitMethod = true;
					}
					else if (foundInitMethod && CodeInstructionExtensions.Calls(instruction, ILInstructionInserter))
					{
						yield return new CodeInstruction(OpCodes.Ldloc_S, (object)11);
						yield return new CodeInstruction(OpCodes.Ldloc_S, (object)12);
						yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
						yield return new CodeInstruction(OpCodes.Ldind_Ref, (object)null);
						yield return new CodeInstruction(OpCodes.Call, (object)ChainloaderFinishedCallInstructionAdder);
					}
				}
			}

			private static void PreChainloader()
			{
				if (!patched)
				{
					patched = true;
					if (delayedPatcher == Toggle.On)
					{
						delayedPatcherHarmony.PatchAll(typeof(InterceptChainloader));
					}
					if (unifiedLocalization == Toggle.On)
					{
						harmony.PatchAll(typeof(InterceptLocalization));
						harmony.PatchAll(typeof(InterceptLanguageLoad));
					}
					if (optimizeConfigSave == Toggle.On)
					{
						harmony.PatchAll(typeof(DelayConfigSave));
						harmony.PatchAll(typeof(ChangeConfigSaveBack));
						harmony.PatchAll(typeof(SkipManuallyChangedSaveOnConfigSet));
					}
				}
			}
		}

		[HarmonyPatch]
		private static class InterceptLocalization
		{
			private static readonly Dictionary<string, Dictionary<string, string>> localizationCache = new Dictionary<string, Dictionary<string, string>>();

			private static readonly HashSet<MethodBase> alreadyAppliedEnglishLoadCSV = new HashSet<MethodBase>();

			private static MethodInfo TargetMethod()
			{
				return AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "SetupLanguage", (Type[])null, (Type[])null);
			}

			[HarmonyPriority(0)]
			private static bool Prefix(object __instance, string language, ref Dictionary<string, string> ___m_translations, ref bool __result)
			{
				if (localizationCache.TryGetValue(language, out Dictionary<string, string> value))
				{
					___m_translations = value;
					if (language == "English" && (string)AccessTools.DeclaredMethod(Type.GetType("UnityEngine.PlayerPrefs, UnityEngine.CoreModule"), "GetString", new Type[2]
					{
						typeof(string),
						typeof(string)
					}, (Type[])null).Invoke(null, new object[2] { "language", "English" }) != "English")
					{
						Patch[] postfixes = PatchManager.ToPatchInfo((MethodBase)AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "LoadCSV", (Type[])null, (Type[])null)).postfixes;
						foreach (Patch val in postfixes)
						{
							if (alreadyAppliedEnglishLoadCSV.Contains(val.PatchMethod))
							{
								continue;
							}
							ParameterInfo[] parameters = val.PatchMethod.GetParameters();
							object[] array = new object[parameters.Length];
							int num = 0;
							ParameterInfo[] array2 = parameters;
							foreach (ParameterInfo parameterInfo in array2)
							{
								if (parameterInfo.Name == "__instance")
								{
									array[num] = __instance;
								}
								else if (parameterInfo.Name == "language")
								{
									array[num] = language;
								}
								else if (parameterInfo.Name == "__result")
								{
									array[num] = true;
								}
								else if (parameterInfo.Name.StartsWith("___"))
								{
									array[num] = AccessTools.Field(__instance.GetType(), parameterInfo.Name.Substring(3)).GetValue(__instance);
								}
								num++;
							}
							val.PatchMethod.Invoke(null, array);
							alreadyAppliedEnglishLoadCSV.Add(val.PatchMethod);
						}
					}
					__result = true;
					return false;
				}
				if (language != "English")
				{
					___m_translations = new Dictionary<string, string>(___m_translations);
				}
				return true;
			}

			[HarmonyPriority(0)]
			private static void Postfix(string language, Dictionary<string, string> ___m_translations, bool __result)
			{
				if (__result)
				{
					localizationCache[language] = ___m_translations;
				}
			}
		}

		[HarmonyPatch]
		private static class InterceptLanguageLoad
		{
			private static MethodInfo TargetMethod()
			{
				return AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "LoadLanguages", (Type[])null, (Type[])null);
			}

			[HarmonyPriority(0)]
			private static bool Prefix(ref List<string> __result)
			{
				Type type = Type.GetType("Localization, assembly_guiutils");
				object value = AccessTools.DeclaredField(type, "m_instance").GetValue(null);
				if (value != null)
				{
					__result = (List<string>)AccessTools.DeclaredMethod(type, "GetLanguages", (Type[])null, (Type[])null).Invoke(value, Array.Empty<object>());
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class InterceptChainloader
		{
			private static bool postChainloader = false;

			private static bool doNotSkipUpdate = false;

			private static readonly HashSet<MethodBase> methods = new HashSet<MethodBase>();

			private static readonly MethodInfo patchSkip = AccessTools.DeclaredMethod(typeof(InterceptChainloader), "SkipUpdates", (Type[])null, (Type[])null);

			private static readonly MethodInfo addReplacementOriginal = AccessTools.DeclaredMethod(typeof(PatchManager), "AddReplacementOriginal", (Type[])null, (Type[])null);

			private static MethodInfo TargetMethod()
			{
				return postChainloader ? AccessTools.DeclaredMethod(Type.GetType("FejdStartup, assembly_valheim"), "Awake", (Type[])null, (Type[])null) : AccessTools.DeclaredMethod(typeof(Chainloader), "Start", (Type[])null, (Type[])null);
			}

			private static bool SkipUpdates(MethodBase original, ref MethodInfo? __result)
			{
				if (!doNotSkipUpdate)
				{
					Type declaringType = original.DeclaringType;
					if ((object)declaringType == null || !passthroughClasses.Contains(declaringType.FullName))
					{
						methods.Add(original);
						__result = null;
						return false;
					}
				}
				return true;
			}

			[HarmonyPriority(800)]
			public static void Prefix()
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				doNotSkipUpdate = false;
				delayedPatcherHarmony.Patch((MethodBase)harmonyPatcher, new HarmonyMethod(patchSkip), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}

			[HarmonyPriority(0)]
			public static void Postfix()
			{
				if (MidgardAntiCheatPlugin.speeditup)
				{
					doNotSkipUpdate = true;
					if (postChainloader)
					{
						delayedPatcherHarmony.UnpatchSelf();
						string text = "after FejdStartup.Awake";
					}
					else
					{
						delayedPatcherHarmony.Unpatch((MethodBase)TargetMethod(), (HarmonyPatchType)0, delayedPatcherHarmony.Id);
						postChainloader = true;
						delayedPatcherHarmony.PatchAll(typeof(InterceptChainloader));
						string text = "after Chainloader end";
					}
					Stopwatch stopwatch = new Stopwatch();
					stopwatch.Start();
					lock (AccessTools.DeclaredField(typeof(PatchProcessor), "locker").GetValue(null))
					{
						foreach (MethodBase method in methods)
						{
							object obj = harmonyPatcher.Invoke(null, new object[2]
							{
								method,
								PatchManager.ToPatchInfo(method)
							});
							addReplacementOriginal.Invoke(null, new object[2] { method, obj });
						}
					}
					int num = (int)stopwatch.ElapsedMilliseconds;
					int num2 = num;
					logger.LogWarning((object)("Midgard Speed it up Picard version 0.2.0 Beta warped to destination in " + num2 + " seconds! Now, Tea, Earl Grey, Hot!"));
					methods.Clear();
				}
				else
				{
					logger.LogWarning((object)"Sorry, Speed it up Picard is only taking orders from Midgard server...Picard will now quit, and rage like a Klingon!");
					Environment.Exit(1);
				}
			}
		}

		[HarmonyPatch]
		private static class DelayConfigSave
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.DeclaredConstructor(typeof(ConfigFile), new Type[3]
				{
					typeof(string),
					typeof(bool),
					typeof(BepInPlugin)
				}, false);
			}

			private static void Postfix(ConfigFile __instance)
			{
				__instance.SaveOnConfigSet = false;
				changedConfigFiles.Add(__instance);
			}
		}

		[HarmonyPatch]
		private static class ChangeConfigSaveBack
		{
			private static MethodInfo TargetMethod()
			{
				return AccessTools.DeclaredMethod(Type.GetType("FejdStartup, assembly_valheim"), "Awake", (Type[])null, (Type[])null);
			}

			private static void Postfix()
			{
				List<ConfigFile> changedConfigFiles = MidgardSpeedItUpPicard.changedConfigFiles;
				MidgardSpeedItUpPicard.changedConfigFiles = new List<ConfigFile>();
				foreach (ConfigFile item in changedConfigFiles)
				{
					item.Save();
					item.SaveOnConfigSet = true;
				}
			}
		}

		[HarmonyPatch]
		private static class SkipManuallyChangedSaveOnConfigSet
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.DeclaredPropertySetter(typeof(ConfigFile), "SaveOnConfigSet");
			}

			private static void Prefix(ConfigFile __instance)
			{
				if (changedConfigFiles.Remove(__instance))
				{
					__instance.Save();
				}
			}
		}

		public const string version = "version 0.2.0 Beta";

		private const string CONFIG_FILE_NAME = "MidgardSpeedItUpPicard.cfg";

		private static readonly ConfigFile Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "MidgardSpeedItUpPicard.cfg"), true);

		private static readonly ManualLogSource logger = Logger.CreateLogSource("MidgardSpeedItUpPicard");

		private static readonly Harmony delayedPatcherHarmony = new Harmony("midgard.speedituppicard.patcher");

		private static readonly Harmony harmony = new Harmony("midgard.speedituppicard");

		private static readonly MethodInfo harmonyPatcher = AccessTools.DeclaredMethod(typeof(Harmony).Assembly.GetType("HarmonyLib.PatchFunctions"), "UpdateWrapper", (Type[])null, (Type[])null);

		private static readonly string[] hardcodedPassthrough = new string[4]
		{
			typeof(Assembly).FullName,
			"BepInEx.Preloader.RuntimeFixes.HarmonyInteropFix",
			"BepInEx.PluginInfo",
			typeof(Enum).FullName
		};

		private static HashSet<string> passthroughClasses = new HashSet<string>();

		private static readonly Toggle delayedPatcher = Toggle.Off;

		private static readonly Toggle unifiedLocalization = Toggle.On;

		private static readonly Toggle optimizeConfigSave = Toggle.On;

		private static List<ConfigFile> changedConfigFiles = new List<ConfigFile>();

		public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>();


		public static void Patch(AssemblyDefinition assembly)
		{
		}

		public static void Initialize()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			logger.LogWarning((object)"Midgard Speed it up Picard is preparing to warp!");
			ConfigEntry<string> passthrough = Config.Bind<string>("Patched", ".", "", new ConfigDescription("", (AcceptableValueBase)null, Array.Empty<object>()));
			passthrough.SettingChanged += delegate
			{
				calcPassthrough();
			};
			calcPassthrough();
			harmony.PatchAll(typeof(Patch_Preloader_PatchEntrypoint));
			void calcPassthrough()
			{
				HashSet<string> hashSet = new HashSet<string>();
				foreach (string item in hardcodedPassthrough.Concat((unifiedLocalization != 0) ? ((IEnumerable<string>)Array.Empty<string>()) : ((IEnumerable<string>)new string[1] { "Localization" })).Concat(passthrough.Value.Split(new char[1] { ',' })))
				{
					hashSet.Add(item);
				}
				passthroughClasses = hashSet;
			}
		}
	}
}

BepInEx/plugins/JustKeepMySkillsPlease.dll

Decompiled 4 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Just Keep My Skills Please")]
[assembly: AssemblyDescription("No skill loss on death + corpse run related things")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Just Keep My Skills Please")]
[assembly: AssemblyCopyright("Copyright © Ravenis 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7C60F62F-A027-415B-9BC5-829E55843008")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace JustKeepMySkillsPlease;

[BepInPlugin("ravenis.justkeepmyskillsplease", "Just Keep My Skills Please", "0.9.0")]
public class JustKeepMySkillsPlease : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Skills))]
	private static class SkillsPatches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(Skills __instance)
		{
			__instance.m_DeathLowerFactor = skillLoss * 0f;
		}
	}

	[HarmonyPatch(typeof(TombStone))]
	private static class TombStone_Patches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(TombStone __instance)
		{
			__instance.m_lootStatusEffect.m_ttl = safeRunDuration.Value;
			sTombStones.Add(__instance);
		}

		[HarmonyPatch("UpdateDespawn")]
		[HarmonyPostfix]
		private static void UpdateDespawn_Postfix(TombStone __instance)
		{
			sTombStones.Remove(__instance);
		}
	}

	public static bool modEnabled;

	public const string ModId = "ravenis.justkeepmyskillsplease";

	public static float skillLoss;

	public static ConfigEntry<float> safeRunDuration;

	private static List<TombStone> sTombStones;

	private void OnDestroy()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		Harmony val = new Harmony("ravenis.justkeepmyskillsplease");
		val.UnpatchSelf();
	}

	private void Awake()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		modEnabled = true;
		skillLoss = 0f;
		safeRunDuration = ((BaseUnityPlugin)this).Config.Bind<float>("After corpse run", "safeRunDuration", 10f, "Status effect duration in seconds, that is granted after looting a tombstone to boost regen rates and other stats. Vanilla default is 50s. This mod default is 10s");
		sTombStones = new List<TombStone>();
		Harmony val = new Harmony("ravenis.justkeepmyskillsplease");
		val.PatchAll();
	}
}

BepInEx/plugins/MidgardAntiCheat.dll

Decompiled 4 months ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using Costura;
using HarmonyLib;
using Jotunn;
using Microsoft.CodeAnalysis;
using MidgardAntiCheat;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Midgard Anti-Cheat and plugin enforcer")]
[assembly: AssemblyDescription("Anti-Cheat, plugin verify and config enforcer system for Midgard Valheim server")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MidgardAntiCheat")]
[assembly: AssemblyCopyright("Copyright ©  2024 - Ravenis")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("33A48729-24B4-4336-B364-4672EBBD15EE")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		AssemblyLoader.Attach();
	}
}
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;
		}
	}
}
public static class ZNetExtensions
{
	public enum ZNetInstanceType
	{
		Local,
		Client,
		Server
	}

	public static bool IsLocalInstance(this ZNet znet)
	{
		return znet.IsServer() && !znet.IsDedicated();
	}

	public static bool IsClientInstance(this ZNet znet)
	{
		return !znet.IsServer() && !znet.IsDedicated();
	}

	public static bool IsServerInstance(this ZNet znet)
	{
		return znet.IsServer() && znet.IsDedicated();
	}

	public static ZNetInstanceType GetInstanceType(this ZNet znet)
	{
		if (znet.IsLocalInstance())
		{
			return ZNetInstanceType.Local;
		}
		if (znet.IsClientInstance())
		{
			return ZNetInstanceType.Client;
		}
		return ZNetInstanceType.Server;
	}
}
namespace AntiMods.GamePatches
{
	public static class ZNet_RPC_PeerInfoPatch
	{
		private static bool Prefix(ref ZNet __instance, ZRpc rpc, ZPackage pkg)
		{
			if (__instance.IsServer())
			{
				string text = "";
				if (pkg.Size() > 32)
				{
					pkg.SetPos(pkg.Size() - 32 - 1);
					if (pkg.ReadByte() == 32)
					{
						pkg.SetPos(pkg.GetPos() - 1);
						text = pkg.ReadString();
					}
				}
				ZLog.Log((object)("[Midgard Anti-Cheat] [AntiMods]: Got client hash: " + text + "\nmine: " + MidgardAntiCheatPlugin.PluginsHash));
				ZLog.LogWarning((object)("[Midgard Anti-Cheat] Plugin Hashes are equal: " + !text.Equals(MidgardAntiCheatPlugin.PluginsHash) + " Force same mods system is on: " + MidgardAntiCheatPlugin.forcesamemods));
				ZLog.LogWarning((object)("[Midgard Anti-Cheat] Is Admin: " + !ZNet.instance.m_adminList.Contains(rpc.GetSocket().GetHostName()) + "Admin bypasses forcemod system: " + MidgardAntiCheatPlugin.adminbypass));
				pkg.SetPos(0);
				if (MidgardAntiCheatPlugin.adminbypass && ZNet.instance.m_adminList.Contains(rpc.GetSocket().GetHostName()))
				{
					return true;
				}
				if (!text.Equals(MidgardAntiCheatPlugin.PluginsHash) && MidgardAntiCheatPlugin.forcesamemods)
				{
					int num = (Utility.IsNullOrWhiteSpace(text) ? 3 : 99);
					ZLog.Log((object)("[Midgard Anti-Cheat] [AntiMods]: Kicking Client: " + rpc.GetSocket().GetEndPointString() + " (incompatible mods)"));
					rpc.Invoke("Error", new object[1] { num });
					return false;
				}
				ZLog.Log((object)("[Midgard Anti-Cheat] [AntiMods]: Accepting Client: " + rpc.GetSocket().GetEndPointString()));
			}
			return true;
		}
	}
}
namespace MidgardAntiCheat
{
	internal class Rpc
	{
		public static Dictionary<long, bool> Clients = new Dictionary<long, bool>(10);

		public static void AcHandshake(ZRpc rpc, long sender, string hash)
		{
			ZLog.Log((object)(ZNet.instance.IsServer() ? "Server" : ("Clientreceived AcHandshake from " + sender)));
			if (ZNet.instance.IsServer())
			{
				Clients.Add(sender, MidgardAntiCheatPlugin.PluginsHash.Equals(hash));
				ZLog.Log((object)("AC: Storing " + sender));
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "AcHandshake", new object[1] { "" });
			}
			else
			{
				ZLog.Log((object)"AC: Got server request, sending hash");
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "AcHandshake", new object[1] { "123451" });
			}
		}

		public static void AcRoutedHandshake(long sender, ZPackage pkg)
		{
			ZLog.Log((object)(ZNet.instance.IsServer() ? "Server" : ("Clientreceived AcRoutedHandshake from " + sender)));
			if (ZNet.instance.IsServer())
			{
				ZLog.Log((object)("AC: Storing " + sender));
			}
			else
			{
				ZLog.Log((object)"AC: Got server request, sending hash");
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			peer.m_rpc.Register<ZPackage>("AntiCheat_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_AntiCheat_Version);
			ZPackage val = new ZPackage();
			val.Write(MidgardAntiCheatPlugin.PluginsHash);
			peer.m_rpc.Invoke("AntiCheat_VersionCheck", new object[1] { val });
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "AntiCheatRequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMin = 15f;
				__instance.m_connectionFailedError.verticalAlignment = (VerticalAlignmentOptions)514;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + MidgardAntiCheatPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_AntiCheat_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			if (ZNet.instance.m_adminList.Contains(rpc.GetSocket().GetHostName()))
			{
				ZLog.Log((object)"[Midgard Anti-Cheat] [AntiMods]: Admin detected, bypassing mod force check...)");
				ValidatedPeers.Add(rpc);
			}
			else if (text != MidgardAntiCheatPlugin.PluginsHash)
			{
				MidgardAntiCheatPlugin.ConnectionError = "[Midgard Anti-Cheat] MOD force system error: Incompatible mod hash, try updating the modpack first or join https://midgard.website/discord";
				if (ZNet.instance.IsServer())
				{
					ZLog.Log((object)("[Midgard Anti-Cheat] [AntiMods]: Client hash: " + text + "  Server hash: " + MidgardAntiCheatPlugin.PluginsHash));
				}
				rpc.Invoke("Error", new object[1] { 3 });
			}
			else if (!ZNet.instance.IsServer())
			{
				ZLog.Log((object)"[Midgard Anti-Cheat] [AntiMods]: Received same version from server!");
			}
			else
			{
				ZLog.Log((object)("[Midgard Anti-Cheat] [AntiMods]: Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}
	}
	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(ZRoutedRpc), "GetServerPeerID")]
	public static class HookedZRoutedRpc
	{
		public static long GetServerPeerID(object instance)
		{
			throw new NotImplementedException();
		}
	}
	public static class HashAlgorithmExtensions
	{
		private static string FinalHash(int hash, bool upperCase)
		{
			if (upperCase)
			{
				return hash.ToString(upperCase ? "X2" : "x2");
			}
			return hash.ToString();
		}

		public static string PluginHashes(string path)
		{
			string text = "";
			int hash = 0;
			List<string> list = (from d in Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories)
				where !d.Contains("MMHOOK")
				select d).ToList();
			File.Delete(path + "\\plugins.dat");
			File.WriteAllLines(path + "\\plugins.dat", list);
			MD5 mD = MD5.Create();
			List<string> list2 = list;
			for (int i = 0; i < list.Count; i++)
			{
				byte[] array = File.ReadAllBytes(list2[i]);
				if (i == list.Count - 1)
				{
					mD.TransformFinalBlock(array, 0, array.Length);
					list2[i] = BitConverter.ToString(mD.Hash).Replace("-", "").ToLower();
					text = string.Join("", list2);
					hash = StringExtensionMethods.GetStableHashCode(text);
				}
				else if (!list[i].Contains("MMHOOK_"))
				{
					mD.TransformBlock(array, 0, array.Length, array, 0);
					mD.TransformFinalBlock(array, 0, array.Length);
					list2[i] = BitConverter.ToString(mD.Hash).Replace("-", "").ToLower();
				}
			}
			File.Delete(path + "\\hashes.dat");
			File.Delete(path + "\\finalhash.dat");
			File.WriteAllLines(path + "\\hashes.dat", list2);
			File.WriteAllText(path + "\\finalhash.dat", FinalHash(hash, upperCase: true));
			return FinalHash(hash, upperCase: true);
		}
	}
	public class Damage_Rule
	{
		public static bool Execute(HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (!MidgardAntiCheatPlugin.anti_debug_mode && !MidgardAntiCheatPlugin.anti_damage_boost)
				{
					return true;
				}
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null && MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogError((object)("[Midgard Anti-Cheat] Send Char" + (object)attacker));
				}
				if ((Object)(object)attacker != (Object)null && attacker.IsPlayer())
				{
					ZNetPeer peer = ZNet.instance.GetPeer((long)((Object)attacker).GetInstanceID());
					if (MidgardAntiCheatPlugin.debugmode)
					{
						ZLog.LogError((object)("[Midgard Anti-Cheat] Player Detected, player:" + ((Object)attacker).GetInstanceID()));
						ZLog.LogError((object)("[Midgard Anti-Cheat] Damage = " + hit.GetTotalDamage()));
					}
					float totalDamage = hit.GetTotalDamage();
					if (peer != null && (!MidgardAntiCheatPlugin.admins_bypass || !ZNet.instance.m_adminList.Contains(peer.m_rpc.GetSocket().GetHostName())) && totalDamage > 1000f)
					{
						if (MidgardAntiCheatPlugin.debugmode)
						{
							ZLog.LogError((object)"[Midgard Anti-Cheat] Player Detected with possible Damage Boost.");
						}
						MidgardAntiCheatPlugin.toKick.Add(peer);
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	public class DamageCharacter_Patch
	{
		private static bool Prefix(ref Character __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to Character");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "RPC_Damage")]
	public class DamageWearNTear_Patch
	{
		private static bool Prefix(ref WearNTear __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to WearNTear");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TreeBase), "RPC_Damage")]
	public class DamageTreeBase_Patch
	{
		private static bool Prefix(ref TreeBase __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to TreeBase");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TreeLog), "RPC_Damage")]
	public class DamageTreeLog_Patch
	{
		private static bool Prefix(ref TreeLog __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to TreeBase");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MineRock5), "RPC_Damage")]
	public class DamageMineRock5_Patch
	{
		private static bool Prefix(ref MineRock5 __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to MineRock5");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Destructible), "RPC_Damage")]
	public class DamageDestructible_Patch
	{
		private static bool Prefix(ref Destructible __instance, ref long sender, ref HitData hit)
		{
			if (MidgardAntiCheatPlugin.AntiParams_IsEnabled)
			{
				if (MidgardAntiCheatPlugin.debugmode)
				{
					ZLog.LogWarning((object)"[Midgard Anti-Cheat] Damage to MineRock5");
				}
				return Damage_Rule.Execute(hit);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ZNet), "UpdatePlayerList")]
	public class UpdatePlayerList_Patch
	{
		private static void Postfix(ref ZNet __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			if (Player.s_players == null || Player.s_players.Count == 0 || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			if (ZNet.instance.IsServer() && (int)SystemInfo.graphicsDeviceType != 4 && Player.s_players != null && Player.s_players.Count > 0)
			{
				foreach (Player s_player in Player.s_players)
				{
					ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(((Object)s_player).name);
					if ((s_player.ToggleDebugFly() || (s_player.ToggleNoPlacementCost() && MidgardAntiCheatPlugin.anti_debug_mode)) && peerByPlayerName != null && !ZNet.instance.m_adminList.Contains(peerByPlayerName.m_rpc.GetSocket().GetHostName()))
					{
						MidgardAntiCheatPlugin.toKick.Add(peerByPlayerName);
					}
					if (s_player.m_godMode && MidgardAntiCheatPlugin.anti_god_mode && peerByPlayerName != null && !ZNet.instance.m_adminList.Contains(peerByPlayerName.m_rpc.GetSocket().GetHostName()))
					{
						MidgardAntiCheatPlugin.toKick.Add(peerByPlayerName);
					}
					Process[] processesByName = Process.GetProcessesByName("ValheimToolerLauncher");
					if (processesByName.Length != 0)
					{
						MonoBehaviour.print((object)"Valheim Tooler DETECTED! Closing Valheim Client...");
						Thread.Sleep(3000);
						Process[] processesByName2 = Process.GetProcessesByName("valheim");
						foreach (Process process in processesByName2)
						{
							process.Kill();
						}
					}
				}
			}
			if (Player.s_players != null && ZNet.instance.m_peers.Count > 0)
			{
				foreach (ZNetPeer peer in ZNet.instance.m_peers)
				{
					if (MidgardAntiCheatPlugin.posMap[peer] == Vector3.zero)
					{
						MidgardAntiCheatPlugin.posMap[peer] = peer.m_refPos;
					}
					else if (MidgardAntiCheatPlugin.anti_fly)
					{
						if ((!ZNet.instance.m_adminList.Contains(peer.m_rpc.GetSocket().GetHostName()) && (double)Math.Abs(peer.m_refPos.x - MidgardAntiCheatPlugin.posMap[peer].x) > 15.0) || (double)Math.Abs(peer.m_refPos.y - MidgardAntiCheatPlugin.posMap[peer].y) > 15.0 || (double)Math.Abs(peer.m_refPos.y - MidgardAntiCheatPlugin.posMap[peer].y) > 15.0)
						{
							MidgardAntiCheatPlugin.toKick.Add(peer);
						}
						else
						{
							MidgardAntiCheatPlugin.posMap[peer] = peer.m_refPos;
						}
					}
					if (peer.IsReady() && !((ZDOID)(ref peer.m_characterID)).IsNone() && ZNet.instance.m_zdoMan.GetZDO(peer.m_characterID).GetBool("DebugFly", false) && !ZNet.instance.m_adminList.Contains(peer.m_rpc.GetSocket().GetHostName()))
					{
						MidgardAntiCheatPlugin.toKick.Add(peer);
					}
				}
			}
			if (Player.s_players == null && MidgardAntiCheatPlugin.toKick.Count <= 0)
			{
				return;
			}
			foreach (ZNetPeer item in MidgardAntiCheatPlugin.toKick)
			{
				if (!MidgardAntiCheatPlugin.admins_bypass || !ZNet.instance.m_adminList.Contains(item.m_rpc.GetSocket().GetHostName()))
				{
					ZDOID characterID;
					if (MidgardAntiCheatPlugin.ban_on_trigger)
					{
						ZLog.LogError((object)"[Midgard Anti-Cheat] Punish");
						__instance.Ban(item.m_playerName);
						string[] obj = new string[5]
						{
							"[Midgard Anti-Cheat] Banned ",
							item.m_playerName,
							item.m_uid.ToString(),
							null,
							null
						};
						characterID = item.m_characterID;
						obj[3] = ((object)(ZDOID)(ref characterID)).ToString();
						obj[4] = " for cheats";
						ZLog.LogWarning((object)string.Concat(obj));
					}
					else
					{
						ZLog.LogError((object)"[Midgard Anti-Cheat] Punish");
						__instance.Kick(item.m_playerName);
						string[] obj2 = new string[5]
						{
							"[Midgard Anti-Cheat] kicked ",
							item.m_playerName,
							item.m_uid.ToString(),
							null,
							null
						};
						characterID = item.m_characterID;
						obj2[3] = ((object)(ZDOID)(ref characterID)).ToString();
						obj2[4] = " for cheats";
						ZLog.LogWarning((object)string.Concat(obj2));
					}
				}
			}
			MidgardAntiCheatPlugin.toKick.Clear();
		}
	}
	[BepInPlugin("midgard.anticheat", "Midgard Anti-Cheat", "0.8.2")]
	public class MidgardAntiCheatPlugin : BaseUnityPlugin
	{
		public const string version = "0.8.2";

		public const string pluginname = "Midgard Anti-Cheat";

		public const string pluginid = "midgard.anticheat";

		public static string description = "Midgard Anti-Cheat & Modforce System";

		internal static string ConnectionError = "";

		public const int HashLength = 32;

		public static string PluginsHash = "";

		public static Harmony harmony = new Harmony("midgard.anticheat");

		public static List<ZNetPeer> toKick = new List<ZNetPeer>();

		public static Dictionary<ZNetPeer, Vector3> posMap;

		public static ManualLogSource logger;

		public static List<string> playernames = new List<string>();

		public static int Counter = 0;

		public static bool antiMods_IsEnabled;

		public static bool forcesamemods;

		public static bool ignoremmhooks;

		public static bool adminbypass;

		public static bool AntiParams_IsEnabled;

		public static bool ban_on_trigger;

		public static bool admins_bypass;

		public static bool anti_fly;

		public static bool anti_debug_mode;

		public static bool anti_god_mode;

		public static bool anti_damage_boost;

		public static bool debugmode;

		public static bool anti_health_boost;

		public static bool speeditup;

		public static string AntiModsActivated;

		public static string AntiModsError;

		public static string AntiModsKickServer;

		public static string AntiModsKickClient;

		public static string AntiParamsMsg;

		private static readonly StringBuilder sb = new StringBuilder();

		private static PlayerProfile playerProfile;

		private static int statCount = 0;

		public static bool AntiMods_IsEnabled
		{
			get
			{
				return antiMods_IsEnabled;
			}
			set
			{
				antiMods_IsEnabled = value;
			}
		}

		private static string GetStatName(PlayerStatType stat)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			string name = Enum.GetName(typeof(PlayerStatType), stat);
			StringBuilder stringBuilder = new StringBuilder();
			string text = name;
			foreach (char c in text)
			{
				if (char.IsUpper(c) && stringBuilder.Length > 0)
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		private static void AddStat(PlayerStatType stat, string statName = "", bool showIfZero = false)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (playerProfile.m_playerStats.m_stats.ContainsKey(stat))
			{
				float num = playerProfile.m_playerStats.m_stats[stat];
				if (num != 0f || showIfZero)
				{
					sb.Append("\n");
					sb.Append(string.Format("{0}: {1}", (statName != "") ? statName : GetStatName(stat), num));
					statCount++;
				}
			}
		}

		private static void AddLine()
		{
			if (statCount > 0)
			{
				sb.Append("\n");
			}
			statCount = 0;
		}

		public static void WriteOnlineList()
		{
			if (ZNet.m_isServer)
			{
				playernames.Clear();
				List<ZNetPeer> peers = ZNet.m_instance.m_peers;
				for (int i = 0; i < ZNet.m_instance.m_peers.Count; i++)
				{
					playernames.Add(peers[i].m_playerName + "<br>");
				}
				File.Delete(Paths.PluginPath + "\\players_online.dat");
				File.WriteAllLines(Paths.PluginPath + "\\players_online.dat", playernames);
				File.Delete(Paths.PluginPath + "\\players_online_count.dat");
				File.WriteAllText(Paths.PluginPath + "\\players_online_count.dat", peers.Count.ToString());
			}
		}

		private void Watcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.PluginPath);
			fileSystemWatcher.Changed += CheckInjections;
			fileSystemWatcher.Created += CheckInjections;
			fileSystemWatcher.Renamed += CheckInjections;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			FileSystemWatcher fileSystemWatcher2 = new FileSystemWatcher(Paths.BepInExRootPath);
			fileSystemWatcher2.Changed += CheckInjections;
			fileSystemWatcher2.Created += CheckInjections;
			fileSystemWatcher2.Renamed += CheckInjections;
			fileSystemWatcher2.IncludeSubdirectories = true;
			fileSystemWatcher2.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher2.EnableRaisingEvents = true;
		}

		private void CheckInjections(object sender, FileSystemEventArgs e)
		{
			Process[] processesByName = Process.GetProcessesByName("ValheimToolerLauncher");
			if (processesByName.Length != 0)
			{
				ZLog.Log((object)"[Midgard Anti-Cheat] Valheim Tooler DETECTED! Closing Valheim and ValheimTooler...");
				Thread.Sleep(3000);
				Process[] processesByName2 = Process.GetProcessesByName("ValheimToolerLauncher");
				foreach (Process process in processesByName2)
				{
					process.Kill();
				}
				Process[] processesByName3 = Process.GetProcessesByName("valheim");
				foreach (Process process2 in processesByName3)
				{
					process2.Kill();
				}
			}
		}

		private void Awake()
		{
			forcesamemods = true;
			AntiMods_IsEnabled = true;
			ban_on_trigger = false;
			adminbypass = true;
			anti_fly = true;
			anti_debug_mode = true;
			anti_god_mode = true;
			anti_damage_boost = true;
			anti_health_boost = true;
			speeditup = true;
			debugmode = false;
			AntiModsActivated = "[Midgard Anti-Cheat] Mod Forcing Enabled.";
			AntiModsError = "[Midgard Anti-Cheat] Mod hash error!";
			AntiModsKickClient = "[Midgard Anti-Cheat] You were kicked for using outdated/wrong/missized/missing/ files, or admin is working on something at the moment. Join https://midgard.website/discord for more info!";
			AntiModsKickServer = "[Midgard Anti-Cheat] Player have been kicked for using not allowed mod(s)!";
			AntiParamsMsg = "[Midgard Anti-Cheat] Player {0} punished for {1}!";
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			harmony.PatchAll(executingAssembly);
			Logger.LogWarning((object)"[Midgard Anti-Cheat] Patching and generating mod hash...");
			posMap = new Dictionary<ZNetPeer, Vector3>();
			toKick = new List<ZNetPeer>();
			if (ZNet.m_isServer)
			{
				StartTimer(1000);
			}
			AntiMods();
			Watcher();
		}

		public void StartTimer(int dueTime)
		{
			Timer timer = new Timer(TimerProc);
			timer.Change(dueTime, 30000);
		}

		private void TimerProc(object state)
		{
			Timer timer = (Timer)state;
			WriteOnlineList();
		}

		public static void AntiMods()
		{
			if (Paths.ProcessName.Equals("valheim_server", StringComparison.OrdinalIgnoreCase))
			{
				PluginsHash = HashAlgorithmExtensions.PluginHashes(Paths.BepInExRootPath + "\\..\\MidgardClientMods");
			}
			else
			{
				PluginsHash = HashAlgorithmExtensions.PluginHashes(Paths.PluginPath);
			}
			Logger.LogWarning((object)("[Midgard Anti-Cheat] Final Mod hash: " + PluginsHash));
			Logger.LogWarning((object)"[Midgard Anti-Cheat] Done patching.");
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	public static class FejdStartup_SetupGui_Patch
	{
		private static void Postfix(ref FejdStartup __instance)
		{
			__instance.m_versionLabel.fontSize = 7f;
			string versionString = Version.GetVersionString(false);
			__instance.m_versionLabel.text = versionString + "\nMidgard Anti-Cheat System 0.8.2\nMidgard Ashlands Client";
		}
	}
	[HarmonyPatch(typeof(FejdStartup))]
	public class FejdStartup_ShowConnectErrorPatch
	{
		[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
		public static void Postfix(FejdStartup __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)ZNet.GetConnectionStatus() != 99)
			{
				__instance.m_connectionFailedError.text = "[Midgard Server] Connection failed. Join https://midgard.website/discord for more info!";
			}
			else
			{
				__instance.m_connectionFailedError.text = MidgardAntiCheatPlugin.AntiModsKickClient;
			}
		}
	}
	public class MidgardAntiCheatAck
	{
		public static void RPC_MidgardAntiCheatAck(long sender)
		{
			RpcQueue.GotAck();
		}

		public static void SendAck(long target)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(target, "MidgardAntiCheatAck", Array.Empty<object>());
		}
	}
	internal static class GameObjectAssistant
	{
		private static ConcurrentDictionary<float, Stopwatch> stopwatches = new ConcurrentDictionary<float, Stopwatch>();

		public static Stopwatch GetStopwatch(GameObject o)
		{
			float gameObjectPosHash = GetGameObjectPosHash(o);
			Stopwatch value = null;
			if (!stopwatches.TryGetValue(gameObjectPosHash, out value))
			{
				value = new Stopwatch();
				stopwatches.TryAdd(gameObjectPosHash, value);
			}
			return value;
		}

		private static float GetGameObjectPosHash(GameObject o)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			return 1000f * o.transform.position.x + o.transform.position.y + 0.001f * o.transform.position.z;
		}

		public static T GetChildComponentByName<T>(string name, GameObject objected) where T : Component
		{
			T[] componentsInChildren = objected.GetComponentsInChildren<T>(true);
			foreach (T val in componentsInChildren)
			{
				if (((Object)((Component)val).gameObject).name == name)
				{
					return val;
				}
			}
			return default(T);
		}
	}
	internal static class Helper
	{
		public static Character getPlayerCharacter(Player __instance)
		{
			return (Character)(object)__instance;
		}

		public static float tFloat(this float value, int digits)
		{
			double num = Math.Pow(10.0, digits);
			double num2 = Math.Truncate(num * (double)value) / num;
			return (float)num2;
		}

		public static float applyModifierValue(float targetValue, float value)
		{
			if (value == 50f)
			{
				value = 51f;
			}
			if (value == -50f)
			{
				value = -51f;
			}
			if (value <= -100f)
			{
				value = -100f;
			}
			float num = targetValue;
			if (value >= 0f)
			{
				return targetValue + targetValue / 100f * value;
			}
			return targetValue - targetValue / 100f * (value * -1f);
		}

		public static string CreateMD5(string input)
		{
			using MD5 mD = MD5.Create();
			byte[] bytes = Encoding.ASCII.GetBytes(input);
			byte[] array = mD.ComputeHash(bytes);
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < array.Length; i++)
			{
				stringBuilder.Append(array[i].ToString("X2"));
			}
			return stringBuilder.ToString();
		}

		public static int Clamp(int value, int min, int max)
		{
			return Math.Min(max, Math.Max(min, value));
		}

		public static float Clamp(float value, float min, float max)
		{
			return Math.Min(max, Math.Max(min, value));
		}
	}
	public static class ListExtensions
	{
		public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize)
		{
			return (from x in source.Select((T x, int i) => new
				{
					Index = i,
					Value = x
				})
				group x by x.Index / chunkSize into x
				select x.Select(v => v.Value).ToList()).ToList();
		}
	}
	public class RpcData
	{
		public string Name;

		public long Target = ZRoutedRpc.Everybody;

		public object[] Payload;
	}
	public static class RpcQueue
	{
		private static Queue<RpcData> _rpcQueue = new Queue<RpcData>();

		private static bool _ack = true;

		public static void Enqueue(RpcData rpc)
		{
			_rpcQueue.Enqueue(rpc);
		}

		public static bool SendNextRpc()
		{
			if (_rpcQueue.Count == 0 || !_ack)
			{
				return false;
			}
			RpcData rpcData = _rpcQueue.Dequeue();
			if (Utility.IsNullOrWhiteSpace(rpcData.Name) || rpcData.Payload == null)
			{
				return false;
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(rpcData.Target, rpcData.Name, rpcData.Payload);
			_ack = false;
			return true;
		}

		public static void GotAck()
		{
			_ack = true;
		}
	}
}
namespace MidgardAntiCheat.AntiParams.GamePatches
{
	[HarmonyPatch(typeof(Character), "RPC_Heal")]
	public class HealthRPC_Heal_Patch
	{
		private static bool Prefix(ref Character __instance, ref long sender, ref float hp, ref bool showText)
		{
			float health = __instance.GetHealth();
			if ((double)health <= 0.0 || __instance.IsDead() || !__instance.IsPlayer())
			{
				return true;
			}
			ZLog.LogWarning((object)("[Midgard Anti-Cheat] Is Player/Is Dead:" + __instance.IsPlayer() + __instance.IsDead()));
			float maxHealth = __instance.GetMaxHealth();
			Character val = __instance;
			ZLog.LogWarning((object)("[Midgard Anti-Cheat] Max Health/Player Character:" + maxHealth + (object)val));
			if (maxHealth >= 1000f || health >= 1000f)
			{
				ZNetPeer peer = ZNet.instance.GetPeer((long)((Object)val).GetInstanceID());
				ZLog.LogWarning((object)("[Midgard Anti-Cheat] Peer:" + (object)peer));
				if (peer != null && (!MidgardAntiCheatPlugin.admins_bypass || !ZNet.instance.m_adminList.Contains(peer.m_rpc.GetSocket().GetHostName())))
				{
					ZLog.LogError((object)"[Midgard Anti-Cheat] Player Detected with possible Health Boost.");
					MidgardAntiCheatPlugin.toKick.Add(peer);
				}
				return true;
			}
			return true;
		}
	}
}
namespace Costura
{
	[CompilerGenerated]
	internal static class AssemblyLoader
	{
		private static object nullCacheLock = new object();

		private static Dictionary<string, bool> nullCache = new Dictionary<string, bool>();

		private static Dictionary<string, string> assemblyNames = new Dictionary<string, string>();

		private static Dictionary<string, string> symbolNames = new Dictionary<string, string>();

		private static int isAttached;

		private static string CultureToString(CultureInfo culture)
		{
			if (culture == null)
			{
				return "";
			}
			return culture.Name;
		}

		private static Assembly ReadExistingAssembly(AssemblyName name)
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			Assembly[] assemblies = currentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				AssemblyName name2 = assembly.GetName();
				if (string.Equals(name2.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) && string.Equals(CultureToString(name2.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase))
				{
					return assembly;
				}
			}
			return null;
		}

		private static void CopyTo(Stream source, Stream destination)
		{
			byte[] array = new byte[81920];
			int count;
			while ((count = source.Read(array, 0, array.Length)) != 0)
			{
				destination.Write(array, 0, count);
			}
		}

		private static Stream LoadStream(string fullName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			if (fullName.EndsWith(".compressed"))
			{
				using (Stream stream = executingAssembly.GetManifestResourceStream(fullName))
				{
					using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress);
					MemoryStream memoryStream = new MemoryStream();
					CopyTo(source, memoryStream);
					memoryStream.Position = 0L;
					return memoryStream;
				}
			}
			return executingAssembly.GetManifestResourceStream(fullName);
		}

		private static Stream LoadStream(Dictionary<string, string> resourceNames, string name)
		{
			if (resourceNames.TryGetValue(name, out var value))
			{
				return LoadStream(value);
			}
			return null;
		}

		private static byte[] ReadStream(Stream stream)
		{
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			return array;
		}

		private static Assembly ReadFromEmbeddedResources(Dictionary<string, string> assemblyNames, Dictionary<string, string> symbolNames, AssemblyName requestedAssemblyName)
		{
			string text = requestedAssemblyName.Name.ToLowerInvariant();
			if (requestedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name))
			{
				text = requestedAssemblyName.CultureInfo.Name + "." + text;
			}
			byte[] rawAssembly;
			using (Stream stream = LoadStream(assemblyNames, text))
			{
				if (stream == null)
				{
					return null;
				}
				rawAssembly = ReadStream(stream);
			}
			using (Stream stream2 = LoadStream(symbolNames, text))
			{
				if (stream2 != null)
				{
					byte[] rawSymbolStore = ReadStream(stream2);
					return Assembly.Load(rawAssembly, rawSymbolStore);
				}
			}
			return Assembly.Load(rawAssembly);
		}

		public static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
		{
			lock (nullCacheLock)
			{
				if (nullCache.ContainsKey(e.Name))
				{
					return null;
				}
			}
			AssemblyName assemblyName = new AssemblyName(e.Name);
			Assembly assembly = ReadExistingAssembly(assemblyName);
			if (assembly != null)
			{
				return assembly;
			}
			assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName);
			if (assembly == null)
			{
				lock (nullCacheLock)
				{
					nullCache[e.Name] = true;
				}
				if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0)
				{
					assembly = Assembly.Load(assemblyName);
				}
			}
			return assembly;
		}

		static AssemblyLoader()
		{
			assemblyNames.Add("0harmony", "costura.0harmony.dll.compressed");
			assemblyNames.Add("assembly_guiutils_publicized", "costura.assembly_guiutils_publicized.dll.compressed");
			assemblyNames.Add("assembly_postprocessing_publicized", "costura.assembly_postprocessing_publicized.dll.compressed");
			assemblyNames.Add("assembly_sunshafts_publicized", "costura.assembly_sunshafts_publicized.dll.compressed");
			assemblyNames.Add("assembly_utils_publicized", "costura.assembly_utils_publicized.dll.compressed");
			assemblyNames.Add("assembly_valheim_publicized", "costura.assembly_valheim_publicized.dll.compressed");
			assemblyNames.Add("bepinex", "costura.bepinex.dll.compressed");
			assemblyNames.Add("com.rlabrecque.steamworks.net", "costura.com.rlabrecque.steamworks.net.dll.compressed");
			assemblyNames.Add("jotunn", "costura.jotunn.dll.compressed");
			symbolNames.Add("jotunn", "costura.jotunn.pdb.compressed");
			assemblyNames.Add("mono.security", "costura.mono.security.dll.compressed");
			assemblyNames.Add("monomod.runtimedetour", "costura.monomod.runtimedetour.dll.compressed");
			assemblyNames.Add("monomod.utils", "costura.monomod.utils.dll.compressed");
			assemblyNames.Add("netstandard", "costura.netstandard.dll.compressed");
			assemblyNames.Add("unity.textmeshpro", "costura.unity.textmeshpro.dll.compressed");
			assemblyNames.Add("unityengine.accessibilitymodule", "costura.unityengine.accessibilitymodule.dll.compressed");
			assemblyNames.Add("unityengine.aimodule", "costura.unityengine.aimodule.dll.compressed");
			assemblyNames.Add("unityengine.androidjnimodule", "costura.unityengine.androidjnimodule.dll.compressed");
			assemblyNames.Add("unityengine.animationmodule", "costura.unityengine.animationmodule.dll.compressed");
			assemblyNames.Add("unityengine.armodule", "costura.unityengine.armodule.dll.compressed");
			assemblyNames.Add("unityengine.assetbundlemodule", "costura.unityengine.assetbundlemodule.dll.compressed");
			assemblyNames.Add("unityengine.audiomodule", "costura.unityengine.audiomodule.dll.compressed");
			assemblyNames.Add("unityengine.clothmodule", "costura.unityengine.clothmodule.dll.compressed");
			assemblyNames.Add("unityengine.clusterinputmodule", "costura.unityengine.clusterinputmodule.dll.compressed");
			assemblyNames.Add("unityengine.clusterrenderermodule", "costura.unityengine.clusterrenderermodule.dll.compressed");
			assemblyNames.Add("unityengine.contentloadmodule", "costura.unityengine.contentloadmodule.dll.compressed");
			assemblyNames.Add("unityengine.coremodule", "costura.unityengine.coremodule.dll.compressed");
			assemblyNames.Add("unityengine.crashreportingmodule", "costura.unityengine.crashreportingmodule.dll.compressed");
			assemblyNames.Add("unityengine.directormodule", "costura.unityengine.directormodule.dll.compressed");
			assemblyNames.Add("unityengine", "costura.unityengine.dll.compressed");
			assemblyNames.Add("unityengine.dspgraphmodule", "costura.unityengine.dspgraphmodule.dll.compressed");
			assemblyNames.Add("unityengine.gamecentermodule", "costura.unityengine.gamecentermodule.dll.compressed");
			assemblyNames.Add("unityengine.gridmodule", "costura.unityengine.gridmodule.dll.compressed");
			assemblyNames.Add("unityengine.imageconversionmodule", "costura.unityengine.imageconversionmodule.dll.compressed");
			assemblyNames.Add("unityengine.imguimodule", "costura.unityengine.imguimodule.dll.compressed");
			assemblyNames.Add("unityengine.inputlegacymodule", "costura.unityengine.inputlegacymodule.dll.compressed");
			assemblyNames.Add("unityengine.inputmodule", "costura.unityengine.inputmodule.dll.compressed");
			assemblyNames.Add("unityengine.jsonserializemodule", "costura.unityengine.jsonserializemodule.dll.compressed");
			assemblyNames.Add("unityengine.localizationmodule", "costura.unityengine.localizationmodule.dll.compressed");
			assemblyNames.Add("unityengine.nvidiamodule", "costura.unityengine.nvidiamodule.dll.compressed");
			assemblyNames.Add("unityengine.particlesystemmodule", "costura.unityengine.particlesystemmodule.dll.compressed");
			assemblyNames.Add("unityengine.performancereportingmodule", "costura.unityengine.performancereportingmodule.dll.compressed");
			assemblyNames.Add("unityengine.physics2dmodule", "costura.unityengine.physics2dmodule.dll.compressed");
			assemblyNames.Add("unityengine.physicsmodule", "costura.unityengine.physicsmodule.dll.compressed");
			assemblyNames.Add("unityengine.propertiesmodule", "costura.unityengine.propertiesmodule.dll.compressed");
			assemblyNames.Add("unityengine.screencapturemodule", "costura.unityengine.screencapturemodule.dll.compressed");
			assemblyNames.Add("unityengine.sharedinternalsmodule", "costura.unityengine.sharedinternalsmodule.dll.compressed");
			assemblyNames.Add("unityengine.spritemaskmodule", "costura.unityengine.spritemaskmodule.dll.compressed");
			assemblyNames.Add("unityengine.spriteshapemodule", "costura.unityengine.spriteshapemodule.dll.compressed");
			assemblyNames.Add("unityengine.streamingmodule", "costura.unityengine.streamingmodule.dll.compressed");
			assemblyNames.Add("unityengine.subsystemsmodule", "costura.unityengine.subsystemsmodule.dll.compressed");
			assemblyNames.Add("unityengine.terrainmodule", "costura.unityengine.terrainmodule.dll.compressed");
			assemblyNames.Add("unityengine.terrainphysicsmodule", "costura.unityengine.terrainphysicsmodule.dll.compressed");
			assemblyNames.Add("unityengine.textcorefontenginemodule", "costura.unityengine.textcorefontenginemodule.dll.compressed");
			assemblyNames.Add("unityengine.textcoretextenginemodule", "costura.unityengine.textcoretextenginemodule.dll.compressed");
			assemblyNames.Add("unityengine.textrenderingmodule", "costura.unityengine.textrenderingmodule.dll.compressed");
			assemblyNames.Add("unityengine.tilemapmodule", "costura.unityengine.tilemapmodule.dll.compressed");
			assemblyNames.Add("unityengine.tlsmodule", "costura.unityengine.tlsmodule.dll.compressed");
			assemblyNames.Add("unityengine.ui", "costura.unityengine.ui.dll.compressed");
			assemblyNames.Add("unityengine.uielementsmodule", "costura.unityengine.uielementsmodule.dll.compressed");
			assemblyNames.Add("unityengine.uimodule", "costura.unityengine.uimodule.dll.compressed");
			assemblyNames.Add("unityengine.unityanalyticscommonmodule", "costura.unityengine.unityanalyticscommonmodule.dll.compressed");
			assemblyNames.Add("unityengine.unityanalyticsmodule", "costura.unityengine.unityanalyticsmodule.dll.compressed");
			assemblyNames.Add("unityengine.unityconnectmodule", "costura.unityengine.unityconnectmodule.dll.compressed");
			assemblyNames.Add("unityengine.unitycurlmodule", "costura.unityengine.unitycurlmodule.dll.compressed");
			assemblyNames.Add("unityengine.unitywebrequestassetbundlemodule", "costura.unityengine.unitywebrequestassetbundlemodule.dll.compressed");
			assemblyNames.Add("unityengine.unitywebrequestaudiomodule", "costura.unityengine.unitywebrequestaudiomodule.dll.compressed");
			assemblyNames.Add("unityengine.unitywebrequestmodule", "costura.unityengine.unitywebrequestmodule.dll.compressed");
			assemblyNames.Add("unityengine.unitywebrequesttexturemodule", "costura.unityengine.unitywebrequesttexturemodule.dll.compressed");
			assemblyNames.Add("unityengine.unitywebrequestwwwmodule", "costura.unityengine.unitywebrequestwwwmodule.dll.compressed");
			assemblyNames.Add("unityengine.vehiclesmodule", "costura.unityengine.vehiclesmodule.dll.compressed");
			assemblyNames.Add("unityengine.vfxmodule", "costura.unityengine.vfxmodule.dll.compressed");
			assemblyNames.Add("unityengine.videomodule", "costura.unityengine.videomodule.dll.compressed");
			assemblyNames.Add("unityengine.virtualtexturingmodule", "costura.unityengine.virtualtexturingmodule.dll.compressed");
			assemblyNames.Add("unityengine.vrmodule", "costura.unityengine.vrmodule.dll.compressed");
			assemblyNames.Add("unityengine.windmodule", "costura.unityengine.windmodule.dll.compressed");
			assemblyNames.Add("unityengine.xrmodule", "costura.unityengine.xrmodule.dll.compressed");
			assemblyNames.Add("yamldotnet", "costura.yamldotnet.dll.compressed");
		}

		public static void Attach()
		{
			if (Interlocked.Exchange(ref isAttached, 1) == 1)
			{
				return;
			}
			AppDomain currentDomain = AppDomain.CurrentDomain;
			currentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
			{
				lock (nullCacheLock)
				{
					if (nullCache.ContainsKey(e.Name))
					{
						return null;
					}
				}
				AssemblyName assemblyName = new AssemblyName(e.Name);
				Assembly assembly = ReadExistingAssembly(assemblyName);
				if (assembly != null)
				{
					return assembly;
				}
				assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName);
				if (assembly == null)
				{
					lock (nullCacheLock)
					{
						nullCache[e.Name] = true;
					}
					if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0)
					{
						assembly = Assembly.Load(assemblyName);
					}
				}
				return assembly;
			};
		}
	}
}
internal class MidgardAntiCheat_ProcessedByFody
{
	internal const string FodyVersion = "6.3.0.0";

	internal const string Costura = "5.0.2";
}

BepInEx/plugins/MidgardPaths.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Utils;
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(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MidgardPaths")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MidgardPaths")]
[assembly: AssemblyTitle("MidgardPaths")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SpeedyPaths
{
	[BepInPlugin("midgard.speedypaths", "MidgardPaths", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SpeedyPathsClientMod : BaseUnityPlugin
	{
		public enum GroundType
		{
			Untamed,
			PathDirt,
			PathStone,
			Cultivated,
			StructureWood,
			StructureHardWood,
			StructureStone,
			StructureIron
		}

		private static Dictionary<GroundType, float> _speedModifiers = new Dictionary<GroundType, float>();

		private static Dictionary<GroundType, float> _staminaModifiers = new Dictionary<GroundType, float>();

		private static Dictionary<Biome, float> _untamedSpeedModifiers = new Dictionary<Biome, float>();

		private static Dictionary<Biome, float> _untamedStaminaModifiers = new Dictionary<Biome, float>();

		private static bool _showHudStatus;

		private static string _hudStatusText;

		private static bool _hudDynamicStatusText;

		private static bool _hudShowEffectPercent;

		private static List<float> _hudPosIconThresholds = new List<float>();

		private static List<float> _hudNegIconThresholds = new List<float>();

		private static float _groundSensorUpdateInterval;

		private static int _groundSensorRadius;

		private static Dictionary<GroundType, string> _groundTypeStrings = new Dictionary<GroundType, string>();

		private static Dictionary<Biome, string> _biomeTypeStrings = new Dictionary<Biome, string>();

		private static int m_pieceLayer;

		private static object[] _worldToVertexArgs = new object[3]
		{
			Vector3.zero,
			null,
			null
		};

		private static List<Sprite> _speedSprites = new List<Sprite>();

		private static float m_sensorTime;

		private static GroundType m_cachedGroundType;

		public static ManualLogSource Logger;

		private static float _activeSpeedModifier = 1f;

		private static float _activeStaminaModifier = 1f;

		private static string _activeStatusText;

		private static Sprite _activeStatusSprite;

		private static StatusEffect _pathBuffSEDummy;

		private static float _prevModValue = 1f;

		private void Awake()
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			_hudDynamicStatusText = true;
			_hudShowEffectPercent = true;
			_showHudStatus = true;
			_hudStatusText = "Path";
			_hudPosIconThresholds.Add(1f);
			_hudPosIconThresholds.Add(1.39f);
			_hudNegIconThresholds.Add(1f);
			_hudNegIconThresholds.Add(0.79f);
			_groundSensorUpdateInterval = 1f;
			_groundSensorRadius = 1;
			_speedModifiers[GroundType.PathDirt] = 1.15f;
			_speedModifiers[GroundType.PathStone] = 1.4f;
			_speedModifiers[GroundType.Cultivated] = 1.05f;
			_speedModifiers[GroundType.StructureWood] = 1.15f;
			_speedModifiers[GroundType.StructureHardWood] = 1.2f;
			_speedModifiers[GroundType.StructureStone] = 1.4f;
			_speedModifiers[GroundType.StructureIron] = 1.5f;
			_staminaModifiers[GroundType.PathDirt] = 0.8f;
			_staminaModifiers[GroundType.PathStone] = 0.7f;
			_staminaModifiers[GroundType.Cultivated] = 1f;
			_staminaModifiers[GroundType.StructureWood] = 0.8f;
			_staminaModifiers[GroundType.StructureHardWood] = 0.8f;
			_staminaModifiers[GroundType.StructureStone] = 0.7f;
			_staminaModifiers[GroundType.StructureIron] = 7f;
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				Biome key = value;
				_untamedSpeedModifiers[key] = 1f;
				_untamedStaminaModifiers[key] = 1f;
				_biomeTypeStrings[key] = "Biome_" + ((object)(Biome)(ref key)).ToString();
			}
			_groundTypeStrings[GroundType.PathDirt] = "Dirt Path";
			_groundTypeStrings[GroundType.PathStone] = "Stone Path";
			_groundTypeStrings[GroundType.Cultivated] = "Cultivated Ground";
			_groundTypeStrings[GroundType.StructureWood] = "Wood Structure";
			_groundTypeStrings[GroundType.StructureHardWood] = "Hardwood Structure";
			_groundTypeStrings[GroundType.StructureStone] = "Stone Structure";
			_groundTypeStrings[GroundType.StructureIron] = "Metal Structure";
			if (m_pieceLayer == 0)
			{
				m_pieceLayer = LayerMask.NameToLayer("piece");
			}
			_speedSprites.Add(AssetUtils.LoadSpriteFromFile("Ravenis-Midgard/Assets/s1.png"));
			_speedSprites.Add(AssetUtils.LoadSpriteFromFile("Ravenis-Midgard/Assets/s2.png"));
			_speedSprites.Add(AssetUtils.LoadSpriteFromFile("Ravenis-Midgard/Assets/sn1.png"));
			_speedSprites.Add(AssetUtils.LoadSpriteFromFile("Ravenis-Midgard/Assets/sn2.png"));
			m_sensorTime = 0f;
			m_cachedGroundType = GroundType.Untamed;
			Harmony.CreateAndPatchAll(typeof(SpeedyPathsClientMod), (string)null);
		}

		[HarmonyPatch(typeof(Player), "FixedUpdate")]
		[HarmonyPrefix]
		private static void UpdateModifiers(Player __instance)
		{
			m_sensorTime -= Time.fixedDeltaTime;
			if (!((Object)(object)Player.m_localPlayer == (Object)(object)__instance) || ((Character)__instance).IsDead())
			{
				return;
			}
			UpdateGroundTypeCache(__instance);
			_activeSpeedModifier = GetSpeedyPathModifier(__instance);
			_activeStaminaModifier = GetSpeedyPathStaminaModifier(__instance);
			if (_activeSpeedModifier > 1f)
			{
				for (int i = 0; i < _hudPosIconThresholds.Count; i++)
				{
					if (_activeSpeedModifier > _hudPosIconThresholds[i])
					{
						_activeStatusSprite = _speedSprites[i];
					}
				}
				return;
			}
			for (int j = 0; j < _hudNegIconThresholds.Count; j++)
			{
				if (_activeSpeedModifier < _hudNegIconThresholds[j])
				{
					_activeStatusSprite = _speedSprites[_hudPosIconThresholds.Count + j];
				}
			}
		}

		[HarmonyPatch(typeof(Player), "CheckRun")]
		[HarmonyPrefix]
		private static void CheckRunPrefixStaminaMod(Player __instance, out float __state)
		{
			__state = __instance.m_runStaminaDrain;
			__instance.m_runStaminaDrain *= _activeStaminaModifier;
		}

		[HarmonyPatch(typeof(Player), "CheckRun")]
		[HarmonyPostfix]
		private static void CheckRunPostfixStaminaMod(Player __instance, float __state)
		{
			__instance.m_runStaminaDrain = __state;
		}

		[HarmonyPatch(typeof(Player), "GetJogSpeedFactor")]
		[HarmonyPostfix]
		private static void JogSpeedPathFactor(Player __instance, ref float __result)
		{
			__result *= _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(Player), "GetRunSpeedFactor")]
		[HarmonyPostfix]
		private static void RunSpeedPathFactor(Player __instance, ref float __result)
		{
			__result *= _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(Hud), "UpdateStatusEffects")]
		[HarmonyPrefix]
		private static void UpdatePathIcon(Hud __instance, List<StatusEffect> statusEffects)
		{
			if (((Character)Player.m_localPlayer).IsDead() || !_showHudStatus || _activeSpeedModifier == 1f)
			{
				return;
			}
			if ((Object)(object)_pathBuffSEDummy == (Object)null)
			{
				ScriptableObject obj = ScriptableObject.CreateInstance(typeof(StatusEffect));
				_pathBuffSEDummy = (StatusEffect)(object)((obj is StatusEffect) ? obj : null);
			}
			_pathBuffSEDummy.m_name = (_hudDynamicStatusText ? _activeStatusText : _hudStatusText);
			_pathBuffSEDummy.m_icon = _activeStatusSprite;
			if (_activeSpeedModifier != 1f)
			{
				if (_activeSpeedModifier != _prevModValue)
				{
					_pathBuffSEDummy.m_isNew = true;
				}
				statusEffects.Add(_pathBuffSEDummy);
			}
			_prevModValue = _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(StatusEffect), "GetIconText")]
		[HarmonyPostfix]
		private static void SpeedyPathsStatusEffect_GetIconText(StatusEffect __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)(object)_pathBuffSEDummy && _hudShowEffectPercent)
			{
				__result = (_activeSpeedModifier - 1f).ToString("P0");
			}
		}

		private static float GetSpeedyPathModifier(Player player)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)player).IsSwimming() && !((Character)player).InInterior())
			{
				if (_speedModifiers.ContainsKey(m_cachedGroundType))
				{
					_activeStatusText = _groundTypeStrings[m_cachedGroundType];
					return _speedModifiers[m_cachedGroundType];
				}
				Biome key = player.GetCurrentBiome();
				if (!_untamedSpeedModifiers.ContainsKey(key))
				{
					key = (Biome)0;
				}
				_activeStatusText = "$biome_" + ((object)(Biome)(ref key)).ToString().ToLower();
				if (_biomeTypeStrings.ContainsKey(key) && _biomeTypeStrings[key] != "default")
				{
					_activeStatusText = _biomeTypeStrings[key];
				}
				return _untamedSpeedModifiers[key];
			}
			return 1f;
		}

		private static float GetSpeedyPathStaminaModifier(Player player)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)player).IsSwimming() && !((Character)player).InInterior())
			{
				if (_staminaModifiers.ContainsKey(m_cachedGroundType))
				{
					return _staminaModifiers[m_cachedGroundType];
				}
				Biome key = player.GetCurrentBiome();
				if (!_untamedStaminaModifiers.ContainsKey(key))
				{
					key = (Biome)0;
				}
				return _untamedStaminaModifiers[key];
			}
			return 1f;
		}

		private static void UpdateGroundTypeCache(Player player)
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected I4, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			if (m_sensorTime > 0f)
			{
				return;
			}
			m_sensorTime = _groundSensorUpdateInterval;
			Collider lastGroundCollider = ((Character)player).GetLastGroundCollider();
			if (Object.op_Implicit((Object)(object)lastGroundCollider))
			{
				if (((Component)lastGroundCollider).gameObject.layer == m_pieceLayer)
				{
					WearNTear componentInParent = ((Component)lastGroundCollider).GetComponentInParent<WearNTear>();
					if (Object.op_Implicit((Object)(object)componentInParent))
					{
						MaterialType materialType = componentInParent.m_materialType;
						MaterialType val = materialType;
						switch ((int)val)
						{
						case 0:
							m_cachedGroundType = GroundType.StructureWood;
							return;
						case 1:
							m_cachedGroundType = GroundType.StructureStone;
							return;
						case 3:
							m_cachedGroundType = GroundType.StructureHardWood;
							return;
						case 2:
							m_cachedGroundType = GroundType.StructureIron;
							return;
						}
					}
				}
				Heightmap component = ((Component)lastGroundCollider).GetComponent<Heightmap>();
				if ((Object)(object)component != (Object)null)
				{
					object value = Traverse.Create((object)component).Field("m_paintMask").GetValue();
					Texture2D val2 = (Texture2D)((value is Texture2D) ? value : null);
					_worldToVertexArgs[0] = Traverse.Create((object)player).Field("m_lastGroundPoint").GetValue() as Vector3?;
					AccessTools.Method(typeof(Heightmap), "WorldToVertex", (Type[])null, (Type[])null).Invoke(component, _worldToVertexArgs);
					int groundSensorRadius = _groundSensorRadius;
					Color val3 = default(Color);
					int num = Math.Max((int)_worldToVertexArgs[1] - groundSensorRadius, 0);
					int num2 = groundSensorRadius * 2;
					if (num2 + (int)_worldToVertexArgs[1] >= ((Texture)val2).width)
					{
						num2 = ((Texture)val2).width - num - 1;
					}
					int num3 = Math.Max((int)_worldToVertexArgs[2] - groundSensorRadius, 0);
					int num4 = groundSensorRadius * 2;
					if (num4 + (int)_worldToVertexArgs[2] >= ((Texture)val2).height)
					{
						num4 = ((Texture)val2).height - num3 - 1;
					}
					Color[] pixels = val2.GetPixels(num, num3, num2, num4, 0);
					Color[] array = pixels;
					foreach (Color val4 in array)
					{
						val3 += val4;
					}
					((Color)(ref val3))..ctor(val3.r / (float)pixels.Length, val3.g / (float)pixels.Length, val3.b / (float)pixels.Length);
					if (val3.b > 0.4f)
					{
						m_cachedGroundType = GroundType.PathStone;
						return;
					}
					if (val3.r > 0.4f)
					{
						m_cachedGroundType = GroundType.PathDirt;
						return;
					}
					if (val3.g > 0.4f)
					{
						m_cachedGroundType = GroundType.Cultivated;
						return;
					}
				}
			}
			m_cachedGroundType = GroundType.Untamed;
		}
	}
}
namespace SpeedyPaths.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("SpeedyPaths.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] speedyassets
		{
			get
			{
				object @object = ResourceManager.GetObject("speedyassets", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}