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";
}