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.Versioning; using System.Text.Json; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using EndskApi.Api; using Enemies; using Expansions.Patches.DoubleJump; using GTFuckingXP.Communication; using GTFuckingXP.Extensions; using GTFuckingXP.Information.Level; using GTFuckingXP.Managers; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem.Collections.Generic; using MTFO.Managers; 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Expansions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+git1aa6666-dirty-master.1aa66668ab1ddf40e165d5fb41baa29f8e80b2d0")] [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.1.3+git35c0c2a-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 = "git1aa6666-dirty-master"; public const string SemVer = "1.0.0+git1aa6666-dirty-master"; public const string GitRevShort = "1aa6666-dirty"; public const string GitRevLong = "1aa66668ab1ddf40e165d5fb41baa29f8e80b2d0-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const int GitCommitsSinceTag = 0; public const bool GitIsDirty = true; } } namespace Expansions.Patches.DoubleJump { [HarmonyPatch] internal static class FallDamagePatches { [HarmonyPrefix] [HarmonyPatch(typeof(Dam_SyncedDamageBase), "FallDamage")] private static bool FallDamage(Dam_SyncedDamageBase __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 if ((int)__instance.DamageBaseOwner != 0) { return true; } PlayerAgent val = ((Il2CppObjectBase)__instance.GetBaseAgent()).Cast(); if ((int)val.Locomotion.m_currentStateEnum == 3 || (int)val.Locomotion.m_currentStateEnum == 4) { return false; } return true; } } [HarmonyPatch] internal static class PLOC_Patches { private static bool _canDoubleJump = true; [HarmonyPostfix] [HarmonyPatch(typeof(PLOC_Crouch), "Enter")] [HarmonyPatch(typeof(PLOC_Run), "Enter")] [HarmonyPatch(typeof(PLOC_Stand), "Enter")] public static void Enter() { _canDoubleJump = DoubleJumpManager.DoubleJumpUnlocked; } [HarmonyPostfix] [HarmonyPatch(typeof(PLOC_Fall), "Update")] public static void Update(PLOC_Fall __instance) { TryDoubleJump((PLOC_Base)(object)__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(PLOC_Jump), "Update")] public static void Update(PLOC_Jump __instance) { TryDoubleJump((PLOC_Base)(object)__instance); } private static void TryDoubleJump(PLOC_Base state) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) PlayerAgent owner = state.m_owner; if (_canDoubleJump && InputMapper.GetButtonDown.Invoke((InputAction)5, owner.InputFilter)) { owner.Sound.Post(EVENTS.FLAMERFIREBURST, true); state.UpdateHorizontalVelocityOnGround(owner.PlayerData.runMoveSpeed); owner.Locomotion.ChangeState((PLOC_State)3, false); _canDoubleJump = false; } } } [HarmonyPatch] internal static class SuperJumpPatches { [HarmonyPostfix] [HarmonyPatch(typeof(PLOC_Jump), "Enter")] public static void Enter(PLOC_Jump __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) PlayerAgent owner = ((PLOC_Base)__instance).m_owner; if (DoubleJumpManager.DoubleJumpUnlocked && InputMapper.GetButtonKeyMouse((InputAction)10, owner.InputFilter)) { owner.Sound.Post(EVENTS.IMPLANTSMALLJUMPBOOSTTRIGGER, true); PlayerLocomotion locomotion = owner.Locomotion; locomotion.VerticalVelocity += Vector3.up * DoubleJumpManager.ActiveConfig.SuperJumpVelocity; } } } } namespace XpExpansions { [BepInPlugin("Endskill.XpExpansions", "XpExpansions", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [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 = "XpExpansions"; public const string AUTHOR = "Endskill"; public const string GUID = "Endskill.XpExpansions"; public const string VERSION = "1.0.1"; public override void Load() { LogManager.SetLogger(((BasePlugin)this).Log); LogManager._debugMessagesActive = ((BasePlugin)this).Config.Bind("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.").Value; ClassInjector.RegisterTypeInIl2Cpp(); CacheApi.SaveInstance(new ExpansionManager(), CacheApiWrapper.ExtensionCacheName); } } } namespace XpExpansions.Scripts { public class ClientSidedBioTrackerAbility : MonoBehaviour { private float _nextUpdate; public ClientSidedBioTrackerAbility(IntPtr intPtr) : base(intPtr) { } public void Update() { if (!(Time.time > _nextUpdate)) { return; } if (GameStateManager.IsInExpedition) { PlayerManager.GetLocalPlayerAgent(); Enumerator enumerator = AIG_CourseGraph.GetReachableEnemiesInNodes(((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode, 1).GetEnumerator(); while (enumerator.MoveNext()) { ToolSyncManager.WantToTagEnemy(enumerator.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(); LocalBioTrackerData localBioTrackerData = CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName).FirstOrDefault((LocalBioTrackerData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId); if (localBioTrackerData != null) { if (localBioTrackerData.UnlockAtLevel <= level.LevelNumber) { CacheApiWrapper.DestroyOldCreateRegisterAndReturnComponent(); } else { DestroyBioTrackerAbility(); } } } public void DestroyBioTrackerAbility() { CacheApiWrapper.KillScript(); } 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>(JsonSerializer.Deserialize>(File.ReadAllText(Path.Combine(base.FolderPath, "BioTracker.json"))), CacheApiWrapper.ExtensionCacheName); } private List GetDefaultData() { List list = new List(); 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 (base.FolderPath.Contains("BepInEx")) { 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 { 69420, 42069 }, options)); } } } } public class DoubleJumpManager : BaseManager { public const string OldGUID = "com.mccad00.DoubleJump"; public const string DoubleJumpXpExpansionId = "Endskill.DoubleJumpExpansion"; private const string _expansionFileName = "DoubleJumpExpansion.json"; private const string _configFileName = "DoubleJumpDefaultConfig.json"; private static DoubleJumpConfig _baseConfig = new DoubleJumpConfig(); public static DoubleJumpConfig ActiveConfig { get; private set; } = new DoubleJumpConfig(); public static bool DoubleJumpUnlocked { get; private set; } public DoubleJumpManager() { //IL_001b: 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_0030: Unknown result type (might be due to invalid IL or missing references) Harmony.UnpatchID("com.mccad00.DoubleJump"); DoubleJumpUnlocked = false; Harmony val = new Harmony("Endskill.DoubleJumpExpansion"); val.PatchAll(typeof(PLOC_Patches)); val.PatchAll(typeof(FallDamagePatches)); val.PatchAll(typeof(SuperJumpPatches)); } public override void Initialize() { WriteDefaultJsonBlocks(); UpdateEverything(); } public override void LevelCleanup() { DoubleJumpUnlocked = false; } public override void LevelReached(Level level) { LogManager.Message("LevelReached, DoubleJump " + ((object)level).ToString()); LevelLayout levelLayout = CacheApiWrapper.GetCurrentLevelLayout(); DoubleJumpData doubleJumpData = CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName).FirstOrDefault((DoubleJumpData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId); if (doubleJumpData != null) { if (doubleJumpData.UnlockAtLevel <= level.LevelNumber) { DoubleJumpUnlocked = true; ActiveConfig = doubleJumpData.DoubleJumpConfig ?? _baseConfig; } else { DoubleJumpUnlocked = false; } } else { DoubleJumpUnlocked = 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)) { File.WriteAllText(path, "[\r\n {\r\n \"LevelLayoutPersistentId\": 13,\r\n \"UnlockAtLevel\": 10,\r\n \"DoubleJumpConfig\": null\r\n },\r\n {\r\n \"LevelLayoutPersistentId\": 14,\r\n \"UnlockAtLevel\": 6,\r\n \"DoubleJumpConfig\": null\r\n },\r\n {\r\n \"LevelLayoutPersistentId\": 7,\r\n \"UnlockAtLevel\": 5,\r\n \"DoubleJumpConfig\": null\r\n },\r\n {\r\n \"LevelLayoutPersistentId\": 8,\r\n \"UnlockAtLevel\": 5,\r\n \"DoubleJumpConfig\": null\r\n },\r\n {\r\n \"LevelLayoutPersistentId\": 15,\r\n \"UnlockAtLevel\": 5,\r\n \"DoubleJumpConfig\": null\r\n }\r\n]"); } string path2 = Path.Combine(base.FolderPath, "DoubleJumpDefaultConfig.json"); if (File.Exists(path2)) { _baseConfig = JsonSerializer.Deserialize(File.ReadAllText(path2)); return; } string path3 = Path.Combine(ConfigManager.CustomPath, "mccad00", "DoubleJump.json"); if (File.Exists(path3)) { _baseConfig = JsonSerializer.Deserialize(File.ReadAllText(path3)); } else { _baseConfig = new DoubleJumpConfig(); } File.WriteAllText(path2, JsonSerializer.Serialize(_baseConfig, new JsonSerializerOptions { WriteIndented = true, IncludeFields = true })); } private void UpdateEverything() { CacheApi.SaveInstance>(JsonSerializer.Deserialize>(File.ReadAllText(Path.Combine(base.FolderPath, "DoubleJumpExpansion.json"))), CacheApiWrapper.ExtensionCacheName); } } 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)LevelReached); XpApi.AddScriptsLoaded((Action)LevelInitialized); } public override void Initialize() { CacheApiWrapper.SetFolderPath(Path.Combine(ScriptManager.Instance.GetFolderPath(), "Expansions")); WriteDefaultData(); List list = CreateManagers(); CacheApi.SaveInstance>(list, CacheApiWrapper.ExtensionCacheName); foreach (BaseManager item in list) { item.Initialize(); } } public override void LevelCleanup() { foreach (BaseManager item in CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName)) { item.LevelCleanup(); } } public override void LevelReached(Level level) { LogManager.Message("LevelReached in the Expansion Manager."); foreach (BaseManager item in CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName)) { item.LevelReached(level); } } public override void LevelInitialized(Level level) { LogManager.Message("LevelInitialized in the Expansion Manager."); foreach (BaseManager item in CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName)) { item.LevelInitialized(level); } } private List CreateManagers() { List list = new List(); ActiveExpansions activeExpansions = JsonSerializer.Deserialize(File.ReadAllText(Path.Combine(base.FolderPath, "ExpansionsActive.json"))); 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: true))); } } } public class ExplosionAbilityManager : BaseManager { public const string ExplosionHarmonyInstanceId = "Endskill.ExplosionAbility"; public Harmony ExplosionHarmony { get; private set; } public ExplosionAbilityManager() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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; StartingXpData startingXpData = CacheApi.GetInstance>(CacheApiWrapper.ExtensionCacheName).FirstOrDefault((StartingXpData it) => it.LevelLayoutData == expedition.LevelLayoutData); if (startingXpData != null) { XpApi.AddXp(startingXpData.StartingXp); } } private void UpdateEverything() { CacheApi.SaveInstance>(JsonSerializer.Deserialize>(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 GetDefaultData() { List list = new List(); foreach (RundownDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { Enumerator enumerator2 = allBlock.TierD.GetEnumerator(); while (enumerator2.MoveNext()) { ExpeditionInTierData current = enumerator2.Current; list.Add(new StartingXpData(current.LevelLayoutData, 100)); } } 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 int StartingXp { get; set; } public StartingXpData(uint levelLayoutData, int 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 { public sealed class DoubleJumpConfig { public bool DoubleJumpEnabled { get; set; } = true; public bool SuperJumpEnabled { get; set; } = true; public float SuperJumpVelocity { get; set; } = 3f; } internal class DoubleJumpData { public int LevelLayoutPersistentId { get; set; } public int UnlockAtLevel { get; set; } public DoubleJumpConfig? DoubleJumpConfig { get; set; } public DoubleJumpData(int levelLayoutPersistentId, int unlockAtLevel, DoubleJumpConfig? doubleJumpConfig) { LevelLayoutPersistentId = levelLayoutPersistentId; UnlockAtLevel = unlockAtLevel; DoubleJumpConfig = doubleJumpConfig; } } } 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((object)"FolderPath", ExtensionCacheName); } } }