using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using AutomaticPvPSwitch.Hooks; using AutomaticPvPSwitch.Models; using AutomaticPvPSwitch.Services; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HookDOTS.API; using HookDOTS.API.Attributes; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Network; using Stunlock.Core; using Unity.Collections; using Unity.Entities; using VampireCommandFramework; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Thiaz")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Automatically switches player ability builds when entering PvP combat.")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+987d784b37d3acf5846585e8e91165652afb95e3")] [assembly: AssemblyProduct("AutomaticPvPSwitch")] [assembly: AssemblyTitle("AutomaticPvPSwitch")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AutomaticPvPSwitch { [BepInPlugin("AutomaticPvPSwitch", "AutomaticPvPSwitch", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { internal static ManualLogSource Logger; private HookDOTS _hookDOTS; public override void Load() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown Logger = ((BasePlugin)this).Log; BuildStorage.Init(Paths.ConfigPath); CommandRegistry.RegisterAll(Assembly.GetExecutingAssembly()); _hookDOTS = new HookDOTS("AutomaticPvPSwitch", ((BasePlugin)this).Log); _hookDOTS.RegisterAnnotatedHooks(); ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutomaticPvPSwitch "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("1.1.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded."); } log.LogInfo(val); } public override bool Unload() { ((BasePlugin)this).Log.LogInfo((object)"AutomaticPvPSwitch unloaded."); return true; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "AutomaticPvPSwitch"; public const string PLUGIN_NAME = "AutomaticPvPSwitch"; public const string PLUGIN_VERSION = "1.1.0"; } } namespace AutomaticPvPSwitch.Services { public static class AbilityHelper { private const int BAR_TRAVEL = 2; private const int BAR_SPELL1 = 5; private const int BAR_SPELL2 = 6; private const int BAR_ULTIMATE = 7; private static readonly string[] SpellSchoolPrefixes = new string[6] { "AB_Blood_", "AB_Unholy_", "AB_Chaos_", "AB_Illusion_", "AB_Frost_", "AB_Storm_" }; public static PlayerBuild ReadCurrentBuild(EntityManager em, Entity charEntity) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) PlayerBuild playerBuild = new PlayerBuild(); if (!((EntityManager)(ref em)).HasBuffer(charEntity)) { return playerBuild; } DynamicBuffer buffer = ((EntityManager)(ref em)).GetBuffer(charEntity, false); int num = 0; for (int i = 0; i < buffer.Length; i++) { AbilityGroupSlotBuffer val = buffer[i]; if (!val.ShowOnBar) { continue; } if (num == 2 || num == 5 || num == 6 || num == 7) { int num2 = ReadSlotAbilityPrefab(em, val); switch (num) { case 2: playerBuild.Travel = num2; break; case 5: playerBuild.Spell1 = num2; break; case 6: playerBuild.Spell2 = num2; break; case 7: playerBuild.Ultimate = num2; break; } } num++; if (num > 7) { break; } } return playerBuild; } public static bool ApplyBuild(EntityManager em, Entity charEntity, PlayerBuild build, ulong platformId) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (build == null || build.IsEmpty) { return false; } World val = FindServerWorld(); if (val == null) { return false; } DebugEventsSystem existingSystemManaged = val.GetExistingSystemManaged(); if (existingSystemManaged == null) { Plugin.Logger.LogWarning((object)"[AbilityHelper] Could not get DebugEventsSystem"); return false; } BuffSpawnerSystemData bssd = BuffSpawnerSystemData.Create((ComponentSystemBase)(object)existingSystemManaged); PrefabCollectionSystem existingSystemManaged2 = val.GetExistingSystemManaged(); if (existingSystemManaged2 == null) { Plugin.Logger.LogWarning((object)"[AbilityHelper] Could not get PrefabCollectionSystem"); return false; } PrefabLookupMap prefabLookupMap = existingSystemManaged2._PrefabLookupMap; int num = 0; PlayerBuild playerBuild = ReadCurrentBuild(em, charEntity); if (build.Spell1 != 0 && build.Spell1 != playerBuild.Spell1 && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Spell1, primarySlot: true, "Spell1")) { num++; } if (build.Spell2 != 0 && build.Spell2 != playerBuild.Spell2 && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Spell2, primarySlot: false, "Spell2")) { num++; } if (build.Ultimate != 0 && build.Ultimate != playerBuild.Ultimate && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Ultimate, primarySlot: true, "Ultimate")) { num++; } if (build.Travel != 0 && build.Travel != playerBuild.Travel && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Travel, primarySlot: true, "Travel")) { num++; } return num > 0; } private static bool ApplyAbility(EntityManager em, BuffSpawnerSystemData bssd, PrefabLookupMap prefabMap, Entity charEntity, int abilityGuid, bool primarySlot, string label) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0066: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Invalid comparison between Unknown and I4 //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) PrefabGUID val = default(PrefabGUID); ((PrefabGUID)(ref val))..ctor(abilityGuid); NativeParallelHashMap assetDataLookup = prefabMap.AssetDataLookup; bool flag = default(bool); if (!assetDataLookup.ContainsKey(val)) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": PrefabGUID "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(abilityGuid); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" not found in game data, skipping."); } logger.LogWarning(val2); return false; } if (!IsAbilityUnlocked(em, charEntity, val, prefabMap)) { ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[AbilityHelper] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ResolveNameFromMap(prefabMap, abilityGuid)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" not unlocked, skipping."); } logger2.LogInfo(val3); return false; } try { ApplyVBloodAbilityResult val4 = VBloodAbilityUtilities.TryApplyVBloodAbility(em, bssd, prefabMap, charEntity, val, (VBloodAbilityApplyType)0, primarySlot); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(26, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[AbilityHelper] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ResolveNameFromMap(prefabMap, abilityGuid)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" result="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val4); } logger3.LogInfo(val3); return (int)val4 == 0; } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; bool flag2 = default(bool); BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[AbilityHelper] "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger4.LogError(val5); return false; } } private static bool IsAbilityUnlocked(EntityManager em, Entity charEntity, PrefabGUID ability, PrefabLookupMap prefabMap) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006b: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) try { if (!IsSpellSchoolAbility(prefabMap, ability)) { return true; } Entity val = charEntity; if (!((EntityManager)(ref em)).HasComponent(charEntity)) { if (!((EntityManager)(ref em)).HasComponent(charEntity)) { return true; } val = ((EntityManager)(ref em)).GetComponentData(charEntity).UserEntity; if (val == Entity.Null || !((EntityManager)(ref em)).HasComponent(val)) { return true; } } Entity entity = ((EntityManager)(ref em)).GetComponentData(val).ProgressionEntity._Entity; if (entity == Entity.Null || !((EntityManager)(ref em)).Exists(entity)) { return true; } if (!((EntityManager)(ref em)).HasBuffer(entity)) { return true; } DynamicBuffer buffer = ((EntityManager)(ref em)).GetBuffer(entity, false); for (int i = 0; i < buffer.Length; i++) { if (buffer[i].Ability._Value == ability._Value) { return true; } } return false; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] IsAbilityUnlocked check failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); return true; } } private static bool IsSpellSchoolAbility(PrefabLookupMap prefabMap, PrefabGUID ability) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown try { NativeParallelHashMap assetDataLookup = prefabMap.AssetDataLookup; ConvertedAssetData val = default(ConvertedAssetData); if (!assetDataLookup.TryGetValue(ability, ref val)) { return false; } string text = ((object)(FixedString128Bytes)(ref val.AssetName)).ToString(); string[] spellSchoolPrefixes = SpellSchoolPrefixes; foreach (string value in spellSchoolPrefixes) { if (text.StartsWith(value, StringComparison.Ordinal)) { return true; } } if (text.IndexOf("VeilOf", StringComparison.Ordinal) >= 0) { return true; } if (text.StartsWith("AB_", StringComparison.Ordinal) && !text.StartsWith("AB_Vampire_", StringComparison.Ordinal) && !text.StartsWith("AB_Interact_", StringComparison.Ordinal)) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(90, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] Unknown spell school prefix for: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" - may need to add to SpellSchoolPrefixes"); } logger.LogWarning(val2); } } catch { } return false; } private static string ResolveNameFromMap(PrefabLookupMap prefabMap, int guidHash) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) try { NativeParallelHashMap assetDataLookup = prefabMap.AssetDataLookup; ConvertedAssetData val = default(ConvertedAssetData); if (assetDataLookup.TryGetValue(new PrefabGUID(guidHash), ref val)) { string text = ((object)(FixedString128Bytes)(ref val.AssetName)).ToString(); if (!string.IsNullOrEmpty(text)) { return CleanAbilityName(text); } } } catch { } return $"#{guidHash}"; } private static int ReadSlotAbilityPrefab(EntityManager em, AbilityGroupSlotBuffer slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Entity entity = slot.GroupSlotEntity._Entity; if (entity == Entity.Null) { return 0; } if (!((EntityManager)(ref em)).HasComponent(entity)) { return 0; } AbilityGroupSlot componentData = ((EntityManager)(ref em)).GetComponentData(entity); Entity entity2 = componentData.StateEntity._Entity; if (entity2 != Entity.Null && ((EntityManager)(ref em)).HasComponent(entity2)) { return ((EntityManager)(ref em)).GetComponentData(entity2)._Value; } return componentData.GroupGuid._Value._Value; } private static World FindServerWorld() { Enumerator enumerator = World.All.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current != null && current.Name == "Server") { return current; } } return null; } public static string ResolveName(int guidHash) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) if (guidHash == 0) { return "(empty)"; } try { Enumerator enumerator = World.All.GetEnumerator(); ConvertedAssetData val3 = default(ConvertedAssetData); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current == null || current.Name != "Server") { continue; } Type val = Il2CppType.Of(); ComponentSystemBase existingSystemManaged = current.GetExistingSystemManaged(val); if (existingSystemManaged == null) { continue; } PrefabCollectionSystem val2 = ((Il2CppObjectBase)existingSystemManaged).TryCast(); if (val2 == null) { continue; } NativeParallelHashMap assetDataLookup = val2._PrefabLookupMap.AssetDataLookup; if (assetDataLookup.TryGetValue(new PrefabGUID(guidHash), ref val3)) { string text = ((object)(FixedString128Bytes)(ref val3.AssetName)).ToString(); if (!string.IsNullOrEmpty(text)) { return CleanAbilityName(text); } } } } catch { } return $"#{guidHash}"; } private static string CleanAbilityName(string raw) { if (raw.StartsWith("AB_Vampire_", StringComparison.Ordinal)) { raw = raw.Substring("AB_Vampire_".Length); } else if (raw.StartsWith("AB_", StringComparison.Ordinal)) { raw = raw.Substring("AB_".Length); } int num = raw.IndexOf("_AbilityGroup", StringComparison.OrdinalIgnoreCase); if (num > 0) { raw = raw.Substring(0, num); } return raw.Replace('_', ' '); } } public static class BuildCommands { private static readonly Dictionary _lastSwitchTime = new Dictionary(); private const int SWITCH_COOLDOWN_SECONDS = 10; [Command("pvp", null, null, "Switch to PvP build. Use '.pvp save' to save current abilities as PvP build.", null, false)] public static void PvpCommand(ChatCommandContext ctx, string action = null) { HandleBuildCommand(ctx, "pvp", action); } [Command("pvpswitch", null, null, "Admin: globally enable/disable automatic PvP build switching.", null, true)] public static void PvpSwitchCommand(ChatCommandContext ctx, string action = null, string playerName = null) { if (action != null && action.Equals("enable", StringComparison.OrdinalIgnoreCase)) { BuildStorage.SetGlobalEnabled(enabled: true); ctx.Reply("AutomaticPvPSwitch: enabled"); Plugin.Logger.LogInfo((object)"[PvPSwitch] Globally enabled by admin."); } else if (action != null && action.Equals("disable", StringComparison.OrdinalIgnoreCase)) { BuildStorage.SetGlobalEnabled(enabled: false); ctx.Reply("AutomaticPvPSwitch: disabled"); Plugin.Logger.LogInfo((object)"[PvPSwitch] Globally disabled by admin."); } else if (action != null && action.Equals("reset", StringComparison.OrdinalIgnoreCase)) { BuildStorage.ResetAllBuilds(); ctx.Reply("AutomaticPvPSwitch: all builds reset."); } else if (action != null && action.Equals("resetplayer", StringComparison.OrdinalIgnoreCase)) { ResetPlayer(ctx, playerName); } else { string text = (BuildStorage.GlobalEnabled ? "enabled" : "disabled"); ctx.Reply("AutomaticPvPSwitch: " + text + ". Use '.pvpswitch enable/disable/reset/resetplayer'."); } } [Command("pve", null, null, "Switch to PvE build. Use '.pve save' to save current abilities as PvE build.", null, false)] public static void PveCommand(ChatCommandContext ctx, string action = null) { HandleBuildCommand(ctx, "pve", action); } private static void HandleBuildCommand(ChatCommandContext ctx, string mode, string action) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0049: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) try { World val = FindServerWorld(); if (val == null) { ctx.Reply("Error: Server world not found."); return; } EntityManager entityManager = val.EntityManager; Entity senderUserEntity = ctx.Event.SenderUserEntity; User componentData = ((EntityManager)(ref entityManager)).GetComponentData(senderUserEntity); ulong platformId = componentData.PlatformId; Entity entity = componentData.LocalCharacter._Entity; if (entity == Entity.Null) { ctx.Reply("Error: Character entity not found."); } else if (action != null && action.Equals("save", StringComparison.OrdinalIgnoreCase)) { SaveBuild(ctx, entityManager, entity, platformId, mode); } else if (action != null && action.Equals("enable", StringComparison.OrdinalIgnoreCase)) { BuildStorage.SetAutoEnabled(platformId, enabled: true); ctx.Reply("Auto-switch: enabled"); } else if (action != null && action.Equals("disable", StringComparison.OrdinalIgnoreCase)) { BuildStorage.SetAutoEnabled(platformId, enabled: false); ctx.Reply("Auto-switch: disabled"); } else { LoadBuild(ctx, entityManager, entity, platformId, mode); } } catch (Exception ex) { ctx.Reply("Error: " + ex.Message); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(18, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[BuildCommands] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(mode); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger.LogError(val2); } } private static void SaveBuild(ChatCommandContext ctx, EntityManager em, Entity charEntity, ulong platformId, string mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlayerBuild playerBuild = AbilityHelper.ReadCurrentBuild(em, charEntity); if (playerBuild.IsEmpty) { ctx.Reply("No abilities found on your bar. Make sure you have spells equipped."); return; } BuildStorage.SaveBuild(platformId, mode, playerBuild); ctx.Reply(mode.ToUpperInvariant() + " build saved."); } private static void LoadBuild(ChatCommandContext ctx, EntityManager em, Entity charEntity, ulong platformId, string mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if (PvPBuffDetector.HasPvPBuff(em, charEntity)) { ctx.Reply("Can't switch build while PvP debuff is active."); return; } if (_lastSwitchTime.TryGetValue(platformId, out var value)) { double totalSeconds = (DateTime.UtcNow - value).TotalSeconds; if (totalSeconds < 10.0) { int value2 = (int)Math.Ceiling(10.0 - totalSeconds); ctx.Reply($"Cooldown: {value2}s remaining."); return; } } PlayerBuild build = BuildStorage.GetBuild(platformId, mode); if (build == null || build.IsEmpty) { ctx.Reply($"No {mode.ToUpperInvariant()} build saved. Use '.{mode} save' first."); } else if (AbilityHelper.ApplyBuild(em, charEntity, build, platformId)) { _lastSwitchTime[platformId] = DateTime.UtcNow; ctx.Reply("Switched to " + mode.ToUpperInvariant() + " build."); } else { ctx.Reply("Already using " + mode.ToUpperInvariant() + " build (no changes needed)."); } } private static void ResetPlayer(ChatCommandContext ctx, string playerName) { //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown if (string.IsNullOrEmpty(playerName)) { ctx.Reply("Usage: .pvpswitch resetplayer "); return; } bool flag = default(bool); try { World val = FindServerWorld(); if (val == null) { ctx.Reply("Error: Server world not found."); return; } EntityManager entityManager = val.EntityManager; ComponentType val2 = default(ComponentType); ((ComponentType)(ref val2))..ctor(Il2CppType.Of(), (AccessMode)1); EntityQueryBuilder val3 = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2)); EntityQueryBuilder val4 = ((EntityQueryBuilder)(ref val3)).AddAll(val2); EntityQuery val5 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val4); ((EntityQueryBuilder)(ref val4)).Dispose(); NativeArray val6 = ((EntityQuery)(ref val5)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); try { for (int i = 0; i < val6.Length; i++) { User componentData = ((EntityManager)(ref entityManager)).GetComponentData(val6[i]); if (((object)(FixedString64Bytes)(ref componentData.CharacterName)).ToString().Equals(playerName, StringComparison.OrdinalIgnoreCase)) { ulong platformId = componentData.PlatformId; Entity entity = componentData.LocalCharacter._Entity; BuildStorage.RemovePlayer(platformId); _lastSwitchTime.Remove(platformId); int num = 0; if (entity != Entity.Null && componentData.IsConnected) { num = RemoveVBloodAbilities(entityManager, entity); } ctx.Reply((num > 0) ? $"Player '{playerName}': builds cleared, {num} abilities removed." : ("Player '" + playerName + "': builds cleared.")); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[PvPSwitch] Admin reset player '"); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(playerName); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("' (pid="); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(platformId); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(")."); } logger.LogInfo(val7); return; } } } finally { val6.Dispose(); } ctx.Reply("Player '" + playerName + "' not found."); } catch (Exception ex) { ctx.Reply("Error: " + ex.Message); ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val8 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("[PvPSwitch] resetplayer: "); ((BepInExLogInterpolatedStringHandler)val8).AppendFormatted(ex); } logger2.LogError(val8); } } private static int RemoveVBloodAbilities(EntityManager em, Entity charEntity) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0067: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).HasBuffer(charEntity)) { return 0; } DynamicBuffer buffer = ((EntityManager)(ref em)).GetBuffer(charEntity, false); List list = new List(buffer.Length); for (int i = 0; i < buffer.Length; i++) { PrefabGUID activeAbility = buffer[i].ActiveAbility; if (activeAbility._Value != 0) { list.Add(activeAbility); } } bool flag = default(bool); foreach (PrefabGUID item in list) { try { VBloodAbilityUtilities.TryRemoveVBloodAbility(em, charEntity, item); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(52, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildCommands] TryRemoveVBloodAbility failed for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item._Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } return list.Count; } private static World FindServerWorld() { Enumerator enumerator = World.All.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current != null && current.Name == "Server") { return current; } } return null; } } public static class BuildStorage { private static readonly Dictionary _builds = new Dictionary(); private static string _filePath; private static string _globalFilePath; public static bool GlobalEnabled { get; private set; } = true; public static int PvpBuildCount { get; private set; } public static void Init(string configDir) { string text = Path.Combine(configDir, "AutomaticPvPSwitch"); Directory.CreateDirectory(text); _filePath = Path.Combine(text, "builds.json"); _globalFilePath = Path.Combine(text, "global_enabled"); LoadGlobalState(); Load(); } public static bool HasBuild(ulong platformId, string mode) { if (!_builds.TryGetValue(platformId, out var value)) { return false; } PlayerBuild playerBuild = ((mode == "pvp") ? value.Pvp : value.Pve); if (playerBuild != null) { return !playerBuild.IsEmpty; } return false; } public static PlayerBuild GetBuild(ulong platformId, string mode) { if (!_builds.TryGetValue(platformId, out var value)) { return null; } if (!(mode == "pvp")) { return value.Pve; } return value.Pvp; } public static void RemovePlayer(ulong platformId) { if (_builds.TryGetValue(platformId, out var value)) { if (value.Pvp != null && !value.Pvp.IsEmpty) { PvpBuildCount--; } _builds.Remove(platformId); Save(); } } public static void ResetAllBuilds() { _builds.Clear(); PvpBuildCount = 0; Save(); Plugin.Logger.LogInfo((object)"[BuildStorage] All builds reset."); } public static void SetGlobalEnabled(bool enabled) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown GlobalEnabled = enabled; try { File.WriteAllText(_globalFilePath, enabled ? "1" : "0"); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Global state save failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogError(val); } } private static void LoadGlobalState() { if (!File.Exists(_globalFilePath)) { return; } try { GlobalEnabled = File.ReadAllText(_globalFilePath).Trim() != "0"; } catch { } } public static bool IsAutoEnabled(ulong platformId) { if (!_builds.TryGetValue(platformId, out var value)) { return true; } return value.AutoEnabled; } public static void SetAutoEnabled(ulong platformId, bool enabled) { if (!_builds.TryGetValue(platformId, out var value)) { value = new PlayerData(); _builds[platformId] = value; } value.AutoEnabled = enabled; Save(); } public static void SaveBuild(ulong platformId, string mode, PlayerBuild build) { if (!_builds.TryGetValue(platformId, out var value)) { value = new PlayerData(); _builds[platformId] = value; } if (mode == "pvp") { bool flag = value.Pvp != null && !value.Pvp.IsEmpty; bool flag2 = build != null && !build.IsEmpty; value.Pvp = build; if (!flag && flag2) { PvpBuildCount++; } else if (flag && !flag2) { PvpBuildCount--; } } else { value.Pve = build; } Save(); } private static void Load() { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown if (!File.Exists(_filePath)) { return; } bool flag = default(bool); try { foreach (KeyValuePair item in SimpleJson.Deserialize(File.ReadAllText(_filePath))) { if (ulong.TryParse(item.Key, out var result)) { _builds[result] = item.Value; } } PvpBuildCount = 0; foreach (PlayerData value in _builds.Values) { if (value.Pvp != null && !value.Pvp.IsEmpty) { PvpBuildCount++; } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Loaded "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_builds.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" players, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(PvpBuildCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" PvP builds."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[BuildStorage] Load failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogError(val2); } } private static void Save() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown try { string contents = SimpleJson.Serialize(_builds); string text = _filePath + ".tmp"; File.WriteAllText(text, contents); File.Move(text, _filePath, overwrite: true); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Save failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogError(val); } } } internal static class SimpleJson { public static string Serialize(Dictionary data) { StringBuilder stringBuilder = new StringBuilder(256); stringBuilder.Append('{'); bool flag = true; foreach (KeyValuePair datum in data) { if (!flag) { stringBuilder.Append(','); } stringBuilder.Append('"').Append(datum.Key).Append("\":{"); bool flag2 = true; if (datum.Value.Pvp != null) { stringBuilder.Append("\"pvp\":"); SerializeBuild(stringBuilder, datum.Value.Pvp); flag2 = false; } if (datum.Value.Pve != null) { if (!flag2) { stringBuilder.Append(','); } stringBuilder.Append("\"pve\":"); SerializeBuild(stringBuilder, datum.Value.Pve); flag2 = false; } if (!datum.Value.AutoEnabled) { if (!flag2) { stringBuilder.Append(','); } stringBuilder.Append("\"auto\":false"); } stringBuilder.Append('}'); flag = false; } stringBuilder.Append('}'); return stringBuilder.ToString(); } private static void SerializeBuild(StringBuilder sb, PlayerBuild b) { sb.Append('{'); sb.Append("\"s1\":").Append(b.Spell1); sb.Append(",\"s2\":").Append(b.Spell2); sb.Append(",\"ult\":").Append(b.Ultimate); sb.Append(",\"tr\":").Append(b.Travel); sb.Append('}'); } public static Dictionary Deserialize(string json) { Dictionary dictionary = new Dictionary(); int idx = 0; SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] != '{') { return dictionary; } idx++; while (idx < json.Length) { SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] == '}') { break; } if (json[idx] == ',') { idx++; continue; } string key = ReadString(json, ref idx); SkipWhitespace(json, ref idx); if (idx < json.Length && json[idx] == ':') { idx++; } PlayerData value = ReadPlayerData(json, ref idx); dictionary[key] = value; } return dictionary; } private static PlayerData ReadPlayerData(string json, ref int idx) { PlayerData playerData = new PlayerData(); SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] != '{') { return playerData; } idx++; while (idx < json.Length) { SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] == '}') { idx++; break; } if (json[idx] == ',') { idx++; continue; } string text = ReadString(json, ref idx); SkipWhitespace(json, ref idx); if (idx < json.Length && json[idx] == ':') { idx++; } if (text == "auto") { bool autoEnabled = ReadBool(json, ref idx); playerData.AutoEnabled = autoEnabled; continue; } PlayerBuild playerBuild = ReadBuild(json, ref idx); if (text == "pvp") { playerData.Pvp = playerBuild; } else if (text == "pve") { playerData.Pve = playerBuild; } } return playerData; } private static PlayerBuild ReadBuild(string json, ref int idx) { PlayerBuild playerBuild = new PlayerBuild(); SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] != '{') { return playerBuild; } idx++; while (idx < json.Length) { SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] == '}') { idx++; break; } if (json[idx] == ',') { idx++; continue; } string text = ReadString(json, ref idx); SkipWhitespace(json, ref idx); if (idx < json.Length && json[idx] == ':') { idx++; } int num = ReadInt(json, ref idx); switch (text) { case "s1": playerBuild.Spell1 = num; break; case "s2": playerBuild.Spell2 = num; break; case "ult": playerBuild.Ultimate = num; break; case "tr": playerBuild.Travel = num; break; } } return playerBuild; } private static string ReadString(string json, ref int idx) { SkipWhitespace(json, ref idx); if (idx >= json.Length || json[idx] != '"') { return ""; } idx++; int num = idx; while (idx < json.Length && json[idx] != '"') { if (json[idx] == '\\') { idx++; } idx++; } int num2 = num; string result = json.Substring(num2, idx - num2); if (idx < json.Length) { idx++; } return result; } private static bool ReadBool(string json, ref int idx) { SkipWhitespace(json, ref idx); if (idx + 4 <= json.Length && json.Substring(idx, 4) == "true") { idx += 4; return true; } if (idx + 5 <= json.Length && json.Substring(idx, 5) == "false") { idx += 5; return false; } return true; } private static int ReadInt(string json, ref int idx) { SkipWhitespace(json, ref idx); int num = idx; if (idx < json.Length && json[idx] == '-') { idx++; } while (idx < json.Length && char.IsDigit(json[idx])) { idx++; } if (num == idx) { return 0; } int num2 = num; if (!int.TryParse(json.Substring(num2, idx - num2), out var result)) { return 0; } return result; } private static void SkipWhitespace(string json, ref int idx) { while (idx < json.Length && char.IsWhiteSpace(json[idx])) { idx++; } } } } namespace AutomaticPvPSwitch.Models { public class PlayerBuild { public int Spell1 { get; set; } public int Spell2 { get; set; } public int Ultimate { get; set; } public int Travel { get; set; } public bool IsEmpty { get { if (Spell1 == 0 && Spell2 == 0 && Ultimate == 0) { return Travel == 0; } return false; } } } public class PlayerData { public PlayerBuild Pvp { get; set; } public PlayerBuild Pve { get; set; } public bool AutoEnabled { get; set; } = true; } } namespace AutomaticPvPSwitch.Hooks { public static class PvPBuffDetector { private const int PVP_COMBAT_BUFF = 697095869; private static World _serverWorld; private static BuffSystem_Spawn_Server _system; private static bool _logged; [EcsSystemUpdatePrefix(typeof(BuffSystem_Spawn_Server), true)] public static void Prefix() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (!BuildStorage.GlobalEnabled || BuildStorage.PvpBuildCount == 0) { return; } BuffSystem_Spawn_Server system = GetSystem(); if (system == null) { return; } if (!_logged) { Plugin.Logger.LogInfo((object)"[PvPBuffDetector] HookDOTS prefix active on BuffSystem_Spawn_Server."); _logged = true; } EntityQuery _query_401358634_; bool flag = default(bool); try { _query_401358634_ = system.__query_401358634_0; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] Spawn query unavailable (game update?): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogError(val); return; } if (((EntityQuery)(ref _query_401358634_)).IsEmpty) { return; } EntityManager entityManager = _serverWorld.EntityManager; NativeArray val2 = default(NativeArray); try { val2 = ((EntityQuery)(ref _query_401358634_)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); for (int i = 0; i < val2.Length; i++) { Entity val3 = val2[i]; if (((EntityManager)(ref entityManager)).HasComponent(val3) && ((EntityManager)(ref entityManager)).GetComponentData(val3)._Value == 697095869 && ((EntityManager)(ref entityManager)).HasComponent(val3)) { Entity owner = ((EntityManager)(ref entityManager)).GetComponentData(val3).Owner; TrySwitchToPvP(entityManager, owner); } } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } logger2.LogError(val); } finally { if (val2.IsCreated) { val2.Dispose(); } } } private static void TrySwitchToPvP(EntityManager em, Entity charEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (charEntity == Entity.Null || !((EntityManager)(ref em)).Exists(charEntity) || !((EntityManager)(ref em)).HasComponent(charEntity)) { return; } Entity userEntity = ((EntityManager)(ref em)).GetComponentData(charEntity).UserEntity; if (userEntity == Entity.Null || !((EntityManager)(ref em)).Exists(userEntity)) { return; } User componentData = ((EntityManager)(ref em)).GetComponentData(userEntity); if (!componentData.IsConnected) { return; } ulong platformId = componentData.PlatformId; if (!BuildStorage.IsAutoEnabled(platformId)) { return; } PlayerBuild build = BuildStorage.GetBuild(platformId, "pvp"); if (build != null && !build.IsEmpty && AbilityHelper.ApplyBuild(em, charEntity, build, platformId)) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] Auto-switched "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(componentData.CharacterName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" to PvP build."); } logger.LogInfo(val); } } public static bool HasPvPBuff(EntityManager em, Entity charEntity) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0022: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).HasBuffer(charEntity)) { return false; } DynamicBuffer buffer = ((EntityManager)(ref em)).GetBuffer(charEntity, false); for (int i = 0; i < buffer.Length; i++) { if (buffer[i].PrefabGuid._Value == 697095869) { return true; } } return false; } private static BuffSystem_Spawn_Server GetSystem() { if (_serverWorld != null && _serverWorld.IsCreated && _system != null) { return _system; } _serverWorld = null; _system = null; Enumerator enumerator = World.All.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current != null && current.IsCreated && current.Name == "Server") { _serverWorld = current; break; } } if (_serverWorld == null) { return null; } _system = _serverWorld.GetExistingSystemManaged(); return _system; } } }