Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CheatTagEnforcement v0.1.1
plugins/Blackheim.CheatTagEnforcement.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Blackheim.CheatTagEnforcement")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1")] [assembly: AssemblyProduct("Blackheim.CheatTagEnforcement")] [assembly: AssemblyTitle("Blackheim.CheatTagEnforcement")] [assembly: AssemblyVersion("0.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 Blackheim.CheatTagEnforcement { [BepInPlugin("blackheim.cheattagenforcement", "Blackheim Cheat Tag Enforcement", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private sealed class Session { internal float Started; internal float LastPong = Time.realtimeSinceStartup; internal float NextHello; internal float NextPing; internal float KickAt; internal bool Accepted; internal bool Kicked; internal string Challenge = ""; } [HarmonyPatch(typeof(Inventory), "Changed", new Type[] { typeof(bool), typeof(bool) })] private static class InventoryChanged { private static void Postfix(Inventory __instance) { if ((Object)(object)Player.m_localPlayer != (Object)null && __instance == ((Humanoid)Player.m_localPlayer).GetInventory()) { Instance?.CleanLocal(); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class Spawned { [HarmonyPriority(800)] private static void Prefix(Player __instance) { if (__instance == Player.m_localPlayer) { Instance?.CleanLocal(); } } } [HarmonyPatch(typeof(Player), "Save")] private static class Saving { [HarmonyPriority(800)] private static void Prefix(Player __instance) { if (__instance == Player.m_localPlayer) { Instance?.CleanLocal(); } } } public const string Id = "blackheim.cheattagenforcement"; public const string Release = "0.1.1"; private const string Hello = "BlackheimCT_Hello_v1"; private const string Policy = "BlackheimCT_Policy_v1"; private const string Report = "BlackheimCT_Report_v1"; private const string Notice = "BlackheimCT_Notice_v1"; private const string Ping = "BlackheimCT_Ping_v1"; private const string Pong = "BlackheimCT_Pong_v1"; private const string Failure = "BlackheimCT_Failure_v1"; internal static Plugin Instance; private Harmony harmony; private readonly Dictionary<ZNetPeer, Session> sessions = new Dictionary<ZNetPeer, Session>(); private ZNetPeer policyPeer; private bool sweeping; private float nextSweep; private string banner = ""; private float bannerUntil; private int pendingStacks; private string pendingDescription = ""; private float nextClientReport; private static readonly MethodInfo KickPeer = AccessTools.Method(typeof(ZNet), "InternalKick", new Type[1] { typeof(ZNetPeer) }, (Type[])null); private bool ActiveClient { get { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && policyPeer != null) { return policyPeer == ZNet.instance.GetServerPeer(); } return false; } } private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (KickPeer == null) { throw new MissingMethodException("Required ZNet.InternalKick(ZNetPeer) unavailable"); } Instance = this; harmony = new Harmony("blackheim.cheattagenforcement"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Blackheim tag enforcement 0.1.1 loaded: native tagged items are deleted on the dedicated server or a connected policy client; carried-item reports trigger warning and kick."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } Instance = null; } private void Update() { if ((Object)(object)ZNet.instance == (Object)null) { sessions.Clear(); policyPeer = null; pendingStacks = 0; pendingDescription = ""; return; } ZNetPeer[] peers = ZNet.instance.GetPeers().ToArray(); ZNetPeer[] array = sessions.Keys.Where((ZNetPeer p) => !peers.Contains(p)).ToArray(); foreach (ZNetPeer key in array) { sessions.Remove(key); } array = peers; foreach (ZNetPeer val in array) { if (!sessions.ContainsKey(val)) { Register(val); } if (!val.IsReady()) { continue; } Session session = sessions[val]; float realtimeSinceStartup = Time.realtimeSinceStartup; if (session.Started == 0f) { session.Started = realtimeSinceStartup; } if (ZNet.instance.IsServer()) { if ((!session.Accepted && realtimeSinceStartup - session.Started > 30f) || (session.Accepted && realtimeSinceStartup - session.LastPong > 40f)) { ScheduleKick(val, "Required Blackheim enforcement client is missing or stopped responding.", 0f); } if (session.Accepted && realtimeSinceStartup >= session.NextPing && session.Challenge.Length == 0) { session.Challenge = Guid.NewGuid().ToString("N"); val.m_rpc.Invoke("BlackheimCT_Ping_v1", new object[1] { session.Challenge }); session.NextPing = realtimeSinceStartup + 10f; } if (!session.Kicked && session.KickAt > 0f && realtimeSinceStartup >= session.KickAt) { session.Kicked = true; KickPeer.Invoke(ZNet.instance, new object[1] { val }); ((BaseUnityPlugin)this).Logger.LogWarning((object)("[kick] connection=" + val.m_uid + " player=" + Safe(val.m_playerName))); } } else if (val == ZNet.instance.GetServerPeer() && realtimeSinceStartup >= session.NextHello) { val.m_rpc.Invoke("BlackheimCT_Hello_v1", new object[1] { "0.1.1" }); session.NextHello = realtimeSinceStartup + 5f; } } if (ActiveClient && pendingStacks > 0 && Time.realtimeSinceStartup >= nextClientReport) { CleanLocal(); if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)Game.instance != (Object)null) { try { Game.instance.SavePlayerProfile(false, true); policyPeer.m_rpc.Invoke("BlackheimCT_Report_v1", new object[2] { pendingStacks, pendingDescription }); pendingStacks = 0; pendingDescription = ""; } catch (Exception error) { FailClient("Could not save cleaned inventory", error); } nextClientReport = Time.realtimeSinceStartup + 1f; } } if (Time.realtimeSinceStartup >= nextSweep) { nextSweep = Time.realtimeSinceStartup + 2f; if (ActiveClient) { CleanLocal(); } if (ZNet.instance.IsDedicated() || ActiveClient) { SweepOwnedWorld(); } } } private void Register(ZNetPeer peer) { sessions[peer] = new Session(); peer.m_rpc.Register<string>("BlackheimCT_Hello_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string version) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && rpc == peer.m_rpc) { if (version != "0.1.1") { ScheduleKick(peer, "Install Blackheim Cheat Tag Enforcement 0.1.1", 0f); } else { Session session = sessions[peer]; if (!session.Accepted) { session.LastPong = Time.realtimeSinceStartup; } session.Accepted = true; rpc.Invoke("BlackheimCT_Policy_v1", new object[1] { "0.1.1" }); } } }); peer.m_rpc.Register<string>("BlackheimCT_Policy_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string version) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && !(version != "0.1.1") && peer == ZNet.instance.GetServerPeer()) { policyPeer = peer; CleanLocal(); } }); peer.m_rpc.Register<string>("BlackheimCT_Ping_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string nonce) { if (ActiveClient && peer == policyPeer) { rpc.Invoke("BlackheimCT_Pong_v1", new object[1] { nonce }); } }); peer.m_rpc.Register<string>("BlackheimCT_Pong_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string nonce) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { Session session = sessions[peer]; if (session.Accepted && session.Challenge.Length > 0 && nonce == session.Challenge) { session.LastPong = Time.realtimeSinceStartup; session.Challenge = ""; } } }); peer.m_rpc.Register<int, string>("BlackheimCT_Report_v1", (Action<ZRpc, int, string>)delegate(ZRpc rpc, int count, string description) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && sessions[peer].Accepted && count > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[client-deletion-report] connection=" + peer.m_uid + " player=" + Safe(peer.m_playerName) + " stacks=" + count + " items=" + Safe(description))); Type type = AccessTools.TypeByName("ValheimEnforcer.modules.character.FullSyncSchedulerBehaviour"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "RequestFullSync", (Type[])null, (Type[])null)); try { if (methodInfo != null && methodInfo.IsStatic) { methodInfo.Invoke(null, new object[1] { peer }); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Full-sync request unavailable; client save sent, server persistence must be checked."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Full-sync request failed: " + ex.Message)); } ScheduleKick(peer, "Cheat-tagged items removed. You will be disconnected. Rejoin with clean items only.", 8f); } }); peer.m_rpc.Register<string>("BlackheimCT_Notice_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string message) { if (ActiveClient && peer == policyPeer) { ShowNotice(message); } }); peer.m_rpc.Register<string>("BlackheimCT_Failure_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string reason) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && sessions[peer].Accepted) { ((BaseUnityPlugin)this).Logger.LogError((object)("[client-enforcement-failure] connection=" + peer.m_uid + " " + Safe(reason))); ScheduleKick(peer, "Item enforcement could not complete. Connection refused until the client is repaired.", 0f); } }); } private void ScheduleKick(ZNetPeer peer, string reason, float delay) { if (sessions.TryGetValue(peer, out var value) && !(value.KickAt > 0f)) { peer.m_rpc.Invoke("BlackheimCT_Notice_v1", new object[1] { reason }); value.KickAt = Time.realtimeSinceStartup + Math.Max(0.01f, delay); ((BaseUnityPlugin)this).Logger.LogWarning((object)("[warning] connection=" + peer.m_uid + " player=" + Safe(peer.m_playerName) + " " + reason)); } } private void ShowNotice(string message) { banner = message; bannerUntil = Time.realtimeSinceStartup + 45f; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } ((BaseUnityPlugin)this).Logger.LogWarning((object)message); } private void OnGUI() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (banner.Length != 0 && !(Time.realtimeSinceStartup > bannerUntil)) { GUI.Box(new Rect(20f, 20f, (float)Math.Min(Screen.width - 40, 850), 75f), "BLACKHEIM ENFORCEMENT\n" + banner); } } internal void CleanLocal() { if (ActiveClient && !((Object)(object)Player.m_localPlayer == (Object)null)) { CleanInventory(((Humanoid)Player.m_localPlayer).GetInventory(), "carried", Player.m_localPlayer); } } private void CleanInventory(Inventory inventory, string location, Player player = null) { if (sweeping || inventory == null) { return; } sweeping = true; try { ItemData[] array = (from i in inventory.GetAllItems() where i.m_cheated select i).ToArray(); foreach (ItemData val in array) { Receipt(val, location); if ((Object)(object)player != (Object)null && val.m_equipped) { ((Humanoid)player).UnequipItem(val, false); } inventory.RemoveItem(val); if ((Object)(object)player != (Object)null) { pendingStacks++; if (pendingDescription.Length < 1400) { pendingDescription = pendingDescription + ItemName(val) + " x" + val.m_stack + "; "; } } } if ((Object)(object)player != (Object)null && pendingStacks > 0) { ShowNotice("Cheat-tagged items deleted. This server removes tagged items and kicks on possession."); } } catch (Exception ex) { if ((Object)(object)player != (Object)null) { FailClient("Could not remove tagged inventory items", ex); } else { ((BaseUnityPlugin)this).Logger.LogError((object)("[world-enforcement-failure] " + Safe(location) + " " + ex.Message)); } } finally { sweeping = false; } } private void FailClient(string reason, Exception error) { ((BaseUnityPlugin)this).Logger.LogError((object)(reason + ": " + error.Message)); ShowNotice("Item enforcement failed; disconnecting. " + reason); if (ActiveClient) { policyPeer.m_rpc.Invoke("BlackheimCT_Failure_v1", new object[1] { reason }); } } private void SweepOwnedWorld() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) Container[] array = Object.FindObjectsByType<Container>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Container val in array) { ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { CleanInventory(val.GetInventory(), "container " + ((object)((Component)val).transform.position/*cast due to .constrained prefix*/).ToString()); } } ItemDrop[] array2 = Object.FindObjectsByType<ItemDrop>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (ItemDrop val2 in array2) { ZNetView component2 = ((Component)val2).GetComponent<ZNetView>(); if (!((Object)(object)component2 == (Object)null) && component2.IsValid() && component2.IsOwner()) { if (!val2.m_itemData.m_cheated) { val2.Load(); } if (val2.m_itemData.m_cheated) { Receipt(val2.m_itemData, "ground " + ((object)((Component)val2).transform.position/*cast due to .constrained prefix*/).ToString()); component2.Destroy(); } } } ItemStand[] array3 = Object.FindObjectsByType<ItemStand>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (ItemStand val3 in array3) { ZNetView component3 = ((Component)val3).GetComponent<ZNetView>(); if (!((Object)(object)component3 == (Object)null) && component3.IsValid() && component3.IsOwner() && val3.HaveAttachment()) { ItemData val4 = ReadAttachment(component3.GetZDO(), val3.GetAttachedItem(), -1); if (val4 != null && val4.m_cheated) { Receipt(val4, "item stand " + ((object)((Component)val3).transform.position/*cast due to .constrained prefix*/).ToString()); val3.DestroyAttachment(); } } } ArmorStand[] array4 = Object.FindObjectsByType<ArmorStand>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (ArmorStand val5 in array4) { ZNetView component4 = ((Component)val5).GetComponent<ZNetView>(); if ((Object)(object)component4 == (Object)null || !component4.IsValid() || !component4.IsOwner()) { continue; } for (int j = 0; j < val5.m_slots.Count; j++) { if (val5.HaveAttachment(j)) { ItemData val6 = ReadAttachment(component4.GetZDO(), val5.GetAttachedItem(j), j); if (val6 != null && val6.m_cheated) { Receipt(val6, "armor stand " + ((object)((Component)val5).transform.position/*cast due to .constrained prefix*/).ToString() + " slot=" + j); val5.DestroyAttachment(j); } } } } } private static ItemData ReadAttachment(ZDO record, int prefabHash, int slot) { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(prefabHash) : null); ItemDrop val2 = (((Object)(object)val == (Object)null) ? null : val.GetComponent<ItemDrop>()); if ((Object)(object)val2 == (Object)null) { return null; } ItemData obj = val2.m_itemData.Clone(); obj.m_dropPrefab = val; ItemDrop.LoadFromZDO(obj, record, slot); return obj; } private void Receipt(ItemData item, string location) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); item.Save(val); string text = DateTime.UtcNow.ToString("O") + "\t" + Safe(location) + "\t" + Safe(ItemName(item)) + "\t" + item.m_stack + "\t" + Convert.ToBase64String(val.GetArray()); string text2 = Path.Combine(Paths.ConfigPath, "BlackheimCheatTagEnforcement"); Directory.CreateDirectory(text2); File.AppendAllText(Path.Combine(text2, "deleted-" + DateTime.UtcNow.ToString("yyyy-MM-dd") + ".tsv"), text + Environment.NewLine); ((BaseUnityPlugin)this).Logger.LogWarning((object)("[delete-tagged] " + Safe(location) + " " + Safe(ItemName(item)) + " x" + item.m_stack)); } private static string ItemName(ItemData item) { object obj; if (!((Object)(object)item.m_dropPrefab != (Object)null)) { obj = item.m_shared?.m_name; if (obj == null) { return "unknown"; } } else { obj = ((Object)item.m_dropPrefab).name; } return (string)obj; } private static string Safe(string text) { return (text ?? "").Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ') .Substring(0, Math.Min((text ?? "").Length, 1600)); } } }