Decompiled source of swampmansrevengeonphilyprealpha v0.0.8
BepInEx/plugins/EndskApi.dll
Decompiled a year agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using System.Text.Json.Serialization; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BoosterImplants; using CellMenu; using EndskApi.Api; using EndskApi.Enums.EnemyKill; using EndskApi.Enums.Menus; using EndskApi.Information.Configs; using EndskApi.Information.EnemyKill; using EndskApi.Information.Menus; using EndskApi.Information.WeaponSwitcher; using EndskApi.Manager; using EndskApi.Manager.Internal; using EndskApi.NativePatches; using EndskApi.Patches.Checkpoint; using EndskApi.Patches.EndLevel; using EndskApi.Patches.Init; using EndskApi.Patches.StartLevel; using EndskApi.Scripts; using Enemies; using GTFO.API; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("EndskApi")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")] [assembly: AssemblyProduct("EndskApi")] [assembly: AssemblyTitle("EndskApi")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace EndskApi { [BepInPlugin("Endskill.EndskApi", "EndskApi", "1.0.1")] public class BepInExLoader : BasePlugin { public const string MODNAME = "EndskApi"; public const string AUTHOR = "Endskill"; public const string GUID = "Endskill.EndskApi"; public const string VERSION = "1.0.1"; public static Harmony Harmony { get; private set; } public static ConfigFile ConfigLoader { get; private set; } public override void Load() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown LogManager.SetLogger(((BasePlugin)this).Log); LogManager._debugMessagesActive = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.").Value; ConfigLoader = ((BasePlugin)this).Config; ClassInjector.RegisterTypeInIl2Cpp<BaseMenu>(); ClassInjector.RegisterTypeInIl2Cpp<MainMenu>(); Harmony = new Harmony("Endskill.EndskApi"); } } [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "EndskApi"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitc03396b-dirty-master"; public const string SemVer = "1.0.0+gitc03396b-dirty-master"; public const string GitRevShort = "c03396b-dirty"; public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const bool GitIsDirty = true; } } namespace EndskApi.Util { public static class MtfoUtils { public static string CustomPath { get; private set; } public static string Version { get; private set; } public static bool PluginExists { get; private set; } static MtfoUtils() { CustomPath = string.Empty; Version = string.Empty; PluginExists = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info)) { return; } PluginExists = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => !x.IsDynamic && x.Location == info.Location); if (assembly == null) { throw new Exception("couldn't locate the MTFO assembly"); } Type[] types = assembly.GetTypes(); Type type = types.FirstOrDefault((Type x) => x.Name == "ConfigManager"); Type type2 = types.FirstOrDefault((Type x) => x.Name == "MTFO"); if (type2 == null) { throw new Exception("couldn't locate MTFO's EntryPoint"); } if (type == null) { throw new Exception("couldn't locate MTFO's ConfigManager"); } FieldInfo field = type2.GetField("VERSION", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); if (field == null) { throw new Exception("couldn't locate MTFO's Version"); } if (field2 == null) { throw new Exception("couldn't locate MTFO's CustomPath"); } CustomPath = (string)field2.GetValue(null); Version = (string)field.GetValue(null); Type type3 = types.FirstOrDefault((Type x) => x.Name == "HotReloader"); } catch (Exception ex) { LogManager.Error(ex.ToString()); } } } } namespace EndskApi.Scripts { public class BaseMenu : MonoBehaviour { protected static string _currentGeomorph; protected static bool _guiInitialized = false; protected static GUIStyle _normalStyle; protected static GUIStyle _titleStyle; protected static readonly float _menuX = 30f; protected static readonly float _menuY = (float)(Screen.height / 2) - 100f; protected MenuStates _currentState; protected List<Tool> _tools; public string PageTitle { get; set; } protected static string PageTitlePostfix { get; set; } = ""; public BaseMenu(IntPtr intPtr) : base(intPtr) { _tools = new List<Tool>(); } protected virtual void Update() { if (_currentState != MenuStates.Deactivated) { DefaultCheatsInputCheck(); } } protected virtual void OnGUI() { if (_currentState == MenuStates.Active) { CreateUi(_tools, PageTitle); } } public virtual void SetState(MenuStates newState) { _currentState = newState; if (newState == MenuStates.Deactivated) { ((Behaviour)this).enabled = false; } else { ((Behaviour)this).enabled = true; } } protected void DefaultCheatsInputCheck() { foreach (Tool tool in _tools) { if (tool.CheckInput.CheckKeyDown()) { tool.UseTool(tool); } } } [HideFromIl2Cpp] public static void CreateUi(List<Tool> cheats, string pageTitle) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_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) //IL_0030: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if (!_guiInitialized) { _titleStyle = new GUIStyle(GUI.skin.GetStyle("label")) { fontSize = 22 }; _normalStyle = new GUIStyle(GUI.skin.GetStyle("label")) { fontSize = 20 }; _guiInitialized = true; } GUI.contentColor = Color.white; GUI.Label(new Rect(_menuX, _menuY - 25f, 400f, 30f), _currentGeomorph, _normalStyle); GUI.Label(new Rect(_menuX, _menuY, 400f, 30f), pageTitle + PageTitlePostfix, _titleStyle); float num = 25f; foreach (Tool cheat in cheats) { GUI.Label(new Rect(_menuX, _menuY + num, 400f, 30f), cheat.ToString(), _normalStyle); num += 22f; } } [HideFromIl2Cpp] protected void ToggleTool(Tool cheat) { cheat.Toggle(); } } internal class MainMenu : BaseMenu { private Dictionary<Tool, BaseMenu> _toolToMenuMap; private List<BaseMenu> _unknownMenus; private List<IExtendedTool> _middleMouseClickTools = new List<IExtendedTool>(); private List<IExtendedTool> _timedTools = new List<IExtendedTool>(); private List<Tool> _hiddenTools = new List<Tool>(); private float _lastToolActive = Time.time; private (uint enemyId, string enemyName)[] _enemyNamesIdMap; private int _currentEnemyIndex = 0; private int _keypadCounter; [HideFromIl2Cpp] internal static MainMenu Instance { get; private set; } public int CurrentEnemyIndex { get { return _currentEnemyIndex; } set { if (value >= _enemyNamesIdMap.Count() || value < 0) { value = _currentEnemyIndex; } _currentEnemyIndex = value; BaseMenu.PageTitlePostfix = ": " + _enemyNamesIdMap[value].enemyName; } } public MainMenu(IntPtr intPtr) : base(intPtr) { base.PageTitle = "MainMenu"; _toolToMenuMap = new Dictionary<Tool, BaseMenu>(); _unknownMenus = new List<BaseMenu>(); _currentState = MenuStates.HiddenAndActive; Instance = this; } public void Awake() { Il2CppArrayBase<EnemyDataBlock> allBlocks = GameDataBlockBase<EnemyDataBlock>.GetAllBlocks(); _enemyNamesIdMap = new(uint, string)[allBlocks.Count]; for (int i = 0; i < allBlocks.Count; i++) { _enemyNamesIdMap[i] = (((GameDataBlockBase<EnemyDataBlock>)(object)allBlocks[i]).persistentID, ((GameDataBlockBase<EnemyDataBlock>)(object)allBlocks[i]).name); } CurrentEnemyIndex = 0; } [HideFromIl2Cpp] public void ActivateUnknownMenu<TScript>(TScript menu) where TScript : BaseMenu { MenuToggleUpdated(null, newToggle: false); _currentState = MenuStates.HiddenAndActive; _unknownMenus.Add(menu); } [HideFromIl2Cpp] public void AddPage(string ToolName, BaseMenu menu) { AddPage(new Tool(ToolName, GetFreeKeypadInput(), isToggle: false, base.ToggleTool, MenuToggleUpdated), menu); } [HideFromIl2Cpp] public void AddPage(Tool Tool, BaseMenu menu) { _toolToMenuMap.Add(Tool, menu); _tools.Add(Tool); _currentState = MenuStates.Active; } [HideFromIl2Cpp] public void AddMiddleMouseClickTool(IExtendedTool Tool) { _middleMouseClickTools.Add(Tool); } public void RemoveMiddleMouseClickTool(IExtendedTool Tool) { _middleMouseClickTools.Remove(Tool); } public void AddTimedTool(IExtendedTool tool) { _timedTools.Add(tool); } public void RemoveTimedTool(IExtendedTool tool) { _timedTools.Remove(tool); } public void AddHiddenTool(Tool tool) { _hiddenTools.Add(tool); } public void RemoveHiddenTool(Tool tool) { _hiddenTools.Remove(tool); } protected override void Update() { if (Input.GetKeyDown((KeyCode)277)) { if (_currentState == MenuStates.Active || _currentState == MenuStates.HiddenAndActive) { _currentState = MenuStates.Deactivated; } else { _currentState = MenuStates.Active; } foreach (KeyValuePair<Tool, BaseMenu> item in _toolToMenuMap) { item.Key.CurrentToggleState = false; item.Value.SetState(MenuStates.Deactivated); } } if (_currentState != MenuStates.Deactivated) { foreach (Tool hiddenTool in _hiddenTools) { if (hiddenTool.CheckInput.CheckKeyDown()) { hiddenTool.UseTool(hiddenTool); } } } base.Update(); MainMenuSpecificUpdate(); } private void MainMenuSpecificUpdate() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 if (Input.GetKeyDown((KeyCode)275)) { CurrentEnemyIndex++; } if (Input.GetKeyDown((KeyCode)276)) { CurrentEnemyIndex--; } if (Input.GetMouseButtonDown(2)) { foreach (IExtendedTool middleMouseClickTool in _middleMouseClickTools) { middleMouseClickTool.ExtraToolAction(GetInformationPackage(middleMouseClickTool.InformationId)); } } if (!(_lastToolActive < Time.time)) { return; } foreach (IExtendedTool timedTool in _timedTools) { timedTool.ExtraToolAction(GetInformationPackage(timedTool.InformationId)); } if ((int)GameStateManager.CurrentStateName == 10) { BaseMenu._currentGeomorph = ((Object)((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode.m_area.m_geomorph).name; } else { BaseMenu._currentGeomorph = ""; } _lastToolActive = Time.time + 0.25f; } private object GetInformationPackage(InformationId id) { return id switch { InformationId.None => null, InformationId.EnemyId => _enemyNamesIdMap[CurrentEnemyIndex], _ => null, }; } private void MenuToggleUpdated(Tool Tool, bool newToggle) { foreach (BaseMenu unknownMenu in _unknownMenus) { unknownMenu.SetState(MenuStates.Deactivated); } _unknownMenus.Clear(); foreach (KeyValuePair<Tool, BaseMenu> item in _toolToMenuMap) { if (item.Key.Equals(Tool)) { item.Value.SetState((!newToggle) ? MenuStates.Deactivated : MenuStates.Active); item.Key.CurrentToggleState = newToggle; } else { item.Key.CurrentToggleState = false; item.Value.SetState(MenuStates.Deactivated); } } _currentState = (_toolToMenuMap.Any<KeyValuePair<Tool, BaseMenu>>((KeyValuePair<Tool, BaseMenu> it) => it.Key.CurrentToggleState) ? MenuStates.HiddenAndActive : MenuStates.Active); } private InputTool GetFreeKeypadInput() { _keypadCounter++; switch (_keypadCounter) { case 1: return MenuInputProvider.KeyPad1; case 2: return MenuInputProvider.KeyPad2; case 3: return MenuInputProvider.KeyPad3; case 4: return MenuInputProvider.KeyPad4; case 5: return MenuInputProvider.KeyPad5; case 6: return MenuInputProvider.KeyPad6; case 7: return MenuInputProvider.KeyPad7; case 8: return MenuInputProvider.KeyPad8; case 9: return MenuInputProvider.KeyPad9; default: LogManager.Error("There are no free Keypad keys, for the added Menu page!\nPlease ask @Endskill#4992 to finally do his Page system."); throw new IndexOutOfRangeException("There are no free keypad keys to add this specific page."); } } } } namespace EndskApi.Patches.StartLevel { [HarmonyPatch(typeof(GS_InLevel))] internal class GsInLevelPatches { [HarmonyPatch("Enter")] [HarmonyPostfix] public static void EnterLevelPostfix() { LevelApi.InvokeStartLevelCallbacks(); } } } namespace EndskApi.Patches.Init { [HarmonyPatch(typeof(GuiManager))] internal class GUIManagerPatches { [HarmonyPatch("Setup")] [HarmonyPrefix] [HarmonyWrapSafe] public static void SetupPrefix() { InitApi.InvokeInitCallbacks(); } } [HarmonyPatch(typeof(CM_PageRundown_New))] internal class PageRundownNewPatches { [HarmonyPatch("PlaceRundown")] [HarmonyPostfix] [HarmonyWrapSafe] public static void PlaceRundownPostFix() { InitApi.InvokeInitCallbacks(); } } } namespace EndskApi.Patches.EnemyKill { [HarmonyBefore(new string[] { "Endskill.EndskApi", "com.dak.DamageNumbers" })] [HarmonyPatch(typeof(Dam_EnemyDamageBase))] internal class EnemyDamageBasePatches { [HarmonyPatch("ReceiveMeleeDamage")] [HarmonyPrefix] public static void MeleePrefix(Dam_EnemyDamageBase __instance, out bool __state) { __state = ((Agent)__instance.Owner).Alive; } [HarmonyPatch("ReceiveMeleeDamage")] [HarmonyPostfix] public static void MeleePostfix(Dam_EnemyDamageBase __instance, bool __state, pFullDamageData data) { if (!__state) { return; } Agent val = default(Agent); ((pAgent)(ref data.source)).TryGet(ref val); if (val != null) { PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>(); DamageDistributionAddDamageDealt(__instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax)); if (!((Agent)__instance.Owner).Alive) { EnemyDied(__instance.Owner, val2, LastHitType.Melee); } } } [HarmonyPatch("ReceiveBulletDamage")] [HarmonyPrefix] public static void BulletPrefix(Dam_EnemyDamageBase __instance, out bool __state) { __state = ((Agent)__instance.Owner).Alive; } [HarmonyPatch("ReceiveBulletDamage")] [HarmonyPostfix] public static void BulletPostfix(Dam_EnemyDamageBase __instance, bool __state, pBulletDamageData data) { if (!__state) { return; } Agent val = default(Agent); ((pAgent)(ref data.source)).TryGet(ref val); if (val != null) { PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>(); DamageDistributionAddDamageDealt(__instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax)); if (!((Agent)__instance.Owner).Alive) { EnemyDied(__instance.Owner, val2, LastHitType.ShootyWeapon); } } } [HarmonyPatch("ExplosionDamage")] [HarmonyPrefix] public static void ExplosionPrefix(Dam_EnemyDamageBase __instance, out bool __state) { __state = ((Agent)__instance.Owner).Alive && SNet.IsMaster; } [HarmonyPatch("ExplosionDamage")] [HarmonyPostfix] public static void ExplosionPostfix(Dam_EnemyDamageBase __instance, bool __state) { if (__state && !((Agent)__instance.Owner).Alive) { EnemyDied(__instance.Owner, null, LastHitType.Explosion); } } private static void DamageDistributionAddDamageDealt(EnemyAgent hitEnemy, PlayerAgent damageDealer, float damageDealt) { Dictionary<string, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<string, EnemyKillDistribution>>("EndskApi"); if (!instance.ContainsKey(((Object)hitEnemy).name)) { EnemyKillDistribution enemyKillDistribution = new EnemyKillDistribution(hitEnemy); enemyKillDistribution.AddDamageDealtByPlayerAgent(damageDealer, damageDealt); instance[((Object)hitEnemy).name] = enemyKillDistribution; } else { instance[((Object)hitEnemy).name].AddDamageDealtByPlayerAgent(damageDealer, damageDealt); } } private static void EnemyDied(EnemyAgent hitEnemy, PlayerAgent lastHit, LastHitType lastHitType) { Dictionary<string, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<string, EnemyKillDistribution>>("EndskApi"); if (instance.TryGetValue(((Object)hitEnemy).name, out var value)) { value.LastHitDealtBy = lastHit; value.lastHitType = lastHitType; EnemyKillApi.InvokeEnemyKilledCallbacks(value); } } } } namespace EndskApi.Patches.EndLevel { [HarmonyPatch(typeof(GS_AfterLevel))] public class GsAfterLevelPatches { [HarmonyPatch("CleanupAfterExpedition")] [HarmonyPrefix] public static void CleanupPrefix() { LevelApi.InvokeEndLevelCallbacks(); } } } namespace EndskApi.Patches.Checkpoint { [HarmonyPatch(typeof(CheckpointManager))] internal static class CheckpointManagerPatches { [HarmonyPatch("StoreCheckpoint")] [HarmonyPostfix] public static void StoreCheackpointPostfix() { CheckpointApi.InvokeCheckpointReachedCallbacks(); NetworkManager.SendCheckpointReached(); } [HarmonyPatch("OnLevelCleanup")] [HarmonyPostfix] public static void OnLevelCleanupPostfix() { CheckpointApi.InvokeCheckpointCleanupCallbacks(); NetworkManager.SendCheckpointCleanups(); } } } namespace EndskApi.NativePatches { internal class EnemyDamageBaseNatviePatches { public unsafe delegate void ReceiveMeleeDamage(IntPtr _this, pFullDamageData* data, Il2CppMethodInfo* methodInfo); public unsafe delegate void ReceiveBulletDamage(IntPtr _this, pBulletDamageData* data, Il2CppMethodInfo* methodInfo); public unsafe delegate void ReceiveExplosionDamage(IntPtr _this, pExplosionDamageData* data, Il2CppMethodInfo* methodInfo); public unsafe delegate bool ProcessReceivedDamage(IntPtr _this, float damage, IntPtr _damageSource, Vector3* position, Vector3* direction, ES_HitreactType hitreact, [MarshalAs(UnmanagedType.I1)] bool tryForceHitreact, int limbID, float staggerDamageMulti, DamageNoiseLevel damageNoiseLevel, Il2CppMethodInfo* methodInfo); private readonly ReceiveMeleeDamage _originalReceiveMeleeDamage; private readonly ReceiveBulletDamage _originalReceiveBulletDamage; private readonly ReceiveExplosionDamage _originalReceiveExplosionDamage; private readonly ProcessReceivedDamage _originalProcessReceivedDamage; private readonly List<INativeDetour> _detours; public unsafe EnemyDamageBaseNatviePatches() { _detours = new List<INativeDetour> { INativeDetour.CreateAndApply<ReceiveMeleeDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveMeleeDamage", "System.Void", false, new string[1] { "pFullDamageData" }), (ReceiveMeleeDamage)ReceiveMeleeDamagePatch, ref _originalReceiveMeleeDamage), INativeDetour.CreateAndApply<ReceiveBulletDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveBulletDamage", "System.Void", false, new string[1] { "pBulletDamageData" }), (ReceiveBulletDamage)ReceiveBulletDamagePatch, ref _originalReceiveBulletDamage), INativeDetour.CreateAndApply<ReceiveExplosionDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveExplosionDamage", "System.Void", false, new string[1] { "pExplosionDamageData" }), (ReceiveExplosionDamage)ReceiveExplosionDamagePatch, ref _originalReceiveExplosionDamage) }; } public unsafe void ReceiveMeleeDamagePatch(IntPtr _this, pFullDamageData* data, Il2CppMethodInfo* methodInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown try { Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this); EnemyDamageBasePatchApi.InvokeReceiveMeleePrefix(instance, ref Unsafe.AsRef<pFullDamageData>((void*)data)); _originalReceiveMeleeDamage(_this, data, methodInfo); EnemyDamageBasePatchApi.InvokeReceiveMeleePostfix(instance, ref Unsafe.AsRef<pFullDamageData>((void*)data)); } catch (Exception ex) { LogManager.Error(ex); LogManager.Error(ex.StackTrace); } } public unsafe void ReceiveBulletDamagePatch(IntPtr _this, pBulletDamageData* data, Il2CppMethodInfo* methodInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown try { Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this); EnemyDamageBasePatchApi.InvokeReceiveBulletPrefix(instance, ref Unsafe.AsRef<pBulletDamageData>((void*)data)); _originalReceiveBulletDamage(_this, data, methodInfo); EnemyDamageBasePatchApi.InvokeReceiveBulletPostfix(instance, ref Unsafe.AsRef<pBulletDamageData>((void*)data)); } catch (Exception ex) { LogManager.Error(ex); LogManager.Error(ex.StackTrace); } } public unsafe void ReceiveExplosionDamagePatch(IntPtr _this, pExplosionDamageData* data, Il2CppMethodInfo* methodInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown try { Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this); EnemyDamageBasePatchApi.InvokeReceiveExplosionPrefix(instance, ref Unsafe.AsRef<pExplosionDamageData>((void*)data)); _originalReceiveExplosionDamage(_this, data, methodInfo); EnemyDamageBasePatchApi.InvokeReceiveExplosionPostfix(instance, ref Unsafe.AsRef<pExplosionDamageData>((void*)data)); } catch (Exception ex) { LogManager.Error(ex); LogManager.Error(ex.StackTrace); } } } } namespace EndskApi.Manager { public static class LogManager { private static ManualLogSource logger; internal static bool _debugMessagesActive; internal static void SetLogger(ManualLogSource log) { logger = log; } public static void Verbose(object msg) { if (_debugMessagesActive) { logger.LogInfo(msg); } } public static void Debug(object msg) { if (_debugMessagesActive) { logger.LogDebug(msg); } } public static void Message(object msg) { if (_debugMessagesActive) { logger.LogMessage(msg); } } public static void Error(object msg) { logger.LogError(msg); } public static void Warn(object msg) { logger.LogWarning(msg); } } public static class MenuInputProvider { private static MenuRebinding _bindings; public static InputTool F1 => new InputTool(_bindings.F1, $": [{_bindings.F1}]"); public static InputTool F2 => new InputTool(_bindings.F2, $": [{_bindings.F2}]"); public static InputTool F3 => new InputTool(_bindings.F3, $": [{_bindings.F3}]"); public static InputTool F4 => new InputTool(_bindings.F4, $": [{_bindings.F4}]"); public static InputTool F5 => new InputTool(_bindings.F5, $": [{_bindings.F5}]"); public static InputTool F6 => new InputTool(_bindings.F6, $": [{_bindings.F6}]"); public static InputTool F7 => new InputTool(_bindings.F7, $": [{_bindings.F7}]"); public static InputTool F8 => new InputTool(_bindings.F8, $": [{_bindings.F8}]"); public static InputTool F9 => new InputTool(_bindings.F9, $": [{_bindings.F9}]"); public static InputTool F10 => new InputTool(_bindings.F10, $": [{_bindings.F10}]"); public static InputTool KeyPad1 => new InputTool(_bindings.Keypad1, $": [{_bindings.Keypad1}]"); public static InputTool KeyPad2 => new InputTool(_bindings.Keypad2, $": [{_bindings.Keypad2}]"); public static InputTool KeyPad3 => new InputTool(_bindings.Keypad3, $": [{_bindings.Keypad3}]"); public static InputTool KeyPad4 => new InputTool(_bindings.Keypad4, $": [{_bindings.Keypad4}]"); public static InputTool KeyPad5 => new InputTool(_bindings.Keypad5, $": [{_bindings.Keypad5}]"); public static InputTool KeyPad6 => new InputTool(_bindings.Keypad6, $": [{_bindings.Keypad6}]"); public static InputTool KeyPad7 => new InputTool(_bindings.Keypad7, $": [{_bindings.Keypad7}]"); public static InputTool KeyPad8 => new InputTool(_bindings.Keypad8, $": [{_bindings.Keypad8}]"); public static InputTool KeyPad9 => new InputTool(_bindings.Keypad9, $": [{_bindings.Keypad9}]"); static MenuInputProvider() { JsonSerializerOptions options = new JsonSerializerOptions { Converters = { (JsonConverter)new JsonStringEnumConverter() } }; ConfigEntry<string> val = BepInExLoader.ConfigLoader.Bind<string>("MenuApi", "KeyBindings", "{\"F1\":\"F1\",\"F2\":\"F2\",\"F3\":\"F3\",\"F4\":\"F4\",\"F5\":\"F5\",\"F6\":\"F6\",\"F7\":\"F7\",\"F8\":\"F8\",\"F9\":\"F9\",\"F10\":\"None\",\"Keypad1\":\"Keypad1\",\"Keypad2\":\"Keypad2\",\"Keypad3\":\"Keypad3\",\"Keypad4\":\"Keypad4\",\"Keypad5\":\"Keypad5\",\"Keypad6\":\"Keypad6\",\"Keypad7\":\"Keypad7\",\"Keypad8\":\"Keypad8\",\"Keypad9\":\"Keypad9\"}", "You can remap keys here."); _bindings = JsonSerializer.Deserialize<MenuRebinding>(val.Value, options); } } } namespace EndskApi.Manager.Internal { public class InformationCache { private readonly Dictionary<string, Dictionary<object, object>> _cache; public static InformationCache Instance { get; } = new InformationCache(); public InformationCache() { _cache = new Dictionary<string, Dictionary<object, object>>(); } public void SaveInformation(object key, object info, string mod) { GetCacheOfMod(mod)[key] = info; } public T GetInformation<T>(object key, string mod) { if (GetCacheOfMod(mod).TryGetValue(key, out object value)) { return (T)value; } LogManager.Error($"There was no information with the key {key}"); throw new KeyNotFoundException($"There was no information with the key {key}!"); } public bool TryGetInformation<T>(object key, out T info, string mod, bool logNotFound = true) { if (GetCacheOfMod(mod).TryGetValue(key, out object value)) { info = (T)value; return true; } if (logNotFound) { LogManager.Warn($"There was no informaiton with the key {key}"); } info = default(T); return false; } public void RemoveInformation(object key, string mod) { if (TryGetCacheOfMod(mod, out Dictionary<object, object> cache)) { cache.Remove(key); } } public bool ContainsKey(object key, string mod) { Dictionary<object, object> cache; return TryGetCacheOfMod(mod, out cache) && cache.ContainsKey(key); } private Dictionary<object, object> GetCacheOfMod(string mod) { if (!_cache.TryGetValue(mod, out Dictionary<object, object> value)) { value = new Dictionary<object, object>(); _cache[mod] = value; } return value; } private bool TryGetCacheOfMod(string mod, out Dictionary<object, object> cache) { return _cache.TryGetValue(mod, out cache); } } internal static class NetworkManager { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct DummyStruct { } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct EquipGearStruct { } private const string _sendCheckpointReachedKey = "CheckpointHasBeenReached"; private const string _sendCheckpointCleanupKey = "CheckpointCleanup"; public static void Setup() { NetworkAPI.RegisterEvent<DummyStruct>("CheckpointCleanup", (Action<ulong, DummyStruct>)ReceiveCheckpointCleanup); NetworkAPI.RegisterEvent<DummyStruct>("CheckpointHasBeenReached", (Action<ulong, DummyStruct>)ReceiveCheckpointReached); } private static void ReceiveCheckpointReached(ulong snetPlayer, DummyStruct _) { CheckpointApi.InvokeCheckpointReachedCallbacks(); } private static void ReceiveCheckpointCleanup(ulong snetPlayer, DummyStruct _) { CheckpointApi.InvokeCheckpointCleanupCallbacks(); } public static void SendCheckpointReached() { NetworkAPI.InvokeEvent<DummyStruct>("CheckpointHasBeenReached", default(DummyStruct), (SNet_ChannelType)2); } public static void SendCheckpointCleanups() { NetworkAPI.InvokeEvent<DummyStruct>("CheckpointCleanup", default(DummyStruct), (SNet_ChannelType)2); } public static void SendEquipGear(GearInfo info) { } } } namespace EndskApi.Information.WeaponSwitcher { public class GearInfo { public InventorySlotAmmo InventorySlotAmmo { get; set; } public InventorySlot Slot { get; set; } public AmmoType AmmoType { get; set; } public GearIDRange GearId { get; set; } public int AmmunitionInMagazine { get; set; } public GearInfo(GearIDRange gearId, int ammunitionInMagazine, InventorySlotAmmo inventorySlotAmmo) { //IL_0022: 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) GearId = gearId; AmmunitionInMagazine = ammunitionInMagazine; InventorySlotAmmo = inventorySlotAmmo; AmmoType = inventorySlotAmmo.AmmoType; Slot = inventorySlotAmmo.Slot; } } } namespace EndskApi.Information.Menus { public interface IExtendedTool { Action<object> ExtraToolAction { get; set; } InformationId InformationId { get; set; } } public class InputTool { public KeyCode InputKey { get; set; } public string Postfix { get; set; } public InputTool(KeyCode inputKey, string postfix) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) InputKey = inputKey; Postfix = postfix; } public virtual bool CheckKeyDown() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Input.GetKeyDown(InputKey); } public virtual bool CheckKey() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Input.GetKey(InputKey); } } public class Tool { public string Text { get; set; } public string TextPostfix { get; set; } public InputTool CheckInput { get; } public Action<Tool> UseTool { get; set; } public Action<Tool, bool> OnToggleUpdate { get; set; } public bool IsToggle { get; set; } public bool CurrentToggleState { get; set; } public object Extra { get; set; } public Tool() { } public Tool(string text, InputTool input, Action<Tool, bool> onToggleUpdate, bool startState) { Text = text; CheckInput = input; IsToggle = true; UseTool = ToggleTool; OnToggleUpdate = onToggleUpdate; CurrentToggleState = startState; } public Tool(string text, InputTool input, bool isToggle, Action<Tool> useCheat, Action<Tool, bool> onToggleUpdate = null, bool currentToggleState = false) { Text = text; CheckInput = input; IsToggle = isToggle; UseTool = useCheat; OnToggleUpdate = onToggleUpdate; CurrentToggleState = currentToggleState; } public void Toggle() { CurrentToggleState = !CurrentToggleState; OnToggleUpdate?.Invoke(this, CurrentToggleState); } public override string ToString() { if (IsToggle) { return $"{Text}{TextPostfix}{CheckInput.Postfix} {(CurrentToggleState ? "ON" : "OFF")}"; } return Text + TextPostfix + CheckInput.Postfix; } private static void ToggleTool(Tool tool) { tool.Toggle(); } } public class ToolExtended : Tool, IExtendedTool { public Action<object> ExtraToolAction { get; set; } public InformationId InformationId { get; set; } public ToolExtended(string text, InputTool input, bool isToggle, Action<Tool> useCheat, Action<object> extraCheatAction, Action<Tool, bool> onToggleUpdate = null, bool currentToggleState = false, InformationId infoId = InformationId.None) : base(text, input, isToggle, useCheat, onToggleUpdate, currentToggleState) { ExtraToolAction = extraCheatAction; InformationId = infoId; } public override string ToString() { return base.ToString(); } } } namespace EndskApi.Information.EnemyKill { public class EnemyKillDistribution { public EnemyAgent KilledEnemyAgent { get; set; } public List<DamageDistribution> DamageDistributions { get; set; } public PlayerAgent LastHitDealtBy { get; set; } public LastHitType lastHitType { get; set; } public EnemyKillDistribution(EnemyAgent agentToKill) { KilledEnemyAgent = agentToKill; DamageDistributions = new List<DamageDistribution>(); } public void AddDamageDealtByPlayerAgent(PlayerAgent agent, float damage) { DamageDistributions.Add(new DamageDistribution(agent.PlayerSlotIndex, damage)); } public float GetDamageDealtBySnet(SNet_Player player) { int slotIndex = player.PlayerSlotIndex(); return DamageDistributions.Where((DamageDistribution it) => it.PlayerSlotIndex == slotIndex).Sum((DamageDistribution it) => it.DamageDealt); } } public class DamageDistribution { public int PlayerSlotIndex { get; set; } public float DamageDealt { get; set; } public DamageDistribution(int slotIndex, float damage) { PlayerSlotIndex = slotIndex; DamageDealt = damage; } } } namespace EndskApi.Information.Configs { public class MenuRebinding { public KeyCode F1 { get; set; } public KeyCode F2 { get; set; } public KeyCode F3 { get; set; } public KeyCode F4 { get; set; } public KeyCode F5 { get; set; } public KeyCode F6 { get; set; } public KeyCode F7 { get; set; } public KeyCode F8 { get; set; } public KeyCode F9 { get; set; } public KeyCode F10 { get; set; } public KeyCode Keypad1 { get; set; } public KeyCode Keypad2 { get; set; } public KeyCode Keypad3 { get; set; } public KeyCode Keypad4 { get; set; } public KeyCode Keypad5 { get; set; } public KeyCode Keypad6 { get; set; } public KeyCode Keypad7 { get; set; } public KeyCode Keypad8 { get; set; } public KeyCode Keypad9 { get; set; } public MenuRebinding() { F1 = (KeyCode)282; F2 = (KeyCode)283; F3 = (KeyCode)284; F4 = (KeyCode)285; F5 = (KeyCode)286; F6 = (KeyCode)287; F7 = (KeyCode)288; F8 = (KeyCode)289; F9 = (KeyCode)290; Keypad1 = (KeyCode)257; Keypad2 = (KeyCode)258; Keypad3 = (KeyCode)259; Keypad4 = (KeyCode)260; Keypad5 = (KeyCode)261; Keypad6 = (KeyCode)262; Keypad7 = (KeyCode)263; Keypad8 = (KeyCode)264; Keypad9 = (KeyCode)265; } } } namespace EndskApi.Information.BoosterInfo { public class BoosterCondition { public string Name { get; set; } public string ShortName { get; set; } public BoosterCondition Condition { get; set; } } public class BoosterEffect { public string Name { get; set; } public string ShortName { get; set; } public AgentModifier Effect { get; set; } public float Value { get; set; } public BoosterEffect(string name, string shortName, AgentModifier effect, float value) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) Name = name; ShortName = shortName; Effect = effect; Value = value; } } public interface IBooster { object Category { get; set; } List<BoosterEffect> BoosterEffects { get; set; } List<BoosterCondition> BoosterConditions { get; set; } } } namespace EndskApi.Enums.Menus { public enum InformationId { None, EnemyId } public enum MenuStates { Active, HiddenAndActive, Deactivated } } namespace EndskApi.Enums.EnemyKill { public enum LastHitType { Melee, ShootyWeapon, Explosion } } namespace EndskApi.Enums.Booster { public enum CustomBoosterCategory { Muted, Bold, Aggressive, NotAccessible } public enum CustomBoosterModifiers { None = 0, RegenerationCap = 1, RegenerationSpeed = 2, HealSupport = 3, ReviveSpeedSupport = 4, ReviveStartHealthSupport = 5, MeleeResistance = 6, ProjectileResistance = 7, InfectionResistance = 8, PistolDamage = 50, SMGDamage = 51, DMRDamage = 52, AssaultRifleDamage = 53, CarbineDamage = 54, AutoPistolDamage = 55, HELDamage = 56, ShotgunDamage = 58, RevolverDamage = 59, SniperDamage = 60, BurstCannonDamage = 61, MachineGunDamage = 62, MachinePistolDamage = 63, RifleDamage = 64, BurstRifleDamage = 65, DoubleTapRifle = 66, BullpupRifleDamage = 67, CombatShotgunDamage = 68, ChokeModShotgunDamage = 69, StandardWeaponDamage = 70, SpecialWeaponDamage = 71, GlueStrength = 100, GlueEfficiency = 101, SentryGunSpeed = 102, SentryGunDamage = 103, SentryGunLongRangeDamage = 104, SentryGunShortRangeDamage = 105, TripMineDamage = 106, ScannerRechargeSpeed = 107, AmmoSupport = 108, HackingProficiency = 150, ComputerProcessingSpeed = 151, InitialAmmoStandard = 152, InitialAmmoSpecial = 153, InitialAmmoTool = 154, FogRepellerEffect = 155, GlowstickEffect = 156, BioscanSpeed = 157, MeleeDamage = 200 } } namespace EndskApi.Api { public static class CacheApi { private const string GlobalCache = "GlobalCache"; internal const string InternalCache = "EndskApi"; private static readonly InformationCache _informationCache; static CacheApi() { _informationCache = InformationCache.Instance; } public static void SaveInformation(object key, object info, string mod = "GlobalCache") { _informationCache.SaveInformation(key, info, mod); } public static void SaveInstance<T>(T info, string mod = "GlobalCache") { SaveInformation(typeof(T), info, mod); } public static T GetInformation<T>(object key, string mod = "GlobalCache") { return _informationCache.GetInformation<T>(key, mod); } public static T GetInstance<T>(string mod = "GlobalCache") { return GetInformation<T>(typeof(T), mod); } public static bool TryGetInformation<T>(object key, out T information, string mod = "GlobalCache", bool logNotFound = true) { return _informationCache.TryGetInformation<T>(key, out information, mod, logNotFound); } public static bool TryGetInstance<T>(out T information, string mod = "GlobalCache", bool logNotFound = true) { return _informationCache.TryGetInformation<T>(typeof(T), out information, mod, logNotFound); } public static void RemoveInformation(object key, string mod = "GlobalCache") { _informationCache.RemoveInformation(key, mod); } public static void RemoveInstance<T>(string mod = "GlobalCache") { RemoveInformation(typeof(T), mod); } public static bool ContainsKey(object key, string mod = "GlobalCache") { return _informationCache.ContainsKey(key, mod); } public static InformationCache GetInformationCache() { return _informationCache; } } public static class CheckpointApi { private const string CheckpointReachedKey = "CheckpointReachedKey"; private const string CleanupCheckpointKey = "CheckpointCleanupKey"; static CheckpointApi() { BepInExLoader.Harmony.PatchAll(typeof(CheckpointManagerPatches)); } public static void AddCheckpointReachedCallback(Action callBack) { if (!CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false)) { information = new List<Action>(); CacheApi.SaveInformation("CheckpointReachedKey", information, "EndskApi"); } information.Add(callBack); } public static void AddCheckpointCleanupCallback(Action callBack) { if (!CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false)) { information = new List<Action>(); CacheApi.SaveInformation("CheckpointCleanupKey", information, "EndskApi"); } information.Add(callBack); } public static void RemoveCheckpointReachedCallback(Action callBack) { if (CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false)) { information.Remove(callBack); } } public static void RemoveCheckpointCleanupCallback(Action callBack) { if (CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false)) { information.Remove(callBack); } } internal static void InvokeCheckpointReachedCallbacks() { if (!CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action item in information) { item(); } } internal static void InvokeCheckpointCleanupCallbacks() { if (!CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action item in information) { item(); } } } public static class EnemyDamageBasePatchApi { public delegate void ReceiveMeleeDamage(Dam_EnemyDamageBase instance, ref pFullDamageData data); public delegate void ReceiveBulletDamage(Dam_EnemyDamageBase instance, ref pBulletDamageData data); public delegate void ReceiveExplosionDamage(Dam_EnemyDamageBase instance, ref pExplosionDamageData data); public delegate void ProcessReceivedDamage(Dam_EnemyDamageBase instance, ref float damage, Agent damageSource, ref Vector3 position, ref Vector3 direction, ref ES_HitreactType hitreact, ref bool tryForceHitreact, ref int limbID, ref float staggerDamageMulti, ref DamageNoiseLevel damageNoiseLevel); private static bool _setup; internal static List<(double, ReceiveMeleeDamage)> MeleePrefixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveMeleeDamage)>>("EndskApi"); } set { CacheApi.SaveInstance(value, "EndskApi"); } } internal static List<(double, ReceiveMeleeDamage)> MeleePostfixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveMeleeDamage)>>(); } set { CacheApi.SaveInstance(value); } } internal static List<(double, ReceiveBulletDamage)> BulletPrefixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveBulletDamage)>>("EndskApi"); } set { CacheApi.SaveInstance(value, "EndskApi"); } } internal static List<(double, ReceiveBulletDamage)> BulletPostfixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveBulletDamage)>>(); } set { CacheApi.SaveInstance(value); } } internal static List<(double, ReceiveExplosionDamage)> ExplosionPrefixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveExplosionDamage)>>("EndskApi"); } set { CacheApi.SaveInstance(value, "EndskApi"); } } internal static List<(double, ReceiveExplosionDamage)> ExplosionPostfixCallbacks { get { return CacheApi.GetInstance<List<(double, ReceiveExplosionDamage)>>(); } set { CacheApi.SaveInstance(value); } } internal static void Setup() { if (!_setup) { CacheApi.SaveInstance(new EnemyDamageBaseNatviePatches(), "EndskApi"); MeleePrefixCallbacks = new List<(double, ReceiveMeleeDamage)>(); MeleePostfixCallbacks = new List<(double, ReceiveMeleeDamage)>(); BulletPrefixCallbacks = new List<(double, ReceiveBulletDamage)>(); BulletPostfixCallbacks = new List<(double, ReceiveBulletDamage)>(); ExplosionPrefixCallbacks = new List<(double, ReceiveExplosionDamage)>(); ExplosionPostfixCallbacks = new List<(double, ReceiveExplosionDamage)>(); _setup = true; } } public static void AddReceiveMeleePrefix(double priority, ReceiveMeleeDamage method) { Setup(); MeleePrefixCallbacks.Add((priority, method)); MeleePrefixCallbacks = new List<(double, ReceiveMeleeDamage)>(MeleePrefixCallbacks.OrderBy<(double, ReceiveMeleeDamage), double>(((double, ReceiveMeleeDamage) x) => x.Item1)); } public static void AddReceiveMeleePostfix(double priority, ReceiveMeleeDamage method) { Setup(); MeleePostfixCallbacks.Add((priority, method)); MeleePostfixCallbacks = new List<(double, ReceiveMeleeDamage)>(MeleePostfixCallbacks.OrderBy<(double, ReceiveMeleeDamage), double>(((double, ReceiveMeleeDamage) x) => x.Item1)); } public static void AddReceiveBulletPrefix(double priority, ReceiveBulletDamage method) { Setup(); BulletPrefixCallbacks.Add((priority, method)); BulletPrefixCallbacks = new List<(double, ReceiveBulletDamage)>(BulletPrefixCallbacks.OrderBy<(double, ReceiveBulletDamage), double>(((double, ReceiveBulletDamage) x) => x.Item1)); } public static void AddReceiveBulletPostfix(double priority, ReceiveBulletDamage method) { Setup(); BulletPostfixCallbacks.Add((priority, method)); BulletPostfixCallbacks = new List<(double, ReceiveBulletDamage)>(BulletPostfixCallbacks.OrderBy<(double, ReceiveBulletDamage), double>(((double, ReceiveBulletDamage) x) => x.Item1)); } public static void AddReceiveExplosionPrefix(double priority, ReceiveExplosionDamage method) { Setup(); ExplosionPrefixCallbacks.Add((priority, method)); ExplosionPrefixCallbacks = new List<(double, ReceiveExplosionDamage)>(ExplosionPrefixCallbacks.OrderBy<(double, ReceiveExplosionDamage), double>(((double, ReceiveExplosionDamage) x) => x.Item1)); } public static void AddReceiveExplosionPostfix(double priority, ReceiveExplosionDamage method) { Setup(); ExplosionPostfixCallbacks.Add((priority, method)); ExplosionPostfixCallbacks = new List<(double, ReceiveExplosionDamage)>(ExplosionPostfixCallbacks.OrderBy<(double, ReceiveExplosionDamage), double>(((double, ReceiveExplosionDamage) x) => x.Item1)); } internal static void InvokeReceiveMeleePrefix(Dam_EnemyDamageBase instance, ref pFullDamageData data) { foreach (var meleePrefixCallback in MeleePrefixCallbacks) { meleePrefixCallback.Item2(instance, ref data); } } internal static void InvokeReceiveMeleePostfix(Dam_EnemyDamageBase instance, ref pFullDamageData data) { foreach (var meleePostfixCallback in MeleePostfixCallbacks) { meleePostfixCallback.Item2(instance, ref data); } } internal static void InvokeReceiveBulletPrefix(Dam_EnemyDamageBase instance, ref pBulletDamageData data) { foreach (var bulletPrefixCallback in BulletPrefixCallbacks) { bulletPrefixCallback.Item2(instance, ref data); } } internal static void InvokeReceiveBulletPostfix(Dam_EnemyDamageBase instance, ref pBulletDamageData data) { foreach (var bulletPostfixCallback in BulletPostfixCallbacks) { bulletPostfixCallback.Item2(instance, ref data); } } internal static void InvokeReceiveExplosionPrefix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data) { foreach (var explosionPrefixCallback in ExplosionPrefixCallbacks) { explosionPrefixCallback.Item2(instance, ref data); } } internal static void InvokeReceiveExplosionPostfix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data) { foreach (var explosionPostfixCallback in ExplosionPostfixCallbacks) { explosionPostfixCallback.Item2(instance, ref data); } } } public static class EnemyKillApi { private const string EnemyKillKey = "EnemyKillCallbacks"; private static bool _setup = false; private static Dictionary<IntPtr, bool> _enemyStates = new Dictionary<IntPtr, bool>(); public static void AddEnemyKilledCallback(Action<EnemyKillDistribution> callBack) { Setup(); if (!CacheApi.TryGetInformation<List<Action<EnemyKillDistribution>>>("EnemyKillCallbacks", out var information, "EndskApi", logNotFound: false)) { information = new List<Action<EnemyKillDistribution>>(); CacheApi.SaveInformation("EnemyKillCallbacks", information, "EndskApi"); } information.Add(callBack); } internal static void InvokeEnemyKilledCallbacks(EnemyKillDistribution enemyKill) { if (!CacheApi.TryGetInformation<List<Action<EnemyKillDistribution>>>("EnemyKillCallbacks", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action<EnemyKillDistribution> item in information) { item(enemyKill); } } private static void Setup() { if (!_setup) { EnemyDamageBasePatchApi.AddReceiveMeleePrefix(1.0, ReceiveMeleePrefix); EnemyDamageBasePatchApi.AddReceiveMeleePostfix(1.0, ReceiveMeleePostfix); EnemyDamageBasePatchApi.AddReceiveBulletPrefix(1.0, ReceiveBulletPrefix); EnemyDamageBasePatchApi.AddReceiveBulletPostfix(1.0, ReceiveBulletPostfix); EnemyDamageBasePatchApi.AddReceiveExplosionPrefix(1.0, ReceiveExplosionPrefix); EnemyDamageBasePatchApi.AddReceiveExplosionPostfix(1.0, ReceiveExplosionPostfix); CacheApi.SaveInstance(new Dictionary<IntPtr, EnemyKillDistribution>(), "EndskApi"); LevelApi.AddEndLevelCallback(delegate { _enemyStates = new Dictionary<IntPtr, bool>(); CacheApi.SaveInstance(new Dictionary<IntPtr, EnemyKillDistribution>(), "EndskApi"); }); _setup = true; } } private static void ReceiveMeleePrefix(Dam_EnemyDamageBase instance, ref pFullDamageData data) { LogManager.Debug($"Receive Melee EnemyKillApi Prefix State = {((Agent)instance.Owner).Alive}"); _enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive; } private static void ReceiveMeleePostfix(Dam_EnemyDamageBase instance, ref pFullDamageData data) { LogManager.Debug($"Receive Melee EnemyKillApi Postfix State = {((Agent)instance.Owner).Alive}"); if (!(_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value)) { return; } Agent val = default(Agent); ((pAgent)(ref data.source)).TryGet(ref val); if (val != null) { PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>(); DamageDistributionAddDamageDealt(instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)instance).HealthMax)); if (!((Agent)instance.Owner).Alive) { EnemyDied(instance.Owner, val2, LastHitType.Melee); } } } private static void ReceiveBulletPrefix(Dam_EnemyDamageBase instance, ref pBulletDamageData data) { _enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive; } private static void ReceiveBulletPostfix(Dam_EnemyDamageBase instance, ref pBulletDamageData data) { if (!(_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value)) { return; } Agent val = default(Agent); ((pAgent)(ref data.source)).TryGet(ref val); if (val != null) { PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>(); DamageDistributionAddDamageDealt(instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)instance).HealthMax)); if (!((Agent)instance.Owner).Alive) { EnemyDied(instance.Owner, val2, LastHitType.ShootyWeapon); } } } private static void ReceiveExplosionPrefix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data) { _enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive; } private static void ReceiveExplosionPostfix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data) { if (_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value && !((Agent)instance.Owner).Alive) { EnemyDied(instance.Owner, null, LastHitType.Explosion); } } private static void DamageDistributionAddDamageDealt(EnemyAgent hitEnemy, PlayerAgent damageDealer, float damageDealt) { Dictionary<IntPtr, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<IntPtr, EnemyKillDistribution>>("EndskApi"); if (!instance.ContainsKey(((Il2CppObjectBase)hitEnemy).Pointer)) { EnemyKillDistribution enemyKillDistribution = new EnemyKillDistribution(hitEnemy); enemyKillDistribution.AddDamageDealtByPlayerAgent(damageDealer, damageDealt); instance[((Il2CppObjectBase)hitEnemy).Pointer] = enemyKillDistribution; } else { instance[((Il2CppObjectBase)hitEnemy).Pointer].AddDamageDealtByPlayerAgent(damageDealer, damageDealt); } } private static void EnemyDied(EnemyAgent hitEnemy, PlayerAgent lastHit, LastHitType lastHitType) { Dictionary<IntPtr, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<IntPtr, EnemyKillDistribution>>("EndskApi"); if (instance.TryGetValue(((Il2CppObjectBase)hitEnemy).Pointer, out var value)) { value.LastHitDealtBy = lastHit; value.lastHitType = lastHitType; InvokeEnemyKilledCallbacks(value); } } } public static class GearSwitchApi { static GearSwitchApi() { LevelApi.AddEndLevelCallback(LevelEndedCallback); SetGearInfoCache(new Dictionary<IntPtr, GearInfo>()); } public static GearInfo CreateNewWeaponInfo(InventorySlot slot, AmmoType ammoType, GearIDRange gearId) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 PlayerDataBlock block = GameDataBlockBase<PlayerDataBlock>.GetBlock(1u); InventorySlotAmmo val = new InventorySlotAmmo(); val.Slot = slot; val.AmmoInPack = (((int)ammoType == 1) ? block.AmmoSpecialInitial : block.AmmoStandardInitial); val.AmmoMaxCap = (((int)ammoType == 1) ? block.AmmoSpecialMaxCap : block.AmmoStandardMaxCap); GearInfo gearInfo = new GearInfo(gearId, 0, val); GearCategoryDataBlock block2 = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(gearId.GetCompID((eGearComponent)2)); uint archetypeID = GearBuilder.GetArchetypeID(block2, (eWeaponFireMode)gearId.GetCompID((eGearComponent)1)); ArchetypeDataBlock block3 = GameDataBlockBase<ArchetypeDataBlock>.GetBlock(archetypeID); gearInfo.InventorySlotAmmo.BulletClipSize = block3.DefaultClipSize; gearInfo.AmmunitionInMagazine = block3.DefaultClipSize; LogManager.Debug($"Putting {gearInfo.AmmunitionInMagazine} into {block2.PublicName}"); return gearInfo; } public static void EquipGear(GearInfo newGear, out GearInfo oldGear) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) AddWeaponInfo(newGear); SyncAmmonitionWithRegisteredWeapon(newGear.Slot, out oldGear); EquipGear(newGear); } public static void SyncAmmonitionWithRegisteredWeapon(InventorySlot slot, out GearInfo changedWeapon) { //IL_0001: 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) if (TryGetItemEquippableInSlot(slot, out ItemEquippable item) && (Object)(object)item != (Object)null) { LogManager.Debug("SyncAmmunitionWithRegisteredWeapon actually found Weapon itemequippable"); InventorySlotAmmo inventorySlotAmmo = PlayerBackpackManager.LocalBackpack.AmmoStorage.GetInventorySlotAmmo(slot); if (GetGearInfo().TryGetValue(((Il2CppObjectBase)inventorySlotAmmo).Pointer, out changedWeapon)) { changedWeapon.AmmunitionInMagazine = item.GetCurrentClip(); LogManager.Debug($"Updated Ammo to {changedWeapon.AmmunitionInMagazine}, Max is {changedWeapon.InventorySlotAmmo.BulletClipSize}"); } } else { changedWeapon = null; } } public static void AddWeaponInfo(GearInfo info) { Dictionary<IntPtr, GearInfo> gearInfo = GetGearInfo(); if (!gearInfo.ContainsKey(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer)) { gearInfo.Add(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer, info); } } public static void UnregisterWeapon(GearInfo info) { GetGearInfo().Remove(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer); } private static void EquipGear(GearInfo info) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) GearInfo info2 = info; PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack; localBackpack.SpawnAndEquipGearAsync(info2.Slot, info2.GearId, delBackpackItemCallback.op_Implicit((Action<BackpackItem>)BackPackItemCreatedCallBack)); SetAmmoStorage(info2, localBackpack.AmmoStorage); void BackPackItemCreatedCallBack(BackpackItem backpackItem) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ItemEquippable val = ((Il2CppObjectBase)backpackItem.Instance).TryCast<ItemEquippable>(); if ((Object)(object)val != (Object)null) { val.SetCurrentClip(info2.AmmunitionInMagazine); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); localPlayerAgent.Sync.WantsToWieldSlot(info2.Slot, false); } } } private static bool TryGetItemEquippableInSlot(InventorySlot slot, out ItemEquippable item) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack; BackpackItem val = default(BackpackItem); if (!localBackpack.TryGetBackpackItem(slot, ref val)) { item = null; return false; } item = ((Il2CppObjectBase)val.Instance).TryCast<ItemEquippable>(); return (Object)(object)item != (Object)null; } private static void SetAmmoStorage(GearInfo info, PlayerAmmoStorage storage) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected I4, 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 ((Il2CppArrayBase<InventorySlotAmmo>)(object)storage.m_ammoStorage)[(int)info.AmmoType] = info.InventorySlotAmmo; AmmoType ammoType = info.AmmoType; AmmoType val = ammoType; if ((int)val != 0) { if ((int)val == 1) { storage.SpecialAmmo = info.InventorySlotAmmo; } } else { storage.StandardAmmo = info.InventorySlotAmmo; } } internal static void LevelEndedCallback() { SetGearInfoCache(new Dictionary<IntPtr, GearInfo>()); } private static Dictionary<IntPtr, GearInfo> GetGearInfo() { return CacheApi.GetInstance<Dictionary<IntPtr, GearInfo>>("EndskApi"); } private static void SetGearInfoCache(Dictionary<IntPtr, GearInfo> dic) { CacheApi.SaveInstance(dic, "EndskApi"); } } public static class InitApi { private const string InitKey = "InitKey"; static InitApi() { BepInExLoader.Harmony.PatchAll(typeof(PageRundownNewPatches)); BepInExLoader.Harmony.PatchAll(typeof(GUIManagerPatches)); } public static void AddInitCallback(Action callBack) { if (!CacheApi.TryGetInformation<List<Action>>("InitKey", out var information, "EndskApi", logNotFound: false)) { information = new List<Action>(); CacheApi.SaveInformation("InitKey", information, "EndskApi"); } information.Add(callBack); } internal static void InvokeInitCallbacks() { if (!CacheApi.TryGetInformation<List<Action>>("InitKey", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action item in information) { try { item(); } catch (Exception ex) { LogManager.Error(ex.ToString()); } } CacheApi.RemoveInformation("InitKey", "EndskApi"); } } public static class LevelApi { private const string EndLevelKey = "EndLevelKey"; private const string StartLevelKey = "StartLevelKey"; static LevelApi() { BepInExLoader.Harmony.PatchAll(typeof(GsAfterLevelPatches)); BepInExLoader.Harmony.PatchAll(typeof(GsInLevelPatches)); } public static void AddBeginLevelCallback(Action callBack) { if (!CacheApi.TryGetInformation<List<Action>>("StartLevelKey", out var information, "EndskApi", logNotFound: false)) { information = new List<Action>(); CacheApi.SaveInformation("StartLevelKey", information, "EndskApi"); } information.Add(callBack); } public static void AddEndLevelCallback(Action callBack) { if (!CacheApi.TryGetInformation<List<Action>>("EndLevelKey", out var information, "EndskApi", logNotFound: false)) { information = new List<Action>(); CacheApi.SaveInformation("EndLevelKey", information, "EndskApi"); } information.Add(callBack); } internal static void InvokeEndLevelCallbacks() { if (!CacheApi.TryGetInformation<List<Action>>("EndLevelKey", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action item in information) { try { item(); } catch (Exception msg) { LogManager.Error(msg); } } } internal static void InvokeStartLevelCallbacks() { if (!CacheApi.TryGetInformation<List<Action>>("StartLevelKey", out var information, "EndskApi", logNotFound: false)) { return; } foreach (Action item in information) { try { item(); } catch (Exception msg) { LogManager.Error(msg); } } } } public static class MenuApi { private static bool _setup; static MenuApi() { _setup = false; } internal static void Setup() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (!_setup) { GameObject val = new GameObject("EndskApi_Menu"); CacheApi.SaveInstance(val.AddComponent<MainMenu>(), "EndskApi"); Object.DontDestroyOnLoad((Object)(object)val); _setup = true; } } public static void ActivateUnknownMenu<TScript>(TScript menu) where TScript : BaseMenu { Setup(); CacheApi.GetInstance<MainMenu>("EndskApi").ActivateUnknownMenu(menu); } public static TScript AddMenu<TScript>(string pageName) where TScript : BaseMenu { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); TScript val = ((Component)instance).gameObject.AddComponent<TScript>(); instance.AddPage(pageName, val); CacheApi.SaveInstance(val, "EndskApi"); return val; } public static TScript GetMenu<TScript>() where TScript : BaseMenu { Setup(); return CacheApi.GetInstance<TScript>("EndskApi"); } public static void AddMiddleMouseClickTool(IExtendedTool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.AddMiddleMouseClickTool(tool); } public static void RemoveMiddleMouseClickTool(IExtendedTool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.RemoveMiddleMouseClickTool(tool); } public static void AddTimerTool(IExtendedTool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.AddTimedTool(tool); } public static void RemoveTimerTool(IExtendedTool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.RemoveTimedTool(tool); } public static void AddHiddenFunction(Tool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.AddHiddenTool(tool); } public static void RemoveHiddenFunction(Tool tool) { Setup(); MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi"); instance.RemoveHiddenTool(tool); } } public static class ProfileIndependentDataApi { private static readonly string _localLowPath; static ProfileIndependentDataApi() { string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).Replace("Roaming", "LocalLow"); _localLowPath = Path.Combine(path, "10 Chambers Collective", "Mods"); if (!Directory.Exists(_localLowPath)) { Directory.CreateDirectory(_localLowPath); } } public static T Load<T>(string fileName, JsonSerializerOptions option = null) where T : new() { if (TryLoadFromCache<T>(fileName, out var cachedObj)) { return cachedObj; } if (option == null) { option = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; } if (File.Exists(CreatePath(fileName))) { return JsonSerializer.Deserialize<T>(File.ReadAllText(CreatePath(fileName)), option); } return new T(); } public static void Save(object obj, string fileName, JsonSerializerOptions option = null) { SaveIntoCache(fileName, obj); if (option == null) { option = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; } File.WriteAllText(CreatePath(fileName), JsonSerializer.Serialize(obj, option)); } internal static bool TryLoadFromCache<T>(string fileName, out T cachedObj) { return CacheApi.TryGetInformation<T>(fileName, out cachedObj, "ProfileIndependentApi", logNotFound: false); } internal static void SaveIntoCache(string fileName, object obj) { CacheApi.SaveInformation(fileName, obj, "ProfileIndependentApi"); } private static string CreatePath(string fileName) { if (fileName.EndsWith(".json")) { return Path.Combine(_localLowPath, fileName); } return Path.Combine(_localLowPath, fileName + ".json"); } } }
BepInEx/plugins/Expansions.dll
Decompiled a year agousing System; using System.CodeDom.Compiler; 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 System.Text.Json; using AIGraph; using Agents; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using DoubleJump; using EndskApi.Api; using Enemies; using GTFuckingXP.Communication; using GTFuckingXP.Extensions; using GTFuckingXP.Information.Level; using GTFuckingXP.Managers; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using Player; using UnityEngine; using XpExpansions.Extensions; using XpExpansions.Information; using XpExpansions.Information.BioTrackerLocal; using XpExpansions.Information.DoubleJump; using XpExpansions.Information.StartingXp; using XpExpansions.Manager; using XpExpansions.Scripts; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Expansions")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")] [assembly: AssemblyProduct("Expansions")] [assembly: AssemblyTitle("Expansions")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Expansions { [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "Expansions"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitc03396b-dirty-master"; public const string SemVer = "1.0.0+gitc03396b-dirty-master"; public const string GitRevShort = "c03396b-dirty"; public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const bool GitIsDirty = true; } } namespace XpExpansions { [BepInPlugin("Endskill.XpExpansions", "XpExpansions", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class BepinExLoader : BasePlugin { public const string MODNAME = "XpExpansions"; public const string AUTHOR = "Endskill"; public const string GUID = "Endskill.XpExpansions"; public const string VERSION = "1.0.0"; public override void Load() { LogManager.SetLogger(((BasePlugin)this).Log); LogManager._debugMessagesActive = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.").Value; ClassInjector.RegisterTypeInIl2Cpp<ClientSidedBioTrackerAbility>(); CacheApi.SaveInstance<ExpansionManager>(new ExpansionManager(), CacheApiWrapper.ExtensionCacheName); } } } namespace XpExpansions.Scripts { public class ClientSidedBioTrackerAbility : MonoBehaviour { private float _nextUpdate = 0f; public ClientSidedBioTrackerAbility(IntPtr intPtr) : base(intPtr) { } public void Update() { if (!(Time.time > _nextUpdate)) { return; } if (GameStateManager.IsInExpedition) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); Enumerator<EnemyAgent> enumerator = AIG_CourseGraph.GetReachableEnemiesInNodes(((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode, 1).GetEnumerator(); while (enumerator.MoveNext()) { EnemyAgent current = enumerator.Current; ToolSyncManager.WantToTagEnemy(current); } } _nextUpdate = Time.time + 10f; } } } namespace XpExpansions.Patches { [HarmonyBefore(new string[] { "Endskill.XpExpansions", "Endskill.GTFuckingXP" })] [HarmonyPatch(typeof(Dam_EnemyDamageBase))] public class EnemyDamageBasePatches { [HarmonyPatch("MeleeDamage")] [HarmonyPrefix] public static bool MeleePrefix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent) { return true; } } } namespace XpExpansions.Manager { public abstract class BaseManager { private static string? _folderPath; protected string FolderPath { get { if (string.IsNullOrEmpty(_folderPath)) { _folderPath = CacheApiWrapper.GetFolderPath(); } return _folderPath; } } public abstract void LevelReached(Level level); public virtual void LevelInitialized(Level level) { } public virtual void Initialize() { } public virtual void LevelCleanup() { } } public class ClientSidedBioTrackerManager : BaseManager { private const string _expansionFileName = "BioTracker.json"; public ClientSidedBioTrackerManager() { LevelApi.AddEndLevelCallback((Action)DestroyBioTrackerAbility); } public override void Initialize() { WriteDefaultJsonBlocks(); UpdateEverything(); } public override void LevelReached(Level level) { LevelLayout levelLayout = CacheApiWrapper.GetCurrentLevelLayout(); List<LocalBioTrackerData> instance = CacheApi.GetInstance<List<LocalBioTrackerData>>(CacheApiWrapper.ExtensionCacheName); LocalBioTrackerData localBioTrackerData = instance.FirstOrDefault((LocalBioTrackerData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId); if (localBioTrackerData != null) { if (localBioTrackerData.UnlockAtLevel <= level.LevelNumber) { CacheApiWrapper.DestroyOldCreateRegisterAndReturnComponent<ClientSidedBioTrackerAbility>(); } else { DestroyBioTrackerAbility(); } } } public void DestroyBioTrackerAbility() { CacheApiWrapper.KillScript<ClientSidedBioTrackerAbility>(); } private void WriteDefaultJsonBlocks() { if (!Directory.Exists(base.FolderPath)) { Directory.CreateDirectory(base.FolderPath); } string path = Path.Combine(base.FolderPath, "BioTracker.json"); if (!File.Exists(path)) { JsonSerializerOptions options = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options)); } } private void UpdateEverything() { CacheApi.SaveInstance<List<LocalBioTrackerData>>(JsonSerializer.Deserialize<List<LocalBioTrackerData>>(File.ReadAllText(Path.Combine(base.FolderPath, "BioTracker.json"))), CacheApiWrapper.ExtensionCacheName); } private List<LocalBioTrackerData> GetDefaultData() { List<LocalBioTrackerData> list = new List<LocalBioTrackerData>(); for (int i = 0; i < 20; i++) { list.Add(new LocalBioTrackerData(i, 3)); } return list; } } public class DeactivateManager : BaseManager { private const string _expansionFileName = "DeactivateOnMissions.json"; private const string _expansionClassFileName = "DeactivateClassLayout.json"; public override void Initialize() { } public override void LevelReached(Level level) { } private void WriteDefaultJsonBlocks() { if (!Directory.Exists(base.FolderPath)) { Directory.CreateDirectory(base.FolderPath); } JsonSerializerOptions options = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; string path = Path.Combine(base.FolderPath, "DeactivateOnMissions.json"); if (!File.Exists(path)) { File.WriteAllText(path, JsonSerializer.Serialize(new List<int> { 69420, 42069 }, options)); } } } public class DoubleJumpManager : BaseManager { public const string DoubleJumpXpExpansionId = "Endskill.DoubleJumpExpansion"; private const string _expansionFileName = "DoubleJumpExpansion.json"; private bool _harmonyState; public Harmony DoubleJumpHarmonyAbility { get; private set; } public DoubleJumpManager() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown DoubleJumpHarmonyAbility = new Harmony("Endskill.DoubleJumpExpansion"); Harmony.UnpatchID("com.mccad00.DoubleJump"); _harmonyState = false; } public override void Initialize() { WriteDefaultJsonBlocks(); UpdateEverything(); } public override void LevelCleanup() { if (_harmonyState) { DoubleJumpHarmonyAbility.UnpatchSelf(); _harmonyState = false; } } public override void LevelReached(Level level) { LogManager.Message("LevelReached, DoubleJump " + ((object)level).ToString()); LevelLayout levelLayout = CacheApiWrapper.GetCurrentLevelLayout(); List<DoubleJumpData> instance = CacheApi.GetInstance<List<DoubleJumpData>>(CacheApiWrapper.ExtensionCacheName); DoubleJumpData doubleJumpData = instance.FirstOrDefault((DoubleJumpData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId); if (doubleJumpData != null) { if (doubleJumpData.UnlockAtLevel <= level.LevelNumber) { if (!_harmonyState) { Assembly assembly = Assembly.GetAssembly(typeof(EntryPoint)); DoubleJumpHarmonyAbility.PatchAll(assembly); _harmonyState = true; } } else if (_harmonyState) { DoubleJumpHarmonyAbility.UnpatchSelf(); _harmonyState = false; } } else if (_harmonyState) { DoubleJumpHarmonyAbility.UnpatchSelf(); _harmonyState = false; } } private void WriteDefaultJsonBlocks() { if (!Directory.Exists(base.FolderPath)) { Directory.CreateDirectory(base.FolderPath); } string path = Path.Combine(base.FolderPath, "DoubleJumpExpansion.json"); if (!File.Exists(path)) { JsonSerializerOptions options = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options)); } } private void UpdateEverything() { CacheApi.SaveInstance<List<DoubleJumpData>>(JsonSerializer.Deserialize<List<DoubleJumpData>>(File.ReadAllText(Path.Combine(base.FolderPath, "DoubleJumpExpansion.json"))), CacheApiWrapper.ExtensionCacheName); } private List<DoubleJumpData> GetDefaultData() { List<DoubleJumpData> list = new List<DoubleJumpData>(); for (int i = 0; i < 20; i++) { list.Add(new DoubleJumpData(i, 3)); } return list; } } public class ExpansionManager : BaseManager { public const string ExpansionActivePath = "ExpansionsActive.json"; public ExpansionManager() { LogManager.Message("ExpansionManager constructor."); InitApi.AddInitCallback((Action)Initialize); LevelApi.AddEndLevelCallback((Action)LevelCleanup); XpApi.AddOnLevelUpCallback((Action<Level>)LevelReached); XpApi.AddScriptsLoaded((Action<Level>)LevelInitialized); } public override void Initialize() { CacheApiWrapper.SetFolderPath(Path.Combine(ScriptManager.Instance.GetFolderPath(), "Expansions")); WriteDefaultData(); List<BaseManager> list = CreateManagers(); CacheApi.SaveInstance<List<BaseManager>>(list, CacheApiWrapper.ExtensionCacheName); foreach (BaseManager item in list) { item.Initialize(); } } public override void LevelCleanup() { List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName); foreach (BaseManager item in instance) { item.LevelCleanup(); } } public override void LevelReached(Level level) { LogManager.Message("LevelReached in the Expansion Manager."); List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName); foreach (BaseManager item in instance) { item.LevelReached(level); } } public override void LevelInitialized(Level level) { LogManager.Message("LevelInitialized in the Expansion Manager."); List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName); foreach (BaseManager item in instance) { item.LevelInitialized(level); } } private List<BaseManager> CreateManagers() { List<BaseManager> list = new List<BaseManager>(); string path = Path.Combine(base.FolderPath, "ExpansionsActive.json"); ActiveExpansions activeExpansions = JsonSerializer.Deserialize<ActiveExpansions>(File.ReadAllText(path)); LogManager.Debug("CreateManagers method."); if (activeExpansions != null) { if (activeExpansions.DoubleJumpAbility) { list.Add(new DoubleJumpManager()); } if (activeExpansions.StartingXp) { list.Add(new StartingLevelXpManager()); } if (activeExpansions.LivingBioAbility) { list.Add(new ClientSidedBioTrackerManager()); } } return list; } private void WriteDefaultData() { if (!Directory.Exists(base.FolderPath)) { Directory.CreateDirectory(base.FolderPath); } string path = Path.Combine(base.FolderPath, "ExpansionsActive.json"); if (!File.Exists(path)) { File.WriteAllText(path, JsonSerializer.Serialize(new ActiveExpansions(startingXp: false, doubleJumpAbility: false))); } } } public class ExplosionAbilityManager : BaseManager { public const string ExplosionHarmonyInstanceId = "Endskill.ExplosionAbility"; public Harmony ExplosionHarmony { get; private set; } public ExplosionAbilityManager() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ExplosionHarmony = new Harmony("Endskill.ExplosionAbility"); } public override void Initialize() { } public override void LevelReached(Level level) { } public override void LevelCleanup() { } } public static class LogManager { private static ManualLogSource logger; internal static bool _debugMessagesActive; internal static void SetLogger(ManualLogSource log) { logger = log; } public static void Verbose(object msg) { if (_debugMessagesActive) { logger.LogInfo(msg); } } public static void Debug(object msg) { if (_debugMessagesActive) { logger.LogDebug(msg); } } public static void Message(object msg) { if (_debugMessagesActive) { logger.LogMessage(msg); } } public static void Error(object msg) { logger.LogError(msg); } public static void Warn(object msg) { logger.LogWarning(msg); } } internal class StartingLevelXpManager : BaseManager { private const string _expansionFileName = "StartingXP.json"; public override void Initialize() { WriteDefaultJsonBlocks(); UpdateEverything(); } public override void LevelReached(Level level) { } public override void LevelInitialized(Level level) { ExpeditionInTierData expedition = RundownManager.ActiveExpedition; List<StartingXpData> instance = CacheApi.GetInstance<List<StartingXpData>>(CacheApiWrapper.ExtensionCacheName); StartingXpData startingXpData = instance.FirstOrDefault((StartingXpData it) => it.LevelLayoutData == expedition.LevelLayoutData); if (startingXpData != null) { XpApi.AddXp(startingXpData.StartingXp); } } private void UpdateEverything() { CacheApi.SaveInstance<List<StartingXpData>>(JsonSerializer.Deserialize<List<StartingXpData>>(File.ReadAllText(Path.Combine(base.FolderPath, "StartingXP.json"))), CacheApiWrapper.ExtensionCacheName); } private void WriteDefaultJsonBlocks() { if (!Directory.Exists(base.FolderPath)) { Directory.CreateDirectory(base.FolderPath); } string path = Path.Combine(base.FolderPath, "StartingXP.json"); if (!File.Exists(path)) { JsonSerializerOptions options = new JsonSerializerOptions { IncludeFields = false, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options)); } } private List<StartingXpData> GetDefaultData() { List<StartingXpData> list = new List<StartingXpData>(); foreach (RundownDataBlock allBlock in GameDataBlockBase<RundownDataBlock>.GetAllBlocks()) { Enumerator<ExpeditionInTierData> enumerator2 = allBlock.TierD.GetEnumerator(); while (enumerator2.MoveNext()) { ExpeditionInTierData current2 = enumerator2.Current; list.Add(new StartingXpData(current2.LevelLayoutData, 100u)); } } return list; } } } namespace XpExpansions.Information { public class ActiveExpansions { public bool DoubleJumpAbility { get; set; } public bool StartingXp { get; set; } public bool LivingBioAbility { get; set; } public ActiveExpansions(bool startingXp, bool doubleJumpAbility) { DoubleJumpAbility = doubleJumpAbility; StartingXp = startingXp; } } } namespace XpExpansions.Information.StartingXp { public class StartingXpData { public uint LevelLayoutData { get; set; } public uint StartingXp { get; set; } public StartingXpData(uint levelLayoutData, uint startingXp) { LevelLayoutData = levelLayoutData; StartingXp = startingXp; } } } namespace XpExpansions.Information.Explosion { public class ExplosionAbilityData { public int LevelLayoutPersistentId { get; set; } public int UnlockAtLevel { get; set; } public ExplosionAbilityData(int levelLayoutPersistentId, int unlockAtLevel) { LevelLayoutPersistentId = levelLayoutPersistentId; UnlockAtLevel = unlockAtLevel; } } } namespace XpExpansions.Information.DoubleJump { internal class DoubleJumpData { public int LevelLayoutPersistentId { get; set; } public int UnlockAtLevel { get; set; } public DoubleJumpData(int levelLayoutPersistentId, int unlockAtLevel) { LevelLayoutPersistentId = levelLayoutPersistentId; UnlockAtLevel = unlockAtLevel; } } } namespace XpExpansions.Information.BioTrackerLocal { internal class LocalBioTrackerData { public int LevelLayoutPersistentId { get; set; } public int UnlockAtLevel { get; set; } public LocalBioTrackerData(int levelLayoutPersistentId, int unlockAtLevel) { LevelLayoutPersistentId = levelLayoutPersistentId; UnlockAtLevel = unlockAtLevel; } } } namespace XpExpansions.Extensions { public static class CacheApiWrapper { internal static string ExtensionCacheName = "XpExtensions"; private const string _folderPath = "FolderPath"; public static void SetFolderPath(string path) { CacheApi.SaveInformation((object)"FolderPath", (object)path, ExtensionCacheName); } public static string GetFolderPath() { return CacheApi.GetInformation<string>((object)"FolderPath", ExtensionCacheName); } } }
BepInEx/plugins/GTFO-API.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using AIGraph; using AssetShards; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BepInEx.Unity.IL2CPP.Utils; using GTFO.API.Attributes; using GTFO.API.Components; using GTFO.API.Extensions; using GTFO.API.Impl; using GTFO.API.JSON; using GTFO.API.JSON.Converters; using GTFO.API.Native; using GTFO.API.Resources; using GTFO.API.Utilities; using GTFO.API.Utilities.Impl; using GTFO.API.Wrappers; using GameData; using Gear; using Globals; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using ItemSetup; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; using UnityEngine.Analytics; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("GTFO-API")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.4.1")] [assembly: AssemblyInformationalVersion("0.4.1+git1e8fe81-main")] [assembly: AssemblyProduct("GTFO-API")] [assembly: AssemblyTitle("GTFO-API")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GTFO.API { internal static class APILogger { private static readonly ManualLogSource _logger; static APILogger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _logger = new ManualLogSource("GTFO-API"); Logger.Sources.Add((ILogSource)(object)_logger); } private static string Format(string module, object msg) { return $"[{module}]: {msg}"; } public static void Info(string module, object data) { _logger.LogMessage((object)Format(module, data)); } public static void Verbose(string module, object data) { } public static void Debug(string module, object data) { _logger.LogDebug((object)Format(module, data)); } public static void Warn(string module, object data) { _logger.LogWarning((object)Format(module, data)); } public static void Error(string module, object data) { _logger.LogError((object)Format(module, data)); } } [API("Asset")] public static class AssetAPI { internal static ConcurrentDictionary<string, Object> s_RegistryCache = new ConcurrentDictionary<string, Object>(); public static ApiStatusInfo Status => APIStatus.Asset; public static event Action OnStartupAssetsLoaded; public static event Action OnAssetBundlesLoaded; public static event Action OnImplReady; public static bool ContainsAsset(string assetName) { string text = assetName.ToUpper(); if (!APIStatus.Asset.Ready) { return s_RegistryCache.ContainsKey(text); } return AssetShardManager.s_loadedAssetsLookup.ContainsKey(text); } public static Object GetLoadedAsset(string path) { string text = path.ToUpper(); APILogger.Verbose("Asset", "Requested Asset: " + text); try { if (!APIStatus.Asset.Ready && s_RegistryCache.TryGetValue(text, out var value)) { return value; } return AssetShardManager.GetLoadedAsset(text, false); } catch { return null; } } public static TAsset GetLoadedAsset<TAsset>(string path) where TAsset : Object { Object loadedAsset = GetLoadedAsset(path); if (loadedAsset == null) { return default(TAsset); } return ((Il2CppObjectBase)loadedAsset).Cast<TAsset>(); } public static void RegisterAsset(string name, Object gameObject) { string text = name.ToUpper(); if (!APIStatus.Asset.Ready) { if (s_RegistryCache.ContainsKey(text)) { throw new ArgumentException("The asset with " + text + " has already been registered.", "name"); } s_RegistryCache.TryAdd(text, gameObject); } else { AssetAPI_Impl.Instance.RegisterAsset(text, gameObject); } } public static void RegisterAssetBundle(AssetBundle bundle) { string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)bundle.AllAssetNames()); APILogger.Verbose("Asset", "Bundle names: [" + string.Join(", ", array) + "]"); string[] array2 = array; foreach (string text in array2) { Object val = bundle.LoadAsset(text); if (val != (Object)null) { RegisterAsset(text, val); } else { APILogger.Warn("Asset", "Skipping asset " + text); } } } public static void LoadAndRegisterAssetBundle(string pathToBundle) { AssetBundle obj = AssetBundle.LoadFromFile(pathToBundle); if ((Object)(object)obj == (Object)null) { throw new Exception("Failed to load asset bundle"); } RegisterAssetBundle(obj); } public static void LoadAndRegisterAssetBundle(byte[] bundleBytes) { AssetBundle obj = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(bundleBytes)); if ((Object)(object)obj == (Object)null) { throw new Exception("Failed to load asset bundle"); } RegisterAssetBundle(obj); } public static Object InstantiateAsset(string assetName, string copyName) { if (ContainsAsset(copyName)) { throw new ArgumentException("The asset you're trying to copy into is already registered", "copyName"); } RegisterAsset(copyName, Object.Instantiate(GetLoadedAsset(assetName) ?? throw new ArgumentException("Couldn't find an asset with the name '" + assetName + "'", "assetName"))); return GetLoadedAsset(copyName); } public static TAsset InstantiateAsset<TAsset>(string assetName, string copyName) where TAsset : Object { Object obj = InstantiateAsset(assetName, copyName); if (obj == null) { return default(TAsset); } return ((Il2CppObjectBase)obj).Cast<TAsset>(); } public static bool TryInstantiateAsset<TAsset>(string assetName, string copyName, out TAsset clonedObj) where TAsset : Object { Object obj = InstantiateAsset(assetName, copyName); clonedObj = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<TAsset>() : default(TAsset)); return (Object)(object)clonedObj != (Object)null; } private static void OnAssetsLoaded() { if (!APIStatus.Asset.Created) { APIStatus.CreateApi<AssetAPI_Impl>("Asset"); } AssetAPI.OnStartupAssetsLoaded?.Invoke(); } internal static void InvokeImplReady() { AssetAPI.OnImplReady?.Invoke(); } internal static void Setup() { EventAPI.OnAssetsLoaded += OnAssetsLoaded; OnImplReady += LoadAssetBundles; } private static void LoadAssetBundles() { string assetBundlesDir = Path.Combine(Paths.BepInExRootPath, "Assets", "AssetBundles"); string assetBundlesDir2 = Path.Combine(Paths.ConfigPath, "Assets", "AssetBundles"); if (LoadAssetBundles(assetBundlesDir) | LoadAssetBundles(assetBundlesDir2, outdated: true)) { AssetAPI.OnAssetBundlesLoaded?.Invoke(); } } private static bool LoadAssetBundles(string assetBundlesDir, bool outdated = false) { if (outdated) { if (!Directory.Exists(assetBundlesDir)) { return false; } APILogger.Warn("AssetAPI", "Storing asset bundles in the config path is deprecated and will be removed in a future version of GTFO-API. The path has been moved to 'BepInEx\\Assets\\AssetBundles'."); } if (!Directory.Exists(assetBundlesDir)) { Directory.CreateDirectory(assetBundlesDir); return false; } string[] array = (from x in Directory.GetFiles(assetBundlesDir, "*", SearchOption.AllDirectories) where !x.EndsWith(".manifest", StringComparison.InvariantCultureIgnoreCase) select x).ToArray(); if (array.Length == 0) { return false; } for (int i = 0; i < array.Length; i++) { try { LoadAndRegisterAssetBundle(array[i]); } catch (Exception ex) { APILogger.Warn("AssetAPI", $"Failed to load asset bundle '{array[i]}' ({ex.Message})"); } } return true; } } [API("Event")] public static class EventAPI { public static ApiStatusInfo Status => APIStatus.Event; public static event Action OnManagersSetup; public static event Action OnExpeditionStarted; public static event Action OnAssetsLoaded; internal static void Setup() { Global.OnAllManagersSetup += Action.op_Implicit((Action)ManagersSetup); AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)AssetsLoaded); RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)ExpeditionStarted); } private static void ManagersSetup() { EventAPI.OnManagersSetup?.Invoke(); } private static void ExpeditionStarted() { EventAPI.OnExpeditionStarted?.Invoke(); } private static void AssetsLoaded() { EventAPI.OnAssetsLoaded?.Invoke(); } } [API("GameData")] public class GameDataAPI { public static ApiStatusInfo Status => APIStatus.GameData; public static event Action OnGameDataInitialized; static GameDataAPI() { Status.Created = true; Status.Ready = true; } internal static void InvokeGameDataInit() { GameDataAPI.OnGameDataInitialized?.Invoke(); } } [API("Il2Cpp")] public static class Il2CppAPI { public static ApiStatusInfo Status => APIStatus.Il2Cpp; static Il2CppAPI() { Status.Created = true; Status.Ready = true; } public unsafe static void InjectWithInterface<T>() where T : Il2CppObjectBase { //IL_007e: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown List<INativeClassStruct> list = new List<INativeClassStruct>(); foreach (Il2CppInterfaceAttribute item in GetCustomAttributesInType<T, Il2CppInterfaceAttribute>()) { Il2CppClass* ptr = (Il2CppClass*)(void*)(IntPtr)typeof(Il2CppClassPointerStore<>).MakeGenericType(item.Type).GetField("NativeClassPtr").GetValue(null); IL2CPP.il2cpp_runtime_class_init((IntPtr)ptr); list.Add(UnityVersionHandler.Wrap(ptr)); } RegisterTypeOptions val = new RegisterTypeOptions(); val.set_LogSuccess(true); val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(list.ToArray())); ClassInjector.RegisterTypeInIl2Cpp<T>(val); } public unsafe static void* GetIl2CppMethod<T>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase { void** ptr = (void**)IL2CPP.GetIl2CppMethod(Il2CppClassPointerStore<T>.NativeClassPtr, isGeneric, methodName, returnTypeName, argTypes).ToPointer(); if (ptr == null) { return ptr; } return *ptr; } public unsafe static TDelegate GetIl2CppMethod<T, TDelegate>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase where TDelegate : Delegate { void* il2CppMethod = GetIl2CppMethod<T>(methodName, returnTypeName, isGeneric, argTypes); if (il2CppMethod == null) { return null; } return Marshal.GetDelegateForFunctionPointer<TDelegate>((IntPtr)il2CppMethod); } public unsafe static INativeDetour CreateGenericDetour<TClass, TDelegate>(string methodName, string returnType, string[] paramTypes, Type[] genericArguments, TDelegate to, out TDelegate original) where TClass : Object where TDelegate : Delegate { //IL_0042: Unknown result type (might be due to invalid IL or missing references) IntPtr nativeClassPtr = Il2CppClassPointerStore<TClass>.NativeClassPtr; if (nativeClassPtr == IntPtr.Zero) { throw new ArgumentException(typeof(TClass).Name + " does not exist in il2cpp domain"); } return INativeDetour.CreateAndApply<TDelegate>(UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)IL2CPP.il2cpp_method_get_from_reflection(((Il2CppObjectBase)new MethodInfo(IL2CPP.il2cpp_method_get_object(IL2CPP.GetIl2CppMethod(nativeClassPtr, true, methodName, returnType, paramTypes), nativeClassPtr)).MakeGenericMethod(((IEnumerable<Type>)genericArguments).Select((Func<Type, Type>)Il2CppType.From).ToArray())).Pointer)).MethodPointer, to, ref original); } private static IEnumerable<TAttribute> GetCustomAttributesInType<T, TAttribute>() where TAttribute : Attribute { Type attributeType = typeof(TAttribute); return typeof(T).GetCustomAttributes(attributeType, inherit: true).Union(typeof(T).GetInterfaces().SelectMany((Type interfaceType) => interfaceType.GetCustomAttributes(attributeType, inherit: true))).Distinct() .Cast<TAttribute>(); } } public delegate void LevelDataUpdateEvent(ActiveExpedition activeExp, ExpeditionInTierData expData); public delegate void LevelSelectedEvent(eRundownTier expTier, int expIndexInTier, ExpeditionInTierData expData); [API("Level")] public static class LevelAPI { private static eRundownTier s_LatestExpTier = (eRundownTier)99; private static int s_LatestExpIndex = -1; public static ApiStatusInfo Status => APIStatus.Level; public static event LevelDataUpdateEvent OnLevelDataUpdated; public static event LevelSelectedEvent OnLevelSelected; public static event Action OnBuildStart; public static event Action OnBuildDone; public static event Action OnEnterLevel; public static event Action OnLevelCleanup; internal static void Setup() { Status.Created = true; Status.Ready = true; EventAPI.OnExpeditionStarted += EnterLevel; } internal static void ExpeditionUpdated(pActiveExpedition activeExp, ExpeditionInTierData expData) { //IL_0018: 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_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_0040: 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) LevelAPI.OnLevelDataUpdated?.Invoke(ActiveExpedition.CreateFrom(activeExp), expData); eRundownTier tier = activeExp.tier; int expeditionIndex = activeExp.expeditionIndex; if (tier != s_LatestExpTier || expeditionIndex != s_LatestExpIndex) { LevelAPI.OnLevelSelected?.Invoke(tier, expeditionIndex, expData); s_LatestExpTier = tier; s_LatestExpIndex = expeditionIndex; } } internal static void BuildStart() { LevelAPI.OnBuildStart?.Invoke(); } internal static void BuildDone() { LevelAPI.OnBuildDone?.Invoke(); } internal static void EnterLevel() { LevelAPI.OnEnterLevel?.Invoke(); } internal static void LevelCleanup() { LevelAPI.OnLevelCleanup?.Invoke(); } } public struct ActiveExpedition { public pPlayer player; public eRundownKey rundownType; public string rundownKey; public eRundownTier tier; public int expeditionIndex; public int hostIDSeed; public int sessionSeed; public static ActiveExpedition CreateFrom(pActiveExpedition pActiveExp) { ActiveExpedition result = default(ActiveExpedition); result.CopyFrom(pActiveExp); return result; } public void CopyFrom(pActiveExpedition pActiveExp) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0013: 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) player = pActiveExp.player; rundownType = pActiveExp.rundownType; rundownKey = pActiveExp.rundownKey.data; tier = pActiveExp.tier; expeditionIndex = pActiveExp.expeditionIndex; hostIDSeed = pActiveExp.hostIDSeed; sessionSeed = pActiveExp.sessionSeed; } } [API("Localization")] public static class LocalizationAPI { private sealed class Entry { private readonly string?[] m_ValuesByLanguage = new string[12]; private TextDBOptions m_Options; public uint? TextBlockId { get; private set; } private bool TryGetStringInAnyLanguage([NotNullWhen(true)] out string? value) { for (int i = 0; i < m_ValuesByLanguage.Length; i++) { value = m_ValuesByLanguage[i]; if (value != null) { return true; } } value = null; return false; } private bool TryGetStringInLanguage(Language language, [NotNullWhen(true)] out string? value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Expected I4, but got Unknown int num = language - 1; value = m_ValuesByLanguage[num]; return value != null; } public bool TryGetString(Language language, FallbackValueOptions options, [NotNullWhen(true)] out string? value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (TryGetStringInLanguage(language, out value)) { return true; } if (options.UseFallbackLanguage && TryGetStringInLanguage(options.FallbackLanguage.Value, out value)) { return true; } if (options.UseAnyLanguage && TryGetStringInAnyLanguage(out value)) { return true; } value = null; return false; } private string GetStringForTextDB(Language language, string key, FallbackValueOptions options) { //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) if (TryGetString(language, options, out string value)) { return value; } ValidateUseKey(key, language, options, "GenerateTextDB"); return key; } [MemberNotNull("TextBlockId")] public void GenerateTextDataBlock(string key, TextDBOptions options, bool force = false) { m_Options = options; GenerateTextDataBlock(key, force); } [MemberNotNull("TextBlockId")] public void GenerateTextDataBlock(string key, bool force = false) { //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00cd: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_018d: Expected O, but got Unknown //IL_018e: Expected O, but got Unknown if (!TextBlockId.HasValue || force) { FallbackValueOptions options = m_Options.FallbackOptions ?? FallbackValueOptions.AnyLangOrKey; TextDataBlock val = new TextDataBlock { CharacterMetaData = (m_Options.CharacterMetadataId ?? 1) }; ((GameDataBlockBase<TextDataBlock>)val).internalEnabled = true; val.ExportVersion = 1; val.ImportVersion = 1; val.Description = string.Empty; val.English = GetStringForTextDB((Language)1, key, options); val.French = LanguageData.op_Implicit(GetStringForTextDB((Language)2, key, options)); val.Italian = LanguageData.op_Implicit(GetStringForTextDB((Language)3, key, options)); val.German = LanguageData.op_Implicit(GetStringForTextDB((Language)4, key, options)); val.Spanish = LanguageData.op_Implicit(GetStringForTextDB((Language)5, key, options)); val.Russian = LanguageData.op_Implicit(GetStringForTextDB((Language)6, key, options)); val.Portuguese_Brazil = LanguageData.op_Implicit(GetStringForTextDB((Language)7, key, options)); val.Polish = LanguageData.op_Implicit(GetStringForTextDB((Language)8, key, options)); val.Japanese = LanguageData.op_Implicit(GetStringForTextDB((Language)9, key, options)); val.Korean = LanguageData.op_Implicit(GetStringForTextDB((Language)10, key, options)); val.Chinese_Traditional = LanguageData.op_Implicit(GetStringForTextDB((Language)11, key, options)); val.Chinese_Simplified = LanguageData.op_Implicit(GetStringForTextDB((Language)12, key, options)); ((GameDataBlockBase<TextDataBlock>)val).name = key; val.MachineTranslation = false; val.SkipLocalization = false; ((GameDataBlockBase<TextDataBlock>)val).persistentID = 0u; TextDataBlock val2 = val; GameDataBlockBase<TextDataBlock>.AddBlock(val2, -1); TextBlockId = ((GameDataBlockBase<TextDataBlock>)(object)val2).persistentID; } } public bool TryGetString(Language language, string key, FallbackValueOptions options, out string? value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (TryGetString(language, options, out value)) { return true; } if (options.UseKey) { value = key; return true; } value = null; return false; } public string GetString(Language language, string key, FallbackValueOptions options) { //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) if (TryGetString(language, options, out string value)) { return value; } ValidateUseKey(key, language, options, "GetString"); return key; } public string FormatString(Language language, string key, FallbackValueOptions options, object?[] args) { //IL_0001: 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) if (TryGetString(language, options, out string value)) { return string.Format(value, args); } ValidateUseKey(key, language, options, "FormatString"); return key; } public bool HasValueInLanguage(Language language) { //IL_0000: 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_0013: Unknown result type (might be due to invalid IL or missing references) ValidateLanguage(language, "language"); return m_ValuesByLanguage[language - 1] != null; } public void AddValue(Language language, string value, bool force = false) { //IL_000b: 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_000f: Expected I4, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) ArgumentNullException.ThrowIfNull(value, "value"); int num = language - 1; if (num < 0 || num >= m_ValuesByLanguage.Length) { throw new ArgumentOutOfRangeException("language"); } ref string reference = ref m_ValuesByLanguage[num]; if (reference != null && !force) { return; } reference = value; if (TextBlockId.HasValue) { TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock(TextBlockId.Value); if (block != null) { UpdateTextDataBlock(block, language, reference); } } } } [Flags] public enum FallbackValueFlags { None = 0, FallbackLanguage = 1, AnyLanguage = 2, Key = 4, FallbackOrAnyLanguage = 3, FallbackLanguageOrKey = 5, AnyLanguageOrKey = 6, FallbackOrAnyLanguageOrKey = 7 } public readonly struct FallbackValueOptions : IEquatable<FallbackValueOptions> { public static readonly FallbackValueOptions None = default(FallbackValueOptions); public static readonly FallbackValueOptions Key = new FallbackValueOptions(FallbackValueFlags.Key); public static readonly FallbackValueOptions AnyLang = new FallbackValueOptions(FallbackValueFlags.AnyLanguage); public static readonly FallbackValueOptions AnyLangOrKey = new FallbackValueOptions(FallbackValueFlags.AnyLanguageOrKey); public FallbackValueFlags Flags { get; } public Language? FallbackLanguage { get; } public bool UseKey => Flags.HasFlag(FallbackValueFlags.Key); [MemberNotNullWhen(true, "FallbackLanguage")] public bool UseFallbackLanguage { [MemberNotNullWhen(true, "FallbackLanguage")] get { return Flags.HasFlag(FallbackValueFlags.FallbackLanguage); } } public bool UseAnyLanguage => Flags.HasFlag(FallbackValueFlags.AnyLanguage); public FallbackValueOptions(FallbackValueFlags flags, Language? fallbackLanguage = null) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (flags.HasFlag(FallbackValueFlags.FallbackLanguage)) { if (!fallbackLanguage.HasValue) { throw new ArgumentNullException("fallbackLanguage", "A fallback language is required if specifying the flag FallbackLanguage"); } ValidateLanguage(fallbackLanguage.Value, "fallbackLanguage"); } Flags = flags; FallbackLanguage = fallbackLanguage; } public override int GetHashCode() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return HashCode.Combine<FallbackValueFlags, Language>(Flags, FallbackLanguage.GetValueOrDefault()); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is FallbackValueOptions other) { return Equals(other); } return false; } public bool Equals(FallbackValueOptions other) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (Flags == other.Flags) { return FallbackLanguage == other.FallbackLanguage; } return false; } public FallbackValueOptions IncludeKey() { return new FallbackValueOptions(Flags | FallbackValueFlags.Key, FallbackLanguage); } public FallbackValueOptions ExcludeKey() { return new FallbackValueOptions(Flags & ~FallbackValueFlags.Key, FallbackLanguage); } public FallbackValueOptions IncludeFallbackLanguage(Language language) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) ValidateLanguage(language, "language"); return new FallbackValueOptions(Flags | FallbackValueFlags.FallbackLanguage, language); } public FallbackValueOptions ExcludeFallbackLanguage() { return new FallbackValueOptions(Flags & ~FallbackValueFlags.FallbackLanguage); } public FallbackValueOptions IncludeAnyLanguage() { return new FallbackValueOptions(Flags | FallbackValueFlags.AnyLanguage, FallbackLanguage); } public FallbackValueOptions ExcludeAnyLanguage() { return new FallbackValueOptions(Flags & ~FallbackValueFlags.AnyLanguage, FallbackLanguage); } public FallbackValueOptions Combine(FallbackValueOptions other) { return new FallbackValueOptions(Flags | other.Flags, FallbackLanguage ?? other.FallbackLanguage); } public static bool operator ==(FallbackValueOptions left, FallbackValueOptions right) { return left.Equals(right); } public static bool operator !=(FallbackValueOptions left, FallbackValueOptions right) { return !(left == right); } public static FallbackValueOptions FallbackLang(Language fallbackLanguage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new FallbackValueOptions(FallbackValueFlags.FallbackLanguage, fallbackLanguage); } public static FallbackValueOptions FallbackOrAnyLang(Language fallbackLanguage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new FallbackValueOptions(FallbackValueFlags.FallbackOrAnyLanguage, fallbackLanguage); } public static FallbackValueOptions FallbackLangOrKey(Language fallbackLanguage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new FallbackValueOptions(FallbackValueFlags.FallbackLanguageOrKey, fallbackLanguage); } public static FallbackValueOptions FallbackOrAnyLangOrKey(Language fallbackLanguage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new FallbackValueOptions(FallbackValueFlags.FallbackOrAnyLanguageOrKey, fallbackLanguage); } } public struct TextDBOptions { private FallbackValueOptions? m_FallbackOptions; private uint? m_CharacterMetadataId; public uint? CharacterMetadataId { readonly get { return m_CharacterMetadataId; } set { m_CharacterMetadataId = value; } } public FallbackValueOptions? FallbackOptions { readonly get { return m_FallbackOptions; } set { m_FallbackOptions = value; } } } private static readonly Dictionary<string, Entry> s_Entries = new Dictionary<string, Entry>(); private static readonly List<string> s_EntriesToGenerateTextDBs = new List<string>(); private static bool s_GameDataInitialized = false; private static readonly string STR_NoValueFoundExceptionMsg = "No localization value exists for key '{1}' in language '{0}'."; private static readonly string STR_UseKeyGeneric = "{2}: No localization value exists for key '{1}' in language '{0}', defaulting to key."; public static ApiStatusInfo Status => APIStatus.Localization; public static Language CurrentLanguage => Text.TextLocalizationService.CurrentLanguage; public static event Action? OnLanguageChange; internal static void Setup() { GameDataAPI.OnGameDataInitialized += OnGameDataInitialized; EventAPI.OnAssetsLoaded += OnGameAssetsLoaded; Status.Created = true; } internal static void OnGameDataInitialized() { s_GameDataInitialized = true; foreach (string s_EntriesToGenerateTextDB in s_EntriesToGenerateTextDBs) { if (s_Entries.TryGetValue(s_EntriesToGenerateTextDB, out Entry value)) { value.GenerateTextDataBlock(s_EntriesToGenerateTextDB, force: true); } } } internal static void OnGameAssetsLoaded() { Status.Ready = true; } internal static void LanguageChanged() { LocalizationAPI.OnLanguageChange?.Invoke(); } public static string FormatString(string key, params object?[] args) { return FormatString(key, FallbackValueOptions.None, args); } public static string FormatString(string key, Language fallbackLanguage, params object?[] args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return FormatString(key, FallbackValueOptions.FallbackLang(fallbackLanguage), args); } public static string FormatString(string key, FallbackValueOptions options, params object?[] args) { //IL_000b: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ValidateLocalizationKey(key, "key"); Language currentLanguage = CurrentLanguage; if (!s_Entries.TryGetValue(key, out Entry value)) { ValidateUseKey(key, currentLanguage, options, "FormatString"); return key; } return value.FormatString(currentLanguage, key, options, args); } public static string GetString(string key) { return GetString(key, FallbackValueOptions.None); } public static string GetString(string key, Language fallbackLanguage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetString(key, FallbackValueOptions.FallbackLang(fallbackLanguage)); } public static string GetString(string key, FallbackValueOptions options) { //IL_000b: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ValidateLocalizationKey(key, "key"); Language currentLanguage = CurrentLanguage; if (!s_Entries.TryGetValue(key, out Entry value)) { ValidateUseKey(key, currentLanguage, options, "GetString"); return key; } return value.GetString(currentLanguage, key, options); } public static bool TryGetString(string key, [NotNullWhen(true)] out string? value) { return TryGetString(key, FallbackValueOptions.None, out value); } public static bool TryGetString(string key, Language fallbackLanguage, [NotNullWhen(true)] out string? value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryGetString(key, FallbackValueOptions.FallbackLang(fallbackLanguage), out value); } public static bool TryGetString(string key, FallbackValueOptions options, [NotNullWhen(true)] out string? value) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) ValidateLocalizationKey(key, "key"); if (!s_Entries.TryGetValue(key, out Entry value2)) { if (options.UseKey) { value = key; return false; } value = null; return false; } return value2.TryGetString(CurrentLanguage, key, options, out value); } public static bool HasKey([NotNullWhen(true)] string? key) { if (!string.IsNullOrWhiteSpace(key)) { return s_Entries.ContainsKey(key); } return false; } public static bool HasLocalizedValue([NotNullWhen(true)] string? key, Language language) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(key) && s_Entries.TryGetValue(key, out Entry value)) { return value.HasValueInLanguage(language); } return false; } public static uint GenerateTextBlock(string key, TextDBOptions? textDataBlockOptions = null) { ValidateLocalizationKey(key, "key"); Entry entry = s_Entries[key]; if (entry.TextBlockId.HasValue) { return entry.TextBlockId.Value; } if (textDataBlockOptions.HasValue) { entry.GenerateTextDataBlock(key, textDataBlockOptions.Value); } else { entry.GenerateTextDataBlock(key); } s_EntriesToGenerateTextDBs.Add(key); return entry.TextBlockId.Value; } public static bool TryGetTextBlockId(string key, out uint blockId) { ValidateLocalizationKey(key, "key"); if (!s_Entries.TryGetValue(key, out Entry value) || !value.TextBlockId.HasValue) { blockId = 0u; return false; } blockId = value.TextBlockId.Value; return true; } public static void AddEntry(string key, Language language, string value, TextDBOptions? textDataBlockOptions = null) { //IL_000b: 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) ValidateLocalizationKey(key, "key"); ValidateLanguage(language, "language"); if (value == null) { value = string.Empty; } bool exists; ref Entry valueRefOrAddDefault = ref CollectionsMarshal.GetValueRefOrAddDefault(s_Entries, key, out exists); if (valueRefOrAddDefault == null) { valueRefOrAddDefault = new Entry(); } valueRefOrAddDefault.AddValue(language, value); if (textDataBlockOptions.HasValue && !exists) { s_EntriesToGenerateTextDBs.Add(key); if (s_GameDataInitialized) { valueRefOrAddDefault.GenerateTextDataBlock(key, textDataBlockOptions.Value); } } } public static void LoadFromResources(string baseName, TextDBOptions? textDataBlockOptions = null) { LoadFromResources(baseName, Assembly.GetCallingAssembly(), textDataBlockOptions); } public static void LoadFromResources(string baseName, Assembly assembly, TextDBOptions? textDataBlockOptions = null) { //IL_002c: 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_0033: 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) ResourceManager resourceManager = new ResourceManager(baseName, assembly); List<Exception> list = new List<Exception>(); CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); foreach (CultureInfo cultureInfo in cultures) { bool isNeutralCulture = cultureInfo.IsNeutralCulture; Language language = GetLanguage(cultureInfo); if ((int)language == 0) { continue; } ResourceSet resourceSet; try { resourceSet = resourceManager.GetResourceSet(cultureInfo, createIfNotExists: true, tryParents: true); } catch (MissingManifestResourceException) { continue; } catch (Exception item) { list.Add(item); continue; } if (resourceSet == null) { continue; } foreach (DictionaryEntry item2 in resourceSet) { if (!(item2.Key is string text) || !(item2.Value is string value)) { continue; } bool exists; ref Entry valueRefOrAddDefault = ref CollectionsMarshal.GetValueRefOrAddDefault(s_Entries, text, out exists); if (valueRefOrAddDefault == null) { valueRefOrAddDefault = new Entry(); } valueRefOrAddDefault.AddValue(language, value, isNeutralCulture); if (textDataBlockOptions.HasValue && !exists) { s_EntriesToGenerateTextDBs.Add(text); if (s_GameDataInitialized) { valueRefOrAddDefault.GenerateTextDataBlock(text, textDataBlockOptions.Value); } } } } resourceManager.ReleaseAllResources(); if (list.Count > 0) { throw new AggregateException(list); } } private static void ValidateLocalizationKey([NotNull] string key, [CallerArgumentExpression("key")] string? paramName = null) { ArgumentNullException.ThrowIfNull(key, paramName); if (string.IsNullOrWhiteSpace(paramName)) { throw new ArgumentException("Localization key cannot be empty/whitespace", paramName ?? "key"); } } private static void ValidateLanguage(Language language, [CallerArgumentExpression("language")] string? paramName = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!Enum.IsDefined<Language>(language)) { throw new ArgumentException($"'{language}' is not a valid language", paramName ?? "language"); } } private static void ValidateUseKey(string key, Language language, FallbackValueOptions options, string useCategory) { //IL_002a: 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) if (!options.UseKey) { throw new KeyNotFoundException(string.Format(STR_NoValueFoundExceptionMsg, language, key)); } APILogger.Warn("LocalizationAPI", string.Format(STR_UseKeyGeneric, language, key, useCategory)); } private static Language GetLanguage(CultureInfo info) { //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) while (!info.IsNeutralCulture) { info = info.Parent; if (string.IsNullOrEmpty(info.Name)) { return (Language)0; } } return (Language)(info.Name switch { "en" => 1, "fr" => 2, "it" => 3, "de" => 4, "es" => 5, "ru" => 6, "pt" => 7, "pl" => 8, "ja" => 9, "ko" => 10, "zh-Hans" => 12, "zh-Hant" => 11, _ => 0, }); } private static void UpdateTextDataBlock(TextDataBlock block, Language language, string text) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected I4, but got Unknown switch (language - 1) { case 0: block.English = text; break; case 1: block.French = LanguageData.op_Implicit(text); break; case 2: block.Italian = LanguageData.op_Implicit(text); break; case 3: block.German = LanguageData.op_Implicit(text); break; case 4: block.Spanish = LanguageData.op_Implicit(text); break; case 5: block.Russian = LanguageData.op_Implicit(text); break; case 6: block.Portuguese_Brazil = LanguageData.op_Implicit(text); break; case 7: block.Polish = LanguageData.op_Implicit(text); break; case 8: block.Japanese = LanguageData.op_Implicit(text); break; case 9: block.Korean = LanguageData.op_Implicit(text); break; case 10: block.Chinese_Traditional = LanguageData.op_Implicit(text); break; case 11: block.Chinese_Simplified = LanguageData.op_Implicit(text); break; } } } [API("Network")] public static class NetworkAPI { internal class CachedEvent { public string EventName { get; set; } public Type PayloadType { get; set; } public object OnReceive { get; set; } public bool IsFreeSize { get; set; } } internal static ConcurrentDictionary<string, CachedEvent> s_EventCache = new ConcurrentDictionary<string, CachedEvent>(); public static ApiStatusInfo Status => APIStatus.Network; public static bool IsEventRegistered(string eventName) { return NetworkAPI_Impl.Instance.EventExists(eventName); } public static void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct { if (!APIStatus.Network.Ready) { if (s_EventCache.ContainsKey(eventName)) { throw new ArgumentException("An event with the name " + eventName + " has already been registered.", "eventName"); } s_EventCache.TryAdd(eventName, new CachedEvent { EventName = eventName, PayloadType = typeof(T), OnReceive = onReceive, IsFreeSize = false }); } else { NetworkAPI_Impl.Instance.RegisterEvent(eventName, onReceive); } } public static void InvokeEvent<T>(string eventName, T payload, SNet_ChannelType channelType = 2) where T : struct { //IL_0019: 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) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val, val2, num); } public static void InvokeEvent<T>(string eventName, T payload, SNet_Player target, SNet_ChannelType channelType = 2) where T : struct { //IL_0019: Unknown result type (might be due to invalid IL or missing references) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, target); } public static void InvokeEvent<T>(string eventName, T payload, List<SNet_Player> targets, SNet_ChannelType channelType = 2) where T : struct { //IL_0019: Unknown result type (might be due to invalid IL or missing references) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, targets.ToIl2Cpp()); } public static void RegisterFreeSizedEvent(string eventName, Action<ulong, byte[]> onReceiveBytes) { if (!APIStatus.Network.Ready) { if (s_EventCache.ContainsKey(eventName)) { throw new ArgumentException("An event with the name " + eventName + " has already been registered.", "eventName"); } s_EventCache.TryAdd(eventName, new CachedEvent { EventName = eventName, PayloadType = null, OnReceive = onReceiveBytes, IsFreeSize = true }); } else { NetworkAPI_Impl.Instance.RegisterFreeSizedEvent(eventName, onReceiveBytes); } } public static void InvokeFreeSizedEvent(string eventName, byte[] payload, SNet_ChannelType channelType = 2) { //IL_0019: 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) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val, val2, num); } public static void InvokeFreeSizedEvent(string eventName, byte[] payload, SNet_Player target, SNet_ChannelType channelType = 2) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, target); } public static void InvokeFreeSizedEvent(string eventName, byte[] payload, IEnumerable<SNet_Player> targets, SNet_ChannelType channelType = 2) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) SNet_SendGroup val = default(SNet_SendGroup); SNet_SendQuality val2 = default(SNet_SendQuality); int num = default(int); SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num); SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, targets.ToList().ToIl2Cpp()); } private static Il2CppStructArray<byte> MakeBytes<T>(string eventName, T payload) where T : struct { return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakePacketBytes(eventName, payload)); } private static Il2CppStructArray<byte> MakeBytes(string eventName, byte[] payload) { return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakeFreeSizedPacketBytes(eventName, payload)); } } [API("Prefab")] public static class PrefabAPI { private static Shader s_CustomGearShader; private static readonly Dictionary<uint, Action<SyringeFirstPerson>> s_SyringeActions = new Dictionary<uint, Action<SyringeFirstPerson>>(); public static ApiStatusInfo Status => APIStatus.Prefab; private static Shader CustomGearShader { get { if ((Object)(object)s_CustomGearShader == (Object)null) { s_CustomGearShader = Shader.Find("Cell/Player/CustomGearShader"); } return s_CustomGearShader; } } public static void CreateConsumable(string assetName, bool enableEmissive = false) { Object loadedAsset = AssetAPI.GetLoadedAsset(assetName); GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null; if ((Object)(object)val == (Object)null) { throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName"); } ItemEquippable obj = val.AddComponent<ItemEquippable>(); obj.m_isFirstPerson = false; ((Item)obj).m_itemModelHolder = val.transform; ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null); } public static void CreateConsumablePickup(string assetName, bool enableEmissive = false) { Object loadedAsset = AssetAPI.GetLoadedAsset(assetName); GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null; if ((Object)(object)val == (Object)null) { throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName"); } BoxCollider componentInChildren = val.GetComponentInChildren<BoxCollider>(); if ((Object)(object)componentInChildren == (Object)null) { throw new Exception("The Consumable Pickup prefab doesn't contain a BoxCollider for interaction"); } GameObject gameObject = ((Component)componentInChildren).gameObject; gameObject.layer = LayerMask.NameToLayer("Interaction"); Interact_Pickup_PickupItem val2 = gameObject.AddComponent<Interact_Pickup_PickupItem>(); ((Interact_Base)val2).m_colliderToOwn = (Collider)(object)componentInChildren; ConsumablePickup_Core obj = val.AddComponent<ConsumablePickup_Core>(); obj.m_syncComp = (Component)(object)val.AddComponent<LG_PickupItem_Sync>(); obj.m_interactComp = (Component)(object)val2; ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null); } public static void CreateConsumableInstance<T>(string assetName) where T : ConsumableInstance { Object loadedAsset = AssetAPI.GetLoadedAsset(assetName); GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null; if ((Object)(object)obj == (Object)null) { throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName"); } if (!ClassInjector.IsTypeRegisteredInIl2Cpp<T>()) { ClassInjector.RegisterTypeInIl2Cpp<T>(); } obj.layer = LayerMask.NameToLayer("Debris"); Rigidbody component = obj.GetComponent<Rigidbody>(); obj.AddComponent<ColliderMaterial>().PhysicsBody = component ?? throw new Exception("The Consumable Instance prefab doesn't contain a Rigidbody"); obj.AddComponent<T>(); } public static void CreateGearComponent(string assetName, bool enableEmissive = false) { Object loadedAsset = AssetAPI.GetLoadedAsset(assetName); GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null; if ((Object)(object)obj == (Object)null) { throw new ArgumentException("Couldnt find a game object asset with the name " + assetName, "assetName"); } obj.layer = LayerMask.NameToLayer("FirstPersonItem"); ReplaceShaderInAssetMaterials(obj, CustomGearShader, "ENABLE_FPS_RENDERING", enableEmissive ? "ENABLE_EMISSIVE" : null); } public static void CreateSyringe(uint itemPersistentId, Action<SyringeFirstPerson> onUse) { if (s_SyringeActions.ContainsKey(itemPersistentId)) { throw new ArgumentException($"{itemPersistentId} is already registered with a syringe action."); } s_SyringeActions.Add(itemPersistentId, onUse); } internal static bool OnSyringeUsed(SyringeFirstPerson syringe) { if (s_SyringeActions.TryGetValue(((GameDataBlockBase<ItemDataBlock>)(object)((Item)syringe).ItemDataBlock).persistentID, out var value)) { value(syringe); return true; } return false; } private static void ReplaceShaderInAssetMaterials(GameObject asset, Shader newShader, params string[] addedKeywords) { addedKeywords = addedKeywords.Where((string x) => !string.IsNullOrEmpty(x)).ToArray(); foreach (MeshRenderer componentsInChild in asset.GetComponentsInChildren<MeshRenderer>(true)) { foreach (Material item in (Il2CppArrayBase<Material>)(object)((Renderer)componentsInChild).materials) { item.shader = newShader; if (addedKeywords.Length != 0) { string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)item.shaderKeywords); int num = array.Length; Array.Resize(ref array, array.Length + addedKeywords.Length); for (int i = 0; i < addedKeywords.Length; i++) { array[num + i] = addedKeywords[i]; } item.shaderKeywords = Il2CppStringArray.op_Implicit(array); } } } } } [API("SoundBank")] public static class SoundBankAPI { public static ApiStatusInfo Status => APIStatus.SoundBank; public static event Action OnSoundBanksLoaded; internal static void Setup() { EventAPI.OnManagersSetup += OnLoadSoundBanks; } private static void OnLoadSoundBanks() { FileInfo[] array = (from file in Directory.CreateDirectory(Path.Combine(Paths.BepInExRootPath, "Assets", "SoundBank")).EnumerateFiles() where file.Extension.Contains(".bnk") select file).ToArray(); CollectionExtensions.Do<FileInfo>((IEnumerable<FileInfo>)array, (Action<FileInfo>)LoadBank); if (array.Any()) { SoundBankAPI.OnSoundBanksLoaded?.Invoke(); } } private unsafe static void LoadBank(FileInfo file) { //IL_0046: 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_004e: Invalid comparison between Unknown and I4 //IL_00e2: Unknown result type (might be due to invalid IL or missing references) using FileStream fileStream = file.OpenRead(); uint num = (uint)fileStream.Length; byte[] array = new byte[num]; if (fileStream.Read(array, 0, (int)num) != 0) { void* intPtr = NativeMemory.AlignedAlloc(num, 16u); Unsafe.CopyBlock(ref Unsafe.AsRef<byte>(intPtr), ref array[0], num); uint value = default(uint); AKRESULT val = AkSoundEngine.LoadBank((IntPtr)(nint)intPtr, num, ref value); if ((int)val == 1) { APILogger.Info("SoundBankAPI", $"Loaded sound bank '{file.Name}' (bankId: {value:X2})"); } else { APILogger.Error("SoundBankAPI", $"Error while loading sound bank '{file.Name}' ({val})"); } } } } [BepInPlugin("dev.gtfomodding.gtfo-api", "GTFO-API", "0.4.1")] internal class EntryPoint : BasePlugin { private Harmony m_Harmony; public override void Load() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown APILogger.Verbose("Core", "Registering API Implementations"); ClassInjector.RegisterTypeInIl2Cpp<NetworkAPI_Impl>(); ClassInjector.RegisterTypeInIl2Cpp<AssetAPI_Impl>(); APILogger.Verbose("Core", "Registering Wrappers"); ClassInjector.RegisterTypeInIl2Cpp<ItemWrapped>(); APILogger.Verbose("Core", "Registering Utilities Implementations"); ClassInjector.RegisterTypeInIl2Cpp<ThreadDispatcher_Impl>(); ClassInjector.RegisterTypeInIl2Cpp<CoroutineDispatcher_Impl>(); APILogger.Verbose("Core", "Applying Patches"); m_Harmony = new Harmony("dev.gtfomodding.gtfo-api"); m_Harmony.PatchAll(); EventAPI.Setup(); AssetAPI.Setup(); SoundBankAPI.Setup(); LevelAPI.Setup(); LocalizationAPI.Setup(); APILogger.Verbose("Core", "Plugin Load Complete"); APILogger.Warn("GTFO-API", "Syringes are currently disabled in this version"); } } [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "GTFO.API"; public const string Version = "0.4.1"; public const string VersionPrerelease = null; public const string VersionMetadata = "git1e8fe81-main"; public const string SemVer = "0.4.1+git1e8fe81-main"; public const string GitRevShort = "1e8fe81"; public const string GitRevLong = "1e8fe816dac645ea837fe046d35f0b1ec044f6db"; public const string GitBranch = "main"; public const string GitTag = "0.4.0"; public const bool GitIsDirty = false; } } namespace GTFO.API.Wrappers { public class ItemWrapped : Item { private static readonly Item__Get_pItemData Get_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Get_pItemData>("Get_pItemData", "Player.pItemData", isGeneric: false, Array.Empty<string>()); private static readonly Item__Set_pItemData Set_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Set_pItemData>("Set_pItemData", "System.Void", isGeneric: false, new string[1] { "Player.pItemData" }); private static readonly Item__GetCustomData GetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetCustomData>("GetCustomData", "Player.pItemData_Custom", isGeneric: false, Array.Empty<string>()); private static readonly Item__SetCustomData SetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetCustomData>("SetCustomData", "System.Void", isGeneric: false, new string[2] { "Player.pItemData_Custom", "System.Boolean" }); private static readonly Item__OnCustomDataUpdated OnCustomDataUpdatedBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnCustomDataUpdated>("OnCustomDataUpdated", "System.Void", isGeneric: false, new string[1] { "Player.pItemData_Custom" }); private static readonly Item__Awake AwakeBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Awake>("Awake", "System.Void", isGeneric: false, Array.Empty<string>()); private static readonly Item__OnDespawn OnDespawnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnDespawn>("OnDespawn", "System.Void", isGeneric: false, Array.Empty<string>()); private static readonly Item__Setup SetupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Setup>("Setup", "System.Void", isGeneric: false, new string[1] { "GameData.ItemDataBlock" }); private static readonly Item__OnGearSpawnComplete OnGearSpawnCompleteBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnGearSpawnComplete>("OnGearSpawnComplete", "System.Void", isGeneric: false, Array.Empty<string>()); private static readonly Item__OnPickUp OnPickUpBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnPickUp>("OnPickUp", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SetupBaseModel SetupBaseModelBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetupBaseModel>("SetupBaseModel", "System.Void", isGeneric: false, new string[1] { "ItemSetup.ItemModelSetup" }); private static readonly Item__SyncedTurnOn SyncedTurnOnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOn>("SyncedTurnOn", "System.Void", isGeneric: false, new string[2] { "Player.PlayerAgent", "AIGraph.AIG_CourseNode" }); private static readonly Item__SyncedTurnOff SyncedTurnOffBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOff>("SyncedTurnOff", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SyncedTrigger SyncedTriggerBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTrigger>("SyncedTrigger", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SyncedTriggerSecondary SyncedTriggerSecondaryBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTriggerSecondary>("SyncedTriggerSecondary", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SyncedThrow SyncedThrowBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedThrow>("SyncedThrow", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SyncedPickup SyncedPickupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedPickup>("SyncedPickup", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" }); private static readonly Item__SyncedSetKeyValue SyncedSetKeyValueBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedSetKeyValue>("SyncedSetKeyValue", "System.Void", isGeneric: false, new string[2] { "System.Int32", "System.Single" }); private static readonly Item__GetPickupInteraction GetPickupInteractionBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetPickupInteraction>("GetPickupInteraction", "Interact_Base", isGeneric: false, Array.Empty<string>()); private static readonly Item__GetItem GetItemBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetItem>("GetItem", "Item", isGeneric: false, Array.Empty<string>()); public ItemWrapped(IntPtr hdl) : base(hdl) { } public unsafe override pItemData Get_pItemData() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) pItemData* retstr = (pItemData*)stackalloc pItemData[1]; return *Get_pItemDataBase(retstr, ((Il2CppObjectBase)this).Pointer.ToPointer()); } public unsafe override void Set_pItemData(pItemData data) { Set_pItemDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &data); } public unsafe override pItemData_Custom GetCustomData() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return *GetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer()); } public unsafe override void SetCustomData(pItemData_Custom custom, bool sync) { SetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &custom, sync); } public unsafe override void OnCustomDataUpdated(pItemData_Custom customDataCopy) { OnCustomDataUpdatedBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &customDataCopy); } public unsafe override void Awake() { AwakeBase(((Il2CppObjectBase)this).Pointer.ToPointer()); } public unsafe override void OnDespawn() { OnDespawnBase(((Il2CppObjectBase)this).Pointer.ToPointer()); } public unsafe override void Setup(ItemDataBlock data) { SetupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)data).Pointer.ToPointer()); } public unsafe override void OnGearSpawnComplete() { OnGearSpawnCompleteBase(((Il2CppObjectBase)this).Pointer.ToPointer()); } public unsafe override void OnPickUp(PlayerAgent player) { OnPickUpBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)player).Pointer.ToPointer()); } public unsafe override void SetupBaseModel(ItemModelSetup setup) { SetupBaseModelBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)setup).Pointer.ToPointer()); } public unsafe override void SyncedTurnOn(PlayerAgent agent, AIG_CourseNode courseNode) { SyncedTurnOnBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer(), ((Il2CppObjectBase)courseNode).Pointer.ToPointer()); } public unsafe override void SyncedTurnOff(PlayerAgent agent) { SyncedTurnOffBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer()); } public unsafe override void SyncedTrigger(PlayerAgent agent) { SyncedTriggerBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer()); } public unsafe override void SyncedTriggerSecondary(PlayerAgent agent) { SyncedTriggerSecondaryBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer()); } public unsafe override void SyncedThrow(PlayerAgent agent) { SyncedThrowBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer()); } public unsafe override void SyncedPickup(PlayerAgent agent) { SyncedPickupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer()); } public unsafe override void SyncedSetKeyValue(int key, float value) { SyncedSetKeyValueBase(((Il2CppObjectBase)this).Pointer.ToPointer(), key, value); } public unsafe override Interact_Base GetPickupInteraction() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return new Interact_Base((IntPtr)GetPickupInteractionBase(((Il2CppObjectBase)this).Pointer.ToPointer())); } public unsafe override Item GetItem() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return new Item((IntPtr)GetItemBase(((Il2CppObjectBase)this).Pointer.ToPointer())); } } public unsafe delegate pItemData* Item__Get_pItemData(pItemData* retstr, void* _this); public unsafe delegate void Item__Set_pItemData(void* _this, void* data); public unsafe delegate pItemData_Custom* Item__GetCustomData(void* _this); public unsafe delegate void Item__SetCustomData(void* _this, pItemData_Custom* custom, bool sync); public unsafe delegate void Item__OnCustomDataUpdated(void* _this, pItemData_Custom* customDataCopy); public unsafe delegate void Item__Awake(void* _this); public unsafe delegate void Item__OnDespawn(void* _this); public unsafe delegate void Item__Setup(void* _this, void* data); public unsafe delegate void Item__OnGearSpawnComplete(void* _this); public unsafe delegate void Item__OnPickUp(void* _this, void* player); public unsafe delegate void Item__SetupBaseModel(void* _this, void* setup); public unsafe delegate void Item__SyncedTurnOn(void* _this, void* agent, void* courseNode); public unsafe delegate void Item__SyncedTurnOff(void* _this, void* agent); public unsafe delegate void Item__SyncedTrigger(void* _this, void* agent); public unsafe delegate void Item__SyncedTriggerSecondary(void* _this, void* agent); public unsafe delegate void Item__SyncedThrow(void* _this, void* agent); public unsafe delegate void Item__SyncedPickup(void* _this, void* agent); public unsafe delegate void Item__SyncedSetKeyValue(void* _this, int key, float value); public unsafe delegate void* Item__GetPickupInteraction(void* _this); public unsafe delegate void* Item__GetItem(void* _this); [Il2CppInterface(typeof(iTerminalItem))] public interface iTerminalItemWrapper { uint TerminalItemId { get; set; } string TerminalItemKey { get; set; } string OverrideCode { get; set; } Vector3 LocatorBeaconPosition { get; set; } AIG_CourseNode SpawnNode { get; set; } bool ShowInFloorInventory { get; set; } string FloorItemLocation { get; set; } eFloorInventoryObjectType FloorItemType { get; set; } eFloorInventoryObjectStatus FloorItemStatus { get; set; } Func<List<string>, List<string>> OnWantDetailedInfo { get; set; } void Setup(string key); List<string> GetDetailedInfo(List<string> defaultDetails); void PlayPing(); } [Il2CppInterface(typeof(iResourcePackReceiver))] public interface iResourcePackReceiverWrapper { bool IsLocallyOwned { get; } string InteractionName { get; } bool NeedHealth(); bool NeedDisinfection(); bool NeedWeaponAmmo(); bool NeedToolAmmo(); void GiveAmmoRel(float ammoStandardRel, float ammoSpecialRel, float ammoClassRel); void GiveHealth(float health); void GiveDisinfection(float disinfection); } [Il2CppInterface(typeof(iPlayerPingTarget))] public interface iPlayerPingTargetWrapper { eNavMarkerStyle PingTargetStyle { get; set; } } [Il2CppInterface(typeof(iWardenObjectiveItem))] public interface iWardenObjectiveItemWrapper { LG_LayerType OriginLayer { get; } AIG_CourseNode SpawnNode { get; } string PublicName { get; } Transform transform { get; } bool ObjectiveItemSolved { get; } ePickupItemStatus PickupItemStatus { get; } PlayerAgent PickedUpByPlayer { get; } void ActivateWardenObjectiveItem(); void DeactivateWardenObjectiveItem(); } } namespace GTFO.API.Utilities { public static class CoroutineDispatcher { public static Coroutine StartCoroutine(IEnumerator routine) { return CoroutineDispatcher_Impl.Instance.RunCoroutine(routine); } public static Coroutine StartInLevelCoroutine(IEnumerator routine) { return CoroutineDispatcher_Impl.Instance.RunInLevelCoroutine(routine); } } public delegate void LiveEditEventHandler(LiveEditEventArgs e); public class LiveEditEventArgs { public LiveEditEventType Type { get; set; } public string FullPath { get; set; } public string FileName { get; set; } } public enum LiveEditEventType { Created, Deleted, Renamed, Changed } public static class LiveEdit { internal const int RETRY_COUNT = 5; internal const float RETRY_INTERVAL = 0.1f; internal static readonly List<LiveEditListener> s_Listeners = new List<LiveEditListener>(); public static LiveEditListener CreateListener(string path, string filter, bool includeSubDir) { LiveEditListener liveEditListener = new LiveEditListener(path, filter, includeSubDir); s_Listeners.Add(liveEditListener); return liveEditListener; } public static void TryReadFileContent(string filepath, Action<string> onReaded) { CoroutineDispatcher.StartCoroutine(GetFileStream(filepath, 5, 0.1f, delegate(FileStream stream) { try { using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); onReaded?.Invoke(streamReader.ReadToEnd()); } catch { } })); } private static IEnumerator GetFileStream(string filepath, int retryCount, float retryInterval, Action<FileStream> onFileStreamOpened) { retryCount = Math.Max(retryCount, 1); retryInterval = Math.Max(retryInterval, 0f); WaitForSecondsRealtime wait = new WaitForSecondsRealtime(retryInterval); for (int i = 0; i < retryCount; i++) { try { FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); onFileStreamOpened?.Invoke(fileStream); fileStream.Close(); break; } catch { } yield return wait; } } } public sealed class LiveEditListener : IDisposable { private FileSystemWatcher m_Watcher; private bool m_Allocated = true; private float m_ChangedCooldownTimer; public float FileChangedEventCooldown { get; set; } = 0.05f; public event LiveEditEventHandler FileChanged; public event LiveEditEventHandler FileDeleted; public event LiveEditEventHandler FileCreated; public event LiveEditEventHandler FileRenamed; private LiveEditListener() { } internal LiveEditListener(string path, string filter, bool includeSubDir) { LiveEditListener liveEditListener = this; m_Watcher = new FileSystemWatcher { Path = path, Filter = filter, IncludeSubdirectories = includeSubDir, NotifyFilter = (NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime) }; m_Watcher.Deleted += delegate(object sender, FileSystemEventArgs e) { FileSystemEventArgs e5 = e; ThreadDispatcher.Dispatch(delegate { liveEditListener.FileDeleted?.Invoke(CreateArgs(e5, LiveEditEventType.Deleted)); }); }; m_Watcher.Created += delegate(object sender, FileSystemEventArgs e) { FileSystemEventArgs e4 = e; ThreadDispatcher.Dispatch(delegate { liveEditListener.FileCreated?.Invoke(CreateArgs(e4, LiveEditEventType.Created)); }); }; m_Watcher.Renamed += delegate(object sender, RenamedEventArgs e) { RenamedEventArgs e3 = e; ThreadDispatcher.Dispatch(delegate { liveEditListener.FileRenamed?.Invoke(CreateArgs(e3, LiveEditEventType.Renamed)); }); }; m_Watcher.Changed += delegate(object sender, FileSystemEventArgs e) { FileSystemEventArgs e2 = e; ThreadDispatcher.Dispatch(delegate { float time = Time.time; if (!(liveEditListener.m_ChangedCooldownTimer > time)) { liveEditListener.m_ChangedCooldownTimer = time + liveEditListener.FileChangedEventCooldown; liveEditListener.FileChanged?.Invoke(CreateArgs(e2, LiveEditEventType.Changed)); } }); }; m_Watcher.Error += delegate(object sender, ErrorEventArgs e) { APILogger.Error("LiveEdit", $"Path: {path} error reported! - {e.GetException()}"); }; StartListen(); } private static LiveEditEventArgs CreateArgs(FileSystemEventArgs args, LiveEditEventType type) { return new LiveEditEventArgs { FullPath = args.FullPath, FileName = Path.GetFileName(args.FullPath), Type = type }; } public void Dispose() { if (m_Allocated) { LiveEdit.s_Listeners.Remove(this); m_Allocated = false; } if (m_Watcher != null) { StopListen(); this.FileChanged = null; this.FileDeleted = null; this.FileCreated = null; this.FileRenamed = null; m_Watcher.Dispose(); } m_Watcher = null; } public void StopListen() { if (m_Watcher != null) { m_Watcher.EnableRaisingEvents = false; } } public void StartListen() { if (m_Watcher != null) { m_Watcher.EnableRaisingEvents = true; } } } internal static class MemoryUtils { private static byte[] _trampolineShellcode = new byte[12] { 72, 184, 0, 0, 0, 0, 0, 0, 0, 0, 255, 208 }; public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, string pattern, string mask, ulong sigOffset = 0uL) { return FindSignatureInBlock(block, blockSize, pattern.ToCharArray(), mask.ToCharArray(), sigOffset); } public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, char[] pattern, char[] mask, ulong sigOffset = 0uL) { for (ulong num = 0uL; num < blockSize; num++) { bool flag = true; for (uint num2 = 0u; num2 < mask.Length; num2++) { if (*(byte*)((long)num + (long)block + num2) != (byte)pattern[num2] && mask[num2] != '?') { flag = false; break; } } if (flag) { return (void*)((ulong)((long)num + (long)block) + sigOffset); } } return null; } public unsafe static byte[] MakeTrampoline(void* destination) { byte[] array = new byte[_trampolineShellcode.Length]; Array.Copy(_trampolineShellcode, 0, array, 0, _trampolineShellcode.Length); fixed (byte* ptr = array) { *(long*)(ptr + 2) = (long)destination; } return array; } public unsafe static void CreateTrampolineBetween(void* start, void* end, void* destination) { ulong num = (ulong)end - (ulong)start; if (num < (ulong)_trampolineShellcode.Length) { throw new Exception("Trampoline block size is not enough to create."); } uint flNewProtect = default(uint); if (!Kernel32.VirtualProtect(start, num, 64u, &flNewProtect)) { throw new Exception("Failed to change protection of trampoline block."); } APILogger.Verbose("MemoryUtils", "NOPing trampoline block"); for (ulong num2 = 0uL; num2 < num; num2++) { *(sbyte*)((ulong)start + num2) = -112; } APILogger.Verbose("MemoryUtils", "Creating trampoline shellcode"); byte[] array = MakeTrampoline(destination); APILogger.Verbose("MemoryUtils", "Writing trampoline shellcode"); for (ulong num3 = 0uL; num3 < (ulong)array.Length; num3++) { *(byte*)((ulong)start + num3) = array[num3]; } if (!Kernel32.VirtualProtect(start, num, flNewProtect, &flNewProtect)) { throw new Exception("Failed to revert trampoline block protection."); } } } public class PersistentData<T> where T : PersistentData<T>, new() { private const string VERSION_REGEX = "\"PersistentDataVersion\": \"(.+?)\""; private static T s_CurrentData; public static T CurrentData { get { if (s_CurrentData != null) { return s_CurrentData; } s_CurrentData = Load(); return s_CurrentData; } set { s_CurrentData = value; } } protected static string persistentPath => Path.Combine(Paths.BepInExRootPath, "GameData", "PersistentData", typeof(T).Assembly.GetName().Name, typeof(T).Name + ".json"); public virtual string PersistentDataVersion { get; set; } = "1.0.0"; public static T Load() { return Load(persistentPath); } public static T Load(string path) { T val = new T(); if (File.Exists(path)) { string text = File.ReadAllText(path); T val2; try { val2 = GTFO.API.JSON.JsonSerializer.Deserialize<T>(text); } catch (JsonException) { APILogger.Warn("JSON", "Failed to deserialize " + typeof(T).Name + ", replacing with default"); string text2 = "FAILED"; Match match = Regex.Match(text, "\"PersistentDataVersion\": \"(.+?)\""); if (match.Success) { text2 = match.Groups[1].Value + "-FAILED"; } File.WriteAllText(Path.ChangeExtension(path, null) + "-" + text2 + ".json", text); val2 = new T(); val2.Save(path); } if (val2.PersistentDataVersion != val.PersistentDataVersion) { val2.Save(Path.ChangeExtension(path, null) + "-" + val2.PersistentDataVersion + ".json"); val.Save(path); } else { val = val2; } } else { val.Save(path); } return val; } public void Save() { Save(persistentPath); } public void Save(string path) { string contents = GTFO.API.JSON.JsonSerializer.Serialize((T)this); string directoryName = Path.GetDirectoryName(path); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(path, contents); } } public static class RegexUtils { private static readonly Regex s_VectorRegex = new Regex("-?[0-9.]+"); public static bool TryParseVectorString(string input, out float[] vectorArray) { try { MatchCollection matchCollection = s_VectorRegex.Matches(input); int count = matchCollection.Count; if (count < 1) { throw new Exception(); } vectorArray = new float[count]; for (int i = 0; i < count; i++) { Match match = matchCollection[i]; vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture); } return true; } catch { vectorArray = null; return false; } } } public static class StringUtils { private static readonly uint[] _lookup32 = ((Func<uint[]>)delegate { uint[] array = new uint[256]; for (int i = 0; i < 256; i++) { string text = i.ToString("X2"); if (BitConverter.IsLittleEndian) { array[i] = text[0] + ((uint)text[1] << 16); } else { array[i] = text[1] + ((uint)text[0] << 16); } } return array; })(); private unsafe static readonly uint* _lookup32Ptr = (uint*)(void*)GCHandle.Alloc(_lookup32, GCHandleType.Pinned).AddrOfPinnedObject(); public unsafe static string FromByteArrayAsHex(byte[] bytes) { char[] array = new char[bytes.Length * 2]; fixed (byte* ptr3 = bytes) { fixed (char* ptr = array) { uint* ptr2 = (uint*)ptr; for (int i = 0; i < bytes.Length; i++) { ptr2[i] = _lookup32Ptr[(int)ptr3[i]]; } } } return new string(array); } } public static class ThreadDispatcher { public static void Dispatch(Action action) { ThreadDispatcher_Impl.Instance.EnqueueAction(action); } } } namespace GTFO.API.Utilities.Impl { internal class CoroutineDispatcher_Impl : MonoBehaviour { private bool m_HasInLevelCoroutines; private readonly List<Coroutine> m_InLevelCoroutines; private static CoroutineDispatcher_Impl s_Instance; public static CoroutineDispatcher_Impl Instance { get { if ((Object)(object)s_Instance == (Object)null) { CoroutineDispatcher_Impl coroutineDispatcher_Impl = Object.FindObjectOfType<CoroutineDispatcher_Impl>(); if ((Object)(object)coroutineDispatcher_Impl != (Object)null) { s_Instance = coroutineDispatcher_Impl; } } return s_Instance; } } static CoroutineDispatcher_Impl() { AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded; } private static void OnAssetsLoaded() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0032: Expected O, but got Unknown if (!((Object)(object)s_Instance != (Object)null)) { GameObject val = new GameObject(); CoroutineDispatcher_Impl coroutineDispatcher_Impl = val.AddComponent<CoroutineDispatcher_Impl>(); ((Object)val).name = "GTFO-API Coroutine Dispatcher"; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); s_Instance = coroutineDispatcher_Impl; } } private void Update() { if (m_HasInLevelCoroutines && !GameStateManager.IsInExpedition) { m_InLevelCoroutines.ForEach(delegate(Coroutine coroutine) { ((MonoBehaviour)this).StopCoroutine(coroutine); }); m_HasInLevelCoroutines = false; } } [HideFromIl2Cpp] internal Coroutine RunCoroutine(IEnumerator routine) { return MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine); } [HideFromIl2Cpp] internal Coroutine RunInLevelCoroutine(IEnumerator routine) { if (!GameStateManager.IsInExpedition) { APILogger.Error("CoroutineDispatcher", "Cannot run InLevelCoroutine while you're not in level!"); return null; } Coroutine val = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine); m_InLevelCoroutines.Add(val); m_HasInLevelCoroutines = true; return val; } } internal class ThreadDispatcher_Impl : MonoBehaviour { private readonly Queue<Action> s_ActionQueue = new Queue<Action>(); private static ThreadDispatcher_Impl s_Instance; public static ThreadDispatcher_Impl Instance { get { if ((Object)(object)s_Instance == (Object)null) { ThreadDispatcher_Impl threadDispatcher_Impl = Object.FindObjectOfType<ThreadDispatcher_Impl>(); if ((Object)(object)threadDispatcher_Impl != (Object)null) { s_Instance = threadDispatcher_Impl; } } return s_Instance; } } public ThreadDispatcher_Impl(IntPtr intPtr) : base(intPtr) { } static ThreadDispatcher_Impl() { AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded; } private static void OnAssetsLoaded() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0032: Expected O, but got Unknown if (!((Object)(object)s_Instance != (Object)null)) { GameObject val = new GameObject(); ThreadDispatcher_Impl threadDispatcher_Impl = val.AddComponent<ThreadDispatcher_Impl>(); ((Object)val).name = "GTFO-API Thread Dispatcher"; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); s_Instance = threadDispatcher_Impl; } } [HideFromIl2Cpp] internal void EnqueueAction(Action action) { lock (s_ActionQueue) { s_ActionQueue.Enqueue(action); } } internal void Update() { lock (s_ActionQueue) { while (s_ActionQueue.Count > 0) { s_ActionQueue.Dequeue()?.Invoke(); } } } } } namespace GTFO.API.Resources { public class ApiStatusInfo { public bool Created { get; internal set; } public bool Ready { get; internal set; } } public static class APIStatus { private static GameObject s_ScriptHolder; public static ApiStatusInfo Asset { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Event { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo GameData { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Localization { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Il2Cpp { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Level { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Network { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo Prefab { get; internal set; } = new ApiStatusInfo(); public static ApiStatusInfo SoundBank { get; internal set; } = new ApiStatusInfo(); internal static GameObject ScriptHolder { get { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if ((Object)(object)s_ScriptHolder == (Object)null) { s_ScriptHolder = new GameObject(); ((Object)s_ScriptHolder).name = "GTFO-API Script Holder"; ((Object)s_ScriptHolder).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)s_ScriptHolder); } return s_ScriptHolder; } } internal static void CreateApi<T>(string apiName) where T : Component { ApiStatusInfo apiStatusInfo = (ApiStatusInfo)(typeof(APIStatus).GetProperty(apiName)?.GetValue(null)); if (apiStatusInfo == null) { throw new ArgumentException("Couldn't find API status for " + apiName, "apiName"); } if (!apiStatusInfo.Created && !((Object)(object)ScriptHolder.GetComponent<T>() != (Object)null)) { APILogger.Verbose("Core", "Creating API " + apiName); ScriptHolder.AddComponent<T>(); apiStatusInfo.Created = true; } } } internal static class RuntimeData { public static Dictionary<InventorySlot, string[]> BotFavorites; } public static class ShaderConstants { public const string CUSTOM_GEAR_SHADER = "Cell/Player/CustomGearShader"; } public static class NetworkConstants { public const string Magic = "GAPI_KSQK"; public const byte MagicSize = 9; public const ulong VersionSignature = 18374688171108015565uL; } } namespace GTFO.API.Patches { [HarmonyPatch(typeof(CellSettingsApply), "ApplyLanguage")] internal static class ApplyLanguage_Patches { private static bool s_LanguageChanged; [HarmonyWrapSafe] public static void Prefix(int value) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 s_LanguageChanged = (int)Text.TextLocalizationService.CurrentLanguage != value; } [HarmonyWrapSafe] public static void Postfix() { if (s_LanguageChanged) { LocalizationAPI.LanguageChanged(); } } } [HarmonyPatch(typeof(AssetShardManager))] internal class AssetShardManager_Patches { [HarmonyPatch("Setup")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Setup_Postfix() { if (!APIStatus.Asset.Created) { APIStatus.CreateApi<AssetAPI_Impl>("Asset"); } } } [HarmonyPatch(typeof(Builder))] internal class Builder_Patches { [HarmonyPatch("Build")] [HarmonyWrapSafe] [HarmonyPostfix] private static void BuildStart_Postfix() { LevelAPI.BuildStart(); } [HarmonyPatch("BuildDone")] [HarmonyWrapSafe] [HarmonyPostfix] private static void BuildDone_Postfix() { LevelAPI.BuildDone(); } } [HarmonyPatch(typeof(GameDataInit))] internal class GameDataInit_Patches { private struct PluginWhitelistInfo { public string GUID; public string Name; public string Version; public string Checksum; } private static PluginWhitelistInfo[] FetchPluginWhitelist() { using HttpClient httpClient = new HttpClient(); using Stream stream = httpClient.GetStreamAsync("https://raw.githubusercontent.com/GTFO-Modding/GTFO-API-PluginWhitelist/main/whitelist.txt").GetAwaiter().GetResult(); using StreamReader streamReader = new StreamReader(stream); string[] array = streamReader.ReadToEnd().Split('\n', StringSplitOptions.RemoveEmptyEntries); PluginWhitelistInfo[] array2 = new PluginWhitelistInfo[array.Length]; for (int i = 0; i < array2.Length; i++) { string[] array3 = array[i].Split(":"); array2[i] = new PluginWhitelistInfo { GUID = array3[0], Name = array3[1], Version = array3[2], Checksum = array3[3].TrimEnd('\r') }; } return array2; } [HarmonyPatch("Initialize")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Initialize_Postfix() { Analytics.enabled = false; GameDataAPI.InvokeGameDataInit(); if (!APIStatus.Network.Created) { APIStatus.CreateApi<NetworkAPI_Impl>("Network"); } } private static void RemoveRequirementFromList(List<ExpeditionInTierData> list) { //IL_0019: 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_001f: 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) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 Enumerator<ExpeditionInTierData> enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionInTierData current = enumerator.Current; if (current.Enabled) { eExpeditionAccessibility accessibility = current.Accessibility; if ((int)accessibility == 0 || accessibility - 4 <= 1) { current.Accessibility = (eExpeditionAccessibility)2; } } } } } [HarmonyPatch(typeof(GearManager))] internal static class GearManager_Patches { private unsafe delegate IntPtr ReadFromDiskDelegate(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo); private unsafe delegate void SaveToDiskDelegate(IntPtr path, IntPtr obj, Il2CppMethodInfo* methodInfo); private static bool m_PatchApplied; private static INativeDetour s_ReadFromDiskDetour; private static ReadFromDiskDelegate s_ReadFromDiskOriginal; private static INativeDetour s_SaveToDiskDetour; private static SaveToDiskDelegate s_SaveToDiskOriginal; private static string FavoritesDirectory => Path.Combine(Paths.BepInExRootPath, "GameData", "Favorites"); private static string FavoritePath => Path.Combine(FavoritesDirectory, "Gear.json"); private static string BotFavoritePath => Path.Combine(FavoritesDirectory, "BotGear.json"); [HarmonyPatch("Setup")] [HarmonyWrapSafe] [HarmonyPrefix] private unsafe static void Setup_Prefix() { if (!m_PatchApplied) { if (!Directory.Exists(FavoritesDirectory)) { Directory.CreateDirectory(FavoritesDirectory); } string methodName = "SaveToDisk"; APILogger.Verbose("GearManager_Patches", "Applying ReadFromDisk Patch"); s_ReadFromDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, ReadFromDiskDelegate>("ReadFromDisk", "T", new string[2] { typeof(string).FullName, typeof(bool).MakeByRefType().FullName }, new Type[1] { typeof(GearFavoritesData) }, (ReadFromDiskDelegate)Patch_ReadFromDisk, out s_ReadFromDiskOriginal); APILogger.Verbose("GearManager_Patches", "Applying SaveToDisk Patch"); s_SaveToDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, SaveToDiskDelegate>(methodName, typeof(void).FullName, new string[2] { typeof(string).FullName, "T" }, new Type[1] { typeof(GearFavoritesData) }, (SaveToDiskDelegate)Patch_SaveToDisk, out s_SaveToDiskOriginal); m_PatchApplied = true; } } private unsafe static IntPtr Patch_ReadFromDisk(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown string text = String.op_Implicit(new String(path)); if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase)) { return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), createNew, methodInfo); } if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase)) { return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), createNew, methodInfo); } return s_ReadFromDiskOriginal(path, createNew, methodInfo); } private unsafe static void Patch_SaveToDisk(IntPtr path, IntPtr favData, Il2CppMethodInfo* methodInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown string text = String.op_Implicit(new String(path)); if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase)) { s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), favData, methodInfo); } else if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase)) { s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), favData, methodInfo); if (File.Exists(text)) { File.Delete(text); } } else { s_SaveToDiskOriginal(path, favData, methodInfo); } } } [HarmonyPatch(typeof(Global))] internal class Global_Patches { [HarmonyPatch("OnLevelCleanup")] [HarmonyWrapSafe] [HarmonyPostfix] private static void LevelCleanup_Postfix() { LevelAPI.LevelCleanup(); } } [HarmonyPatch(typeof(RundownManager))] internal class RundownManager_Patches { [HarmonyPatch("SetActiveExpedition")] [HarmonyWrapSafe] [HarmonyPostfix] private static void SetActiveExpedition_Postfix(pActiveExpedition expPackage, ExpeditionInTierData expTierData) { LevelAPI.ExpeditionUpdated(expPackage, expTierData); } } [HarmonyPatch(typeof(SNet_Replication))] internal class SNet_Replication_Patches { [HarmonyPatch("RecieveBytes")] [HarmonyWrapSafe] [HarmonyPrefix] public static bool RecieveBytes_Prefix(Il2CppStructArray<byte> bytes, uint size, ulong messagerID) { if (size < 12) { return true; } byte[] array = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes); ushort num = BitConverter.ToUInt16(array, 0); if (NetworkAPI_Impl.Instance.m_ReplicatorKey == num) { string @string = Encoding.ASCII.GetString(array, 2, 9); if (@string != "GAPI_KSQK") { APILogger.Verbose("NetworkApi", $"Received invalid magic from {messagerID} ({@string} != {9})."); return true; } ulong num2 = BitConverter.ToUInt64(array, 11); if ((num2 & 0xFF00000000000000uL) != 18374686479671623680uL) { APILogger.Verbose("NetworkApi", $"Received invalid version signature from {messagerID}."); return true; } if (num2 != NetworkAPI_Impl.Instance.m_Signature) { APILogger.Error("NetworkApi", $"Received incompatible version signature, cannot unmask packet. Is {messagerID} on the same version?. ({num2} != {NetworkAPI_Impl.Instance.m_Signature})"); return false; } ushort num3 = BitConverter.ToUInt16(array, 19); string string2 = Encoding.UTF8.GetString(array, 21, num3); if (!NetworkAPI.IsEventRegistered(string2)) { APILogger.Error("NetworkApi", $"{messagerID} invoked an event {string2} which isn't registered."); return false; } NetworkAPI_Impl.Instance.HandlePacket(string2, messagerID, array, 21 + num3); return false; } return true; } } } namespace GTFO.API.Patches.Native { internal class SyringeFirstPerson_Patch : NativePatch<SyringeFirstPerson_Patch.SyringeUsedDelegate> { [UnmanagedFunctionPointer(CallingConvention.FastCall)] public unsafe delegate eSyringeType SyringeUsedDelegate(void* pSyringe); public unsafe override void* MethodPtr => Il2CppAPI.GetIl2CppMethod<_ApplySyringe_d__18>("MoveNext", "System.Boolean", isGeneric: false, Array.Empty<string>()); public override string JmpStartSig => "Æ\u0081\u00b4\0\0\0\u0001\u008b\u0087Ð\u0001\0\0\u0085À"; public override string JmpStartMask => "xxxxxxxxxxxxxxx"; public override byte[] CodeCave => new byte[10] { 198, 129, 180, 0, 0, 0, 1, 72, 137, 249 }; public override uint TrampolineSize => 13u; public unsafe override SyringeUsedDelegate To => OnSyringeApplyEffect; public unsafe static eSyringeType OnSyringeApplyEffect(void* pSyringe) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) SyringeFirstPerson val = new SyringeFirstPerson(new IntPtr(pSyringe)); if (PrefabAPI.OnSyringeUsed(val)) { return (eSyringeType)(-1); } return val.m_type; } } } namespace GTFO.API.Native { internal static class Kernel32 { [DllImport("kernel32.dll")] public unsafe static extern void* VirtualAlloc(void* lpAddress, ulong dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public unsafe static extern bool VirtualProtect(void* lpAddress, ulong dwSize, uint flNewProtect, uint* lpflOldProtect); } internal static class MSVCRT { [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern void* memcpy(void* destination, void* source, long num); } public abstract class NativePatch<T> where T : Delegate { private static readonly byte[] s_CodeCaveHeader = new byte[4] { 72, 131, 236, 40 }; private static readonly byte[] s_CodeCaveFooter = new byte[17] { 72, 184, 0, 0, 0, 0, 0, 0, 0, 0, 255, 208, 72, 131,
BepInEx/plugins/GTFuckingXp.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using EndskApi.Api; using EndskApi.Enums.Menus; using EndskApi.Information.EnemyKill; using EndskApi.Information.Menus; using EndskApi.Manager; using EndskApi.Scripts; using Enemies; using FloatingTextAPI; using GTFO.API; using GTFuckingXP.Communication; using GTFuckingXP.Enums; using GTFuckingXP.Extensions; using GTFuckingXP.Information; using GTFuckingXP.Information.ClassSelector; using GTFuckingXP.Information.Enemies; using GTFuckingXP.Information.Level; using GTFuckingXP.Information.NetworkingInfo; using GTFuckingXP.Managers; using GTFuckingXP.Patches; using GTFuckingXP.Patches.SelectLevelPatches; using GTFuckingXP.Scripts; using GTFuckingXP.StolenCode; using GTFuckingXp.Managers; using GTFuckingXp.Patches; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("GTFuckingXp")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")] [assembly: AssemblyProduct("GTFuckingXp")] [assembly: AssemblyTitle("GTFuckingXp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace GTFuckingXp { [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "GTFuckingXp"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitc03396b-dirty-master"; public const string SemVer = "1.0.0+gitc03396b-dirty-master"; public const string GitRevShort = "c03396b-dirty"; public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const bool GitIsDirty = true; } } namespace GTFuckingXp.Patches { [HarmonyPatch(typeof(Dam_EnemyDamageBase))] public static class EnemyDamageBasePatches { [HarmonyPatch("MeleeDamage")] [HarmonyPrefix] public static void MeleePrefix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent) { if (((Agent)__instance.Owner).Alive && (Object)(object)sourceAgent != (Object)null && sourceAgent.IsLocallyOwned) { float num = dam; LogManager.Debug($"Melee damage from local player registered. {num} was scaled up to:"); num *= CacheApiWrapper.GetActiveLevel().MeleeDamageMultiplier; LogManager.Debug($"{num}"); dam = num; } } [HarmonyBefore(new string[] { "Endskill.GTFuckingXP", "com.dak.DamageNumbers" })] [HarmonyPatch("BulletDamage")] [HarmonyPrefix] public static void BulletPostfix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent) { if (((Agent)__instance.Owner).Alive && (Object)(object)sourceAgent != (Object)null && sourceAgent.IsLocallyOwned) { float num = dam; LogManager.Debug($"Bullet damage from local player registered. {num} was scaled to:"); num *= CacheApiWrapper.GetActiveLevel().WeaponDamageMultiplier; LogManager.Debug($"{num}"); dam = num; } } } } namespace GTFuckingXp.Managers { public static class EnemyKillManager { public static void Setup() { EnemyKillApi.AddEnemyKilledCallback((Action<EnemyKillDistribution>)EnemyKilled); } public static void EnemyKilled(EnemyKillDistribution info) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_00da: 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) if ((int)info.lastHitType == 2) { GiveXpToEveryone(info.KilledEnemyAgent); return; } EnemyXp enemyXp = GetEnemyXp(info.KilledEnemyAgent); Vector3 position = info.KilledEnemyAgent.Position; position.y += 1f; Enumerator<SNet_Player> enumerator = SNet.LobbyPlayers.GetEnumerator(); XpHandler xpHandler = default(XpHandler); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; if (current.IsBot) { continue; } if (info.LastHitDealtBy.Owner.PlayerSlot.index == current.PlayerSlot.index) { if (current.IsLocal) { if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { xpHandler.AddXp(enemyXp, position); } } else { NetworkApiXpManager.SendReceiveXp(current, enemyXp, position, forceDebuffXp: false); } continue; } float damageDealtBySnet = info.GetDamageDealtBySnet(current); if (damageDealtBySnet > 0.5f) { float num = damageDealtBySnet / ((Dam_SyncedDamageBase)info.KilledEnemyAgent.Damage).HealthMax; LogManager.Debug($"percentageDealt = {num} and damageDealt is {damageDealtBySnet}"); NetworkApiXpManager.SendStaticXpInfo(current, (uint)((float)enemyXp.XpGain * num), (uint)((float)enemyXp.DebuffXp * num), (int)((float)enemyXp.LevelScalingXpDecrese * num), position); } } } private static void GiveXpToEveryone(EnemyAgent killedEnemy) { //IL_0009: 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_0011: 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_0036: Unknown result type (might be due to invalid IL or missing references) EnemyXp enemyXp = GetEnemyXp(killedEnemy); Vector3 position = killedEnemy.Position; position.y += 1f; XpHandler xpHandler = default(XpHandler); if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { xpHandler.AddXp(enemyXp, position, forceDebuffXp: true, "<#F30>"); } NetworkApiXpManager.SendHalfAssedXp(enemyXp, position, forceDebuffXp: true); } private static EnemyXp GetEnemyXp(EnemyAgent killedEnemy) { EnemyAgent killedEnemy2 = killedEnemy; List<EnemyXp> instance = CacheApi.GetInstance<List<EnemyXp>>("GTF_XP"); EnemyXp enemyXp = instance.FirstOrDefault((EnemyXp it) => it.EnemyId == killedEnemy2.EnemyDataID); if (enemyXp == null) { LogManager.Warn($"There was no enemy XP data found for {killedEnemy2.EnemyDataID}!"); enemyXp = new EnemyXp(killedEnemy2.EnemyDataID, ((Object)killedEnemy2).name, 0u, 0u, 0); instance.Add(enemyXp); CacheApi.SaveInstance<List<EnemyXp>>(instance, "GTF_XP"); } LogManager.Debug($"Enemy kill was registered. Enemy XpData was {enemyXp.XpGain}."); return enemyXp; } } } namespace GTFuckingXP.StolenCode { public static class MtfoUtils { public static bool PluginExists; public static bool DataLoaded; public static string CustomPath { get; private set; } public static string Version { get; private set; } static MtfoUtils() { CustomPath = string.Empty; Version = string.Empty; PluginExists = false; DataLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info)) { return; } PluginExists = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => !x.IsDynamic && x.Location == info.Location); if (assembly == null) { throw new Exception("couldn't locate the MTFO assembly"); } Type[] types = assembly.GetTypes(); Type type = types.FirstOrDefault((Type x) => x.Name == "ConfigManager"); Type type2 = types.FirstOrDefault((Type x) => x.Name == "MTFO"); if (type2 == null) { throw new Exception("couldn't locate MTFO's EntryPoint"); } if (type == null) { throw new Exception("couldn't locate MTFO's ConfigManager"); } FieldInfo field = type2.GetField("VERSION", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); if (field == null) { throw new Exception("couldn't locate MTFO's Version"); } if (field2 == null) { throw new Exception("couldn't locate MTFO's CustomPath"); } CustomPath = (string)field2.GetValue(null); Version = (string)field.GetValue(null); DataLoaded = true; Type type3 = types.FirstOrDefault((Type x) => x.Name == "HotReloader"); } catch (Exception ex) { LogManager.Error(ex.ToString()); } } } } namespace GTFuckingXP.Scripts { public class BlinkKnife : MonoBehaviour { public void Update() { } } public class DevModeTools : MonoBehaviour { private static bool _guiInitialized; private static GUIStyle _normalStyle; private readonly float _xPos = 30f; private readonly float _yPos = (float)(Screen.height / 2) - 300f; private bool _active = true; private string _addXpNumber; private float _timeTillXpNumberInvalid; public DevModeTools(IntPtr intPtr) : base(intPtr) { } public void Update() { if (Input.GetKeyDown((KeyCode)127)) { _active = !_active; } if (!_active) { return; } if (Input.GetKeyDown((KeyCode)270) && XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber + 1, out var cheatedXp)) { CheatedXpMessage(cheatedXp); } if (Input.GetKeyDown((KeyCode)269) && XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber - 1, out var cheatedXp2)) { CheatedXpMessage(cheatedXp2); } if (Input.GetKeyDown((KeyCode)268)) { XpApi.ReloadData(); } if (Input.GetKeyDown((KeyCode)267)) { List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP"); LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); int num = instance.IndexOf(currentLevelLayout); if (instance.Count <= num + 1) { XpApi.ChangeCurrentLevelLayout(instance[0]); } else { XpApi.ChangeCurrentLevelLayout(instance[num + 1]); } } if (Input.GetKeyDown((KeyCode)256)) { AddCharToXpNumber("0"); } if (Input.GetKeyDown((KeyCode)257)) { AddCharToXpNumber("1"); } if (Input.GetKeyDown((KeyCode)258)) { AddCharToXpNumber("2"); } if (Input.GetKeyDown((KeyCode)259)) { AddCharToXpNumber("3"); } if (Input.GetKeyDown((KeyCode)260)) { AddCharToXpNumber("4"); } if (Input.GetKeyDown((KeyCode)261)) { AddCharToXpNumber("5"); } if (Input.GetKeyDown((KeyCode)262)) { AddCharToXpNumber("6"); } if (Input.GetKeyDown((KeyCode)263)) { AddCharToXpNumber("7"); } if (Input.GetKeyDown((KeyCode)264)) { AddCharToXpNumber("8"); } if (Input.GetKeyDown((KeyCode)265)) { AddCharToXpNumber("9"); } if (Input.GetKeyDown((KeyCode)271) && !string.IsNullOrEmpty(_addXpNumber)) { XpApi.AddXp(Convert.ToUInt32(_addXpNumber)); PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), "Cheated " + _addXpNumber + "XP", (PlayerAgent)null); } } public void OnGUI() { //IL_004a: 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_009c: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_0043: Expected O, but got Unknown if (_active) { if (!_guiInitialized) { _normalStyle = new GUIStyle(GUI.skin.GetStyle("label")) { fontSize = 22 }; _guiInitialized = true; } GUI.contentColor = Color.white; GUI.Label(new Rect(_xPos, _yPos, 400f, 30f), "Xp dev tools:", _normalStyle); GUI.Label(new Rect(_xPos, _yPos + 25f, 400f, 30f), "Reload xp data : Keypad*", _normalStyle); GUI.Label(new Rect(_xPos, _yPos + 50f, 400f, 30f), "Change class : Keypad/", _normalStyle); GUI.Label(new Rect(_xPos, _yPos + 75f, 400f, 30f), "Level up : Keypad+", _normalStyle); GUI.Label(new Rect(_xPos, _yPos + 100f, 400f, 30f), "Level down : Keypad-", _normalStyle); GUI.Label(new Rect(_xPos, _yPos + 125f, 400f, 30f), "AddXP \"" + _addXpNumber + "\" KeypadEnter to add XP", _normalStyle); } } private void AddCharToXpNumber(string number) { if (Time.time > _timeTillXpNumberInvalid) { _addXpNumber = string.Empty; } _addXpNumber += number; _timeTillXpNumberInvalid = Time.time + 2f; } private void CheatedXpMessage(float xpAmount) { PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), $"Cheated {xpAmount}XP", (PlayerAgent)null); } } internal class DevTools : BaseMenu { public DevTools(IntPtr intPtr) : base(intPtr) { //IL_0017: 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_0045: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown ((BaseMenu)this).PageTitle = "Xp dev tools"; base._currentState = (MenuStates)2; base._tools.Add(new Tool("Reload xp data", MenuInputProvider.F1, false, (Action<Tool>)ReloadData, (Action<Tool, bool>)null, false)); base._tools.Add(new Tool("Change class", MenuInputProvider.F2, false, (Action<Tool>)ChangeClass, (Action<Tool, bool>)null, false)); base._tools.Add(new Tool("Level up", MenuInputProvider.F3, false, (Action<Tool>)LevelUp, (Action<Tool, bool>)null, false)); base._tools.Add(new Tool("Level down", MenuInputProvider.F4, false, (Action<Tool>)LevelDown, (Action<Tool, bool>)null, false)); } protected override void Update() { ((BaseMenu)this).Update(); } public void ReloadData(Tool _) { XpApi.ReloadData(); } public void LevelUp(Tool _) { if (XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber + 1, out var cheatedXp)) { CheatedXpMessage(cheatedXp); } } public void LevelDown(Tool _) { if (XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber - 1, out var cheatedXp)) { CheatedXpMessage(cheatedXp); } } public void ChangeClass(Tool _) { List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP"); LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); int num = instance.IndexOf(currentLevelLayout); if (instance.Count <= num + 1) { XpApi.ChangeCurrentLevelLayout(instance[0]); } else { XpApi.ChangeCurrentLevelLayout(instance[num + 1]); } } private void CheatedXpMessage(float xpAmount) { PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), $"Cheated {xpAmount}XP", (PlayerAgent)null); } } internal class XpBar : MonoBehaviour { private RectTransform _xpBar; private SpriteRenderer _xpProgressBar; private TextMeshPro _textUi; public XpBar(IntPtr intPtr) : base(intPtr) { XpBarStuff(); } public void UpdateUiString(Level currentLevel, Level nextLevel, uint currentTotalXp, string header) { //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); string text; if (string.IsNullOrEmpty(currentLevel.CustomLevelStatsText)) { if (nextLevel != null) { uint num = currentTotalXp - currentLevel.TotalXpRequired; uint value = nextLevel.TotalXpRequired - currentLevel.TotalXpRequired; StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2); handler.AppendLiteral("Classname: "); handler.AppendFormatted(header); stringBuilder3.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(10, 2, stringBuilder2); handler.AppendLiteral("MaxHP "); handler.AppendFormatted(currentLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp()); handler.AppendLiteral(" => "); handler.AppendFormatted(nextLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp()); stringBuilder4.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(7, 2, stringBuilder2); handler.AppendLiteral("MD "); handler.AppendFormatted(currentLevel.MeleeDamageMultiplier); handler.AppendLiteral(" => "); handler.AppendFormatted(nextLevel.MeleeDamageMultiplier); stringBuilder5.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(7, 2, stringBuilder2); handler.AppendLiteral("WD "); handler.AppendFormatted(currentLevel.WeaponDamageMultiplier); handler.AppendLiteral(" => "); handler.AppendFormatted(nextLevel.WeaponDamageMultiplier); stringBuilder6.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(13, 3, stringBuilder2); handler.AppendLiteral("Level "); handler.AppendFormatted(currentLevel.LevelNumber); handler.AppendLiteral(" => "); handler.AppendFormatted(num); handler.AppendLiteral(" / "); handler.AppendFormatted(value); stringBuilder7.AppendLine(ref handler); ((Component)_xpProgressBar).gameObject.SetActive(false); double num2 = (double)num / Convert.ToDouble(value); _xpProgressBar.size = new Vector2((float)(num2 * 300.0), 20f); } else { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2); handler.AppendLiteral("Classname: "); handler.AppendFormatted(header); stringBuilder8.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2); handler.AppendLiteral("MaxHP "); handler.AppendFormatted(currentLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp()); stringBuilder9.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2); handler.AppendLiteral("MD "); handler.AppendFormatted(currentLevel.MeleeDamageMultiplier); stringBuilder10.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2); handler.AppendLiteral("WD "); handler.AppendFormatted(currentLevel.WeaponDamageMultiplier); stringBuilder11.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2); handler.AppendLiteral("Level "); handler.AppendFormatted(currentLevel.LevelNumber); stringBuilder12.AppendLine(ref handler); ((Component)_xpProgressBar).gameObject.SetActive(false); } text = stringBuilder.ToString(); } else { stringBuilder.Append(currentLevel.CustomLevelStatsText); text = stringBuilder.ToString(); if (nextLevel == null) { ((Component)_xpProgressBar).gameObject.SetActive(false); text = string.Format(text, $"Level {currentLevel.LevelNumber}"); } else { uint num3 = currentTotalXp - currentLevel.TotalXpRequired; uint value2 = nextLevel.TotalXpRequired - currentLevel.TotalXpRequired; double num4 = (double)num3 / Convert.ToDouble(value2); _xpProgressBar.size = new Vector2((float)(num4 * 300.0), 20f); text = string.Format(text, $"Level {currentLevel.LevelNumber} => {num3} / {value2}"); } } ((TMP_Text)_textUi).text = text; ((TMP_Text)_textUi).ForceMeshUpdate(false, false); } public void HideTextUi() { ((TMP_Text)_textUi).text = ""; ((TMP_Text)_textUi).ForceMeshUpdate(false, false); } public void XpBarStuff() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (!CacheApi.TryGetInstance<RectTransform>(ref _xpBar, "GTF_XP", false) || !CacheApi.TryGetInstance<SpriteRenderer>(ref _xpProgressBar, "GTF_XP", false) || !CacheApi.TryGetInstance<TextMeshPro>(ref _textUi, "GTF_XP", false)) { PUI_LocalPlayerStatus playerStatus = GuiManager.Current.m_playerLayer.m_playerStatus; _xpBar = ((Component)((Component)playerStatus.m_health2).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("XpBarRenderer"); ((Component)_xpBar).transform.Translate(0f, (float)Screen.height * 50f / 2560f, 0f); ((Transform)_xpBar).Rotate(0f, 180f, 0f); ((Renderer)((Component)((Transform)_xpBar).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false; _xpProgressBar = ((Component)((Transform)_xpBar).GetChild(1)).GetComponent<SpriteRenderer>(); _xpProgressBar.size = new Vector2(3f, 10f); _xpProgressBar.color = new Color(1f, 64f / 85f, 0.79607844f); _textUi = ((Component)GuiManager.Current.m_watermarkLayer.m_watermark.m_watermarkText).gameObject.Instantiate<TextMeshPro>("XpText"); _textUi.transform.Translate(new Vector3(-120f, 0f, 0f)); CacheApi.SaveInstance<TextMeshPro>(_textUi, "GTF_XP"); CacheApi.SaveInstance<RectTransform>(_xpBar, "GTF_XP"); CacheApi.SaveInstance<SpriteRenderer>(_xpProgressBar, "GTF_XP"); ((Component)_xpBar).gameObject.SetActive(false); } } } internal class XpHandler : MonoBehaviour { private bool _hasDebuff; private float _nextUpdate; public uint CurrentTotalXp { get; internal set; } public Level NextLevel { get; internal set; } public bool IsMaxLevel => NextLevel == null; public XpHandler(IntPtr intPtr) : base(intPtr) { } public void Awake() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (CacheApiWrapper.TryGetXpStorageData(out (LevelLayout, uint) checkpointData)) { LogManager.Message("Found old xp storage data!"); CacheApiWrapper.SetCurrentLevelLayout(checkpointData.Item1); Level level0 = checkpointData.Item1.Levels.First((Level it) => it.LevelNumber == 0); NextLevel = checkpointData.Item1.Levels.FirstOrDefault((Level it) => it.LevelNumber == level0.LevelNumber + 1); CacheApiWrapper.SetActiveLevel(level0, sendToOtherPeople: false); CurrentTotalXp = 0u; AddXp(new DummyXp(checkpointData.Item2, checkpointData.Item2), default(Vector3)); } else { LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); Level newActiveLevel = currentLevelLayout.Levels.First((Level it) => it.LevelNumber == 0); NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == newActiveLevel.LevelNumber + 1); CurrentTotalXp = 0u; ChangeCurrentLevel(newActiveLevel, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, newActiveLevel.LevelNumber)); CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), NextLevel, CurrentTotalXp, currentLevelLayout.Header); } _nextUpdate = Time.time + 300f; } public void Update() { if (_nextUpdate < Time.time) { _nextUpdate = Time.time + 300f; } } public void AddXp(IXpData xpData, Vector3 xpTextPosition, bool forceDebuffXp = false, string xpPopupColor = "<#F80>") { //IL_00a1: 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) uint num = ((forceDebuffXp || _hasDebuff) ? xpData.DebuffXp : xpData.XpGain); int num2 = xpData.LevelScalingXpDecrese * CacheApiWrapper.GetActiveLevel().LevelNumber; num = (uint)((num <= num2) ? 1u : (num - num2)); CurrentTotalXp += num; LogManager.Debug($"Giving xp Amount {num}, new total Xp is {CurrentTotalXp}"); if (!CheckForLevelThresholdReached(xpTextPosition, out string currentClassName) && BepInExLoader.XpPopups.Value && NextLevel != null) { DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, $"{xpPopupColor}{num}XP")); } CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), NextLevel, CurrentTotalXp, currentClassName); } public bool CheckForLevelThresholdReached(Vector3 xpTextPosition, out string currentClassName) { //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); currentClassName = currentLevelLayout.Header; if (IsMaxLevel) { return false; } Level activeLevel = CacheApiWrapper.GetActiveLevel(); IEnumerable<Level> source = currentLevelLayout.Levels.Where((Level it) => it.LevelNumber > CacheApiWrapper.GetActiveLevel().LevelNumber && it.TotalXpRequired <= CurrentTotalXp); if (source.Count() > 0) { Level newLevel = source.OrderByDescending((Level it) => it.LevelNumber).First(); ChangeCurrentLevel(newLevel, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, newLevel.LevelNumber)); NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == newLevel.LevelNumber + 1); if (BepInExLoader.LvlUpPopups.Value) { if (string.IsNullOrEmpty(newLevel.CustomLevelUpPopupText)) { DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, $"<#f00>LV {newLevel.LevelNumber}\nHP: +<#f80>{Math.Round(newLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp() - activeLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp(), 1)}\n<#f00>MD: <#f80>{Math.Round(newLevel.MeleeDamageMultiplier - activeLevel.MeleeDamageMultiplier, 2)}x \n<#f00>WD: <#f80>{Math.Round(newLevel.WeaponDamageMultiplier - activeLevel.WeaponDamageMultiplier, 2)}x", 4f)); } else { DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, newLevel.CustomLevelUpPopupText, 4f)); } } return true; } return false; } internal void ChangeCurrentLevel(Level newLevel, BoosterBuffs newBoosterBuff = null) { CacheApiWrapper.SetActiveLevel(newLevel); CacheApiWrapper.SetCurrentBoosterBuff(newBoosterBuff); LogManager.Debug("saved information."); BoosterBuffManager.Instance.ApplyBoosterEffects(PlayerManager.GetLocalPlayerAgent(), newBoosterBuff); NetworkApiXpManager.SendBoosterStatsReached(newBoosterBuff); Dam_PlayerDamageBase damage = PlayerManager.GetLocalPlayerAgent().Damage; float healthMax = ((Dam_SyncedDamageBase)damage).HealthMax; float num2 = (((Dam_SyncedDamageBase)damage).HealthMax = CacheApiWrapper.GetDefaultMaxHp() * newLevel.HealthMultiplier); ((Dam_SyncedDamageBase)damage).Health = ((Dam_SyncedDamageBase)damage).Health + (num2 - healthMax); ((Il2CppObjectBase)damage).Cast<Dam_PlayerDamageLocal>().UpdateHealthGui(); ApplySingleUseBuffs(newLevel); LogManager.Debug("Pre applying custom scaling effects."); CustomScalingBuffManager.ApplyCustomScalingEffects(PlayerManager.GetLocalPlayerAgent(), newLevel.CustomScaling); } private void ApplySingleUseBuffs(Level reachedLevel) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); foreach (SingleUseBuff levelUpBonu in reachedLevel.LevelUpBonus) { switch (levelUpBonu.SingleBuff) { case SingleBuff.Heal: localPlayerAgent.GiveHealth(localPlayerAgent, levelUpBonu.Value); break; case SingleBuff.Desinfect: localPlayerAgent.GiveDisinfection(localPlayerAgent, levelUpBonu.Value); break; case SingleBuff.AmmunitionMain: localPlayerAgent.GiveAmmoRel(localPlayerAgent, levelUpBonu.Value, 0f, 0f); break; case SingleBuff.AmmunitionSpecial: localPlayerAgent.GiveAmmoRel(localPlayerAgent, 0f, levelUpBonu.Value, 0f); break; case SingleBuff.AmmunitionTool: localPlayerAgent.GiveAmmoRel(localPlayerAgent, 0f, 0f, levelUpBonu.Value); break; } } } } } namespace GTFuckingXP.Patches { [HarmonyPatch(typeof(GS_InLevel))] public class GS_InLevelPatches { [HarmonyPatch("Enter")] [HarmonyPostfix] public static void EnterLevelPostfix() { LogManager.Debug("Level Enter"); ScriptManager.Instance.StartLevelScripts(); UI_Apply.SetSkewing(0f); } } [HarmonyPatch(typeof(GS_AfterLevel))] public class GS_AfterLevelPatches { [HarmonyPatch("CleanupAfterExpedition")] [HarmonyPrefix] public static void EnterLevelPostfix() { ScriptManager.Instance.EndLevelScripts(); } } [HarmonyPatch(typeof(PlaceNavMarkerOnGO))] public class PlaceNavMarkerOnGoPatches { [HarmonyPatch("UpdateName")] [HarmonyPrefix] public static void UpdateNamePrefix(PlaceNavMarkerOnGO __instance, ref string name) { Dictionary<int, Level> playerToLevelMapping = CacheApiWrapper.GetPlayerToLevelMapping(); if (playerToLevelMapping.TryGetValue(__instance.m_player.PlayerSlotIndex, out var value)) { name = $"<color=#F80>Lv.{value.LevelNumber}</color> {name}"; } } } [HarmonyPatch(typeof(SNet_SessionHub))] public class SnetSessionHubPatches { [HarmonyPatch("AddPlayerToSession")] [HarmonyPostfix] public static void AddPlayerToSessionPostfix(SNet_SessionHub __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 if (!CacheApiWrapper.TryGetCurrentLevelLayout(out LevelLayout classLayout)) { return; } List<Group> instance = CacheApi.GetInstance<List<Group>>("GTF_XP"); Group group = instance.FirstOrDefault((Group it) => it.PersistentId == classLayout.GroupPersistentId); if (group.VisibleForPlayerCount.Contains(__instance.PlayersInSession.Count)) { return; } if ((int)GameStateManager.Current.m_currentStateName == 5) { foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase<CM_PlayerLobbyBar>)(object)CM_PageLoadout.Current.m_playerLobbyBars) { if (item.m_player.Lookup == SNet.LocalPlayer.Lookup) { CacheApiWrapper.SetCurrentLevelLayout(CacheApi.GetInstance<List<LevelLayout>>("GTF_XP")[0]); PlayerLobbyBarPatches.ShowClassesSelector(item); break; } } return; } XpApi.ChangeCurrentLevelLayout(CacheApi.GetInstance<List<LevelLayout>>("GTF_XP")[0]); } } } namespace GTFuckingXP.Patches.SelectLevelPatches { [HarmonyPatch(typeof(CM_PlayerLobbyBar))] public class PlayerLobbyBarPatches { [HarmonyPatch("SetupFromPage")] [HarmonyPostfix] public static void SetupFromPagePostfix(CM_PlayerLobbyBar __instance) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) CM_PlayerLobbyBar __instance2 = __instance; LogManager.Debug($"SetupFromPage Postfix on {((Object)__instance2).GetInstanceID()}"); CM_LobbyScrollItem classButton = ((Component)__instance2.m_clothesButton).gameObject.Instantiate<CM_LobbyScrollItem>("ClassSelectorButton"); CacheApi.SaveInformation((object)((Object)__instance2).GetInstanceID(), (object)classButton, "GTF_XP"); ((Component)classButton).transform.Translate(new Vector3(0f, -70f, 0f)); ((CM_Item)classButton).SetOnBtnPressCallback(Action<int>.op_Implicit((Action<int>)delegate(int test) { LogManager.Debug($"Button pressed with {test} as parameter"); __instance2.Select(); classButton.IsSelected = true; ShowClassesSelector(__instance2); })); } [HarmonyPatch("HideLoadoutUI")] [HarmonyPostfix] public static void HideLoadoutUiPostfix(CM_PlayerLobbyBar __instance, bool hide) { if (!__instance.m_introDone || __instance.m_player == null) { return; } CM_LobbyScrollItem information = CacheApi.GetInformation<CM_LobbyScrollItem>((object)((Object)__instance).GetInstanceID(), "GTF_XP"); if (__instance.m_player.IsLocal) { ((Component)information).gameObject.SetActive(!hide); foreach (TextMeshPro item in (Il2CppArrayBase<TextMeshPro>)(object)((CM_Item)information).GetTexts()) { ((TMP_Text)item).text = "Class selector"; ((TMP_Text)item).ForceMeshUpdate(false, false); } } if (__instance.m_player.IsBot) { } } internal static void ShowClassesSelector(CM_PlayerLobbyBar lobbyBar) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) LogManager.Debug("Calling ShowClass Selector method."); lobbyBar.HidePopup(); lobbyBar.m_popupVisible = true; lobbyBar.m_popupScrollWindow.m_infoBoxWidth = 700f; ((RectTransformComp)lobbyBar.m_popupScrollWindow).SetSize(new Vector2(1600f, 700f)); lobbyBar.m_popupScrollWindow.ResetHeaders(); List<Group> instance = CacheApi.GetInstance<List<Group>>("GTF_XP"); AddHeaders(lobbyBar, instance); ((RectTransformComp)lobbyBar.m_popupScrollWindow).SetPosition(new Vector2(0f, 350f)); lobbyBar.m_popupScrollWindow.RespawnInfoBoxFromPrefab(lobbyBar.m_popupInfoBoxWeaponPrefab); ChangeClassHeader(instance[0].Name, 0, lobbyBar); lobbyBar.ShowPopup(); CM_ScrollWindowInfoBox infoBox = lobbyBar.m_popupScrollWindow.InfoBox; if (!CacheApiWrapper.TryGetAnchorDifference(out var anchorDifference)) { anchorDifference = ((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition.y * -1f - 40f; CacheApiWrapper.SetAnchorDifference(anchorDifference); } ((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition = new Vector2(0f, ((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition.y + anchorDifference); ((TMP_Text)infoBox.m_infoDescriptionText).rectTransform.anchoredPosition = new Vector2(0f, ((TMP_Text)infoBox.m_infoDescriptionText).rectTransform.anchoredPosition.y + anchorDifference); ((TMP_Text)infoBox.m_infoDescriptionText).fontSizeMin = ((TMP_Text)infoBox.m_infoDescriptionText).fontSizeMax; } private static void ChangeClassHeader(string groupName, int key, CM_PlayerLobbyBar lobbyBar) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) LogManager.Debug("Showing groupname " + groupName); List<iScrollWindowContent> val = new List<iScrollWindowContent>(); List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP"); LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); CM_ScrollWindowInfoBox infoBox = lobbyBar.m_popupScrollWindow.InfoBox; float y = infoBox.m_infoMainIcon.size.y; ((Component)infoBox.m_infoMainIcon).gameObject.SetActive(false); ((Renderer)infoBox.m_infoMainIcon).enabled = false; CM_LobbyScrollItem selected = null; foreach (LevelLayout layout in instance) { if (layout.GroupPersistentId != key) { continue; } CM_LobbyScrollItem content = GOUtil.SpawnChildAndGetComp<CM_LobbyScrollItem>(lobbyBar.m_clothesCardPrefab, ((Component)lobbyBar).transform); ((CM_Item)content).TextMeshRoot = ((Component)lobbyBar.m_parentPage).transform; content.SetupFromLobby(((Component)lobbyBar).transform, lobbyBar, true); ((RectTransformComp)content).ForcePopupLayer(true, (GameObject)null); ((TMP_Text)content.m_descText).text = ""; ((TMP_Text)content.m_subTitleText).text = ""; if (layout.PersistentId == currentLevelLayout.PersistentId) { selected = content; selected.IsSelected = true; SelectItem(content, selected); } ((TMP_Text)content.m_nameText).text = layout.Header; ((CM_Item)content).OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)delegate { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown LogManager.Debug($"LayoutName {layout.Header} and Id is {layout.PersistentId}"); if ((Object)(object)selected != (Object)null) { selected.IsSelected = false; } content.IsSelected = true; SelectItem(content, selected); selected = content; CoroutineManager.BlinkIn(((Component)content).gameObject, 0f); infoBox.SetInfoBox(layout.Header, "", layout.InfoText, "", "", new Sprite()); CacheApiWrapper.SetCurrentLevelLayout(layout); }); ((CM_Item)content).m_alphaSpriteOnHover = true; ((CM_Item)content).m_alphaTextOnHover = true; val.Add(((Il2CppObjectBase)content).Cast<iScrollWindowContent>()); } lobbyBar.m_popupScrollWindow.SetContentItems(val, 0f); Enumerator<iScrollWindowContent> enumerator2 = val.GetEnumerator(); while (enumerator2.MoveNext()) { iScrollWindowContent current = enumerator2.Current; ((Il2CppObjectBase)current).Cast<CM_LobbyScrollItem>().UpdateSizesAndOffsets(); } lobbyBar.ShowPopup(); lobbyBar.m_popupScrollWindow.SelectHeader(key); Transform val2 = ((Component)infoBox).transform.FindChild("InfoBox/IconBackground"); LogManager.Debug($"Child is null {val2 == null}"); ((Component)val2).gameObject.SetActive(false); } private static void SelectItem(CM_LobbyScrollItem newSelectItem, CM_LobbyScrollItem oldSelectItem) { if ((Object)(object)oldSelectItem != (Object)null) { ((TMP_Text)oldSelectItem.m_subTitleText).text = ""; CacheApi.SaveInstance<CM_LobbyScrollItem>((CM_LobbyScrollItem)null, "GTF_XP"); } if ((Object)(object)newSelectItem != (Object)null) { ((TMP_Text)newSelectItem.m_subTitleText).text = "<color=orange>" + Text.Get(492u) + "</color>"; CacheApi.SaveInstance<CM_LobbyScrollItem>(newSelectItem, "GTF_XP"); } } private static void AddHeaders(CM_PlayerLobbyBar lobbyBar, List<Group> groups) { CM_PlayerLobbyBar lobbyBar2 = lobbyBar; int num = 0; int count = SNet.SessionHub.PlayersInSession.Count; bool flag = false; foreach (Group group in groups) { if (num <= 5 && group.VisibleForPlayerCount != null && group.VisibleForPlayerCount.Contains(count)) { lobbyBar2.m_popupScrollWindow.AddHeader(group.Name, group.PersistentId, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex) { LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or {group.PersistentId}"); ChangeClassHeader(group.Name, group.PersistentId, lobbyBar2); })); flag = true; num++; } } if (flag) { return; } Group group2 = groups.FirstOrDefault((Group it) => it.PersistentId == 0); Group group3 = groups.FirstOrDefault((Group it) => it.PersistentId == 1); Group group4 = groups.FirstOrDefault((Group it) => it.PersistentId == 2); Group group5 = groups.FirstOrDefault((Group it) => it.PersistentId == 3); if (group2 != null) { lobbyBar2.m_popupScrollWindow.AddHeader(group2.Name, 0, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex) { LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 0"); ChangeClassHeader(group2.Name, 0, lobbyBar2); })); } if (group3 != null) { lobbyBar2.m_popupScrollWindow.AddHeader(group3.Name, 1, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex) { LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 1"); ChangeClassHeader(group3.Name, 1, lobbyBar2); })); } if (group4 != null) { lobbyBar2.m_popupScrollWindow.AddHeader(group4.Name, 2, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex) { LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 2"); ChangeClassHeader(group4.Name, 2, lobbyBar2); })); } if (group5 != null) { lobbyBar2.m_popupScrollWindow.AddHeader(group5.Name, 3, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex) { LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 3"); ChangeClassHeader(group5.Name, 3, lobbyBar2); })); } } } } namespace GTFuckingXP.Information { public static class DefaultXpData { public static List<EnemyXp> GetDefaultEnemyXp() { List<EnemyXp> list = new List<EnemyXp>(); Il2CppArrayBase<EnemyBalancingDataBlock> allBlocks = GameDataBlockBase<EnemyBalancingDataBlock>.GetAllBlocks(); foreach (EnemyDataBlock enemy in GameDataBlockBase<EnemyDataBlock>.GetAllBlocks()) { EnemyBalancingDataBlock val = ((IEnumerable<EnemyBalancingDataBlock>)allBlocks).FirstOrDefault((Func<EnemyBalancingDataBlock, bool>)((EnemyBalancingDataBlock it) => ((GameDataBlockBase<EnemyBalancingDataBlock>)(object)it).persistentID == enemy.BalancingDataId)); float num; if (val == null) { LogManager.Warn($"No balance datablock found for balance id {enemy.BalancingDataId} ({((GameDataBlockBase<EnemyDataBlock>)(object)enemy).name})!"); num = 20f; } else { num = val.Health.HealthMax; } int num2 = (int)(num / 35f); num2 = ((num2 <= 0) ? 1 : num2); list.Add(new EnemyXp(((GameDataBlockBase<EnemyDataBlock>)(object)enemy).persistentID, ((GameDataBlockBase<EnemyDataBlock>)(object)enemy).name, (uint)(num / 2f), (uint)(num / 4f), num2)); } return list; } public static List<LevelLayout> GetDefaultLevelLayout() { List<LevelLayout> list = new List<LevelLayout>(); List<GTFuckingXP.Information.Level.Level> list2 = new List<GTFuckingXP.Information.Level.Level>(); for (int i = 0; i <= 60; i++) { float num = 1f + 0.25f * (float)i; uint totalXp = Convert.ToUInt32(250.0 * (0.8 + 0.2 * (double)i) * (double)i); List<SingleUseBuff> list3 = new List<SingleUseBuff>(); if (i % 5 == 0 && i != 0) { list3.Add(new SingleUseBuff(SingleBuff.Heal, 1f)); list3.Add(new SingleUseBuff(SingleBuff.Desinfect, 1f)); list3.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 1f)); list3.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 1f)); list3.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 1f)); } list2.Add(new GTFuckingXP.Information.Level.Level(i, totalXp, num, num, num, list3, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(1, "All Rounder", 0, "Scales equally acceptable with everything.", list2)); List<GTFuckingXP.Information.Level.Level> list4 = new List<GTFuckingXP.Information.Level.Level>(); for (int j = 0; j <= 12; j++) { float num2 = 1f + 0.5f * (float)j; uint totalXp2 = Convert.ToUInt32(150.0 * (0.8 + 0.2 * (double)j) * (double)j); List<SingleUseBuff> list5 = new List<SingleUseBuff>(); list5.Add(new SingleUseBuff(SingleBuff.Heal, 0.1f)); list5.Add(new SingleUseBuff(SingleBuff.Desinfect, 0.1f)); list4.Add(new GTFuckingXP.Information.Level.Level(j, totalXp2, 0.1f * num2, 1.5f * num2, 1.4f * num2, list5, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(2, "Glass cannon", 0, "Great scaling, but only 12 levels with no HP.", list4)); List<GTFuckingXP.Information.Level.Level> list6 = new List<GTFuckingXP.Information.Level.Level>(); for (int k = 0; k <= 80; k++) { float num3 = 1f + 0.1f * (float)k; uint totalXp3 = Convert.ToUInt32(100.0 * (0.8 + 0.2 * (double)k) * (double)k); List<SingleUseBuff> list7 = new List<SingleUseBuff>(); if (k % 2 == 0 && k != 0) { list7.Add(new SingleUseBuff(SingleBuff.Heal, 0.5f)); list7.Add(new SingleUseBuff(SingleBuff.Desinfect, 0.2f)); } list6.Add(new GTFuckingXP.Information.Level.Level(k, totalXp3, 5f * num3, 0.5f * num3, 0.5f * num3, list7, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(3, "Tank", 0, "Slow overall scaling, very good HP but decreased damage output.", list6)); List<GTFuckingXP.Information.Level.Level> list8 = new List<GTFuckingXP.Information.Level.Level>(); for (int l = 0; l <= 20; l++) { float num4 = 1f + 0.5f * (float)l; uint totalXp4 = Convert.ToUInt32(400.0 * (0.8 + 0.2 * (double)l) * (double)l); List<SingleUseBuff> list9 = new List<SingleUseBuff>(); list9.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 1f)); list9.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 1f)); list9.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 1f)); list8.Add(new GTFuckingXP.Information.Level.Level(l, totalXp4, 0.05f * num4, 30f * num4, 0.1f * num4, list9, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(4, "Kamikaze", 0, "No HP, no weapondamage, melee for life\nBut has a curse of getting regulary useless ammunition.", list8)); List<GTFuckingXP.Information.Level.Level> list10 = new List<GTFuckingXP.Information.Level.Level>(); for (int m = 0; m <= 20; m++) { float num5 = 1f + 0.25f * (float)m; uint totalXp5 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)m) * (double)m); List<SingleUseBuff> list11 = new List<SingleUseBuff>(); list11.Add(new SingleUseBuff(SingleBuff.Heal, 0.2f)); list10.Add(new GTFuckingXP.Information.Level.Level(m, totalXp5, 1f * num5, 1f * num5 + 1f, num5 * 0.5f - 0.5f, list11, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(5, "Melee Main", 0, "Acceptable scaling, faster leveling\nCapable of tanking some hits and deals great melee damage. May lack a bit of Weapondamage", list10)); List<GTFuckingXP.Information.Level.Level> list12 = new List<GTFuckingXP.Information.Level.Level>(); for (int n = 0; n <= 20; n++) { float num6 = 1f + 0.5f * (float)n; uint totalXp6 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)n) * (double)n); List<SingleUseBuff> singleUseBuffs = new List<SingleUseBuff>(); list12.Add(new GTFuckingXP.Information.Level.Level(n, totalXp6, num6, num6, 0f, singleUseBuffs, new List<CustomScalingBuff>())); } list.Add(new LevelLayout(6, "Boxer", 1, "Great Scaling.\nNo weapon damage!\nVery tanky against melee damage but can't withstand any shooter.", list12)); List<GTFuckingXP.Information.Level.Level> list13 = new List<GTFuckingXP.Information.Level.Level>(); for (int num7 = 0; num7 <= 20; num7++) { float num8 = 1f + 0.5f * (float)num7; uint totalXp7 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)num7) * (double)num7); List<SingleUseBuff> list14 = new List<SingleUseBuff>(); list14.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 0.2f)); list14.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 0.2f)); list14.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 0.2f)); List<CustomScalingBuff> list15 = new List<CustomScalingBuff>(); if (num7 != 0) { list15.Add(new CustomScalingBuff(CustomScaling.MeleeHitBoxSizeMultiplier, num7 * 5)); list15.Add(new CustomScalingBuff(CustomScaling.MeleeRangeMultiplier, num7)); list15.Add(new CustomScalingBuff(CustomScaling.MovementSpeedMultiplier, 1f + (float)num7 * 0.3f)); list15.Add(new CustomScalingBuff(CustomScaling.AntiFogSphere, num7 * 2)); } list13.Add(new GTFuckingXP.Information.Level.Level(num7, totalXp7, num8, num8, 0f, list14, list15)); } list.Add(new LevelLayout(7, "SpeedRunner", 1, "Gets increasingly faster while playing, so you can circle kite even easier.", list13)); return list; } public static List<BoosterBuffs> GetDefaultBoosterBuffs() { List<BoosterBuffs> list = new List<BoosterBuffs>(); list.Add(new BoosterBuffs(6, new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }, new Dictionary<AgentModifier, float> { { (AgentModifier)6, 1000f }, { (AgentModifier)7, -500f } })); return list; } public static List<Group> GetDefaultGroups() { List<Group> list = new List<Group>(); list.Add(new Group(0, "Example Classes", new List<int> { 1, 2, 3, 4 })); list.Add(new Group(1, "For gods sake, don't use it", new List<int> { 1 })); return list; } } internal class DummyXp : IXpData { public uint XpGain { get; set; } public uint DebuffXp { get; set; } public int LevelScalingXpDecrese { get; set; } public DummyXp(uint xpGain, uint debuffXp) { XpGain = xpGain; DebuffXp = debuffXp; LevelScalingXpDecrese = 0; } } public class FloatingXpTextInfo : IFloatingTextInfo { public Vector3 Velocity { get; } public Vector3 SpawnPosition { get; } public float Gravity => 0f; public float LifeTime { get; } public string Text { get; } public FloatingXpTextInfo(Vector3 position, string text, float lifeTime = 2f) { //IL_0018: 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_0023: 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) Velocity = new Vector3(0f, 0.1f, 0f); SpawnPosition = position; Text = text; LifeTime = lifeTime; } public void OnUpdate(TextMeshPro tmp, FloatingTextBase textBase) { } public void UpdateTextMesh(TextMeshPro tmp) { } } public interface IXpData { uint XpGain { get; set; } uint DebuffXp { get; set; } int LevelScalingXpDecrese { get; set; } } public enum TermsOfUsage { Undecided, Accepted, Declined, Anonymized } } namespace GTFuckingXP.Information.WebModels { public class XpWebModel { public string SteamId { get; set; } public string PlayFabId { get; set; } public string NickName { get; set; } public XpWebModel(TermsOfUsage howToHandleData) { switch (howToHandleData) { case TermsOfUsage.Accepted: SteamId = SteamManager.LocalPlayerID.ToString(); PlayFabId = PlayFabManager.EntityID; NickName = SteamManager.LocalPlayerName; break; case TermsOfUsage.Anonymized: SteamId = "Unknown"; PlayFabId = "Unknown"; NickName = "Unknown"; break; default: throw new Exception("You should not create a data package if there is no consent!"); } } } } namespace GTFuckingXP.Information.NetworkingInfo { public struct BoosterInfo { public float F1; public float F2; public float F3; public float F4; public float F5; public float F6; public float F7; public float F8; public float F9; public float F10; public float F11; public float F12; public float F13; public float F14; public float F15; public float F16; public float F17; public float F18; public float F19; public float F20; public float F21; public float F22; public float F23; public float F24; public float F25; public float F26; public float F27; public float F28; public float F29; public float F30; public float F31; public float F32; public float F33; public float F34; public float F35; public float F36; public float F37; public float F38; public float F39; public float F40; public float F41; public float F42; public float F43; public float F44; public float F45; public float F46; public float F47; public float F48; public float F49; public float F50; public float F51; public float F52; public float F53; public float F54; public BoosterInfo(float[] boosterValues) { if (boosterValues.Length > 54) { LogManager.Error("There are more values in Boosters values, than supported.\nPlease message \"Endskill\" about that issue!"); } else if (boosterValues.Length < 54) { LogManager.Error("There are less than 47 Booster values!"); } F1 = boosterValues[0]; F2 = boosterValues[1]; F3 = boosterValues[2]; F4 = boosterValues[3]; F5 = boosterValues[4]; F6 = boosterValues[5]; F7 = boosterValues[6]; F8 = boosterValues[7]; F9 = boosterValues[8]; F10 = boosterValues[9]; F11 = boosterValues[10]; F12 = boosterValues[11]; F13 = boosterValues[12]; F14 = boosterValues[13]; F15 = boosterValues[14]; F16 = boosterValues[15]; F17 = boosterValues[16]; F18 = boosterValues[17]; F19 = boosterValues[18]; F20 = boosterValues[19]; F21 = boosterValues[20]; F22 = boosterValues[21]; F23 = boosterValues[22]; F24 = boosterValues[23]; F25 = boosterValues[24]; F26 = boosterValues[25]; F27 = boosterValues[26]; F28 = boosterValues[27]; F29 = boosterValues[28]; F30 = boosterValues[29]; F31 = boosterValues[30]; F32 = boosterValues[31]; F33 = boosterValues[32]; F34 = boosterValues[33]; F35 = boosterValues[34]; F36 = boosterValues[35]; F37 = boosterValues[36]; F38 = boosterValues[37]; F39 = boosterValues[38]; F40 = boosterValues[39]; F41 = boosterValues[40]; F42 = boosterValues[41]; F43 = boosterValues[42]; F44 = boosterValues[43]; F45 = boosterValues[44]; F46 = boosterValues[45]; F47 = boosterValues[46]; F48 = boosterValues[47]; F49 = boosterValues[48]; F50 = boosterValues[49]; F51 = boosterValues[50]; F52 = boosterValues[51]; F53 = boosterValues[52]; F54 = boosterValues[53]; } public float[] GetBoosterValues() { return new float[54] { F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31, F32, F33, F34, F35, F36, F37, F38, F39, F40, F41, F42, F43, F44, F45, F46, F47, F48, F49, F50, F51, F52, F53, F54 }; } public static implicit operator BoosterInfo(BoosterBuffs buff) { //IL_0029: 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_0038: Unknown result type (might be due to invalid IL or missing references) Array values = Enum.GetValues(typeof(AgentModifier)); float[] array = new float[values.Length]; for (int i = 0; i < values.Length; i++) { AgentModifier key = (AgentModifier)values.GetValue(i); if (buff != null && buff.ValueToBoosterEffects.TryGetValue(key, out var value)) { array[i] = value; } else { array[i] = 0f; } } return new BoosterInfo(array); } } public struct GtfoApiXpInfo : IXpData { public bool ForceDebuffXp { get; set; } public uint XpGain { get; set; } public uint DebuffXp { get; set; } public int LevelScalingXpDecrese { get; set; } public float PositionX { get; set; } public float PositionY { get; set; } public float PositionZ { get; set; } public GtfoApiXpInfo(uint xpGain, uint debuffXp, int levelScaling, Vector3 position, bool forceDebuffXp = false) { //IL_0023: 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_003f: Unknown result type (might be due to invalid IL or missing references) XpGain = xpGain; DebuffXp = debuffXp; LevelScalingXpDecrese = levelScaling; ForceDebuffXp = forceDebuffXp; PositionX = position.x; PositionY = position.y; PositionZ = position.z; } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LevelReachedInfo { public int LevelNumber; public float HealthMultiplier; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 230)] public string CustomScaling; public LevelReachedInfo(int levelNumber, float healthMultiplier, string customScaling) { LevelNumber = levelNumber; HealthMultiplier = healthMultiplier; CustomScaling = customScaling; } } public struct StaticXpInfo : IXpData { public uint XpGain { get; set; } public uint DebuffXp { get; set; } public int LevelScalingXpDecrese { get; set; } public Vector3 Position { get; set; } public StaticXpInfo(uint xpGain, uint debuffXp, int levelScaling, Vector3 position) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) XpGain = xpGain; DebuffXp = debuffXp; LevelScalingXpDecrese = levelScaling; Position = position; } } } namespace GTFuckingXP.Information.Level { public class BoosterBuffs { public int ClassLayoutPersistentId { get; set; } public List<int> ActiveLevels { get; set; } public Dictionary<AgentModifier, float> ValueToBoosterEffects { get; set; } public BoosterBuffs(int classLayoutPersistentId, List<int> activeLevels, Dictionary<AgentModifier, float> valueToBoosterEffects) { ClassLayoutPersistentId = classLayoutPersistentId; ActiveLevels = activeLevels; ValueToBoosterEffects = valueToBoosterEffects; } public static implicit operator BoosterBuffs(BoosterInfo boosterInfo) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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) Array values = Enum.GetValues(typeof(AgentModifier)); Dictionary<AgentModifier, float> dictionary = new Dictionary<AgentModifier, float>(); float[] boosterValues = boosterInfo.GetBoosterValues(); for (int i = 0; i < values.Length; i++) { if (boosterValues[i] != 0f) { AgentModifier key = (AgentModifier)values.GetValue(i); dictionary[key] = boosterValues[i]; } } return new BoosterBuffs(0, null, dictionary); } } public class CustomScalingBuff { public CustomScaling CustomBuff { get; set; } public float Value { get; set; } public CustomScalingBuff(CustomScaling customBuff, float value) { CustomBuff = customBuff; Value = value; } } public class Level { public int LevelNumber { get; set; } public uint TotalXpRequired { get; set; } public string CustomLevelUpPopupText { get; set; } public string CustomLevelStatsText { get; set; } public float HealthMultiplier { get; set; } public float MeleeDamageMultiplier { get; set; } public float WeaponDamageMultiplier { get; set; } public List<CustomScalingBuff> CustomScaling { get; set; } public List<SingleUseBuff> LevelUpBonus { get; set; } public Level() { } public Level(LevelReachedInfo levelData) : this(levelData.LevelNumber, 0u, levelData.HealthMultiplier, 0f, 0f, null, JsonSerializer.Deserialize<List<CustomScalingBuff>>(levelData.CustomScaling)) { } public Level(int levelNumber, uint totalXp, float healthMultiplier, float meleeMultiplier, float weaponMultiplier, List<SingleUseBuff> singleUseBuffs, List<CustomScalingBuff> customScaling, string customLevelUpPopupText = "", string customLevelStatsText = "") { LevelNumber = levelNumber; TotalXpRequired = totalXp; HealthMultiplier = healthMultiplier; MeleeDamageMultiplier = meleeMultiplier; WeaponDamageMultiplier = weaponMultiplier; LevelUpBonus = singleUseBuffs; CustomScaling = customScaling; CustomLevelStatsText = customLevelStatsText; CustomLevelUpPopupText = customLevelUpPopupText; } public override string ToString() { return $"LevelNumber {LevelNumber}"; } } public class LevelLayout { public string Header { get; set; } public int GroupPersistentId { get; set; } public int PersistentId { get; set; } public string InfoText { get; set; } public List<Level> Levels { get; set; } public LevelLayout(int persistentId, string header, int groupPersistentId, string infoText, List<Level> levels) { PersistentId = persistentId; GroupPersistentId = groupPersistentId; Header = header; InfoText = infoText; Levels = levels; } } public class SingleUseBuff { public SingleBuff SingleBuff { get; set; } public float Value { get; set; } public SingleUseBuff(SingleBuff singleBuff, float value) { SingleBuff = singleBuff; Value = value; } } } namespace GTFuckingXP.Information.Enemies { public class EnemyXp : IXpData { public uint EnemyId { get; set; } public string EnemyName { get; set; } public uint XpGain { get; set; } public uint DebuffXp { get; set; } public int LevelScalingXpDecrese { get; set; } public EnemyXp() { } public EnemyXp(uint enemyId, string enemyName, uint killXp, uint debuffXp, int levelScalingXpDecrease) { EnemyId = enemyId; EnemyName = enemyName; XpGain = killXp; DebuffXp = debuffXp; LevelScalingXpDecrese = levelScalingXpDecrease; } } } namespace GTFuckingXP.Information.Enemies.Scaling { public class EnemyDefaultZoneLevel { public int SpawningZone { get; set; } public string TagText { get; set; } public float MaxHealthMultiplier { get; set; } public float ShooterDamageMultiplier { get; set; } public float MeleeDamageMultiplier { get; set; } public float PushDamageMutliplier { get; set; } public EnemyDefaultZoneLevel(int spawningZone, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier) { SpawningZone = spawningZone; MaxHealthMultiplier = hpMultiplier; ShooterDamageMultiplier = shooterDamageMultiplier; MeleeDamageMultiplier = meleeDamageMultiplier; PushDamageMutliplier = pushDamageMultiplier; } } public class EnemyLevel { public uint EnemyId { get; set; } public int SpawningZone { get; set; } public string TagText { get; set; } public float MaxHealthMultiplier { get; set; } public float ShooterDamageMultiplier { get; set; } public float MeleeDamageMultiplier { get; set; } public float PushDamageMutliplier { get; set; } public EnemyLevel(uint enemyId, int spawningZone, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier) { EnemyId = enemyId; SpawningZone = spawningZone; MaxHealthMultiplier = hpMultiplier; ShooterDamageMultiplier = shooterDamageMultiplier; MeleeDamageMultiplier = meleeDamageMultiplier; PushDamageMutliplier = pushDamageMultiplier; } } public class EnemyScaling { public eRundownTier Tier { get; set; } public int ExpeditionIndex { get; set; } public List<EnemyDefaultZoneLevel> DefaultScale { get; set; } public List<EnemyLevel> EnemyLevels { get; set; } public EnemyScaling(eRundownTier tier, int expeditionIndex, List<EnemyDefaultZoneLevel> zoneLevels, List<EnemyLevel> enemyLevels) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) Tier = tier; ExpeditionIndex = expeditionIndex; } } } namespace GTFuckingXP.Information.Enemies.Scale { public class EnemyLevels { public uint PersistendId { get; set; } public int EnemyId { get; set; } public int LevelNumber { get; set; } public string TagText { get; set; } public float MaxHealthMultiplier { get; set; } public float ShooterDamageMultiplier { get; set; } public float MeleeDamageMultiplier { get; set; } public float PushDamageMutliplier { get; set; } public EnemyLevels(uint persistentId, int enemyId, int levelNumber, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier) { PersistendId = persistentId; LevelNumber = levelNumber; TagText = tagText; MaxHealthMultiplier = hpMultiplier; ShooterDamageMultiplier = shooterDamageMultiplier; MeleeDamageMultiplier = meleeDamageMultiplier; PushDamageMutliplier = pushDamageMultiplier; } } public class LevelEnemyScaler { public eRundownTier Tier { get; set; } public int ExpeditionIndex { get; set; } public List<ZoneToEnemyId> ZoneToEnemyIds { get; set; } public LevelEnemyScaler(eRundownTier tier, int expeditionIndex, List<ZoneToEnemyId> zoneToEnemyIds) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) Tier = tier; ExpeditionIndex = expeditionIndex; ZoneToEnemyIds = zoneToEnemyIds; } } public class ZoneToEnemyId { public int Zone { get; set; } public List<uint> EnemyLevelIds { get; set; } public ZoneToEnemyId(int zone, List<uint> enemyLevelIds) { Zone = zone; EnemyLevelIds = enemyLevelIds; } } } namespace GTFuckingXP.Information.ClassSelector { public class Group { public int PersistentId { get; set; } public List<int> VisibleForPlayerCount { get; set; } public string Name { get; set; } public Group(int persistentId, string name, List<int> visibleForPlayerCount) { PersistentId = persistentId; Name = name; VisibleForPlayerCount = visibleForPlayerCount; } } } namespace GTFuckingXP.Extensions { public static class CacheApiWrapper { public const string XpModCacheName = "GTF_XP"; internal const string LevelLayoutKey = "LevelLayout"; internal const string CheckpointData = "XpCheckpointData"; private const string ActiveLevelKey = "ActiveLevel"; private const string DefaultDataBlockMaxHpKey = "MaxHpDefault"; private const string PlayerSlotToLevelIndexMappingKey = "PlayerLevelIndexMapping"; private const string BoosterBuffKey = "BoosterBuffKey"; private const string AnchorDifferenceKey = "AnchorDifferenceKey"; private const string LvlUpCallbackKey = "LvlUpCallbackKey"; private const string ScriptsStartedCallbackKey = "ScriptsStartedCallback"; private const string DefaultMeleeRangeKey = "DefaultMeleeRangeKey"; private const string DefaultMeleeHitBoxKey = "DefaultMeleeHitBoxKey"; private const string DefaultMovmentKey = "DefaultMovmentKeys"; private const string DefaultJumpVelInitialKey = "DefaultVelInitialKey"; private const string DefaultJumpGravityMulDefaultKey = "DefaultJumpGravityMulDefaultKey"; private const string DefaultJumpGravityMulButtonReleasedKey = "DefaultJumpGravityMulButtonReleasedKey"; private const string DefaultJumpGravityMulAfterPeakKey = "DefaultJumpGravityMulAfterPeakKey"; private const string DefaultJumpGravityMulFallingKey = "DefaultJumpGravityMulFallingKey"; private const string DefaultJumpVelocityMaxKey = "DefaultJumpVelocityMaxKey"; public static Tscript DestroyOldCreateRegisterAndReturnComponent<Tscript>() where Tscript : Component { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown Tscript val = default(Tscript); if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true)) { ((Component)val).gameObject.SetActive(false); Object.Destroy((Object)(object)val); CacheApi.RemoveInstance<Tscript>("GTF_XP"); } GameObject val2 = new GameObject("GetTheFuckingXp_Endskill"); Object.DontDestroyOnLoad((Object)(object)val2); val = val2.AddComponent<Tscript>(); CacheApi.SaveInstance<Tscript>(val, "GTF_XP"); return val; } public static Tscript CreateRegisterAndReturnComponent<Tscript>() where Tscript : Component { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Tscript val = default(Tscript); if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true)) { ((Component)val).gameObject.SetActive(true); return val; } GameObject val2 = new GameObject("GetTheFuckingXp_Endskill"); Object.DontDestroyOnLoad((Object)(object)val2); val = val2.AddComponent<Tscript>(); CacheApi.SaveInstance<Tscript>(val, "GTF_XP"); return val; } public static void KillScript<Tscript>() where Tscript : Component { Tscript val = default(Tscript); if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true)) { ((Component)val).gameObject.SetActive(false); Object.Destroy((Object)(object)val); CacheApi.RemoveInstance<Tscript>("GTF_XP"); } } public static void SetCurrentLevelLayout(LevelLayout levelLayout) { LogManager.Debug("Set current level layout to " + levelLayout.Header + "."); CacheApi.SaveInformation((object)"LevelLayout", (object)levelLayout, "GTF_XP"); } public static LevelLayout GetCurrentLevelLayout() { return CacheApi.GetInformation<LevelLayout>((object)"LevelLayout", "GTF_XP"); } public static bool TryGetCurrentLevelLayout(out LevelLayout levelLayout) { return CacheApi.TryGetInformation<LevelLayout>((object)"LevelLayout", ref levelLayout, "GTF_XP", true); } public static void SetActiveLevel(Level newLevel, bool sendToOtherPeople = true) { LogManager.Debug($"Setting new level to {newLevel.LevelNumber}."); CacheApi.SaveInformation((object)"ActiveLevel", (object)newLevel, "GTF_XP"); if (sendToOtherPeople) { NetworkApiXpManager.SendNewLevelActive(newLevel); } foreach (Action<Level> lvlUpCallBack in GetLvlUpCallBackList()) { LogManager.Message("Doing some weird Lvl Up callback stuff"); lvlUpCallBack(newLevel); } } public static Level GetActiveLevel() { return CacheApi.GetInformation<Level>((object)"ActiveLevel", "GTF_XP"); } public static float GetDefaultMaxHp() { return CacheApi.GetInformation<float>((object)"MaxHpDefault", "GTF_XP"); } public static void SetDefaultMaxHp(float defaultMaxHp) { CacheApi.SaveInformation((object)"MaxHpDefault", (object)defaultMaxHp, "GTF_XP"); } public static void SetPlayerToLevelMapping(Dictionary<int, Level> playerToLevelMap) { CacheApi.SaveInformation((object)"PlayerLevelIndexMapping", (object)playerToLevelMap, "GTF_XP"); } public static Dictionary<int, Level> GetPlayerToLevelMapping() { return CacheApi.GetInformation<Dictionary<int, Level>>((object)"PlayerLevelIndexMapping", "GTF_XP"); } public static void SetXpStorageData(uint knownXpState) { CacheApi.SaveInformation((object)"XpCheckpointData", (object)(GetCurrentLevelLayout(), knownXpState, "GTF_XP"), "GlobalCache"); } public static bool TryGetXpStorageData(out (LevelLayout levelLayout, uint totalXp) checkpointData) { return CacheApi.TryGetInformation<(LevelLayout, uint)>((object)"XpCheckpointData", ref checkpointData, "GTF_XP", true); } public static BoosterBuffs GetCurrentBoosterBuffs() { return CacheApi.GetInformation<BoosterBuffs>((object)"BoosterBuffKey", "GTF_XP"); } public static void SetCurrentBoosterBuff(BoosterBuffs boosterBuff) { CacheApi.SaveInformation((object)"BoosterBuffKey", (object)boosterBuff, "GTF_XP"); } public static void SetAnchorDifference(float anchorDifference) { CacheApi.SaveInformation((object)"AnchorDifferenceKey", (object)anchorDifference, "GTF_XP"); } public static bool TryGetAnchorDifference(out float anchorDifference) { return CacheApi.TryGetInformation<float>((object)"AnchorDifferenceKey", ref anchorDifference, "GTF_XP", true); } public static void SetLvlUpCallBackList(List<Action<Level>> lvlUpCallbacks) { CacheApi.SaveInformation((object)"LvlUpCallbackKey", (object)lvlUpCallbacks, "GTF_XP"); } public static void AddLvlUpCallback(Action<Level> lvlUpCallback) { CacheApi.GetInformation<List<Action<Level>>>((object)"LvlUpCallbackKey", "GTF_XP").Add(lvlUpCallback); } public static void SetScriptsStartedCallBackList(List<Action<Level>> lvlUpCallbacks) { CacheApi.SaveInformation((object)"ScriptsStartedCallback", (object)lvlUpCallbacks, "GTF_XP"); } public static void AddScriptsStartedCallback(Action<Level> lvlUpCallback) { CacheApi.GetInformation<List<Action<Level>>>((object)"ScriptsStartedCallback", "GTF_XP").Add(lvlUpCallback); } public static List<Action<Level>> GetLvlUpCallBackList() { return CacheApi.GetInformation<List<Action<Level>>>((object)"LvlUpCallbackKey", "GTF_XP"); } public static List<Action<Level>> GetScriptsStartedCallbackList() { return CacheApi.GetInformation<List<Action<Level>>>((object)"ScriptsStartedCallback", "GTF_XP"); } public static void SetDefaultMeleeRange(float meleeRange) { CacheApi.SaveInformation((object)"DefaultMeleeRangeKey", (object)meleeRange, "GTF_XP"); } public static void RemoveDefaultMeleeRange() { CacheApi.RemoveInformation((object)"DefaultMeleeRangeKey", "GTF_XP"); } public static bool TryGetDefaultMeleeRange(out float meleeRange) { return CacheApi.TryGetInformation<float>((object)"DefaultMeleeRangeKey", ref meleeRange, "GTF_XP", true); } public static void SetDefaultMeleeHitBox(float meleeHitbox) { CacheApi.SaveInformation((object)"DefaultMeleeHitBoxKey", (object)meleeHitbox, "GTF_XP"); } public static void RemoveDefaultMeleeHitBox() { CacheApi.RemoveInformation((object)"DefaultMeleeHitBoxKey", "GTF_XP"); } public static bool TryGetDefaultMeleeHitBox(out float meleeHitbox) { return CacheApi.TryGetInformation<float>((object)"DefaultMeleeHitBoxKey", ref meleeHitbox, "GTF_XP", true); } public static bool TryGetDefaultMovment(out (float walk, float run, float air, float crouch) movmentData) { return CacheApi.TryGetInformation<(float, float, float, float)>((object)"DefaultMovmentKeys", ref movmentData, "GTF_XP", true); } public static void SetDefaultMovment(float walk, float run, float air, float crouch) { CacheApi.SaveInformation((object)"DefaultMovmentKeys", (object)(walk, run, air, crouch), "GTF_XP"); } public static void SetDefaultJumpVelInitial(float value) { CacheApi.SaveInformation((object)"DefaultVelInitialKey", (object)value, "GTF_XP"); } public static void SetDefaultJumpGravityMulDefault(float value) { CacheApi.SaveInformation((object)"DefaultJumpGravityMulDefaultKey", (object)value, "GTF_XP"); } public static void SetDefaultJumpGravityMulButtonReleased(float value) { CacheApi.SaveInformation((object)"DefaultJumpGravityMulButtonReleasedKey", (object)value, "GTF_XP"); } public static void SetDefaultJumpGravityMulAfterPeak(float value) { CacheApi.SaveInformation((object)"DefaultJumpGravityMulAfterPeakKey", (object)value, "GTF_XP"); } public static void SetDefaultJumpGravityMulFalling(float value) { CacheApi.SaveInformation((object)"DefaultJumpGravityMulFallingKey", (object)value, "GTF_XP"); } public static void SetDefaultJumpVelocityMax(float value) { CacheApi.SaveInformation((object)"DefaultJumpVelocityMaxKey", (object)value, "GTF_XP"); } public static bool TryGetDefaultJumpVelInitial(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultVelInitialKey", ref value, "GTF_XP", true); } public static bool TryGetDefaultJumpGravityMulDefault(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulDefaultKey", ref value, "GTF_XP", true); } public static bool TryGetDefaultJumpGravityMulButtonReleased(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulButtonReleasedKey", ref value, "GTF_XP", true); } public static bool TryGetDefaultJumpGravityMulAfterPeak(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulAfterPeakKey", ref value, "GTF_XP", true); } public static bool TryGetDefaultJumpGravityMulFalling(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulFallingKey", ref value, "GTF_XP", true); } public static bool TryGetDefaultJumpVelocityMax(out float value) { return CacheApi.TryGetInformation<float>((object)"DefaultJumpVelocityMaxKey", ref value, "GTF_XP", true); } } internal static class GameObjectExtensions { public static T Instantiate<T>(this GameObject gameObject, string name) where T : Component { GameObject val = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, false); ((Object)val).name = name; return val.GetComponent<T>(); } } } namespace GTFuckingXP.Enums { public enum CustomScaling { MeleeRangeMultiplier, MeleeHitBoxSizeMultiplier, MovementSpeedMultiplier, AntiFogSphere, JumpVelInitialPlus, JumpGravityMulDefaultPlus, JumpGravityMulButtonReleased, JumpGravityMulAfterPeakPlus, JumpGravityMulFallingPlus, JumpVerticalVelocityMaxPlus } public enum PlayerBuff { MaxHP, HammerDamage, WeaponDamage } public enum SingleBuff { Heal, Desinfect, AmmunitionMain, AmmunitionSpecial, AmmunitionTool } } namespace GTFuckingXP.Communication { public static class XpApi { public static bool ReloadData() { try { ScriptManager instance = ScriptManager.Instance; instance.UpdateEverything(); LevelLayout levelLayout = default(LevelLayout); if (CacheApi.TryGetInformation<LevelLayout>((object)"LevelLayout", ref levelLayout, "GTF_XP", true)) { List<LevelLayout> instance2 = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP"); LevelLayout currentLevelLayout = instance2.FirstOrDefault((LevelLayout it) => it.Header == levelLayout.Header); Level activeLevel = CacheApiWrapper.GetActiveLevel(); CacheApiWrapper.SetCurrentLevelLayout(currentLevelLayout); SetCurrentLevel(activeLevel.LevelNumber, out var _); } return true; } catch (Exception msg) { LogManager.Error(msg); return false; } } public static bool AddXp(uint xpAmount) { //IL_001e: 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) try { XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP"); instance.AddXp(new EnemyXp(0u, "", xpAmount, xpAmount, 0), default(Vector3)); return true; } catch (Exception msg) { LogManager.Error(msg); return false; } } public static bool SetCurrentTotalXp(uint newTotalXpAmount, out int cheatedXp) { //IL_0022: 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) try { XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP"); cheatedXp = (int)(newTotalXpAmount - instance.CurrentTotalXp); instance.CurrentTotalXp = newTotalXpAmount; instance.CheckForLevelThresholdReached(default(Vector3), out string currentClassName); CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), instance.NextLevel, instance.CurrentTotalXp, currentClassName); return true; } catch (Exception msg) { LogManager.Error(msg); cheatedXp = 0; return false; } } public static bool SetCurrentLevel(int levelNumber, out int cheatedXp) { try { LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout(); XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP"); Level level = currentLevelLayout.Levels.First((Level it) => it.LevelNumber == levelNumber); instance.ChangeCurrentLevel(level, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, level.LevelNumber)); cheatedXp = (int)(level.TotalXpRequired - instance.CurrentTotalXp); instance.CurrentTotalXp = level.TotalXpRequired + 1; instance.NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == levelNumber + 1); CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), instance.NextLevel, instance.CurrentTotalXp, currentLevelLayout.Header); } catch (Exception msg) { LogManager.Error(msg); cheatedXp = 0; return false; } return true; } public static bool ChangeCurrentLevelLayout(string header) { string header2 = header; try { LevelLayout newActiveLevelLayout = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP").First((LevelLayout it) => it.Header == header2); return ChangeCurrentLevelLayout(newActiveLevelLayout); } catch (Exception msg) { LogManager.Error(msg); return false; } } public static bool ChangeCurrentLevelLayout(LevelLayout newActiveLevelLayout) { try { bool flag = true; CacheApiWrapper.SetCurrentLevelLayout(newActiveLevelLayout); XpHandler xpHandler = default(XpHandler); if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { uint currentTotalXp = xpHandler.CurrentTotalXp; flag = SetCurrentLevel(0, out var cheatedXp) && SetCurrentTotalXp(currentTotalXp, out cheatedXp); } return true; } catch (Exception msg) { LogManager.Error(msg); return false; } } public static void AddOnLevelUpCallback(Action<Level> lvlUpCallback) { CacheApiWrapper.AddLvlUpCallback(lvlUpCallback); } public static void AddScriptsLoaded(Action<Level> scriptsLoadedCallback) { CacheApiWrapper.AddScriptsStartedCallback(scriptsLoadedCallback); } } } namespace GTFuckingXP.Managers { [BepInPlugin("Endskill.GTFuckingXP", "GTFuckingXP", "1.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class BepInExLoader : BasePlugin { public const string MODNAME = "GTFuckingXP"; public const string AUTHOR = "Endskill"; public const string GUID = "Endskill.GTFuckingXP"; public const string VERSION = "1.3.1"; public static bool RundownDevMode { get; private set; } public static ConfigEntry<bool> DebugMessages { get; private set; } public static ConfigEntry<bool> LvlUpPopups { get; private set; } public static ConfigEntry<bool> XpPopups { get; private set; } public static ConfigEntry<string> TermsOfUsage { get; internal set; } public static TermsOfUsage TermsOfUsageState { get; private set; } public static Harmony Harmony { get; private set; } public override void Load() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown RundownDevMode = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "RundownDev Mode", false, "This will activate the xp dev tool while in an expedition \nPress \"Delete\" to hide/show it").Value; DebugMessages = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin."); LvlUpPopups = ((BasePlugin)this).Config.Bind<bool>("Popups", "Lvl up popups", true, "If Lvl UP popups should be shown."); XpPopups = ((BasePlugin)this).Config.Bind<bool>("Popups", "XP gain popups", true, "If XP gain popups should be shown"); TermsOfUsageState = GTFuckingXP.Information.TermsOfUsage.Declined; ClassInjector.RegisterTypeInIl2Cpp<XpHandler>(); ClassInjector.RegisterTypeInIl2Cpp<XpBar>(); ClassInjector.RegisterTypeInIl2Cpp<DevModeTools>(); ClassInjector.RegisterTypeInIl2Cpp<DevTools>(); ScriptManager.Instance = new ScriptManager(); BoosterBuffManager.Instance = new BoosterBuffManager(); NetworkApiXpManager.Setup(); Harmony = new Harmony("Endskill.GTFuckingXP"); FasterPatching(); CacheApiWrapper.SetLvlUpCallBackList(new List<Action<Level>>()); CacheApiWrapper.SetScriptsStartedCallBackList(new List<Action<Level>>()); InitApi.AddInitCallback((Action)delegate { ScriptManager.Instance.Initialize(); }); } private void FasterPatching() { Harmony.PatchAll(typeof(PlayerLobbyBarPatches)); Harmony.PatchAll(typeof(GS_InLevelPatches)); Harmony.PatchAll(typeof(EnemyDamageBasePatches)); Harmony.PatchAll(typeof(GS_AfterLevelPatches)); Harmony.PatchAll(typeof(PlaceNavMarkerOnGoPatches)); Harmony.PatchAll(typeof(SnetSessionHubPatches)); } private void TermsOfUsageChanged(object sender, EventArgs e) { LogManager.Debug("Accepting terms of usage while ingame."); UpdateTermsOfUsage(); TermsOfUsage.SettingChanged -= TermsOfUsageChanged; } private void UpdateTermsOfUsage() { Enum.TryParse<TermsOfUsage>(TermsOfUsage.Value, out var result); TermsOfUsageState = result; } } public class BoosterBuffManager { public static BoosterBuffManager Instance { get; set; } public void ApplyBoosterEffects(PlayerAgent targetAgent, BoosterBuffs buffs) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) List<uint> list = default(List<uint>); if (!CacheApi.TryGetInformation<List<uint>>((object)targetAgent.Owner.Lookup, ref list, "GTF_XP", true)) { list = new List<uint>(); } foreach (uint item in list) { AgentModifierManager.ClearModifierChange(item); } list = new List<uint>(); if (buffs != null) { foreach (KeyValuePair<AgentModifier, float> valueToBoosterEffect in buffs.ValueToBoosterEffects) { if (valueToBoosterEffect.Value != 0f) { list.Add(AgentModifierManager.AddModifierValue((Agent)(object)targetAgent, valueToBoosterEffect.Key, valueToBoosterEffect.Value - 1f, 0f)); } } } CacheApi.SaveInformation((object)targetAgent.Owner.Lookup, (object)list, "GTF_XP"); } public BoosterBuffs GetFittingBoosterBuff(int levelLayoutPersistendId, int levelNumber) { List<BoosterBuffs> instance = CacheApi.GetInstance<List<BoosterBuffs>>("GTF_XP"); BoosterBuffs boosterBuffs = instance.FirstOrDefault((BoosterBuffs it) => it.ClassLayoutPersistentId == levelLayoutPersistendId && it.ActiveLevels.Contains(levelNumber)); LogManager.Debug($"GetfittingBoosterBuff call with {levelLayoutPersistendId} as ID and {levelNumber} as levelNumber. {((boosterBuffs != null) ? "buff found" : "Buff is null")}"); return boosterBuffs; } } public static class CustomScalingBuffManager { public static void ApplyCustomScalingEffects(PlayerAgent targetAgent, List<CustomScalingBuff> buffs) { if (buffs == null || buffs.Count == 0) { return; } foreach (CustomScalingBuff buff in buffs) { switch (buff.CustomBuff) { case CustomScaling.MeleeRangeMultiplier: if (((Agent)targetAgent).IsLocallyOwned) { MeleeArchetypeDataBlock meleeArchetypeData = ((ItemEquippable)GetLocalMeleeWeapon()).MeleeArchetypeData; if (!CacheApiWrapper.TryGetDefaultMeleeRange(out var meleeRange)) { meleeRange = meleeArchetypeData.CameraDamageRayLength; CacheApiWrapper.SetDefaultMeleeRange(meleeRange); } meleeArchetypeData.CameraDamageRayLength = meleeRange * buff.Value; } break; case CustomScaling.MeleeHitBoxSizeMultiplier: if (((Agent)targetAgent).IsLocallyOwned) { MeleeArchetypeDataBlock meleeArchetypeData2 = ((ItemEquippable)GetLocalMeleeWeapon()).MeleeArchetypeData; if (!CacheApiWrapper.TryGetDefaultMeleeHitBox(out var meleeHitbox)) { meleeHitbox = meleeArchetypeData2.AttackSphereRadius; CacheApiWrapper.SetDefaultMeleeHitBox(meleeHitbox); } meleeArchetypeData2.AttackSphereRadius = meleeHitbox * buff.Value; } break; case CustomScaling.MovementSpeedMultiplier: if (((Agent)targetAgent).IsLocallyOwned) { LogManager.Debug("Pre movment speed"); PlayerDataBlock playerData = targetAgent.PlayerData; if (!CacheApiWrapper.TryGetDefaultMovment(out (float, float, float, float) movmentData)) { movmentData.Item1 = playerData.walkMoveSpeed; movmentData.Item2 = playerData.runMoveSpeed; movmentData.Item3 = playerData.airMoveSpeed; movmentData.Item4 = playerData.crouchMoveSpeed; CacheApiWrapper.SetDefaultMovment(movmentData.Item1, movmentData.Item2, movmentData.Item3, movmentData.Item4); } playerData.walkMoveSpeed = movmentData.Item1 * buff.Value; playerData.runMoveSpeed = movmentData.Item2 * buff.Value; playerData.airMoveSpeed = movmentData.Item3 * buff.Value; playerData.crouchMoveSpeed = movmentData.Item4 * buff.Value; LogManager.Debug("Post movment speed"); } break; case CustomScaling.JumpVelInitialPlus: { if (!CacheApiWrapper.TryGetDefaultJumpVelInitial(out var value5)) { value5 = targetAgent.PlayerData.jumpVelInitial; CacheApiWrapper.SetDefaultJumpVelInitial(value5); } targetAgent.PlayerData.jumpVelInitial = value5 + buff.Value; break; } case CustomScaling.JumpGravityMulDefaultPlus: { if (!CacheApiWrapper.TryGetDefaultJumpGravityMulDefault(out var value4)) { value4 = targetAgent.PlayerData.jumpGravityMulDefault; CacheApiWrapper.SetDefaultJumpGravityMulDefault(value4); } targetAgent.PlayerData.jumpGravityMulDefault = value4 + buff.Value; break; } case CustomScaling.JumpGravityMulButtonReleased: { if (!CacheApiWrapper.TryGetDefaultJumpGravityMulButtonReleased(out var value2)) { value2 = targetAgent.PlayerData.jumpGravityMulButtonReleased; CacheApiWrapper.SetDefaultJumpGravityMulButtonReleased(value2); } targetAgent.PlayerData.jumpGravityMulButtonReleased = value2 + buff.Value; break; } case CustomScaling.JumpGravityMulAfterPeakPlus: { if (!CacheApiWrapper.TryGetDefaultJumpGravityMulAfterPeak(out var value6)) { value6 = targetAgent.PlayerData.jumpGravityMulAfterPeak; CacheApiWrapper.SetDefaultJumpGravityMulAfterPeak(value6); } targetAgent.PlayerData.jumpGravityMulAfterPeak = value6 + buff.Value; break; } case CustomScaling.JumpGravityMulFallingPlus: { if (!CacheApiWrapper.TryGetDefaultJumpGravityMulFalling(out var value3)) { value3 = targetAgent.PlayerData.jumpGravityMulFalling; CacheApiWrapper.SetDefaultJumpGravityMulFalling(value3); } targetAgent.PlayerData.jumpGravityMulFalling = value3 + buff.Value; break; } case CustomScaling.JumpVerticalVelocityMaxPlus: { if (!CacheApiWrapper.TryGetDefaultJumpVelocityMax(out var value)) { value = targetAgent.PlayerData.jumpVerticalVelocityMax; CacheApiWrapper.SetDefaultJumpVelocityMax(value); } targetAgent.PlayerData.jumpVerticalVelocityMax = value + buff.Value; break; } } } } private static void StartRepellerWithoutSound(FogRepeller_Sphere antiFog) { } private static MeleeWeaponFirstPerson GetLocalMeleeWeapon() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 Enumerator<BackpackItem> enumerator = PlayerBackpackManager.LocalBackpack.BackpackItems.GetEnumerator(); while (enumerator.MoveNext()) { BackpackItem current = enumerator.Current; if ((int)current.Instance.pItemData.slot == 10) { LogManager.Debug("Found Melee"); return ((Il2CppObjectBase)current.Instance).Cast<MeleeWeaponFirstPerson>(); } } LogManager.Warn("No melee weapon found o.O?"); throw new Exception($"There is no {typeof(MeleeWeaponFirstPerson)} item in the local backpack!"); } } internal class LogManager { private static readonly ManualLogSource logger; private static readonly bool _debugMessagesActive; static LogManager() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown _debugMessagesActive = BepInExLoader.DebugMessages.Value; logger = new ManualLogSource("GTFuckingXP"); Logger.Sources.Add((ILogSource)(object)logger); } public static void Verbose(object msg) { if (_debugMessagesActive) { logger.LogInfo(msg); } } public static void Debug(object msg) { if (_debugMessagesActive) { logger.LogDebug(msg); } } public static void Message(object msg) { if (_debugMessagesActive) { logger.LogMessage(msg); } } public static void Error(object msg) { logger.LogError(msg); } public static void Warn(object msg) { logger.LogWarning(msg); } } public static class NetworkApiXpManager { private const string _sendXpString = "ThisSeemsLikeItComesFromTheRandomXpMod..."; private const string _levelStatsDistribution = "ReachedSentLevel_XP"; private const string _receiveStaticXp = "XpModTriesToGiveYouSomeHalfAssedXP"; private const string _undistributedXp = "XpModGivesYouSomeXpWhereYouHadNotToDoAnything"; private const string _sendBoosterNetworkString = "MyNewBoostersEffectFromTheXpMod"; public static void Setup() { NetworkAPI.RegisterEvent<GtfoApiXpInfo>("ThisSeemsLikeItComesFromTheRandomXpMod...", (Action<ulong, GtfoApiXpInfo>)ReceiveXp); NetworkAPI.RegisterEvent<LevelReachedInfo>("ReachedSentLevel_XP", (Action<ulong, LevelReachedInfo>)ReceiveLevelReached); NetworkAPI.RegisterEvent<StaticXpInfo>("XpModTriesToGiveYouSomeHalfAssedXP", (Action<ulong, StaticXpInfo>)ReceiveStaticXp); NetworkAPI.RegisterEvent<BoosterInfo>("MyNewBoostersEffectFromTheXpMod", (Action<ulong, BoosterInfo>)ReceiveBoosterBuffs); NetworkAPI.RegisterEvent<GtfoApiXpInfo>("XpModGivesYouSomeXpWhereYouHadNotToDoAnything", (Action<ulong, GtfoApiXpInfo>)ReceiveHalfAssedXp); } public static void ReceiveXp(ulong snetPlayer, GtfoApiXpInfo xpData) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) LogManager.Debug("Received xp networking package"); XpHandler xpHandler = default(XpHandler); if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { xpHandler.AddXp(xpData, new Vector3(xpData.PositionX, xpData.PositionY, xpData.PositionZ)); } } public static void ReceiveHalfAssedXp(ulong snetPlayer, GtfoApiXpInfo xpData) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) XpHandler xpHandler = default(XpHandler); if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { xpHandler.AddXp(xpData, new Vector3(xpData.PositionX, xpData.PositionY, xpData.PositionZ), xpData.ForceDebuffXp, "<#888>"); } } public static void ReceiveStaticXp(ulong snetPlayer, StaticXpInfo xpInfo) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) LogManager.Debug("Received static xp networking pckage"); XpHandler xpHandler = default(XpHandler); if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true)) { xpHandler.AddXp(xpInfo, xpInfo.Position, forceDebuffXp: false, "<#F30>"); } } public static void ReceiveLevelReached(ulong snetPlayer, LevelReachedInfo levelData) { LogManager.Debug("Receive level reached info"); SNet_Player val = default(SNet_Player); if (!SNet.TryGetPlayer(snetPlayer, ref val)) { return; } List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel; Enumerator<PlayerAgent> enumerator = playerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (current.PlayerSlotIndex == val.PlayerSlotIndex()) { Level level = new Level(levelData); float num = level.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp(); LogManager.Debug($"Setting HP of {((Object)current).name} to {num}"); ((Dam_SyncedDamageBase)current.Damage).HealthMax = num; CustomScalingBuffManager.ApplyCustomScalingEffects(current, level.CustomScaling); CacheApiWrapper.GetPlayerToLevelMapping()[current.PlayerSlotIndex] = level; } } } internal static void ReceiveBoosterBuffs(ulong snetPlayer, BoosterInfo newInfo) { SNet_Player val = default(SNet_Player); if (!SNet.TryGetPlayer(snetPlayer, ref val)) { return; } List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel; Enumerator<PlayerAgent> enumerator = playerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (current.PlayerSlotIndex == val.PlayerSlotIndex()) { BoosterBuffManager.Instance.ApplyBoosterEffects(current, newInfo); } } } public static void SendReceiveXp(SNet_Player receiver, EnemyXp xpData, Vector3 position, bool forceDebuffXp) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<GtfoApiXpInfo>("ThisSeemsLikeItComesFromTheRandomXpMod...", new GtfoApiXpInfo(xpData.XpGain, xpData.DebuffXp, xpData.LevelScalingXpDecrese, position, forceDebuffXp), receiver, (SNet_ChannelType)2); } public static void SendHalfAssedXp(EnemyXp xpData, Vector3 position, bool forceDebuffXp) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<GtfoApiXpInfo>("XpModGivesYouSomeXpWhereYouHadNotToDoAnything", new GtfoApiXpInfo(xpData.XpGain, xpData.DebuffXp, xpData.LevelScalingXpDecrese, position, forceDebuffXp), (SNet_ChannelType)2); } public static void SendNewLevelActive(Level newLevel) { string customScaling = JsonSerializer.Serialize((newLevel.CustomScaling == null) ? new List<CustomScalingBuff>() : newLevel.CustomScaling); NetworkAPI.InvokeEvent<LevelReachedInfo>("ReachedSentLevel_XP", new LevelReachedInfo(newLevel.LevelNumber, newLevel.HealthMultiplier, customScaling), (SNet_ChannelType)2); } public static void SendBoosterStatsReached(BoosterInfo boosterInfo) { NetworkAPI.InvokeEvent<BoosterInfo>("MyNewBoostersEffectFromTheXpMod", boosterInfo, (SNet_ChannelType)2); } public static void SendStaticXpInfo(SNet_Player receiver, uint xpGain, uint debuffXp, int levelScalingDecrease, Vector3 position) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<StaticXpInfo>("XpModTriesToGiveYouSomeHalfAssedXP", new StaticXpInfo(xpGain, debuffXp, levelScalingDecrease, position), receiver, (SNet_ChannelType)2); } } public class ScriptManag
BepInEx/plugins/MadnessLights.dll
Decompiled a year agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using GTFO.API; using Il2CppSystem; using LevelGeneration; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("MadnessLights")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MadnessLights")] [assembly: AssemblyTitle("MadnessLights")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace MadnessLights { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("MadnessLights", "MadnessLights", "0.0.1")] public class Plugin : BasePlugin { private class MadnessLights : MonoBehaviour { public bool _valot; public ManualLogSource Log; public void Initialize() { foreach (LG_Light item in Object.FindObjectsOfType<LG_Light>()) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(SetLightIntensity(item)), (Action)null); } } private void Start() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin is loaded!"); } log.LogInfo(val); } private void Update() { if (Input.GetKeyDown((KeyCode)56)) { _valot = !_valot; Log.LogInfo((object)("flashing lights manual activation: " + (_valot ? "enabled" : "disabled"))); } } private IEnumerator SetLightIntensity(LG_Light obj) { bool hirnudirection = true; float hirnuintensity = 0.02f; ((Object)obj).GetInstanceID(); float origintensity = obj.m_intensity; Color origcolor = obj.m_color; Color hirnuvari = Color.red; while (true) { if (_valot | WorldEventManager.GetCondition(16)) { obj.ChangeColor(hirnuvari); while (_valot | WorldEventManager.GetCondition(16)) { if (hirnuintensity > 0.1f && hirnudirection) { hirnudirection = false; hirnuintensity = 0.09f; } if (hirnuintensity < 0.01f && !hirnudirection) { hirnudirection = true; } if (hirnudirection) { hirnuintensity += 0.003f; } if (!hirnudirection) { hirnuintensity -= 0.003f; } obj.ChangeIntensity(hirnuintensity); yield return (object)new WaitForSeconds(0.04f); } } obj.ChangeColor(origcolor); obj.ChangeIntensity(origintensity); yield return (object)new WaitForSeconds(0.5f); } } } public override void Load() { MadnessLights madnessLights = ((BasePlugin)this).AddComponent<MadnessLights>(); EventAPI.OnExpeditionStarted += madnessLights.Initialize; madnessLights.Log = ((BasePlugin)this).Log; } } [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "MadnessLights"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = null; public const string SemVer = "1.0.0"; public const string GitRevShort = null; public const string GitRevLong = null; public const string GitBranch = null; public const string GitTag = null; public const bool GitIsDirty = false; } }