Decompiled source of Recall v1.0.0
plugins/net6/FloLib.dll
Decompiled 10 months 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using AIGraph; using AK; using Agents; using AssetShards; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BepInEx.Unity.IL2CPP.Utils; using BepInEx.Unity.IL2CPP.Utils.Collections; using FloLib.Attributes; using FloLib.Events; using FloLib.Infos; using FloLib.Infos.Comps; using FloLib.Networks; using FloLib.Networks.Inject; using FloLib.Networks.PayloadStructs; using FloLib.Utils; using FloLib.Utils.Comps; using FloLib.Utils.Extensions; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.InteropTypes.Fields; using Il2CppInterop.Runtime.Runtime; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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("FloLib")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitd7090d7-dirty-master")] [assembly: AssemblyProduct("FloLib")] [assembly: AssemblyTitle("FloLib")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.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.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = 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 FloLib { public static class Automation { private const BindingFlags ALL = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartGame; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartupAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenEnemyAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenSharedAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenAllAssetsLoaded; static Automation() { _InvokeWhenStartGame = new Queue<(MethodInfo, object[])>(); _InvokeWhenStartupAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenEnemyAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenSharedAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenAllAssetsLoaded = new Queue<(MethodInfo, object[])>(); StartGameEvent.OnGameLoaded += delegate { (MethodInfo, object[]) result5; while (_InvokeWhenStartGame.TryDequeue(out result5)) { RunMethod(result5.Item1, result5.Item2); } }; AssetEvent.OnStartupAssetLoaded += delegate { (MethodInfo, object[]) result4; while (_InvokeWhenStartupAssetLoaded.TryDequeue(out result4)) { RunMethod(result4.Item1, result4.Item2); } }; AssetEvent.OnEnemyAssetLoaded += delegate { (MethodInfo, object[]) result3; while (_InvokeWhenEnemyAssetLoaded.TryDequeue(out result3)) { RunMethod(result3.Item1, result3.Item2); } }; AssetEvent.OnSharedAssetLoaded += delegate { (MethodInfo, object[]) result2; while (_InvokeWhenSharedAssetLoaded.TryDequeue(out result2)) { RunMethod(result2.Item1, result2.Item2); } }; AssetEvent.OnAllAssetsLoaded += delegate { (MethodInfo, object[]) result; while (_InvokeWhenAllAssetsLoaded.TryDequeue(out result)) { RunMethod(result.Item1, result.Item2); } }; } public static void RegisterTypes() { Assembly obj = new StackFrame(1).GetMethod()?.GetType()?.Assembly ?? null; if (obj == null) { throw new NullReferenceException("Caller Assembly was null"); } RegisterTypes(obj); } public static void RegisterTypes(Type target) { if (target == null) { throw new ArgumentNullException("target"); } RegisterTypes(target.Assembly); } public static void RegisterTypes(Assembly target) { if (target == null) { throw new ArgumentNullException("target"); } InjectAll(target); AddAutoInvokes(target); } private static void InjectAll(Assembly assem) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown foreach (Type item in assem.GetTypes()?.Where((Type x) => Attribute.IsDefined(x, typeof(AutoInjectAttribute))) ?? Enumerable.Empty<Type>()) { AutoInjectAttribute autoInjectAttribute = (AutoInjectAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInjectAttribute)); if (autoInjectAttribute.Interfaces.Length != 0) { RegisterTypeOptions val = new RegisterTypeOptions(); val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(autoInjectAttribute.Interfaces)); val.set_LogSuccess(RegisterTypeOptions.Default.LogSuccess); ClassInjector.RegisterTypeInIl2Cpp(item, val); } else { ClassInjector.RegisterTypeInIl2Cpp(item); } } } private static void AddAutoInvokes(Assembly assem) { foreach (MethodInfo item in assem.GetTypes()?.SelectMany((Type x) => x.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.Where((MethodInfo x) => x.IsStatic && Attribute.IsDefined(x, typeof(AutoInvokeAttribute))) ?? Enumerable.Empty<MethodInfo>()) { AutoInvokeAttribute obj = (AutoInvokeAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInvokeAttribute)); object[] arguments = obj.Arguments; switch (obj.When) { case InvokeWhen.PluginLoaded: RunMethod(item, arguments); break; case InvokeWhen.StartGame: _InvokeWhenStartGame.Enqueue((item, arguments)); break; case InvokeWhen.StartupAssetLoaded: _InvokeWhenStartupAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.EnemyAssetLoaded: _InvokeWhenEnemyAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.SharedAssetLoaded: _InvokeWhenSharedAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.AllAssetsLoaded: _InvokeWhenAllAssetsLoaded.Enqueue((item, arguments)); break; } } } private static void RunMethod(MethodInfo method, params object[] args) { if (method.IsConstructor) { RuntimeHelpers.RunClassConstructor(method.DeclaringType.TypeHandle); } else { method.Invoke(null, args); } } } [BepInPlugin("GTFO.FloLib", "FloLib", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { private Harmony _Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _Harmony = new Harmony("FloLib.Harmony"); _Harmony.PatchAll(); Automation.RegisterTypes(((object)this).GetType()); } public override bool Unload() { _Harmony.UnpatchSelf(); return ((BasePlugin)this).Unload(); } } internal static class Logger { internal static bool LogExceptionInDetail; private static readonly ManualLogSource _Logger; static Logger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _Logger = new ManualLogSource("FloLib"); Logger.Sources.Add((ILogSource)(object)_Logger); } private static string Format(object msg) { return msg.ToString(); } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { _Logger.LogInfo(handler); } public static void Info(string str) { _Logger.LogMessage((object)str); } public static void Info(object data) { _Logger.LogMessage((object)Format(data)); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { _Logger.LogDebug(handler); } public static void Debug(string str) { _Logger.LogDebug((object)str); } public static void Debug(object data) { _Logger.LogDebug((object)Format(data)); } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { _Logger.LogError(handler); } public static void Error(string str) { _Logger.LogError((object)str); } public static void Error(object data) { _Logger.LogError((object)Format(data)); } public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler) { _Logger.LogFatal(handler); } public static void Fatal(string str) { _Logger.LogFatal((object)str); } public static void Fatal(object data) { _Logger.LogFatal((object)Format(data)); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { _Logger.LogWarning(handler); } public static void Warn(string str) { _Logger.LogWarning((object)str); } public static void Warn(object data) { _Logger.LogWarning((object)Format(data)); } [Conditional("DEBUG")] public static void DebugOnly(object data) { } public static void Exception(Exception e) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (LogExceptionInDetail) { _Logger.LogError((object)e.ToString()); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(2, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message); } _Logger.LogError(val); } } internal static class TaskQueue { public const float INTERVAL = 0.15f; private static readonly ConcurrentQueue<(Action action, string? name)> q; public static Coroutine mainCoroutine { get; private set; } private static IEnumerator MainLoop() { while (true) { if (q.TryDequeue(out (Action, string) result)) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ExecuteTask(result.Item1, (result.Item2 == null) ? "unnamed" : result.Item2)), (Action)null); } yield return (object)new WaitForSeconds(0.15f); } } private static IEnumerator ExecuteTask(Action task, string name) { bool flag = default(bool); try { task?.Invoke(); } catch (Exception ex) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Exception occurred during execution of task "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } Logger.Error(val); } finally { BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(11, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Task "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ended"); } Logger.Debug(val2); } yield break; } public static void AddTask(Action task, string name = null) { q.Enqueue((task, name)); } static TaskQueue() { q = new ConcurrentQueue<(Action, string)>(); Logger.Debug("TaskQueue: Coroutine started"); mainCoroutine = CoroutineManager.StartPersistantCoroutine(CollectionExtensions.WrapToIl2Cpp(MainLoop())); } } [GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "FloLib"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitd7090d7-dirty-master"; public const string SemVer = "1.0.0+gitd7090d7-dirty-master"; public const string GitRevShort = "d7090d7-dirty"; public const string GitRevLong = "d7090d7625ec9ea5a37260ec10ba96729e107216-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const int GitCommitsSinceTag = 0; public const bool GitIsDirty = true; } } namespace FloLib.Utils { public enum CoroutineLifeTime { Forever, Lobby, Level, BetweenRecall } public static class Coroutines { private static MonoBehaviour _Runner; private static readonly Queue<Coroutine> _Coroutines_Lobby = new Queue<Coroutine>(); private static readonly Queue<Coroutine> _Coroutines_Level = new Queue<Coroutine>(); private static readonly Queue<Coroutine> _Coroutines_CPLoad = new Queue<Coroutine>(); [AutoInvoke(InvokeWhen.StartGame)] internal static void Init() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject(); Object.DontDestroyOnLoad((Object)val); _Runner = (MonoBehaviour)(object)val.AddComponent<EmptyMB>(); LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup; Inject_SNet_Capture.OnBufferRecalled += Inject_SNet_Capture_OnBufferRecalled; } private static void Inject_SNet_Capture_OnBufferRecalled(eBufferType obj) { StopAll(CoroutineLifeTime.BetweenRecall); } private static void LevelAPI_OnLevelCleanup() { StopAll(); StopAll(CoroutineLifeTime.BetweenRecall); } public static void StopAll(CoroutineLifeTime lifeTime = CoroutineLifeTime.Level) { Queue<Coroutine> queue = lifeTime switch { CoroutineLifeTime.Lobby => _Coroutines_Lobby, CoroutineLifeTime.Level => _Coroutines_Level, CoroutineLifeTime.BetweenRecall => _Coroutines_CPLoad, _ => throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!"), }; Coroutine result; while (queue.TryDequeue(out result)) { _Runner.StopCoroutine(result); } } public static void Stop(Coroutine coroutine) { _Runner.StopCoroutine(coroutine); } public static Coroutine Start(IEnumerator coroutine, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { switch (lifeTime) { case CoroutineLifeTime.Forever: return MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); case CoroutineLifeTime.Lobby: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_Lobby.Enqueue(val); return val; } case CoroutineLifeTime.Level: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_Level.Enqueue(val); return val; } case CoroutineLifeTime.BetweenRecall: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_CPLoad.Enqueue(val); return val; } default: throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!!"); } } public static Coroutine DoWait(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Wait(delay, onDone), lifeTime); } public static Coroutine DoWaitRealtime(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(WaitRealtime(delay, onDone), lifeTime); } public static Coroutine DoBlink(BlinkInfo blinkInfo, Action<bool> onBlinkChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Blink(blinkInfo, onBlinkChanged), lifeTime); } public static Coroutine DoLerp(LerpInfo lerpInfo, Action<float> onValueChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Lerp(lerpInfo, onValueChanged), lifeTime); } public static IEnumerator Wait(float delay, Action onDone) { yield return (object)new WaitForSeconds(delay); onDone?.Invoke(); } public static IEnumerator WaitRealtime(float delay, Action onDone) { yield return (object)new WaitForSecondsRealtime(delay); onDone?.Invoke(); } public static IEnumerator Blink(BlinkInfo info, Action<bool> onBlinkChanged) { float time = 0f; bool lastCond = false; onBlinkChanged?.Invoke(obj: false); while (time < info.Duration) { bool flag = BlinkByProgress(Mathf.Repeat(time * info.Speed, 1f)); if (flag != lastCond) { onBlinkChanged?.Invoke(flag); lastCond = flag; } time += Time.deltaTime; yield return null; } onBlinkChanged?.Invoke(info.EndBlinkState); } public static IEnumerator Lerp(LerpInfo info, Action<float> onValueChanged) { float time = 0f; onValueChanged?.Invoke(info.From); while (time < info.Duration) { float num = info.Easing.Evaluate(time / info.Duration); float obj = Mathf.Lerp(info.From, info.To, num); onValueChanged?.Invoke(obj); time += Time.deltaTime; yield return null; } onValueChanged?.Invoke(info.To); } private static bool BlinkByProgress(float progress) { return progress % 0.25f < 0.125f; } } public struct BlinkInfo { public bool EndBlinkState; public float Speed; public float Duration; public static readonly BlinkInfo InDefault = new BlinkInfo { Duration = 0.33f, Speed = 3f, EndBlinkState = true }; public static readonly BlinkInfo OutDefault = new BlinkInfo { Duration = 0.33f, Speed = 3f, EndBlinkState = false }; } public struct LerpInfo { public float From; public float To; public float Duration; public EaseFunc.Type Easing; public LerpInfo(float from, float to, float duration, EaseFunc.Type ease = EaseFunc.Type.Linear) { From = from; To = to; Duration = duration; Easing = ease; } } public static class EaseFunc { public enum Type : byte { Linear, Zero, One, InQuad, OutQuad, InOutQuad, InCubic, OutCubic, InOutCubic, InQuart, OutQuart, InOutQuart, InQuint, OutQuint, InOutQuint, InSine, OutSine, InOutSine, InExpo, OutExpo, InOutExpo, InCirc, OutCirc, InOutCirc, InElastic, OutElastic, InOutElastic, InBack, OutBack, InOutBack, InBounce, OutBounce, InOutBounce } public static float Evaluate(this Type type, float t) { t = Mathf.Clamp01(t); return type switch { Type.Linear => t, Type.Zero => 0f, Type.One => 1f, Type.InQuad => InQuad(t), Type.OutQuad => OutQuad(t), Type.InOutQuad => InOutQuad(t), Type.InCubic => InCubic(t), Type.OutCubic => OutCubic(t), Type.InOutCubic => InOutCubic(t), Type.InQuart => InQuart(t), Type.OutQuart => OutQuart(t), Type.InOutQuart => InOutQuart(t), Type.InQuint => InQuint(t), Type.OutQuint => OutQuint(t), Type.InOutQuint => InOutQuint(t), Type.InSine => InSine(t), Type.OutSine => OutSine(t), Type.InOutSine => InOutSine(t), Type.InExpo => InExpo(t), Type.OutExpo => OutExpo(t), Type.InOutExpo => InOutExpo(t), Type.InCirc => InCirc(t), Type.OutCirc => OutCirc(t), Type.InOutCirc => InOutCirc(t), Type.InElastic => InElastic(t), Type.OutElastic => OutElastic(t), Type.InOutElastic => InOutElastic(t), Type.InBack => InBack(t), Type.OutBack => OutBack(t), Type.InOutBack => InOutBack(t), Type.InBounce => InBounce(t), Type.OutBounce => OutBounce(t), Type.InOutBounce => InOutBounce(t), _ => throw new ArgumentOutOfRangeException("type", "Given type was invalid!"), }; } public static float InQuad(float t) { return t * t; } public static float OutQuad(float t) { return 1f - InQuad(1f - t); } public static float InOutQuad(float t) { if ((double)t < 0.5) { return InQuad(t * 2f) / 2f; } return 1f - InQuad((1f - t) * 2f) / 2f; } public static float InCubic(float t) { return t * t * t; } public static float OutCubic(float t) { return 1f - InCubic(1f - t); } public static float InOutCubic(float t) { if ((double)t < 0.5) { return InCubic(t * 2f) / 2f; } return 1f - InCubic((1f - t) * 2f) / 2f; } public static float InQuart(float t) { return t * t * t * t; } public static float OutQuart(float t) { return 1f - InQuart(1f - t); } public static float InOutQuart(float t) { if ((double)t < 0.5) { return InQuart(t * 2f) / 2f; } return 1f - InQuart((1f - t) * 2f) / 2f; } public static float InQuint(float t) { return t * t * t * t * t; } public static float OutQuint(float t) { return 1f - InQuint(1f - t); } public static float InOutQuint(float t) { if ((double)t < 0.5) { return InQuint(t * 2f) / 2f; } return 1f - InQuint((1f - t) * 2f) / 2f; } public static float InSine(float t) { return (float)(0.0 - Math.Cos((double)t * Math.PI / 2.0)); } public static float OutSine(float t) { return (float)Math.Sin((double)t * Math.PI / 2.0); } public static float InOutSine(float t) { return (float)(Math.Cos((double)t * Math.PI) - 1.0) / -2f; } public static float InExpo(float t) { return (float)Math.Pow(2.0, 10f * (t - 1f)); } public static float OutExpo(float t) { return 1f - InExpo(1f - t); } public static float InOutExpo(float t) { if ((double)t < 0.5) { return InExpo(t * 2f) / 2f; } return 1f - InExpo((1f - t) * 2f) / 2f; } public static float InCirc(float t) { return 0f - ((float)Math.Sqrt(1f - t * t) - 1f); } public static float OutCirc(float t) { return 1f - InCirc(1f - t); } public static float InOutCirc(float t) { if ((double)t < 0.5) { return InCirc(t * 2f) / 2f; } return 1f - InCirc((1f - t) * 2f) / 2f; } public static float InElastic(float t) { return 1f - OutElastic(1f - t); } public static float OutElastic(float t) { float num = 0.3f; return (float)Math.Pow(2.0, -10f * t) * (float)Math.Sin((double)(t - num / 4f) * (Math.PI * 2.0) / (double)num) + 1f; } public static float InOutElastic(float t) { if ((double)t < 0.5) { return InElastic(t * 2f) / 2f; } return 1f - InElastic((1f - t) * 2f) / 2f; } public static float InBack(float t) { float num = 1.70158f; return t * t * ((num + 1f) * t - num); } public static float OutBack(float t) { return 1f - InBack(1f - t); } public static float InOutBack(float t) { if ((double)t < 0.5) { return InBack(t * 2f) / 2f; } return 1f - InBack((1f - t) * 2f) / 2f; } public static float InBounce(float t) { return 1f - OutBounce(1f - t); } public static float OutBounce(float t) { float num = 2.75f; float num2 = 7.5625f; if (t < 1f / num) { return num2 * t * t; } if (t < 2f / num) { t -= 1.5f / num; return num2 * t * t + 0.75f; } if ((double)t < 2.5 / (double)num) { t -= 2.25f / num; return num2 * t * t + 0.9375f; } t -= 2.625f / num; return num2 * t * t + 63f / 64f; } public static float InOutBounce(float t) { if ((double)t < 0.5) { return InBounce(t * 2f) / 2f; } return 1f - InBounce((1f - t) * 2f) / 2f; } } public static class EasyDetour { public unsafe delegate void StaticVoidDelegate(Il2CppMethodInfo* methodInfo); public unsafe delegate void InstanceVoidDelegate(IntPtr instancePtr, Il2CppMethodInfo* methodInfo); public static bool TryCreate<T>(DetourDescriptor descriptor, T to, out T originalCall, out INativeDetour detourInstance) where T : Delegate { try { nint methodPointer = descriptor.GetMethodPointer(); detourInstance = INativeDetour.CreateAndApply<T>((IntPtr)methodPointer, to, ref originalCall); return detourInstance != null; } catch (Exception ex) { Logger.Error("Exception Thrown while creating Detour:"); Logger.Error(ex.ToString()); } originalCall = null; detourInstance = null; return false; } } public struct DetourDescriptor { public Type Type; public Type ReturnType; public Type[] ArgTypes; public string MethodName; public bool IsGeneric; public unsafe nint GetMethodPointer() { if (Type == null) { throw new MissingFieldException("Field Type is not set!"); } if (ReturnType == null) { throw new MissingFieldException("Field ReturnType is not set! If you mean 'void' do typeof(void)"); } if (string.IsNullOrEmpty(MethodName)) { throw new MissingFieldException("Field MethodName is not set or valid!"); } Il2CppType.From(Type, true); IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(Type); string fullName = GetFullName(ReturnType); string[] array; if (ArgTypes == null || ArgTypes.Length == 0) { array = Array.Empty<string>(); } else { int num = ArgTypes.Length; array = new string[num]; for (int i = 0; i < num; i++) { Type type = ArgTypes[i]; array[i] = GetFullName(type); } } void** ptr = (void**)IL2CPP.GetIl2CppMethod(nativeClassPointer, IsGeneric, MethodName, fullName, array).ToPointer(); if (ptr == null) { return (nint)ptr; } return (nint)(*ptr); } private static string GetFullName(Type type) { bool isPointer = type.IsPointer; if (isPointer) { type = type.GetElementType(); } if (type.IsPrimitive || type == typeof(string)) { if (isPointer) { return type.MakePointerType().FullName; } return type.FullName; } Type val = Il2CppType.From(type, true); if (isPointer) { return val.MakePointerType().FullName; } return val.FullName; } } public struct HalfColor { public Half R; public Half G; public Half B; public Half A; public HalfColor() { R = (Half)0f; G = (Half)0f; B = (Half)0f; A = (Half)0f; } public HalfColor(float r, float g, float b, float a) { R = (Half)r; G = (Half)g; B = (Half)b; A = (Half)a; } public static implicit operator Color(HalfColor halfCol) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B, (float)halfCol.A); } public static implicit operator HalfColor(Color col) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) HalfColor result = new HalfColor(); result.R = (Half)col.r; result.G = (Half)col.g; result.B = (Half)col.b; result.A = (Half)col.a; return result; } } public struct HalfRGBColor { public Half R; public Half G; public Half B; public static implicit operator Color(HalfRGBColor halfCol) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B); } public static implicit operator HalfRGBColor(Color col) { //IL_000a: 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_002e: Unknown result type (might be due to invalid IL or missing references) HalfRGBColor result = default(HalfRGBColor); result.R = (Half)col.r; result.G = (Half)col.g; result.B = (Half)col.b; return result; } } public class RNG { private const int Float01Precision = 2000000000; private const float Float01Inv = 5E-10f; private static uint _UniqueIDForRandomSeed = 0u; private Random _Rand; private int _Seed; public static GlobalRNG Global { get; private set; } = new GlobalRNG(); public float Float01 => (float)_Rand.Next(0, 2000000001) * 5E-10f; public float FloatMinusOneToPlusOne => (float)_Rand.Next(-2000000000, 2000000001) * 5E-10f; public int Int0ToPositive => _Rand.Next(0, int.MaxValue); public int Int0ToNegative => _Rand.Next(int.MinValue, 1); public int Int => _Rand.Next(int.MinValue, int.MaxValue); public RNG() { if (_UniqueIDForRandomSeed == uint.MaxValue) { _UniqueIDForRandomSeed = 0u; } else { _UniqueIDForRandomSeed++; } _Seed = $"{_UniqueIDForRandomSeed} {Environment.TickCount64}".GetHashCode(); _Rand = new Random(_Seed); } public RNG(int seed) { _Seed = seed; _Rand = new Random(seed); } public virtual void Reset(int? newSeed = null) { if (newSeed.HasValue) { _Seed = newSeed.Value; } _Rand = new Random(_Seed); } public bool Probability(float probability) { if (probability <= 0f) { return false; } if (probability >= 1f) { return true; } return Float01 < probability; } public bool OneIn(int cases) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (cases <= 0) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RNG"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("OneIn"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" received "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(cases); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (0 or negative); fallback to false"); } Logger.Warn(val); return false; } if (cases == 1) { return true; } return _Rand.Next(0, cases) == 0; } public T Choice<T>(params T[] items) { return Choice((IEnumerable<T>)items); } public T Choice<T>(IEnumerable<T> items) { if (IsChoiceHaveSimpleScenarioValue(items, out var value)) { return value; } int maxValue = items.Count(); int index = _Rand.Next(0, maxValue); return items.ElementAt(index); } public T[] Choice<T>(IEnumerable<T> items, int count) { if (IsChoiceHaveSimpleScenarioValue(items, out var value)) { return new T[1] { value }; } return items.OrderBy((T x) => _Rand.NextDouble()).Take(count).ToArray(); } public T WeightedChoice<T>(IEnumerable<(T item, float weight)> itemTuples) { if (IsChoiceHaveSimpleScenarioValue<(T, float)>(itemTuples, out var value)) { return value.Item1; } T[] array = itemTuples.Select(((T item, float weight) x) => x.item).ToArray(); float[] array2 = itemTuples.Select(((T item, float weight) x) => x.weight).ToArray(); float num = 0f; for (int i = 0; i < array2.Length; i++) { float num2 = array2[i]; if (num2 <= 0f) { array2[i] = -1f; } else { num = (array2[i] = num + num2); } } if (num <= 0f) { return Choice(array); } float num3 = Float01 * num; for (int j = 0; j < array2.Length; j++) { if (j == array2.Length - 1 || num3 <= array2[j]) { return array[j]; } } throw new InvalidOperationException("What? this should never happen"); } private static bool IsChoiceHaveSimpleScenarioValue<T>(IEnumerable<T> items, out T value) { int num = items.Count(); if (num <= 0) { throw new ArgumentException("Argument Item Count is 0!", "items"); } if (num == 1) { value = items.First(); return true; } value = default(T); return false; } } public sealed class GlobalRNG : RNG { public sealed override void Reset(int? newSeed = null) { Logger.Warn("Resetting Seed Value is not allowed on RNG.Global"); } } } namespace FloLib.Utils.Extensions { public static class ColorExtension { public static string ToHex(this Color input) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(input); } public static string ToHexRGBA(this Color input) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGBA(input); } public static void GetColorInfo(this Color input, out Color baseColor, out float colorMultiplier) { //IL_000c: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) float num = 0f; float num2 = 0f; float r = input.r; float g = input.g; float b = input.b; float num3 = Mathf.Abs(r); float num4 = Mathf.Abs(g); float num5 = Mathf.Abs(b); if (num3 > num2) { num2 = num3; num = r; } if (num4 > num2) { num2 = num4; num = g; } if (num5 > num2) { num2 = num5; num = b; } if (num2 > 0f) { baseColor = new Color(r / num, g / num, b / num, 1f); colorMultiplier = num; } else { baseColor = Color.black; colorMultiplier = 1f; } } } public static class ComponentExtension { public static bool TryGetComp<T>(this Component comp, out T component) { component = comp.GetComponent<T>(); return component != null; } public static bool TryGetVirtualScene(this Component comp, out GUIX_VirtualScene scene) { GUIX_VirtualSceneLink component = comp.GetComponent<GUIX_VirtualSceneLink>(); if ((Object)(object)component == (Object)null) { scene = null; return false; } scene = component.m_virtualScene; return (Object)(object)scene != (Object)null; } public static string GetGameObjectPath(this Component comp) { return comp.gameObject.GetPath(); } } public static class GameObjectExtension { public static bool TryGetComp<T>(this GameObject obj, out T component) { component = obj.GetComponent<T>(); return component != null; } public static T GetCompInParentOrChild<T>(this GameObject obj) { T val = obj.GetComponentInParent<T>(); if (val == null) { val = obj.GetComponentInChildren<T>(); if (val == null) { obj.GetComponent<T>(); } } return val; } public static string GetPath(this GameObject obj) { string text = "/" + ((Object)obj).name; while ((Object)(object)obj.transform.parent != (Object)null) { obj = ((Component)obj.transform.parent).gameObject; text = "/" + ((Object)obj).name + text; } return text; } } public static class Il2CppBoxingExtension { public static Object BoxToIl2CppObject(this bool value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Boolean val = default(Boolean); val.m_value = value; return ((Boolean)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this byte value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Byte val = default(Byte); val.m_value = value; return ((Byte)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this sbyte value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SByte val = default(SByte); val.m_value = value; return ((SByte)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this char value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Char val = default(Char); val.m_value = value; return ((Char)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this short value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int16 val = default(Int16); val.m_value = value; return ((Int16)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this ushort value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt16 val = default(UInt16); val.m_value = value; return ((UInt16)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this int value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int32 val = default(Int32); val.m_value = value; return ((Int32)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this uint value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt32 val = default(UInt32); val.m_value = value; return ((UInt32)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this long value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int64 val = default(Int64); val.m_value = value; return ((Int64)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this ulong value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt64 val = default(UInt64); val.m_value = value; return ((UInt64)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Single val = default(Single); val.m_value = value; return ((Single)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this double value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Double val = default(Double); val.m_value = value; return ((Double)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this nint value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) IntPtr val = default(IntPtr); val.m_value = value; return ((IntPtr)(ref val)).BoxIl2CppObject(); } } public static class Il2CppObjectExtension { public static bool CanCastToType<T>(this Il2CppObjectBase obj) where T : Il2CppObjectBase { return obj.TryCast<T>() != null; } public static bool TryCastToType<T>(this Il2CppObjectBase obj, out T result) where T : Il2CppObjectBase { result = obj.TryCast<T>(); return result != null; } } public static class LGLightExtension { public static void SetColor(this IEnumerable<LG_Light> lights, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) foreach (LG_Light light in lights) { light.ChangeColor(color); } } public static void SetEnabled(this IEnumerable<LG_Light> lights, bool enabled) { foreach (LG_Light light in lights) { light.SetEnabled(enabled); } } public static bool Is(this LG_Light light, LightCategory lightCategory) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 return (int)light.m_category == (int)lightCategory; } public static bool IsAny(this LG_Light light, params LightCategory[] categories) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 for (int i = 0; i < categories.Length; i++) { if ((int)light.m_category == (int)categories[i]) { return true; } } return false; } } public enum LightCategory { General = 0, Special = 1, Independent = 3, Sign = 5, Door = 4, DoorImportant = 6, Emergency = 2 } public static class TerminalExtension { public static void SetPowered(this LG_ComputerTerminal terminal, bool isPowered) { terminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)terminal).GetComponentInChildren<Interact_ComputerTerminal>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = isPowered; ((Interact_Base)componentInChildren).SetActive(isPowered); } GUIX_VirtualSceneLink component = ((Component)terminal).GetComponent<GUIX_VirtualSceneLink>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_virtualScene != (Object)null) { GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera; float num = (isPowered ? 0.3f : 0f); float num2 = (isPowered ? 1000f : 0f); virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, num, num2); } if ((Object)(object)terminal.m_text != (Object)null) { ((Behaviour)terminal.m_text).enabled = isPowered; } if (!isPowered) { PlayerAgent localInteractionSource = terminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { terminal.ExitFPSView(); } } } } public static class VectorExtension { public static string ToFormattedString(this Vector2 vector) { //IL_0017: 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) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000}"; } public static string ToFormattedString(this Vector3 vector) { //IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000}"; } public static string ToFormattedString(this Vector4 vector) { //IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000} w: {vector.w:0.0000}"; } } } namespace FloLib.Utils.Comps { [AutoInject] internal sealed class EmptyMB : MonoBehaviour { } } namespace FloLib.Networks { public static class GlobalNetAction<P> where P : struct { private static string _EventName; private static bool _IsSetup; public static SNet_ChannelType SendChannel { get; set; } public static SNet_Player LastSender { get; private set; } public static ulong LastSenderID { get; private set; } public static event Action<ulong, P> OnReceive; public static event Action<ulong, P> OnReceiveLocally; static GlobalNetAction() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendChannel = (SNet_ChannelType)2; _IsSetup = false; Setup(); } public static void Setup() { if (!_IsSetup) { _EventName = UName.Get(typeof(P), "NA"); NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received); _IsSetup = true; } } public static void Send(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SendToLocal(payload); TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetAction.Send"); } public static void SendTo(P payload, SNet_Player target) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } if (target.IsLocal) { SendToLocal(payload); return; } TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetAction.SendTo"); } public static void SendTo(P payload, SNet_SendGroup group) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } Enumerator<SNet_Player> enumerator = SNet_PlayerSendGroupManager.GetGroup(group).GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; SendTo(payload, current); } } private static void SendToLocal(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player val = (LastSender = SNet.LocalPlayer); if ((Object)(object)val != (Object)null) { LastSenderID = val.Lookup; } GlobalNetAction<P>.OnReceive?.Invoke(LastSenderID, payload); GlobalNetAction<P>.OnReceiveLocally?.Invoke(LastSenderID, payload); } private static void Received(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player lastSender = default(SNet_Player); if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false)) { LastSender = null; LastSenderID = 0uL; Logger.Error("NetAction sender was invalid!"); } LastSender = lastSender; LastSenderID = sender; GlobalNetAction<P>.OnReceive?.Invoke(sender, payload); } } public static class GlobalNetMasterAction<P> where P : struct { public static Func<ulong, P, bool> IsActionValid; private static string _AskEventName; private static string _EventName; private static bool _IsSetup; public static SNet_ChannelType SendChannel { get; set; } public static SNet_Player LastSender { get; private set; } public static ulong LastSenderID { get; private set; } public static event Action<ulong, P> OnReceive; public static event Action<ulong, P> OnMasterReceive; static GlobalNetMasterAction() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendChannel = (SNet_ChannelType)2; IsActionValid = (ulong sender, P p) => true; _IsSetup = false; Setup(); } public static void Setup() { if (!_IsSetup) { _AskEventName = UName.Get(typeof(P), "NMA0"); _EventName = UName.Get(typeof(P), "NMA1"); NetworkAPI.RegisterEvent<P>(_AskEventName, (Action<ulong, P>)ReceivedAsk); NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received); _IsSetup = true; } } public static void Ask(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); } else { if (!SNet.HasMaster) { return; } if (SNet.IsMaster) { Func<ulong, P, bool> isActionValid = IsActionValid; if (isActionValid == null || isActionValid(SNet.LocalPlayer.Lookup, payload)) { TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetMasterAction.Master"); GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); } } else { TaskQueue.AddTask(delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_AskEventName, payload, SNet.Master, SendChannel); }, "GlobalNetMasterAction.Ask.Client"); } } } private static void ReceivedAsk(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } if (!SNet.IsMaster) { Logger.Error("Non Master Received Ask Action!"); return; } Func<ulong, P, bool> isActionValid = IsActionValid; if (isActionValid == null || isActionValid(sender, payload)) { TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetMasterAction.ReceivedAsk.Master"); GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(sender, payload); } } private static void Received(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player lastSender = default(SNet_Player); if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false)) { LastSender = null; LastSenderID = 0uL; Logger.Error("NetMasterAction sender was invalid!"); return; } LastSender = lastSender; LastSenderID = sender; if (!LastSender.IsMaster) { Logger.Error("Sender was not a master"); } else { GlobalNetMasterAction<P>.OnReceive?.Invoke(sender, payload); } } } internal static class UName { private static readonly SHA1 SHA = SHA1.Create(); public static string Get(Type type, string prefix) { return prefix + GetHash(type.FullName); } public static string GetHash(string text) { return Convert.ToBase64String(SHA.ComputeHash(Encoding.Unicode.GetBytes(text + "this is salt text, Awesome!"))); } } } namespace FloLib.Networks.Replications { public interface IStateReplicatorHolder<S> where S : struct { StateReplicator<S> Replicator { get; } void OnStateChange(S oldState, S state, bool isRecall); } public sealed class ReplicatorHandshake { public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer); public struct Packet { public uint replicatorID; public PacketAction action; } public enum PacketAction : byte { Created, Destroyed, SyncRequest } public sealed class Data { public bool SetupOnHost; public bool SetupOnClient; } private readonly Dictionary<uint, Data> _Lookup = new Dictionary<uint, Data>(); public string EventName { get; private set; } public bool IsReadyToSync { get; private set; } public event ClientRequestedSyncDel OnClientSyncRequested; public static ReplicatorHandshake Create(string guid) { if (string.IsNullOrWhiteSpace(guid)) { return null; } string text = "RHs" + guid; if (!NetworkAPI.IsEventRegistered(text)) { return new ReplicatorHandshake(text); } return null; } private ReplicatorHandshake(string eventName) { EventName = eventName; NetworkAPI.RegisterEvent<Packet>(eventName, (Action<ulong, Packet>)OnSyncAction); Inject_OnRecallDone.OnRecallDone += delegate { foreach (uint replicatorID in _Lookup.Keys) { TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = replicatorID, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); }, $"SyncReplicatorID_{replicatorID}"); } }; } public void Reset() { _Lookup.Clear(); } private void OnSyncAction(ulong sender, Packet packet) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown if (!SNet.IsMaster && sender == SNet.Master.Lookup) { if (packet.action == PacketAction.Created) { SetHostState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetHostState(packet.replicatorID, isSetup: false); } } else { if (!SNet.IsMaster) { return; } if (packet.action == PacketAction.Created) { SetClientState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetClientState(packet.replicatorID, isSetup: false); } else { if (packet.action != PacketAction.SyncRequest) { return; } SNet_Player requestedPlayer = default(SNet_Player); if (!SNet.TryGetPlayer(sender, ref requestedPlayer)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cannot find player from sender: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(sender); } Logger.Error(val); } else { this.OnClientSyncRequested?.Invoke(requestedPlayer); } } } } public void UpdateCreated(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, (SNet_ChannelType)2); }, "UpdateCreated.Master"); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, SNet.Master, (SNet_ChannelType)2); }, "UpdateCreated.Client"); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } public void UpdateDestroyed(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, (SNet_ChannelType)2); }, "UpdateDestroyed.Master"); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, SNet.Master, (SNet_ChannelType)2); }, "UpdateDestroyed.Client"); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } private void SetHostState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out var value)) { value.SetupOnHost = isSetup; } else { _Lookup[id] = new Data { SetupOnHost = isSetup }; } UpdateSyncState(id); } private void SetClientState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out var value)) { value.SetupOnClient = isSetup; } else { _Lookup[id] = new Data { SetupOnClient = isSetup }; } UpdateSyncState(id); } private void UpdateSyncState(uint id) { bool isReadyToSync = IsReadyToSync; if (_Lookup.TryGetValue(id, out var value)) { IsReadyToSync = value.SetupOnHost && value.SetupOnClient; } else { IsReadyToSync = false; } if (IsReadyToSync && isReadyToSync != IsReadyToSync && SNet.HasMaster && !SNet.IsMaster) { TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); }, "Client.UpdateSyncState.SyncRequest"); } } } public delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct; public static class StatePayloads { public enum Size { State4Byte = 4, State8Byte = 8, State16Byte = 16, State32Byte = 32, State48Byte = 48, State64Byte = 64, State80Byte = 80, State96Byte = 96, State128Byte = 128, State196Byte = 196, State256Byte = 256 } public static Size GetSizeType(int size) { Size size2 = Size.State8Byte; foreach (object value in Enum.GetValues(typeof(Size))) { if (size <= (int)value && (int)size2 < (int)value) { size2 = (Size)value; break; } } return size2; } public static IReplicatorEvent<S> CreateEvent<S>(Size size, string eventName, OnReceiveDel<S> onReceiveCallback) where S : struct { return size switch { Size.State4Byte => ReplicatorPayloadWrapper<S, StatePayload4Byte>.Create(eventName, onReceiveCallback), Size.State8Byte => ReplicatorPayloadWrapper<S, StatePayload8Byte>.Create(eventName, onReceiveCallback), Size.State16Byte => ReplicatorPayloadWrapper<S, StatePayload16Byte>.Create(eventName, onReceiveCallback), Size.State32Byte => ReplicatorPayloadWrapper<S, StatePayload32Byte>.Create(eventName, onReceiveCallback), Size.State48Byte => ReplicatorPayloadWrapper<S, StatePayload48Byte>.Create(eventName, onReceiveCallback), Size.State64Byte => ReplicatorPayloadWrapper<S, StatePayload64Byte>.Create(eventName, onReceiveCallback), Size.State80Byte => ReplicatorPayloadWrapper<S, StatePayload80Byte>.Create(eventName, onReceiveCallback), Size.State96Byte => ReplicatorPayloadWrapper<S, StatePayload96Byte>.Create(eventName, onReceiveCallback), Size.State128Byte => ReplicatorPayloadWrapper<S, StatePayload128Byte>.Create(eventName, onReceiveCallback), Size.State196Byte => ReplicatorPayloadWrapper<S, StatePayload196Byte>.Create(eventName, onReceiveCallback), Size.State256Byte => ReplicatorPayloadWrapper<S, StatePayload256Byte>.Create(eventName, onReceiveCallback), _ => null, }; } public static S Get<S>(byte[] bytes, int bytesLength) where S : struct { int num = Marshal.SizeOf(typeof(S)); if (num > bytesLength) { throw new ArgumentException($"StateData Exceed size of {bytesLength} : Unable to Deserialize", "S"); } IntPtr intPtr = Marshal.AllocHGlobal(num); Marshal.Copy(bytes, 0, intPtr, num); S result = (S)Marshal.PtrToStructure(intPtr, typeof(S)); Marshal.FreeHGlobal(intPtr); return result; } public static void Set<S>(S stateData, int size, ref byte[] payloadBytes) where S : struct { if (Marshal.SizeOf(stateData) > size) { throw new ArgumentException($"StateData Exceed size of {size} : Unable to Serialize", "S"); } byte[] array = new byte[size]; IntPtr intPtr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, size); Marshal.FreeHGlobal(intPtr); payloadBytes = array; } } public interface IReplicatorEvent<S> where S : struct { string Name { get; } bool IsRegistered { get; } void Invoke(uint replicatorID, S data); void Invoke(uint replicatorID, S data, SNet_ChannelType channelType); void Invoke(uint replicatorID, S data, SNet_Player target); void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType); } public class ReplicatorPayloadWrapper<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload { public string Name { get; private set; } public bool IsRegistered { get; private set; } public static IReplicatorEvent<S> Create(string eventName, OnReceiveDel<S> onReceiveCallback) { ReplicatorPayloadWrapper<S, P> replicatorPayloadWrapper = new ReplicatorPayloadWrapper<S, P>(); replicatorPayloadWrapper.Register(eventName, onReceiveCallback); if (!replicatorPayloadWrapper.IsRegistered) { return null; } return replicatorPayloadWrapper; } public void Register(string eventName, OnReceiveDel<S> onReceiveCallback) { if (!IsRegistered && !NetworkAPI.IsEventRegistered(eventName)) { NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload) { onReceiveCallback?.Invoke(sender, payload.ID, payload.Get<S>()); }); IsRegistered = true; Name = eventName; } } public void Invoke(uint replicatorID, S data) { P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<P>(Name, payload, (SNet_ChannelType)2); }, "ReplicatorPayloadWrapper.Invoke(uint, S)"); } public void Invoke(uint replicatorID, S data, SNet_ChannelType channelType) { //IL_000d: 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) P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(Name, payload, channelType); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_ChannelType)"); } public void Invoke(uint replicatorID, S data, SNet_Player target) { P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<P>(Name, payload, target, (SNet_ChannelType)2); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player)"); } public void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(Name, payload, target, channelType); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player, SNet_ChannelType)"); } } public interface IStatePayload { uint ID { get; set; } S Get<S>() where S : struct; void Set<S>(S stateData) where S : struct; } public struct StatePayload4Byte : IStatePayload { public const int Size = 4; private uint id; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] PayloadBytes; public uint ID { get { return id; } set { id = value; } } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 4); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 4, ref PayloadBytes); } } public struct StatePayload8Byte : IStatePayload { public const int Size = 8; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 8); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 8, ref PayloadBytes); } } public struct StatePayload16Byte : IStatePayload { public const int Size = 16; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 16); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 16, ref PayloadBytes); } } public struct StatePayload32Byte : IStatePayload { public const int Size = 32; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 32); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 32, ref PayloadBytes); } } public struct StatePayload48Byte : IStatePayload { public const int Size = 48; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 48); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 48, ref PayloadBytes); } } public struct StatePayload64Byte : IStatePayload { public const int Size = 64; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 64); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 64, ref PayloadBytes); } } public struct StatePayload80Byte : IStatePayload { public const int Size = 80; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 80); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 80, ref PayloadBytes); } } public struct StatePayload96Byte : IStatePayload { public const int Size = 96; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 96); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 96, ref PayloadBytes); } } public struct StatePayload128Byte : IStatePayload { public const int Size = 128; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 128); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 128, ref PayloadBytes); } } public struct StatePayload196Byte : IStatePayload { public const int Size = 196; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 196); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 196, ref PayloadBytes); } } public struct StatePayload256Byte : IStatePayload { public const int Size = 256; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 256); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 256, ref PayloadBytes); } } public enum LifeTimeType { Forever, Level } public sealed class StateReplicator<S> where S : struct { private readonly Dictionary<eBufferType, S> _RecallStateSnapshots = new Dictionary<eBufferType, S>(); public static readonly string Name; public static readonly string HashName; public static readonly string ClientRequestEventName; public static readonly string HostSetStateEventName; public static readonly string HostSetRecallStateEventName; public static readonly int StateSize; public static readonly StatePayloads.Size StateSizeType; private static readonly IReplicatorEvent<S> _C_RequestEvent; private static readonly IReplicatorEvent<S> _H_SetStateEvent; private static readonly IReplicatorEvent<S> _H_SetRecallStateEvent; private static readonly ReplicatorHandshake _Handshake; private static readonly Dictionary<uint, StateReplicator<S>> _Replicators; public bool IsValid => ID != 0; public bool IsInvalid => ID == 0; public uint ID { get; private set; } public LifeTimeType LifeTime { get; private set; } public IStateReplicatorHolder<S> Holder { get; private set; } public S State { get; private set; } public bool ClientSendStateAllowed { get; set; } = true; public bool CanSendToClient { get { if (SNet.IsInLobby) { return SNet.IsMaster; } return false; } } public bool CanSendToHost { get { if (SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster) { return ClientSendStateAllowed; } return false; } } public bool IsHandshakeSetup { get; private set; } public event Action<S, S, bool> OnStateChanged; public void SetupHandshake() { if (!IsInvalid && !IsHandshakeSetup) { _Handshake.UpdateCreated(ID); IsHandshakeSetup = true; } } public void SetState(S state) { if (!IsInvalid) { DoSync(state); } } public void SetStateUnsynced(S state) { if (!IsInvalid) { State = state; } } public void Unload() { if (IsValid) { _Replicators.Remove(ID); _RecallStateSnapshots.Clear(); _Handshake.UpdateDestroyed(ID); IsHandshakeSetup = false; ID = 0u; } } private void DoSync(S newState) { if (!IsInvalid) { if (CanSendToClient) { _H_SetStateEvent.Invoke(ID, newState); Internal_ChangeState(newState, isRecall: false); } else if (CanSendToHost) { _C_RequestEvent.Invoke(ID, newState, SNet.Master); } } } private void Internal_ChangeState(S state, bool isRecall) { if (!IsInvalid) { S state2 = State; State = state; this.OnStateChanged?.Invoke(state2, state, isRecall); Holder?.OnStateChange(state2, state, isRecall); } } private void SendDropInState(SNet_Player target) { if (!IsInvalid) { if ((Object)(object)target == (Object)null) { Logger.Error("SendDropInState::Target was null??"); } else { _H_SetRecallStateEvent.Invoke(ID, State, target); } } } public void ClearAllRecallSnapshot() { if (!IsInvalid) { _RecallStateSnapshots.Clear(); } } private void SaveSnapshot(eBufferType type) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!IsInvalid) { _RecallStateSnapshots[type] = State; } } private void RestoreSnapshot(eBufferType type) { //IL_0017: 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_0046: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (IsInvalid || !CanSendToClient) { return; } if (_RecallStateSnapshots.TryGetValue(type, out var value)) { _H_SetRecallStateEvent.Invoke(ID, value); Internal_ChangeState(value, isRecall: true); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RestoreSnapshot"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("::There was no snapshot for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eBufferType>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?"); } Logger.Error(val); } static StateReplicator() { _Replicators = new Dictionary<uint, StateReplicator<S>>(); Name = typeof(S).Name; StateSize = Marshal.SizeOf(typeof(S)); StateSizeType = StatePayloads.GetSizeType(StateSize); using (MD5.Create()) { HashName = UName.GetHash(typeof(S).FullName); ClientRequestEventName = "SRs" + Name + "-" + HashName; HostSetStateEventName = "SRr" + Name + "-" + HashName; HostSetRecallStateEventName = "SRre" + Name + "-" + HashName; _C_RequestEvent = StatePayloads.CreateEvent<S>(StateSizeType, ClientRequestEventName, ClientRequestEventCallback); _H_SetStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetStateEventName, HostSetStateEventCallback); _H_SetRecallStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetRecallStateEventName, HostSetRecallStateEventCallback); _Handshake = ReplicatorHandshake.Create(Name + "-" + HashName); _Handshake.OnClientSyncRequested += ClientSyncRequested; Inject_SNet_Capture.OnBufferCapture += BufferStored; Inject_SNet_Capture.OnBufferRecalled += BufferRecalled; LevelAPI.OnLevelCleanup += LevelCleanedUp; } } public static void Setup() { } private static void ClientSyncRequested(SNet_Player requestedPlayer) { foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SendDropInState(requestedPlayer); } } } private static void BufferStored(eBufferType type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SaveSnapshot(type); } } } private static void BufferRecalled(eBufferType type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.RestoreSnapshot(type); } } } private static void LevelCleanedUp() { UnloadSessionReplicator(); } private StateReplicator() { } public static StateReplicator<S> Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S> owner = null) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if (replicatorID == 0) { Logger.Error("Replicator ID 0 is reserved for empty!"); return null; } if (_Replicators.ContainsKey(replicatorID)) { Logger.Error("Replicator ID has already assigned!"); return null; } StateReplicator<S> stateReplicator = new StateReplicator<S> { ID = replicatorID, LifeTime = lifeTime, Holder = owner, State = startState }; switch (lifeTime) { case LifeTimeType.Forever: stateReplicator.IsHandshakeSetup = true; break; case LifeTimeType.Level: stateReplicator.SetupHandshake(); break; default: { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime is invalid!: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime); } Logger.Error(val); return null; } } _Replicators[replicatorID] = stateReplicator; return stateReplicator; } public static void UnloadSessionReplicator() { List<uint> list = new List<uint>(); foreach (StateReplicator<S> value in _Replicators.Values) { if (value.LifeTime == LifeTimeType.Level) { list.Add(value.ID); value.Unload(); } } foreach (uint item in list) { _Replicators.Remove(item); } _Handshake.Reset(); } private static void ClientRequestEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.IsMaster && _Replicators.TryGetValue(replicatorID, out var value)) { value.SetState(newState); } } private static void HostSetStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value)) { value.Internal_ChangeState(newState, isRecall: false); } } private static void HostSetRecallStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value)) { value.Internal_ChangeState(newState, isRecall: true); } } } } namespace FloLib.Networks.PayloadStructs { public struct PL_Agent { public ushort AgentID; public PL_Agent() { AgentID = 0; } public PL_Agent(Agent agent) { AgentID = agent.GlobalID; } public void Set(Agent agent) { AgentID = agent.GlobalID; } public bool TryGet(out Agent agent) { IReplicator val = default(IReplicator); if (!SNet_Replication.TryGetReplicator(AgentID, ref val)) { agent = null; return false; } if (val == null) { agent = null; return false; } if (val.ReplicatorSupplier == null) { agent = null; return false; } MonoBehaviour val2 = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<MonoBehaviour>(); if ((Object)(object)val2 == (Object)null) { agent = null; return false; } agent = ((Component)val2).GetComponent<Agent>(); return (Object)(object)agent != (Object)null; } } } namespace FloLib.Networks.Inject { [HarmonyPatch] internal class Inject_OnRecallDone { public static event Action OnRecallDone; [HarmonyPostfix] [HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")] private static void Post_OnRecallDone(SNet_SyncManager __instance) { Inject_OnRecallDone.OnRecallDone?.Invoke(); } } [HarmonyPatch(typeof(SNet_Capture))] internal static class Inject_SNet_Capture { public static event Action<eBufferType> OnBufferCapture; public static event Action<eBufferType> OnBufferRecalled; [HarmonyPatch("TriggerCapture")] [HarmonyPrefix] private static void Pre_TriggerCapture(SNet_Capture __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) eBufferType primedBufferType = __instance.PrimedBufferType; Inject_SNet_Capture.OnBufferCapture?.Invoke(primedBufferType); } [HarmonyPatch("RecallBuffer")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!__instance.IsRecalling) { Inject_SNet_Capture.OnBufferRecalled?.Invoke(bufferType); } } } } namespace FloLib.Infos { public sealed class ComponentList<T> : IEnumerable<T>, IEnumerable where T : Component { private readonly List<T> _InternalList = new List<T>(); private T[] _ArrayCache = Array.Empty<T>(); public T[] Items => _ArrayCache; internal void Add(T itemToAdd) { int id = ((Object)(object)itemToAdd).GetInstanceID(); if (!_InternalList.Any((T t) => ((Object)(object)t).GetInstanceID() == id)) { _InternalList.Add(itemToAdd); _ArrayCache = _InternalList.ToArray(); } } internal void AddRange(IEnumerable<T> itemsToAdd) { foreach (T item in itemsToAdd) { Add(item); } } internal void Remove(T itemToRemove) { int id = ((Object)(object)itemToRemove).GetInstanceID(); int num = _InternalList.FindIndex((T i) => ((Object)(object)i).GetInstanceID() == id); if (num > -1) { _InternalList.RemoveAt(num); _ArrayCache = _InternalList.ToArray(); } } internal void Clear() { _InternalList.Clear(); _ArrayCache = Array.Empty<T>(); } public IEnumerator<T> GetEnumerator() { return _InternalList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _InternalList.GetEnumerator(); } } public static class LG_LightInfo { public struct Data { public float PrefabIntensity; public LightMode SpawnedMode; public float SpawnedIntensity; public Color SpawnedColor; } public static bool TryGetLightData(LG_Light light, out Data data) { if ((Object)(object)light == (Object)null) { data = default(Data); return false; } if (!((Component)(object)light).TryGetComp<LightData>(out var component)) { data = default(Data); return false; } data = component.CreateData(); return true; } public static void RevertToSpawnedState(LG_Light light) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)light == (Object)null) && ((Component)(object)light).TryGetComp<LightData>(out var component)) { light.ChangeColor(component.SpawnedColor); light.ChangeIntensity(component.SpawnedIntensity); } } } public enum LightMode { Off, On, Broken_Flickering } public static class LG_Objects { public static ComponentList<LG_SecurityDoor> SecurityDoors { get; private set; } = new ComponentList<LG_SecurityDoor>(); public static ComponentList<LG_WeakDoor> WeakDoors { get; private set; } = new ComponentList<LG_WeakDoor>(); public static ComponentList<LG_Light> Lights { get; private set; } = new ComponentList<LG_Light>(); public static ComponentList<LG_ComputerTerminal> Terminals { get; private set; } = new ComponentList<LG_ComputerTerminal>(); public static ComponentList<LG_LabDisplay> LabDisplays { get; private set; } = new ComponentList<LG_LabDisplay>(); public static ComponentList<LG_DoorButton> DoorButtons { get; private set; } = new ComponentList<LG_DoorButton>(); public static ComponentList<LG_WeakLock> WeakLocks { get; private set; } = new ComponentList<LG_WeakLock>(); public static ComponentList<LG_HSUActivator_Core> HSUActivators { get; private set; } = new ComponentList<LG_HSUActivator_Core>(); public static ComponentList<CarryItemPickup_Core> CarryItems { get; private set; } = new ComponentList<CarryItemPickup_Core>(); public static ComponentList<GenericSmallPickupItem_Core> PickupItems { get; private set; } = new ComponentList<GenericSmallPickupItem_Core>(); public static ComponentList<LG_Ladder> Ladders { get; private set; } = new ComponentList<LG_Ladder>(); public static ComponentList<LG_WardenObjective_Reactor> Reactors { get; private set; } = new ComponentList<LG_WardenObjective_Reactor>(); public static ComponentList<LG_PowerGeneratorCluster> GeneratorClusters { get; private set; } = new ComponentList<LG_PowerGeneratorCluster>(); public static ComponentList<LG_PowerGenerator_Core> Generators { get; private set; } = new ComponentList<LG_PowerGenerator_Core>(); [AutoInvoke(InvokeWhen.PluginLoaded)] internal static void Init() { LevelAPI.OnLevelCleanup += OnLevelCleanup; } private static void OnLevelCleanup() { SecurityDoors.Clear(); WeakDoors.Clear(); Lights.Clear(); Terminals.Clear(); LabDisplays.Clear(); DoorButtons.Clear(); WeakLocks.Clear(); HSUActivators.Clear(); CarryItems.Clear(); PickupItems.Clear(); Ladders.Clear(); Reactors.Clear(); GeneratorClusters.Clear(); Generators.Clear(); } public static O FindObjectInLevel<O>(bool includeInactive = false) where O : Object { return ((Component)Builder.CurrentFloor).GetComponentInChildren<O>(includeInactive); } public static IEnumerable<O> FindObjectsInLevel<O>(bool includeInactive = false) where O : Object { return (IEnumerable<O>)((Component)Builder.CurrentFloor).GetComponentsInChildren<O>(includeInactive); } public static LG_SecurityDoor FindSecurityDoor(LG_LayerType layer, eLocalZoneIndex localindex) { //IL_0001: 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) return FindSecurityDoor((eDimensionIndex)0, layer, localindex); } public static LG_SecurityDoor FindSecurityDoor(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localindex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localindex, ref val); if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)val.m_sourceGate == (Object)null) { return null; } if (val.m_sourceGate.SpawnedDoor == null) { return null; } return ((Il2CppObjectBase)val.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>(); } } public static class LocalPlayer { private static int? _InstanceID; public static bool HasAgent { get; private set; } public static PlayerAgent Agent { get; private set; } public static LocalPlayerAgent LocalAgent { get; private set; } public static bool TryGetAgent(out PlayerAgent agent) { agent = Agent; return HasAgent; } public static bool TryGetLocalAgent(out LocalPlayerAgent agent) { agent = LocalAgent; return HasAgent; } public static Vector3 GetPosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).Position; } return Vector3.zero; } public static Vector3 GetPosition(Vector3 fallback) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).Position; } return fallback; } public static Vector3 GetEyePosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).EyePosition; } return Vector3.zero; } public static Vector3 GetEyePosition(Vector3 fallback) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).EyePosition; } return fallback; } [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { Coroutines.Start(UpdatePlayerInfo()); } private static IEnumerator UpdatePlayerInfo() { while (true) { if (PlayerManager.HasLocalPlayerAgent()) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int instanceID = ((Object)localPlayerAgent).GetInstanceID(); if (!_InstanceID.HasValue || _InstanceID.Value != instanceID) { Agent = localPlayerAgent; LocalAgent = ((Il2CppObjectBase)localPlayerAgent).Cast<LocalPlayerAgent>(); _InstanceID = ((Object)localPlayerAgent).GetInstanceID(); HasAgent = true; } } else { Agent = null; LocalAgent = null; _InstanceID = null; HasAgent = false; } yield return null; } } } } namespace FloLib.Infos.Inject { [HarmonyPatch(typeof(Builder), "BuildDone")] internal static class Inject_Builder { [HarmonyPriority(800)] private static void Postfix() { LG_Objects.Terminals.AddRange(Find<LG_ComputerTerminal>()); LG_Objects.LabDisplays.AddRange(Find<LG_LabDisplay>()); LG_Objects.DoorButtons.AddRange(Find<LG_DoorButton>()); LG_Objects.WeakLocks.AddRange(Find<LG_WeakLock>()); LG_Objects.HSUActivators.AddRange(Find<LG_HSUActivator_Core>()); LG_Objects.CarryItems.AddRange(Find<CarryItemPickup_Core>()); LG_Objects.PickupItems.AddRange(Find<GenericSmallPickupItem_Core>()); LG_Objects.Ladders.AddRange(Find<LG_Ladder>()); LG_Objects.Reactors.AddRange(Find<LG_WardenObjective_Reactor>()); LG_Objects.GeneratorClusters.AddRange(Find<LG_PowerGeneratorCluster>()); LG_Objects.Generators.AddRange(Find<LG_PowerGenerator_Core>()); } private static IEnumerable<T> Find<T>() where T : Object { return LG_Objects.FindObjectsInLevel<T>(); } } [HarmonyPatch(typeof(LG_BuildZoneLightsJob), "Build")] internal static class Inject_LG_LightBuild { [HarmonyPriority(0)] private static void Prefix(LG_BuildZoneLightsJob __instance, out List<LG_Light> __state) { __state = new List<LG_Light>(); Enumerator<AIG_CourseNode> enumerator = __instance.m_zone.m_courseNodes.GetEnumerator(); while (enumerator.MoveNext()) { foreach (LG_Light componentsInChild in ((Component)enumerator.Current.m_area).GetComponentsInChildren<LG_Light>()) { LightData lightData = ((Component)componentsInChild).gameObject.AddComponent<LightData>(); LG_PointLight result2; if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLight>(out LG_SpotLight result)) { lightData.PrefabIntensity.Set(result.m_spotLight.intensity); } else if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_PointLight>(out result2)) { lightData.PrefabIntensity.Set(result2.m_pointLight.intensity); } else { if (!((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLightAmbient>(out LG_SpotLightAmbient result3)) { continue; } lightData.PrefabIntensity.Set(result3.m_spotLight.intensity); } __state.Add(componentsInChild); } } LG_Objects.Lights.AddRange(__state); } [HarmonyPriority(0)] private static void Postfix(List<LG_Light> __state) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown bool flag = default(bool); foreach (LG_Light item in __state) { LightData component = ((Component)item).GetComponent<LightData>(); if ((Object)(object)component == (Object)null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found Light without "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("LightData"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Component! "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Component)(object)item).GetGameObjectPath()); } Logger.Error(val); } else { component.SpawnedIntensity = item.m_intensity; component.SpawnedColor = item.m_color; component.SpawnedMode = GetLightMode(item); } } __state.Clear(); } private static LightMode GetLightMode(LG_Light light) { if (light.GetC_Light().LightUpdator != null) { return LightMode.Broken_Flickering; } if (((Component)light).gameObject.active) { return LightMode.On; } return LightMode.Off; } } [HarmonyPatch(typeof(LG_SecurityDoor), "Setup")] internal static class Inject_LG_SecDoor { private static void Postfix(LG_SecurityDoor __instance) { LG_Objects.SecurityDoors.Add(__instance); } } [HarmonyPatch(typeof(LG_WeakDoor), "Setup")] internal static class Inject_LG_WeakDoor { private static void Postfix(LG_WeakDoor __instance) { LG_Objects.WeakDoors.Add(__instance); } } } namespace FloLib.Infos.Comps { [AutoInject] internal sealed class LightData : MonoBehaviour { public Il2CppValueField<float> PrefabIntensity; public LightMode SpawnedMode; public float SpawnedIntensity; public Color SpawnedColor; public LG_LightInfo.Data CreateData() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) LG_LightInfo.Data result = default(LG_LightInfo.Data); result.PrefabIntensity = Il2CppValueField<float>.op_Implicit(PrefabIntensity); result.SpawnedMode = SpawnedMode; result.SpawnedIntensity = SpawnedIntensity; result.SpawnedColor = SpawnedColor; return result; } } } namespace FloLib.Game.ScreenShakes { public sealed class ScreenShake { [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { GlobalNetAction<ScreenShakeDescriptor>.OnReceive += OnReceive; } public static void Trigger(ScreenShakeDescriptor data) { GlobalNetAction<ScreenShakeDescriptor>.Send(data); } private static void OnReceive(ulong sender, ScreenShakeDescriptor data) { if (LocalPlayer.TryGetAgent(out var agent)) { FPSCamera fPSCamera = agent.FPSCamera; MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)fPSCamera, DoShake(fPSCamera, data)); } } private static IEnumerator DoShake(FPSCamera camera, ScreenShakeDescriptor data) { float time = 0f; while (time < data.Duration) { float num = 1f; if (data.Mode == ScreenShakeMode.PositionFalloff) { float num2 = Vector3.Distance(data.Position, camera.Position); num = Mathf.InverseLerp(data.FalloffEnd, data.FalloffStart, num2); } float t = data.Modifier switch { ScreenShakeModifier.PingPong => Mathf.PingPong(Mathf.InverseLerp(data.Duration, 0f, time) * 2f, 1f), ScreenShakeModifier.Increase => Mathf.InverseLerp(0f, data.Duration, time), ScreenShakeModifier.Decrease => Mathf.InverseLerp(data.Duration, 0f, time), _ => 1f, }; t = data.IntensityEasing.Evaluate(t); float constantCameraShakeAmount = num * t * data.Intensity; camera.SetConstantCameraShakeAmount(constantCameraShakeAmount); time += Time.deltaTime; yield return null; } camera.SetConstantCameraShakeAmount(0f); } } public struct ScreenShakeDescriptor { public ScreenShakeMode Mode; public ScreenShakeModifier Modifier; public Vector3 Position; public float Intensity; public float Duration; public float FalloffStart; public float FalloffEnd; public EaseFunc.Type IntensityEasing; } public enum ScreenShakeMode : byte { Global, PositionFalloff } public enum ScreenShakeModifier : byte { PingPong, Increase, Decrease, Constant } } namespace FloLib.Game.Projectiles { public class Projectile : MonoBehaviour { } } namespace FloLib.Game.Explosions { public sealed class Explosion { public static readonly Color DefaultFlashColor = new Color(1f, 0.2f, 0f, 1f); [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { ExplosionEffectPooling.Initialize(); GlobalNetAction<ExplosionDescriptor>.OnReceive += OnReceive; } private static void OnReceive(ulong sender, ExplosionDescriptor data) { Internal_TriggerExplosion(data); } public static void Trigger(ExplosionDescriptor data) { GlobalNetAction<ExplosionDescriptor>.Send(data); } internal static void Internal_TriggerExplosion(ExplosionDescriptor data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) CellSound.Post(EVENTS.STICKYMINEEXPLODE, data.Position); LightFlash(data.Position, data.MaxDamageRange, data.LightColor); if (!SNet.IsMaster) { return; } Il2CppReferenceArray<Collider> val = Physics.OverlapSphere(data.Position, data.MaxDamageRange, LayerManager.MASK_EXPLOSION_TARGETS); if (((Il2CppArrayBase<Collider>)(object)val).Count < 1) { return; } DamageUtil.IncrementSearchID(); uint searchID = DamageUtil.SearchID; foreach (Collider item in (Il2CppArrayBase<Collider>)(object)val) { ProcessExplosion(data, item, searchID); } } private static void ProcessExplosion(ExplosionDescriptor data, Collider target, uint searchID) { //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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || (Object)(object)((Component)target).gameObject == (Object)null || !((Component)target).gameObject.TryGetComp<IDamageable>(out var component)) { return; } component = component.GetBaseDamagable(); if (component == null || component.TempSearchID == searchID) { return; } Vector3 damagablePosition = GetDamagablePosition(component); component.TempSearchID = searchID; float distance = Vector3.Distance(data.Position, damagablePosition); if (!IsExplosionBlocked(data.Position, damagablePosition, target)) { float num = CalcBaseRangeDamage(data.MaxDamage, distance, data.MaxDamageRange, data.MinDamageRange); if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_EnemyDamageBase>() != (Object)null) { num *= (float)data.DamageMultiplierToEnemy; } else if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_PlayerDamageBase>() != (Object)null) { num *= (float)data.DamageMultiplierToPlayer; } Agent baseAgent = component.GetBaseAgent(); if ((Object)(object)baseAgent != (Object)null && baseAgent.GlobalID == data.Inflictor.AgentID) { num *= (float)data.DamageMultiplierToInflictor; } if (Mathf.Abs(num) > float.Epsilon) { component.ExplosionDamage(num, data.Position, Vector3.up * 1000f, 0u); } } } private static Vector3 GetDamagablePosition(IDamageable damagable) { //IL_0018: 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) Agent baseAgent = damagable.GetBaseAgent(); if ((Object)(object)baseAgent != (Object)null) { return baseAgent.EyePosition; } return damagable.DamageTargetPos; } private static bool IsExplosionBlocked(Vector3 pos1, Vector3 pos2, Collider targetCollider) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (Physics.Linecast(pos1, pos2, ref val, LayerManager.MASK_EXPLOSION_BLOCKERS)) { if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) { return
plugins/net6/Flowaria.MeltdownReactor.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using System.Text.Json.Serialization; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.Managers; using MeltdownReactor.Json; using MeltdownReactor.Json.PartialData; using MeltdownReactor.ReactorData; using Microsoft.CodeAnalysis; using SNetwork; 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("Flowaria.MeltdownReactor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Flowaria.MeltdownReactor")] [assembly: AssemblyTitle("Flowaria.MeltdownReactor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MeltdownReactor { [BepInPlugin("Flowaria.MeltdownReactor", "MeltdownReactor", "2.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("Inas.EOSExt.Reactor")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EntryPoint : BasePlugin { [CompilerGenerated] private static class <>O { public static LiveEditEventHandler <0>__Listener_FileChanged1; } public const string PLUGIN_NAME = "MeltdownReactor"; public const string AUTHOR = "Flowaria"; public const string GUID = "Flowaria.MeltdownReactor"; public const string VERSION = "2.1.4"; public static string REACTOR_OVERRIDE_DATA_PATH = Path.Combine(MTFOUtil.CustomPath, "MeltdownReactor"); public static readonly Dictionary<uint, ReactorOverrideData> ReactorOverrideDatas = new Dictionary<uint, ReactorOverrideData>(); private Harmony m_Harmony; private LiveEditListener listener; public override void Load() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown MeltdownReactorLogger.Debug("This plugin is dev-ed based on Flowaria.MeltdownReactor, which is only used in rundowns Flowaria.Modulation and Flowaria.Paradigm"); MeltdownReactorLogger.Debug("All credits belong to Flowaria."); if (!Directory.Exists(REACTOR_OVERRIDE_DATA_PATH)) { Directory.CreateDirectory(REACTOR_OVERRIDE_DATA_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(REACTOR_OVERRIDE_DATA_PATH, "Template.json")); streamWriter.WriteLine(JSON.Serialize(new ReactorOverrideData())); streamWriter.Flush(); streamWriter.Close(); return; } ClassInjector.RegisterTypeInIl2Cpp<MeltdownReactor>(); m_Harmony = new Harmony("Flowaria.MeltdownReactor"); m_Harmony.PatchAll(); foreach (string item in Directory.EnumerateFiles(REACTOR_OVERRIDE_DATA_PATH, "*.json", SearchOption.AllDirectories)) { JSON.Load<ReactorOverrideData>(item, out var config); if (ReactorOverrideDatas.ContainsKey(config.ObjectiveDataID)) { MeltdownReactorLogger.Error($"Duplicate ObjectiveDataID {config.ObjectiveDataID}"); } else { ReactorOverrideDatas.Add(config.ObjectiveDataID, config); } } listener = LiveEdit.CreateListener(REACTOR_OVERRIDE_DATA_PATH, "*.json", true); LiveEditListener obj = listener; object obj2 = <>O.<0>__Listener_FileChanged1; if (obj2 == null) { LiveEditEventHandler val = Listener_FileChanged1; <>O.<0>__Listener_FileChanged1 = val; obj2 = (object)val; } obj.FileChanged += (LiveEditEventHandler)obj2; } private static void Listener_FileChanged1(LiveEditEventArgs e) { MeltdownReactorLogger.Warning("LiveEdit File Changed: " + e.FullPath + "."); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { ReactorOverrideData reactorOverrideData = JSON.Deserialize<ReactorOverrideData>(content); if (!ReactorOverrideDatas.ContainsKey(reactorOverrideData.ObjectiveDataID)) { MeltdownReactorLogger.Error("Changing ObjectiveDataID is not allowed, will not update."); } else { ReactorOverrideDatas[reactorOverrideData.ObjectiveDataID] = reactorOverrideData; MeltdownReactorLogger.Warning($"Updated override data with ObjectiveDataID {reactorOverrideData.ObjectiveDataID}"); } }); } } public class MeltdownReactor : MonoBehaviour { private const string MAINTERMINAL_NAME = "Main Terminal"; private const float HIDE_TIMER_THRESHOLD = 43200f; private static Color LowTemperature; private static Color HighTemperature; private static uint VerifyTextID; private static uint MainTerminalTextID; private static uint CooldownCommandDescTextID; private static uint InfiniteWaveVerifyTextID; internal static uint NotReadyForVerificationOutputTextID; internal static uint IncorrectTerminalOutputTextID; internal static uint CorrectTerminalOutputTextID; private LG_Light[] _lights; private float _updateTimer; private Dictionary<int, LG_ComputerTerminal> verifyZoneOverrideTerminals = new Dictionary<int, LG_ComputerTerminal>(); internal ReactorOverrideData overrideData; private Dictionary<int, string> meltdownWaveTerminalKeys; private HashSet<int> infiniteWaveIndices; private WardenObjectiveDataBlock objectiveDataBlock; private Dictionary<TERM_Command, List<WardenObjectiveEventData>> commandEventMap = new Dictionary<TERM_Command, List<WardenObjectiveEventData>>(); private Dictionary<TERM_Command, List<TerminalOutput>> commandPostOutputMap = new Dictionary<TERM_Command, List<TerminalOutput>>(); internal LG_WardenObjective_Reactor ChainedReactor { get; set; } public bool UsingLightEffect { get; set; } = true; public bool IsCorrectTerminal(LG_ComputerTerminal terminal) { int num = ChainedReactor.m_currentWaveCount - 1; if (num >= 0) { MeltdownReactorLogger.Error($"Index: {num}"); MeltdownReactorLogger.Error("Comp Terminal Key1: " + terminal.ItemKey); MeltdownReactorLogger.Error("Comp Terminal Key2: " + (meltdownWaveTerminalKeys.ContainsKey(num) ? meltdownWaveTerminalKeys[num] : "empty")); if (meltdownWaveTerminalKeys.ContainsKey(num) && meltdownWaveTerminalKeys[num].Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase)) { return true; } } return false; } public void Init() { if (overrideData == null) { MeltdownReactorLogger.Error("ReactorOverrideData is null!"); return; } meltdownWaveTerminalKeys = new Dictionary<int, string>(); overrideData.MeltdownWaveIndices.ForEach(delegate(int index) { meltdownWaveTerminalKeys.TryAdd(index, string.Empty); }); infiniteWaveIndices = overrideData.InfiniteWaveIndices.ToHashSet(); LevelAPI.OnEnterLevel += OnDrop; if (VerifyTextID == 0) { VerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification"); MainTerminalTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName"); CooldownCommandDescTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc"); InfiniteWaveVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave"); NotReadyForVerificationOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output"); IncorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output"); CorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output"); } } private void OnDrop() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor chainedReactor = ChainedReactor; LG_ComputerTerminal terminal = ChainedReactor.m_terminal; objectiveDataBlock = GameDataBlockBase<WardenObjectiveDataBlock>.GetBlock(overrideData.ObjectiveDataID); if (objectiveDataBlock == null) { MeltdownReactorLogger.Error($"Failed to get the Reactor Startup objective for layer {chainedReactor.SpawnNode.LayerType}"); return; } if ((int)objectiveDataBlock.Type != 1) { MeltdownReactorLogger.Error("Only Reactor Startup is supported"); ((Behaviour)this).enabled = false; return; } if (UsingLightEffect) { _lights = ((IEnumerable<LG_Light>)chainedReactor.SpawnNode.m_lightsInNode).Where((LG_Light x) => (int)x.m_category == 3).ToArray(); chainedReactor.m_lightCollection.RemoveLights(Il2CppReferenceArray<LG_Light>.op_Implicit(_lights)); } if (overrideData.StartupOnDrop && SNet.IsMaster) { chainedReactor.AttemptInteract((eReactorInteraction)0, 0f); terminal.TrySyncSetCommandHidden((TERM_Command)21); } SetupVerifyZoneOverride(); SetupMeltdownAndInfiniteWave(); if (overrideData.ReactorTerminal != null && overrideData.ReactorTerminal.TerminalPassword.PasswordProtected) { BuildReactorTerminalPassword(); } } private void SetupVerifyZoneOverride() { //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) LG_Zone val3 = default(LG_Zone); foreach (VerifyZoneOverride verifyZoneOverride in overrideData.VerifyZoneOverrides) { if (verifyZoneOverrideTerminals.ContainsKey(verifyZoneOverride.WaveIndex)) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: Duplicate Wave Index {verifyZoneOverride.WaveIndex}"); continue; } if (infiniteWaveIndices.Contains(verifyZoneOverride.WaveIndex)) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: Wave Index {verifyZoneOverride.WaveIndex} is specified as Infinite Wave but VerifyZoneOverride is specified! Will not process"); continue; } if (verifyZoneOverride.WaveIndex < 0 || verifyZoneOverride.WaveIndex >= objectiveDataBlock.ReactorWaves.Count) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: Invalid Wave Index {verifyZoneOverride.WaveIndex}. Valid value for this reactor is: [0, {objectiveDataBlock.ReactorWaves.Count - 1}]"); continue; } ReactorWaveData val = objectiveDataBlock.ReactorWaves[verifyZoneOverride.WaveIndex]; if (!val.VerifyInOtherZone) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: `VerifyInOtherZone` is false for wave {verifyZoneOverride.WaveIndex}. You need to set it to true to generate the log, and thereby enabling moving the log."); continue; } LG_ComputerTerminal val2 = Utils.FindTerminalWithTerminalSerial(val.VerificationTerminalSerial, ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, val.ZoneForVerification); if ((Object)(object)val2 == (Object)null) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find wave log terminal. Wave index: {verifyZoneOverride.WaveIndex}"); continue; } TargetZone targetZone = verifyZoneOverride.TargetZone; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val3) || (Object)(object)val3 == (Object)null) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}."); continue; } if (val3.TerminalsSpawnedInZone == null || val3.TerminalsSpawnedInZone.Count < 0) { MeltdownReactorLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}.."); continue; } int num = Builder.SessionSeedRandom.Seed; if (num < 0) { num = ((num != int.MinValue) ? (-num) : int.MaxValue); } int num2 = num % val3.TerminalsSpawnedInZone.Count; LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[num2]; string text = val.VerificationTerminalFileName.ToUpperInvariant(); TerminalLogFileData localLog = val2.GetLocalLog(text); if (localLog == null) { MeltdownReactorLogger.Error("VerifyZoneOverrides: Cannot find reactor verify log on terminal."); continue; } val2.RemoveLocalLog(text); val4.AddLocalLog(localLog, true); val.VerificationTerminalSerial = val4.ItemKey; val2.ResetInitialOutput(); val4.ResetInitialOutput(); MeltdownReactorLogger.Debug($"VerifyZoneOverrides: moved wave {verifyZoneOverride.WaveIndex} verify log from {val2.ItemKey} to {val4.ItemKey}"); verifyZoneOverrideTerminals.Add(verifyZoneOverride.WaveIndex, val4); } } private void SetupMeltdownAndInfiniteWave() { //IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor chainedReactor = ChainedReactor; LG_ComputerTerminal terminal = ChainedReactor.m_terminal; eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex; LG_LayerType layerType = chainedReactor.SpawnNode.LayerType; LG_Zone val3 = default(LG_Zone); for (int i = 0; i < objectiveDataBlock.ReactorWaves.Count; i++) { if (!meltdownWaveTerminalKeys.ContainsKey(i) && !infiniteWaveIndices.Contains(i)) { continue; } ReactorWaveData val = objectiveDataBlock.ReactorWaves[i]; if (!val.HasVerificationTerminal) { _ = terminal.m_command; if (meltdownWaveTerminalKeys.ContainsKey(i)) { meltdownWaveTerminalKeys[i] = terminal.ItemKey; AddVerifyCommand(terminal); MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}"); } else { MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wavefor wave index {i}"); } continue; } LG_ComputerTerminal val2 = null; if (verifyZoneOverrideTerminals.ContainsKey(i)) { val2 = verifyZoneOverrideTerminals[i]; } else { if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, val.ZoneForVerification, ref val3)) { MeltdownReactorLogger.Error($"Cannot find LG_Zone {dimensionIndex}, {layerType}, {val.ZoneForVerification}"); continue; } for (int j = 0; j < val3.TerminalsSpawnedInZone.Count; j++) { LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[j]; if (val4.ItemKey.Equals(val.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)) { val2 = val4; break; } } } if ((Object)(object)val2 == (Object)null) { MeltdownReactorLogger.Error($"MeltdownWave: cannot find verify terminal for wave index {i}"); continue; } val2.ConnectedReactor = chainedReactor; val2.RemoveLocalLog(val.VerificationTerminalFileName.ToUpperInvariant()); if (meltdownWaveTerminalKeys.ContainsKey(i)) { meltdownWaveTerminalKeys[i] = val2.ItemKey; AddVerifyCommand(val2); MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}"); } else { MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wave for wave index {i}"); } val2.ResetInitialOutput(); } if (meltdownWaveTerminalKeys.Count == objectiveDataBlock.ReactorWaves.Count) { terminal.TrySyncSetCommandHidden((TERM_Command)22); } } private void AddVerifyCommand(LG_ComputerTerminal terminal) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown LG_ComputerTerminalCommandInterpreter command = terminal.m_command; if (command.HasRegisteredCommand((TERM_Command)42)) { MeltdownReactorLogger.Debug("TERM_Command.UniqueCommand5 already registered. If this terminal is specified as objective terminal for 2 waves and the number of commands in 'UniqueCommands' on this terminal isn't more than 4, simply ignore this message."); return; } command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", new LocalizedText { UntranslatedText = ((CooldownCommandDescTextID == 0) ? "Confirm Reactor Startup Cooling Protocol" : Text.Get(CooldownCommandDescTextID)), Id = 0u }, (TERM_CommandRule)0); terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0); } private void SetIdle() { //IL_0011: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ChainedReactor == (Object)null)) { pReactorState val = default(pReactorState); val.status = (eReactorStatus)0; val.stateCount = 0; val.stateProgress = 0f; val.verifyFailed = false; pReactorState state = val; ChainedReactor.m_stateReplicator.State = state; } } private void OnDestroy() { LevelAPI.OnEnterLevel -= OnDrop; ChainedReactor = null; infiniteWaveIndices?.Clear(); meltdownWaveTerminalKeys?.Clear(); verifyZoneOverrideTerminals?.Clear(); commandEventMap?.Clear(); commandPostOutputMap?.Clear(); infiniteWaveIndices = null; meltdownWaveTerminalKeys = null; overrideData = null; objectiveDataBlock = null; verifyZoneOverrideTerminals = null; commandEventMap = null; commandPostOutputMap = null; } private void LateUpdate() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0024: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName == 10) { eReactorStatus status = ChainedReactor.m_currentState.status; if (UsingLightEffect) { UpdateLight(status, ChainedReactor.m_currentWaveProgress); } UpdateGUIText(status); } } private void UpdateGUIText(eReactorStatus status) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 int num = ChainedReactor.m_currentWaveCount - 1; if (num < 0) { return; } bool flag = ChainedReactor.m_currentWaveData.Verify < 43200f; if ((int)status != 4) { return; } if (meltdownWaveTerminalKeys.ContainsKey(num)) { string text = ((MainTerminalTextID == 0) ? "Main Terminal" : Text.Get(MainTerminalTextID)); if (ChainedReactor.m_currentWaveData.HasVerificationTerminal) { text = ChainedReactor.m_currentWaveData.VerificationTerminalSerial; } ChainedReactor.SetGUIMessage(true, FormatText(VerifyTextID, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>"); } else if (infiniteWaveIndices.Contains(num)) { ChainedReactor.SetGUIMessage(true, string.Format(Text.Get(InfiniteWaveVerifyTextID), ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>"); } else if (ChainedReactor.m_currentWaveData.HasVerificationTerminal) { ChainedReactor.SetGUIMessage(true, Text.Format(1103u, (Object[])(object)new Object[3] { Object.op_Implicit(ChainedReactor.m_currentWaveCount), Object.op_Implicit(ChainedReactor.m_waveCountMax), Object.op_Implicit("<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>"); } else { ChainedReactor.SetGUIMessage(true, Text.Format(1105u, (Object[])(object)new Object[3] { Object.op_Implicit(ChainedReactor.m_currentWaveCount), Object.op_Implicit(ChainedReactor.m_waveCountMax), Object.op_Implicit("<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>") }), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>"); } } private void UpdateLight(eReactorStatus status, float progress) { //IL_001f: 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_003b: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0077: 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) if (!(_updateTimer > Clock.Time)) { _updateTimer = Clock.Time + 0.15f; switch (status - 1) { case 0: SetLightColor(Color.black); break; case 1: SetLightColor(Color.Lerp(LowTemperature, HighTemperature, progress)); break; case 2: SetLightColor(Color.Lerp(HighTemperature, LowTemperature, progress)); break; case 3: SetLightColor(LowTemperature); break; case 4: SetLightColor(LowTemperature); break; } } } private void SetLightColor(Color color) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (UsingLightEffect && _lights != null) { for (int i = 0; i < _lights.Length; i++) { _lights[i].ChangeColor(color); } } } private void BuildReactorTerminalPassword() { //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown LG_ComputerTerminal terminal = ChainedReactor.m_terminal; TerminalPassword terminalPassword = overrideData.ReactorTerminal.TerminalPassword; if (!terminalPassword.GeneratePassword) { terminal.LockWithPassword(terminalPassword.Password, new string[1] { "" }); return; } if (terminalPassword.TerminalZoneSelectionDatas.Count <= 0) { MeltdownReactorLogger.Error("Tried to generate a password for terminal " + terminal.PublicName + " with no " + typeof(TerminalZoneSelectionData).Name + "!! This is not allowed."); return; } string codeWord = SerialGenerator.GetCodeWord(); string passwordHintText = terminalPassword.PasswordHintText; string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on "; int num = terminalPassword.PasswordPartCount; if (codeWord.Length % num != 0) { MeltdownReactorLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({terminalPassword.PasswordPartCount}). Defaulting to 1."); num = 1; } string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord }); string text2 = ""; if (terminalPassword.ShowPasswordPartPositions) { for (int i = 0; i < array[0].Length; i++) { text2 += "-"; } } HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>(); for (int j = 0; j < num; j++) { int index = j % terminalPassword.TerminalZoneSelectionDatas.Count; LG_ComputerTerminal val = Utils.SelectTerminalFromSelectionData(terminalPassword.TerminalZoneSelectionDatas[index][Builder.SessionSeedRandom.Range(0, terminalPassword.TerminalZoneSelectionDatas[index].Count, "NO_TAG")]); if ((Object)(object)val != (Object)null) { string text3 = ""; string text4; if (terminalPassword.ShowPasswordPartPositions) { for (int k = 0; k < j; k++) { text3 += text2; } text4 = text3 + array[j]; for (int l = j; l < num - 1; l++) { text4 += text2; } } else { text4 = array[j]; } string text5 = (terminalPassword.ShowPasswordPartPositions ? ("0" + (j + 1)) : ("0" + Builder.SessionSeedRandom.Range(0, 9, "NO_TAG"))); TerminalLogFileData val2 = new TerminalLogFileData(); val2.FileName = "key" + text5 + "_" + terminal.m_serialNumber + (val.HasPasswordPart ? "_1" : "") + ".LOG"; val2.FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get((num == 1) ? 1431221909u : 2260297836u), text4), Id = 0u }; TerminalLogFileData val3 = val2; val.AddLocalLog(val3, true); if (!hashSet.Contains(val)) { if (j > 0) { text += ", "; } text = text + val.PublicName + " in " + val.SpawnNode.m_zone.AliasName; } hashSet.Add(val); val.HasPasswordPart = true; } else { MeltdownReactorLogger.Error($"Build() CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log."); } } string text6 = text + "."; if (terminalPassword.ShowPasswordLength) { terminal.LockWithPassword(codeWord, new string[3] { passwordHintText, text6, "Char[" + codeWord.Length + "]" }); } else { terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text6 }); } foreach (LG_ComputerTerminal item in hashSet) { item.ResetInitialOutput(); } } private void BuildReactorTerminalCustomCommands() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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) LG_ComputerTerminal terminal = ChainedReactor.m_terminal; List<ReactorCustomTerminalCommand> uniqueCommands = overrideData.ReactorTerminal.UniqueCommands; TERM_Command val = default(TERM_Command); for (int i = 0; i < uniqueCommands.Count; i++) { ReactorCustomTerminalCommand reactorCustomTerminalCommand = uniqueCommands[i]; if (terminal.m_command.TryGetUniqueCommandSlot(ref val)) { terminal.m_command.AddCommand(val, reactorCustomTerminalCommand.Command, reactorCustomTerminalCommand.CommandDesc, reactorCustomTerminalCommand.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(reactorCustomTerminalCommand.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(reactorCustomTerminalCommand.PostCommandOutputs)); for (int j = 0; j < reactorCustomTerminalCommand.CommandEvents.Count; j++) { WardenObjectiveEventData val2 = reactorCustomTerminalCommand.CommandEvents[j]; if (val2.ChainPuzzle != 0) { ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle); if (block != null) { ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.ConnectedReactor.SpawnNode.m_area, terminal.ConnectedReactor.m_chainedPuzzleAlign.position, terminal.ConnectedReactor.m_chainedPuzzleAlign, val2.UseStaticBioscanPoints); terminal.SetChainPuzzleForCommand(val, j, val3); } } } } else { MeltdownReactorLogger.Error($"LG_ComputerTerminal: Could not get any more unique command slots for this terminal!! Have you added too many unique commands to this terminal? (Yours: {uniqueCommands.Count}, Max: 5)"); } } ChainedPuzzleInstance val6 = default(ChainedPuzzleInstance); for (int k = 38; k <= 42; k++) { TERM_Command val4 = (TERM_Command)(byte)k; if (!commandEventMap.TryGetValue(val4, out var value) || value == null) { continue; } ChainedPuzzleInstance val5 = null; for (int l = 0; l < value.Count; l++) { WardenObjectiveEventData eventData = value[l]; if (eventData == null) { continue; } if (ChainedReactor.m_terminal.TryGetChainPuzzleForCommand(val4, l, ref val6) && (Object)(object)val6 != (Object)null) { ChainedPuzzleInstance obj = val6; obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f); }); val5 = val6; } else if ((Object)(object)val5 != (Object)null) { ChainedPuzzleInstance obj2 = val5; obj2.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f); }); } } } MeltdownReactorLogger.Warning("CustomCommand built!"); } private static string FormatText(uint id, params object[] objs) { return string.Format(Text.Get(id), objs); } static MeltdownReactor() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) LowTemperature = ColorExt.Hex("#23E4F2") * 2.5f; HighTemperature = ColorExt.Hex("#F63838") * 12f; VerifyTextID = 0u; MainTerminalTextID = 0u; CooldownCommandDescTextID = 0u; InfiniteWaveVerifyTextID = 0u; NotReadyForVerificationOutputTextID = 0u; IncorrectTerminalOutputTextID = 0u; CorrectTerminalOutputTextID = 0u; } } internal static class MeltdownReactorLogger { private static readonly ManualLogSource _logger = Logger.CreateLogSource("MeltdownReactor"); private static string Format(object msg) { return msg.ToString(); } public static void Info(object data) { _logger.LogMessage((object)Format(data)); } public static void Verbose(object data) { } public static void Debug(object data) { _logger.LogDebug((object)Format(data)); } public static void Error(object data) { _logger.LogError((object)Format(data)); } public static void Warning(object data) { _logger.LogWarning((object)Format(data)); } } internal static class Utils { public static LG_ComputerTerminal FindTerminalWithTerminalSerial(string itemKey, eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = null; if (Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localIndex, ref val) && (Object)(object)val != (Object)null) { Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current = enumerator.Current; if (current.ItemKey.Equals(itemKey, StringComparison.InvariantCultureIgnoreCase)) { return current; } } } return null; } public static TerminalLogFileData GetLocalLog(this LG_ComputerTerminal terminal, string logName) { Dictionary<string, TerminalLogFileData> localLogs = terminal.GetLocalLogs(); logName = logName.ToUpperInvariant(); if (!localLogs.ContainsKey(logName)) { return null; } return localLogs[logName]; } public static void ResetInitialOutput(this LG_ComputerTerminal terminal) { terminal.m_command.ClearOutputQueueAndScreenBuffer(); terminal.m_command.AddInitialTerminalOutput(); if (terminal.IsPasswordProtected) { terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null); } } public static LG_ComputerTerminal SelectTerminalFromSelectionData(PasswordTerminalZoneSelectionData selectionData) { //IL_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected I4, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) TargetZone targetZone = selectionData.TargetZone; LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val) || (Object)(object)val == (Object)null) { MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could NOT find zone with " + targetZone); return null; } if (val.TerminalsSpawnedInZone.Count <= 0) { MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals in zone with " + targetZone?.ToString() + ". At least one terminal required!!"); return null; } List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>(); if ((int)selectionData.SeedType != 0) { Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current = enumerator.Current; if (!current.HasPasswordPart) { list.Add(current); } } if (list.Count <= 0) { eLocalZoneIndex localIndex = targetZone.LocalIndex; MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals without a password part in zone with " + ((object)(eLocalZoneIndex)(ref localIndex)).ToString() + ". Putting the password on random (session) already used terminal."); return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")]; } } eSeedType seedType = selectionData.SeedType; switch ((int)seedType) { case 0: return val.TerminalsSpawnedInZone[Mathf.Clamp(0, val.TerminalsSpawnedInZone.Count - 1, selectionData.TerminalIndex)]; case 1: return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")]; case 2: return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")]; case 3: Random.InitState(selectionData.StaticSeed); return list[Random.Range(0, list.Count)]; default: MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() did not have a valid SeedType!!"); return null; } } } } namespace MeltdownReactor.ReactorData { public class PasswordTerminalZoneSelectionData { public TargetZone TargetZone { get; set; } = new TargetZone(); public eSeedType SeedType { get; set; } public int TerminalIndex { get; set; } public int StaticSeed { get; set; } public PasswordTerminalZoneSelectionData() { SeedType = (eSeedType)1; } public override string ToString() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) string[] obj = new string[7] { TargetZone?.ToString(), " ", null, null, null, null, null }; eSeedType seedType = SeedType; obj[2] = ((object)(eSeedType)(ref seedType)).ToString(); obj[3] = " "; obj[4] = TerminalIndex.ToString(); obj[5] = " "; obj[6] = StaticSeed.ToString(); return string.Concat(obj); } } public class ReactorCustomTerminalCommand { public string Command { get; set; } public LocalizedText CommandDesc { get; set; } public List<TerminalOutput> PostCommandOutputs { get; set; } public List<WardenObjectiveEventData> CommandEvents { get; set; } public TERM_CommandRule SpecialCommandRule { get; set; } public ReactorCustomTerminalCommand() { PostCommandOutputs = new List<TerminalOutput>(); CommandEvents = new List<WardenObjectiveEventData>(); } } public class ReactorOverrideData { public uint ObjectiveDataID { get; set; } public bool StartupOnDrop { get; set; } public List<int> MeltdownWaveIndices { get; set; } = new List<int>(); public List<int> InfiniteWaveIndices { get; set; } = new List<int>(); public ReactorTerminalSetting ReactorTerminal { get; set; } = new ReactorTerminalSetting(); public List<VerifyZoneOverride> VerifyZoneOverrides { get; set; } = new List<VerifyZoneOverride> { new VerifyZoneOverride() }; } public class ReactorTerminalSetting { public List<ReactorCustomTerminalCommand> UniqueCommands { get; set; } = new List<ReactorCustomTerminalCommand>(); public TerminalPassword TerminalPassword { get; set; } = new TerminalPassword(); } public class TargetZone { public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType LayerType { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public override string ToString() { //IL_000c: 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_003e: Unknown result type (might be due to invalid IL or missing references) return $"{LocalIndex}, {LayerType}, {DimensionIndex}"; } } public class TerminalPassword { public bool PasswordProtected { get; set; } public string Password { get; set; } = string.Empty; public string PasswordHintText { get; set; } = "Password Required."; public bool GeneratePassword { get; set; } = true; public int PasswordPartCount { get; set; } = 1; public bool ShowPasswordLength { get; set; } public bool ShowPasswordPartPositions { get; set; } public List<List<PasswordTerminalZoneSelectionData>> TerminalZoneSelectionDatas { get; set; } = new List<List<PasswordTerminalZoneSelectionData>> { new List<PasswordTerminalZoneSelectionData>() }; } public class VerifyZoneOverride { public int WaveIndex { get; set; } = -1; public TargetZone TargetZone { get; set; } = new TargetZone(); } } namespace MeltdownReactor.Patches { [HarmonyPatch] internal static class Patch_LG_ComputerTerminal { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminal), "OnStateChange")] private static bool Pre_OnStateChange(LG_ComputerTerminal __instance, bool isRecall) { if (__instance.SpawnNode != null || !isRecall) { return true; } return false; } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] internal static class Patch_Meltdown_Reactor_Terminal { private static bool Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null || (int)cmd != 42) { return true; } if (__instance.m_terminal.CommandIsHidden(cmd)) { return true; } _ = __instance.m_terminal.ItemKey; MeltdownReactor component = ((Component)connectedReactor).gameObject.GetComponent<MeltdownReactor>(); if ((Object)(object)component == (Object)null) { return true; } if (!connectedReactor.ReadyForVerification) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.NotReadyForVerificationOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); return false; } if (component.IsCorrectTerminal(__instance.m_terminal)) { MeltdownReactorLogger.Info("Reactor Verify Correct!"); if (SNet.IsMaster) { if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax) { connectedReactor.AttemptInteract((eReactorInteraction)5, 0f); } else { connectedReactor.AttemptInteract((eReactorInteraction)3, 0f); } } __instance.AddOutput(Text.Get(MeltdownReactor.CorrectTerminalOutputTextID), true); } else { MeltdownReactorLogger.Info("Reactor Verify Incorrect!"); __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.IncorrectTerminalOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } } [HarmonyPatch] internal static class Patch_Meltdown_Reactor { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Post_BuildDone(LG_WardenObjective_Reactor __instance) { //IL_000d: 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_0051: Invalid comparison between Unknown and I4 WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val)) { MeltdownReactorLogger.Error("Failed to get WardenObjectiveData for this reactor"); } else if (EntryPoint.ReactorOverrideDatas.ContainsKey(((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID)) { ReactorOverrideData overrideData = EntryPoint.ReactorOverrideDatas[((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID]; if ((int)val.Type != 1) { MeltdownReactorLogger.Error($"ObjectiveDataID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID} is not reactor startup, which is unsupported."); return; } MeltdownReactor meltdownReactor = ((Component)__instance).gameObject.AddComponent<MeltdownReactor>(); meltdownReactor.ChainedReactor = __instance; meltdownReactor.UsingLightEffect = false; meltdownReactor.overrideData = overrideData; meltdownReactor.Init(); MeltdownReactorLogger.Warning($"Override Reactor Data for ObjectiveID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID}"); } } } } namespace MeltdownReactor.Json { internal static class JSON { private static readonly JsonSerializerOptions s_SerializerOptions; public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, s_SerializerOptions); } public static string Serialize<T>(T obj) { return JsonSerializer.Serialize(obj, s_SerializerOptions); } static JSON() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown s_SerializerOptions = new JsonSerializerOptions { AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; s_SerializerOptions.Converters.Add(new JsonStringEnumConverter()); if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized) { s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter); s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter); MeltdownReactorLogger.Info("PartialData Support Found!"); } else { s_SerializerOptions.Converters.Add((JsonConverter)new LocalizedTextConverter()); } } public static void Load<T>(string file, out T config) where T : new() { if (file.Length < ".json".Length) { config = default(T); return; } if (file.Substring(file.Length - ".json".Length) != ".json") { file += ".json"; } file = File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "MeltdownReactor", file)); config = Deserialize<T>(file); } } } namespace MeltdownReactor.Json.PartialData { public static class MTFOPartialDataUtil { public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks"; public static JsonConverter PersistentIDConverter { get; private set; } public static JsonConverter LocalizedTextConverter { get; private set; } public static bool IsLoaded { get; private set; } public static bool Initialized { get; private set; } public static string PartialDataPath { get; private set; } public static string ConfigPath { get; private set; } static MTFOPartialDataUtil() { PersistentIDConverter = null; LocalizedTextConverter = null; IsLoaded = false; Initialized = false; PartialDataPath = string.Empty; ConfigPath = string.Empty; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type[] types = obj.GetTypes(); Type type = types.First((Type t) => t.Name == "PersistentIDConverter"); if ((object)type == null) { throw new Exception("Unable to Find PersistentIDConverter Class"); } Type type2 = types.First((Type t) => t.Name == "LocalizedTextConverter"); if ((object)type2 == null) { throw new Exception("Unable to Find LocalizedTextConverter Class"); } Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class"); PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public); PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public); PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public); if ((object)property == null) { throw new Exception("Unable to Find Property: Initialized"); } if ((object)property2 == null) { throw new Exception("Unable to Find Property: PartialDataPath"); } if ((object)property3 == null) { throw new Exception("Unable to Find Field: ConfigPath"); } Initialized = (bool)property.GetValue(null); PartialDataPath = (string)property2.GetValue(null); ConfigPath = (string)property3.GetValue(null); PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type); LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type2); IsLoaded = true; } catch (Exception value2) { MeltdownReactorLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}"); } } } public static class MTFOUtil { public const string PLUGIN_GUID = "com.dak.MTFO"; public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public; public static string GameDataPath { get; private set; } public static string CustomPath { get; private set; } public static bool HasCustomContent { get; private set; } public static bool IsLoaded { get; private set; } static MTFOUtil() { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class"); FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public); if ((object)field == null) { throw new Exception("Unable to Find Field: GameDataPath"); } if ((object)field2 == null) { throw new Exception("Unable to Find Field: CustomPath"); } if ((object)field3 == null) { throw new Exception("Unable to Find Field: HasCustomContent"); } GameDataPath = (string)field.GetValue(null); CustomPath = (string)field2.GetValue(null); HasCustomContent = (bool)field3.GetValue(null); IsLoaded = true; } catch (Exception value2) { MeltdownReactorLogger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}"); } } } }
plugins/net6/Inas07.EOSExt.EMP.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AK; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using EOSExt.EMP.Definition; using EOSExt.EMP.EMPComponent; using EOSExt.EMP.Impl; using EOSExt.EMP.Impl.Handlers; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; 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("Inas07.EOSExt.EMP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.EOSExt.EMP")] [assembly: AssemblyTitle("Inas07.EOSExt.EMP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.EMP { public class EMPManager : GenericExpeditionDefinitionManager<pEMPDefinition> { public struct pEMPState { public uint pEMPIndex; public bool enabled; public pEMPState() { pEMPIndex = 0u; enabled = false; } public pEMPState(pEMPState o) { pEMPIndex = 0u; enabled = false; o.pEMPIndex = pEMPIndex; o.enabled = enabled; } } private readonly Dictionary<uint, pEMP> _pEMPs = new Dictionary<uint, pEMP>(); public IEnumerable<pEMP> pEMPs => _pEMPs.Values; protected override string DEFINITION_NAME => "PersistentEMP"; private List<EMPController> _empTargets { get; } = new List<EMPController>(); private List<EMPShock> _activeEMPShock { get; } = new List<EMPShock>(); public static EMPManager Current { get; private set; } public PlayerAgent LocalPlayerAgent { get; private set; } public IEnumerable<EMPController> EMPTargets => _empTargets; internal void SetupHUDAndFlashlight() { if ((Object)(object)LocalPlayerAgent == (Object)null) { EOSLogger.Error($"{"SetupHUDAndFlashlight": LocalPlayerAgent is not set!}"); } else if (!((Object)(object)((Component)LocalPlayerAgent).gameObject.GetComponent<EMPController>() != (Object)null)) { ((Component)LocalPlayerAgent).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerHudHandler()); ((Component)LocalPlayerAgent).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerFlashLightHandler()); EOSLogger.Log("pEMP: PlayerHUD & flashlight setup completed"); } } internal void SetupAmmoWeaponHandlers(InventorySlot slot) { //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: Invalid comparison between Unknown and I4 //IL_0006: 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 (slot - 1 <= 1) { SetupAmmoWeaponHandlerForSlot(slot); EOSLogger.Log($"pEMP: Backpack {slot} setup completed"); } static void SetupAmmoWeaponHandlerForSlot(InventorySlot slot) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(slot, ref val)) { if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent<EMPController>() != (Object)null)) { ((Component)val.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPGunSightHandler()); } } else { EOSLogger.Warning($"Couldn't get item for slot {slot}!"); } } } internal void SetupToolHandler() { BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem((InventorySlot)3, ref val)) { if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent<EMPController>() != (Object)null) && (Object)(object)((Component)val.Instance).GetComponent<EnemyScanner>() != (Object)null) { ((Component)val.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPBioTrackerHandler()); EOSLogger.Warning($"pEMP: Backpack {3} setup completed"); } } else { EOSLogger.Warning($"Couldn't get item for slot {3}!"); } } public void TogglepEMPState(uint pEMPIndex, bool enabled) { if (!_pEMPs.ContainsKey(pEMPIndex)) { EOSLogger.Error($"TogglepEMPState: pEMPIndex {pEMPIndex} not defined"); } else { ActiveState newState = (enabled ? ActiveState.ENABLED : ActiveState.DISABLED); _pEMPs[pEMPIndex].ChangeState(newState); } } public void TogglepEMPState(WardenObjectiveEventData e) { uint count = (uint)e.Count; bool enabled = e.Enabled; TogglepEMPState(count, enabled); } private void pEMPInit() { LevelAPI.OnBuildStart += delegate { pEMPClear(); InitializepEMPs(); }; LevelAPI.OnLevelCleanup += pEMPClear; } private void pEMPClear() { _pEMPs.Clear(); } private void InitializepEMPs() { if (!base.definitions.ContainsKey(base.CurrentMainLevelLayout)) { return; } GenericExpeditionDefinition<pEMPDefinition> val = base.definitions[base.CurrentMainLevelLayout]; if (val == null || val.Definitions.Count < 1) { return; } foreach (pEMPDefinition definition in val.Definitions) { pEMP pEMP = new pEMP(definition); _pEMPs[definition.pEMPIndex] = pEMP; uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("SetuppEMPReplicators: replicator ID depleted, cannot set up!"); } else { pEMP.SetupReplicator(num); EOSLogger.Debug($"SetuppEMPReplicators: replicator_{num} setup! "); } EOSLogger.Warning($"pEMP_{definition.pEMPIndex} initialized"); } } internal void SetLocalPlayerAgent(PlayerAgent localPlayerAgent) { LocalPlayerAgent = localPlayerAgent; PlayerpEMPComponent.Current = ((Component)localPlayerAgent).gameObject.AddComponent<PlayerpEMPComponent>(); PlayerpEMPComponent.Current.player = localPlayerAgent; EOSLogger.Debug("LocalPlayerAgent setup completed"); } internal void OnLocalPlayerAgentDestroy() { PlayerpEMPComponent.Current = null; EOSLogger.Debug("LocalPlayerAgent Destroyed"); } public void AddTarget(EMPController target) { _empTargets.Add(target); } public void RemoveTarget(EMPController target) { _empTargets.Remove(target); } public void ActivateEMPShock(Vector3 position, float range, float duration) { //IL_0018: 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_003d: Unknown result type (might be due to invalid IL or missing references) if (!GameStateManager.IsInExpedition) { EOSLogger.Error("Tried to activate an EMP when not in level, this shouldn't happen!"); return; } _activeEMPShock.Add(new EMPShock(position, range, duration)); foreach (EMPController empTarget in _empTargets) { if (Vector3.Distance(position, empTarget.Position) < range) { empTarget.AddTime(duration); } } } public float DurationFromPosition(Vector3 position) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) _activeEMPShock.RemoveAll((EMPShock e) => Mathf.Round(e.RemainingTime) <= 0f); float num = 0f; foreach (EMPShock item in _activeEMPShock) { if (item.InRange(position)) { num += item.RemainingTime; } } return num; } private void Clear() { _empTargets.Clear(); _activeEMPShock.Clear(); EMPHandler.Cleanup(); } public override void Init() { EMPWardenEvents.Init(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; Events.InventoryWielded = (Action<InventorySlot>)Delegate.Combine(Events.InventoryWielded, new Action<InventorySlot>(SetupAmmoWeaponHandlers)); pEMPInit(); } private EMPManager() { } static EMPManager() { Current = new EMPManager(); ClassInjector.RegisterTypeInIl2Cpp<EMPController>(); ClassInjector.RegisterTypeInIl2Cpp<PlayerpEMPComponent>(); } } internal static class EMPWardenEvents { public enum EMPEvents { Instant_Shock = 300, Toggle_PEMP_State } internal static void InstantShock(WardenObjectiveEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector3 position = e.Position; float fogTransitionDuration = e.FogTransitionDuration; float duration = e.Duration; EMPManager.Current.ActivateEMPShock(position, fogTransitionDuration, duration); } internal static void TogglepEMPState(WardenObjectiveEventData e) { EMPManager.Current.TogglepEMPState(e); } internal static void Init() { EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Instant_Shock.ToString(), 300u, (Action<WardenObjectiveEventData>)InstantShock); EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Toggle_PEMP_State.ToString(), 301u, (Action<WardenObjectiveEventData>)TogglepEMPState); } } public static class Events { public static Action<GearPartFlashlight> FlashLightWielded; public static Action<InventorySlot> InventoryWielded; public static Action EnterGSInLevel; } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.EMP", "EOSExt.EMP", "1.0.4")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.EMP"; public const string VERSION = "1.0.4"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("EOSExt.EMP"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<pEMPDefinition>)EMPManager.Current).Init(); } } } namespace EOSExt.EMP.Patches { [HarmonyPatch(typeof(EnemyScanner))] internal static class Inject_EnemyScanner { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateDetectedEnemies")] internal static bool Pre_UpdateDetectedEnemies() { return !EMPHandler.IsLocalPlayerDisabled; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateTagProgress")] internal static bool Pre_UpdateTagProgress(EnemyScanner __instance) { //IL_0061: 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) if (EMPHandler.IsLocalPlayerDisabled) { ((ItemEquippable)__instance).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); __instance.m_screen.SetStatusText("ERROR"); ((ProgressBarBase)__instance.m_progressBar).SetProgress(1f); __instance.m_screen.SetGuixColor(Color.yellow); return false; } __instance.m_screen.SetStatusText("Ready to tag"); __instance.m_screen.SetGuixColor(Color.red); return true; } } [HarmonyPatch(typeof(LG_Light))] internal static class Inject_LG_Light { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("Start")] internal static void Pre_Start(LG_Light __instance) { ((Component)__instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPLightHandler()); } } [HarmonyPatch(typeof(PlayerAgent))] internal static class Inject_PlayerAgent { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("Setup")] internal static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { EMPManager.Current.SetLocalPlayerAgent(__instance); } } } [HarmonyPatch(typeof(PlayerGuiLayer))] internal static class Inject_PlayerGuiLayer { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateGUIElementsVisibility")] internal static bool Pre_UpdateGUIElementsVisibility() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if (EMPHandler.IsLocalPlayerDisabled) { foreach (EMPPlayerHudHandler handler in EMPPlayerHudHandler.Handlers) { handler.ForceState(EMPState.Off); } return false; } if ((int)GameStateManager.CurrentStateName == 10) { foreach (EMPPlayerHudHandler handler2 in EMPPlayerHudHandler.Handlers) { handler2.ForceState(EMPState.On); } } return true; } } [HarmonyPatch] internal static class Inject_Events { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryBase), "OnItemEquippableFlashlightWielded")] internal static void Post_OnItemEquippableFlashlightWielded(GearPartFlashlight flashlight) { Events.FlashLightWielded?.Invoke(flashlight); } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryLocal), "DoWieldItem")] internal static void Post_DoWieldItem(PlayerInventoryLocal __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Events.InventoryWielded?.Invoke(((PlayerInventoryBase)__instance).WieldedSlot); } [HarmonyPostfix] [HarmonyPatch(typeof(GS_InLevel), "Enter")] private static void Post_SetupGear(GS_InLevel __instance) { Events.EnterGSInLevel?.Invoke(); } } [HarmonyPatch(typeof(PlayerSync))] internal static class Inject_PlayerSync { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("WantsToSetFlashlightEnabled")] internal static bool Pre_WantsToSetFlashlightEnabled(PlayerSync __instance, bool enable) { if (EMPHandler.IsLocalPlayerDisabled) { return false; } if (enable != __instance.m_agent.Inventory.FlashlightEnabled) { return true; } __instance.WantsToSetFlashlightEnabled(!__instance.m_agent.Inventory.FlashlightEnabled, false); return false; } } [HarmonyPatch(typeof(SentryGunFirstPerson))] internal static class Inject_SentryGunFirstPerson { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("CheckCanPlace")] internal static bool Pre_CheckCanPlace(ref bool __result) { if (!EMPHandler.IsLocalPlayerDisabled) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(SentryGunInstance))] internal static class Inject_SentryGunInstance { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("Setup")] internal static void Post_Setup(SentryGunInstance __instance) { ((Component)__instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPSentryHandler()); } } } namespace EOSExt.EMP.Definition { public class ItemToDisable { public bool BioTracker { get; set; } = true; public bool PlayerHUD { get; set; } = true; public bool PlayerFlashLight { get; set; } = true; public bool EnvLight { get; set; } = true; public bool GunSight { get; set; } = true; public bool Sentry { get; set; } = true; } public class pEMPDefinition { public uint pEMPIndex { get; set; } public Vec3 Position { get; set; } = new Vec3(); public float Range { get; set; } public ItemToDisable ItemToDisable { get; set; } = new ItemToDisable(); public pEMPDefinition() { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown public pEMPDefinition(pEMPDefinition other) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown pEMPIndex = other.pEMPIndex; Position = new Vec3 { x = other.Position.x, y = other.Position.y, z = other.Position.z }; Range = other.Range; ItemToDisable = new ItemToDisable { BioTracker = other.ItemToDisable.BioTracker, PlayerHUD = other.ItemToDisable.PlayerHUD, PlayerFlashLight = other.ItemToDisable.PlayerFlashLight, EnvLight = other.ItemToDisable.EnvLight, GunSight = other.ItemToDisable.GunSight, Sentry = other.ItemToDisable.Sentry }; } } } namespace EOSExt.EMP.EMPComponent { public class PlayerpEMPComponent : MonoBehaviour { private float nextUpdateTime = float.NaN; public const float UPDATE_INTERVAL = 0.2f; public static PlayerpEMPComponent Current { get; internal set; } public bool InAnypEMP { get; private set; } public PlayerAgent player { get; internal set; } private void CheckSetup() { if (!((Object)(object)EMPManager.Current.LocalPlayerAgent == (Object)null)) { EMPManager.Current.SetupHUDAndFlashlight(); EMPManager.Current.SetupToolHandler(); } } private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextUpdateTime) && Clock.Time < nextUpdateTime)) { return; } nextUpdateTime = Clock.Time + 0.2f; CheckSetup(); if ((Object)(object)player == (Object)null) { return; } ItemToDisable itemToDisable = new ItemToDisable { BioTracker = false, PlayerFlashLight = false, PlayerHUD = false, EnvLight = false, GunSight = false, Sentry = false }; InAnypEMP = false; foreach (pEMP pEMP in EMPManager.Current.pEMPs) { if (pEMP.State == ActiveState.ENABLED && pEMP.InRange(((Agent)player).Position)) { itemToDisable.BioTracker = itemToDisable.BioTracker || pEMP.ItemToDisable.BioTracker; itemToDisable.PlayerFlashLight = itemToDisable.PlayerFlashLight || pEMP.ItemToDisable.PlayerFlashLight; itemToDisable.PlayerHUD = itemToDisable.PlayerHUD || pEMP.ItemToDisable.PlayerHUD; itemToDisable.GunSight = itemToDisable.GunSight || pEMP.ItemToDisable.GunSight; itemToDisable.Sentry = itemToDisable.Sentry || pEMP.ItemToDisable.Sentry; InAnypEMP = true; } } if (itemToDisable.BioTracker) { foreach (EMPBioTrackerHandler handler in EMPBioTrackerHandler.Handlers) { handler?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPBioTrackerHandler handler2 in EMPBioTrackerHandler.Handlers) { handler2?.controller?.ClearTime(); } } if (itemToDisable.PlayerFlashLight) { foreach (EMPPlayerFlashLightHandler handler3 in EMPPlayerFlashLightHandler.Handlers) { handler3?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPPlayerFlashLightHandler handler4 in EMPPlayerFlashLightHandler.Handlers) { handler4?.controller?.ClearTime(); } } if (itemToDisable.PlayerHUD) { foreach (EMPPlayerHudHandler handler5 in EMPPlayerHudHandler.Handlers) { handler5?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPPlayerHudHandler handler6 in EMPPlayerHudHandler.Handlers) { handler6?.controller?.ClearTime(); } } if (itemToDisable.GunSight) { foreach (EMPGunSightHandler handler7 in EMPGunSightHandler.Handlers) { handler7?.controller?.AddTime(float.PositiveInfinity); } } else { foreach (EMPGunSightHandler handler8 in EMPGunSightHandler.Handlers) { handler8?.controller?.ClearTime(); } } if (itemToDisable.Sentry) { foreach (EMPSentryHandler handler9 in EMPSentryHandler.Handlers) { handler9?.controller?.AddTime(float.PositiveInfinity); } return; } foreach (EMPSentryHandler handler10 in EMPSentryHandler.Handlers) { handler10?.controller?.ClearTime(); } } private void OnDestroy() { EMPManager.Current.OnLocalPlayerAgentDestroy(); player = null; } static PlayerpEMPComponent() { } } } namespace EOSExt.EMP.Impl { public sealed class EMPController : MonoBehaviour { private bool _hasHandler; private bool _setup; public EMPHandler Handler { get; private set; } public float endTime { get; private set; } [HideFromIl2Cpp] private bool IsEMPActive => endTime > Clock.Time; [HideFromIl2Cpp] public Vector3 Position => ((Component)this).transform.position; private void Awake() { EMPManager.Current.AddTarget(this); } private void OnEnable() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName == 10 && _setup) { if (endTime > Clock.Time) { Handler.ForceState(EMPState.Off); } else { Handler.ForceState(EMPState.On); } } } private void Update() { if (_hasHandler) { Handler.Tick(IsEMPActive); } } [HideFromIl2Cpp] public void AddTime(float time) { endTime = Clock.Time + time; } [HideFromIl2Cpp] public void ClearTime() { endTime = Clock.Time - 1f; } [HideFromIl2Cpp] public void AssignHandler(EMPHandler handler) { if (Handler != null) { EOSLogger.Warning("Tried to assign a handler to a controller that already had one!"); return; } Handler = handler; Handler.Setup(((Component)this).gameObject, this); _hasHandler = true; _setup = true; } [HideFromIl2Cpp] public void ForceState(EMPState state) { if (Handler != null) { Handler.ForceState(state); } } private void OnDestroy() { EMPManager.Current.RemoveTarget(this); Handler.OnDespawn(); Handler = null; } } public abstract class EMPHandler { protected enum DeviceState { On, Off, Unknown } protected DeviceState _deviceState; protected float _stateTimer; private static bool _isLocalPlayerDisabled; private float _delayTimer; private bool _destroyed; protected static Random _rand = new Random(); public EMPState State { get; protected set; } public EMPController controller { get; protected set; } public GameObject gameObject { get; protected set; } public static bool IsLocalPlayerDisabled { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (_isLocalPlayerDisabled) { return (int)GameStateManager.CurrentStateName == 10; } return false; } } protected virtual float FlickerDuration => 0.2f; protected virtual float MinDelay => 0f; protected virtual float MaxDelay => 1.5f; protected virtual bool IsDeviceOnPlayer => false; public virtual void Setup(GameObject gameObject, EMPController controller) { this.gameObject = gameObject; this.controller = controller; } public static void Cleanup() { _isLocalPlayerDisabled = false; } public void ForceState(EMPState state) { if (State != state) { State = state; _delayTimer = Clock.Time - 1f; _stateTimer = Clock.Time - 1f; switch (state) { case EMPState.Off: _deviceState = DeviceState.Off; DeviceOff(); break; default: _deviceState = DeviceState.Unknown; break; case EMPState.On: _deviceState = DeviceState.On; DeviceOn(); break; } } } public void Tick(bool isEMPD) { if (_destroyed) { return; } if (isEMPD && State == EMPState.On) { float randomDelay = GetRandomDelay(MinDelay, MaxDelay); State = EMPState.FlickerOff; _delayTimer = Clock.Time + randomDelay; _stateTimer = Clock.Time + FlickerDuration + randomDelay; } if (!isEMPD && State == EMPState.Off) { float randomDelay2 = GetRandomDelay(0f, 1.5f); State = EMPState.FlickerOn; _delayTimer = Clock.Time + randomDelay2; _stateTimer = Clock.Time + FlickerDuration + randomDelay2; } switch (State) { case EMPState.On: if (_deviceState != 0) { DeviceOn(); _deviceState = DeviceState.On; if (IsDeviceOnPlayer) { _isLocalPlayerDisabled = false; } } break; case EMPState.FlickerOff: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.Off; } } break; case EMPState.Off: if (_deviceState != DeviceState.Off) { DeviceOff(); _deviceState = DeviceState.Off; if (IsDeviceOnPlayer) { _isLocalPlayerDisabled = true; } } break; case EMPState.FlickerOn: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.On; } } break; } } public void OnDespawn() { _destroyed = true; } protected abstract void FlickerDevice(); protected abstract void DeviceOn(); protected abstract void DeviceOff(); protected static float GetRandomDelay(float min, float max) { return (float)((double)min + _rand.NextDouble() * (double)(max - min)); } protected static float GetRandom01() { return (float)_rand.NextDouble(); } protected static int GetRandomRange(int min, int maxPlusOne) { return _rand.Next(min, maxPlusOne); } protected static int Index(int length) { return _rand.Next(0, length); } protected static bool FlickerUtil(int oneInX = 2) { return Index(oneInX) == 0; } } public class EMPShock { public Vector3 position { get; internal set; } public float range { get; internal set; } public float endTime { get; internal set; } public float RemainingTime => endTime - Clock.Time; public EMPShock(Vector3 position, float range, float duration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) this.position = position; this.range = range; endTime = Clock.Time + duration; } public bool InRange(Vector3 position) { //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) return Vector3.Distance(position, this.position) < range; } } public enum EMPState { On, FlickerOff, Off, FlickerOn } public enum ActiveState { DISABLED, ENABLED } public struct pEMPState { public ActiveState status; public pEMPState() { status = ActiveState.DISABLED; } public pEMPState(ActiveState status) { this.status = status; } public pEMPState(pEMPState o) { status = o.status; } } public class pEMP : EMPShock { public readonly ItemToDisable DISABLE_NOTHING = new ItemToDisable { BioTracker = false, PlayerFlashLight = false, PlayerHUD = false, Sentry = false, EnvLight = false, GunSight = false }; public pEMPDefinition def { get; private set; } public StateReplicator<pEMPState> StateReplicator { get; private set; } public ActiveState State { get { if (StateReplicator == null) { return ActiveState.DISABLED; } return StateReplicator.State.status; } } public ItemToDisable ItemToDisable { get { if (def == null) { return DISABLE_NOTHING; } return def.ItemToDisable; } } public void OnStateChanged(pEMPState oldState, pEMPState newState, bool isRecall) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (def == null || oldState.status == newState.status) { return; } EOSLogger.Debug($"pEMP_{def.pEMPIndex} Change state: {oldState.status} -> {newState.status}"); switch (newState.status) { case ActiveState.DISABLED: base.endTime = float.NegativeInfinity; break; case ActiveState.ENABLED: base.endTime = float.PositiveInfinity; break; default: throw new NotImplementedException(); } foreach (EMPController eMPTarget in EMPManager.Current.EMPTargets) { if ((Object)(object)((Component)eMPTarget).GetComponent<LG_Light>() == (Object)null) { continue; } switch (newState.status) { case ActiveState.DISABLED: eMPTarget.ClearTime(); break; case ActiveState.ENABLED: if (InRange(eMPTarget.Position)) { eMPTarget.AddTime(float.PositiveInfinity); } else { eMPTarget.ClearTime(); } break; default: throw new NotImplementedException(); } } } public void ChangeState(ActiveState newState) { StateReplicator?.SetState(new pEMPState { status = newState }); } internal void SetupReplicator(uint replicatorID) { StateReplicator = StateReplicator<pEMPState>.Create(replicatorID, new pEMPState { status = ActiveState.DISABLED }, (LifeTimeType)1, (IStateReplicatorHolder<pEMPState>)null); StateReplicator.OnStateChanged += OnStateChanged; } public pEMP(pEMPDefinition def) : base(def.Position.ToVector3(), def.Range, float.NegativeInfinity) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) this.def = new pEMPDefinition(def); } internal void Destroy() { StateReplicator = null; def = null; } } } namespace EOSExt.EMP.Impl.Handlers { public class EMPBioTrackerHandler : EMPHandler { private static List<EMPBioTrackerHandler> handlers; private EnemyScanner _scanner; public static IEnumerable<EMPBioTrackerHandler> Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPBioTrackerHandler() { handlers = new List<EMPBioTrackerHandler>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _scanner = gameObject.GetComponent<EnemyScanner>(); if ((Object)(object)_scanner == (Object)null) { EOSLogger.Error("Couldn't get bio-tracker component!"); } handlers.Add(this); } protected override void DeviceOff() { ((ItemEquippable)_scanner).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); _scanner.m_graphics.m_display.enabled = false; } protected override void DeviceOn() { _scanner.m_graphics.m_display.enabled = true; } protected override void FlickerDevice() { ((Behaviour)_scanner).enabled = EMPHandler.FlickerUtil(); } } public class EMPGunSightHandler : EMPHandler { private static List<EMPGunSightHandler> handlers; public GameObject[] _sightPictures; public static IEnumerable<EMPGunSightHandler> Handlers => handlers; static EMPGunSightHandler() { handlers = new List<EMPGunSightHandler>(); LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnBuildStart += Clear; } private void SetupGunSights() { Il2CppArrayBase<Renderer> componentsInChildren = base.gameObject.GetComponentsInChildren<Renderer>(true); if (componentsInChildren != null) { _sightPictures = (from x in (IEnumerable<Renderer>)componentsInChildren where (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null where ((Object)x.sharedMaterial.shader).name.Contains("HolographicSight") select ((Component)x).gameObject).ToArray(); } if (_sightPictures == null || _sightPictures.Length < 1) { EOSLogger.Error("Unable to find sight on " + ((Object)base.gameObject).name + "!"); } } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); SetupGunSights(); handlers.Add(this); } protected override void DeviceOff() { ForEachSights(delegate(GameObject x) { x.SetActive(false); }); } protected override void DeviceOn() { ForEachSights(delegate(GameObject x) { x.SetActive(true); }); } protected override void FlickerDevice() { ForEachSights(delegate(GameObject x) { x.SetActive(EMPHandler.FlickerUtil()); }); } private void ForEachSights(Action<GameObject> action) { GameObject[] sightPictures = _sightPictures; foreach (GameObject val in sightPictures) { if ((Object)(object)val != (Object)null) { action?.Invoke(val); } } } private static void Clear() { handlers.Clear(); } } public class EMPLightHandler : EMPHandler { private static List<EMPLightHandler> handlers; private LG_Light _light; private float _originalIntensity; private Color _originalColor; public static IEnumerable<EMPLightHandler> Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPLightHandler() { handlers = new List<EMPLightHandler>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) base.Setup(gameObject, controller); _light = gameObject.GetComponent<LG_Light>(); if ((Object)(object)_light == (Object)null) { EOSLogger.Warning("No Light!"); } else { _originalIntensity = _light.GetIntensity(); _originalColor = new Color(_light.m_color.r, _light.m_color.g, _light.m_color.b, _light.m_color.a); base.State = EMPState.On; } handlers.Add(this); } protected override void FlickerDevice() { if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(EMPHandler.GetRandom01() * _originalIntensity); } } protected override void DeviceOn() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(_originalIntensity); _light.ChangeColor(_originalColor); } } protected override void DeviceOff() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_light == (Object)null)) { _light.ChangeIntensity(0f); _light.ChangeColor(Color.black); } } } public class EMPPlayerFlashLightHandler : EMPHandler { private static List<EMPPlayerFlashLightHandler> handlers; private PlayerInventoryBase _inventory; private float _originalIntensity; private bool _originalFlashlightState; public static IEnumerable<EMPPlayerFlashLightHandler> Handlers => handlers; protected override bool IsDeviceOnPlayer => true; private bool FlashlightEnabled => _inventory.FlashlightEnabled; private static void Clear() { handlers.Clear(); } static EMPPlayerFlashLightHandler() { handlers = new List<EMPPlayerFlashLightHandler>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _inventory = gameObject.GetComponent<PlayerAgent>().Inventory; if ((Object)(object)_inventory == (Object)null) { EOSLogger.Warning("Player inventory was null!"); } else { base.State = EMPState.On; Events.FlashLightWielded = (Action<GearPartFlashlight>)Delegate.Combine(Events.FlashLightWielded, new Action<GearPartFlashlight>(InventoryEvents_ItemWielded)); } handlers.Add(this); } private void InventoryEvents_ItemWielded(GearPartFlashlight flashlight) { _originalIntensity = GameDataBlockBase<FlashlightSettingsDataBlock>.GetBlock(flashlight.m_settingsID).intensity; } protected override void DeviceOff() { _originalFlashlightState = FlashlightEnabled; if (_originalFlashlightState) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(false, false); } } protected override void DeviceOn() { if (_originalFlashlightState != FlashlightEnabled) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(_originalFlashlightState, false); } _inventory.m_flashlight.intensity = _originalIntensity; } protected override void FlickerDevice() { if (FlashlightEnabled) { _inventory.m_flashlight.intensity = EMPHandler.GetRandom01() * _originalIntensity; } } } public class EMPPlayerHudHandler : EMPHandler { private static List<EMPPlayerHudHandler> handlers; private readonly List<RectTransformComp> _targets = new List<RectTransformComp>(); public static IEnumerable<EMPPlayerHudHandler> Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPPlayerHudHandler() { handlers = new List<EMPPlayerHudHandler>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { _targets.Clear(); base.Setup(gameObject, controller); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_compass); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_wardenObjective); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.Inventory); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_playerStatus); handlers.Add(this); } protected override void DeviceOff() { foreach (RectTransformComp target in _targets) { ((Component)target).gameObject.SetActive(false); } } protected override void DeviceOn() { foreach (RectTransformComp target in _targets) { ((Component)target).gameObject.SetActive(true); } } protected override void FlickerDevice() { foreach (RectTransformComp target in _targets) { target.SetVisible(EMPHandler.FlickerUtil()); } } } public class EMPSentryHandler : EMPHandler { private static List<EMPSentryHandler> handlers; private static Color _offColor; private SentryGunInstance _sentry; private SentryGunInstance_ScannerVisuals_Plane _visuals; public static IEnumerable<EMPSentryHandler> Handlers => handlers; private static void Clear() { handlers.Clear(); } static EMPSentryHandler() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) handlers = new List<EMPSentryHandler>(); _offColor = new Color { r = 0f, g = 0f, b = 0f, a = 0f }; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); _sentry = gameObject.GetComponent<SentryGunInstance>(); _visuals = gameObject.GetComponent<SentryGunInstance_ScannerVisuals_Plane>(); if ((Object)(object)_sentry == (Object)null || (Object)(object)_visuals == (Object)null) { EOSLogger.Error($"Missing components on Sentry! Has Sentry?: {(Object)(object)_sentry == (Object)null}, Has Visuals?: {(Object)(object)_visuals == (Object)null}"); } handlers.Add(this); } protected override void DeviceOff() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) _visuals.m_scannerPlane.SetColor(_offColor); _visuals.UpdateLightProps(_offColor, false); _sentry.m_isSetup = false; _sentry.m_isScanning = false; _sentry.m_isFiring = false; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true); } protected override void DeviceOn() { _sentry.m_isSetup = true; _sentry.m_visuals.SetVisualStatus((eSentryGunStatus)0, true); _sentry.m_isScanning = false; _sentry.m_startScanTimer = Clock.Time + _sentry.m_initialScanDelay; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true); } protected override void FlickerDevice() { int randomRange = EMPHandler.GetRandomRange(0, 3); _sentry.StopFiring(); switch (randomRange) { case 0: _visuals.SetVisualStatus((eSentryGunStatus)4, true); break; case 1: _visuals.SetVisualStatus((eSentryGunStatus)1, true); break; case 2: _visuals.SetVisualStatus((eSentryGunStatus)2, true); break; } } } }
plugins/net6/Inas07.EOSExt.Reactor.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json.Serialization; using AIGraph; using AK; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.Reactor.Component; using EOSExt.Reactor.Definition; using EOSExt.Reactor.Managers; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Extensions; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using SNetwork; 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("Inas07.EOSExt.Reactor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.EOSExt.Reactor")] [assembly: AssemblyTitle("Inas07.EOSExt.Reactor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.Reactor { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.Reactor", "EOSExt.Reactor", "1.0.4")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.Reactor"; public const string VERSION = "1.0.4"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("EOSExt.Reactor"); m_Harmony.PatchAll(); SetupManagers(); SetupExtraWardenEventDefinitions(); ClassInjector.RegisterTypeInIl2Cpp<OverrideReactorComp>(); EOSLogger.Log("ExtraObjectiveSetup.Reactor loaded."); } private void SetupManagers() { ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).Init(); ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).Init(); } private void SetupExtraWardenEventDefinitions() { EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.ReactorStartup.ToString(), 150u, (Action<WardenObjectiveEventData>)WardenEvents.ReactorStartup); EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.CompleteCurrentVerify.ToString(), 151u, (Action<WardenObjectiveEventData>)WardenEvents.CompleteCurrentVerify); } } } namespace EOSExt.Reactor.Patches { [HarmonyPatch] internal class CommandInterpreter_ReactorVerify { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReactorVerify")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_ReactorVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null) { EOSLogger.Error("ReactorVerify: connected reactor is null - bug detected"); return true; } if (connectedReactor.m_isWardenObjective) { return true; } if (connectedReactor.ReadyForVerification && param1 == connectedReactor.CurrentStateOverrideCode) { __instance.m_terminal.ChangeState((TERM_State)7); } else { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, Text.Get(2195342028u), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } } [HarmonyPatch] internal class OnTerminalStartupSequenceVerify { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnTerminalStartupSequenceVerify")] private static void Post_ExecuteEventsOnEndOnClientSide(LG_WardenObjective_Reactor __instance) { if (!SNet.IsMaster) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } } [HarmonyPatch] internal class Reactor_OnBuildDone { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Post_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Invalid comparison between Unknown and I4 uint num = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).Register(__instance); if (__instance.m_isWardenObjective) { ReactorStartupOverride definition = ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num); if (definition == null) { return; } WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(__instance.SpawnNode.LayerType, __instance.WardenObjectiveChainIndex, ref val) || val == null) { EOSLogger.Error("Failed to get WardenObjectiveData for this reactor"); return; } if ((int)val.Type != 1) { EOSLogger.Error($"Reactor Instance {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)} is not setup as vanilla ReactorStartup, cannot override"); return; } definition.ObjectiveDB = val; ReactorStartupOverrideManager.Current.Build(__instance, definition); } else { ReactorShutdownDefinition definition2 = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num); if (definition2 != null) { ReactorShutdownObjectiveManager.Current.Build(__instance, definition2); EOSLogger.Debug($"Reactor Shutdown Instance {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)}: custom setup complete"); } } if ((Object)(object)__instance.m_terminal != (Object)null) { TerminalInstanceManager.Current.RegisterReactorTerminal(__instance); } } } [HarmonyPatch] internal class Reactor_OnStateChange { private static void Startup_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState) { } private static void Shutdown_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState, ReactorShutdownDefinition def) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown eReactorStatus status = newState.status; switch (status - 6) { case 0: GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1080u), false, 200f, 8f, (Action)null); reactor.m_progressUpdateEnabled = true; reactor.m_currentDuration = 15f; reactor.m_lightCollection.SetMode(false); reactor.m_sound.Stop(); def.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; case 1: GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1081u), false, 200f, 8f, (Action)null); reactor.m_progressUpdateEnabled = false; reactor.ReadyForVerification = true; break; case 2: reactor.m_progressUpdateEnabled = false; if ((Object)(object)def.ChainedPuzzleOnVerificationInstance != (Object)null) { GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1082u), false, 200f, 8f, (Action)null); def.ChainedPuzzleOnVerificationInstance.AttemptInteract((eChainedPuzzleInteraction)0); } def.EventsOnShutdownPuzzleStarts.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; case 3: reactor.m_progressUpdateEnabled = false; reactor.m_objectiveCompleteTimer = Clock.Time + 5f; def.EventsOnComplete.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; } } [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static bool Pre_LG_WardenObjective_Reactor_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState, bool isDropinState) { //IL_000a: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0045: 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_00a6: 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_00be: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_isWardenObjective) { return true; } if (oldState.stateCount != newState.stateCount) { __instance.OnStateCountUpdate(newState.stateCount); } if (oldState.stateProgress != newState.stateProgress) { __instance.OnStateProgressUpdate(newState.stateProgress); } if (oldState.status == newState.status) { return false; } __instance.ReadyForVerification = false; uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance); if (ReactorInstanceManager.Current.IsStartupReactor(__instance)) { return true; } if (ReactorInstanceManager.Current.IsShutdownReactor(__instance)) { ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but its definition is missing, what happened?"); return false; } Shutdown_OnStateChange(__instance, oldState, newState, isDropinState, definition); __instance.m_currentState = newState; return false; } EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but it's neither startup nor shutdown reactor, what happened?"); return false; } } [HarmonyPatch] internal class Reactor_OnStateCountUpdate { [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateCountUpdate")] private static bool Pre_LG_WardenObjective_Reactor_OnStateCountUpdate(LG_WardenObjective_Reactor __instance, int count) { //IL_0109: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_015c: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown if (__instance.m_isWardenObjective) { return true; } uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance); if (ReactorInstanceManager.Current.IsStartupReactor(__instance)) { return true; } if (ReactorInstanceManager.Current.IsShutdownReactor(__instance)) { ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but its definition is missing, what happened?"); return true; } __instance.m_currentWaveCount = count; if (definition.PutVerificationCodeOnTerminal) { LG_ComputerTerminal instance = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)definition.VerificationCodeTerminal).GlobalZoneIndexTuple(), definition.VerificationCodeTerminal.InstanceIndex); __instance.m_currentWaveData = new ReactorWaveData { HasVerificationTerminal = (definition.PutVerificationCodeOnTerminal && (Object)(object)instance != (Object)null), VerificationTerminalSerial = (((Object)(object)instance != (Object)null) ? instance.ItemKey : string.Empty), Warmup = 1f, WarmupFail = 1f, Wave = 1f, Verify = 1f, VerifyFail = 1f }; } else { __instance.m_currentWaveData = new ReactorWaveData { HasVerificationTerminal = false, VerificationTerminalSerial = string.Empty, Warmup = 1f, WarmupFail = 1f, Wave = 1f, Verify = 1f, VerifyFail = 1f }; } if (__instance.m_overrideCodes != null && !string.IsNullOrEmpty(((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0])) { __instance.CurrentStateOverrideCode = ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0]; } else { EOSLogger.Error("Reactor_OnStateCountUpdate: code is not built?"); } return false; } EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but it's neither a startup nor shutdown reactor, what happen?"); return true; } } [HarmonyPatch] internal class Reactor_Update { private static bool _checked; private static TextDataBlock shutdownVerification_GUIText; [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")] private static bool Pre_LG_WardenObjective_Reactor_Update(LG_WardenObjective_Reactor __instance) { //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_0014: Invalid comparison between Unknown and I4 if (__instance.m_isWardenObjective || (int)__instance.m_currentState.status != 7) { return true; } if (!_checked) { shutdownVerification_GUIText = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExtraObjectiveSetup_ReactorShutdown.SecurityVerificationRequired"); _checked = true; } string empty = string.Empty; empty = ((!__instance.m_currentWaveData.HasVerificationTerminal) ? string.Format(Text.Get(1107u), "<color=orange>" + __instance.CurrentStateOverrideCode + "</color>") : string.Format((shutdownVerification_GUIText != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)shutdownVerification_GUIText).persistentID) : "SECURITY VERIFICATION REQUIRED. USE COMMAND <color=orange>REACTOR_VERIFY</color> AND FIND CODE ON <color=orange>{0}</color>.", __instance.m_currentWaveData.VerificationTerminalSerial)); __instance.SetGUIMessage(true, empty, (ePUIMessageStyle)3, false, "", ""); return false; } } [HarmonyPatch] internal class Reactor_CommandInterpreter { private static bool Handle_ReactorShutdown(LG_ComputerTerminalCommandInterpreter __instance) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor); ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { EOSLogger.Error("ReactorVerify: found built custom reactor shutdown but its definition is missing, what happened?"); return true; } __instance.AddOutput((TerminalLineType)3, Text.Get(3436726297u), 4f, (TerminalSoundType)0, (TerminalSoundType)0); if ((Object)(object)definition.ChainedPuzzleToActiveInstance != (Object)null) { __instance.AddOutput(Text.Get(2277987284u), true); if (SNet.IsMaster) { definition.ChainedPuzzleToActiveInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { connectedReactor.AttemptInteract((eReactorInteraction)6, 0f); } return false; } private static bool Handle_ReactorStartup_SpecialCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if (__instance.m_terminal.CommandIsHidden(cmd)) { return true; } _ = __instance.m_terminal.ItemKey; OverrideReactorComp component = ((Component)connectedReactor).gameObject.GetComponent<OverrideReactorComp>(); if ((Object)(object)component == (Object)null) { return true; } if (!connectedReactor.ReadyForVerification) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.NotReadyForVerificationOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); return false; } if (component.IsCorrectTerminal(__instance.m_terminal)) { EOSLogger.Log("Reactor Verify Correct!"); if (SNet.IsMaster) { if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax) { connectedReactor.AttemptInteract((eReactorInteraction)5, 0f); } else { connectedReactor.AttemptInteract((eReactorInteraction)3, 0f); } } else { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(connectedReactor.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } __instance.AddOutput(ReactorStartupOverrideManager.CorrectTerminalOutputText, true); } else { EOSLogger.Log("Reactor Verify Incorrect!"); __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.IncorrectTerminalOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] private static bool Pre_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null) { return true; } if ((int)cmd == 23 && !connectedReactor.m_isWardenObjective) { return Handle_ReactorShutdown(__instance); } if ((int)cmd == 42) { return Handle_ReactorStartup_SpecialCommand(__instance, cmd); } return true; } } } namespace EOSExt.Reactor.Patches.Shutdown { [HarmonyPatch] internal class Reactor_OnReactorShutdownVerifyChaosDone { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "OnReactorShutdownVerifyChaosDone")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_OnReactorShutdownVerifyChaosDone(LG_ComputerTerminalCommandInterpreter __instance) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null || connectedReactor.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor); uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor); ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { EOSLogger.Error("OnReactorShutdownVerifyChaosDone: found built custom reactor shutdown but its definition is missing, what happened?"); return false; } connectedReactor.AttemptInteract((eReactorInteraction)(((Object)(object)definition.ChainedPuzzleOnVerificationInstance != (Object)null) ? 8 : 9), 0f); return false; } } } namespace EOSExt.Reactor.Managers { public sealed class ReactorInstanceManager : InstanceManager<LG_WardenObjective_Reactor> { private HashSet<IntPtr> startupReactor = new HashSet<IntPtr>(); private HashSet<IntPtr> shutdownReactor = new HashSet<IntPtr>(); public static ReactorInstanceManager Current { get; private set; } public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_WardenObjective_Reactor instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } public void MarkAsStartupReactor(LG_WardenObjective_Reactor reactor) { if (shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } startupReactor.Add(((Il2CppObjectBase)reactor).Pointer); } public void MarkAsShutdownReactor(LG_WardenObjective_Reactor reactor) { if (startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } shutdownReactor.Add(((Il2CppObjectBase)reactor).Pointer); } public bool IsStartupReactor(LG_WardenObjective_Reactor reactor) { return startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer); } public bool IsShutdownReactor(LG_WardenObjective_Reactor reactor) { return shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer); } private void Clear() { //IL_0015: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) foreach (IntPtr item in startupReactor) { LG_WardenObjective_Reactor val = new LG_WardenObjective_Reactor(item); if ((int)val != 0) { CellSoundPlayer sound = val.m_sound; if (sound != null) { sound.Recycle(); } } } foreach (IntPtr item2 in shutdownReactor) { LG_WardenObjective_Reactor val2 = new LG_WardenObjective_Reactor(item2); if ((int)val2 != 0) { CellSoundPlayer sound2 = val2.m_sound; if (sound2 != null) { sound2.Recycle(); } } } startupReactor.Clear(); shutdownReactor.Clear(); } public void SetupReactorTerminal(LG_WardenObjective_Reactor reactor, TerminalDefinition reactorTerminalData) { reactor.SpawnNode.m_zone.TerminalsSpawnedInZone.Add(reactor.m_terminal); if (reactorTerminalData != null) { reactorTerminalData.LocalLogFiles?.ForEach(delegate(TerminalLogFileData log) { reactor.m_terminal.AddLocalLog(log, true); }); reactorTerminalData.UniqueCommands?.ForEach(delegate(CustomCommand cmd) { EOSTerminalUtils.AddUniqueCommand(reactor.m_terminal, cmd); }); EOSTerminalUtils.BuildPassword(reactor.m_terminal, reactorTerminalData.PasswordData); } } public static LG_WardenObjective_Reactor FindVanillaReactor(LG_LayerType layer, int count) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (count < 0) { EOSLogger.Error($"FindVanillaReactor: Count should be non-negative, but got {count}!"); return null; } LG_WardenObjective_Reactor val = null; int num = count; Enumerator<LayerChainIndex, iWardenObjectiveItem> enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<LayerChainIndex, iWardenObjectiveItem> current = enumerator.Current; if (current.Key.Layer != layer) { continue; } iWardenObjectiveItem value = current.Value; val = ((value != null) ? ((Il2CppObjectBase)value).TryCast<LG_WardenObjective_Reactor>() : null); if (!((Object)(object)val == (Object)null)) { if (num <= 0) { break; } val = null; num--; } } if ((Object)(object)val == (Object)null) { EOSLogger.Error($"FindVanillaReactor: reactor not found with index(Count) {num} in {layer}!"); } return val; } private ReactorInstanceManager() { LevelAPI.OnLevelCleanup += Clear; } static ReactorInstanceManager() { Current = new ReactorInstanceManager(); } } internal class ReactorStartupOverrideManager : InstanceDefinitionManager<ReactorStartupOverride> { private List<ReactorStartupOverride> builtOverride = new List<ReactorStartupOverride>(); public static uint SpecialCmdVerifyTextID { get; private set; } public static uint MainTerminalTextID { get; private set; } public static uint CooldownCommandDescTextID { get; private set; } public static uint InfiniteWaveVerifyTextID { get; private set; } public static uint NotReadyForVerificationOutputTextID { get; private set; } public static uint IncorrectTerminalOutputTextID { get; private set; } public static uint CorrectTerminalOutputTextID { get; private set; } public static string CoolDownCommandDesc { get { if (CooldownCommandDescTextID == 0) { return "Confirm Reactor Startup Cooling Protocol"; } return Text.Get(CooldownCommandDescTextID); } } public static string MainTerminalText { get { if (MainTerminalTextID == 0) { return "Main Terminal"; } return Text.Get(MainTerminalTextID); } } public static string SpecialCmdVerifyText { get { if (SpecialCmdVerifyTextID == 0) { return "REACTOR COOLING REQUIRED ({0}/{1})\nMANUAL OVERRIDE REQUIRED. USE COMMAND <color=orange>REACTOR_COOLDOWN</color> AT {2}"; } return Text.Get(SpecialCmdVerifyTextID); } } public static string InfiniteWaveVerifyText { get { if (InfiniteWaveVerifyTextID == 0) { return "VERIFICATION ({0}/{1})."; } return Text.Get(InfiniteWaveVerifyTextID); } } public static string NotReadyForVerificationOutputText { get { if (NotReadyForVerificationOutputTextID == 0) { return "<color=red>Reactor intensive test in progress, cannot initate cooldown</color>"; } return Text.Get(NotReadyForVerificationOutputTextID); } } public static string CorrectTerminalOutputText { get { if (CorrectTerminalOutputTextID == 0) { return "<color=red>Reactor stage cooldown completed</color>"; } return Text.Get(CorrectTerminalOutputTextID); } } public static string IncorrectTerminalOutputText { get { if (IncorrectTerminalOutputTextID == 0) { return "<color=red>Incorrect terminal, cannot initate cooldown</color>"; } return Text.Get(IncorrectTerminalOutputTextID); } } public static ReactorStartupOverrideManager Current { get; private set; } protected override string DEFINITION_NAME => "ReactorStartup"; public static void FetchOverrideTextDB() { SpecialCmdVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification"); MainTerminalTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName"); CooldownCommandDescTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc"); InfiniteWaveVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave"); NotReadyForVerificationOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output"); IncorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output"); CorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output"); } protected override void AddDefinitions(InstanceDefinitionsForLevel<ReactorStartupOverride> definitions) { definitions.Definitions.ForEach(delegate(ReactorStartupOverride def) { def.Overrides.Sort((WaveOverride o1, WaveOverride o2) => (o1.WaveIndex >= o2.WaveIndex) ? ((o1.WaveIndex > o2.WaveIndex) ? 1 : 0) : (-1)); }); base.AddDefinitions(definitions); } internal void Build(LG_WardenObjective_Reactor reactor, ReactorStartupOverride def) { if (!reactor.m_isWardenObjective) { EOSLogger.Error($"ReactorStartup: Reactor Override for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is not setup by vanilla, won't override"); return; } OverrideReactorComp overrideReactorComp = ((Component)reactor).gameObject.AddComponent<OverrideReactorComp>(); overrideReactorComp.ChainedReactor = reactor; overrideReactorComp.overrideData = def; overrideReactorComp.UsingLightEffect = false; overrideReactorComp.Init(); ReactorInstanceManager.Current.MarkAsStartupReactor(reactor); ReactorInstanceManager.Current.SetupReactorTerminal(reactor, def.ReactorTerminal); def.ChainedPuzzleToActiveInstance = reactor.m_chainedPuzzleToStartSequence; if ((Object)(object)def.ChainedPuzzleToActiveInstance != (Object)null) { ChainedPuzzleInstance chainedPuzzleToActiveInstance = def.ChainedPuzzleToActiveInstance; chainedPuzzleToActiveInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { def.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); }); } builtOverride.Add(def); EOSLogger.Debug($"ReactorStartup: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, override completed"); } private void OnLevelCleanup() { builtOverride.ForEach(delegate(ReactorStartupOverride def) { def.ChainedPuzzleToActiveInstance = null; }); builtOverride.Clear(); } private ReactorStartupOverrideManager() { LevelAPI.OnLevelCleanup += OnLevelCleanup; LevelAPI.OnBuildStart += OnLevelCleanup; } static ReactorStartupOverrideManager() { SpecialCmdVerifyTextID = 0u; MainTerminalTextID = 0u; CooldownCommandDescTextID = 0u; InfiniteWaveVerifyTextID = 0u; NotReadyForVerificationOutputTextID = 0u; IncorrectTerminalOutputTextID = 0u; CorrectTerminalOutputTextID = 0u; Current = new ReactorStartupOverrideManager(); EventAPI.OnExpeditionStarted += FetchOverrideTextDB; } } internal class ReactorShutdownObjectiveManager : InstanceDefinitionManager<ReactorShutdownDefinition> { private List<ReactorShutdownDefinition> builtShutdownPuzzles = new List<ReactorShutdownDefinition>(); public static ReactorShutdownObjectiveManager Current { get; private set; } protected override string DEFINITION_NAME => "ReactorShutdown"; private void GenericObjectiveSetup(LG_WardenObjective_Reactor reactor, TerminalDefinition reactorTerminalData) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) reactor.m_serialNumber = SerialGenerator.GetUniqueSerialNo(); reactor.m_itemKey = "REACTOR_" + reactor.m_serialNumber; reactor.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(reactor.m_terminalItemComp); reactor.m_terminalItem.Setup(reactor.m_itemKey, (AIG_CourseNode)null); reactor.m_terminalItem.FloorItemStatus = EnumUtil.GetRandomValue<eFloorInventoryObjectStatus>(); reactor.m_overrideCodes = Il2CppStringArray.op_Implicit(new string[1] { SerialGenerator.GetCodeWord() }); reactor.m_terminalItem.OnWantDetailedInfo = Func<List<string>, List<string>>.op_Implicit((Func<List<string>, List<string>>)delegate(List<string> defaultDetails) { List<string> list = new List<string> { "----------------------------------------------------------------", "MAIN POWER REACTOR" }; Enumerator<string> enumerator = defaultDetails.GetEnumerator(); while (enumerator.MoveNext()) { string current = enumerator.Current; list.Add(current); } list.Add("----------------------------------------------------------------"); return ListExtensions.ToIl2Cpp<string>(list); }); reactor.m_terminal = GOUtil.SpawnChildAndGetComp<LG_ComputerTerminal>(reactor.m_terminalPrefab, reactor.m_terminalAlign); reactor.m_terminal.Setup((TerminalStartStateData)null, (TerminalPlacementData)null); reactor.m_terminal.ConnectedReactor = reactor; ReactorInstanceManager.Current.SetupReactorTerminal(reactor, reactorTerminalData); } private void OnLateBuildJob(LG_WardenObjective_Reactor reactor, BaseReactorDefinition reactorDefinition) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) reactor.m_stateReplicator = SNet_StateReplicator<pReactorState, pReactorInteraction>.Create(new iSNet_StateReplicatorProvider<pReactorState, pReactorInteraction>(((Il2CppObjectBase)reactor).Pointer), (eSNetReplicatorLifeTime)1, default(pReactorState), (SNet_ChannelType)2); GenericObjectiveSetup(reactor, reactorDefinition.ReactorTerminal); reactor.m_sound = new CellSoundPlayer(reactor.m_terminalAlign.position); reactor.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_LOOP, true); reactor.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 100f); reactor.m_terminal.m_command.SetupReactorCommands(false, true); } internal void Build(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_019b: Expected O, but got Unknown //IL_019d: Expected O, but got Unknown //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) if (reactor.m_isWardenObjective) { EOSLogger.Error($"ReactorShutdown: Reactor definition for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is already setup by vanilla, won't build."); return; } OnLateBuildJob(reactor, def); reactor.m_lightCollection = LG_LightCollection.Create(reactor.m_reactorArea.m_courseNode, reactor.m_terminalAlign.position, (LG_LightCollectionSorting)1, float.MaxValue); reactor.m_lightCollection.SetMode(true); if (def.PutVerificationCodeOnTerminal) { LG_ComputerTerminal instance = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)def.VerificationCodeTerminal).GlobalZoneIndexTuple(), def.VerificationCodeTerminal.InstanceIndex); if ((Object)(object)instance == (Object)null) { EOSLogger.Error($"ReactorShutdown: PutVerificationCodeOnTerminal is specified but could NOT find terminal {def.VerificationCodeTerminal}, will show verification code upon shutdown initiation"); } else { string fileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log"; TerminalLogFileData val = new TerminalLogFileData { FileName = fileName, FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)reactor.m_overrideCodes)[0].ToUpperInvariant()), Id = 0u } }; instance.AddLocalLog(val, true); instance.m_command.ClearOutputQueueAndScreenBuffer(); instance.m_command.AddInitialTerminalOutput(); } } if (reactor.SpawnNode != null && reactor.m_terminalItem != null) { reactor.m_terminalItem.SpawnNode = reactor.SpawnNode; reactor.m_terminalItem.FloorItemLocation = reactor.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7); } if (def.ChainedPuzzleToActive != 0) { ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleToActive); if (block == null) { EOSLogger.Error("ReactorShutdown: ChainedPuzzleToActive is specified but could not find its ChainedPuzzleDatablock definition!"); } else { _ = ((Component)reactor).transform.position; def.ChainedPuzzleToActiveInstance = ChainedPuzzleManager.CreatePuzzleInstance(block, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform); ChainedPuzzleInstance chainedPuzzleToActiveInstance = def.ChainedPuzzleToActiveInstance; chainedPuzzleToActiveInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (SNet.IsMaster) { reactor.AttemptInteract((eReactorInteraction)6, 0f); } }); } } else { EOSLogger.Debug("ReactorShutdown: Reactor has no ChainedPuzzleToActive, will start shutdown sequence on shutdown command initiation."); } if (def.ChainedPuzzleOnVerification != 0) { ChainedPuzzleDataBlock block2 = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleOnVerification); if (block2 == null) { EOSLogger.Error("ReactorShutdown: ChainedPuzzleOnVerification is specified but could not find its ChainedPuzzleDatablock definition! Will complete shutdown on verification"); } _ = ((Component)reactor).transform.position; def.ChainedPuzzleOnVerificationInstance = ChainedPuzzleManager.CreatePuzzleInstance(block2, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform); ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = def.ChainedPuzzleOnVerificationInstance; chainedPuzzleOnVerificationInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (SNet.IsMaster) { reactor.AttemptInteract((eReactorInteraction)9, 0f); } }); } else { EOSLogger.Debug("ReactorShutdown: ChainedPuzzleOnVerification unspecified, will complete shutdown on verification."); } LG_ComputerTerminal terminal = reactor.m_terminal; iLG_SpawnedInNodeHandler val2 = ((terminal != null) ? ((Component)terminal).GetComponent<iLG_SpawnedInNodeHandler>() : null); if (val2 != null) { val2.SpawnNode = reactor.SpawnNode; } reactor.SetLightsEnabled(reactor.m_lightsWhenOff, false); reactor.SetLightsEnabled(reactor.m_lightsWhenOn, true); builtShutdownPuzzles.Add(def); ReactorInstanceManager.Current.MarkAsShutdownReactor(reactor); EOSLogger.Debug($"ReactorShutdown: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, custom setup completed"); } private void OnLevelCleanup() { builtShutdownPuzzles.ForEach(delegate(ReactorShutdownDefinition def) { ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = (def.ChainedPuzzleToActiveInstance = null); def.ChainedPuzzleOnVerificationInstance = chainedPuzzleOnVerificationInstance; }); builtShutdownPuzzles.Clear(); } private ReactorShutdownObjectiveManager() { LevelAPI.OnLevelCleanup += OnLevelCleanup; LevelAPI.OnBuildStart += OnLevelCleanup; } static ReactorShutdownObjectiveManager() { Current = new ReactorShutdownObjectiveManager(); } } } namespace EOSExt.Reactor.Definition { public enum EOSReactorVerificationType { NORMAL, BY_SPECIAL_COMMAND, BY_WARDEN_EVENT } public class WaveOverride { public int WaveIndex { get; set; } = -1; public EOSReactorVerificationType VerificationType { get; set; } public bool HideVerificationTimer { get; set; } public bool ChangeVerifyZone { get; set; } public BaseInstanceDefinition VerifyZone { get; set; } = new BaseInstanceDefinition(); [JsonIgnore] public LG_ComputerTerminal VerifyTerminal { get; set; } } public class ReactorStartupOverride : BaseReactorDefinition { public bool StartupOnDrop { get; set; } [JsonIgnore] public WardenObjectiveDataBlock ObjectiveDB { get; set; } public List<WaveOverride> Overrides { get; set; } = new List<WaveOverride> { new WaveOverride() }; } internal class WardenEvents { public enum EventType { ReactorStartup = 150, CompleteCurrentVerify } internal static void ReactorStartup(WardenObjectiveEventData e) { //IL_0009: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } LG_WardenObjective_Reactor val = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count); WardenObjectiveDataBlock val2 = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val2) || val2 == null) { EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock"); return; } if ((int)val2.Type != 1) { EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid."); return; } if ((Object)(object)val == (Object)null) { EOSLogger.Error($"ReactorStartup: Cannot find reactor in {e.Layer}."); return; } if ((int)val.m_currentState.status == 0) { if (SNet.IsMaster) { val.AttemptInteract((eReactorInteraction)0, 0f); } val.m_terminal.TrySyncSetCommandHidden((TERM_Command)21); } EOSLogger.Debug($"ReactorStartup: Current reactor wave for {e.Layer} completed"); } internal static void CompleteCurrentVerify(WardenObjectiveEventData e) { //IL_0006: 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_0029: Invalid comparison between Unknown and I4 //IL_0068: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val) || val == null) { EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock"); return; } if ((int)val.Type != 1) { EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid."); return; } LG_WardenObjective_Reactor val2 = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count); if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"CompleteCurrentReactorWave: Cannot find reactor in {e.Layer}."); return; } if (SNet.IsMaster) { if (val2.m_currentWaveCount == val2.m_waveCountMax) { val2.AttemptInteract((eReactorInteraction)5, 0f); } else { val2.AttemptInteract((eReactorInteraction)3, 0f); } } else { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val2.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } EOSLogger.Debug($"CompleteCurrentReactorWave: Current reactor verify for {e.Layer} completed"); } } public class BaseReactorDefinition : BaseInstanceDefinition { [JsonPropertyOrder(-9)] public TerminalDefinition ReactorTerminal { get; set; } = new TerminalDefinition(); [JsonPropertyOrder(-9)] public List<WardenObjectiveEventData> EventsOnActive { get; set; } = new List<WardenObjectiveEventData>(); [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleToActiveInstance { get; set; } } public class ReactorShutdownDefinition : BaseReactorDefinition { [JsonPropertyOrder(-9)] public uint ChainedPuzzleToActive { get; set; } public bool PutVerificationCodeOnTerminal { get; set; } public BaseInstanceDefinition VerificationCodeTerminal { get; set; } = new BaseInstanceDefinition(); public uint ChainedPuzzleOnVerification { get; set; } [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleOnVerificationInstance { get; set; } public List<WardenObjectiveEventData> EventsOnShutdownPuzzleStarts { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnComplete { get; set; } = new List<WardenObjectiveEventData>(); } } namespace EOSExt.Reactor.Component { public class OverrideReactorComp : MonoBehaviour { private static Color LowTemperature; private static Color HighTemperature; private LG_Light[] _lights; private float _updateTimer; private List<WaveOverride> WaveData = new List<WaveOverride>(); public LG_WardenObjective_Reactor ChainedReactor { get; internal set; } public ReactorStartupOverride overrideData { get; internal set; } public bool UsingLightEffect { get; set; } = true; public WardenObjectiveDataBlock ObjectiveData => overrideData?.ObjectiveDB; public void Init() { if ((Object)(object)ChainedReactor == (Object)null || overrideData == null) { EOSLogger.Error("ReactorOverride not properly initialized!"); return; } int i; for (i = 0; i < ObjectiveData.ReactorWaves.Count; i++) { int num = overrideData.Overrides.FindIndex((WaveOverride o) => o.WaveIndex == i); if (num != -1) { WaveData.Add(new WaveOverride { WaveIndex = i, VerificationType = overrideData.Overrides[num].VerificationType, HideVerificationTimer = overrideData.Overrides[num].HideVerificationTimer, ChangeVerifyZone = overrideData.Overrides[num].ChangeVerifyZone, VerifyZone = overrideData.Overrides[num].VerifyZone }); } else { WaveData.Add(new WaveOverride { WaveIndex = i }); } } LevelAPI.OnEnterLevel += OnEnterLevel; } private void OnEnterLevel() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 LG_WardenObjective_Reactor chainedReactor = ChainedReactor; LG_ComputerTerminal terminal = ChainedReactor.m_terminal; if ((int)ObjectiveData.Type != 1) { EOSLogger.Error("Only Reactor Startup is supported"); ((Behaviour)this).enabled = false; return; } if (UsingLightEffect) { _lights = ((IEnumerable<LG_Light>)chainedReactor.SpawnNode.m_lightsInNode).Where((LG_Light x) => (int)x.m_category == 3).ToArray(); chainedReactor.m_lightCollection.RemoveLights(Il2CppReferenceArray<LG_Light>.op_Implicit(_lights)); } if (overrideData.StartupOnDrop && SNet.IsMaster) { chainedReactor.AttemptInteract((eReactorInteraction)0, 0f); terminal.TrySyncSetCommandHidden((TERM_Command)21); } SetupVerifyZoneOverrides(); SetupWaves(); } private void SetupVerifyZoneOverrides() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Expected O, but got Unknown //IL_041f: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); foreach (WaveOverride waveDatum in WaveData) { if (!waveDatum.ChangeVerifyZone) { continue; } if (waveDatum.VerificationType == EOSReactorVerificationType.BY_WARDEN_EVENT) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Verification Type is {2}, which doesn't work with VerifyZoneOverride"); continue; } BaseInstanceDefinition verifyZone = waveDatum.VerifyZone; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(((GlobalZoneIndex)verifyZone).DimensionIndex, ((GlobalZoneIndex)verifyZone).LayerType, ((GlobalZoneIndex)verifyZone).LocalIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}."); continue; } if (val.TerminalsSpawnedInZone == null || val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}."); continue; } LG_ComputerTerminal val2 = null; if (verifyZone.InstanceIndex >= 0) { val2 = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple(), verifyZone.InstanceIndex); } else { List<LG_ComputerTerminal> instancesInZone = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstancesInZone(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()); int index = Builder.SessionSeedRandom.Range(0, instancesInZone.Count, "NO_TAG"); val2 = instancesInZone[index]; } if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"VerifyZoneOverride: cannot find target terminal with Terminal Instance Index: {waveDatum}"); } waveDatum.VerifyTerminal = val2; ReactorWaveData waveData = ObjectiveData.ReactorWaves[waveDatum.WaveIndex]; TerminalLogFileData val3 = null; if (waveData.VerifyInOtherZone) { List<LG_ComputerTerminal> list = EOSTerminalUtils.FindTerminal(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal x) => x.ItemKey == waveData.VerificationTerminalSerial)); if (list == null || list.Count < 1) { EOSLogger.Error($"Wave_{waveDatum.WaveIndex}: cannot find vanilla verification terminal in {(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification)}, unable to override"); continue; } LG_ComputerTerminal val4 = list[0]; if ((Object)(object)val4 == (Object)null) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find log terminal"); continue; } string text = waveData.VerificationTerminalFileName.ToUpperInvariant(); val3 = EOSTerminalUtils.GetLocalLog(val4, text); if (val3 == null) { EOSLogger.Error("VerifyZoneOverrides: Cannot find vanilla-generated reactor verify log on terminal..."); continue; } val4.RemoveLocalLog(text); EOSTerminalUtils.ResetInitialOutput(val4); } else { waveData.VerificationTerminalFileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log"; val3 = new TerminalLogFileData { FileName = waveData.VerificationTerminalFileName, FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpper()), Id = 0u } }; EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Log generated."); } waveData.HasVerificationTerminal = true; waveData.VerificationTerminalSerial = val2.ItemKey; val2.AddLocalLog(val3, true); EOSTerminalUtils.ResetInitialOutput(val2); EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} verification overriden"); } } private void SetupWaves() { //IL_0012: 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_001e: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor chainedReactor = ChainedReactor; eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex; LG_LayerType layerType = chainedReactor.SpawnNode.LayerType; int num = 0; for (int i = 0; i < WaveData.Count; i++) { ReactorWaveData reactorWave = ObjectiveData.ReactorWaves[i]; WaveOverride waveOverride = WaveData[i]; switch (waveOverride.VerificationType) { case EOSReactorVerificationType.BY_SPECIAL_COMMAND: if (!reactorWave.HasVerificationTerminal) { waveOverride.VerifyTerminal = ChainedReactor.m_terminal; AddVerifyCommand(ChainedReactor.m_terminal); } else { LG_ComputerTerminal val = waveOverride.VerifyTerminal; if ((Object)(object)val == (Object)null) { val = EOSTerminalUtils.FindTerminal(dimensionIndex, layerType, reactorWave.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal terminal) => terminal.ItemKey.Equals(reactorWave.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)))?[0]; if ((Object)(object)val == (Object)null) { EOSLogger.Error($"SetupWaves: cannot find verify terminal for Wave_{i}, skipped"); break; } waveOverride.VerifyTerminal = val; } val.ConnectedReactor = chainedReactor; val.RemoveLocalLog(reactorWave.VerificationTerminalFileName.ToUpperInvariant()); AddVerifyCommand(val); EOSTerminalUtils.ResetInitialOutput(val); } num++; EOSLogger.Debug($"WaveOverride: Setup as Wave Verification {1} for Wave_{i}"); break; default: EOSLogger.Error($"Unimplemented Verification Type {waveOverride.VerificationType}"); break; case EOSReactorVerificationType.NORMAL: case EOSReactorVerificationType.BY_WARDEN_EVENT: break; } } if (num == ObjectiveData.ReactorWaves.Count) { ChainedReactor.m_terminal.TrySyncSetCommandHidden((TERM_Command)22); } } private void AddVerifyCommand(LG_ComputerTerminal terminal) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown LG_ComputerTerminalCommandInterpreter command = terminal.m_command; if (command.HasRegisteredCommand((TERM_Command)42)) { EOSLogger.Debug("TERM_Command.UniqueCommand5 already registered. If this terminal is specified as objective terminal for 2 waves and the number of commands in 'UniqueCommands' on this terminal isn't more than 4, simply ignore this message."); return; } command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", new LocalizedText { UntranslatedText = ReactorStartupOverrideManager.CoolDownCommandDesc, Id = 0u }, (TERM_CommandRule)0); terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0); } public bool IsCorrectTerminal(LG_ComputerTerminal terminal) { int num = ChainedReactor.m_currentWaveCount - 1; if (num >= 0) { EOSLogger.Debug($"Index: {num}"); EOSLogger.Debug("Comp Terminal Key1: " + terminal.ItemKey); EOSLogger.Debug("Comp Terminal Key2: " + (((Object)(object)WaveData[num].VerifyTerminal != (Object)null) ? WaveData[num].VerifyTerminal.ItemKey : "empty")); if (WaveData[num].VerifyTerminal.ItemKey != null && WaveData[num].VerifyTerminal.ItemKey.Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase)) { return true; } } return false; } public void SetIdle() { //IL_0011: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ChainedReactor == (Object)null)) { pReactorState val = default(pReactorState); val.status = (eReactorStatus)0; val.stateCount = 0; val.stateProgress = 0f; val.verifyFailed = false; pReactorState state = val; ChainedReactor.m_stateReplicator.State = state; } } private void OnDestroy() { LevelAPI.OnEnterLevel -= OnEnterLevel; ChainedReactor = null; overrideData = null; } private void LateUpdate() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0024: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName == 10) { eReactorStatus status = ChainedReactor.m_currentState.status; if (UsingLightEffect) { UpdateLight(status, ChainedReactor.m_currentWaveProgress); } UpdateGUIText(status); } } private void UpdateGUIText(eReactorStatus status) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 int num = ChainedReactor.m_currentWaveCount - 1; if (num < 0) { return; } WaveOverride waveOverride = WaveData[num]; if ((int)status != 4) { return; } switch (waveOverride.VerificationType) { case EOSReactorVerificationType.NORMAL: if (ChainedReactor.m_currentWaveData.HasVerificationTerminal) { ChainedReactor.SetGUIMessage(true, Text.Format(1103u, (Object[])(object)new Object[3] { Object.op_Implicit(ChainedReactor.m_currentWaveCount), Object.op_Implicit(ChainedReactor.m_waveCountMax), Object.op_Implicit("<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); } else { ChainedReactor.SetGUIMessage(true, Text.Format(1105u, (Object[])(object)new Object[3] { Object.op_Implicit(ChainedReactor.m_currentWaveCount), Object.op_Implicit(ChainedReactor.m_waveCountMax), Object.op_Implicit("<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>") }), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); } break; case EOSReactorVerificationType.BY_SPECIAL_COMMAND: { string text = (ChainedReactor.m_currentWaveData.HasVerificationTerminal ? ChainedReactor.m_currentWaveData.VerificationTerminalSerial : ReactorStartupOverrideManager.MainTerminalText); ChainedReactor.SetGUIMessage(true, string.Format(ReactorStartupOverrideManager.SpecialCmdVerifyText, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); break; } case EOSReactorVerificationType.BY_WARDEN_EVENT: ChainedReactor.SetGUIMessage(true, string.Format(ReactorStartupOverrideManager.InfiniteWaveVerifyText, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); break; } } private void UpdateLight(eReactorStatus status, float progress) { //IL_001f: 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_003b: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0077: 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) if (!(_updateTimer > Clock.Time)) { _updateTimer = Clock.Time + 0.15f; switch (status - 1) { case 0: SetLightColor(Color.black); break; case 1: SetLightColor(Color.Lerp(LowTemperature, HighTemperature, progress)); break; case 2: SetLightColor(Color.Lerp(HighTemperature, LowTemperature, progress)); break; case 3: SetLightColor(LowTemperature); break; case 4: SetLightColor(LowTemperature); break; } } } private void SetLightColor(Color color) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (UsingLightEffect && _lights != null) { for (int i = 0; i < _lights.Length; i++) { _lights[i].ChangeColor(color); } } } static OverrideReactorComp() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) LowTemperature = ColorExt.Hex("#23E4F2") * 2.5f; HighTemperature = ColorExt.Hex("#F63838") * 12f; } } }
plugins/net6/Inas07.EOSExt.SecurityDoorTerminal.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.SecurityDoorTerminal.Definition; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Extensions; using GameData; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SecDoorTerminalInterface; 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("Inas07.EOSExt.SecurityDoorTerminal")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.EOSExt.SecurityDoorTerminal")] [assembly: AssemblyTitle("Inas07.EOSExt.SecurityDoorTerminal")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.SecurityDoorTerminal { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.SecurityDoorTerminal", "EOSExt.SecurityDoorTerminal", "1.0.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.SecurityDoorTerminal"; public const string VERSION = "1.0.0"; public override void Load() { SetupManagers(); EOSLogger.Log("ExtraObjectiveSetup.SecurityDoorTerminal loaded."); } private void SetupManagers() { ((ZoneDefinitionManager<SecurityDoorTerminalDefinition>)SecurityDoorTerminalManager.Current).Init(); } } public sealed class SecurityDoorTerminalManager : ZoneDefinitionManager<SecurityDoorTerminalDefinition> { private enum SDTWardenEvents { ADD_OVERRIDE_COMMAND = 1000 } private const string OVERRIDE_COMMAND = "ACCESS_OVERRIDE"; private List<(SecDoorTerminal sdt, SecurityDoorTerminalDefinition def)> levelSDTs = new List<(SecDoorTerminal, SecurityDoorTerminalDefinition)>(); public static SecurityDoorTerminalManager Current { get; private set; } protected override string DEFINITION_NAME => "SecDoorTerminal"; public bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door) { if ((Object)(object)zone == (Object)null) { door = null; return false; } if ((Object)(object)zone.m_sourceGate == (Object)null) { door = null; return false; } if (zone.m_sourceGate.SpawnedDoor == null) { door = null; return false; } door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>(); return (Object)(object)door != (Object)null; } protected override void AddDefinitions(ZoneDefinitionsForLevel<SecurityDoorTerminalDefinition> definitions) { base.Sort(definitions); base.AddDefinitions(definitions); } private void AddOverrideCommandWithAlarmText(SecDoorTerminal sdt) { if (sdt.CmdProcessor.HasRegisteredCommand((TERM_Command)254)) { return; } string text = "<color=orange>" + Text.Get(841u) + "</color>"; if ((Object)(object)sdt.LinkedDoorLocks.ChainedPuzzleToSolve != (Object)null && sdt.LinkedDoorLocks.ChainedPuzzleToSolve.Data.TriggerAlarmOnActivate) { string format = Text.Get(840u); ChainedPuzzleInstance chainedPuzzleToSolve = sdt.LinkedDoorLocks.ChainedPuzzleToSolve; text = "<color=orange>" + string.Format(format, (chainedPuzzleToSolve != null) ? chainedPuzzleToSolve.Data.PublicAlarmName : null) + "</color>"; int num = text.IndexOf('['); if (num >= 0 && num < text.Length) { text = text.Insert(num, "\n"); } } sdt.AddOverrideCommand("ACCESS_OVERRIDE", text, (Action<LG_ComputerTerminalCommandInterpreter>)null); } private void BuildSDT_UniqueCommands(SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) { def.TerminalSettings.UniqueCommands.ForEach(delegate(CustomCommand cmd) { EOSTerminalUtils.AddUniqueCommand(sdt.ComputerTerminal, cmd); }); } private void BuildLevelSDTs_UniqueCommands() { levelSDTs.ForEach(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp) { BuildSDT_UniqueCommands(tp.sdt, tp.def); }); } private void BuildLevelSDTs_Passwords() { levelSDTs.ForEach(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp) { EOSTerminalUtils.BuildPassword(tp.sdt.ComputerTerminal, tp.def.TerminalSettings.PasswordData); }); } private void WardenEvent_AddOverrideCommand(WardenObjectiveEventData e) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) int num = levelSDTs.FindIndex(delegate((SecDoorTerminal sdt, SecurityDoorTerminalDefinition def) tp) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0057: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode courseNode = ((LG_ZoneExpander)tp.sdt.LinkedDoor.Gate).m_linksTo.m_courseNode; return courseNode.m_dimension.DimensionIndex == e.DimensionIndex && courseNode.LayerType == e.Layer && courseNode.m_zone.LocalIndex == e.LocalIndex; }); if (num == -1) { EOSLogger.Error($"SDT_AddOverrideCommand: SDT not found on door to {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); } else { SecDoorTerminal item = levelSDTs[num].sdt; AddOverrideCommandWithAlarmText(item); EOSLogger.Debug($"SDT_AddOverrideCommand: added for SDT {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); } } private SecDoorTerminal BuildSDT_Instantiation(SecurityDoorTerminalDefinition def) { //IL_0020: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected I4, but got Unknown var (val, val2, val3) = ((GlobalZoneIndex)def).GlobalZoneIndexTuple(); LG_Zone val4 = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(val, val2, val3, ref val4) || (Object)(object)val4 == (Object)null) { EOSLogger.Error($"SecDoorTerminal: Cannot find target zone {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}"); return null; } if (!TryGetZoneEntranceSecDoor(val4, out var door) || (Object)(object)door == (Object)null) { EOSLogger.Error($"SecDoorTerminal: Cannot find spawned sec-door for zone {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}"); return null; } SecDoorTerminal sdt = SecDoorTerminal.Place(door, new TerminalStartStateData { StartingState = (TERM_State)0 }, (TerminalPlacementData)null); sdt.BioscanScanSolvedBehaviour = def.StateSettings.OnPuzzleSolved; if (sdt == null) { EOSLogger.Error("Build failed: Can only attach SDT to regular security door"); return null; } ((LG_ZoneExpander)val4.m_sourceGate).m_linksFrom.m_zone.TerminalsSpawnedInZone.Add(sdt.ComputerTerminal); sdt.BioscanScanSolvedBehaviour = def.StateSettings.OnPuzzleSolved; def.TerminalSettings.LocalLogFiles.ForEach(delegate(TerminalLogFileData log) { sdt.ComputerTerminal.AddLocalLog(log, true); }); eDoorStatus status = sdt.LinkedDoor.m_sync.GetCurrentSyncState().status; switch (status - 1) { case 2: if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked) { sdt.LinkedDoorLocks.m_gateKeyItemNeeded.keyPickupCore.m_interact.OnPickedUpByPlayer += Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)delegate { sdt.SetTerminalActive(false); }); sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked); List<string> list4 = new List<string> { string.Format("<color=orange>" + Text.Get(849u) + "</color>", sdt.LinkedDoorLocks.m_gateKeyItemNeeded.PublicName) }; sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list4)); } break; case 5: sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked); if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked) { List<string> list2 = new List<string> { string.Format("<color=orange>" + Text.Get(842u) + "</color>", sdt.LinkedDoorLocks.m_powerGeneratorNeeded.PublicName) }; sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list2)); } break; case 14: sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked); if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked) { List<string> list = new List<string> { string.Format("<color=orange>" + Text.Get(843u) + "</color>", sdt.LinkedDoorLocks.m_bulkheadDCNeeded.PublicName) }; sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list)); } break; case 6: sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked); if (def.StateSettings.LockedStateSetting.AccessibleWhenLocked) { List<string> list3 = new List<string> { sdt.LinkedDoorLocks.m_intCustomMessage.m_message }; sdt.ComputerTerminal.m_command.AddOutput(ListExtensions.ToIl2Cpp<string>(list3)); } else { sdt.SetCustomMessageActive(true); } break; case 0: case 3: case 4: case 8: if (def.StateSettings.OverrideCommandAccessibility != OverrideCmdAccess.ADDED_BY_WARDEN_EVENT) { AddOverrideCommandWithAlarmText(sdt); } sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenUnlocked); break; } sdt.LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate(pDoorState state, bool isDropin) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 eDoorStatus status3 = state.status; switch (status3 - 3) { case 0: case 3: case 4: case 12: sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenLocked); if ((int)state.status == 7) { sdt.SetCustomMessageActive(true); } break; case 1: case 2: case 6: sdt.SetTerminalActive(def.StateSettings.LockedStateSetting.AccessibleWhenUnlocked); break; case 5: case 7: case 8: case 9: case 10: case 11: break; } }); switch (def.StateSettings.OverrideCommandAccessibility) { case OverrideCmdAccess.ALWAYS: AddOverrideCommandWithAlarmText(sdt); break; case OverrideCmdAccess.ON_UNLOCK: sdt.LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate(pDoorState state, bool isDropin) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 eDoorStatus status2 = state.status; if (status2 - 4 <= 1 || (int)status2 == 9) { AddOverrideCommandWithAlarmText(sdt); } }); break; } return sdt; } public override void Init() { base.Init(); } private void BuildLevelSDTs_Instantiation() { if (!base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { return; } foreach (SecurityDoorTerminalDefinition definition in base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions) { SecDoorTerminal item = BuildSDT_Instantiation(definition); levelSDTs.Add((item, definition)); } } private void OnLevelCleanup() { levelSDTs.Clear(); } private SecurityDoorTerminalManager() { EOSWardenEventManager.Current.AddEventDefinition(SDTWardenEvents.ADD_OVERRIDE_COMMAND.ToString(), 1000u, (Action<WardenObjectiveEventData>)WardenEvent_AddOverrideCommand); BatchBuildManager.Current.Add_OnBatchDone((BatchName)75, (Action)BuildLevelSDTs_Instantiation); BatchBuildManager.Current.Add_OnBatchDone((BatchName)76, (Action)BuildLevelSDTs_Passwords); LevelAPI.OnBuildDone += BuildLevelSDTs_UniqueCommands; LevelAPI.OnLevelCleanup += OnLevelCleanup; } static SecurityDoorTerminalManager() { Current = new SecurityDoorTerminalManager(); } } } namespace EOSExt.SecurityDoorTerminal.Definition { public enum OverrideCmdAccess { ALWAYS, ON_UNLOCK, ADDED_BY_WARDEN_EVENT } public class SDTStateSetting_Locked { public bool AccessibleWhenLocked { get; set; } public bool AccessibleWhenUnlocked { get; set; } = true; } public class SDTStateSetting { public SDTStateSetting_Locked LockedStateSetting { get; set; } = new SDTStateSetting_Locked(); public OverrideCmdAccess OverrideCommandAccessibility { get; set; } = OverrideCmdAccess.ON_UNLOCK; public CPSolvedBehaviour OnPuzzleSolved { get; set; } = (CPSolvedBehaviour)1; } public class SecurityDoorTerminalDefinition : GlobalZoneIndex { public SDTStateSetting StateSettings { get; set; } = new SDTStateSetting(); public TerminalDefinition TerminalSettings { get; set; } = new TerminalDefinition(); } }
plugins/net6/Inas07.EOSExt.SecuritySensor.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.SecuritySensor.Component; using EOSExt.SecuritySensor.Definition; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GTFO.API.Extensions; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; 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("Inas07.EOSExt.SecuritySensor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.EOSExt.SecuritySensor")] [assembly: AssemblyTitle("Inas07.EOSExt.SecuritySensor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.SecuritySensor { internal static class Assets { public static GameObject CircleSensor { get; private set; } public static GameObject MovableSensor { get; private set; } public static void Init() { CircleSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/CircleSensor.prefab"); MovableSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/MovableSensor.prefab"); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.SecuritySensor", "EOSExt.SecuritySensor", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.SecuritySensor"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown SetupManagers(); AssetAPI.OnAssetBundlesLoaded += Assets.Init; m_Harmony = new Harmony("EOSExt.SecuritySensor"); m_Harmony.PatchAll(); ClassInjector.RegisterTypeInIl2Cpp<SensorCollider>(); EOSLogger.Log("ExtraObjectiveSetup.SecuritySensor loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<SensorGroupSettings>)SecuritySensorManager.Current).Init(); } } internal class MovableSensor { public GameObject movableGO { get; private set; } public CP_BasicMovable movingComp { get; private set; } private GameObject graphicsGO { get { GameObject obj = movableGO; if (obj == null) { return null; } return ((Component)obj.transform.GetChild(0)).gameObject; } } public static MovableSensor Instantiate(SensorSettings sensorSetting) { if (EOSNetworking.AllotReplicatorID() == 0) { EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator..."); return null; } MovableSensor movableSensor = new MovableSensor(); movableSensor.movableGO = Object.Instantiate<GameObject>(Assets.MovableSensor); movableSensor.movingComp = movableSensor.movableGO.GetComponent<CP_BasicMovable>(); movableSensor.movingComp.Setup(); List<Vector3> scanPositions = ListExtensions.ToIl2Cpp<Vector3>(sensorSetting.MovingPosition.Prepend(sensorSetting.Position).ToList().ConvertAll((Vec3 vec3) => vec3.ToVector3())); movableSensor.movingComp.ScanPositions = scanPositions; movableSensor.movingComp.m_amountOfPositions = sensorSetting.MovingPosition.Count; if (sensorSetting.MovingSpeedMulti > 0f) { CP_BasicMovable obj = movableSensor.movingComp; obj.m_movementSpeed *= sensorSetting.MovingSpeedMulti; } return movableSensor; } public void StartMoving() { graphicsGO.SetActive(true); movingComp.SyncUpdate(); movingComp.StartMoving(); } public void ResumeMoving() { graphicsGO.SetActive(true); movingComp.ResumeMovement(); } public void StopMoving() { movingComp.StopMoving(); graphicsGO.SetActive(false); } public void PauseMoving() { movingComp.PauseMovement(); graphicsGO.SetActive(false); } public void Destroy() { Object.Destroy((Object)(object)movableGO); movableGO = null; movingComp = null; } private MovableSensor() { } } public enum SensorEventType { ToggleSensorGroupState = 400 } public sealed class SecuritySensorManager : GenericExpeditionDefinitionManager<SensorGroupSettings> { private List<(SensorGroupSettings settings, SensorGroup sensorGroup)> securitySensorGroups = new List<(SensorGroupSettings, SensorGroup)>(); private Dictionary<IntPtr, int> sensorGroupIndex = new Dictionary<IntPtr, int>(); public static SecuritySensorManager Current { get; private set; } protected override string DEFINITION_NAME => "SecuritySensor"; public void BuildSensorGroup(SensorGroupSettings sensorGroupSettings) { int count = securitySensorGroups.Count; SensorGroup sensorGroup = SensorGroup.Instantiate(sensorGroupSettings, count); securitySensorGroups.Add((sensorGroupSettings, sensorGroup)); foreach (GameObject sensorGO in sensorGroup.SensorGOs) { sensorGroupIndex[((Il2CppObjectBase)sensorGO).Pointer] = count; } foreach (MovableSensor movableSensor in sensorGroup.MovableSensors) { sensorGroupIndex[((Il2CppObjectBase)movableSensor.movableGO).Pointer] = count; } EOSLogger.Debug($"SensorGroup_{count} built"); } internal void TriggerSensor(IntPtr pointer) { if (!sensorGroupIndex.ContainsKey(pointer)) { EOSLogger.Error("Triggering a sensor but doesn't find its corresponding sensor group! This should not happen!"); return; } int num = sensorGroupIndex[pointer]; if (num < 0 || num >= securitySensorGroups.Count) { EOSLogger.Error($"TriggerSensor: invalid SensorGroup index {num}"); return; } securitySensorGroups[num].settings.EventsOnTrigger.ForEach(delegate(WardenObjectiveEventData e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, e.Trigger, true, 0f); }); EOSLogger.Warning($"TriggerSensor: SensorGroup_{num} triggered"); } private void BuildSecuritySensor() { if (base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(BuildSensorGroup); } } private void Clear() { securitySensorGroups.ForEach(delegate((SensorGroupSettings settings, SensorGroup sensorGroup) builtSensorGroup) { builtSensorGroup.sensorGroup.Destroy(); }); securitySensorGroups.Clear(); sensorGroupIndex.Clear(); } private void ToggleSensorGroup(WardenObjectiveEventData e) { int count = e.Count; bool enabled = e.Enabled; if (count < 0 || count >= securitySensorGroups.Count) { EOSLogger.Error($"ToggleSensorGroup: invalid SensorGroup index {count}"); } else { securitySensorGroups[count].sensorGroup.ChangeState(enabled ? ActiveState.ENABLED : ActiveState.DISABLED); } } private SecuritySensorManager() { LevelAPI.OnBuildStart += delegate { Clear(); BuildSecuritySensor(); }; LevelAPI.OnLevelCleanup += Clear; EventAPI.OnExpeditionStarted += delegate { securitySensorGroups.ForEach(delegate((SensorGroupSettings settings, SensorGroup sensorGroup) tuple) { tuple.sensorGroup.StartMovingMovables(); }); }; EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleSensorGroupState.ToString(), 400u, (Action<WardenObjectiveEventData>)ToggleSensorGroup); } static SecuritySensorManager() { Current = new SecuritySensorManager(); } } internal class SensorGroup { private List<GameObject> GOSensorGroup = new List<GameObject>(); private List<MovableSensor> movableSensors = new List<MovableSensor>(); public int sensorGroupIndex { get; private set; } public StateReplicator<SensorGroupState> StateReplicator { get; private set; } public IEnumerable<GameObject> SensorGOs => GOSensorGroup; public IEnumerable<MovableSensor> MovableSensors => movableSensors; public void ChangeState(ActiveState status) { switch (status) { case ActiveState.ENABLED: GOSensorGroup.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActiveRecursively(true); }); ResumeMovingMovables(); break; case ActiveState.DISABLED: PauseMovingMovables(); GOSensorGroup.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActiveRecursively(false); }); break; } EOSLogger.Debug($"ChangeState: SecuritySensorGroup_{sensorGroupIndex} changed to state {status}"); StateReplicator.SetState(new SensorGroupState { status = status }); } private void OnStateChanged(SensorGroupState oldState, SensorGroupState newState, bool isRecall) { EOSLogger.Warning($"OnStateChanged: isRecall ? {isRecall}"); if (!isRecall) { return; } EOSLogger.Debug($"Recalling: SecuritySensorGroup_{sensorGroupIndex} changed to state {newState.status}"); switch (newState.status) { case ActiveState.ENABLED: GOSensorGroup.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActiveRecursively(true); }); ResumeMovingMovables(); break; case ActiveState.DISABLED: PauseMovingMovables(); GOSensorGroup.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActiveRecursively(false); }); break; } } public static SensorGroup Instantiate(SensorGroupSettings sensorGroupSettings, int sensorGroupIndex) { //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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) SensorGroup sensorGroup = new SensorGroup(); sensorGroup.sensorGroupIndex = sensorGroupIndex; foreach (SensorSettings item in sensorGroupSettings.SensorGroup) { Vector3 val = item.Position.ToVector3(); if (val == Vector3.zeroVector) { continue; } GameObject val2 = null; switch (item.SensorType) { case SensorType.BASIC: val2 = Object.Instantiate<GameObject>(Assets.CircleSensor); sensorGroup.GOSensorGroup.Add(val2); break; case SensorType.MOVABLE: { MovableSensor movableSensor = MovableSensor.Instantiate(item); if (movableSensor == null) { EOSLogger.Error("ERROR: failed to build movable sensor"); continue; } val2 = movableSensor.movableGO; sensorGroup.movableSensors.Add(movableSensor); break; } default: EOSLogger.Error($"Unsupported SensorType {item.SensorType}, skipped"); continue; } val2.transform.SetPositionAndRotation(val, Quaternion.identityQuaternion); float num = 0.16216217f; val2.transform.localScale = new Vector3(item.Radius, item.Radius, item.Radius); Transform transform = val2.transform; transform.localPosition += Vector3.up * num; val2.AddComponent<SensorCollider>().Setup(item); val2.SetActive(true); } uint num2 = EOSNetworking.AllotReplicatorID(); if (num2 == 0) { EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator..."); } else { sensorGroup.StateReplicator = StateReplicator<SensorGroupState>.Create(num2, new SensorGroupState { status = ActiveState.ENABLED }, (LifeTimeType)1, (IStateReplicatorHolder<SensorGroupState>)null); sensorGroup.StateReplicator.OnStateChanged += sensorGroup.OnStateChanged; } return sensorGroup; } public void StartMovingMovables() { movableSensors.ForEach(delegate(MovableSensor movable) { movable.StartMoving(); }); } public void PauseMovingMovables() { movableSensors.ForEach(delegate(MovableSensor movable) { movable.PauseMoving(); }); } public void ResumeMovingMovables() { movableSensors.ForEach(delegate(MovableSensor movable) { movable.ResumeMoving(); }); } public void Destroy() { GOSensorGroup.ForEach((Action<GameObject>)Object.Destroy); GOSensorGroup.Clear(); movableSensors.ForEach(delegate(MovableSensor m) { m.Destroy(); }); movableSensors.Clear(); StateReplicator = null; } private SensorGroup() { } } public enum ActiveState { DISABLED, ENABLED } public struct SensorGroupState { public ActiveState status; public SensorGroupState() { status = ActiveState.DISABLED; } public SensorGroupState(SensorGroupState o) { status = o.status; } public SensorGroupState(ActiveState status) { this.status = status; } } public struct MovableSensorLerp { public float lerp; public MovableSensorLerp() { lerp = 0f; } public MovableSensorLerp(MovableSensorLerp o) { lerp = o.lerp; } public MovableSensorLerp(float lerp) { this.lerp = lerp; } } } namespace EOSExt.SecuritySensor.Component { public class SensorCollider : MonoBehaviour { private float nextCheckTime = float.NaN; private SensorSettings sensorSettings; private int last_playersInSensor; public static float CHECK_INTERVAL { get; } = 0.1f; private Vector3 Position => ((Component)this).gameObject.transform.position; internal void Setup(SensorSettings sensorSettings) { this.sensorSettings = sensorSettings; } private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextCheckTime) && Clock.Time < nextCheckTime)) { return; } nextCheckTime = Clock.Time + CHECK_INTERVAL; int num = 0; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!current.Owner.IsBot && ((Agent)current).Alive) { Vector3 val = Position - ((Agent)current).Position; if (((Vector3)(ref val)).magnitude < sensorSettings.Radius) { num++; } } } if (num > last_playersInSensor) { SecuritySensorManager.Current.TriggerSensor(((Il2CppObjectBase)((Component)this).gameObject).Pointer); } last_playersInSensor = num; } } } namespace EOSExt.SecuritySensor.Patches { [HarmonyPatch] internal class Debug { [HarmonyPostfix] [HarmonyPatch(typeof(LG_CollisionWorldEventTrigger), "Update")] private static void Post(LG_CollisionWorldEventTrigger __instance) { } static Debug() { } } } namespace EOSExt.SecuritySensor.Definition { public class SensorColor { public float r { get; set; } public float g { get; set; } public float b { get; set; } public float a { get; set; } public Color toColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(r, g, b, a); } } public class SensorGroupSettings { public List<SensorSettings> SensorGroup { get; set; } = new List<SensorSettings> { new SensorSettings() }; public List<WardenObjectiveEventData> EventsOnTrigger { get; set; } = new List<WardenObjectiveEventData>(); } public enum SensorType { BASIC, MOVABLE } public class SensorSettings { public Vec3 Position { get; set; } = new Vec3(); public float Radius { get; set; } = 2.3f; public SensorType SensorType { get; set; } public float MovingSpeedMulti { get; set; } = 1f; public List<Vec3> MovingPosition { get; set; } = new List<Vec3> { new Vec3() }; } }
plugins/net6/Inas07.ExtraObjectiveSetup.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using ChainedPuzzles; using Enemies; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.Expedition; using ExtraObjectiveSetup.Expedition.Gears; using ExtraObjectiveSetup.Expedition.IndividualGeneratorGroup; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.JSON; using ExtraObjectiveSetup.Objectives.ActivateSmallHSU; using ExtraObjectiveSetup.Objectives.GeneratorCluster; using ExtraObjectiveSetup.Objectives.IndividualGenerator; using ExtraObjectiveSetup.Objectives.TerminalUplink; using ExtraObjectiveSetup.Tweaks.BossEvents; using ExtraObjectiveSetup.Tweaks.Scout; using ExtraObjectiveSetup.Tweaks.TerminalPosition; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using StateMachines; 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("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyTitle("Inas07.ExtraObjectiveSetup")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExtraObjectiveSetup { public static class EOSNetworking { public const uint INVALID_ID = 0u; public const uint FOREVER_REPLICATOR_ID_START = 1000u; public const uint REPLICATOR_ID_START = 10000u; private static uint currentForeverID; private static uint currentID; private static HashSet<uint> foreverUsedIDs; private static HashSet<uint> usedIDs; public static uint AllotReplicatorID() { while (currentID >= 10000 && usedIDs.Contains(currentID)) { currentID++; } if (currentID < 10000) { EOSLogger.Error("Replicator ID depleted. How?"); return 0u; } uint num = currentID; usedIDs.Add(num); currentID++; return num; } public static bool TryAllotID(uint id) { return usedIDs.Add(id); } public static uint AllotForeverReplicatorID() { while (currentForeverID < 10000 && foreverUsedIDs.Contains(currentForeverID)) { currentForeverID++; } if (currentForeverID >= 10000) { EOSLogger.Error("Forever Replicator ID depleted."); return 0u; } uint num = currentForeverID; foreverUsedIDs.Add(num); currentForeverID++; return num; } private static void Clear() { usedIDs.Clear(); currentID = 10000u; } public static void ClearForever() { foreverUsedIDs.Clear(); currentForeverID = 1000u; } static EOSNetworking() { currentForeverID = 1000u; currentID = 10000u; foreverUsedIDs = new HashSet<uint>(); usedIDs = new HashSet<uint>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } public sealed class BatchBuildManager { private Dictionary<BatchName, Action> OnBatchDone = new Dictionary<BatchName, Action>(); public static BatchBuildManager Current { get; private set; } public void Init() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (OnBatchDone.Count > 0) { return; } foreach (object value in Enum.GetValues(typeof(BatchName))) { OnBatchDone[(BatchName)value] = null; } } public void Add_OnBatchDone(BatchName batchName, Action action) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Combine(onBatchDone[batchName], action); } public void Remove_OnBatchDone(BatchName batchName, Action action) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Remove(onBatchDone[batchName], action); } public Action Get_OnBatchDone(BatchName batchName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return OnBatchDone[batchName]; } private BatchBuildManager() { } static BatchBuildManager() { Current = new BatchBuildManager(); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.ExtraObjectiveSetup", "ExtraObjectiveSetup", "1.4.4")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "ExtraObjectiveSetup"; public const string VERSION = "1.4.4"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("ExtraObjectiveSetup"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { BatchBuildManager.Current.Init(); IndividualGeneratorObjectiveManager.Current.Init(); GeneratorClusterObjectiveManager.Current.Init(); HSUActivatorObjectiveManager.Current.Init(); UplinkObjectiveManager.Current.Init(); TerminalPositionOverrideManager.Current.Init(); ScoutScreamEventManager.Current.Init(); BossDeathEventManager.Current.Init(); ExpeditionDefinitionManager.Current.Init(); ExpeditionGearManager.Current.Init(); ExpeditionIGGroupManager.Current.Init(); GeneratorClusterInstanceManager.Current.Init(); HSUActivatorInstanceManager.Current.Init(); PowerGeneratorInstanceManager.Current.Init(); TerminalInstanceManager.Current.Init(); } } } namespace ExtraObjectiveSetup.Utils { public static class EOSTerminalUtils { public static List<LG_ComputerTerminal> FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, Predicate<LG_ComputerTerminal> predicate) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"SelectTerminal: Could NOT find zone {(dimensionIndex, layerType, localIndex)}"); return null; } if (val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals in zone {(dimensionIndex, layerType, localIndex)}"); return null; } List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>(); Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current = enumerator.Current; if (predicate != null) { if (predicate(current)) { list.Add(current); } } else { list.Add(current); } } return list; } public static TerminalLogFileData GetLocalLog(this LG_ComputerTerminal terminal, string logName) { Dictionary<string, TerminalLogFileData> localLogs = terminal.GetLocalLogs(); logName = logName.ToUpperInvariant(); if (!localLogs.ContainsKey(logName)) { return null; } return localLogs[logName]; } public static void ResetInitialOutput(this LG_ComputerTerminal terminal) { terminal.m_command.ClearOutputQueueAndScreenBuffer(); terminal.m_command.AddInitialTerminalOutput(); if (terminal.IsPasswordProtected) { terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null); } } public static LG_ComputerTerminal SelectPasswordTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, eSeedType seedType, int staticSeed = 1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected I4, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if ((int)seedType == 0) { EOSLogger.Error($"SelectTerminal: unsupported seed type {seedType}"); return null; } List<LG_ComputerTerminal> list = FindTerminal(dimensionIndex, layerType, localIndex, (LG_ComputerTerminal x) => !x.HasPasswordPart); if (list == null) { EOSLogger.Error($"SelectTerminal: Could not find zone {(dimensionIndex, layerType, localIndex)}!"); return null; } if (list.Count <= 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals without a password part in zone {(dimensionIndex, layerType, localIndex)}, putting the password on random (session) already used terminal."); LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val); return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")]; } switch (seedType - 1) { case 0: return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")]; case 1: return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")]; case 2: Random.InitState(staticSeed); return list[Random.Range(0, list.Count)]; default: EOSLogger.Error("SelectTerminal: did not have a valid SeedType!!"); return null; } } public static void BuildPassword(LG_ComputerTerminal terminal, TerminalPasswordData data) { //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: 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) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Expected O, but got Unknown //IL_04ce: Expected O, but got Unknown if (!data.PasswordProtected) { return; } if (terminal.IsPasswordProtected) { EOSLogger.Error("EOSTerminalUtils.BuildPassword: " + terminal.PublicName + " is already password-protected!"); return; } if (!data.GeneratePassword) { terminal.LockWithPassword(data.Password, new string[1] { data.PasswordHintText }); return; } if (data.TerminalZoneSelectionDatas.Count <= 0) { EOSLogger.Error($"Tried to generate a password for terminal {terminal.PublicName} with no {typeof(TerminalZoneSelectionData).Name}!! This is not allowed."); return; } string codeWord = SerialGenerator.GetCodeWord(); string passwordHintText = data.PasswordHintText; string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on "; int num = data.PasswordPartCount; if (codeWord.Length % num != 0) { EOSLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({num}). Defaulting to 1."); num = 1; } string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord }); string text2 = ""; if (data.ShowPasswordPartPositions) { for (int i = 0; i < array[0].Length; i++) { text2 += "-"; } } HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>(); LG_Zone val = default(LG_Zone); for (int j = 0; j < num; j++) { int index = j % data.TerminalZoneSelectionDatas.Count; List<CustomTerminalZoneSelectionData> list = data.TerminalZoneSelectionDatas[index]; int index2 = Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG"); CustomTerminalZoneSelectionData customTerminalZoneSelectionData = list[index2]; LG_ComputerTerminal val2; if ((int)customTerminalZoneSelectionData.SeedType == 0) { if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } if (val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find terminal zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } val2 = val.TerminalsSpawnedInZone[customTerminalZoneSelectionData.TerminalIndex]; } else { val2 = SelectPasswordTerminal(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, customTerminalZoneSelectionData.SeedType); } if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"BuildPassword: CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log."); continue; } string text3 = ""; string text4; if (data.ShowPasswordPartPositions) { for (int k = 0; k < j; k++) { text3 += text2; } text4 = text3 + array[j]; for (int l = j; l < num - 1; l++) { text4 += text2; } } else { text4 = array[j]; } string value = (data.ShowPasswordPartPositions ? $"0{j + 1}" : $"0{Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")}"); TerminalLogFileData val3 = new TerminalLogFileData { FileName = $"key{value}_{LG_TerminalPasswordLinkerJob.GetTerminalNumber(terminal)}{(val2.HasPasswordPart ? "_1" : "")}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get((num > 1) ? 1431221909u : 2260297836u), text4), Id = 0u } }; val2.AddLocalLog(val3, true); if (!hashSet.Contains(val2)) { if (j > 0) { text += ", "; } text = text + val2.PublicName + " in " + val2.SpawnNode.m_zone.AliasName; } hashSet.Add(val2); val2.HasPasswordPart = true; } string text5 = text + "."; if (data.ShowPasswordLength) { terminal.LockWithPassword(codeWord, new string[3] { passwordHintText, text5, "Char[" + codeWord.Length + "]" }); } else { terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text5 }); } } public static void AddUniqueCommand(LG_ComputerTerminal terminal, CustomCommand cmd) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if (terminal.m_command.m_commandsPerString.ContainsKey(cmd.Command)) { EOSLogger.Error("Duplicate command name: '" + cmd.Command + "', cannot add command"); return; } TERM_Command val = default(TERM_Command); if (!terminal.m_command.TryGetUniqueCommandSlot(ref val)) { EOSLogger.Error("Cannot get more unique command slot, max: 5"); return; } terminal.m_command.AddCommand(val, cmd.Command, cmd.CommandDesc, cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(cmd.PostCommandOutputs)); for (int i = 0; i < cmd.CommandEvents.Count; i++) { WardenObjectiveEventData val2 = cmd.CommandEvents[i]; if (val2.ChainPuzzle == 0) { continue; } ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle); if (block != null) { ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.SpawnNode.m_area, terminal.m_wardenObjectiveSecurityScanAlign.position, terminal.m_wardenObjectiveSecurityScanAlign, val2.UseStaticBioscanPoints); List<WardenObjectiveEventData> events = ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents.GetRange(i, cmd.CommandEvents.Count - i)); val3.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); }); terminal.SetChainPuzzleForCommand(val, i, val3); } } } } public static class Helper { } public class Vec3 { public float x { get; set; } public float y { get; set; } public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } public Quaternion ToQuaternion() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(x, y, z); } } public static class EOSLogger { private static ManualLogSource logger = Logger.CreateLogSource("ExtraObjectiveSetup"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } } namespace ExtraObjectiveSetup.Tweaks.TerminalPosition { public class TerminalPosition : BaseInstanceDefinition { public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); } internal class TerminalPositionOverrideManager : InstanceDefinitionManager<TerminalPosition> { public static TerminalPositionOverrideManager Current; protected override string DEFINITION_NAME => "TerminalPosition"; private TerminalPositionOverrideManager() { } static TerminalPositionOverrideManager() { Current = new TerminalPositionOverrideManager(); } } } namespace ExtraObjectiveSetup.Tweaks.Scout { public class EventsOnZoneScoutScream : GlobalZoneIndex { public bool SuppressVanillaScoutWave { get; set; } public List<WardenObjectiveEventData> EventsOnScoutScream { get; set; } = new List<WardenObjectiveEventData>(); } internal class ScoutScreamEventManager : ZoneDefinitionManager<EventsOnZoneScoutScream> { public static ScoutScreamEventManager Current; protected override string DEFINITION_NAME => "EventsOnScoutScream"; private ScoutScreamEventManager() { } static ScoutScreamEventManager() { Current = new ScoutScreamEventManager(); } } } namespace ExtraObjectiveSetup.Tweaks.BossEvents { public class EventsOnZoneBossDeath : GlobalZoneIndex { public bool ApplyToHibernate { get; set; } = true; public int ApplyToHibernateCount { get; set; } = int.MaxValue; public bool ApplyToWave { get; set; } public int ApplyToWaveCount { get; set; } = int.MaxValue; public List<uint> BossIDs { get; set; } = new List<uint> { 29u, 36u, 37u }; public List<WardenObjectiveEventData> EventsOnBossDeath { get; set; } = new List<WardenObjectiveEventData>(); } internal class BossDeathEventManager : ZoneDefinitionManager<EventsOnZoneBossDeath> { public enum Mode { HIBERNATE, WAVE } public static BossDeathEventManager Current; private ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode), int> InLevelBDEventsExecution = new ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode), int>(); protected override string DEFINITION_NAME => "EventsOnBossDeath"; public void RegisterInLevelBDEventsExecution(EventsOnZoneBossDeath def, Mode mode) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) (eDimensionIndex, LG_LayerType, eLocalZoneIndex, Mode) key = (def.DimensionIndex, def.LayerType, def.LocalIndex, mode); if (!InLevelBDEventsExecution.ContainsKey(key)) { switch (mode) { case Mode.HIBERNATE: InLevelBDEventsExecution[key] = def.ApplyToHibernateCount; return; case Mode.WAVE: InLevelBDEventsExecution[key] = def.ApplyToWaveCount; return; } EOSLogger.Error($"BossDeathEventManager.RegisterInLevelBDEventsExecution: unimplemented mode: {mode}"); } } public bool TryConsumeBDEventsExecutionTimes(EventsOnZoneBossDeath def, Mode mode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) return TryConsumeBDEventsExecutionTimes(def.DimensionIndex, def.LayerType, def.LocalIndex, mode); } public bool TryConsumeBDEventsExecutionTimes(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, Mode mode) { //IL_0006: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!InLevelBDEventsExecution.ContainsKey((dimensionIndex, layer, localIndex, mode))) { EOSLogger.Error($"BossDeathEventManager: got an unregistered entry: {(dimensionIndex, layer, localIndex, mode)}"); return false; } int num = InLevelBDEventsExecution[(dimensionIndex, layer, localIndex, mode)]; if (num == int.MaxValue) { return true; } if (num > 0) { InLevelBDEventsExecution[(dimensionIndex, layer, localIndex, mode)] = num - 1; return true; } return false; } private void Clear() { InLevelBDEventsExecution.Clear(); } private BossDeathEventManager() { LevelAPI.OnLevelCleanup += Clear; } static BossDeathEventManager() { Current = new BossDeathEventManager(); } } } namespace ExtraObjectiveSetup.Patches { [HarmonyPatch] internal class Patch_CheckAndExecuteEventsOnTrigger { [HarmonyPrefix] [HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[] { typeof(WardenObjectiveEventData), typeof(eWardenObjectiveEventTrigger), typeof(bool), typeof(float) })] private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration)) { return true; } uint num = (uint)(int)eventToTrigger.Type; if (!EOSWardenEventManager.Current.HasEventDefinition(num)) { return true; } string value = (EOSWardenEventManager.Current.IsVanillaEventID(num) ? "overriding vanilla event implementation..." : "executing..."); EOSLogger.Debug($"WardenEvent: found definition for event ID {num}, {value}"); EOSWardenEventManager.Current.ExecuteEvent(eventToTrigger, currentDuration); return false; } } [HarmonyPatch] internal class Patch_EventsOnBossDeath { private static HashSet<ushort> ExecutedForInstances; [HarmonyPostfix] [HarmonyPatch(typeof(EnemySync), "OnSpawn")] private static void Post_SpawnEnemy(EnemySync __instance, pEnemySpawnData spawnData) { //IL_0034: 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) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Invalid comparison between Unknown and I4 //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode val = null; if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref val) || val == null) { EOSLogger.Error("Failed to get spawnnode for a boss! Skipped EventsOnBossDeath for it"); return; } LG_Zone zone = val.m_zone; EventsOnZoneBossDeath def = BossDeathEventManager.Current.GetDefinition(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex); if (def == null) { return; } EnemyAgent enemy = __instance.m_agent; if (!def.BossIDs.Contains(((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID) || (((int)spawnData.mode != 4 || !def.ApplyToHibernate) && ((int)spawnData.mode != 1 || !def.ApplyToWave))) { return; } BossDeathEventManager.Mode mode = (((int)spawnData.mode != 4) ? BossDeathEventManager.Mode.WAVE : BossDeathEventManager.Mode.HIBERNATE); BossDeathEventManager.Current.RegisterInLevelBDEventsExecution(def, mode); if (!BossDeathEventManager.Current.TryConsumeBDEventsExecutionTimes(def, mode)) { EOSLogger.Debug($"EventsOnBossDeath: execution times depleted for {def.GlobalZoneIndexTuple()}, {mode}"); return; } enemy.OnDeadCallback += Action.op_Implicit((Action)delegate { ushort globalID = ((Agent)enemy).GlobalID; if (ExecutedForInstances.Contains(globalID)) { ExecutedForInstances.Remove(globalID); } else { def.EventsOnBossDeath.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); ExecutedForInstances.Add(globalID); } }); EOSLogger.Debug($"EventsOnBossDeath: added for enemy with id {((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID}, mode: {spawnData.mode}"); } static Patch_EventsOnBossDeath() { ExecutedForInstances = new HashSet<ushort>(); LevelAPI.OnLevelCleanup += ExecutedForInstances.Clear; } } [HarmonyPatch] internal class Patch_EventsOnZoneScoutScream { [HarmonyPrefix] [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] private static bool Pre_ES_ScoutScream_CommonUpdate(ES_ScoutScream __instance) { //IL_0017: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode courseNode = ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode; EventsOnZoneScoutScream definition = ScoutScreamEventManager.Current.GetDefinition(courseNode.m_dimension.DimensionIndex, courseNode.LayerType, courseNode.m_zone.LocalIndex); if (definition == null) { return true; } if ((int)__instance.m_state != 3 || __instance.m_stateDoneTimer >= Clock.Time) { return true; } if (definition.EventsOnScoutScream != null && definition.EventsOnScoutScream.Count > 0) { EOSLogger.Debug($"EventsOnZoneScoutScream: found config for {definition.GlobalZoneIndexTuple()}, executing events."); definition.EventsOnScoutScream.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } if (!definition.SuppressVanillaScoutWave) { if (SNet.IsMaster && ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode != null) { if (RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings != 0 && RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation != 0) { ushort num = default(ushort); Mastermind.Current.TriggerSurvivalWave(((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode, RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings, RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation, ref num, (SurvivalWaveSpawnType)0, 0f, 2f, true, false, default(Vector3), ""); } else { Debug.LogError(Object.op_Implicit("ES_ScoutScream, a scout is screaming but we can't spawn a wave because the the scout settings are not set for this expedition! ScoutWaveSettings: " + RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings + " ScoutWavePopulation: " + RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation)); } } } else { EOSLogger.Debug("Vanilla scout wave suppressed."); } if (SNet.IsMaster) { ((ES_Base)__instance).m_enemyAgent.AI.m_behaviour.ChangeState((EB_States)5); } ((MachineState<ES_Base>)(object)__instance).m_machine.ChangeState(2); __instance.m_state = (ScoutScreamState)4; return false; } } [HarmonyPatch] internal class Patch_LG_ComputerTerminal_Setup { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminal), "Setup")] private static void Post_LG_ComputerTerminal_Setup(LG_ComputerTerminal __instance) { //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_008e: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) uint instanceIndex = TerminalInstanceManager.Current.Register(__instance); if (__instance.SpawnNode == null) { return; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance); TerminalPosition definition = TerminalPositionOverrideManager.Current.GetDefinition(globalZoneIndex, instanceIndex); if (definition != null) { if (definition.Position.ToVector3() != Vector3.zeroVector) { ((Component)__instance).transform.position = definition.Position.ToVector3(); ((Component)__instance).transform.rotation = definition.Rotation.ToQuaternion(); } EOSLogger.Debug($"TerminalPositionOverride: {definition.LocalIndex}, {definition.LayerType}, {definition.DimensionIndex}, TerminalIndex {definition.InstanceIndex}"); } } } [HarmonyPatch] internal class Patch_LG_PowerGeneratorCluster { [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGeneratorCluster), "Setup")] private static void Post_PowerGeneratorCluster_Setup(LG_PowerGeneratorCluster __instance) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 uint instanceIndex = GeneratorClusterInstanceManager.Current.Register(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = GeneratorClusterInstanceManager.Current.GetGlobalZoneIndex(__instance); GeneratorClusterDefinition def = GeneratorClusterObjectiveManager.Current.GetDefinition(globalZoneIndex, instanceIndex); if (def == null) { return; } if ((int)WardenObjectiveManager.Current.m_activeWardenObjectives[__instance.SpawnNode.LayerType].Type == 9) { EOSLogger.Error("Found built Warden Objective LG_PowerGeneratorCluster but there's also a config for it! Won't apply this config"); EOSLogger.Error($"{globalZoneIndex}"); return; } EOSLogger.Debug("Found LG_PowerGeneratorCluster and its definition! Building this Generator cluster..."); __instance.m_serialNumber = SerialGenerator.GetUniqueSerialNo(); __instance.m_itemKey = "GENERATOR_CLUSTER_" + __instance.m_serialNumber; __instance.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(__instance.m_terminalItemComp); __instance.m_terminalItem.Setup(__instance.m_itemKey, (AIG_CourseNode)null); __instance.m_terminalItem.FloorItemStatus = (eFloorInventoryObjectStatus)4; if (__instance.SpawnNode != null) { __instance.m_terminalItem.FloorItemLocation = __instance.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7); } List<Transform> list = new List<Transform>((IEnumerable<Transform>)__instance.m_generatorAligns); uint numberOfGenerators = def.NumberOfGenerators; __instance.m_generators = Il2CppReferenceArray<LG_PowerGenerator_Core>.op_Implicit((LG_PowerGenerator_Core[])(object)new LG_PowerGenerator_Core[numberOfGenerators]); if (list.Count >= numberOfGenerators) { for (int i = 0; i < numberOfGenerators; i++) { int index = Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG"); LG_PowerGenerator_Core val = GOUtil.SpawnChildAndGetComp<LG_PowerGenerator_Core>(__instance.m_generatorPrefab, list[index]); ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators)[i] = val; val.SpawnNode = __instance.SpawnNode; PowerGeneratorInstanceManager.Current.MarkAsGCGenerator(val); val.Setup(); val.SetCanTakePowerCell(true); val.OnSyncStatusChanged += Action<ePowerGeneratorStatus>.op_Implicit((Action<ePowerGeneratorStatus>)delegate(ePowerGeneratorStatus status) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Debug.Log(Object.op_Implicit("LG_PowerGeneratorCluster.powerGenerator.OnSyncStatusChanged! status: " + ((object)(ePowerGeneratorStatus)(ref status)).ToString())); if ((int)status == 0) { uint num = 0u; for (int j = 0; j < ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Length; j++) { if ((int)((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators)[j].m_stateReplicator.State.status == 0) { num++; } } EOSLogger.Log($"Generator Cluster PowerCell inserted ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count})"); List<List<WardenObjectiveEventData>> eventsOnInsertCell = def.EventsOnInsertCell; int num2 = (int)(num - 1); if (num2 >= 0 && num2 < eventsOnInsertCell.Count) { EOSLogger.Log($"Executing events ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count}). Event count: {eventsOnInsertCell[num2].Count}"); eventsOnInsertCell[num2].ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } if (num == ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators).Count && !__instance.m_endSequenceTriggered) { EOSLogger.Log("All generators powered, executing end sequence"); ((MonoBehaviour)__instance).StartCoroutine(__instance.ObjectiveEndSequence()); __instance.m_endSequenceTriggered = true; } } }); Debug.Log(Object.op_Implicit("Spawning generator at alignIndex: " + index)); list.RemoveAt(index); } } else { Debug.LogError(Object.op_Implicit("LG_PowerGeneratorCluster does NOT have enough generator aligns to support the warden objective! Has " + list.Count + " needs " + numberOfGenerators)); } __instance.ObjectiveItemSolved = true; if (def.EndSequenceChainedPuzzle != 0) { GeneratorClusterObjectiveManager.Current.RegisterForChainedPuzzleBuild(__instance, def); } } } [HarmonyPatch] internal class Patch_LG_PowerGenerator_Core { [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGenerator_Core), "Setup")] private static void Post_PowerGenerator_Setup(LG_PowerGenerator_Core __instance) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (PowerGeneratorInstanceManager.Current.IsGCGenerator(__instance)) { return; } uint num = PowerGeneratorInstanceManager.Current.Register(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = PowerGeneratorInstanceManager.Current.GetGlobalZoneIndex(__instance); IndividualGeneratorDefinition def = IndividualGeneratorObjectiveManager.Current.GetDefinition(globalZoneIndex, num); if (def == null) { return; } Vector3 val = def.Position.ToVector3(); Quaternion rotation = def.Rotation.ToQuaternion(); if (val != Vector3.zero) { ((Component)__instance).transform.position = val; ((Component)__instance).transform.rotation = rotation; __instance.m_sound.UpdatePosition(val); EOSLogger.Debug("LG_PowerGenerator_Core: modified position / rotation"); } if (def.ForceAllowPowerCellInsertion) { __instance.SetCanTakePowerCell(true); } List<WardenObjectiveEventData> eventsOnInsertCell = def.EventsOnInsertCell; if (eventsOnInsertCell != null && eventsOnInsertCell.Count > 0) { __instance.OnSyncStatusChanged += Action<ePowerGeneratorStatus>.op_Implicit((Action<ePowerGeneratorStatus>)delegate(ePowerGeneratorStatus status) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)status == 0) { def.EventsOnInsertCell.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } }); } EOSLogger.Debug($"LG_PowerGenerator_Core: overriden, instance {num} in {globalZoneIndex}"); } } } namespace ExtraObjectiveSetup.Patches.Uplink { [HarmonyPatch] internal class CorruptedUplinkConfirm { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConfirm")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConfirm(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal receiver = __instance.m_terminal; LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver; if ((Object)(object)sender == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConfirm() critical failure because terminal does not have a CorruptedUplinkReceiver (sender)."); __result = false; return false; } if (sender.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender); UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); receiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(2816126705u), sender.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); if ((Object)(object)sender.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = sender.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = 0 }); }); sender.m_command.AddOutput("", true); sender.m_command.AddOutput(Text.Get(3268596368u), true); sender.m_command.AddOutput(Text.Get(2277987284u), true); receiver.m_command.AddOutput("", true); receiver.m_command.AddOutput(Text.Get(3268596368u), true); receiver.m_command.AddOutput(Text.Get(2277987284u), true); if (SNet.IsMaster) { sender.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = 0 }); } __result = true; return false; } } [HarmonyPatch] internal class CorruptedUplinkConnect { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConnect")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } __result = false; LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver; if ((Object)(object)corruptedUplinkReceiver == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConnect() critical failure because terminal does not have a CorruptedUplinkReceiver."); return false; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); __result = false; return false; } LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = terminal.SyncID; (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition.UseUplinkAddress) { param1 = param1.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, param1: " + param1 + ", TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } else { param1 = terminal.UplinkPuzzle.TerminalUplinkIP.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, not using uplink address, TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } if (!definition.UseUplinkAddress || param1 == terminal.UplinkPuzzle.TerminalUplinkIP) { if (corruptedUplinkReceiver.m_command.HasRegisteredCommand((TERM_Command)27)) { terminal.m_command.AddUplinkCorruptedOutput(); } else { terminal.m_command.AddUplinkCorruptedOutput(); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(3492863045u), corruptedUplinkReceiver.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(2761366063u), 0.6f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(3435969025u), 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); corruptedUplinkReceiver.m_command.AddCommand((TERM_Command)27, "UPLINK_CONFIRM", new LocalizedText { UntranslatedText = Text.Get(112719254u), Id = 0u }, (TERM_CommandRule)2); corruptedUplinkReceiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(1173595354u), terminal.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } } else { terminal.m_command.AddUplinkWrongAddressError(param1); } return false; } } [HarmonyPatch] internal class StartTerminalUplinkSequence { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "StartTerminalUplinkSequence")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_StartTerminalUplinkSequence(LG_ComputerTerminalCommandInterpreter __instance, string uplinkIp, bool corrupted) { if (!corrupted) { LG_ComputerTerminal uplinkTerminal = __instance.m_terminal; if (uplinkTerminal.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(uplinkTerminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(uplinkTerminal); UplinkDefinition uplinkConfig = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); uplinkTerminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2583360288u), uplinkIp), 3f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.TerminalUplinkSequenceOutputs(uplinkTerminal, false); uplinkTerminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Debug("UPLINK CONNECTION DONE!"); uplinkTerminal.UplinkPuzzle.Connected = true; uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = true; uplinkTerminal.UplinkPuzzle.OnStartSequence(); uplinkConfig.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); int num2 = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); ((num2 != -1) ? uplinkConfig.RoundOverrides[num2] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); }); } else { LG_ComputerTerminal terminal = __instance.m_terminal; LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver; if (sender.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex2 = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender); uint zoneInstanceIndex2 = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender); UplinkDefinition uplinkConfig2 = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex2, zoneInstanceIndex2); sender.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); sender.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); terminal.m_command.TerminalUplinkSequenceOutputs(sender, false); terminal.m_command.TerminalUplinkSequenceOutputs(terminal, true); terminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Debug("UPLINK CONNECTION DONE!"); sender.UplinkPuzzle.Connected = true; sender.UplinkPuzzle.CurrentRound.ShowGui = true; sender.UplinkPuzzle.OnStartSequence(); uplinkConfig2.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); int num = uplinkConfig2.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); ((num != -1) ? uplinkConfig2.RoundOverrides[num] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); }); } return false; } } [HarmonyPatch] internal class TerminalUplinkConnect { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkConnect")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); return false; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (!definition.UseUplinkAddress) { param1 = __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP; } if (!definition.UseUplinkAddress || param1 == __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP) { __instance.m_terminal.TrySyncSetCommandRule((TERM_Command)25, (TERM_CommandRule)1); if ((Object)(object)__instance.m_terminal.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = __instance.m_terminal.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.StartTerminalUplinkSequence(param1, false); }); __instance.AddOutput("", true); __instance.AddOutput(Text.Get(3268596368u), true); __instance.AddOutput(Text.Get(3041541194u), true); if (SNet.IsMaster) { __instance.m_terminal.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.StartTerminalUplinkSequence(param1, false); } __result = true; } else { __instance.AddUplinkWrongAddressError(param1); __result = false; } return false; } } [HarmonyPatch] internal class TerminalUplinkSequenceOutput { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkSequenceOutputs")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkSequenceOutputs(LG_ComputerTerminal terminal, bool corrupted) { if (terminal.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { if (!((Object)(object)terminal.CorruptedUplinkReceiver != (Object)null)) { return true; } LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver; globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(corruptedUplinkReceiver); zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(corruptedUplinkReceiver); definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null || definition.DisplayUplinkWarning) { return true; } } terminal.m_command.AddOutput((TerminalLineType)3, Text.Get(3418104670u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); if (!corrupted) { terminal.m_command.AddOutput(string.Format(Text.Get(947485599u), terminal.UplinkPuzzle.CurrentRound.CorrectPrefix), true); } return false; } } [HarmonyPatch] internal class TerminalUplinkVerify { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkVerify")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { if (__instance.m_terminal.m_isWardenObjective) { return true; } TerminalUplinkPuzzle uplinkPuzzle = __instance.m_terminal.UplinkPuzzle; (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(__instance.m_terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); int CurrentRoundIndex = uplinkPuzzle.m_roundIndex; int num = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == CurrentRoundIndex); UplinkRound roundOverride = ((num != -1) ? definition.RoundOverrides[num] : null); TimeSettings timeSettings = ((num != -1) ? roundOverride.OverrideTimeSettings : definition.DefaultTimeSettings); float num2 = ((timeSettings.TimeToStartVerify >= 0f) ? timeSettings.TimeToStartVerify : definition.DefaultTimeSettings.TimeToStartVerify); float timeToCompleteVerify = ((timeSettings.TimeToCompleteVerify >= 0f) ? timeSettings.TimeToCompleteVerify : definition.DefaultTimeSettings.TimeToCompleteVerify); float num3 = ((timeSettings.TimeToRestoreFromFail >= 0f) ? timeSettings.TimeToRestoreFromFail : definition.DefaultTimeSettings.TimeToRestoreFromFail); if (uplinkPuzzle.Connected) { __instance.AddOutput((TerminalLineType)3, Text.Get(2734004688u), num2, (TerminalSoundType)0, (TerminalSoundType)0); if (!uplinkPuzzle.Solved && uplinkPuzzle.CurrentRound.CorrectCode.ToUpper() == param1.ToUpper()) { __instance.AddOutput(string.Format(Text.Get(1221800228u), uplinkPuzzle.CurrentProgress), true); if (uplinkPuzzle.TryGoToNextRound()) { int newRoundIndex = uplinkPuzzle.m_roundIndex; int num4 = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == newRoundIndex); UplinkRound newRoundOverride = ((num4 != -1) ? definition.RoundOverrides[num4] : null); roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f); }); if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.UplinkTerminal.ScanRequiredToProgress"); if (block != null) { __instance.AddOutput((TerminalLineType)4, Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } ChainedPuzzleInstance chainedPuzzleToEndRoundInstance = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!"); uplinkPuzzle.CurrentRound.ShowGui = true; newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!"); uplinkPuzzle.CurrentRound.ShowGui = true; newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); } } else { __instance.AddOutput((TerminalLineType)3, Text.Get(1780488547u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f); }); uplinkPuzzle.CurrentRound.ShowGui = false; if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { ChainedPuzzleInstance chainedPuzzleToEndRoundInstance2 = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance2.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!"); LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u; uplinkPuzzle.Solved = true; Action onPuzzleSolved2 = uplinkPuzzle.OnPuzzleSolved; if (onPuzzleSolved2 != null) { onPuzzleSolved2.Invoke(); } UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.Finished, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!"); LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u; uplinkPuzzle.Solved = true; Action onPuzzleSolved = uplinkPuzzle.OnPuzzleSolved; if (onPuzzleSolved != null) { onPuzzleSolved.Invoke(); } UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.Finished, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); } }); } } else if (uplinkPuzzle.Solved) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, Text.Get(4080876165u), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), 6f, (TerminalSoundType)0, (TerminalSoundType)0); } else { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, string.Format(Text.Get(507647514u), uplinkPuzzle.CurrentRound.CorrectPrefix), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), num3, (TerminalSoundType)0, (TerminalSoundType)0); } } else { __instance.AddOutput("", true); __instance.AddOutput(Text.Get(403360908u), true); } __result = false; return false; } } [HarmonyPatch] internal class UplinkGUI_Update { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminal), "Update")] private static void Post_LG_ComputerTerminal_Update(LG_ComputerTerminal __instance) { if (!__instance.m_isWardenObjective && __instance.UplinkPuzzle != null) { __instance.UplinkPuzzle.UpdateGUI(false); } } } } namespace ExtraObjectiveSetup.Patches.LGFactory { [HarmonyPatch] internal class Patch_LG_Factory_NextBatch { [HarmonyPostfix] [HarmonyPatch(typeof(LG_Factory), "NextBatch")] private static void Post_LG_Factory_NextBatch(LG_Factory __instance) { //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_0025: 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) int num = __instance.m_batchStep - 1; if (num >= 0) { BatchName batchName = ((Il2CppArrayBase<LG_FactoryBatch>)(object)__instance.m_batches)[num].m_batchName; Action action = BatchBuildManager.Current.Get_OnBatchDone(batchName); if (action != null) { EOSLogger.Warning($"On Batch '{batchName}' Done: {action.GetInvocationList().Length} injected jobs"); action(); } } } } } namespace ExtraObjectiveSetup.Patches.HSUActivator { [HarmonyPatch] internal class SetupFromCustomGeomorph { [HarmonyPostfix] [HarmonyPatch(typeof(LG_HSUActivator_Core), "SetupFromCustomGeomorph")] private static void Post_LG_HSUActivator_Core_SetupFromCustomGeomorph(LG_HSUActivator_Core __instance) { //IL_0034: 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_0059: 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) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) uint instanceIndex = HSUActivatorInstanceManager.Current.Register(__instance); HSUActivatorDefinition def = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, instanceIndex); if (def == null) { return; } if (__instance.m_isWardenObjective) { EOSLogger.Error("BuildCustomHSUActivator: the HSUActivator has been set up by vanilla! Aborting custom setup..."); EOSLogger.Error($"HSUActivator in {__instance.SpawnNode.m_zone.LocalIndex}, {__instance.SpawnNode.LayerType}, {__instance.SpawnNode.m_dimension.DimensionIndex}"); return; } __instance.m_linkedItemGoingIn = __instance.SpawnPickupItemOnAlign(def.ItemFromStart, __instance.m_itemGoingInAlign, false, -1); __instance.m_linkedItemComingOut = __instance.SpawnPickupItemOnAlign(def.ItemAfterActivation, __instance.m_itemComingOutAlign, false, -1); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemGoingIn).GetComponentInChildren<iTerminalItem>()); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemComingOut).GetComponentInChildren<iTerminalItem>()); __instance.m_linkedItemGoingIn.SetPickupInteractionEnabled(false); __instance.m_linkedItemComingOut.SetPickupInteractionEnabled(false); __instance.m_insertHSUInteraction.OnInteractionSelected = Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)delegate { }); __instance.m_sequencerInsertItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //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_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) pHSUActivatorState state2 = __instance.m_stateReplicator.State; if (!state2.isSequenceIncomplete) { EOSLogger.Error(">>>>>> HSUInsertSequenceDone! Sequence was already complete"); } state2.isSequenceIncomplete = false; __instance.m_stateReplicator.SetStateUnsynced(state2); EOSLogger.Error(">>>>>> HSUInsertSequenceDone!"); if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } ChainedPuzzleInstance chainedPuzzleOnActivationInstance = def.ChainedPuzzleOnActivationInstance; if ((Object)(object)chainedPuzzleOnActivationInstance == (Object)null) { if (def.TakeOutItemAfterActivation) { __instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)__instance).StartCoroutine(__instance.TriggerRemoveSequence()); } } else { chainedPuzzleOnActivationInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (def.TakeOutItemAfterActivation) { __instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)__instance).StartCoroutine(__instance.TriggerRemoveSequence()); } def.EventsOnActivationScanSolved.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); }); if (SNet.IsMaster) { chainedPuzzleOnActivationInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } }); __instance.m_sequencerExtractItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) SNet_StateReplicator<pHSUActivatorState, pHSUActivatorInteraction> stateReplicator = __instance.m_stateReplicator; pHSUActivatorState state = __instance.m_stateReplicator.State; state.isSequenceIncomplete = true; stateReplicator.SetStateUnsynced(state); if (SNet.IsMaster) { __instance.AttemptInteract(new pHSUActivatorInteraction { type = (eHSUActivatorInteractionType)2 }); } }); EOSLogger.Debug($"HSUActivator: {(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex)}, custom setup complete"); } } [HarmonyPatch] internal class SyncStatusChanged { [HarmonyPrefix] [HarmonyPatch(typeof(LG_HSUActivator_Core), "SyncStatusChanged")] private static bool Pre_LG_HSUActivator_Core_SyncStatusChanged(LG_HSUActivator_Core __instance, ref pHSUActivatorState newState, bool isRecall) { //IL_0060: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected I4, but got Unknown if (__instance.m_isWardenObjective) { return true; } uint zoneInstanceIndex = HSUActivatorInstanceManager.Current.GetZoneInstanceIndex(__instance); if (zoneInstanceIndex == uint.MaxValue) { EOSLogger.Error($"Found unregistered HSUActivator!! {HSUActivatorInstanceManager.Current.GetGlobalZoneIndex(__instance)}"); return true; } HSUActivatorDefinition definition = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, zoneInstanceIndex); if (definition == null) { return true; } if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } bool goingInVisibleForPostCulling = __instance.m_goingInVisibleForPostCulling; bool comingOutVisibleForPostCulling = __instance.m_comingOutVisibleForPostCulling; EOSLogger.Debug("LG_HSUActivator_Core.OnSyncStatusChanged " + ((object)(eHSUActivatorStatus)(ref newState.status)).ToString()); eHSUActivatorStatus status = newState.status; switch ((int)status) { case 0: __instance.m_insertHSUInteraction.SetActive(true); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, false, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StartSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 1: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, true, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); __instance.m_sequencerInsertItem.StartSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StopSequence(); definition?.EventsOnHSUActivation.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; case 2: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StartSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 3: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, definition.TakeOutItemAfterActivation, false, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StartSequence(); if (newState.isSequenceIncomplete) { __instance.HSUInsertSequenceDone(); } break; } return false; } } } namespace ExtraObjectiveSetup.Patches.Expedition { [HarmonyPatch] internal class GearManager_LoadOfflineGearDatas { [HarmonyPostfix] [HarmonyPatch(typeof(GearManager), "LoadOfflineGearDatas")] private static void Post_GearManager_LoadOfflineGearDatas(GearManager __instance) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown ExpeditionGearManager.Current.vanillaGearManager = __instance; foreach (var gearSlot in ExpeditionGearManager.Current.gearSlots) { Enumerator<GearIDRange> enumerator2 = ((Il2CppArrayBase<List<GearIDRange>>)(object)__instance.m_gearPerSlot)[(int)gearSlot.inventorySlot].GetEnumerator(); while (enumerator2.MoveNext()) { GearIDRange current2 = enumerator2.Current; uint offlineGearPID = ExpeditionGearManager.GetOfflineGearPID(current2); gearSlot.loadedGears.Add(offlineGearPID, current2); } } } } [HarmonyPatch] internal class RundownManager_SetActiveExpedition { [HarmonyPostfix] [HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")] private static void Post_RundownManager_SetActiveExpedition(RundownManager __instance, pActiveExpedition expPackage, ExpeditionInTierData expTierData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)expPackage.tier != 99) { ExpeditionGearManager.Current.SetupAllowedGearsForActiveExpedition(); } } } } namespace ExtraObjectiveSetup.Instances { public sealed class HSUActivatorInstanceManager : InstanceManager<LG_HSUActivator_Core> { public static HSUActivatorInstanceManager Current { get; private set; } public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_HSUActivator_Core instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } private HSUActivatorInstanceManager() { } static HSUActivatorInstanceManager() { Current = new HSUActivatorInstanceManager(); } } public sealed class GeneratorClusterInstanceManager : InstanceManager<LG_PowerGeneratorCluster> { public static GeneratorClusterInstanceManager Current { get; private set; } public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_PowerGeneratorCluster instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } static GeneratorClusterInstanceManager() { Current = new GeneratorClusterInstanceManager(); } } public sealed class PowerGeneratorInstanceManager : InstanceManager<LG_PowerGenerator_Core> { private HashSet<IntPtr> gcGenerators = new HashSet<IntPtr>(); public static PowerGeneratorInstanceManager Current { get; private set; } public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_PowerGenerator_Core instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } public override uint Register((eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex, LG_PowerGenerator_Core instance) { if (gcGenerators.Contains(((Il2CppObjectBase)instance).Pointer)) { EOSLogger.Error("PowerGeneratorInstanceManager: Trying to register a GC Generator, which is an invalid operation"); return uint.MaxValue; } return base.Register(globalZoneIndex, instance); } public void MarkAsGCGenerator(LG_PowerGenerator_Core instance) { if (IsRegistered(instance)) { EOSLogger.Error("PowerGeneratorInstanceManager: Trying to mark a registered Generator as GC Generator, which is an invalid operation"); } else { gcGenerators.Add(((Il2CppObjectBase)instance).Pointer); } } public bool IsGCGenerator(LG_PowerGenerator_Core instance) { return gcGenerators.Contains(((Il2CppObjectBase)instance).Pointer); } private void OutputLevelInstanceInfo() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(); foreach (var item in RegisteredZones()) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 3, stringBuilder2); handler.AppendFormatted<eLocalZoneIndex>(item.zone); handler.AppendLiteral(", "); handler.AppendFormatted<LG_LayerType>(item.layer); handler.AppendLiteral(", Dim "); handler.AppendFormatted<eDimensionIndex>(item.dim); stringBuilder3.AppendLine(ref handler); List<LG_PowerGenerator_Core> instancesInZone = GetInstancesInZone(item); for (int i = 0; i < instancesInZone.Count; i++) { LG_PowerGenerator_Core val = instancesInZone[i]; stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(28, 2, stringBuilder2); handler.AppendLiteral("GENERATOR_"); handler.AppendFormatted(val.m_serialNumber); handler.AppendLiteral(". Instance index: "); handler.AppendFormatted(i); stringBuilder4.AppendLine(ref handler); } stringBuilder.AppendLine(); } if (!string.IsNullOrWhiteSpace(stringBuilder.ToString())) { EOSLogger.Debug(stringBuilder.ToString()); } } private void Clear() { gcGenerators.Clear(); } private PowerGeneratorInstanceManager() { LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnEnterLevel += OutputLevelInstanceInfo; } static PowerGeneratorInstanceManager() { Current = new PowerGeneratorInstanceManager(); } } public sealed class TerminalInstanceManager : InstanceManager<LG_ComputerTerminal> { public static TerminalInstanceManager Current { get; private set; } public override (eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex zone) GetGlobalZoneIndex(LG_ComputerTerminal instance) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (instance.SpawnNode == null) { throw new ArgumentException("LG_ComputerTerminal.SpawnNode == null! This is a reactor terminal."); } return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } public override uint Register(LG_ComputerTerminal instance) { if (instance.SpawnNode == null) { EOSLogger.Error("Trying to register reactor terminal. Use TerminalInstanceManager.RegisterReactorTerminal instead."); return uint.MaxValue; } return Register(GetGlobalZoneIndex(instance), instance); } public uint RegisterReactorTerminal(LG_WardenObjective_Reactor reactor) { //IL_0026: 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_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)reactor.m_terminal == (Object)null) { EOSLogger.Error("RegisterReactorTerminal: reactor has no terminal"); return uint.MaxValue; } uint num = Register((reactor.SpawnNode.m_dimension.DimensionIndex, reactor.SpawnNode.LayerType, reactor.SpawnNode.m_zone.LocalIndex), reactor.m_terminal); EOSLogger.Debug($"Registered reactor terminal, {reactor.PublicName} - {reactor.m_terminal.PublicName}, instance index: {num}"); return num; } private void Clear() { } private TerminalInstanceManager() { LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } static TerminalInstanceManager() { Current = new TerminalInstanceManager(); } } } namespace ExtraObjectiveSetup.Objectives.TerminalUplink { public enum UplinkTerminal { SENDER, RECEIVER } public class Terminal { public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType LayerType { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public uint InstanceIndex { get; set; } = uint.MaxValue; } public class UplinkRound { public int RoundIndex { get; set; } = -1; public uint ChainedPuzzleToEndRound { get; set; } public UplinkTerminal BuildChainedPuzzleOn { get; set; } [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleToEndRoundInstance { get; set; } public TimeSettings OverrideTimeSettings { get; set; } = new TimeSettings { TimeToStartVerify = -1f, TimeToCompleteVerify = -1f, TimeToRestoreFromFail = -1f }; public List<WardenObjectiveEventData> EventsOnRound { get; set; } = new List<WardenObjectiveEventData>(); } public class TimeSettings { public float TimeToStartVerify { get; set; } = 5f; public float TimeToCompleteVerify { get; set; } = 6f; public float TimeToRestoreFromFail { get; set; } = 6f; } public class UplinkDefinition : BaseInstanceDefinition { public bool DisplayUplinkWarning { get; set; } = true; public bool SetupAsCorruptedUplink { get; set; } public Terminal CorruptedUplinkReceiver { get; set; } = new Terminal(); public bool UseUplinkAddress { get; set; } = true; public Terminal UplinkAddressLogPosition { get; set; } = new Terminal(); public uint ChainedPuzzleToStartUplink { get; set; } public uint NumberOfVerificationRounds { get; set; } = 1u; public TimeSettings DefaultTimeSettings { get; set; } = new TimeSettings(); public List<UplinkRound> RoundOverrides { get; set; } = new List<UplinkRound> { new UplinkRound() }; public List<WardenObjectiveEventData> EventsOnCommence { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnComplete { get; set; } = new List<WardenObjectiveEventData>(); } internal sealed class UplinkObjectiveManager : InstanceDefinitionManager<UplinkDefinition> { private TextDataBlock UplinkAddrLogContentBlock; private Dictionary<IntPtr, StateReplicator<UplinkState>> stateReplicators = new Dictionary<IntPtr, StateReplicator<UplinkState>>(); private List<UplinkRound> builtRoundPuzzles = new List<UplinkRound>(); public static UplinkObjectiveManager Current { get; private set; } protected override string DEFINITION_NAME { get; } = "TerminalUplink"; protected override void AddDefinitions(InstanceDefinitionsForLevel<UplinkDefinition> definitions) { Sort(definitions); definitions.Definitions.ForEach(delegate(UplinkDefinition u) { u.RoundOverrides.Sort(delegate(UplinkRound r1, UplinkRound r2) { if (r1.RoundIndex == r2.RoundIndex) { return 0; } return (r1.RoundIndex >= r2.RoundIndex) ? 1 : (-1); }); }); base.AddDefinitions(definitions); } private void Build(UplinkDefinition def) { //IL_0018: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Expected O, but got Unknown //IL_02ed: Expected O, but got Unknown //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) LG_ComputerTerminal instance = TerminalInstanceManager.Current.GetInstance(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex); if ((Object)(object)instance == (Object)null) { return; } if (instance.m_isWardenObjective && instance.UplinkPuzzle != null) { EOSLogger.Error("BuildUplink: terminal uplink already built (by vanilla or custom build), aborting!"); return; } if (def.SetupAsCorruptedUplink) { LG_ComputerTerminal instance2 = TerminalInstanceManager.Current.GetInstance(def.CorruptedUplinkReceiver.DimensionIndex, def.CorruptedUplinkReceiver.LayerType, def.CorruptedUplinkReceiver.LocalIndex, def.CorruptedUplinkReceiver.InstanceIndex); if ((Object)(object)instance2 == (Object)null) { EOSLogger.Error("BuildUplink: SetupAsCorruptedUplink specified but didn't find the receiver terminal, will fall back to normal uplink instead"); return; } if (((Il2CppObjectBase)instance2).Pointer == ((Il2CppObjectBase)instance).Pointer) { EOSLogger.Error("BuildUplink: Don't specify uplink sender and receiver on the same terminal"); return; } instance.CorruptedUplinkReceiver = instance2; instance2.CorruptedUplinkReceiver = instance; } instance.UplinkPuzzle = new TerminalUplinkPuzzle(); SetupUplinkPuzzle(instance.UplinkPuzzle, instance, def); TerminalUplinkPuzzle uplinkPuzzle = instance.UplinkPuzzle; uplinkPuzzle.OnPuzzleSolved += Action.op_Implicit((Action)delegate { def.EventsOnComplete?.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); }); instance.m_command.AddCommand((TERM_Command)(((Object)(object)instance.CorruptedUplinkReceiver == (Object)null) ? 25 : 33), def.UseUplinkAddress ? "UPLINK_CONNECT" : "UPLINK_ESTABLISH", new LocalizedText { UntranslatedText = Text.Get(3914968919u), Id = 3914968919u }, (TERM_CommandRule)0); instance.m_command.AddCommand((TERM_Command)26, "UPLINK_VERIFY", new LocalizedText { UntranslatedText = Text.Get(1728022075u), Id = 1728022075u }, (TERM_CommandRule)0); if (def.UseUplinkAddress) { LG_ComputerTerminal val = null; EOSLogger.Debug("BuildUplinkOverride: UseUplinkAddress"); val = TerminalInstanceManager.Current.GetInstance(def.UplinkAddressLogPosition.DimensionIndex, def.UplinkAddressLogPosition.LayerType, def.UplinkAddressLogPosition.LocalIndex, def.UplinkAddressLogPosition.InstanceIndex); if ((Object)(object)val == (Object)null) { EOSLogger.Error("BuildUplinkOverride: didn't find the terminal to put the uplink address log, will put on uplink terminal"); val = instance; } val.AddLocalLog(new TerminalLogFileData { FileName = $"UPLINK_ADDR_{instance.m_serialNumber}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format((UplinkAddrLogContentBlock != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)UplinkAddrLogContentBlock).persistentID) : "Available uplink address for TERMINAL_{0}: {1}", instance.m_serialNumber, instance.UplinkPuzzle.TerminalUplinkIP), Id = 0u } }, true); val.m_command.ClearOutputQueueAndScreenBuffer(); val.m_command.AddInitialTerminalOutput(); } if (def.ChainedPuzzleToStartUplink != 0) { ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleToStartUplink); if (block == null) { EOSLogger.Error($"BuildTerminalUplink: ChainedPuzzleToActive with id {def.ChainedPuzzleToStartUplink} is specified but no ChainedPuzzleDataBlock definition is found... Won't build"); instance.m_chainPuzzleForWardenObjective = null; } else { instance.m_chainPuzzleForWardenObjective = ChainedPuzzleManager.CreatePuzzleInstance(block, instance.SpawnNode.m_area, instance.m_wardenObjectiveSecurityScanAlign.position, instance.m_wardenObjectiveSecurityScanAlign); } } foreach (UplinkRound roundOverride in def.RoundOverrides) { if (roundOverride.ChainedPuzzleToEndRound == 0) { continue; } ChainedPuzzleDataBlock block2 = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(roundOverride.ChainedPuzzleToEndRound); if (block2 != null) { LG_ComputerTerminal val2 = null; switch (roundOverride.BuildChainedPuzzleOn) { case UplinkTerminal.SENDER: val2 = instance; break; case UplinkTerminal.RECEIVER: if (def.SetupAsCorruptedUplink && (Object)(object)instance.CorruptedUplinkReceiver != (Object)null) { val2 = instance.CorruptedUplinkReceiver; break; } EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} specified to build on receiver but this is not a properly setup-ed corr-uplink! Will build ChainedPuzzle on sender side"); val2 = instance; break; default: EOSLogger.Error($"Unimplemented enum UplinkTerminal type {roundOverride.BuildChainedPuzzleOn}"); continue; } roundOverride.ChainedPuzzleToEndRoundInstance = ChainedPuzzleManager.CreatePuzzleInstance(block2, val2.SpawnNode.m_area, val2.m_wardenObjectiveSecurityScanAlign.position, val2.m_wardenObjectiveSecurityScanAlign); builtRoundPuzzles.Add(roundOverride); } else { EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} specified but didn't find its ChainedPuzzleDatablock definition! Will not build!"); } } SetupUplinkReplicator(instance); EOSLogger.Debug($"BuildUplink: built on {(def.DimensionIndex, def.LayerType, def.LocalIndex, def.InstanceIndex)}"); } private void SetupUplinkPuzzle(TerminalUplinkPuzzle uplinkPuzzle, LG_ComputerTerminal terminal, UplinkDefinition def) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown uplinkPuzzle.m_rounds = ListExtensions.ToIl2Cpp<TerminalUplinkPuzzleRound>(new List<TerminalUplinkPuzzleRound>()); uplinkPuzzle.TerminalUplinkIP = SerialGenerator.GetIpAddress(); uplinkPuzzle.m_roundIndex = 0; uplinkPuzzle.m_lastRoundIndexToUpdateGui = -1; uplinkPuzzle.m_position = ((Comp
plugins/net6/Inas07.ExtraSurvivalWaveSettings.dll
Decompiled 10 months agousing System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using GTFO.API; using GameData; using HarmonyLib; using Il2CppSystem; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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("Inas07.ExtraSurvivalWaveSettings")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.ExtraSurvivalWaveSettings")] [assembly: AssemblyTitle("Inas07.ExtraSurvivalWaveSettings")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExtraSurvivalWaveSettings { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.ExtraSurvivalWaveSettings", "ExtraSurvivalWaveSettings", "1.1.1")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "ExtraSurvivalWaveSettings"; public const string VERSION = "1.1.1"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("ExtraSurvivalWaveSettings"); m_Harmony.PatchAll(); } } public class SurvivalWaveManager { public static readonly SurvivalWaveManager Current; private ConcurrentDictionary<string, List<ushort>> WaveEventsMap = new ConcurrentDictionary<string, List<ushort>>(); public void SpawnWave(WardenObjectiveEventData e) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //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) //IL_00ba: 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_0090: Invalid comparison between Unknown and I4 //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Invalid comparison between Unknown and I4 //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Invalid comparison between Unknown and I4 //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Invalid comparison between Unknown and I4 //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_041c: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0131: Invalid comparison between Unknown and I4 //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { ESWSLogger.Error("SpawnWave: LocalPlayerAgent is null, wtf?"); return; } GenericEnemyWaveData enemyWaveData = e.EnemyWaveData; if (enemyWaveData.WaveSettings == 0 || enemyWaveData.WavePopulation == 0) { ESWSLogger.Error("SpawnWave: WaveSettings or WavePopulation is 0"); return; } SurvivalWaveSettingsDataBlock block = GameDataBlockBase<SurvivalWaveSettingsDataBlock>.GetBlock(enemyWaveData.WaveSettings); SurvivalWavePopulationDataBlock block2 = GameDataBlockBase<SurvivalWavePopulationDataBlock>.GetBlock(enemyWaveData.WavePopulation); if (block == null || block2 == null) { return; } AIG_CourseNode val = ((Agent)localPlayerAgent).CourseNode; SurvivalWaveSpawnType val2 = (SurvivalWaveSpawnType)0; Vector3 val3 = Vector3.zero; if (block.m_overrideWaveSpawnType) { LG_Zone val4 = default(LG_Zone); if ((int)block.m_survivalWaveSpawnType != 1 && (int)block.m_survivalWaveSpawnType != 2 && (int)block.m_survivalWaveSpawnType != 3) { val2 = block.m_survivalWaveSpawnType; } else if (Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val4) && (Object)(object)val4 != (Object)null) { val = val4.m_courseNodes[0]; val2 = (SurvivalWaveSpawnType)1; if ((int)block.m_survivalWaveSpawnType == 2 || (int)block.m_survivalWaveSpawnType == 3) { if (e.Count < val4.m_courseNodes.Count) { val = val4.m_courseNodes[e.Count]; val2 = (SurvivalWaveSpawnType)2; if ((int)block.m_survivalWaveSpawnType == 3) { val3 = e.Position; val2 = (SurvivalWaveSpawnType)3; } } else { ESWSLogger.Error($"SpawnWave: SpawnType InSuppliedCourseNode(_OnPosition) is specified but cannot find AREA_{(ushort)(65 + e.Count)} in ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}), falling back to SpawnType: InSuppliedCourseNodeZone"); } } } else { ESWSLogger.Error($"SpawnWave: Failed to find zone with GlobalIndex ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}), falling back to default spawn type"); } } Mastermind current = Mastermind.Current; AIG_CourseNode obj = val; uint waveSettings = enemyWaveData.WaveSettings; uint wavePopulation = enemyWaveData.WavePopulation; SurvivalWaveSpawnType val5 = val2; float spawnDelay = enemyWaveData.SpawnDelay; Vector3 val6 = val3; ushort num = default(ushort); if (!current.TriggerSurvivalWave(obj, waveSettings, wavePopulation, ref num, val5, spawnDelay, (float)enemyWaveData.AreaDistance, val6, true, false, default(Vector3), "")) { ESWSLogger.Error("SpawnWave: Critical ERROR! Failed spawning enemy wave"); return; } WardenObjectiveManager.RegisterSurvivalWaveID(num); ESWSLogger.Log($"SpawnWave: Enemy wave spawned ({val2}) with eventID {num}"); if (enemyWaveData.TriggerAlarm) { WardenObjectiveManager.Current.m_sound.UpdatePosition(val.Position); WardenObjectiveManager.Current.m_sound.Post(EVENTS.APEX_PUZZLE_START_ALARM, true); ESWSLogger.Debug("SpawnWave: Trigger Alarm (prolly bugged when there're multiple alarms)"); } if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(enemyWaveData.IntelMessage))) { GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", LocalizedText.op_Implicit(enemyWaveData.IntelMessage), false, 200f, 8f, (Action)null); } if ((int)val2 == 1) { ESWSLogger.Log($"Spawning in: ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex})"); } else if ((int)val2 == 2) { ESWSLogger.Log($"Spawning in: ({e.DimensionIndex}, {e.Layer}, {e.LocalIndex}, AREA_{(ushort)(65 + e.Count)})"); } string worldEventObjectFilter = e.WorldEventObjectFilter; if (!string.IsNullOrEmpty(worldEventObjectFilter)) { if (!WaveEventsMap.ContainsKey(worldEventObjectFilter)) { WaveEventsMap[worldEventObjectFilter] = new List<ushort>(); } WaveEventsMap[worldEventObjectFilter].Add(num); ESWSLogger.Debug($"SpawnWave: Registered wave with filter {worldEventObjectFilter}, number of waves assigned: {WaveEventsMap[worldEventObjectFilter].Count}"); } } public void StopNamedWaves(string waveName) { if (string.IsNullOrEmpty(waveName)) { return; } if (!WaveEventsMap.Remove(waveName, out var value)) { ESWSLogger.Error("Wave Filter " + waveName + " is unregistered, cannot stop wave."); return; } ESWSLogger.Debug($"StopNamedWaves: Stopping waves with name {waveName}, wave count: {value.Count}"); value.ForEach(delegate(ushort eventID) { MastermindEvent val = default(MastermindEvent); if (Mastermind.Current.TryGetEvent(eventID, ref val)) { val.StopEvent(); } else { ESWSLogger.Error($"Wave with ID {eventID}: cannot find event. Are you debugging a level?"); } }); } internal void OnStopAllWave() { WaveEventsMap.Clear(); } public void Clear() { WaveEventsMap.Clear(); } private SurvivalWaveManager() { } static SurvivalWaveManager() { Current = new SurvivalWaveManager(); LevelAPI.OnLevelCleanup += Current.Clear; } } internal static class ESWSLogger { private static ManualLogSource logger = Logger.CreateLogSource("ExtraSurvivalWaveSettings"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } [HarmonyPatch] internal class Patch_CheckAndExecuteEventsOnTrigger { [HarmonyPrefix] [HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[] { typeof(WardenObjectiveEventData), typeof(eWardenObjectiveEventTrigger), typeof(bool), typeof(float) })] private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration)) { return true; } bool flag = false; eWardenObjectiveEventType type = eventToTrigger.Type; if (type - 9 <= 1) { flag = true; Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(eventToTrigger, 0f)), (Action)null); WorldEventManager.m_worldEventEventCoroutines.Add(val); } return !flag; } internal static IEnumerator Handle(WardenObjectiveEventData e, float currentDuration) { float num = Mathf.Max(e.Delay - currentDuration, 0f); if (num > 0f) { yield return (object)new WaitForSeconds(num); } if (e.Condition.ConditionIndex >= 0 && WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue) { yield break; } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string text = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text); } } eWardenObjectiveEventType type = e.Type; if ((int)type != 9) { if ((int)type == 10) { if (string.IsNullOrEmpty(e.WorldEventObjectFilter)) { WardenObjectiveManager.StopAlarms(); WardenObjectiveManager.StopAllWardenObjectiveEnemyWaves(); WardenObjectiveManager.Current.m_sound.Post(EVENTS.ALARM_AMBIENT_STOP, true); SurvivalWaveManager.Current.OnStopAllWave(); } else { SurvivalWaveManager.Current.StopNamedWaves(e.WorldEventObjectFilter); } } } else { SurvivalWaveManager.Current.SpawnWave(e); } } } }
plugins/net6/Inas07.FixEndScreen.dll
Decompiled 10 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Inas07.FixEndScreen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.FixEndScreen")] [assembly: AssemblyTitle("Inas07.FixEndScreen")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FixEndScreen { [BepInPlugin("Inas.FixEndScreen", "FixEndScreen", "1.0.0")] public class EntryPoint : BasePlugin { private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("FixEndScreen"); m_Harmony.PatchAll(); } } } namespace FixEndScreen.Patches { [HarmonyPatch] internal class Patch_DiscordManager { [HarmonyPrefix] [HarmonyPatch(typeof(DiscordManager), "UpdateDiscordDetails")] private static bool Pre_UpdateDiscordDetails() { return false; } } }
plugins/net6/Inas07.LocalProgression.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BoosterImplants; using CellMenu; using DropServer; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LocalProgression.Data; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Inas07.LocalProgression")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Inas07.LocalProgression")] [assembly: AssemblyTitle("Inas07.LocalProgression")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LocalProgression { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.LocalProgression", "LocalProgression", "1.1.10")] public class EntryPoint : BasePlugin { private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("LocalProgression"); m_Harmony.PatchAll(); EventAPI.OnManagersSetup += LocalProgressionManager.Current.Init; } } public class LocalProgressionManager { public static readonly LocalProgressionManager Current; public static readonly string DirPath; private CM_PageRundown_New rundownPage; private RundownProgressionData CurrentRundownProgressionData { get; } = new RundownProgressionData(); internal RundownProgData nativeProgData { get; private set; } private static string RundownLocalProgressionFilePath(string rundownName) { char[] invalidPathChars = Path.GetInvalidPathChars(); foreach (char oldChar in invalidPathChars) { rundownName = rundownName.Replace(oldChar, '_'); } return Path.Combine(DirPath, rundownName); } private static Dictionary<string, ExpeditionProgressionData> ReadRundownLocalProgressionData(string rundownName) { string path = RundownLocalProgressionFilePath(rundownName); Dictionary<string, ExpeditionProgressionData> dictionary = new Dictionary<string, ExpeditionProgressionData>(); if (File.Exists(path)) { using FileStream input = File.Open(path, FileMode.Open); using BinaryReader binaryReader = new BinaryReader(input, Encoding.UTF8, leaveOpen: false); int num = 0; num = binaryReader.ReadInt32(); for (int i = 0; i < num; i++) { ExpeditionProgressionData expeditionProgressionData = new ExpeditionProgressionData(); expeditionProgressionData.ExpeditionKey = binaryReader.ReadString(); expeditionProgressionData.MainCompletionCount = binaryReader.ReadInt32(); expeditionProgressionData.SecondaryCompletionCount = binaryReader.ReadInt32(); expeditionProgressionData.ThirdCompletionCount = binaryReader.ReadInt32(); expeditionProgressionData.AllClearCount = binaryReader.ReadInt32(); dictionary.Add(expeditionProgressionData.ExpeditionKey, expeditionProgressionData); } } return dictionary; } internal RundownProgressionData GetLocalProgressionDataForCurrentRundown() { return CurrentRundownProgressionData; } private void SaveRundownProgressionDataToDisk() { string text = RundownLocalProgressionFilePath(CurrentRundownProgressionData.RundownName); LPLogger.Warning("SaveData: saving to " + text); using FileStream output = File.Open(text, FileMode.Create); using BinaryWriter binaryWriter = new BinaryWriter(output, Encoding.UTF8, leaveOpen: false); Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict; binaryWriter.Write(localProgressionDict.Count); foreach (string key in CurrentRundownProgressionData.LocalProgressionDict.Keys) { ExpeditionProgressionData expeditionProgressionData = localProgressionDict[key]; binaryWriter.Write(key); binaryWriter.Write(expeditionProgressionData.MainCompletionCount); binaryWriter.Write(expeditionProgressionData.SecondaryCompletionCount); binaryWriter.Write(expeditionProgressionData.ThirdCompletionCount); binaryWriter.Write(expeditionProgressionData.AllClearCount); } } public void RecordExpeditionSuccessForCurrentRundown(string expeditionKey, bool mainLayerCleared, bool secondaryLayerCleared, bool thirdLayerCleared) { if (RundownManager.ActiveExpedition.ExcludeFromProgression) { return; } bool flag = mainLayerCleared && secondaryLayerCleared && thirdLayerCleared; Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict; if (!localProgressionDict.ContainsKey(expeditionKey)) { localProgressionDict[expeditionKey] = new ExpeditionProgressionData { ExpeditionKey = expeditionKey, MainCompletionCount = (mainLayerCleared ? 1 : 0), SecondaryCompletionCount = (secondaryLayerCleared ? 1 : 0), ThirdCompletionCount = (thirdLayerCleared ? 1 : 0), AllClearCount = (flag ? 1 : 0) }; CurrentRundownProgressionData.MainClearCount += (mainLayerCleared ? 1 : 0); CurrentRundownProgressionData.SecondaryClearCount += (secondaryLayerCleared ? 1 : 0); CurrentRundownProgressionData.ThirdClearCount += (thirdLayerCleared ? 1 : 0); CurrentRundownProgressionData.AllClearCount += (flag ? 1 : 0); } else { ExpeditionProgressionData expeditionProgressionData = localProgressionDict[expeditionKey]; if (expeditionProgressionData.MainCompletionCount == 0 && mainLayerCleared) { CurrentRundownProgressionData.MainClearCount++; } if (expeditionProgressionData.SecondaryCompletionCount == 0 && secondaryLayerCleared) { CurrentRundownProgressionData.SecondaryClearCount++; } if (expeditionProgressionData.ThirdCompletionCount == 0 && thirdLayerCleared) { CurrentRundownProgressionData.ThirdClearCount++; } if (expeditionProgressionData.AllClearCount == 0 && flag) { CurrentRundownProgressionData.AllClearCount++; } expeditionProgressionData.MainCompletionCount += (mainLayerCleared ? 1 : 0); expeditionProgressionData.SecondaryCompletionCount += (secondaryLayerCleared ? 1 : 0); expeditionProgressionData.ThirdCompletionCount += (thirdLayerCleared ? 1 : 0); expeditionProgressionData.AllClearCount += (flag ? 1 : 0); } SaveRundownProgressionDataToDisk(); } public void UpdateLocalProgressionDataToActiveRundown() { string activeRundownKey = RundownManager.ActiveRundownKey; uint num = default(uint); if (!RundownManager.TryGetIdFromLocalRundownKey(activeRundownKey, ref num) || num == 0) { LPLogger.Debug("OnRundownProgressionUpdated: cannot find rundown with rundown key `" + activeRundownKey + "`!"); return; } LPLogger.Warning($"Update LPData to rundown_id: {num}"); CurrentRundownProgressionData.Reset(); RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(num); if (block == null) { LPLogger.Error($"Didn't find Rundown Datablock with rundown id {num}"); return; } Dictionary<string, ExpeditionProgressionData> dictionary = ReadRundownLocalProgressionData(((GameDataBlockBase<RundownDataBlock>)(object)block).name); CurrentRundownProgressionData.RundownID = num; CurrentRundownProgressionData.RundownName = ((GameDataBlockBase<RundownDataBlock>)(object)block).name; CurrentRundownProgressionData.LocalProgressionDict = dictionary; foreach (ExpeditionProgressionData value in dictionary.Values) { CurrentRundownProgressionData.MainClearCount += ((value.MainCompletionCount > 0) ? 1 : 0); CurrentRundownProgressionData.SecondaryClearCount += ((value.SecondaryCompletionCount > 0) ? 1 : 0); CurrentRundownProgressionData.ThirdClearCount += ((value.ThirdCompletionCount > 0) ? 1 : 0); CurrentRundownProgressionData.AllClearCount += ((value.AllClearCount > 0) ? 1 : 0); } } internal void Init() { if (!Directory.Exists(DirPath)) { Directory.CreateDirectory(DirPath); } RundownManager.OnRundownProgressionUpdated += Action.op_Implicit((Action)OnNativeRundownProgressionUpdated); } internal void OnNativeRundownProgressionUpdated() { UpdateLocalProgressionDataToActiveRundown(); if (!((Object)(object)rundownPage == (Object)null) && ((CM_PageBase)rundownPage).m_isActive) { UpdateRundownPageExpeditionIconProgression(); } } internal void SetCurrentRundownPageInstance(CM_PageRundown_New __instance) { rundownPage = __instance; } private void UpdateRundownPageExpeditionIconProgression() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rundownPage == (Object)null) { return; } uint rundownID = CurrentRundownProgressionData.RundownID; if (rundownID == 0) { LPLogger.Warning("UpdateRundownPageExpeditionIconProgression: rundown_id == 0!"); return; } RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(rundownID); LPLogger.Log($"CM_PageRundown_New.UpdateRundownExpeditionProgression, overwrite with LocalProgression Data, RundownID {CurrentRundownProgressionData.RundownID}"); nativeProgData = ComputeLocalProgressionDataToRundownProgData(); if ((Object)(object)rundownPage.m_tierMarker1 != (Object)null) { rundownPage.m_tierMarker1.SetProgression(nativeProgData, new RundownTierProgressionData()); if (rundownPage.m_expIconsTier1 != null) { UpdateTierIconsWithProgression(rundownPage.m_expIconsTier1, rundownPage.m_tierMarker1, thisTierUnlocked: true); } } if ((Object)(object)rundownPage.m_tierMarker2 != (Object)null) { rundownPage.m_tierMarker2.SetProgression(nativeProgData, block.ReqToReachTierB); if (rundownPage.m_expIconsTier2 != null) { UpdateTierIconsWithProgression(rundownPage.m_expIconsTier2, rundownPage.m_tierMarker2, nativeProgData.tierBUnlocked && block.UseTierUnlockRequirements); } } if ((Object)(object)rundownPage.m_tierMarker3 != (Object)null) { rundownPage.m_tierMarker3.SetProgression(nativeProgData, block.ReqToReachTierC); if (rundownPage.m_expIconsTier3 != null) { UpdateTierIconsWithProgression(rundownPage.m_expIconsTier3, rundownPage.m_tierMarker3, nativeProgData.tierCUnlocked && block.UseTierUnlockRequirements); } } if ((Object)(object)rundownPage.m_tierMarker4 != (Object)null) { rundownPage.m_tierMarker4.SetProgression(nativeProgData, block.ReqToReachTierD); if (rundownPage.m_expIconsTier4 != null) { UpdateTierIconsWithProgression(rundownPage.m_expIconsTier4, rundownPage.m_tierMarker4, nativeProgData.tierDUnlocked && block.UseTierUnlockRequirements); } } if ((Object)(object)rundownPage.m_tierMarker5 != (Object)null) { rundownPage.m_tierMarker5.SetProgression(nativeProgData, block.ReqToReachTierE); if (rundownPage.m_expIconsTier5 != null) { UpdateTierIconsWithProgression(rundownPage.m_expIconsTier5, rundownPage.m_tierMarker5, nativeProgData.tierEUnlocked && block.UseTierUnlockRequirements); } } if ((Object)(object)rundownPage.m_tierMarkerSectorSummary != (Object)null) { rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForMain($"<color=orange>[{nativeProgData.clearedMain}/{nativeProgData.totalMain}]</color>", "#FFFFFFCC"); rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForSecondary($"<color=orange>[{nativeProgData.clearedSecondary}/{nativeProgData.totalSecondary}]</color>", "#CCCCCCCC"); rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForThird($"<color=orange>[{nativeProgData.clearedThird}/{nativeProgData.totalThird}]</color>", "#CCCCCCCC"); rundownPage.m_tierMarkerSectorSummary.SetSectorIconTextForAllCleared($"<color=orange>[{nativeProgData.clearedAllClear}/{nativeProgData.totalAllClear}]</color>", "#CCCCCCCC"); } } private void UpdateTierIconsWithProgression(List<CM_ExpeditionIcon_New> tierIcons, CM_RundownTierMarker tierMarker, bool thisTierUnlocked) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if (tierIcons == null || tierIcons.Count == 0) { if (tierMarker != null) { tierMarker.SetVisible(false, 0f); } return; } for (int i = 0; i < tierIcons.Count; i++) { CM_ExpeditionIcon_New val = tierIcons[i]; string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(tierIcons[i].Tier, tierIcons[i].ExpIndex); ExpeditionProgressionData value; bool flag = CurrentRundownProgressionData.LocalProgressionDict.TryGetValue(rundownProgressionExpeditionKey, out value); string text = "0"; string text2 = (RundownManager.HasSecondaryLayer(tierIcons[i].DataBlock) ? "0" : "-"); string text3 = (RundownManager.HasThirdLayer(tierIcons[i].DataBlock) ? "0" : "-"); string text4 = (RundownManager.HasAllCompletetionPossibility(tierIcons[i].DataBlock) ? "0" : "-"); if (flag) { if (value.MainCompletionCount > 0) { text = value.MainCompletionCount.ToString(); } if (value.SecondaryCompletionCount > 0) { text2 = value.SecondaryCompletionCount.ToString(); } if (value.ThirdCompletionCount > 0) { text3 = value.ThirdCompletionCount.ToString(); } if (value.AllClearCount > 0) { text4 = value.AllClearCount.ToString(); } } if (CheckExpeditionUnlocked(val.DataBlock, val.Tier)) { if (flag) { rundownPage.SetIconStatus(val, (eExpeditionIconStatus)4, text, text2, text3, text4, 1f, false, (eExpeditionAccessibility)0); } else { rundownPage.SetIconStatus(val, (eExpeditionIconStatus)2, "-", "-", "-", "-", 1f, false, (eExpeditionAccessibility)0); } } else if (flag) { rundownPage.SetIconStatus(val, (eExpeditionIconStatus)1, text, text2, text3, text4, 1f, false, (eExpeditionAccessibility)0); } else if (val.DataBlock.HideOnLocked) { ((RectTransformComp)val).SetVisible(false); } else { rundownPage.SetIconStatus(val, (eExpeditionIconStatus)0, "-", "-", "-", "-", 1f, false, (eExpeditionAccessibility)0); } } if (thisTierUnlocked) { if (tierMarker != null) { tierMarker.SetStatus((eRundownTierMarkerStatus)1); } } else if (tierMarker != null) { tierMarker.SetStatus((eRundownTierMarkerStatus)0); } } private RundownProgData ComputeLocalProgressionDataToRundownProgData() { //IL_0002: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) RundownProgData progressionData = default(RundownProgData); if (CurrentRundownProgressionData.RundownID == 0) { LPLogger.Error("ComputeLocalProgressionDataToRundownProgData: rundown_id == 0..."); return progressionData; } RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(CurrentRundownProgressionData.RundownID); if (block == null) { LPLogger.Error($"ComputeLocalProgressionDataToRundownProgData: cannot get rundown datablock with rundown_id: {CurrentRundownProgressionData.RundownID}"); return progressionData; } progressionData.clearedMain = CurrentRundownProgressionData.MainClearCount; progressionData.clearedSecondary = CurrentRundownProgressionData.SecondaryClearCount; progressionData.clearedThird = CurrentRundownProgressionData.ThirdClearCount; progressionData.clearedAllClear = CurrentRundownProgressionData.AllClearCount; AccumulateTierClearance(block, (eRundownTier)1, ref progressionData); AccumulateTierClearance(block, (eRundownTier)2, ref progressionData); AccumulateTierClearance(block, (eRundownTier)3, ref progressionData); AccumulateTierClearance(block, (eRundownTier)4, ref progressionData); AccumulateTierClearance(block, (eRundownTier)5, ref progressionData); return progressionData; } private void AccumulateTierClearance(RundownDataBlock rundownDB, eRundownTier tier, ref RundownProgData progressionData) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) List<ExpeditionInTierData> val = rundownDB.TierA; switch (tier - 1) { case 1: val = rundownDB.TierB; break; case 2: val = rundownDB.TierC; break; case 3: val = rundownDB.TierD; break; case 4: val = rundownDB.TierE; break; default: LPLogger.Error($"Unsupported eRundownTier {tier}"); return; case 0: break; } int num = 0; Enumerator<ExpeditionInTierData> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionInTierData current = enumerator.Current; if (current.Enabled && (!current.HideOnLocked || CheckExpeditionUnlocked(current, tier))) { progressionData.totalMain++; if (RundownManager.HasSecondaryLayer(current)) { progressionData.totalSecondary++; } if (RundownManager.HasThirdLayer(current)) { progressionData.totalThird++; } if (RundownManager.HasAllCompletetionPossibility(current)) { progressionData.totalAllClear++; } if (current.Descriptive.IsExtraExpedition) { progressionData.totatlExtra++; } string uniqueExpeditionKey = RundownManager.GetUniqueExpeditionKey(rundownDB, tier, num); if (CurrentRundownProgressionData.LocalProgressionDict.ContainsKey(uniqueExpeditionKey)) { progressionData.clearedExtra++; } num++; } } } private bool CheckTierUnlocked(eRundownTier tier) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) RundownDataBlock block = GameDataBlockBase<RundownDataBlock>.GetBlock(CurrentRundownProgressionData.RundownID); RundownTierProgressionData val = null; switch (tier - 1) { case 0: return true; case 1: val = block.ReqToReachTierB; break; case 2: val = block.ReqToReachTierC; break; case 3: val = block.ReqToReachTierD; break; case 4: val = block.ReqToReachTierE; break; default: LPLogger.Error("Unsupporrted tier: {0}", tier); return true; } if (CurrentRundownProgressionData.MainClearCount >= val.MainSectors && CurrentRundownProgressionData.SecondaryClearCount >= val.SecondarySectors && CurrentRundownProgressionData.ThirdClearCount >= val.ThirdSectors) { return CurrentRundownProgressionData.AllClearCount >= val.AllClearedSectors; } return false; } private bool CheckExpeditionUnlocked(ExpeditionInTierData expedition, eRundownTier tier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected I4, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) eExpeditionAccessibility accessibility = expedition.Accessibility; switch ((int)accessibility) { case 1: case 3: return false; case 2: return true; case 0: return CheckTierUnlocked(tier); case 4: { RundownTierProgressionData customProgressionLock = expedition.CustomProgressionLock; if (CurrentRundownProgressionData.MainClearCount >= customProgressionLock.MainSectors && CurrentRundownProgressionData.SecondaryClearCount >= customProgressionLock.SecondarySectors && CurrentRundownProgressionData.ThirdClearCount >= customProgressionLock.ThirdSectors) { return CurrentRundownProgressionData.AllClearCount >= customProgressionLock.AllClearedSectors; } return false; } case 5: { ExpeditionIndex unlockedByExpedition = expedition.UnlockedByExpedition; string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(unlockedByExpedition.Tier, (int)unlockedByExpedition.Exp); return CurrentRundownProgressionData.LocalProgressionDict.ContainsKey(rundownProgressionExpeditionKey); } default: LPLogger.Warning("Unsupported eExpeditionAccessibility: {0}", expedition.Accessibility); return true; } } private void SetNativeRundownProgression() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, Expedition> expeditions = RundownManager.RundownProgression.Expeditions; if (expeditions.Count > 0) { LPLogger.Warning($"Non-empty native rundown progression data! RundownID: {CurrentRundownProgressionData.RundownID}"); expeditions.Clear(); } Dictionary<string, ExpeditionProgressionData> localProgressionDict = CurrentRundownProgressionData.LocalProgressionDict; Layer val2 = default(Layer); Layer val3 = default(Layer); Layer val4 = default(Layer); foreach (string key in localProgressionDict.Keys) { Expedition val = new Expedition(); ExpeditionProgressionData expeditionProgressionData = localProgressionDict[key]; val.AllLayerCompletionCount = expeditionProgressionData.AllClearCount; val.Layers = new LayerSet<Layer>(); val2.CompletionCount = expeditionProgressionData.MainCompletionCount; val2.State = (LayerProgressionState)((expeditionProgressionData.MainCompletionCount > 0) ? 3 : 0); val3.CompletionCount = expeditionProgressionData.SecondaryCompletionCount; val3.State = (LayerProgressionState)((expeditionProgressionData.SecondaryCompletionCount > 0) ? 3 : 0); val4.CompletionCount = expeditionProgressionData.ThirdCompletionCount; val4.State = (LayerProgressionState)((expeditionProgressionData.ThirdCompletionCount > 0) ? 3 : 0); val.Layers.SetLayer((ExpeditionLayers)0, val2); val.Layers.SetLayer((ExpeditionLayers)1, val3); val.Layers.SetLayer((ExpeditionLayers)2, val4); LPLogger.Warning($"{val2.CompletionCount}, {val3.CompletionCount}, {val4.CompletionCount}"); expeditions[key] = val; } } static LocalProgressionManager() { Current = new LocalProgressionManager(); DirPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "GTFO-Modding", "LocalProgression"); } private LocalProgressionManager() { } } internal static class LPLogger { private static ManualLogSource logger = Logger.CreateLogSource("LocalProgression"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } public static class Utils { public static bool TryGetComponent<T>(this GameObject obj, out T comp) { comp = obj.GetComponent<T>(); return comp != null; } } } namespace LocalProgression.Patches { [HarmonyPatch] internal class Patches_CM_PageRundown_New { [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "Setup")] private static void Post_Setup(CM_PageRundown_New __instance) { LocalProgressionManager.Current.SetCurrentRundownPageInstance(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "PlaceRundown")] private static void Post_PlaceRundown(CM_PageRundown_New __instance) { LocalProgressionManager.Current.OnNativeRundownProgressionUpdated(); } [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")] private static void Post_OnEnable(CM_PageRundown_New __instance) { LocalProgressionManager.Current.OnNativeRundownProgressionUpdated(); } } [HarmonyPatch] internal class FixEndScreen { [HarmonyPrefix] [HarmonyPatch(typeof(DiscordManager), "UpdateDiscordDetails")] private static bool Pre_UpdateDiscordDetails() { return false; } } [HarmonyPatch] internal class Patches_GS_ExpeditionSuccess { [HarmonyPostfix] [HarmonyPatch(typeof(GS_ExpeditionSuccess), "Enter")] private static void DoChangeState(GS_ExpeditionSuccess __instance) { //IL_0007: 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_0024: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData(); string rundownProgressionExpeditionKey = RundownManager.GetRundownProgressionExpeditionKey(activeExpeditionData.tier, activeExpeditionData.expeditionIndex); bool mainLayerCleared = (int)WardenObjectiveManager.CurrentState.main_status == 40; bool secondaryLayerCleared = (int)WardenObjectiveManager.CurrentState.second_status == 40; bool thirdLayerCleared = (int)WardenObjectiveManager.CurrentState.third_status == 40; LPLogger.Debug("Level cleared, recording - " + rundownProgressionExpeditionKey); LocalProgressionManager.Current.RecordExpeditionSuccessForCurrentRundown(rundownProgressionExpeditionKey, mainLayerCleared, secondaryLayerCleared, thirdLayerCleared); } } } namespace LocalProgression.Data { public class ExpeditionProgressionData { public string ExpeditionKey { get; set; } = string.Empty; public int MainCompletionCount { get; set; } public int SecondaryCompletionCount { get; set; } public int ThirdCompletionCount { get; set; } public int AllClearCount { get; set; } } public class RundownProgressionData { public string RundownName { get; set; } = string.Empty; public uint RundownID { get; set; } public Dictionary<string, ExpeditionProgressionData> LocalProgressionDict { get; set; } = new Dictionary<string, ExpeditionProgressionData>(); public int MainClearCount { get; set; } public int SecondaryClearCount { get; set; } public int ThirdClearCount { get; set; } public int AllClearCount { get; set; } public void Reset() { RundownName = string.Empty; RundownID = 0u; LocalProgressionDict.Clear(); int num2 = (AllClearCount = 0); int num4 = (ThirdClearCount = num2); int mainClearCount = (SecondaryClearCount = num4); MainClearCount = mainClearCount; } } } namespace LocalProgression.Component { public class ExpeditionSuccess_NoBooster : MonoBehaviour { private CM_PageExpeditionSuccess expeditionSuccessPage; private CM_ExpeditionSectorIcon m_completeWithNoBoosterIcon; private float m_time_clearedWithNoBooster = 7.5f; public void Setup() { if ((Object)(object)expeditionSuccessPage != (Object)null && (Object)(object)m_completeWithNoBoosterIcon != (Object)null) { return; } EventAPI.OnAssetsLoaded += delegate { expeditionSuccessPage = ((Component)this).gameObject.GetComponent<CM_PageExpeditionSuccess>(); if ((Object)(object)expeditionSuccessPage == (Object)null) { LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot find CM_PageExpeditionSuccess in parent.. Add `PageExpeditionSuccessWithNoBooster` to CM_ExpeditionSuccessPage as component first!"); } else { m_completeWithNoBoosterIcon = Object.Instantiate<CM_ExpeditionSectorIcon>(expeditionSuccessPage.m_sectorIconAllCompleted); if ((Object)(object)m_completeWithNoBoosterIcon == (Object)null) { LPLogger.Error("ExpeditionSuccess_NoBooster.Setup: cannot instantiate NoBooster icon..."); } } }; ((Component)this).gameObject.SetActive(false); } private void OnEnable() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Invalid comparison between Unknown and I4 //IL_00fc: Unknown result type (might be due to invalid IL or missing references) LPLogger.Warning("ExpeditionSuccess_NoBooster: OnEnable"); ((Component)this).gameObject.SetActive(true); bool boosterUnused = true; foreach (PlayerBoosterImplantState item in (Il2CppArrayBase<PlayerBoosterImplantState>)(object)BoosterImplantManager.Current.m_boosterPlayers) { if (item == null) { continue; } foreach (pBoosterImplantData item2 in (Il2CppArrayBase<pBoosterImplantData>)(object)item.BoosterImplantDatas) { if (item2.BoosterImplantID != 0) { boosterUnused = false; break; } } } int num = 0; bool flag = RundownManager.HasSecondaryLayer(RundownManager.ActiveExpedition); bool flag2 = RundownManager.HasThirdLayer(RundownManager.ActiveExpedition); num += (flag ? 1 : 0); num += (flag2 ? 1 : 0); num += ((flag && (int)WardenObjectiveManager.CurrentState.second_status == 40 && flag2 && (int)WardenObjectiveManager.CurrentState.second_status == 40) ? 1 : 0); SetupNoBoosterUsedIcon(boosterUnused); ((RectTransformComp)m_completeWithNoBoosterIcon).SetPosition(new Vector2((float)num * 400f, 0f)); m_completeWithNoBoosterIcon.BlinkIn(m_time_clearedWithNoBooster); } private void SetupNoBoosterUsedIcon(bool boosterUnused) { CM_ExpeditionSectorIcon completeWithNoBoosterIcon = m_completeWithNoBoosterIcon; completeWithNoBoosterIcon.m_isFinishedAll = true; completeWithNoBoosterIcon.m_root = ((Component)expeditionSuccessPage).transform; completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconMainSkull, completeWithNoBoosterIcon.m_iconMainBG, false, false, 0.5f, 0.7f); completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconSecondarySkull, completeWithNoBoosterIcon.m_iconSecondaryBG, false, false, 0.5f, 0.7f); completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconThirdSkull, completeWithNoBoosterIcon.m_iconThirdBG, false, false, 0.5f, 0.7f); completeWithNoBoosterIcon.SetupIcon(completeWithNoBoosterIcon.m_iconFinishedAllSkull, completeWithNoBoosterIcon.m_iconFinishedAllBG, true, true, 0.5f, 0.7f); completeWithNoBoosterIcon.m_titleVisible = true; completeWithNoBoosterIcon.m_isCleared = boosterUnused; ((Component)completeWithNoBoosterIcon.m_rightSideText).gameObject.SetActive(false); ((TMP_Text)completeWithNoBoosterIcon.m_title).text = "<color=orange>NO BOOSTER</color>"; ((Graphic)completeWithNoBoosterIcon.m_title).Rebuild((CanvasUpdate)3); ((Component)completeWithNoBoosterIcon.m_title).gameObject.SetActive(completeWithNoBoosterIcon.m_titleVisible); } static ExpeditionSuccess_NoBooster() { ClassInjector.RegisterTypeInIl2Cpp<ExpeditionSuccess_NoBooster>(); } } }
plugins/net6/InjectLib.dll
Decompiled 10 months agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using GTFO.API; using GTFO.API.JSON; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class; using Il2CppJsonNet; using Il2CppJsonNet.Converters; using Il2CppJsonNet.Linq; using Il2CppJsonNet.Serialization; using Il2CppSystem; using Il2CppSystem.Runtime.InteropServices; using InjectLib.FieldInjection; using InjectLib.JsonNETInjection; using InjectLib.JsonNETInjection.Converter; using InjectLib.JsonNETInjection.Detours; using InjectLib.JsonNETInjection.Handler; using InjectLib.Utils; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("InjectLib")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitc83a124-master")] [assembly: AssemblyProduct("InjectLib")] [assembly: AssemblyTitle("InjectLib")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [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] internal sealed class IsUnmanagedAttribute : Attribute { } [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 NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } } namespace InjectLib { [BepInPlugin("GTFO.InjectLib", "InjectLib", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { public override void Load() { NativeJsonProcessorStore.Initialize(); } public override bool Unload() { return ((BasePlugin)this).Unload(); } } internal static class Logger { private static readonly ManualLogSource _Logger; static Logger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _Logger = new ManualLogSource("InjectLib"); Logger.Sources.Add((ILogSource)(object)_Logger); } private static string Format(object msg) { return msg.ToString(); } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { _Logger.LogInfo(handler); } public static void Info(string str) { _Logger.LogMessage((object)str); } public static void Info(object data) { _Logger.LogMessage((object)Format(data)); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { _Logger.LogDebug(handler); } public static void Debug(string str) { _Logger.LogDebug((object)str); } public static void Debug(object data) { _Logger.LogDebug((object)Format(data)); } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { _Logger.LogError(handler); } public static void Error(string str) { _Logger.LogError((object)str); } public static void Error(object data) { _Logger.LogError((object)Format(data)); } public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler) { _Logger.LogFatal(handler); } public static void Fatal(string str) { _Logger.LogFatal((object)str); } public static void Fatal(object data) { _Logger.LogFatal((object)Format(data)); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { _Logger.LogWarning(handler); } public static void Warn(string str) { _Logger.LogWarning((object)str); } public static void Warn(object data) { _Logger.LogWarning((object)Format(data)); } [Conditional("DEBUG")] public static void DebugOnly(object data) { } } [GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "InjectLib"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitc83a124-master"; public const string SemVer = "1.0.0+gitc83a124-master"; public const string GitRevShort = "c83a124"; public const string GitRevLong = "c83a124696b1272397115ca04d902622f35ba87e"; public const string GitBranch = "master"; public const string GitTag = null; public const int GitCommitsSinceTag = 0; public const bool GitIsDirty = false; } } namespace InjectLib.Utils { internal static class FieldsExtension { public static void SetNativeJsonProcessor(this DataSetConverter converter, NativeJsonProcessor processor) { FieldInjector<DataSetConverter>.TrySetManagedField(converter, "m_JsonProcessor", processor); } public static NativeJsonProcessor GetNativeJsonProcessor(this DataSetConverter converter) { FieldInjector<DataSetConverter>.TryGetManagedField<NativeJsonProcessor>(converter, "m_JsonProcessor", out var value); return value; } } internal static class ObjectCopier { public static void CopyProperties<T>(T source, T target) where T : Il2CppObjectBase { PropertyInfo[] properties = typeof(T).GetProperties(); foreach (PropertyInfo propertyInfo in properties) { Type propertyType = propertyInfo.PropertyType; if (!propertyInfo.Name.Contains("_k__BackingField") && !(propertyType == typeof(IntPtr)) && propertyInfo.CanRead && propertyInfo.CanWrite) { propertyInfo.SetValue(target, propertyInfo.GetValue(source)); } } } } } namespace InjectLib.JsonNETInjection { public static class JsonInjector { static JsonInjector() { FieldInjector<DataSetConverter>.DefineManagedField<NativeJsonProcessor>("m_JsonProcessor"); } public static void SetConverter<T>(Il2CppJsonReferenceTypeConverter<T> converter) where T : Il2CppObjectBase { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown if (converter == null) { throw new ArgumentNullException("converter"); } if (!NativeJsonProcessorStore.Prepare<T>(out var processor)) { return; } if (processor.Converter != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(76, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Converter (type: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") will be replaced! This would leads to unwanted behaviour!"); } Logger.Warn(val); Logger.Warn(" - Suggetion: If your converter does not require to deep-level altering of JSON, consider use Il2CppJsonReferenceTypeHandler instead."); val = new BepInExWarningLogInterpolatedStringHandler(19, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Previous Owner: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().Assembly.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().FullName); } Logger.Warn(val); val = new BepInExWarningLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("New Owner: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().Assembly.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().FullName); } Logger.Warn(val); } processor.Converter = converter; } public static void SetConverter<T>(Il2CppJsonUnmanagedTypeConverter<T> converter) where T : unmanaged { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown if (converter == null) { throw new ArgumentNullException("converter"); } if (!NativeJsonProcessorStore.Prepare<T>(out var processor)) { return; } if (processor.Converter != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(76, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Converter (type: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") will be replaced! This would leads to unwanted behaviour!"); } Logger.Warn(val); Logger.Warn(" - Suggetion: If your converter does not require to deep-level altering of JSON, consider use Il2CppJsonUnmanagedTypeHandler instead."); val = new BepInExWarningLogInterpolatedStringHandler(22, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" - Previous Owner: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().Assembly.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(processor.Converter.GetType().FullName); } Logger.Warn(val); val = new BepInExWarningLogInterpolatedStringHandler(17, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" - New Owner: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().Assembly.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(converter.GetType().FullName); } Logger.Warn(val); } processor.Converter = converter; } public static void AddHandler<T>(Il2CppJsonReferenceTypeHandler<T> handler) where T : Il2CppObjectBase { if (handler == null) { throw new ArgumentNullException("handler"); } if (NativeJsonProcessorStore.Prepare<T>(out var processor)) { processor.Handlers.Add(handler); } } public static void AddHandler<T>(Il2CppJsonUnmanagedTypeHandler<T> handler) where T : unmanaged { if (handler == null) { throw new ArgumentNullException("handler"); } if (NativeJsonProcessorStore.Prepare<T>(out var processor)) { processor.Handlers.Add(handler); } } } internal class NativeJsonProcessor { public Type Type { get; set; } public DataSetConverter DummyConverter { get; set; } public INativeJsonConverter Converter { get; set; } public IList<INativeJsonHandler> Handlers { get; } = new List<INativeJsonHandler>(); public bool Enabled { get; set; } = true; public IntPtr ProcessRead(JsonReader reader, IntPtr existingValue, JsonSerializer serializer) { JToken jToken = JToken.ReadFrom(reader); IntPtr pointer; if (Converter != null) { pointer = ((Il2CppObjectBase)Converter.ReadJson(jToken, existingValue, serializer)).Pointer; } else { SetUsingContractConverter(serializer, use: false); pointer = ((Il2CppObjectBase)serializer.Deserialize(jToken.CreateReader(), Type)).Pointer; SetUsingContractConverter(serializer, use: true); } Object result = PtrToObject(pointer); foreach (INativeJsonHandler handler in Handlers) { handler.OnRead(in result, in jToken); } return pointer; } public void ProcessWrite(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer) { if (Converter != null) { Converter.WriteJson(writer, valueToWrite, serializer); return; } SetUsingContractConverter(serializer, use: false); serializer.Serialize(writer, PtrToObject(valueToWrite)); SetUsingContractConverter(serializer, use: true); } private static Object PtrToObject(IntPtr ptr) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (ptr == IntPtr.Zero) { return null; } return new Object(ptr); } private void SetUsingContractConverter(JsonSerializer serializer, bool use) { JsonContract val = serializer.ContractResolver.ResolveContract(Type); if (use) { val.Converter = (JsonConverter)(object)DummyConverter; val.InternalConverter = (JsonConverter)(object)DummyConverter; } else { val.Converter = null; val.InternalConverter = null; } } } internal static class NativeJsonProcessorStore { private static readonly Dictionary<IntPtr, NativeJsonProcessor> _RegisteredProcessors = new Dictionary<IntPtr, NativeJsonProcessor>(); internal static void Initialize() { Detour_JsonConverterTrampoline.Patch(); Detour_NativeConverterLink.Patch(); } public static bool Prepare<T>(out NativeJsonProcessor processor) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Type val = Il2CppType.From(typeof(T)); if (val != (Type)null && ((Il2CppObjectBase)val).Pointer != IntPtr.Zero) { if (_RegisteredProcessors.TryGetValue(((Il2CppObjectBase)val).Pointer, out processor)) { return true; } DataSetConverter val2 = new DataSetConverter(); NativeJsonProcessor nativeJsonProcessor2 = (_RegisteredProcessors[((Il2CppObjectBase)val).Pointer] = new NativeJsonProcessor()); processor = nativeJsonProcessor2; processor.Type = val; processor.DummyConverter = val2; val2.SetNativeJsonProcessor(processor); return true; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Type: '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(typeof(T).Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' is not in il2cpp domain!"); } Logger.Error(val3); processor = null; return false; } public static bool TryGetConverterPointer(IntPtr typePtr, out IntPtr converterPtr) { if (TryGetProcessor(typePtr, out var processor) && processor.DummyConverter != null) { converterPtr = ((Il2CppObjectBase)processor.DummyConverter).Pointer; return converterPtr != IntPtr.Zero; } converterPtr = IntPtr.Zero; return false; } public static bool TryGetProcessor(IntPtr typePtr, out NativeJsonProcessor processor) { if (_RegisteredProcessors.TryGetValue(typePtr, out processor) && processor != null && processor.Enabled) { return processor != null; } processor = null; return false; } } } namespace InjectLib.JsonNETInjection.Supports { internal interface IBaseConnector { NativeJsonProcessor Processor { get; set; } } public sealed class InjectLibConnector : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) { Type val = Il2CppType.From(typeToConvert, false); if (val != (Type)null && NativeJsonProcessorStore.TryGetProcessor(((Il2CppObjectBase)val).Pointer, out var _)) { return true; } return false; } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { if (!NativeJsonProcessorStore.TryGetProcessor(((Il2CppObjectBase)Il2CppType.From(typeToConvert, false)).Pointer, out var processor)) { return null; } if (typeToConvert.IsAssignableTo(typeof(Il2CppObjectBase))) { JsonConverter obj = (JsonConverter)Activator.CreateInstance(typeof(ReferenceTypeConnector<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, null, null, null); ((IBaseConnector)obj).Processor = processor; return obj; } if (typeToConvert.IsValueType) { JsonConverter obj2 = (JsonConverter)Activator.CreateInstance(typeof(ValueTypeConnector<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, null, null, null); ((IBaseConnector)obj2).Processor = processor; return obj2; } return null; } } public class InjectLibJSON { public static JsonSerializerOptions JsonOptions => new JsonSerializerOptions(JsonSerializer.DefaultSerializerSettingsWithLocalizedText) { Converters = { (JsonConverter)new InjectLibConnector() } }; public static T Deserialize<T>(string json, params JsonConverter[] converters) { JsonSerializerOptions jsonOptions = JsonOptions; if (converters != null) { foreach (JsonConverter item in converters) { jsonOptions.Converters.Add(item); } } return JsonSerializer.Deserialize<T>(json, jsonOptions); } public static object Deserialize(string json, Type type, params JsonConverter[] converters) { JsonSerializerOptions jsonOptions = JsonOptions; if (converters != null) { foreach (JsonConverter item in converters) { jsonOptions.Converters.Add(item); } } return JsonSerializer.Deserialize(json, type, jsonOptions); } public static string Serialize<T>(T obj, params JsonConverter[] converters) { JsonSerializerOptions jsonOptions = JsonOptions; if (converters != null) { foreach (JsonConverter item in converters) { jsonOptions.Converters.Add(item); } } return JsonSerializer.Serialize(obj, JsonOptions); } public static string Serialize(object obj, params JsonConverter[] converters) { JsonSerializerOptions jsonOptions = JsonOptions; if (converters != null) { foreach (JsonConverter item in converters) { jsonOptions.Converters.Add(item); } } return JsonSerializer.Serialize(obj, JsonOptions); } } internal class ReferenceTypeConnector<T> : JsonConverter<T>, IBaseConnector where T : Il2CppObjectBase { public NativeJsonProcessor Processor { get; set; } public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Type val = Il2CppType.From(typeToConvert, false); JsonNode jsonNode = JsonNode.Parse(ref reader); return (T)Activator.CreateInstance(typeof(T), ((Il2CppObjectBase)JsonConvert.DeserializeObject(jsonNode.ToJsonString(), val, (JsonSerializerSettings)null)).Pointer); } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value); } } internal class ValueTypeConnector<T> : JsonConverter<T>, IBaseConnector where T : unmanaged { public NativeJsonProcessor Processor { get; set; } public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Type val = Il2CppType.From(typeToConvert, false); return ((Il2CppObjectBase)JsonConvert.DeserializeObject(JsonNode.Parse(ref reader).ToJsonString(), val, (JsonSerializerSettings)null)).Unbox<T>(); } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value); } } } namespace InjectLib.JsonNETInjection.Handler { public abstract class Il2CppJsonReferenceTypeHandler<T> : INativeJsonHandler where T : Il2CppObjectBase { public abstract void OnRead(in Object result, in JToken jToken); } public abstract class Il2CppJsonUnmanagedTypeHandler<T> : INativeJsonHandler where T : unmanaged { public abstract void OnRead(in Object result, in JToken jToken); } internal interface INativeJsonHandler { void OnRead(in Object result, in JToken jToken); } } namespace InjectLib.JsonNETInjection.Detours { internal class Detour_JsonConverterTrampoline { public unsafe delegate IntPtr GetMatchingConverterDel(IntPtr converters, IntPtr objectType, Il2CppMethodInfo* methodInfo); private static INativeDetour _Detour; private static GetMatchingConverterDel _Original; public unsafe static void Patch() { _Detour = INativeDetour.CreateAndApply<GetMatchingConverterDel>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<JsonSerializer>("GetMatchingConverter", "Newtonsoft.Json.JsonConverter", false, new string[2] { "System.Collections.Generic.IList<Newtonsoft.Json.JsonConverter>", typeof(Type).FullName }), (GetMatchingConverterDel)Detour, ref _Original); } private unsafe static IntPtr Detour(IntPtr converters, IntPtr objectType, Il2CppMethodInfo* methodInfo) { if (NativeJsonProcessorStore.TryGetConverterPointer(objectType, out var converterPtr)) { return converterPtr; } return _Original(converters, objectType, methodInfo); } } internal class Detour_NativeConverterLink { public delegate IntPtr ReadJsonDel(IntPtr _this, IntPtr reader, IntPtr objectType, IntPtr existingValue, IntPtr serializer); public delegate void WriteJsonDel(IntPtr _this, IntPtr writer, IntPtr value, IntPtr serializer); private static INativeDetour _ReadDetour; private static INativeDetour _WriteDetour; private static ReadJsonDel _ReadOriginal; private static WriteJsonDel _WriteOriginal; public unsafe static void Patch() { void* il2CppMethod = Il2CppAPI.GetIl2CppMethod<DataSetConverter>("ReadJson", "System.Object", false, new string[4] { "Newtonsoft.Json.JsonReader", "System.Type", "System.Object", "Newtonsoft.Json.JsonSerializer" }); void* il2CppMethod2 = Il2CppAPI.GetIl2CppMethod<DataSetConverter>("WriteJson", typeof(void).FullName, false, new string[3] { "Newtonsoft.Json.JsonWriter", "System.Object", "Newtonsoft.Json.JsonSerializer" }); _ReadDetour = INativeDetour.CreateAndApply<ReadJsonDel>((IntPtr)(nint)il2CppMethod, (ReadJsonDel)Detour_Read, ref _ReadOriginal); _WriteDetour = INativeDetour.CreateAndApply<WriteJsonDel>((IntPtr)(nint)il2CppMethod2, (WriteJsonDel)Detour_Write, ref _WriteOriginal); } private static IntPtr Detour_Read(IntPtr _this, IntPtr reader, IntPtr objectType, IntPtr existingValue, IntPtr serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown NativeJsonProcessor nativeJsonProcessor = FieldsExtension.GetNativeJsonProcessor(new DataSetConverter(_this)); if (nativeJsonProcessor != null) { JsonReader reader2 = new JsonReader(reader); JsonSerializer serializer2 = new JsonSerializer(serializer); return nativeJsonProcessor.ProcessRead(reader2, existingValue, serializer2); } return _ReadOriginal(_this, reader, objectType, existingValue, serializer); } private static void Detour_Write(IntPtr _this, IntPtr writer, IntPtr value, IntPtr serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown NativeJsonProcessor nativeJsonProcessor = FieldsExtension.GetNativeJsonProcessor(new DataSetConverter(_this)); if (nativeJsonProcessor != null) { JsonWriter writer2 = new JsonWriter(writer); JsonSerializer serializer2 = new JsonSerializer(serializer); nativeJsonProcessor.ProcessWrite(writer2, value, serializer2); } else { _WriteOriginal(_this, writer, value, serializer); } } } } namespace InjectLib.JsonNETInjection.Converter { public abstract class Il2CppJsonReferenceTypeConverter<T> : INativeJsonConverter where T : Il2CppObjectBase { public virtual string Name => GetType().Name; public Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer) { if (existingValue == IntPtr.Zero) { return ((Il2CppObjectBase)Read(jToken, default(T), serializer)).Cast<Object>(); } T existingValue2 = (T)Activator.CreateInstance(typeof(T), existingValue); return ((Il2CppObjectBase)Read(jToken, existingValue2, serializer)).Cast<Object>(); } public void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer) { if (valueToWrite == IntPtr.Zero) { Write(writer, default(T), serializer); return; } T value = (T)Activator.CreateInstance(typeof(T), valueToWrite); Write(writer, value, serializer); } protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer); protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer); } public abstract class Il2CppJsonUnmanagedTypeConverter<T> : INativeJsonConverter where T : unmanaged { public virtual string Name => GetType().Name; public Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (existingValue == IntPtr.Zero) { return ToIl2CppObject(Read(jToken, default(T), serializer)); } Object val = new Object(existingValue); return ToIl2CppObject(Read(jToken, ((Il2CppObjectBase)val).Unbox<T>(), serializer)); } public void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (valueToWrite == IntPtr.Zero) { Write(writer, default(T), serializer); return; } Object val = new Object(valueToWrite); Write(writer, ((Il2CppObjectBase)val).Unbox<T>(), serializer); } protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer); protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer); protected abstract Object ToIl2CppObject(T value); } internal interface INativeJsonConverter { string Name { get; } Object ReadJson(JToken jToken, IntPtr existingValue, JsonSerializer serializer); void WriteJson(JsonWriter writer, IntPtr valueToWrite, JsonSerializer serializer); } } namespace InjectLib.FieldInjection { public static class FieldInjector<Il2CppType> where Il2CppType : Il2CppObjectBase { private static readonly Dictionary<string, InjectedFieldInfo> _OffsetLookup = new Dictionary<string, InjectedFieldInfo>(); public static void DefineValueField<Value>(string fieldName) where Value : unmanaged { if (!_OffsetLookup.ContainsKey(fieldName)) { InjectValueField<Value>(fieldName); } } public static void DefineManagedField<Value>(string fieldName) where Value : class { if (!_OffsetLookup.ContainsKey(fieldName)) { InjectManagedField<Value>(fieldName); } } private unsafe static void InjectManagedField<Value>(string fieldName) where Value : class { int num = 8; INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<Il2CppType>.NativeClassPtr); val.InstanceSize += (uint)num; val.ActualSize = val.InstanceSize; _OffsetLookup[fieldName] = new InjectedFieldInfo { FieldOffset = (nint)(val.InstanceSize - num), FieldSize = num }; } public unsafe static bool TryGetManagedField<Value>(Il2CppType obj, string fieldName, out Value value) where Value : class { if (obj == null) { value = null; return false; } if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero) { value = null; return false; } if (!_OffsetLookup.TryGetValue(fieldName, out var value2)) { value = null; return false; } if (8 != value2.FieldSize) { value = null; return false; } ulong num = *(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset); if (num == 0L) { value = null; return false; } value = ManagedReferenceStore<Il2CppType, Value>.Get(num); return value != null; } public unsafe static bool TrySetManagedField<Value>(Il2CppType obj, string fieldName, Value value) where Value : class { if (obj == null) { return false; } if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero) { return false; } if (!_OffsetLookup.TryGetValue(fieldName, out var value2)) { return false; } if (8 != value2.FieldSize) { return false; } ulong num = *(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset); if (num == 0L) { ulong uniqueKey = ManagedReferenceStore<Il2CppType, Value>.UniqueKey; ManagedReferenceStore<Il2CppType, Value>.Set(uniqueKey, value); *(ulong*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset) = uniqueKey; return true; } ManagedReferenceStore<Il2CppType, Value>.Set(num, value); return true; } private static int SizeOfUnmanagedType<Value>() where Value : unmanaged { if (typeof(Value) == typeof(bool)) { return 1; } return Marshal.SizeOf<Value>(); } private unsafe static void InjectValueField<Value>(string fieldName) where Value : unmanaged { int num = SizeOfUnmanagedType<Value>(); INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<Il2CppType>.NativeClassPtr); val.InstanceSize += (uint)num; val.ActualSize = val.InstanceSize; _OffsetLookup[fieldName] = new InjectedFieldInfo { FieldOffset = (nint)(val.InstanceSize - num), FieldSize = num }; } public unsafe static bool TryGetValueField<Value>(Il2CppType obj, string fieldName, out Value value) where Value : unmanaged { if (obj == null) { value = default(Value); return false; } if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero) { value = default(Value); return false; } if (!_OffsetLookup.TryGetValue(fieldName, out var value2)) { value = default(Value); return false; } if (SizeOfUnmanagedType<Value>() != value2.FieldSize) { value = default(Value); return false; } value = *(Value*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset); return true; } public unsafe static bool TrySetValueField<Value>(Il2CppType obj, string fieldName, Value value) where Value : unmanaged { if (obj == null) { return false; } if (((Il2CppObjectBase)obj).Pointer == IntPtr.Zero) { return false; } if (!_OffsetLookup.TryGetValue(fieldName, out var value2)) { return false; } if (SizeOfUnmanagedType<Value>() != value2.FieldSize) { return false; } *(Value*)((nint)((Il2CppObjectBase)obj).Pointer + value2.FieldOffset) = value; return true; } } internal struct InjectedFieldInfo { public nint FieldOffset; public int FieldSize; } public static class ManagedReferenceStore<C, T> where C : Il2CppObjectBase where T : class { private static readonly Dictionary<ulong, T> _Lookup = new Dictionary<ulong, T>(); private static ulong _Key = 1uL; public static ulong UniqueKey => _Key++; public static T Get(ulong key) { _Lookup.TryGetValue(key, out var value); return value; } public static void Set(ulong key, T value) { _Lookup[key] = value; } public static void Remove(ulong key) { _Lookup.Remove(key); } } }
plugins/net6/LEGACY.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using BoosterImplants; using CellMenu; using ChainedPuzzles; using EOSExt.Reactor.Managers; using Enemies; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GTFO.API.Utilities; 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 LEGACY.ExtraEvents; using LEGACY.LegacyOverride; using LEGACY.LegacyOverride.ElevatorCargo; using LEGACY.LegacyOverride.EnemyTagger; using LEGACY.LegacyOverride.FogBeacon; using LEGACY.LegacyOverride.ForceFail; using LEGACY.LegacyOverride.Music; using LEGACY.LegacyOverride.SecDoorIntText; using LEGACY.LegacyOverride.Terminal; using LEGACY.Utils; using LEGACY.VanillaFix; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using ScanPosOverride.JSON; using ScanPosOverride.Managers; using TMPro; 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("LEGACY")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LEGACY")] [assembly: AssemblyTitle("LEGACY")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")] internal static class Patch_WatermarkUpdateWatermark { private static void Postfix(PUI_Watermark __instance) { string text = "4.6.1+gitf831086-dirty-main".Remove("x.x.x".Length); ((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>" + text + "</color>\n" + string.Empty + "<color=#00ae9d>LEGACY</color><color=orange> 3.8.8</color>", true); } } namespace LEGACY { internal static class Assets { public static GameObject OBSVisual { get; private set; } public static GameObject ObjectiveMarker { get; private set; } public static void Init() { OBSVisual = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/OBSVisual.prefab"); ObjectiveMarker = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/ObjectiveMarker.prefab"); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("GTFO.AWO")] [BepInPlugin("Inas.LEGACY", "LEGACY", "3.8.8")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string RUNDOWN_NAME = "LEGACY"; public const string VERSION = "3.8.8"; public const bool TESTING = false; public const string TEST_STRING = "TESTING"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("LEGACY"); m_Harmony.PatchAll(); LegacyOverrideManagers.Init(); LegacyExtraEvents.Init(); LEGACY.VanillaFix.Debugger.Current.Init(); AssetAPI.OnAssetBundlesLoaded += Assets.Init; } } } namespace LEGACY.Reactor { [HarmonyPatch] internal class Patch_ReactorShutdown { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static void Post_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected I4, but got Unknown //IL_007e: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || oldState.status == newState.status) { return; } WardenObjectiveDataBlock val = null; if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null) { LegacyLogger.Error("Patch_ReactorShutdown: "); LegacyLogger.Error("Failed to get warden objective"); } else if ((int)val.Type == 2 && !val.OnActivateOnSolveItem) { eWardenObjectiveEventTrigger val2 = (eWardenObjectiveEventTrigger)0; eReactorStatus status = newState.status; switch (status - 7) { default: return; case 0: val2 = (eWardenObjectiveEventTrigger)1; break; case 1: val2 = (eWardenObjectiveEventTrigger)2; break; case 2: val2 = (eWardenObjectiveEventTrigger)3; break; } _ = __instance.SpawnNode.LayerType; WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val.EventsOnActivate, val2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Pre_OnBuildDone_ChainedPuzzleMidObjectiveFix(LG_WardenObjective_Reactor __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = null; if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null) { LegacyLogger.Error("Patch_ReactorShutdown: Failed to get warden objective"); } else if (val.ChainedPuzzleMidObjective != 0) { __instance.m_chainedPuzzleAlignMidObjective = __instance.m_chainedPuzzleAlign; } } [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")] private static bool Pre_Update(LG_WardenObjective_Reactor __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)__instance.m_currentState.status != 7) { return true; } if (!__instance.m_currentWaveData.HasVerificationTerminal) { return true; } __instance.SetGUIMessage(true, Text.Format(3000u, (Object[])(object)new Object[1] { Object.op_Implicit("<color=orange>" + __instance.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, false, "", ""); return false; } } [HarmonyPatch] internal class Patch_ReactorStartup_ExtraEventsExecution { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static void Post_ExecuteOnNoneEventsOnDefenseStart(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (oldState.status != newState.status && (int)newState.status == 3) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)0, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Post_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 WardenObjectiveDataBlock db = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref db) || db == null) { LegacyLogger.Error("Patch_ReactorStartup_ExtraEventsExecution: "); LegacyLogger.Error("Failed to get warden objective"); } else if ((int)db.Type == 1 && !db.OnActivateOnSolveItem) { ChainedPuzzleInstance chainedPuzzleToStartSequence = __instance.m_chainedPuzzleToStartSequence; chainedPuzzleToStartSequence.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(db.EventsOnActivate, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); }); } } } [HarmonyPatch] internal class Patch_ReactorStartup_OverwriteGUIBehaviour { private static HashSet<uint> ForceDisableLevels; [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static bool Pre_HideReactorMessageForInfiniteWave(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //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) //IL_0020: Invalid comparison between Unknown and I4 //IL_0037: 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_0022: 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_0029: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected I4, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) if (oldState.status == newState.status) { return true; } if ((int)newState.status != 2 && (int)newState.status != 3 && (int)newState.status != 4) { return true; } if (ForceDisable()) { if (oldState.stateCount != newState.stateCount) { __instance.OnStateCountUpdate(newState.stateCount); } if (oldState.stateProgress != newState.stateProgress) { __instance.OnStateProgressUpdate(newState.stateProgress); } __instance.ReadyForVerification = false; eReactorStatus status = newState.status; switch (status - 2) { case 0: { WardenObjectiveDataBlock val = null; if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null) { LegacyLogger.Error("Patch_ReactorStartup_OverwriteGUIBehaviour: "); LegacyLogger.Error("Failed to get warden objective datablock"); break; } __instance.m_lightCollection.SetMode(val.LightsOnDuringIntro); __instance.m_lightCollection.ResetUpdateValues(true); __instance.lcReset = true; __instance.m_lightsBlinking = false; __instance.m_spawnEnemies = false; __instance.m_progressUpdateEnabled = true; __instance.m_alarmCountdownPlayed = false; __instance.m_currentDuration = ((!newState.verifyFailed) ? __instance.m_currentWaveData.Warmup : __instance.m_currentWaveData.WarmupFail); WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)1, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); if (__instance.m_currentWaveCount == 1) { Debug.LogError(Object.op_Implicit("Reactor IDLE START")); __instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_LOOP, true); __instance.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 0f); } else { Debug.LogError(Object.op_Implicit("Reactor REACTOR_POWER_DOWN")); __instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_2_TO_1_TRANSITION, true); __instance.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 0f); } break; } case 1: __instance.m_lightCollection.ResetUpdateValues(true); __instance.lcReset = true; __instance.m_spawnEnemies = true; __instance.m_currentEnemyWaveIndex = 0; __instance.m_alarmCountdownPlayed = false; __instance.m_progressUpdateEnabled = true; __instance.m_currentDuration = __instance.m_currentWaveData.Wave; __instance.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_TO_3_TRANSITION, true); break; case 2: __instance.m_lightCollection.ResetUpdateValues(false); __instance.lcReset = true; __instance.m_spawnEnemies = false; __instance.m_progressUpdateEnabled = true; __instance.ReadyForVerification = true; Debug.Log(Object.op_Implicit("Wait for verify! newState.verifyFailed? " + newState.verifyFailed)); __instance.m_currentDuration = ((!newState.verifyFailed) ? __instance.m_currentWaveData.Verify : __instance.m_currentWaveData.VerifyFail); WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); break; } __instance.m_currentState = newState; return false; } return true; } private static bool ForceDisable() { return ForceDisableLevels.Contains(RundownManager.ActiveExpedition.LevelLayoutData); } static Patch_ReactorStartup_OverwriteGUIBehaviour() { ForceDisableLevels = new HashSet<uint>(); LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L3E2_L1"); if (block != null) { ForceDisableLevels.Add(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID); } block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L1E1_L1"); if (block != null) { ForceDisableLevels.Add(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID); } } } } namespace LEGACY.HardcodedBehaviours { [HarmonyPatch] internal class Patch_PickupItem_Hardcoded { [HarmonyPrefix] [HarmonyPatch(typeof(LG_Distribute_PickupItemsPerZone), "Build")] private static void Pre_LG_Distribute_PickupItemsPerZone(LG_Distribute_PickupItemsPerZone __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock("Legacy_L2E1_Gridlock"); if (block == null || RundownManager.ActiveExpedition.LevelLayoutData != ((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID) { return; } eLocalZoneIndex localIndex = __instance.m_zone.LocalIndex; if ((int)localIndex != 10) { if ((int)localIndex == 11) { __instance.m_zonePlacementWeights.Start = 0f; __instance.m_zonePlacementWeights.Middle = 5000f; __instance.m_zonePlacementWeights.End = 5000f; } } else { __instance.m_zonePlacementWeights.Start = 10000f; __instance.m_zonePlacementWeights.Middle = 0f; __instance.m_zonePlacementWeights.End = 0f; } } } } namespace LEGACY.VanillaFix { [HarmonyPatch] internal class Patch_FixHiddenCommandExecution { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] private static void Pre_TerminalInterpreter_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected I4, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 TERM_Command val = cmd; switch (val - 1) { default: if ((int)val != 43) { break; } goto case 0; case 0: case 1: case 2: case 3: case 11: case 13: case 14: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: if (__instance.m_terminal.CommandIsHidden(cmd)) { cmd = (TERM_Command)10; } break; case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 12: case 15: case 16: break; } } } [HarmonyPatch] internal class Patch_FixScoutFreeze { [HarmonyPrefix] [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] private static bool Prefix_Debug(ES_ScoutScream __instance) { if (((AgentAI)((ES_Base)__instance).m_ai).Target == null) { return false; } return true; } } [HarmonyPatch] internal class Patch_LG_SecurityDoor_Fix_EventsOnUnlockDoor_Powergenerator { [HarmonyPrefix] [HarmonyPatch(typeof(LG_SecurityDoor), "OnSyncDoorStatusChange")] private static void Pre_OnSyncDoorStatusChange(LG_SecurityDoor __instance, pDoorState state, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 eDoorStatus status = state.status; if ((status - 4 <= 1 || (int)status == 9) && (int)__instance.m_lastState.status == 6) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.LinkedToZoneData.EventsOnUnlockDoor, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } } [HarmonyPatch] internal class Patch_LockSecurityDoor_FixCustomText { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })] private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor door, LG_SecurityDoor_Locks __instance) { LocalizedText customText = door.LinkedToZoneData.ProgressionPuzzleToEnter.CustomText; __instance.m_lockedWithNoKeyInteractionText = customText; } } [HarmonyPatch] internal class Debugger { public static Debugger Current { get; private set; } = new Debugger(); public bool DEBUGGING { get; private set; } private Debugger() { } internal void Init() { _ = DEBUGGING; } } [HarmonyPatch] [HarmonyWrapSafe] internal class Patch_RepeatableCommandEventFix { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "SetupCommandEvents")] private static void Post_ResetupChainedPuzzleAfterExecution(LG_ComputerTerminalCommandInterpreter __instance) { //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected I4, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Invalid comparison between Unknown and I4 //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Invalid comparison between Unknown and I4 //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Invalid comparison between Unknown and I4 //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 uint num = 0u; if ((Object)(object)__instance.m_terminal.ConnectedReactor != (Object)null) { return; } if (__instance.m_terminal.SpawnNode.m_dimension.IsMainDimension) { LG_LayerType layerType = __instance.m_terminal.SpawnNode.LayerType; switch ((int)layerType) { case 0: num = RundownManager.ActiveExpedition.LevelLayoutData; break; case 1: num = RundownManager.ActiveExpedition.SecondaryLayout; break; case 2: num = RundownManager.ActiveExpedition.ThirdLayout; break; default: LegacyLogger.Error("Unimplemented layer type."); return; } } else { num = __instance.m_terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData; } LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num); List<CustomTerminalCommand> val = null; int num2 = __instance.m_terminal.SpawnNode.m_zone.TerminalsSpawnedInZone.IndexOf(__instance.m_terminal); ExpeditionZoneData val2 = null; Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.LocalIndex == __instance.m_terminal.SpawnNode.m_zone.LocalIndex) { val2 = current; break; } } if (val2 == null) { LegacyLogger.Error("Cannot find target zone data."); return; } if (num2 >= val2.TerminalPlacements.Count) { LegacyLogger.Debug("RepeatableCommand: TerminalDataIndex >= TargetZoneData.TerminalPlacements.Count: found sec-door terminal, skipping"); return; } val = val2.TerminalPlacements[num2].UniqueCommands; if (val.Count == 0) { return; } Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator(); TERM_Command val3 = default(TERM_Command); string text = default(string); string text2 = default(string); while (enumerator2.MoveNext()) { CustomTerminalCommand current2 = enumerator2.Current; if ((int)current2.SpecialCommandRule != 0 || !__instance.TryGetCommand(current2.Command, ref val3, ref text, ref text2) || ((int)val3 != 38 && (int)val3 != 39 && (int)val3 != 40 && (int)val3 != 41 && (int)val3 != 42)) { continue; } ChainedPuzzleInstance OldCPInstance = null; List<WardenObjectiveEventData> commandEvents = current2.CommandEvents; for (int i = 0; i < commandEvents.Count && (commandEvents[i].ChainPuzzle == 0 || !__instance.m_terminal.TryGetChainPuzzleForCommand(val3, i, ref OldCPInstance) || !((Object)(object)OldCPInstance != (Object)null)); i++) { } if (!((Object)(object)OldCPInstance == (Object)null)) { ChainedPuzzleInstance obj = OldCPInstance; obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate { Helper.ResetChainedPuzzle(OldCPInstance); }); } } } } } namespace LEGACY.Utils { public delegate float EasingFunction(float t, float b, float c, float d); public delegate bool BoolCheck(); internal static class CoroutineEase { private static IEnumerator DoEaseLocalScale(Transform trans, Vector3 startScale, Vector3 targetScale, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) bool doAbort = false; while (Clock.Time < startTime + duration && !doAbort) { doAbort = checkAbort?.Invoke() ?? false; float num = ease(Clock.Time - startTime, 0f, 1f, duration); trans.localScale = Vector3.Lerp(startScale, targetScale, num); yield return null; } trans.localScale = targetScale; if (!doAbort) { onDone?.Invoke(); } } private static IEnumerator DoEaseLocalPos(Transform trans, Vector3 sourcePos, Vector3 targetPos, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) bool doAbort = false; while (Clock.Time < startTime + duration && !doAbort) { doAbort = checkAbort?.Invoke() ?? false; float num = ease(Clock.Time - startTime, 0f, 1f, duration); trans.localPosition = Vector3.Lerp(sourcePos, targetPos, num); yield return null; } trans.localPosition = targetPos; if (!doAbort) { onDone?.Invoke(); } } private static IEnumerator DoEaseLocalRot(Transform trans, Vector3 sourceEuler, Vector3 targetEuler, float startTime, float duration, EasingFunction ease, Action onDone, BoolCheck checkAbort) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) bool doAbort = false; while (Clock.Time < startTime + duration && !doAbort) { doAbort = checkAbort?.Invoke() ?? false; float num = ease(Clock.Time - startTime, 0f, 1f, duration); trans.localEulerAngles = Vector3.Lerp(sourceEuler, targetEuler, num); yield return null; } trans.localEulerAngles = targetEuler; if (!doAbort) { onDone?.Invoke(); } } internal static Coroutine EaseLocalScale(Transform trans, Vector3 startScale, Vector3 targetScale, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo); return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalScale(trans, startScale, targetScale, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null); } internal static Coroutine EaseLocalPos(Transform trans, Vector3 sourcePos, Vector3 targetPos, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo); return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalPos(trans, sourcePos, targetPos, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null); } internal static Coroutine EaseLocalRot(Transform trans, Vector3 sourceEuler, Vector3 targetEuler, float duration, EasingFunction ease = null, Action onDone = null, BoolCheck checkAbort = null) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) EasingFunction ease2 = ease ?? new EasingFunction(Easing.EaseOutExpo); return CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoEaseLocalRot(trans, sourceEuler, targetEuler, Clock.Time, duration, ease2, onDone, checkAbort)), (Action)null); } } public static class Helper { private static void ResetChild(iChainedPuzzleCore ICore) { CP_Bioscan_Core val = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val != (Object)null) { ((Il2CppObjectBase)val.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f); ((Il2CppObjectBase)val.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f); return; } CP_Cluster_Core val2 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>(); if ((Object)(object)val2 == (Object)null) { LegacyLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core..."); return; } ((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f); foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val2.m_childCores) { ResetChild(item); } } public static void ResetChainedPuzzle(ChainedPuzzleInstance chainedPuzzleInstance) { foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzleInstance.m_chainedPuzzleCores) { ResetChild(item); } if (SNet.IsMaster) { chainedPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)2); } } public static bool TryGetComponent<T>(this GameObject obj, out T comp) { comp = obj.GetComponent<T>(); return comp != null; } public static bool IsPlayerInLevel(PlayerAgent player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 return (int)player.Owner.Load<pGameState>().gameState == 10; } public static ChainedPuzzleInstance GetChainedPuzzleForCommandOnTerminal(LG_ComputerTerminal terminal, string command) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Invalid comparison between Unknown and I4 //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Invalid comparison between Unknown and I4 //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Invalid comparison between Unknown and I4 //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Invalid comparison between Unknown and I4 uint num = 0u; if (terminal.SpawnNode.m_dimension.IsMainDimension) { LG_LayerType layerType = terminal.SpawnNode.LayerType; switch ((int)layerType) { case 0: num = RundownManager.ActiveExpedition.LevelLayoutData; break; case 1: num = RundownManager.ActiveExpedition.SecondaryLayout; break; case 2: num = RundownManager.ActiveExpedition.ThirdLayout; break; default: LegacyLogger.Error("Unimplemented layer type."); return null; } } else { num = terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData; } LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num); List<CustomTerminalCommand> val = null; List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone; int num2 = terminalsSpawnedInZone.IndexOf(terminal); ExpeditionZoneData val2 = null; Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.LocalIndex == terminal.SpawnNode.m_zone.LocalIndex) { val2 = current; break; } } if (val2 == null) { LegacyLogger.Error("Cannot find target zone data."); return null; } if (val2.TerminalPlacements.Count != terminalsSpawnedInZone.Count) { LegacyLogger.Error("The numbers of terminal placement and spawn, skipped for the zone terminal."); return null; } val = val2.TerminalPlacements[num2].UniqueCommands; if (val.Count == 0) { return null; } List<WardenObjectiveEventData> val3 = null; TERM_Command val4 = (TERM_Command)0; Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator(); string text = default(string); string text2 = default(string); while (enumerator2.MoveNext()) { CustomTerminalCommand current2 = enumerator2.Current; if (current2.Command == command) { val3 = current2.CommandEvents; if (!terminal.m_command.TryGetCommand(current2.Command, ref val4, ref text, ref text2)) { LegacyLogger.Error("Cannot get TERM_COMMAND for command {0} on the specified terminal."); } break; } } if (val3 == null || (int)val4 == 0) { return null; } if ((int)val4 != 38 && (int)val4 != 39 && (int)val4 != 40 && (int)val4 != 41 && (int)val4 != 42) { return null; } ChainedPuzzleInstance val5 = null; for (int i = 0; i < val3.Count && (val3[i].ChainPuzzle == 0 || !terminal.TryGetChainPuzzleForCommand(val4, i, ref val5) || !((Object)(object)val5 != (Object)null)); i++) { } return val5; } public static bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door) { if ((Object)(object)zone == (Object)null) { door = null; return false; } if ((Object)(object)zone.m_sourceGate == (Object)null) { door = null; return false; } if (zone.m_sourceGate.SpawnedDoor == null) { door = null; return false; } door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>(); return (Object)(object)door != (Object)null; } internal static bool isSecDoorToZoneOpened(LG_Zone zone14) { //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_0029: Invalid comparison between Unknown and I4 LG_SecurityDoor door = null; if (!TryGetZoneEntranceSecDoor(zone14, out door) || (Object)(object)door == (Object)null) { return false; } return (int)door.m_sync.GetCurrentSyncState().status == 10; } public static List<T> cast<T>(List<T> list) { List<T> list2 = new List<T>(); Enumerator<T> enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; list2.Add(current); } return list2; } private static eDimensionIndex GetCurrentDimensionIndex() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (PlayerManager.PlayerAgentsInLevel.Count <= 0) { throw new Exception("? You don't have any player agent in level? How could that happen?"); } return ((Agent)PlayerManager.PlayerAgentsInLevel[0]).DimensionIndex; } public static void GetMinLayerAndLocalIndex(out LG_LayerType MinLayer, out eLocalZoneIndex MinLocalIndex) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between I4 and Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between I4 and Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected I4, but got Unknown MinLayer = (LG_LayerType)2; MinLocalIndex = (eLocalZoneIndex)20; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (IsPlayerInLevel(current)) { if ((int)MinLayer > (int)current.m_courseNode.LayerType) { MinLayer = (LG_LayerType)(int)current.m_courseNode.LayerType; MinLocalIndex = (eLocalZoneIndex)20; } if ((int)MinLocalIndex >= (int)current.m_courseNode.m_zone.LocalIndex) { MinLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex; } } } } public static void GetMaxLayerAndLocalIndex(out LG_LayerType MaxLayer, out eLocalZoneIndex MaxLocalIndex) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between I4 and Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between I4 and Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected I4, but got Unknown MaxLayer = (LG_LayerType)0; MaxLocalIndex = (eLocalZoneIndex)0; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (IsPlayerInLevel(current)) { if ((int)MaxLayer < (int)current.m_courseNode.LayerType) { MaxLayer = (LG_LayerType)(int)current.m_courseNode.LayerType; MaxLocalIndex = (eLocalZoneIndex)0; } if ((int)MaxLocalIndex < (int)current.m_courseNode.m_zone.LocalIndex) { MaxLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex; } } } } public static int GetMinAreaIndex(LG_Zone zone) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)zone == (Object)null) { return -1; } LG_LayerType type = zone.m_layer.m_type; eLocalZoneIndex localIndex = zone.LocalIndex; GetCurrentDimensionIndex(); int num = zone.m_areas.Count; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (current.m_courseNode.LayerType != type || current.m_courseNode.m_zone.LocalIndex != localIndex) { continue; } int i = 0; for (List<LG_Area> areas = zone.m_areas; i < areas.Count; i++) { if (((Object)((Component)areas[i]).gameObject).GetInstanceID() == ((Object)((Component)current.m_courseNode.m_area).gameObject).GetInstanceID()) { if (num > i) { num = i; } break; } } } return num; } public static LG_ComputerTerminal FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, int terminalIndex) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = null; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"FindTerminal: Didn't find LG_Zone {dimensionIndex}, {layerType}, {localIndex}"); return null; } if (val.TerminalsSpawnedInZone == null || terminalIndex >= val.TerminalsSpawnedInZone.Count) { LegacyLogger.Error($"FindTerminal: Invalid terminal index {terminalIndex} - {((val.TerminalsSpawnedInZone != null) ? val.TerminalsSpawnedInZone.Count : 0)} terminals are spawned in {dimensionIndex}, {layerType}, {localIndex}"); return null; } if (terminalIndex >= 0) { return val.TerminalsSpawnedInZone[terminalIndex]; } return null; } public static AIG_NodeCluster GetNodeFromDimensionPosition(eDimensionIndex dimensionIndex, Vector3 position) { //IL_0001: 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_0012: 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) AIG_GeomorphNodeVolume val = default(AIG_GeomorphNodeVolume); AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar); AIG_INode val3 = default(AIG_INode); AIG_NodeCluster result = default(AIG_NodeCluster); if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, dimensionIndex, position, ref val) || !((AIG_NodeVolume)val).m_voxelNodeVolume.TryGetPillar(position, ref val2) || !val2.TryGetVoxelNode(position.y, ref val3) || !AIG_NodeCluster.TryGetNodeCluster(val3.ClusterID, ref result)) { LegacyLogger.Error("TryWarpTo : Position is not valid, try again inside an area."); return null; } return result; } } internal static class Json { private static readonly JsonSerializerOptions _setting; static Json() { _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = false, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new JsonStringEnumConverter()); _setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter); _setting.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter); } public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, _setting); } public static object Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize<T>(T value) { return JsonSerializer.Serialize(value, _setting); } public static void Load<T>(string filePath, out T config) where T : new() { config = Deserialize<T>(File.ReadAllText(filePath)); } } internal static class LegacyLogger { private static ManualLogSource logger = Logger.CreateLogSource("LEGACYCore"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } public class SpawnHibernateEnemiesEvent { public eWardenObjectiveEventTrigger Trigger { get; set; } public int Type { get; set; } = 170; public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType Layer { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public string WorldEventObjectFilter { get; set; } = "RANDOM"; public uint EnemyID { get; set; } public int Count { get; set; } = 1; public float Delay { get; set; } public float Duration { get; set; } = 2f; } public class WeightedAreaSelector { private static readonly Dictionary<LG_Zone, WeightedAreaSelector> dict; private WeightedRandomBag<LG_Area> weightedRandomBag; public static WeightedAreaSelector Get(LG_Zone zone) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) //IL_0059: Expected I4, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!dict.ContainsKey(zone)) { WeightedAreaSelector weightedAreaSelector = new WeightedAreaSelector(); Enumerator<LG_Area> enumerator = zone.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { LG_Area current = enumerator.Current; float num = 0f; LG_AreaSize size = current.m_size; switch (size - 1) { case 4: num = 7f; break; case 0: num = 20f; break; case 1: num = 30f; break; case 2: num = 35f; break; case 3: num = 45f; break; default: LegacyLogger.Error($"Unhandled LG_AreaSize: {current.m_size}. Won't build."); return null; } weightedAreaSelector.AddEntry(current, num); } dict.Add(zone, weightedAreaSelector); } return dict[zone]; } public static WeightedAreaSelector Get(eDimensionIndex eDimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(eDimensionIndex, layerType, localIndex, ref val) || !Object.op_Implicit((Object)(object)val)) { return null; } return Get(val); } private WeightedAreaSelector() { weightedRandomBag = new WeightedRandomBag<LG_Area>(); } private void AddEntry(LG_Area area, float weight) { weightedRandomBag.AddEntry(area, weight); } public LG_Area GetRandom() { return weightedRandomBag.GetRandom(); } private static void OnBuildDone() { } private static void Clear() { dict.Clear(); } static WeightedAreaSelector() { dict = new Dictionary<LG_Zone, WeightedAreaSelector>(); LevelAPI.OnLevelCleanup += dict.Clear; } } public class WeightedRandomBag<T> { private struct Entry { public double accumulatedWeight; public T item; } private List<Entry> entries = new List<Entry>(); private double accumulatedWeight; private Random rand = new Random(); public void AddEntry(T item, double weight) { if (weight <= 0.0) { LegacyLogger.Error("AddEntry: no non-positive weight pls."); return; } accumulatedWeight += weight; entries.Add(new Entry { item = item, accumulatedWeight = accumulatedWeight }); } public T GetRandom() { double num = rand.NextDouble() * accumulatedWeight; foreach (Entry entry in entries) { if (entry.accumulatedWeight >= num) { return entry.item; } } return default(T); } } } namespace LEGACY.LegacyOverride { internal class NavMarkerManager { private Dictionary<string, GameObject> markerVisuals = new Dictionary<string, GameObject>(); private Dictionary<string, NavMarker> navMarkers = new Dictionary<string, NavMarker>(); private const bool USE_MARKER_VISUAL = true; public static NavMarkerManager Current { get; private set; } = new NavMarkerManager(); private GameObject InstantiateMarkerVisual() { //IL_0017: 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: 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) GameObject obj = Object.Instantiate<GameObject>(Assets.ObjectiveMarker); float num = 0.16216217f; Transform transform = obj.transform; transform.localPosition += Vector3.up * num; return obj; } public void EnableMarkerAt(string markerName, GameObject target, float scale) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (navMarkers.ContainsKey(markerName)) { navMarkers[markerName].SetVisible(true); } else { NavMarker val = GuiManager.NavMarkerLayer.PrepareGenericMarker(target); if ((Object)(object)val != (Object)null) { val.SetColor(new Color(0.855f, 0.482f, 0.976f)); val.SetStyle((eNavMarkerStyle)14); val.SetVisible(true); navMarkers[markerName] = val; } else { LegacyLogger.Error("EnableMarkerAt: got null nav marker"); } } GameObject val2 = null; if (markerVisuals.ContainsKey(markerName)) { val2 = markerVisuals[markerName]; } else { val2 = InstantiateMarkerVisual(); val2.transform.localScale = new Vector3(scale, scale, scale); val2.transform.SetPositionAndRotation(target.transform.position, Quaternion.identity); markerVisuals[markerName] = val2; } CoroutineManager.BlinkIn(val2, 0f); LegacyLogger.Debug("EnableMarker: marker " + markerName + " enabled"); } public void DisableMakrer(string markerName) { if (navMarkers.ContainsKey(markerName)) { navMarkers[markerName].SetVisible(false); } if (!markerVisuals.ContainsKey(markerName)) { LegacyLogger.Error("Marker " + markerName + " is not active"); return; } CoroutineManager.BlinkOut(markerVisuals[markerName], 0f); LegacyLogger.Debug("DisableMakrer: marker " + markerName + " disabled"); } public void Clear() { foreach (GameObject value in markerVisuals.Values) { Object.Destroy((Object)(object)value); } markerVisuals.Clear(); navMarkers.Clear(); } public GameObject FindTarget(int objectType, eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, int instanceIndex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject result = null; if (objectType == 0) { LG_ComputerTerminal val = Helper.FindTerminal(dimensionIndex, layer, localIndex, instanceIndex); if ((Object)(object)val != (Object)null) { result = ((Component)val).gameObject; } } else { LegacyLogger.Error($"Find Object of Type '{objectType}' is not implemented"); } return result; } private NavMarkerManager() { LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } internal static class LegacyOverrideManagers { internal static readonly string LEGACY_CONFIG_PATH = Path.Combine(MTFOPathAPI.CustomPath, "LegacyOverride"); internal static void Init() { ElevatorCargoOverrideManager.Current.Init(); FogBeaconSettingManager.Current.Init(); EnemyTaggerSettingManager.Current.Init(); SecDoorIntTextOverrideManager.Current.Init(); ((GenericExpeditionDefinitionManager<DimensionWarpPosition>)DimensionWarpPositionManager.Current).Init(); ForceFailManager.Current.Init(); } } } namespace LEGACY.LegacyOverride.SecDoorIntText { public class PositionAndLookDir { public Vec3 Position { get; set; } = new Vec3(); public int LookDir { get; set; } } public class WarpLocations { public string WorldEventObjectFilter { get; set; } = string.Empty; public List<PositionAndLookDir> Locations { get; set; } = new List<PositionAndLookDir>(); } public class DimensionWarpPosition { public eDimensionIndex DimensionIndex { get; set; } public List<WarpLocations> WarpLocations { get; set; } = new List<WarpLocations> { new WarpLocations() }; } internal class DimensionWarpPositionManager : GenericExpeditionDefinitionManager<DimensionWarpPosition> { public readonly List<PositionAndLookDir> DUMB = new List<PositionAndLookDir>(); public static DimensionWarpPositionManager Current { get; private set; } protected override string DEFINITION_NAME => "DimensionWarp"; public List<PositionAndLookDir> GetWarpPositions(eDimensionIndex dimensionIndex, string worldEventObjectFilter) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || !base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { LegacyLogger.Error($"GetWarpPositions: Didn't find config with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}"); return DUMB; } DimensionWarpPosition dimensionWarpPosition = base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.Find((DimensionWarpPosition def) => def.DimensionIndex == dimensionIndex); if (dimensionWarpPosition == null) { LegacyLogger.Error($"GetWarpPositions: Didn't find config for {dimensionIndex} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}"); return DUMB; } WarpLocations warpLocations = dimensionWarpPosition.WarpLocations.Find((WarpLocations position) => position.WorldEventObjectFilter == worldEventObjectFilter); if (warpLocations == null) { LegacyLogger.Error($"GetWarpPositions: Didn't find config for {worldEventObjectFilter} in {dimensionIndex} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}"); return DUMB; } return warpLocations.Locations; } private DimensionWarpPositionManager() { } static DimensionWarpPositionManager() { Current = new DimensionWarpPositionManager(); } } public class DoorToZone { public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType LayerType { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public LocalizedText Prefix { get; set; } public LocalizedText Postfix { get; set; } public LocalizedText TextToReplace { get; set; } } public class LevelSecDoorIntTextOverride { public uint MainLevelLayout { get; set; } public List<DoorToZone> doorToZones { get; set; } = new List<DoorToZone> { new DoorToZone() }; } internal class SecDoorIntTextOverrideManager { public static readonly SecDoorIntTextOverrideManager Current; private Dictionary<uint, LevelSecDoorIntTextOverride> SecDoorIntTextOverrides = new Dictionary<uint, LevelSecDoorIntTextOverride>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; internal LevelSecDoorIntTextOverride SettingForCurrentLevel { get; private set; } private void AddOverride(LevelSecDoorIntTextOverride _override) { if (_override != null) { if (SecDoorIntTextOverrides.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); SecDoorIntTextOverrides[_override.MainLevelLayout] = _override; } else { SecDoorIntTextOverrides.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new LevelSecDoorIntTextOverride())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<LevelSecDoorIntTextOverride>(item, out var config); AddOverride(config); } LevelAPI.OnBuildStart += UpdateSetting; liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { LevelSecDoorIntTextOverride @override = Json.Deserialize<LevelSecDoorIntTextOverride>(content); AddOverride(@override); if (GameStateManager.IsInExpedition) { UpdateSetting(); } }); } private void UpdateSetting() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; SettingForCurrentLevel = (SecDoorIntTextOverrides.ContainsKey(levelLayoutData) ? SecDoorIntTextOverrides[levelLayoutData] : null); } private SecDoorIntTextOverrideManager() { } static SecDoorIntTextOverrideManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "SecDoorIntText"); Current = new SecDoorIntTextOverrideManager(); } } } namespace LEGACY.LegacyOverride.Terminal { public struct TerminalState { public bool Enabled; public TerminalState() { Enabled = true; } public TerminalState(bool Enabled) { this.Enabled = true; this.Enabled = Enabled; } public TerminalState(TerminalState o) { Enabled = true; Enabled = o.Enabled; } } public class TerminalStateManager { private Dictionary<IntPtr, TerminalWrapper> terminals = new Dictionary<IntPtr, TerminalWrapper>(); public static TerminalStateManager Current { get; private set; } = new TerminalStateManager(); public void SetupTerminal(LG_ComputerTerminal terminal) { uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { LegacyLogger.Error("TerminalStateManager: replicator ID depleted, cannot setup terminal..."); return; } TerminalWrapper value = TerminalWrapper.Instantiate(terminal, num); terminals[((Il2CppObjectBase)terminal).Pointer] = value; } public TerminalWrapper Get(LG_ComputerTerminal lgTerminal) { if (!terminals.ContainsKey(((Il2CppObjectBase)lgTerminal).Pointer)) { return null; } return terminals[((Il2CppObjectBase)lgTerminal).Pointer]; } private void Clear() { terminals.Clear(); } private TerminalStateManager() { LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnBuildStart += Clear; } } public class TerminalWrapper { public LG_ComputerTerminal lgTerminal { get; private set; } public StateReplicator<TerminalState> stateReplicator { get; private set; } public void ChangeState(bool enabled) { stateReplicator.SetState(new TerminalState { Enabled = enabled }); } private void OnStateChanged(TerminalState oldState, TerminalState newState, bool isRecall) { if (oldState.Enabled == newState.Enabled) { return; } LegacyLogger.Debug($"{lgTerminal.ItemKey} state: {newState.Enabled}"); lgTerminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)lgTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true); bool enabled = newState.Enabled; if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = enabled; ((Interact_Base)componentInChildren).SetActive(enabled); } GUIX_VirtualSceneLink component = ((Component)lgTerminal).GetComponent<GUIX_VirtualSceneLink>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_virtualScene != (Object)null) { GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera; virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, enabled ? 0.3f : 0f, enabled ? 1000f : 0f); } if ((Object)(object)lgTerminal.m_text != (Object)null) { ((Behaviour)lgTerminal.m_text).enabled = enabled; } if (!enabled) { PlayerAgent localInteractionSource = lgTerminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { lgTerminal.ExitFPSView(); } } } public static TerminalWrapper Instantiate(LG_ComputerTerminal lgTerminal, uint replicatorID) { if ((Object)(object)lgTerminal == (Object)null || replicatorID == 0) { return null; } TerminalWrapper terminalWrapper = new TerminalWrapper(); terminalWrapper.lgTerminal = lgTerminal; terminalWrapper.stateReplicator = StateReplicator<TerminalState>.Create(replicatorID, new TerminalState { Enabled = true }, (LifeTimeType)1, (IStateReplicatorHolder<TerminalState>)null); terminalWrapper.stateReplicator.OnStateChanged += terminalWrapper.OnStateChanged; return terminalWrapper; } private TerminalWrapper() { } } } namespace LEGACY.LegacyOverride.FogBeacon { public class RepellerSphereSetting { public bool InfiniteDuration { get; set; } public float GrowDuration { get; set; } = 10f; public float ShrinkDuration { get; set; } = 10f; public float Range { get; set; } = 11f; } public class FogBeaconSetting { public uint MainLevelLayout { get; set; } public float TimeToPickup { get; set; } = 1f; public float TimeToPlace { get; set; } = 1f; public RepellerSphereSetting RSHold { get; set; } = new RepellerSphereSetting(); public RepellerSphereSetting RSPlaced { get; set; } = new RepellerSphereSetting(); } internal class FogBeaconSettingManager { public static readonly FogBeaconSettingManager Current; private Dictionary<uint, FogBeaconSetting> fogBeaconSettings = new Dictionary<uint, FogBeaconSetting>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; internal FogBeaconSetting SettingForCurrentLevel { get; private set; } private void AddOverride(FogBeaconSetting _override) { if (_override != null) { if (fogBeaconSettings.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); fogBeaconSettings[_override.MainLevelLayout] = _override; } else { fogBeaconSettings.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new FogBeaconSetting())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<FogBeaconSetting>(item, out var config); AddOverride(config); } LevelAPI.OnBuildStart += UpdateSetting; liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { FogBeaconSetting @override = Json.Deserialize<FogBeaconSetting>(content); AddOverride(@override); if (GameStateManager.IsInExpedition) { UpdateSetting(); } }); } private void UpdateSetting() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; SettingForCurrentLevel = (fogBeaconSettings.ContainsKey(levelLayoutData) ? fogBeaconSettings[levelLayoutData] : null); LegacyLogger.Debug($"FogBeaconSettingManager: updated setting for level with main level layout id {levelLayoutData}"); } private FogBeaconSettingManager() { } static FogBeaconSettingManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "FogBeaconSetting"); Current = new FogBeaconSettingManager(); } } } namespace LEGACY.LegacyOverride.ElevatorCargo { internal class ElevatorCargoOverrideManager { public static readonly ElevatorCargoOverrideManager Current; private Dictionary<uint, LevelElevatorCargo> elevatorCargos = new Dictionary<uint, LevelElevatorCargo>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; private void AddOverride(LevelElevatorCargo _override) { if (_override != null) { if (elevatorCargos.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); elevatorCargos[_override.MainLevelLayout] = _override; } else { elevatorCargos.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new LevelElevatorCargo())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<LevelElevatorCargo>(item, out var config); AddOverride(config); } liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { LevelElevatorCargo @override = Json.Deserialize<LevelElevatorCargo>(content); AddOverride(@override); }); } internal LevelElevatorCargo GetLevelElevatorCargoItems(uint MainLevelLayout) { if (!elevatorCargos.ContainsKey(MainLevelLayout)) { return null; } return elevatorCargos[MainLevelLayout]; } private ElevatorCargoOverrideManager() { } static ElevatorCargoOverrideManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ElevatorCargoOverride"); Current = new ElevatorCargoOverrideManager(); } } public enum ItemType { Consumable, BigPickup } public class ElevatorCargoItem { public uint ItemID { get; set; } public ItemType ItemType { get; set; } } public class LevelElevatorCargo { public uint MainLevelLayout { get; set; } public bool ForceDisable { get; set; } public List<ElevatorCargoItem> ElevatorCargoItems { get; set; } = new List<ElevatorCargoItem>(); } } namespace LEGACY.LegacyOverride.Patches { [HarmonyPatch] internal class CustomizeSecDoorInteractionText { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")] private static void Post_Customize_SecDoor_Interaction_Text(pDoorState state, LG_SecurityDoor_Locks __instance) { //IL_001c: 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_0024: Invalid comparison between Unknown and I4 //IL_0026: 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_002d: Invalid comparison between Unknown and I4 //IL_0116: 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_0148: Unknown result type (might be due to invalid IL or missing references) LevelSecDoorIntTextOverride settingForCurrentLevel = SecDoorIntTextOverrideManager.Current.SettingForCurrentLevel; if (settingForCurrentLevel == null || ((int)state.status != 9 && (int)state.status != 5)) { return; } int num = settingForCurrentLevel.doorToZones.FindIndex((DoorToZone door) => door.DimensionIndex == __instance.m_door.Gate.DimensionIndex && door.LayerType == __instance.m_door.LinksToLayerType && door.LocalIndex == __instance.m_door.LinkedToZoneData.LocalIndex); if (num != -1) { DoorToZone doorToZone = settingForCurrentLevel.doorToZones[num]; _ = __instance.m_door; Interact_Timed intOpenDoor = __instance.m_intOpenDoor; string text = LocalizedText.op_Implicit(doorToZone.Prefix); string text2 = LocalizedText.op_Implicit(doorToZone.Postfix); string text3 = LocalizedText.op_Implicit(doorToZone.TextToReplace); if (string.IsNullOrEmpty(text)) { text = string.Empty; } if (string.IsNullOrEmpty(text2)) { text2 = string.Empty; } if (string.IsNullOrEmpty(text3)) { text3 = intOpenDoor.InteractionMessage; } intOpenDoor.InteractionMessage = text + "\n" + text3 + "\n" + text2; LegacyLogger.Debug($"SecDoorIntTextOverride: Override IntText. {doorToZone.LocalIndex}, {doorToZone.LayerType}, {doorToZone.DimensionIndex}"); } } } [HarmonyPatch] internal class RundownSelectionCustomization { [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "Setup")] private static void Post_CM_PageRundown_New(CM_PageRundown_New __instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u); if (block.RundownIdsToLoad.Count > 1 && block.RundownIdsToLoad.Count == 2) { ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[0] = new Vector3(-320f, 75f, 0f); ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[1] = new Vector3(320f, 0f, 0f); Vector3 zero = Vector3.zero; for (int i = block.RundownIdsToLoad.Count; i < ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions).Count; i++) { zero = ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[i]; ((Il2CppArrayBase<Vector3>)(object)__instance.m_rundownSelectionPositions)[i] = new Vector3(zero.x, -10000f, zero.z); } zero = __instance.m_textRundownHeaderTop.transform.position; __instance.m_textRundownHeaderTop.transform.position = new Vector3(zero.x, -350f, zero.z); } } private static void SetSelectionScale(CM_PageRundown_New p) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u); if (block.RundownIdsToLoad.Count > 1 && block.RundownIdsToLoad.Count == 2) { CM_RundownSelection obj = p.m_rundownSelections[0]; CM_RundownSelection val = p.m_rundownSelections[1]; ((Component)obj).transform.localScale = new Vector3(2f, 2f, 2f) * 1.625f; ((Component)val).transform.localScale = new Vector3(1.25f, 1.25f, 1.25f) * 1.5f; Transform transform = obj.m_rundownText.transform; Quaternion localRotation = (val.m_rundownText.transform.localRotation = Quaternion.AngleAxis(45f, Vector3.right)); transform.localRotation = localRotation; obj.m_rundownText.transform.localPosition = Vector3.up * 60f + Vector3.right * 20f; val.m_rundownText.transform.localPosition = Vector3.up * 85f + Vector3.left * 25f; Transform transform2 = ((Component)obj).transform; localRotation = (((Component)val).transform.localRotation = Quaternion.AngleAxis(-45f, Vector3.right)); transform2.localRotation = localRotation; } } [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "UpdateRundownSelectionButton")] private static void Post_UpdateRundownSelectionButton(CM_PageRundown_New __instance) { SetSelectionScale(__instance); } private static IEnumerator reverseReveal(CM_PageRundown_New p, bool hosting, Transform guixSurfaceTransform) { float arrowScale = p.m_tierSpacing * 5f * p.m_tierSpaceToArrowScale; if (hosting) { CoroutineManager.BlinkIn(p.m_buttonConnect, 0f, (Transform)null); yield return (object)new WaitForSeconds(0.1f); yield return (object)new WaitForSeconds(0.24f); ((RectTransformComp)p.m_buttonConnect).SetVisible(false); } CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_MOVE_UP, ""); yield return CoroutineEase.EaseLocalPos(guixSurfaceTransform, Vector3.zero, new Vector3(0f, 650f, 0f), 0.5f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null); yield return (object)new WaitForSeconds(0.1f); CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_SHRINK, ""); CoroutineEase.EaseLocalScale(p.m_textRundownHeader.transform, Vector3.one, new Vector3(0.6f, 0.6f, 0.6f), 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null); yield return CoroutineEase.EaseLocalScale(guixSurfaceTransform, Vector3.one, new Vector3(0.2f, 0.2f, 0.2f), 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null); yield return (object)new WaitForSeconds(0.1f); CoroutineEase.EaseLocalPos(p.m_textRundownHeader.transform, p.m_textRundownHeader.transform.localPosition, p.m_rundownHeaderPos, 0.2f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null); CoroutineManager.BlinkIn(p.m_rundownIntelButton, 0f, (Transform)null); yield return (object)new WaitForSeconds(0.2f); CM_PageBase.PostSound(EVENTS.MENU_SURFACE_LEVEL_TURN, ""); yield return CoroutineEase.EaseLocalRot(guixSurfaceTransform, Vector3.zero, new Vector3(70f, 0f, 0f), 0.3f, (EasingFunction)Easing.LinearTween, (Action)null, (BoolCheck)null); p.m_verticalArrow.SetActive(true); yield return (object)new WaitForSeconds(0.5f); CoroutineManager.BlinkIn(((Component)p.m_tierMarkerSectorSummary).gameObject, 0f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_5, ""); yield return (object)new WaitForSeconds(0.5f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_SPINE_START, ""); CoroutineEase.EaseLocalScale(p.m_verticalArrow.transform, new Vector3(1f, 0f, 1f), new Vector3(1f, arrowScale, 1f), 4.3f, (EasingFunction)Easing.LinearTween, (Action)delegate { CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_SPINE_STOP, ""); }, (BoolCheck)null); float tierMarkerDelay = 0.6f; yield return (object)new WaitForSeconds(0.2f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_3, ""); ((Component)p.m_guix_Tier3).gameObject.SetActive(true); for (int i = 0; i < p.m_expIconsTier3.Count; i++) { CoroutineManager.BlinkIn(((Component)p.m_expIconsTier3[i]).gameObject, (float)i * 0.1f); } if (p.m_expIconsTier3.Count > 0) { p.m_tierMarker3.SetVisible(true, tierMarkerDelay); } yield return (object)new WaitForSeconds(1f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_5, ""); ((Component)p.m_guix_Tier5).gameObject.SetActive(true); for (int j = 0; j < p.m_expIconsTier5.Count; j++) { CoroutineManager.BlinkIn(((Component)p.m_expIconsTier5[j]).gameObject, (float)j * 0.1f); } if (p.m_expIconsTier5.Count > 0) { p.m_tierMarker5.SetVisible(true, tierMarkerDelay); } yield return (object)new WaitForSeconds(1f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_4, ""); ((Component)p.m_guix_Tier4).gameObject.SetActive(true); for (int k = 0; k < p.m_expIconsTier4.Count; k++) { CoroutineManager.BlinkIn(((Component)p.m_expIconsTier4[k]).gameObject, (float)k * 0.1f); } if (p.m_expIconsTier4.Count > 0) { p.m_tierMarker4.SetVisible(true, tierMarkerDelay); } yield return (object)new WaitForSeconds(1f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_2, ""); ((Component)p.m_guix_Tier2).gameObject.SetActive(true); for (int l = 0; l < p.m_expIconsTier2.Count; l++) { CoroutineManager.BlinkIn(((Component)p.m_expIconsTier2[l]).gameObject, (float)l * 0.1f); } if (p.m_expIconsTier2.Count > 0) { p.m_tierMarker2.SetVisible(true, tierMarkerDelay); } yield return (object)new WaitForSeconds(1f); CM_PageBase.PostSound(EVENTS.MENU_RUNDOWN_DISC_APPEAR_1, ""); ((Component)p.m_guix_Tier1).gameObject.SetActive(true); for (int m = 0; m < p.m_expIconsTier1.Count; m++) { CoroutineManager.BlinkIn(((Component)p.m_expIconsTier1[m]).gameObject, (float)m * 0.1f); } if (p.m_expIconsTier1.Count > 0) { p.m_tierMarker1.SetVisible(true, tierMarkerDelay); } yield return (object)new WaitForSeconds(1f); ((Component)p.m_joinOnServerIdText).gameObject.SetActive(true); CoroutineManager.BlinkIn(p.m_aboutTheRundownButton, 0f, (Transform)null); CoroutineManager.BlinkIn(p.m_discordButton, 0.1f, (Transform)null); if (SNet.IsMaster || !SNet.IsInLobby) { CoroutineManager.BlinkIn(p.m_matchmakeAllButton, 0.2f, (Transform)null); } p.m_selectionIsRevealed = true; p.CheckClipboard(); } } [HarmonyPatch] internal class DisableExpeditionFailPageArtifactDisplay { private class CustomExpeditionFailedSequence { private CM_PageExpeditionFail page; public CustomExpeditionFailedSequence(CM_PageExpeditionFail page) { this.page = page; } public IEnumerator CustomFailedSequence() { yield return (object)new WaitForSeconds(0.5f); ((Component)page.m_bgCortex_text).gameObject.SetActive(false); page.m_bgCortex_textBoxSmall.SetActive(false); page.m_bgCortex_textBoxLarge.SetActive(false); ((Component)page.m_returnToLobby_text).gameObject.SetActive(false); CM_PageBase.PostSound(EVENTS.PLAY_01_FIRST_TEXT_APPEAR, ""); yield return CoroutineManager.BlinkIn(page.m_bgCortex_logo, 0f); yield return (object)new WaitForSeconds(0.3f); CM_PageBase.PostSound(EVENTS.PLAY_01_FIRST_TEXT_APPEAR, ""); yield return CoroutineManager.BlinkIn(page.m_bgCortex_text, 0f, (Transform)null); yield return (object)new WaitForSeconds(0.4f); CoroutineManager.BlinkIn(page.m_bgCortex_textBoxSmall, 0f); CoroutineManager.BlinkIn(page.m_bgCortex_textBoxLarge, 0.15f); yield return (object)new WaitForSeconds(0.5f); yield return CoroutineManager.BlinkOut(page.m_bgCortex_textBoxLarge, 0f); yield return CoroutineManager.BlinkOut(page.m_bgCortex_textBoxSmall, 0f); ((Component)page.m_bgCortex_text).gameObject.SetActive(false); yield return CoroutineManager.BlinkOut(page.m_bgCortex_logo, 0f); yield return (object)new WaitForSeconds(1f); CM_PageBase.PostSound(EVENTS.PLAY_06_MAIN_MENU_LAUNCH, ""); ((Component)page.m_bgScare).gameObject.SetActive(true); page.m_bgScare.Play(); yield return (object)new WaitForSeconds(0.5f); ((Component)page.m_bgScare).gameObject.SetActive(false); yield return CoroutineManager.BlinkIn(((Component)page.m_missionFailed_text).gameObject, 0f); yield return (object)new WaitForSeconds(0.2f); yield return CoroutineManager.BlinkIn(((Component)page.m_returnToLobby_text).gameObject, 0f); } } [HarmonyPrefix] [HarmonyPatch(typeof(CM_PageExpeditionFail), "OnEnable")] private static bool Pre_CM_PageExpeditionFail(CM_PageExpeditionFail __instance) { if (((CM_PageBase)__instance).m_isSetup) { CellSound.StopAll(); CellSound.AllSoundsStoppedThisSession = true; CM_PageBase.PostSound(EVENTS.MUSIC_EXPEDITION_FAILED, ""); ((RectTransformComp)__instance.m_ArtifactInventoryDisplay).Setup(); __instance.m_ArtifactInventoryDisplay.SetArtifactValuesFromInventory(BoosterImplantManager.ArtifactInventory); ((Component)__instance.m_missionFailed_text).gameObject.SetActive(false); ((Component)__instance.m_artifactInfo_text).gameObject.SetActive(false); __instance.m_btnRestartCheckpoint.SetText(Text.Get(916u)); if (SNet.IsMaster) { __instance.m_btnRestartCheckpoint.SetButtonEnabled(true); __instance.m_btnGoToLobby.SetButtonEnabled(true); __instance.m_btnGoToLobby.SetText(Text.Get(917u)); } else { __instance.m_btnRestartCheckpoint.SetButtonEnabled(false); __instance.m_btnGoToLobby.SetButtonEnabled(false); __instance.m_btnGoToLobby.SetText(Text.Get(918u)); } ((Component)__instance.m_btnGoToLobby).gameObject.SetActive(false); ((Component)__instance.m_btnRestartCheckpoint).gameObject.SetActive(false); __instance.m_lobbyButtonVisible = false; __instance.m_showLobbybuttonTimer = Clock.Time + 3f; ((RectTransformComp)__instance.m_ArtifactInventoryDisplay).SetVisible(false); ((CM_PageBase)__instance).StartPageTransitionRoutine(CollectionExtensions.WrapToIl2Cpp(new CustomExpeditionFailedSequence(__instance).CustomFailedSequence())); } return false; } } [HarmonyPatch] internal class SetupBigPickupItemWithItemId { private static List<GameObject> go; private static void SetupAsObserver(LG_PickupItem __instance) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) EnemyTaggerSetting setting = EnemyTaggerSettingManager.Current.SettingForCurrentLevel; CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>(); Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>(); LG_PickupItem_Sync obj = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>(); EnemyTaggerComponent tagger = ((Component)componentInChildren).gameObject.AddComponent<EnemyTaggerComponent>(); tagger.Parent = componentInChildren; ((Component)tagger).gameObject.SetActive(true); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; tagger.MaxTagPerScan = setting.MaxTagPerScan; tagger.TagInterval = setting.TagInterval; tagger.TagRadius = setting.TagRadius; tagger.WarmupTime = setting.WarmupTime; GameObject obsVisual = null; if (setting.UseVisual) { obsVisual = Object.Instantiate<GameObject>(Assets.OBSVisual, ((Component)__instance).transform); obsVisual.transform.localScale = new Vector3(setting.TagRadius, setting.TagRadius, setting.TagRadius); obsVisual.SetActive(false); } obj.OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)delegate(ePickupItemStatus status, pPickupPlacement placement, PlayerAgent playerAgent, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 //IL_006a: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if ((int)status != 0) { if ((int)status == 1) { ((Component)tagger).gameObject.SetActive(true); tagger.PickedByPlayer = playerAgent; tagger.ChangeState((!setting.TagWhenHold) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup); ((Interact_Timed)interact).InteractDuration = setting.TimeToPlace; if ((Object)(object)obsVisual != (Object)null && obsVisual.active) { CoroutineManager.BlinkOut(obsVisual, 0f); } } } else { tagger.PickedByPlayer = null; tagger.ChangeState((!setting.TagWhenPlaced) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; if ((Object)(object)obsVisual != (Object)null) { obsVisual.gameObject.transform.SetPositionAndRotation(placement.position, placement.rotation); if (!obsVisual.active) { CoroutineManager.BlinkIn(obsVisual, tagger.WarmupTime); } } } }); } private static void SetupAsFogBeacon(LG_PickupItem __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_01a1: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent<FogRepeller_Sphere>(); val.InfiniteDuration = false; val.LifeDuration = 99999f; val.GrowDuration = 99999f; val.ShrinkDuration = 99999f; val.Range = 1f; FogBeaconSetting setting = FogBeaconSettingManager.Current.SettingForCurrentLevel; FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>(); fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration; fogRepHold.GrowDuration = setting.RSHold.GrowDuration; fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration; fogRepHold.Range = setting.RSHold.Range; fogRepHold.Offset = Vector3.zero; FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent<FogRepeller_Sphere>(); fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration; fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration; fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration; fogRepPlaced.Range = setting.RSPlaced.Range; fogRepPlaced.Offset = Vector3.zero; CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>(); HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>(); iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState); byte byteId = default(byte); if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, __instance.m_root, ref val3, ref byteId)) { pItemData_Custom customData = ((Item)val2).GetCustomData(); customData.byteId = byteId; pItemData_Custom val4 = customData; ((Item)val2).SetCustomData(val4, true); } HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>(); ((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false); ((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false); val5.m_repellerSphere = val; fogRepHold.m_sphereAllocator = new FogSphereAllocator(); fogRepPlaced.m_sphereAllocator = new FogSphereAllocator(); Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>(); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status; if ((int)val6 != 1) { if ((int)val6 == 2) { FogRepeller_Sphere obj = fogRepHold; if (obj != null) { obj.StopRepelling(); } FogRepeller_Sphere obj2 = fogRepPlaced; if (obj2 != null) { obj2.StartRepelling(); } ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; } } else { FogRepeller_Sphere obj3 = fogRepHold; if (obj3 != null) { obj3.StartRepelling(); } if (oldState.status != 0) { FogRepeller_Sphere obj4 = fogRepPlaced; if (obj4 != null) { obj4.StopRepelling(); } } ((Interact_Timed)interact).InteractDuration = setting.TimeToPlace; } if (isRecall) { FogRepeller_Sphere obj5 = fogRepHold; if (obj5 != null) { obj5.KillRepellerInstantly(); } FogRepeller_Sphere obj6 = fogRepPlaced; if (obj6 != null) { obj6.KillRepellerInstantly(); } } }); } [HarmonyPostfix] [HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")] private static void Post_SetupBigPickupItemWithItemId(LG_PickupItem __instance, uint itemId) { switch (itemId) { case 233u: SetupAsFogBeacon(__instance); break; case 234u: case 235u: case 236u: SetupAsObserver(__instance); break; } } private static void Clear() { go.ForEach((Action<GameObject>)Object.Destroy); go.Clear(); } static SetupBigPickupItemWithItemId() { go = new List<GameObject>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } [HarmonyPatch] internal class ElevatorCargoOverride { [HarmonyPrefix] [HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")] private static bool Pre_ElevatorCargoOverride(ElevatorCargoCage __instance) { LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData); if (levelElevatorCargoItems == null) { return true; } if (levelElevatorCargoItems.ForceDisable) { ElevatorRide.Current.m_cargoCageInUse = false; return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")] private static void Post_ElevatorCargoOverride(ElevatorCargoCage __instance) { LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData); if (levelElevatorCargoItems == null || levelElevatorCargoItems.ElevatorCargoItems.Count < 1 || levelElevatorCargoItems.ForceDisable) { return; } foreach (ElevatorCargoItem elevatorCargoItem
plugins/net6/LGTuner.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using System.Text.Json.Serialization; using AssetShards; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Expedition; using GTFO.API; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LGTuner.Configs; using LGTuner.Manager; using LGTuner.Utils; using LevelGeneration; using LevelGeneration.Core; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("LGTuner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LGTuner")] [assembly: AssemblyTitle("LGTuner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace LGTuner { public static class BuilderInfo { private static readonly List<Complex> _extraComplexResourceToLoad = new List<Complex>(); public static IEnumerable<Complex> ExtraComplexResourceToLoad => _extraComplexResourceToLoad; public static ComplexResourceSetDataBlock ComplexResourceSet { get; private set; } public static int GridSize { get; private set; } public static int GridCenter { get; private set; } public static int GridZeroOffset { get; private set; } public static float AltitudeOffset { get; private set; } public static LayoutConfig MainLayer { get; private set; } public static LayoutConfig SecondaryLayer { get; private set; } public static LayoutConfig ThirdLayer { get; private set; } public static LayoutConfig[] DimensionLayer { get; private set; } = Array.Empty<LayoutConfig>(); internal static void OnResourceSetSelected() { //IL_014c: Unknown result type (might be due to invalid IL or missing references) ComplexResourceSet = Builder.ComplexResourceSetBlock; GridSize = ComplexResourceSet.LevelGenConfig.GridSize; GridCenter = GridSize / 2; GridZeroOffset = -GridCenter; AltitudeOffset = ComplexResourceSet.LevelGenConfig.AltitudeOffset; MainLayer = null; SecondaryLayer = null; ThirdLayer = null; DimensionLayer = new LayoutConfig[Enum.GetValues(typeof(eDimensionIndex)).Length]; _extraComplexResourceToLoad.Clear(); ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition; if (ConfigManager.TryGetConfig(activeExpedition.LevelLayoutData, out var config)) { MainLayer = config; } if (activeExpedition.SecondaryLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.SecondaryLayout, out var config2)) { SecondaryLayer = config2; } if (activeExpedition.ThirdLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.ThirdLayout, out var config3)) { ThirdLayer = config3; } Enumerator<Dimension> enumerator = Builder.CurrentFloor.m_dimensions.GetEnumerator(); while (enumerator.MoveNext()) { Dimension current = enumerator.Current; if (!current.IsMainDimension && !current.DimensionData.IsStaticDimension) { LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(current.DimensionData.LevelLayoutData); if (block != null && ConfigManager.TryGetConfig(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID, out var config4)) { config4.Reset(((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)current.Grid).m_sizeX); DimensionLayer[current.DimensionIndex] = config4; } } } MainLayer?.Reset(GridSize); SecondaryLayer?.Reset(GridSize); ThirdLayer?.Reset(GridSize); AddExtraShard(MainLayer); AddExtraShard(SecondaryLayer); AddExtraShard(ThirdLayer); Array.ForEach(DimensionLayer, delegate(LayoutConfig x) { AddExtraShard(x); }); } private static void AddExtraShard(LayoutConfig layerConfig) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) if (layerConfig == null) { return; } Complex[] extraComplexResourceToLoad = layerConfig.ExtraComplexResourceToLoad; foreach (Complex item in extraComplexResourceToLoad) { if (!_extraComplexResourceToLoad.Contains(item)) { _extraComplexResourceToLoad.Add(item); } } } public static bool TryGetConfig(LG_Zone zone, out LayoutConfig config) { //IL_0001: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) Dimension val = default(Dimension); if (!Dimension.GetDimension(zone.DimensionIndex, ref val)) { config = null; return false; } if (val.IsMainDimension) { LG_LayerType type = zone.Layer.m_type; switch ((int)type) { case 0: config = MainLayer; return MainLayer != null; case 1: config = SecondaryLayer; return SecondaryLayer != null; case 2: config = ThirdLayer; return ThirdLayer != null; } } else if (!val.DimensionData.IsStaticDimension) { config = DimensionLayer[zone.DimensionIndex]; return config != null; } config = null; return false; } public static GameObject GetRandomPlug(uint seed, int plugHeight, SubComplex subcomplex, bool withGate) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) ComplexResourceSetDataBlock complexResourceSet = ComplexResourceSet; return (GameObject)(plugHeight switch { 0 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_straightPlugsWithGates : complexResourceSet.m_straightPlugsNoGates, subcomplex), 1 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_singleDropPlugsWithGates : complexResourceSet.m_singleDropPlugsNoGates, subcomplex), 2 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_doubleDropPlugsWithGates : complexResourceSet.m_doubleDropPlugsNoGates, subcomplex), _ => null, }); } public static uint GetLayoutIdOfZone(LG_Zone zone) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) Dimension dimension = zone.Dimension; if (dimension.IsMainDimension) { LG_LayerType type = zone.Layer.m_type; ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition; return (int)type switch { 0 => activeExpedition.LevelLayoutData, 1 => activeExpedition.SecondaryLayout, 2 => activeExpedition.ThirdLayout, _ => throw new NotSupportedException($"LayerType: {type} is not supported!"), }; } return dimension.DimensionData.LevelLayoutData; } } [BepInPlugin("LGTuner", "LGTuner", "1.0.0")] [BepInProcess("GTFO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EntryPoint : BasePlugin { public Harmony HarmonyInstance { get; private set; } public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown HarmonyInstance = new Harmony("LGTuner"); HarmonyInstance.PatchAll(); ConfigManager.Init(); } } public static class LGExtensions { public static bool IsSame(this LG_GridPosition position, LG_GridPosition other) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (position.x == other.x) { return position.z == other.z; } return false; } public static LG_GridPosition ToNormalGrid(this LG_Tile tile, int gridSize) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return tile.m_shape.m_gridPosition.GetNormal(gridSize); } public static LG_GridPosition GetNormal(this LG_GridPosition position, int gridSize) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0032: Unknown result type (might be due to invalid IL or missing references) LG_GridPosition result; if (gridSize < 0) { result = default(LG_GridPosition); result.x = position.x + BuilderInfo.GridZeroOffset; result.z = position.z + BuilderInfo.GridZeroOffset; return result; } int num = gridSize / 2; result = default(LG_GridPosition); result.x = position.x - num; result.z = position.z - num; return result; } public static Vector3 GetPositionNormal(this LG_Grid grid, int x, int z, int gridSize) { //IL_0024: 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) if (gridSize < 0) { return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x - BuilderInfo.GridZeroOffset, z - BuilderInfo.GridZeroOffset); } int num = gridSize / 2; return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x + num, z + num); } public static int GetGridSize(this Dimension dimension) { return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)dimension.Grid).m_sizeX; } public static bool TryGetDimension(this LG_Floor floor, int dimensionIndex, out Dimension dimension) { if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex)) { return floor.GetDimension((eDimensionIndex)dimensionIndex, ref dimension); } dimension = null; return false; } public static bool TryGetDimension(this LG_Floor floor, eDimensionIndex dimensionIndex, out Dimension dimension) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex)) { return floor.GetDimension(dimensionIndex, ref dimension); } dimension = null; return false; } } public static class RandomExtensions { public static uint NextUint(this Random random) { int num = random.Next(1073741824); uint num2 = (uint)random.Next(4); return (uint)(num << 2) | num2; } public static float NextFloat(this Random random) { return Mathf.Clamp01((float)random.NextDouble()); } public static int ToSeed(this uint seed) { return (int)seed; } } internal static class Logger { private static readonly ManualLogSource _logger; static Logger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _logger = new ManualLogSource("LGTuner"); Logger.Sources.Add((ILogSource)(object)_logger); } private static string Format(object msg) { return msg.ToString(); } public static void Info(object data) { _logger.LogMessage((object)Format(data)); } public static void Verbose(object data) { } public static void Debug(object data) { _logger.LogDebug((object)Format(data)); } public static void Error(object data) { _logger.LogError((object)Format(data)); } } public enum DirectionType { Unknown, Forward, Backward, Left, Right } public enum RotateType { None, Flip, MoveTo_Left, MoveTo_Right, Towards_Random, Towards_Forward, Towards_Backward, Towards_Left, Towards_Right } public struct LG_PlugInfo { public static readonly Quaternion NoRotation = Quaternion.AngleAxis(0f, Vector3.up); public static readonly Quaternion RightRotation = Quaternion.AngleAxis(90f, Vector3.up); public static readonly Quaternion BackwardRotation = Quaternion.AngleAxis(180f, Vector3.up); public static readonly Quaternion LeftRotation = Quaternion.AngleAxis(270f, Vector3.up); public static readonly Vector3 FrontPlugPosition = Vector3.forward * 32f; public static readonly Vector3 BackPlugPosition = Vector3.back * 32f; public static readonly Vector3 LeftPlugPosition = Vector3.left * 32f; public static readonly Vector3 RightPlugPosition = Vector3.right * 32f; public bool IsValid { get; private set; } public DirectionType StartDirection { get; private set; } public int Count { get; private set; } public bool HasFront { get; private set; } public bool HasBack { get; private set; } public bool HasLeft { get; private set; } public bool HasRight { get; private set; } public bool TryGetNewRotation(uint seed, RotateType rotate, out Quaternion rotation) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_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) DirectionType newDirection = GetNewDirection(seed, StartDirection, rotate); if (Count >= 4) { rotation = GetRotationOfDirection(newDirection); return true; } Logger.Info($"You are rotating {Count} side Geomorph, this could lead to level gen crash!"); rotation = GetRotationOfDirection(newDirection); return true; } public bool HasPlug(DirectionType direction) { if (!IsValid) { return false; } if (Count >= 4) { return true; } return direction switch { DirectionType.Forward => HasFront, DirectionType.Backward => HasBack, DirectionType.Left => HasLeft, DirectionType.Right => HasRight, _ => false, }; } public static LG_PlugInfo BuildPlugInfo(GameObject geoObject, Quaternion rotation) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected I4, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)geoObject.GetComponent<LG_Geomorph>() == (Object)null) { return default(LG_PlugInfo); } Il2CppArrayBase<LG_Plug> componentsInChildren = geoObject.GetComponentsInChildren<LG_Plug>(); if (componentsInChildren == null) { return default(LG_PlugInfo); } if (componentsInChildren.Length < 1) { return default(LG_PlugInfo); } LG_PlugInfo result = default(LG_PlugInfo); foreach (LG_Plug item in componentsInChildren) { LG_PlugDir dir = item.m_dir; switch (dir - 2) { case 0: result.HasBack = true; result.Count++; break; case 2: result.HasFront = true; result.Count++; break; case 3: result.HasLeft = true; result.Count++; break; case 1: result.HasRight = true; result.Count++; break; } } result.IsValid = result.Count > 0; float num = Mathf.Round(((Quaternion)(ref rotation)).eulerAngles.y); Logger.Verbose($"angle: {num}"); num = Mathf.Repeat(num, 360f); result.StartDirection = Mathf.RoundToInt(num / 90f) switch { 0 => DirectionType.Forward, 1 => DirectionType.Right, 2 => DirectionType.Backward, 3 => DirectionType.Left, _ => DirectionType.Unknown, }; return result; } public static DirectionType GetNewDirection(uint seed, DirectionType direction, RotateType rotate) { if (direction == DirectionType.Unknown) { return DirectionType.Unknown; } if (rotate == RotateType.Towards_Random) { rotate = new Random(seed.ToSeed()).Next(4) switch { 0 => RotateType.Towards_Forward, 1 => RotateType.Towards_Backward, 2 => RotateType.Towards_Left, 3 => RotateType.Towards_Right, _ => throw new IndexOutOfRangeException("Towards_Random: nextIndex was out of range?!"), }; } return rotate switch { RotateType.None => direction, RotateType.Flip => direction switch { DirectionType.Forward => DirectionType.Backward, DirectionType.Backward => DirectionType.Forward, DirectionType.Left => DirectionType.Right, DirectionType.Right => DirectionType.Left, _ => throw new ArgumentOutOfRangeException("direction"), }, RotateType.MoveTo_Left => direction switch { DirectionType.Forward => DirectionType.Left, DirectionType.Backward => DirectionType.Right, DirectionType.Left => DirectionType.Backward, DirectionType.Right => DirectionType.Forward, _ => throw new ArgumentOutOfRangeException("direction"), }, RotateType.MoveTo_Right => direction switch { DirectionType.Forward => DirectionType.Right, DirectionType.Backward => DirectionType.Left, DirectionType.Left => DirectionType.Forward, DirectionType.Right => DirectionType.Backward, _ => throw new ArgumentOutOfRangeException("direction"), }, RotateType.Towards_Forward => DirectionType.Forward, RotateType.Towards_Backward => DirectionType.Backward, RotateType.Towards_Left => DirectionType.Left, RotateType.Towards_Right => DirectionType.Right, _ => throw new ArgumentOutOfRangeException("direction"), }; } public static Quaternion GetRotationOfDirection(DirectionType direction) { //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_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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0045: Unknown result type (might be due to invalid IL or missing references) return (Quaternion)(direction switch { DirectionType.Forward => NoRotation, DirectionType.Backward => BackwardRotation, DirectionType.Left => LeftRotation, DirectionType.Right => RightRotation, _ => throw new ArgumentOutOfRangeException("direction"), }); } } } namespace LGTuner.Utils { internal static class JSON { private static readonly JsonSerializerOptions _setting; static JSON() { _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = false, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new JsonStringEnumConverter()); if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized) { _setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter); Logger.Info("PartialData Support Found!"); } } public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, _setting); } public static object Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize(object value, Type type) { return JsonSerializer.Serialize(value, type, _setting); } } public static class MTFOPartialDataUtil { public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks"; public static JsonConverter PersistentIDConverter { get; private set; } public static bool IsLoaded { get; private set; } public static bool Initialized { get; private set; } public static string PartialDataPath { get; private set; } public static string ConfigPath { get; private set; } static MTFOPartialDataUtil() { PersistentIDConverter = null; IsLoaded = false; Initialized = false; PartialDataPath = string.Empty; ConfigPath = string.Empty; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type[] types = obj.GetTypes(); Type type = types.First((Type t) => t.Name == "PersistentIDConverter"); if ((object)type == null) { throw new Exception("Unable to Find PersistentIDConverter Class"); } Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class"); PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public); PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public); PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public); if ((object)property == null) { throw new Exception("Unable to Find Property: Initialized"); } if ((object)property2 == null) { throw new Exception("Unable to Find Property: PartialDataPath"); } if ((object)property3 == null) { throw new Exception("Unable to Find Field: ConfigPath"); } Initialized = (bool)property.GetValue(null); PartialDataPath = (string)property2.GetValue(null); ConfigPath = (string)property3.GetValue(null); PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type); IsLoaded = true; } catch (Exception value2) { Logger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}"); } } } public static class MTFOUtil { public const string PLUGIN_GUID = "com.dak.MTFO"; public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public; public static string GameDataPath { get; private set; } public static string CustomPath { get; private set; } public static bool HasCustomContent { get; private set; } public static bool IsLoaded { get; private set; } static MTFOUtil() { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class"); FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public); if ((object)field == null) { throw new Exception("Unable to Find Field: GameDataPath"); } if ((object)field2 == null) { throw new Exception("Unable to Find Field: CustomPath"); } if ((object)field3 == null) { throw new Exception("Unable to Find Field: HasCustomContent"); } GameDataPath = (string)field.GetValue(null); CustomPath = (string)field2.GetValue(null); HasCustomContent = (bool)field3.GetValue(null); IsLoaded = true; } catch (Exception value2) { Logger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}"); } } } } namespace LGTuner.Manager { public static class ConfigManager { [CompilerGenerated] private static class <>O { public static LiveEditEventHandler <0>__LiveEdit_FileChanged; } private static readonly List<LayoutConfig> _layouts = new List<LayoutConfig>(); private static readonly Dictionary<uint, LayoutConfig> _lookup = new Dictionary<uint, LayoutConfig>(); private static readonly Dictionary<string, LayoutConfig> _fileNameLookup = new Dictionary<string, LayoutConfig>(); public static IEnumerable<LayoutConfig> Layouts => _layouts; public static void Init() { //IL_012a: 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_0135: Expected O, but got Unknown if (!MTFOUtil.HasCustomContent) { return; } string text = Path.Combine(MTFOUtil.CustomPath, "LGTuner"); FileInfo[] files = Directory.CreateDirectory(text).GetFiles(); foreach (FileInfo fileInfo in files) { string extension = fileInfo.Extension; bool flag = extension.Equals(".json", StringComparison.InvariantCultureIgnoreCase); bool flag2 = extension.Equals(".jsonc", StringComparison.InvariantCultureIgnoreCase); if (flag || flag2) { LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(File.ReadAllText(fileInfo.FullName)); if (_lookup.ContainsKey(layoutConfig.LevelLayoutID)) { Logger.Error($"Duplicated ID found!: {fileInfo.Name}, {layoutConfig.LevelLayoutID}"); } else { _layouts.Add(layoutConfig); _lookup.Add(layoutConfig.LevelLayoutID, layoutConfig); _fileNameLookup.Add(fileInfo.Name.ToLowerInvariant(), layoutConfig); } } } LiveEditListener obj = LiveEdit.CreateListener(text, "*.*", true); object obj2 = <>O.<0>__LiveEdit_FileChanged; if (obj2 == null) { LiveEditEventHandler val = LiveEdit_FileChanged; <>O.<0>__LiveEdit_FileChanged = val; obj2 = (object)val; } obj.FileChanged += (LiveEditEventHandler)obj2; obj.StartListen(); } private static void LiveEdit_FileChanged(LiveEditEventArgs e) { string key = Path.GetFileName(e.FullPath).ToLowerInvariant(); string extension = Path.GetExtension(e.FullPath); if (!extension.Equals(".json", StringComparison.InvariantCulture) && !extension.Equals(".jsonc", StringComparison.InvariantCulture)) { return; } Logger.Error($"File Edited: '{key}' '{e.FullPath}'"); try { LayoutConfig data = _fileNameLookup[key]; uint oldID = data.LevelLayoutID; LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string json) { try { LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(json); layoutConfig.LevelLayoutID = oldID; _fileNameLookup.Remove(key); _lookup.Remove(oldID); _layouts.Remove(data); _layouts.Add(layoutConfig); _lookup.Add(oldID, layoutConfig); _fileNameLookup.Add(key, layoutConfig); } catch (Exception value2) { Logger.Error($"Error while reading LGTuner Config: {value2}"); } }); } catch (Exception value) { Logger.Error($"Error while reading LGTuner Config: {value}"); } } private static void DumpLevel() { } private static void DumpLayerToConfig() { } public static bool TryGetConfig(uint layoutID, out LayoutConfig config) { return _lookup.TryGetValue(layoutID, out config); } } } namespace LGTuner.Inject { [HarmonyPatch(typeof(LG_BuildPlugBaseJob), "SpawnPlug")] internal static class Inject_BuildPlug { private static void Prefix(LG_Plug plug, ref GameObject prefab) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected I4, but got Unknown //IL_0253: Unknown result type (might be due to invalid IL or missing references) Logger.Info($"found plug for zone: {((LG_ZoneExpander)plug).m_linksFrom.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksFrom).name}->{((LG_ZoneExpander)plug).m_linksTo.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksTo).name}"); if (!BuilderInfo.TryGetConfig(((LG_ZoneExpander)plug).m_linksFrom.m_zone, out var config)) { return; } LG_GridPosition normal = ((LG_ZoneExpander)plug).m_linksFrom.m_geomorph.m_tile.m_shape.m_gridPosition.GetNormal(config.GridSize); if (!config.TryGetTileData(normal, out var overrideData)) { return; } ZoneOverrideData zoneData = overrideData.ZoneData; if (zoneData != null && zoneData.OverridePlugs && TryGetPlugPrefab(overrideData.ZoneData.GetNextPlug(), out var prefab2)) { Logger.Info(" - Prefab Replaced by Zone OverridePlugs! " + ((Object)prefab2).name); prefab = prefab2; } LG_PlugDir dir = plug.m_dir; GameObject prefab3; switch (dir - 2) { case 0: if (TryGetPlugPrefab(overrideData.BackwardPlug, out prefab3)) { Logger.Info(" - Prefab Replaced by BackwardPlug setting! " + ((Object)prefab3).name); prefab = prefab3; return; } break; case 2: if (TryGetPlugPrefab(overrideData.ForwardPlug, out prefab3)) { Logger.Info(" - Prefab Replaced by ForwardPlug setting! " + ((Object)prefab3).name); prefab = prefab3; return; } break; case 3: if (TryGetPlugPrefab(overrideData.LeftPlug, out prefab3)) { Logger.Info(" - Prefab Replaced by LeftPlug setting! " + ((Object)prefab3).name); prefab = prefab3; return; } break; case 1: if (TryGetPlugPrefab(overrideData.RightPlug, out prefab3)) { Logger.Info(" - Prefab Replaced by RightPlug setting! " + ((Object)prefab3).name); prefab = prefab3; return; } break; } if (overrideData.OverridePlugWithNoGateChance) { Random random = new Random(((LG_ZoneExpander)plug).m_linksFrom.AreaSeed.ToSeed()); bool withGate = ((LG_ZoneExpander)plug).m_isZoneSource || (!(overrideData.PlugWithNoGateChance >= 1f) && (overrideData.PlugWithNoGateChance <= 0f || random.NextFloat() >= overrideData.PlugWithNoGateChance)); int dropHeight = GetDropHeight(plug); GameObject randomPlug = BuilderInfo.GetRandomPlug(random.NextUint(), dropHeight, GetSubComplexOfPlug(plug), withGate); if ((Object)(object)randomPlug == (Object)null) { Logger.Error($"Plug was null! - Height: {dropHeight}"); } else { prefab = randomPlug; } } } private static SubComplex GetSubComplexOfPlug(LG_Plug plug) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) SubComplex result = ((LG_ZoneExpander)plug).m_subComplex; if (((LG_ZoneExpander)plug).m_subComplex != ((LG_ZoneExpander)plug.m_pariedWith).m_subComplex) { result = (SubComplex)8; } return result; } private static bool TryGetPlugPrefab(string prefabPath, out GameObject prefab) { if (string.IsNullOrEmpty(prefabPath)) { prefab = null; return false; } prefab = ((Il2CppObjectBase)AssetAPI.GetLoadedAsset(prefabPath)).Cast<GameObject>(); return (Object)(object)prefab != (Object)null; } private static int GetDropHeight(LG_Plug plug) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return Mathf.RoundToInt(Mathf.Abs(((Component)plug).transform.position.y - ((Component)plug.m_pariedWith).transform.position.y) / BuilderInfo.AltitudeOffset); } } [HarmonyPatch(typeof(LG_LevelBuilder), "PlaceRoot")] internal static class Inject_BuildGeomorph { private static LayoutConfig _configContext; private static RotateType _nextRotateType; [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("BuildFloor")] private static void Post_BuildFloor() { BuilderInfo.OnResourceSetSelected(); } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("PlaceRoot")] private static void Pre_PlaceRoot(LG_Tile tile, ref GameObject tilePrefab, ref bool forceAlignToVector, ref Vector3 alignVector, LG_Zone zone) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) _configContext = null; _nextRotateType = RotateType.None; forceAlignToVector = alignVector != Vector3.zero; int gridSize = zone.Dimension.GetGridSize(); LG_GridPosition val = tile.ToNormalGrid(gridSize); Logger.Info($"tile info: {val.x} {val.z} {((Object)tilePrefab).name} for {zone.LocalIndex} : {zone.DimensionIndex}"); if (!BuilderInfo.TryGetConfig(zone, out _configContext)) { return; } if (!_configContext.TryGetTileData(val, out var overrideData)) { overrideData = _configContext.PopulateTileOverrideForZone(zone, val); if (overrideData == null) { return; } } if (!string.IsNullOrEmpty(overrideData.Geomorph)) { Object loadedAsset = AssetAPI.GetLoadedAsset(overrideData.Geomorph); GameObject val2 = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).Cast<GameObject>() : null); if ((Object)(object)val2 != (Object)null) { Logger.Info(" - tile overriden! " + ((Object)val2).name); tilePrefab = val2; } } if (overrideData.Rotation != 0) { _nextRotateType = overrideData.Rotation; } } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("GetTilePosition")] private static void Post_GetTilePosition(LG_Tile tile, LG_Floor floor, int dimensionIndex, ref Vector3 __result) { //IL_0021: 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_002c: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (_configContext != null && floor.TryGetDimension(dimensionIndex, out var dimension)) { int gridSize = _configContext.GridSize; LG_GridPosition val = tile.ToNormalGrid(gridSize); if (_configContext.TryGetTileData(val, out var overrideData) && overrideData.OverrideAltitude) { Vector3 positionNormal = dimension.Grid.GetPositionNormal(val.x, val.z, gridSize); positionNormal += new Vector3(0f, (float)overrideData.Altitude * BuilderInfo.AltitudeOffset, 0f); __result = positionNormal; } } } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("PlaceRoot")] private static void Post_PlaceRoot(LG_Tile tile, LG_Zone zone, LG_Geomorph __result) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_007f: Unknown result type (might be due to invalid IL or missing references) if (_configContext == null) { return; } if (_nextRotateType != 0) { GameObject gameObject = ((Component)__result).gameObject; LG_PlugInfo lG_PlugInfo = LG_PlugInfo.BuildPlugInfo(gameObject, gameObject.transform.rotation); Logger.Info($" - TRYING ROTATION! PLUG COUNT: {lG_PlugInfo.Count}"); if (lG_PlugInfo.TryGetNewRotation(zone.m_subSeed, _nextRotateType, out var rotation)) { Logger.Info(" - Done!"); gameObject.transform.rotation = rotation; } __result.SetPlaced(); } int gridSize = _configContext.GridSize; LG_GridPosition normalGridPosition = tile.ToNormalGrid(gridSize); if (!_configContext.TryGetTileData(normalGridPosition, out var overrideData) || !overrideData.OverrideAreaSeeds) { return; } if (overrideData.AreaSeeds.Length == ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length) { int length = ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length; for (int i = 0; i < length; i++) { uint num = overrideData.AreaSeeds[i]; if (num != 0) { ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].AreaSeed = num; Logger.Info($" - new area seed: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].m_navInfo}, {num}"); } } } else { Logger.Error($" - Area count and AreaSeeds item count mismatched! (CFG: {overrideData.AreaSeeds.Length} != AREA: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length}) Area seed will not be applied!"); } } } [HarmonyPatch(typeof(LG_LoadComplexDataSetResourcesJob), "Build")] internal static class Inject_LoadComplexShard { private static int _waitingShared; [HarmonyWrapSafe] private static void Prefix(LG_LoadComplexDataSetResourcesJob __instance) { //IL_0017: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown //IL_0032: 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_003a: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_loadingStarted) { return; } foreach (Complex item in BuilderInfo.ExtraComplexResourceToLoad) { AssetBundleName val = (AssetBundleName)((int)item switch { 0 => 2, 1 => 4, 2 => 3, _ => 0, }); if ((int)val != 0) { AssetShardManager.LoadAllShardsForBundleAsync(val, Action.op_Implicit((Action)Loaded), 1, (LoadSceneMode)1); _waitingShared++; } } } private static void Loaded() { _waitingShared--; } [HarmonyWrapSafe] private static void Postfix(LG_LoadComplexDataSetResourcesJob __instance, ref bool __result) { if (_waitingShared >= 1) { __result = false; } } } } namespace LGTuner.Configs { public sealed class LayoutConfig { private TileOverrideData[,] _builtTileOverrides = new TileOverrideData[0, 0]; public uint LevelLayoutID { get; set; } public Complex[] ExtraComplexResourceToLoad { get; set; } = Array.Empty<Complex>(); public ZoneOverrideData[] ZoneOverrides { get; set; } = Array.Empty<ZoneOverrideData>(); public TileOverrideData[] TileOverrides { get; set; } = Array.Empty<TileOverrideData>(); [JsonIgnore] public int GridSize { get; private set; } [JsonIgnore] public int GridSizeHalf { get; private set; } public void Reset(int gridSize) { Array.ForEach(ZoneOverrides, delegate(ZoneOverrideData item) { item.Clear(); }); Array.Clear(_builtTileOverrides, 0, _builtTileOverrides.Length); GridSize = gridSize; GridSizeHalf = gridSize / 2; _builtTileOverrides = new TileOverrideData[GridSize, GridSize]; TileOverrideData[] tileOverrides = TileOverrides; foreach (TileOverrideData tileOverrideData in tileOverrides) { if (_builtTileOverrides[tileOverrideData.X + GridSizeHalf, tileOverrideData.Z + GridSizeHalf] == null) { PutOverrideData(tileOverrideData); continue; } Logger.Error($"Duplicate tile data in layout: {LevelLayoutID}, ({tileOverrideData.X}, {tileOverrideData.Z})!"); } } public bool TryGetTileData(LG_GridPosition normalGridPosition, out TileOverrideData overrideData) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) int num = normalGridPosition.x + GridSizeHalf; if (num >= GridSize) { Logger.Error($"TryGetTileData grid x was out of range! {num}:{GridSize}"); overrideData = null; return false; } int num2 = normalGridPosition.z + GridSizeHalf; if (num2 >= GridSize) { Logger.Error($"TryGetTileData grid Z was out of range! {num2}:{GridSize}"); overrideData = null; return false; } overrideData = _builtTileOverrides[num, num2]; return overrideData != null; } public void PutOverrideData(TileOverrideData data) { _builtTileOverrides[data.X + GridSizeHalf, data.Z + GridSizeHalf] = data; } public TileOverrideData PopulateTileOverrideForZone(LG_Zone zone, LG_GridPosition normalGridPosition) { //IL_0002: 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_003b: 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) if (!TryGetZoneOverride(zone.LocalIndex, out var data)) { return null; } if (TryGetTileData(normalGridPosition, out var overrideData)) { overrideData.ZoneData = data; TryApplyOverrides(data, overrideData); return overrideData; } TileOverrideData tileOverrideData = new TileOverrideData { ZoneData = data, X = normalGridPosition.x, Z = normalGridPosition.z, OverridePlugWithNoGateChance = data.OverridePlugWithNoGateChance, PlugWithNoGateChance = data.PlugWithNoGateChance }; TryApplyOverrides(data, tileOverrideData); PutOverrideData(tileOverrideData); return tileOverrideData; } private void TryApplyOverrides(ZoneOverrideData zoneOverrideData, TileOverrideData tileOverrideData) { if (zoneOverrideData.OverrideGeomorphs && string.IsNullOrEmpty(tileOverrideData.Geomorph)) { ZoneOverrideData.GeomorphData? nextGeo = zoneOverrideData.GetNextGeo(); if (nextGeo.HasValue) { tileOverrideData.Geomorph = nextGeo.Value.Geomorph; if (tileOverrideData.Rotation == RotateType.None) { tileOverrideData.Rotation = ZoneOverrideData.DirectionToRotate(nextGeo.Value.Direction); } } } if (zoneOverrideData.OverrideAltitudes && !tileOverrideData.OverrideAltitude) { int? nextAltitude = zoneOverrideData.GetNextAltitude(); if (nextAltitude.HasValue) { tileOverrideData.OverrideAltitude = true; tileOverrideData.Altitude = nextAltitude.Value; } } } public bool TryGetZoneOverride(eLocalZoneIndex localIndex, out ZoneOverrideData data) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) data = ZoneOverrides.SingleOrDefault((ZoneOverrideData z) => z.LocalIndex == localIndex); return data != null; } } public sealed class TileOverrideData { public int X { get; set; } public int Z { get; set; } public bool OverrideAreaSeeds { get; set; } public uint[] AreaSeeds { get; set; } = Array.Empty<uint>(); public RotateType Rotation { get; set; } public string Geomorph { get; set; } = string.Empty; public bool OverrideAltitude { get; set; } public int Altitude { get; set; } public string ForwardPlug { get; set; } = string.Empty; public string BackwardPlug { get; set; } = string.Empty; public string LeftPlug { get; set; } = string.Empty; public string RightPlug { get; set; } = string.Empty; public bool OverridePlugWithNoGateChance { get; set; } public float PlugWithNoGateChance { get; set; } = 0.5f; [JsonIgnore] public ZoneOverrideData ZoneData { get; set; } } public sealed class ZoneOverrideData { public enum Direction { Unchanged, Random, Forward, Backward, Left, Right } public struct GeomorphData { public string Geomorph { get; set; } public Direction Direction { get; set; } } private int _curGeomorphIndex; private int _curAltitudeIndex; private int _curPlugIndex; public eLocalZoneIndex LocalIndex { get; set; } public bool OverrideGeomorphs { get; set; } public GeomorphData[] Geomorphs { get; set; } = Array.Empty<GeomorphData>(); public bool OverrideAltitudes { get; set; } public int[] Altitudes { get; set; } = Array.Empty<int>(); public bool OverridePlugs { get; set; } public string[] Plugs { get; set; } = Array.Empty<string>(); public bool OverridePlugWithNoGateChance { get; set; } public float PlugWithNoGateChance { get; set; } = 0.5f; public void Clear() { _curGeomorphIndex = 0; _curAltitudeIndex = 0; _curPlugIndex = 0; } public GeomorphData? GetNextGeo() { if (Geomorphs == null || Geomorphs.Length == 0) { return null; } return Geomorphs[_curGeomorphIndex++ % Geomorphs.Length]; } public int? GetNextAltitude() { if (Altitudes == null || Altitudes.Length == 0) { return null; } return Altitudes[_curAltitudeIndex++ % Altitudes.Length]; } public string GetNextPlug() { if (Plugs == null || Plugs.Length == 0) { return string.Empty; } return Plugs[_curPlugIndex++ % Plugs.Length]; } public static RotateType DirectionToRotate(Direction direction) { return direction switch { Direction.Unchanged => RotateType.None, Direction.Random => RotateType.Towards_Random, Direction.Forward => RotateType.Towards_Forward, Direction.Backward => RotateType.Towards_Backward, Direction.Left => RotateType.Towards_Left, Direction.Right => RotateType.Towards_Right, _ => throw new NotImplementedException($"DirectionType: {direction} is not supported"), }; } } }
plugins/net6/MTFO.dll
Decompiled 10 months agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using AK; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using CellMenu; using ChainedPuzzles; using GTFO.API; using GameData; using GameEvent; using Gear; using Globals; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.InteropTypes.Fields; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MTFO.API; using MTFO.Custom; using MTFO.Custom.CCP.Components; using MTFO.CustomCP; using MTFO.HotReload; using MTFO.Managers; using MTFO.NativeDetours; using MTFO.Utilities; using Player; using SNetwork; using TMPro; using UnityEngine; using UnityEngine.Analytics; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("MTFO")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© dakkhuza 2021")] [assembly: AssemblyFileVersion("4.5.2")] [assembly: AssemblyInformationalVersion("4.5.2+gitbdd649e-main")] [assembly: AssemblyProduct("MTFO")] [assembly: AssemblyTitle("MTFO")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.5.2.0")] [module: UnverifiableCode] namespace MTFO { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class ConfigStrings { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("MTFO.ConfigStrings", typeof(ConfigStrings).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static string SECTION_DEBUG => ResourceManager.GetString("SECTION_DEBUG", resourceCulture); internal static string SECTION_DEV => ResourceManager.GetString("SECTION_DEV", resourceCulture); internal static string SECTION_GENERAL => ResourceManager.GetString("SECTION_GENERAL", resourceCulture); internal static string SETTING_DUMPDATA => ResourceManager.GetString("SETTING_DUMPDATA", resourceCulture); internal static string SETTING_DUMPDATA_DESC => ResourceManager.GetString("SETTING_DUMPDATA_DESC", resourceCulture); internal static string SETTING_DUMPDATA_MODE => ResourceManager.GetString("SETTING_DUMPDATA_MODE", resourceCulture); internal static string SETTING_DUMPDATA_MODE_DESC => ResourceManager.GetString("SETTING_DUMPDATA_MODE_DESC", resourceCulture); internal static string SETTING_HOTRELOAD => ResourceManager.GetString("SETTING_HOTRELOAD", resourceCulture); internal static string SETTING_HOTRELOAD_DESC => ResourceManager.GetString("SETTING_HOTRELOAD_DESC", resourceCulture); internal static string SETTING_RUNDOWNPACKAGE => ResourceManager.GetString("SETTING_RUNDOWNPACKAGE", resourceCulture); internal static string SETTING_RUNDOWNPACKAGE_DESC => ResourceManager.GetString("SETTING_RUNDOWNPACKAGE_DESC", resourceCulture); internal static string SETTING_USE_LEGACY_PATH => ResourceManager.GetString("SETTING_USE_LEGACY_PATH", resourceCulture); internal static string SETTING_USE_LEGACY_PATH_DESC => ResourceManager.GetString("SETTING_USE_LEGACY_PATH_DESC", resourceCulture); internal static string SETTING_VERBOSE => ResourceManager.GetString("SETTING_VERBOSE", resourceCulture); internal static string SETTING_VERBOSE_DESC => ResourceManager.GetString("SETTING_VERBOSE_DESC", resourceCulture); internal ConfigStrings() { } } [BepInPlugin("com.dak.MTFO", "MTFO", "4.5.2+gitbdd649e-main")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MTFO : BasePlugin { public const string MODNAME = "MTFO"; public const string AUTHOR = "dak"; public const string GUID = "com.dak.MTFO"; public const string VERSION = "4.5.2+gitbdd649e-main"; public override void Load() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Analytics.enabled = false; Harmony harmony = new Harmony("com.dak.MTFO"); AssetAPI.OnImplReady += delegate { if (ConfigManager.IsHotReloadEnabled) { ClassInjector.RegisterTypeInIl2Cpp<HotReloader>(); harmony.PatchAll(typeof(HotReloadInjector)); } }; harmony.PatchAll(); Detour_DataBlockBase.Patch(); } } public static class DataDumperExtensions { public static int GetStableHashCode(this string str) { int num = 5381; int num2 = num; for (int i = 0; i < str.Length && str[i] != 0; i += 2) { num = ((num << 5) + num) ^ str[i]; if (i == str.Length - 1 || str[i + 1] == '\0') { break; } num2 = ((num2 << 5) + num2) ^ str[i + 1]; } return num + num2 * 1566083941; } } public static class JsonNodeExtension { private static JsonDocumentOptions _JsonDocumentOptions = new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }; private static readonly JsonSerializerOptions _JsonSerializerOptions = new JsonSerializerOptions { AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip, WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; public static string ToJsonStringIndented(this JsonNode jsonNode) { return jsonNode.ToJsonString(_JsonSerializerOptions); } public static bool TryParseToJsonNode(this string json, out JsonNode jsonNode) { try { jsonNode = json.ToJsonNode(); return jsonNode != null; } catch { jsonNode = null; return false; } } public static bool TryParseJsonNode(this Stream stream, bool dispose, out JsonNode jsonNode) { try { jsonNode = stream.ToJsonNode(); return jsonNode != null; } catch { jsonNode = null; return false; } finally { if (dispose) { stream.Close(); } } } public static JsonNode ToJsonNode(this string json) { return JsonNode.Parse(json, null, _JsonDocumentOptions); } public static JsonNode ToJsonNode(this Stream jsonStream) { return JsonNode.Parse(jsonStream, null, _JsonDocumentOptions); } public static bool TryAddJsonItem(this JsonArray jsonArray, string json) { try { if (jsonArray == null) { throw new Exception(); } if (string.IsNullOrWhiteSpace(json)) { throw new Exception(); } if (!json.TryParseToJsonNode(out var jsonNode)) { throw new Exception(); } jsonArray.Add(jsonNode); return true; } catch { return false; } } } [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "MTFO"; public const string Version = "4.5.2"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitbdd649e-main"; public const string SemVer = "4.5.2+gitbdd649e-main"; public const string GitRevShort = "bdd649e"; public const string GitRevLong = "bdd649ecde4cd5fb568e315265e04a3f41a9ab87"; public const string GitBranch = "main"; public const string GitTag = "v4.3.0"; public const bool GitIsDirty = false; } } namespace MTFO.Utilities { public class JsonSerializer { public JsonSerializerOptions Options; public JsonSerializer() { Options = new JsonSerializerOptions { AllowTrailingCommas = true, IncludeFields = true, PropertyNameCaseInsensitive = true, ReadCommentHandling = JsonCommentHandling.Skip, WriteIndented = true }; Options.Converters.Add(new JsonStringEnumConverter()); } public JsonSerializer(bool allowTrailingCommas = true, bool includeFields = true, bool propertyNameCaseInsensitive = true, bool writeIndented = true) { Options = new JsonSerializerOptions { AllowTrailingCommas = allowTrailingCommas, IncludeFields = includeFields, PropertyNameCaseInsensitive = propertyNameCaseInsensitive, ReadCommentHandling = JsonCommentHandling.Skip, WriteIndented = writeIndented }; Options.Converters.Add(new JsonStringEnumConverter()); } public void TryRead<T>(string path, out T output) where T : new() { if (File.Exists(path)) { string json = File.ReadAllText(path); output = Deserialize<T>(json); } else { output = new T(); string json = Serialize(output); File.WriteAllText(path, json); } } public string Serialize(object value) { return System.Text.Json.JsonSerializer.Serialize(value, Options); } public T Deserialize<T>(string json) { return System.Text.Json.JsonSerializer.Deserialize<T>(json, Options); } } public static class Log { private static readonly ManualLogSource logger; static Log() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown logger = new ManualLogSource("MTFO"); Logger.Sources.Add((ILogSource)(object)logger); } public static void Verbose(object msg) { if (ConfigManager.IsVerbose) { logger.LogInfo(msg); } } public static void Debug(object msg) { logger.LogDebug(msg); } public static void Message(object msg) { logger.LogMessage(msg); } public static void Error(object msg) { logger.LogError(msg); } public static void Warn(object msg) { logger.LogWarning(msg); } } public enum BaseDirectory { BepInEx, Plugins, GameData } public static class PathUtil { public static string Prepare(BaseDirectory baseDir, params string[] subDirs) { string text = baseDir switch { BaseDirectory.BepInEx => Paths.BepInExRootPath, BaseDirectory.Plugins => Paths.PluginPath, BaseDirectory.GameData => Path.Combine(Paths.BepInExRootPath, "GameData"), _ => throw new ArgumentOutOfRangeException("baseDir", string.Format("{0} is not a valid value for Argument: {1}", baseDir, "baseDir")), }; string obj = ((subDirs == null || subDirs.Length == 0) ? text : Path.Combine(text, Path.Combine(subDirs))); Directory.CreateDirectory(obj); return obj; } public static bool CheckCustomFile(string file, out string CombinedPath) { CombinedPath = Path.Combine(ConfigManager.CustomPath, file); if (File.Exists(CombinedPath)) { return true; } return false; } public static bool CheckFile(string pathToFile) { if (File.Exists(pathToFile)) { return true; } return false; } [Obsolete] public static string MakeRelativeDirectory(string path, bool createPath = true) { string text = Path.Combine(Path.Combine(Paths.ConfigPath, "Rundowns"), path); if (createPath && !Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } public static string MakeRelativeDirectory(string path, string folder) { string text = Path.Combine(path, folder); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } public static void PrepareEmptyDirectory(string path) { if (Directory.Exists(path)) { Directory.Delete(path, recursive: true); } Directory.CreateDirectory(path); } public static Stream OpenUtf8Stream(string filePath) { return new StreamReader(filePath, Encoding.UTF8).BaseStream; } } } namespace MTFO.Patches { [HarmonyPatch(typeof(AnalyticsManager), "OnGameEvent", new Type[] { typeof(GameEventData) })] internal static class Patch_Analytics { public static bool Prefix(GameEventData data) { return false; } } [HarmonyPatch(typeof(SNet_Core_STEAM), "SetFriendsData", new Type[] { typeof(FriendsDataType), typeof(string) })] internal static class Patch_RichPresence2 { public static void Prefix(FriendsDataType type, ref string data, SNet_Core_STEAM __instance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((int)type != 1) { if ((int)type == 9) { data = "0"; } else { Log.Verbose($"Lobby data\nType: {type} Data: {data}"); } } else { data = "MODDED - " + data; } } } [HarmonyPatch(typeof(GlowstickInstance), "Update")] internal static class Patch_Glowstick { public static void Postfix(GlowstickInstance __instance) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (ConfigManager.HasCustomContent && ConfigManager.CustomContent.GlowstickHolder != null && !((Object)(object)__instance == (Object)null) && (int)__instance.m_state != 3 && (int)__instance.m_state != 4 && ConfigManager.CustomContent.GlowstickHolder.GlowstickLookup.TryGetValue(((Item)__instance).PublicName, out var value) && (Object)(object)__instance.m_light != (Object)null) { ((LightBase)__instance.m_light).Range = value.Range; ((LightBase)__instance.m_light).Color = value.Color * __instance.m_progression; ((LightBase)__instance.m_light).UpdateVisibility(true); } } } [HarmonyPatch(typeof(CP_Holopath_Spline), "Reveal")] internal static class Patch_InstantRevealPuzzlePath { public static bool Prefix(CP_Holopath_Spline __instance) { //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) if (__instance.m_revealSpeed < 0f) { if (!__instance.m_isSetup) { return false; } __instance.SetSplineProgress(1f); __instance.SetVisible(true); __instance.m_sound.UpdatePosition(__instance.TipPos); if (!__instance.m_didSetColor) { __instance.m_didSetColor = __instance.TrySetColor(); } __instance.m_sound.Post(EVENTS.BIOSCAN_TUBE_EMITTER_STOP, true); Action onRevealDone = __instance.OnRevealDone; if (onRevealDone != null) { onRevealDone.Invoke(); } return false; } return true; } } [HarmonyPatch(typeof(CM_PageLoadout), "UpdatePageData")] internal static class Patch_PageLoadoutUpdatePageData { public static void Prefix(CM_PageLoadout __instance) { ((TMP_Text)((Component)((Transform)((CM_PageBase)__instance).m_movingContentHolder).Find("ShareServerId/ShareText")).gameObject.GetComponent<TextMeshPro>()).SetText("<color=red><b>Do not play modded content on the official GTFO server or online matchmake lobbies.</b></color>\n\nFeel free to join the unofficial discord server linked below and ask people to play.", true); __instance.m_discordButton.SetText("Mod Server"); __instance.m_discordButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate { Application.OpenURL("https://discord.com/invite/rRMPtv4FAh"); }); } } [HarmonyPatch(typeof(CM_PageLoadout), "UpdatePlayerBars")] internal static class Patch_PageLoadoutUpdatePlayerBars { public static void Prefix(CM_PageLoadout __instance) { foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase<CM_PlayerLobbyBar>)(object)__instance.m_playerLobbyBars) { item.m_matchmakeButton.SetOnBtnPressCallback((Action<int>)null); item.m_matchmakeButton.SetText("DISABLED"); } } } [HarmonyPatch(typeof(CM_PageRundown_New), "Intro_RevealRundown")] internal static class Patch_PageRundownNew { public static void Postfix(CM_PageRundown_New __instance) { __instance.m_discordButton.SetText("MOD SERVER"); __instance.m_discordButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate { Application.OpenURL("https://discord.com/invite/rRMPtv4FAh"); }); ((RectTransformComp)__instance.m_matchmakeAllButton).SetVisible(false); __instance.m_matchmakeAllButton.SetText("MATCHMAKE DISABLED"); __instance.m_matchmakeAllButton.OnBtnPressCallback = null; __instance.m_aboutTheRundownButton.SetText("THUNDERSTORE"); __instance.m_aboutTheRundownButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate { Application.OpenURL("https://gtfo.thunderstore.io/"); }); } } [HarmonyPatch(typeof(CM_PageRundown_New), "PlaceRundown")] internal static class Patch_RundownTierMarker { public static void Postfix(CM_PageRundown_New __instance) { ContentManager customContent = ConfigManager.CustomContent; if (customContent != null) { __instance.m_tierMarker1.m_name = customContent.TierNames.Tier1; __instance.m_tierMarker2.m_name = customContent.TierNames.Tier2; __instance.m_tierMarker3.m_name = customContent.TierNames.Tier3; __instance.m_tierMarker4.m_name = customContent.TierNames.Tier4; __instance.m_tierMarker5.m_name = customContent.TierNames.Tier5; __instance.m_tierMarker1.UpdateHeader(); __instance.m_tierMarker2.UpdateHeader(); __instance.m_tierMarker3.UpdateHeader(); __instance.m_tierMarker4.UpdateHeader(); __instance.m_tierMarker5.UpdateHeader(); } } } [HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")] internal static class Patch_WatermarkUpdateWatermark { public static void Postfix(PUI_Watermark __instance) { ((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>4.5.2</color>", true); } } } namespace MTFO.NativeDetours { internal class DataBlockBaseWrapper { private static readonly HashSet<string> _PreferPartialDumpBlocks = new HashSet<string> { "RundownDataBlock".ToLower(), "LightSettingsDataBlock".ToLower(), "FogSettingsDataBlock".ToLower(), "LevelLayoutDataBlock".ToLower(), "WardenObjectiveDataBlock".ToLower(), "DimensionDataBlock".ToLower(), "EnemyDataBlock".ToLower(), "EnemySFXDataBlock".ToLower(), "EnemyBehaviorDataBlock".ToLower(), "EnemyBalancingDataBlock".ToLower(), "EnemyMovementDataBlock".ToLower(), "ArchetypeDataBlock".ToLower(), "PlayerOfflineGearDataBlock".ToLower(), "ComplexResourceSetDataBlock".ToLower(), "TextDataBlock".ToLower() }; private IntPtr Ptr__m_fileNameNoExt; public IntPtr ClassPointer { get; private set; } public string FileName { get; private set; } public string BinaryFileName { get; private set; } public bool PreferPartialBlockOnDump { get; private set; } public unsafe DataBlockBaseWrapper(Il2CppMethodInfo* methodInfo) { INativeClassStruct val = UnityVersionHandler.Wrap(UnityVersionHandler.Wrap(methodInfo).Class); ClassPointer = ((INativeStruct)val).Pointer; Ptr__m_fileNameNoExt = IL2CPP.GetIl2CppField(((INativeStruct)val).Pointer, "m_fileNameNoExt"); IntPtr zero = IntPtr.Zero; IL2CPP.il2cpp_field_static_get_value(Ptr__m_fileNameNoExt, (void*)(&zero)); FileName = IL2CPP.Il2CppStringToManaged(zero).Replace('.', '_'); BinaryFileName = FileName + "_bin"; if (_PreferPartialDumpBlocks.Contains(FileName.ToLower().Replace("gamedata_", ""))) { PreferPartialBlockOnDump = true; } } } internal static class Detour_DataBlockBase { private unsafe delegate IntPtr GetFileContentsDel(Il2CppMethodInfo* methodInfo); private static string _BasePathToDump; private static INativeDetour _Detour; private static GetFileContentsDel _Original; public unsafe static void Patch() { _BasePathToDump = Path.Combine(Paths.BepInExRootPath, "GameData-Dump", CellBuildData.GetRevision().ToString()); if (ConfigManager.DumpGameData) { PathUtil.PrepareEmptyDirectory(_BasePathToDump); } _Detour = INativeDetour.CreateAndApply<GetFileContentsDel>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<GameDataBlockBase<EnemyDataBlock>>("GetFileContents", typeof(string).FullName, false, Array.Empty<string>()), (GetFileContentsDel)Dtor_GetFileContents, ref _Original); } private unsafe static IntPtr Dtor_GetFileContents(Il2CppMethodInfo* methodInfo) { IntPtr intPtr = _Original(methodInfo); try { DataBlockBaseWrapper dataBlockBaseWrapper = new DataBlockBaseWrapper(methodInfo); string binaryFileName = dataBlockBaseWrapper.BinaryFileName; _ = binaryFileName + ".json"; if (ConfigManager.DumpGameData) { DumpContent(dataBlockBaseWrapper, IL2CPP.Il2CppStringToManaged(intPtr)); } Log.Verbose("GetFileContents Call of " + binaryFileName); Stream contentStream = GetContentStream(dataBlockBaseWrapper, intPtr); JsonNode jsonNode = contentStream.ToJsonNode(); JsonArray jsonArray = jsonNode["Blocks"].AsArray(); string path = Path.Combine(ConfigManager.GameDataPath, dataBlockBaseWrapper.FileName); if (Directory.Exists(path)) { int num = 0; string[] files = Directory.GetFiles(path, "*.json"); foreach (string text in files) { Log.Verbose(" - Trying to add PartialData [" + text + "]"); if (File.Exists(text) && PathUtil.OpenUtf8Stream(text).TryParseJsonNode(dispose: true, out var jsonNode2)) { jsonArray.Add(jsonNode2); num++; } } Log.Verbose($" - Added {num} partial data of {binaryFileName}"); } List<string> jsonItemsToInject = new List<string>(); MTFOGameDataAPI.Invoke_OnGameDataContentLoad(dataBlockBaseWrapper.FileName, contentStream, in jsonItemsToInject); foreach (string item2 in jsonItemsToInject) { try { JsonNode item = item2.ToJsonNode(); jsonArray.Add(item); } catch (Exception ex) { Log.Error("Exception were found while reading Injected Json Data!"); Log.Error(ex.ToString()); Log.Error("Full Json:\n" + item2); } } uint num2 = 0u; foreach (JsonNode item3 in jsonNode["Blocks"].AsArray()) { uint num3 = (uint)(JsonNode)item3["persistentID"].AsValue(); if (num3 > num2) { num2 = num3; } } jsonNode["LastPersistentID"] = num2; string text2 = jsonNode.ToJsonStringIndented(); IntPtr result = IL2CPP.ManagedStringToIl2Cpp(text2); MTFOGameDataAPI.Invoke_OnGameDataContentLoaded(dataBlockBaseWrapper.FileName, text2); return result; } catch (Exception ex2) { Log.Error("Exception were found while handling Detour;Falling back to original content!"); Log.Error(ex2.ToString()); return intPtr; } } private static Stream GetContentStream(DataBlockBaseWrapper datablock, IntPtr originalContentPtr) { string binaryFileName = datablock.BinaryFileName; string path = binaryFileName + ".json"; string s = IL2CPP.Il2CppStringToManaged(originalContentPtr); string text = Path.Combine(ConfigManager.GameDataPath, path); if (File.Exists(text)) { Log.Verbose("Opening filestream of [" + binaryFileName + "] from disk..."); Log.Verbose(text); return PathUtil.OpenUtf8Stream(text); } Log.Verbose("No file found at [" + binaryFileName + "]"); return new MemoryStream(Encoding.UTF8.GetBytes(s)); } private static void DumpContent(DataBlockBaseWrapper datablock, string json) { if (!json.TryParseToJsonNode(out var jsonNode)) { Log.Verbose("Unable to dump " + datablock.FileName + ", Invalid Json Content!"); return; } bool flag = false; switch (ConfigManager.DumpMode) { case DumpGameDataMode.Single: flag = false; break; case DumpGameDataMode.PartialData: flag = datablock.PreferPartialBlockOnDump; break; case DumpGameDataMode.FullPartialData: flag = true; break; } if (flag) { JsonArray jsonArray = jsonNode["Blocks"].AsArray(); string text = Path.Combine(path2: datablock.FileName, path1: _BasePathToDump); PathUtil.PrepareEmptyDirectory(text); foreach (JsonNode item in jsonArray) { string path = string.Format("{0}__{1}.json", item["persistentID"], item["name"]); string text2 = Path.Combine(text, path); File.WriteAllText(text2, item.ToJsonStringIndented()); Log.Verbose(" - Save... " + text2); } jsonNode["Blocks"] = new JsonArray(); } string path2 = datablock.BinaryFileName + ".json"; File.WriteAllText(Path.Combine(_BasePathToDump, path2), jsonNode.ToJsonStringIndented()); Log.Verbose(datablock.FileName + " has dumped to '" + _BasePathToDump + "'"); } } } namespace MTFO.Managers { public enum DumpGameDataMode { Single, PartialData, FullPartialData } public static class ConfigManager { private const string CUSTOM_FOLDER = "Custom"; private static readonly ConfigEntry<bool> _enableHotReload; private static readonly ConfigEntry<bool> _dumpGameData; private static readonly ConfigEntry<bool> _isVerbose; private static readonly ConfigEntry<DumpGameDataMode> _dumpGameDataMode; public static int GAME_VERSION; public static ContentManager CustomContent; public static readonly string GameDataPath; public static readonly string CustomPath; public static bool HasGameDataPath; public static bool HasCustomContent; public static bool IsModded; public static bool IsPluginGameDataPath; public static bool IsVerbose => _isVerbose.Value; public static bool IsHotReloadEnabled => _enableHotReload.Value; public static bool DumpGameData => _dumpGameData.Value; public static DumpGameDataMode DumpMode => _dumpGameDataMode.Value; private static string ResolveGameDataPath(string rootPath) { foreach (string item in Directory.GetFiles(rootPath, "GameData_*.json", SearchOption.AllDirectories).OrderBy(Path.GetDirectoryName)) { if (Path.GetDirectoryName(item) != GameDataPath) { HasGameDataPath = true; return Path.GetDirectoryName(item); } } return null; } static ConfigManager() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "MTFO.cfg"), true); _enableHotReload = val.Bind<bool>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_HOTRELOAD, false, ConfigStrings.SETTING_HOTRELOAD_DESC); _dumpGameData = val.Bind<bool>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_DUMPDATA, false, ConfigStrings.SETTING_DUMPDATA_DESC); _dumpGameDataMode = val.Bind<DumpGameDataMode>(ConfigStrings.SECTION_DEV, ConfigStrings.SETTING_DUMPDATA_MODE, DumpGameDataMode.Single, ConfigStrings.SETTING_DUMPDATA_MODE_DESC); _isVerbose = val.Bind<bool>(ConfigStrings.SECTION_DEBUG, ConfigStrings.SETTING_VERBOSE, false, ConfigStrings.SETTING_VERBOSE_DESC); GAME_VERSION = GetGameVersion(); GameDataPath = ResolveGameDataPath(PathUtil.Prepare(BaseDirectory.GameData)); IsPluginGameDataPath = string.IsNullOrEmpty(GameDataPath); if (IsPluginGameDataPath) { GameDataPath = ResolveGameDataPath(Paths.PluginPath); Log.Warn("Plugin paths for gamedata are under legacy support and will be removed in the future. Considering migrating to the '\\BepInEx\\GameData' folder."); } if (HasGameDataPath) { CustomPath = Path.Combine(GameDataPath, "Custom"); HasCustomContent = Directory.Exists(CustomPath); } else { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsPluginGameDataPath = false; } try { CustomContent = new ContentManager(); } catch (Exception arg) { HasCustomContent = false; Log.Error($"Failed to init custom content!\nIs your JSON valid?\n---- ERROR MESSAGE ---- {arg} ---- END ERROR MESSAGE ----"); } Log.Debug("---- DEBUG INFO ----"); Log.Debug($"Time: {DateTime.Now}"); Log.Debug($"Game Version: {GAME_VERSION}"); Log.Debug("---- PATHS ----"); Log.Debug("Path to rundown: " + GameDataPath); Log.Debug("Path to custom content: " + CustomPath); Log.Debug("---- FLAGS ----"); Log.Debug($"Has GameData Path? {HasGameDataPath}"); Log.Debug($"Using plugin GameData path? {IsPluginGameDataPath}"); Log.Debug($"Has Custom Content? {HasCustomContent}"); Log.Debug($"Hot Reload Enabled? {IsHotReloadEnabled}"); Log.Debug($"Verbose Logging? {IsVerbose}"); Log.Debug($"Dump Game Data? {DumpGameData}"); Log.Debug("---- DEBUG END ----"); } private static int GetGameVersion() { return CellBuildData.GetRevision(); } } public class ContentManager { private readonly global::MTFO.Utilities.JsonSerializer json = new global::MTFO.Utilities.JsonSerializer(); private readonly Dictionary<string, Action<string>> Handlers; public ScanHolder ScanHolder; public GlowstickHolder GlowstickHolder; public TierNames TierNames; public ContentManager() { Handlers = new Dictionary<string, Action<string>> { { "puzzletypes.json", SetupChainedPuzzles }, { "glowsticks.json", SetupGlowsticks }, { "tiernames.json", SetupTierNames } }; Init(); } private void Init() { if (!ConfigManager.HasCustomContent) { return; } foreach (string key in Handlers.Keys) { if (PathUtil.CheckCustomFile(key, out var CombinedPath)) { Handlers.TryGetValue(key, out var value); try { value?.Invoke(CombinedPath); } catch (Exception msg) { Log.Error(msg); } Log.Debug(CombinedPath); } } } public void SetupChainedPuzzles(string path) { Log.Debug("Custom puzzles found"); ScanHolder = json.Deserialize<ScanHolder>(File.ReadAllText(path)); } public void SetupGlowsticks(string path) { Log.Debug("Custom glowsticks found"); GlowstickHolder = json.Deserialize<GlowstickHolder>(File.ReadAllText(path)); GlowstickHolder.Setup(); } public void SetupTierNames(string path) { TierNames = json.Deserialize<TierNames>(File.ReadAllText(path)); } } } namespace MTFO.HotReload { internal class HotGameDataManager : IHotManager { public void OnHotReload(int id) { GameDataInit.ReInitialize(); Log.Verbose("Reinitialized GameData"); } } internal class HotGearManager : IHotManager { private readonly int gearSlotsTotal = 3; public void OnHotReload(int id) { GearManager.Current.m_offlineSetupDone = false; CleanGearIcons(); CleanGearSlots(); GearManager.Current.SetupGearContainers(); LoadOfflineGearDatas(); GearManager.GenerateAllGearIcons(); GearManager.Current.m_offlineSetupDone = true; Log.Verbose("Reloaded Gear"); } private void CleanGearIcons() { GearManager.m_allGearWithPostedIconJobs.Clear(); foreach (Dictionary<uint, RenderTexture> item in (Il2CppArrayBase<Dictionary<uint, RenderTexture>>)(object)GearManager.Current.m_allGearIconTexturesPerInstanceKey) { item.Clear(); } } [Obsolete] private void CleanGearLobbySlots() { if (!((Object)(object)CM_PageLoadout.Current != (Object)null)) { return; } foreach (CM_InventorySlotItem componentsInChild in ((Component)CM_PageLoadout.Current.m_popupAlign).gameObject.GetComponentsInChildren<CM_InventorySlotItem>(true)) { Object.Destroy((Object)(object)((Component)componentsInChild).gameObject); } } private void CleanGearSlots() { for (int i = 0; i < gearSlotsTotal; i++) { ((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[i].Clear(); } } private void LoadOfflineGearDatas() { Il2CppArrayBase<PlayerOfflineGearDataBlock> allBlocks = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks(); if (allBlocks == null) { Log.Warn("Unable to get Player Offline Gear blocks"); return; } Log.Verbose($"Loading {allBlocks.Length} gear"); foreach (PlayerOfflineGearDataBlock item in allBlocks) { OfflineGear.Load(item); } } } public class HotReloader : MonoBehaviour { public static HotReloader Current; private CM_Item button; private readonly string buttonLabel = "Reload Game Data"; private readonly Vector3 buttonPosition = new Vector3(0f, 77f, 0f); private readonly List<IHotManager> managers = new List<IHotManager>(); public HotReloader(IntPtr intPtr) : base(intPtr) { }//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) private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ((Component)this).gameObject.transform.localPosition = buttonPosition; button = ((Component)this).gameObject.GetComponent<CM_Item>(); button.SetText(buttonLabel); AddOnReloadListener(new HotGameDataManager()); AddOnReloadListener(new HotRundownManager()); AddOnReloadListener(new HotGearManager()); button.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)delegate { MTFOHotReloadAPI.HotReloaded(); }); } public void AddOnReloadListener(IHotManager manager) { if (!managers.Contains(manager)) { button.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)manager.OnHotReload); managers.Add(manager); } } public void RemoveOnReloadListener(IHotManager manager) { if (managers.Contains(manager)) { button.OnBtnPressCallback -= Action<int>.op_Implicit((Action<int>)manager.OnHotReload); managers.Remove(manager); } } public static void Setup() { if (!((Object)(object)Current != (Object)null) && !((Object)(object)MainMenuGuiLayer.Current.PageRundownNew == (Object)null)) { GameObject obj = Object.Instantiate<GameObject>(((Component)MainMenuGuiLayer.Current.PageRundownNew.m_discordButton).gameObject, ((Component)MainMenuGuiLayer.Current.PageRundownNew.m_discordButton).transform.parent, false); ((Object)obj).name = "Button HotReload"; Current = obj.AddComponent<HotReloader>(); obj.SetActive(true); Log.Verbose("Created hot reload button"); } } } public class HotReloadInjector { [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")] public static void OnEnable() { HotReloader.Setup(); } } internal class HotRundownManager : IHotManager { private CM_PageRundown_New rundownPage; private bool hasValidRundown => GameDataBlockBase<RundownDataBlock>.s_blockByID.ContainsKey(Global.RundownIdToLoad); private RundownDataBlock rundownDataCurrent => GameDataBlockBase<RundownDataBlock>.GetBlock(Global.RundownIdToLoad); public HotRundownManager() { rundownPage = MainMenuGuiLayer.Current.PageRundownNew; } public void OnHotReload(int id) { if (hasValidRundown) { rundownPage.m_dataIsSetup = false; CleanIconsOfTier(); TryPlaceRundown(); } else { Log.Warn($"Failed to place the rundown due to missing Rundown id {Global.RundownIdToLoad}"); } Log.Verbose("Reloaded Rundown"); } private void CleanIconsOfTier() { CleanIconsOfTier(rundownPage.m_expIconsTier1); CleanIconsOfTier(rundownPage.m_expIconsTier2); CleanIconsOfTier(rundownPage.m_expIconsTier3); CleanIconsOfTier(rundownPage.m_expIconsTier4); CleanIconsOfTier(rundownPage.m_expIconsTier5); } private void CleanIconsOfTier(List<CM_ExpeditionIcon_New> tier) { Enumerator<CM_ExpeditionIcon_New> enumerator = tier.GetEnumerator(); while (enumerator.MoveNext()) { Object.Destroy((Object)(object)((Component)enumerator.Current).gameObject); } } private void TryPlaceRundown() { rundownPage.m_currentRundownData = rundownDataCurrent; if (rundownPage.m_currentRundownData != null) { rundownPage.PlaceRundown(rundownPage.m_currentRundownData); rundownPage.m_dataIsSetup = true; } else { Log.Warn("Unable to place rundown due to null data during reload"); } } } public interface IHotManager { void OnHotReload(int id); } public class OfflineGear { private GearIDRange gearIDRange; private ItemDataBlock itemData; private int inventorySlot; private uint persistentID; private OfflineGear(PlayerOfflineGearDataBlock block) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (TryParseGearJson(block.GearJSON, out gearIDRange)) { gearIDRange.PlayfabItemId = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name; gearIDRange.PlayfabItemInstanceId = $"OfflineGear_ID_{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}"; gearIDRange.OfflineGearType = block.Type; } if (TryParseGearID(gearIDRange, out itemData, out inventorySlot)) { persistentID = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID; } else { Log.Warn($"Unable to construct Offline Gear [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name}"); } } public static void Load(PlayerOfflineGearDataBlock block) { if (TryParse(block, out var result) && TryStash(result)) { Log.Verbose($"Loaded offline gear [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name}"); } } private static bool TryParse(PlayerOfflineGearDataBlock block, out OfflineGear result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) eOfflineGearType type = block.Type; if (type - 1 <= 1) { result = new OfflineGear(block); return true; } result = null; Log.Warn($"Unimplemented Offline Gear Type [{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}] {block.Type}"); return false; } private bool TryParseGearID(GearIDRange gearIDRange, out ItemDataBlock itemData, out int inventorySlot) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected I4, but got Unknown inventorySlot = 0; itemData = null; if (gearIDRange == null) { Log.Warn("Unable to parse GearIDRange due to it being null"); return false; } uint compID = gearIDRange.GetCompID((eGearComponent)3); itemData = ((compID != 0) ? GameDataBlockBase<ItemDataBlock>.GetBlock(compID) : null); if (itemData == null) { Log.Warn($"Invalid ItemDataBlock for component in offlinear gear [c:{compID}]"); return false; } inventorySlot = (int)itemData.inventorySlot; return true; } private bool TryParseGearJson(string gearJson, out GearIDRange gearIDRange) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (string.IsNullOrEmpty(gearJson)) { gearIDRange = null; Log.Warn("Unable to assign GearIDRange due to null or empty GearJson"); return false; } gearIDRange = new GearIDRange(gearJson); if (gearIDRange == null) { return false; } return true; } private static bool TryStash(OfflineGear gear) { if (gear == null) { Log.Warn("Unable to stash due to null offline gear"); return false; } if (gear.gearIDRange == null) { Log.Warn($"Unable to stash offline gear due to null GearIDRange [{gear.persistentID}]"); return false; } if (gear.itemData == null) { Log.Warn($"Unable to stash offline gear due to null ItemDataBlock [{gear.persistentID}]"); return false; } ((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[gear.inventorySlot].Add(gear.gearIDRange); return true; } } } namespace MTFO.CustomCP { public static class CustomPuzzleManager { private static readonly Dictionary<uint, CustomBioScan> s_scanMap = new Dictionary<uint, CustomBioScan>(); private static readonly Dictionary<uint, CustomClusterScan> s_clusterMap = new Dictionary<uint, CustomClusterScan>(); private static bool s_initialized = false; public static bool TryGetScanByID(uint id, out CustomBioScan scan) { return s_scanMap.TryGetValue(id, out scan); } public static bool TryGetClusterByID(uint id, out CustomClusterScan cluster) { return s_clusterMap.TryGetValue(id, out cluster); } internal static void Initialize(ChainedPuzzleManager manager) { if (!s_initialized) { s_initialized = true; ClassInjector.RegisterTypeInIl2Cpp<CorePuzzleData>(); ClassInjector.RegisterTypeInIl2Cpp<ClusterPuzzleData>(); if (ConfigManager.CustomContent.ScanHolder != null) { InitScans(manager); InitClusters(manager); } } } private static void InitScans(ChainedPuzzleManager manager) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)manager == (Object)null) { Log.Error("Attempted to initialize custom bioscans with a null ChainedPuzzleManager. This should not happen!"); throw new NullReferenceException("ChainedPuzzleManager was null"); } foreach (CustomBioScan scan in ConfigManager.CustomContent.ScanHolder.Scans) { Log.Debug($"Adding scan with ID of [{scan.PersistentID}]"); if (!manager.m_puzzleComponentPrefabs.ContainsKey(scan.BaseScan)) { Log.Error($"Custom scan with persistent ID {scan.PersistentID} references a non-existing base scan of persistent ID {scan.BaseScan}"); continue; } GameObject val = manager.m_puzzleComponentPrefabs[scan.BaseScan]; if ((Object)(object)val.GetComponent<CP_Bioscan_Core>() == (Object)null) { Log.Error(string.Format("BaseScan id: {0} does not have {1} component!", scan.PersistentID, "CP_Bioscan_Core")); continue; } GameObject val2 = Object.Instantiate<GameObject>(val); val2.transform.position = new Vector3(10000f, 10000f, 10000f); CP_PlayerScanner component = val2.GetComponent<CP_PlayerScanner>(); if ((Object)(object)component != (Object)null) { component.m_reduceSpeed = scan.ReduceSpeed; component.m_reduceWhenNoPlayer = scan.ReduceWhenNoPlayer; component.m_scanRadius = scan.ScanRadius; component.m_scanSpeeds = Il2CppStructArray<float>.op_Implicit(scan.PlayersInScanMulti); component.m_playerRequirement = scan.PlayerRequirement; } else { Log.Warn(string.Format("BaseScan id: {0} does not have {1} component! This will make following setting won't work!", scan.BaseScan, "CP_PlayerScanner")); Log.Warn(" - ReduceSpeed"); Log.Warn(" - ReduceWhenNoPlayer"); Log.Warn(" - ScanRadius"); Log.Warn(" - PlayersInScanMulti"); Log.Warn(" - PlayerRequirement"); } CP_Bioscan_Graphics component2 = val2.GetComponent<CP_Bioscan_Graphics>(); if ((Object)(object)component2 != (Object)null) { component2.m_radius = scan.BioScanGraphics.Radius; component2.m_colors = Il2CppReferenceArray<ColorModeColor>.op_Implicit(ConvertToColorMode(scan.BioScanGraphics.ColorModeColor)); component2.SetText(scan.BioScanGraphics.ScanText); } else { Log.Warn(string.Format("BaseScan id: {0} does not have {1} component! This will make {2} setting won't work!", scan.BaseScan, "CP_Bioscan_Graphics", "BioScanGraphics")); } val2.GetComponent<CP_Bioscan_Core>().m_playerAgents = new List<PlayerAgent>(); val2.AddComponent<CorePuzzleData>().PersistentID.Set(scan.PersistentID); s_scanMap.Add(scan.PersistentID, scan); manager.m_puzzleComponentPrefabs.Add(scan.PersistentID, val2); } } private static void InitClusters(ChainedPuzzleManager manager) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)manager == (Object)null) { Log.Error("Attempted to initialize custom clusters with a null ChainedPuzzleManager. This should not happen!"); throw new NullReferenceException("ChainedPuzzleManager was null"); } foreach (CustomClusterScan cluster in ConfigManager.CustomContent.ScanHolder.Clusters) { Log.Debug($"Adding cluster with ID of [{cluster.PersistentID}]"); if (!manager.m_puzzleComponentPrefabs.ContainsKey(cluster.BaseCluster)) { Log.Error($"Custom cluster scan with persistent ID {cluster.PersistentID} references a non-existing base cluster of persistent ID {cluster.BaseCluster}"); continue; } if (!manager.m_puzzleComponentPrefabs.ContainsKey(cluster.BioscanID)) { Log.Error($"Custom cluster scan with persistent ID {cluster.PersistentID} references a non-existing bioscan of persistent ID {cluster.BioscanID}"); continue; } GameObject val = manager.m_puzzleComponentPrefabs[cluster.BaseCluster]; if ((Object)(object)val.GetComponent<CP_Cluster_Core>() == (Object)null) { Log.Error(string.Format("BaseScan id: {0} does not have {1} component!", cluster.PersistentID, "CP_Cluster_Core")); continue; } GameObject val2 = Object.Instantiate<GameObject>(val); val2.transform.position = new Vector3(1000f, 1000f, 1000f); CP_Cluster_Core component = val2.GetComponent<CP_Cluster_Core>(); GameObject childPuzzlePrefab = manager.m_puzzleComponentPrefabs[cluster.BioscanID]; component.m_amountOfPuzzles = cluster.ClusterCount; component.m_childPuzzlePrefab = childPuzzlePrefab; component.m_distanceBetween = cluster.DistanceBetweenScans; component.m_revealWithHoloPath = cluster.RevealWithHoloPath; val2.AddComponent<ClusterPuzzleData>().PersistentID.Set(cluster.PersistentID); s_clusterMap.Add(cluster.PersistentID, cluster); manager.m_puzzleComponentPrefabs.Add(cluster.PersistentID, val2); } } private static ColorModeColor[] ConvertToColorMode(CustomBioScan.BioScanColorByMode[] bioScanColorByModes) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_003b: 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_0048: Expected O, but got Unknown ColorModeColor[] array = (ColorModeColor[])(object)new ColorModeColor[bioScanColorByModes.Length]; for (int i = 0; i < bioScanColorByModes.Length; i++) { CustomBioScan.BioScanColorByMode bioScanColorByMode = bioScanColorByModes[i]; array[i] = new ColorModeColor { col = new Color(bioScanColorByMode.R, bioScanColorByMode.G, bioScanColorByMode.B, bioScanColorByMode.A), mode = bioScanColorByMode.Mode }; } return array; } } } namespace MTFO.CustomCP.Patches { [HarmonyPatch(typeof(ChainedPuzzleManager), "OnAssetsLoaded")] internal static class Patch_PuzzleManager { internal static void Postfix(ChainedPuzzleManager __instance) { CustomPuzzleManager.Initialize(__instance); } } [HarmonyPatch(typeof(CP_Bioscan_Core), "Update")] internal static class FixNullRefSpam { internal static bool Prefix(CP_Bioscan_Core __instance) { //IL_000b: 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_0043: Unknown result type (might be due to invalid IL or missing references) if (((Component)__instance).gameObject.transform.position.x > 9000f && ((Component)__instance).gameObject.transform.position.y > 9000f && ((Component)__instance).gameObject.transform.position.z > 9000f) { return false; } return true; } } [HarmonyPatch] internal static class Patch_SetupPuzzleCores { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")] public static void SetupSpline(CP_Bioscan_Core __instance) { CorePuzzleData component = ((Component)__instance).GetComponent<CorePuzzleData>(); if (!((Object)(object)component == (Object)null) && CustomPuzzleManager.TryGetScanByID(component.PersistentID.Value, out var scan)) { CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast<CP_Holopath_Spline>(); if ((Object)(object)val != (Object)null) { scan.ApplySplineRevealSpeed(val); } } } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(CP_Cluster_Core), "Setup")] public static void SetupSpline(CP_Cluster_Core __instance) { ClusterPuzzleData component = ((Component)__instance).GetComponent<ClusterPuzzleData>(); if (!((Object)(object)component == (Object)null) && CustomPuzzleManager.TryGetClusterByID(component.PersistentID.Value, out var cluster)) { CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast<CP_Holopath_Spline>(); if ((Object)(object)val != (Object)null) { cluster.ApplySplineRevealSpeed(val); } } } } } namespace MTFO.Custom { public class GlowstickHolder { [JsonIgnore] public Dictionary<string, CustomGlowstick> GlowstickLookup; public List<GlowstickConfig> Glowsticks { get; set; } public void Setup() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) GlowstickLookup = new Dictionary<string, CustomGlowstick>(); foreach (GlowstickConfig glowstick in Glowsticks) { Log.Verbose(glowstick); if (GlowstickLookup.TryGetValue(glowstick.Name, out var value)) { Log.Warn("Custom glowstick with name " + glowstick.Name + " already exists in the lookup! Skipping..."); continue; } value = default(CustomGlowstick); value.Color = new Color(glowstick.r, glowstick.g, glowstick.b, (glowstick.a == 0f) ? 1f : glowstick.a); value.Range = ((glowstick.Range == 0f) ? 15f : glowstick.Range); CustomGlowstick value2 = value; GlowstickLookup.Add(glowstick.Name, value2); } } } public struct CustomGlowstick { public Color Color { get; set; } public float Range { get; set; } } public struct GlowstickConfig { public string Name { get; set; } public float Range { get; set; } public float r { get; set; } public float g { get; set; } public float b { get; set; } public float a { get; set; } public override string ToString() { return $"{Name},{Range},{r},{g},{b},{a}"; } } public class ScanHolder { public List<CustomBioScan> Scans { get; set; } public List<CustomClusterScan> Clusters { get; set; } } public enum RevealMode { ScaleByDistance, ConstantTime, Instant } public struct CustomBioScan : IRevealableScanConfig { public struct BioScanGx { public bool HideScanText { get; set; } public string ScanText { get; set; } public float Radius { get; set; } public BioScanColorByMode[] ColorModeColor { get; set; } } public class BioScanColorByMode { public eChainedPuzzleGraphicsColorMode Mode { get; set; } public float R { get; set; } public float G { get; set; } public float B { get; set; } public float A { get; set; } } public uint BaseScan { get; set; } public uint PersistentID { get; set; } public PlayerRequirement PlayerRequirement { get; set; } public float ScanRadius { get; set; } public float[] PlayersInScanMulti { get; set; } public float ReduceSpeed { get; set; } public bool ReduceWhenNoPlayer { get; set; } public float RevealTime { get; set; } public RevealMode RevealMode { get; set; } public BioScanGx BioScanGraphics { get; set; } } public struct CustomClusterScan : IRevealableScanConfig { public uint BaseCluster { get; set; } public uint PersistentID { get; set; } public int ClusterCount { get; set; } public uint BioscanID { get; set; } public float DistanceBetweenScans { get; set; } public float RevealTime { get; set; } public RevealMode RevealMode { get; set; } public bool RevealWithHoloPath { get; set; } } internal interface IRevealableScanConfig { uint PersistentID { get; } float RevealTime { get; } RevealMode RevealMode { get; } } internal static class IRevealibleScanConfigExtensions { public static void ApplySplineRevealSpeed(this IRevealableScanConfig scan, CP_Holopath_Spline spline) { float revealTime = scan.RevealTime; switch (scan.RevealMode) { case RevealMode.ConstantTime: if (revealTime <= 0f) { Log.Warn($"Attempted to set a custom scan with persistent id '{scan.PersistentID}' to reveal in less than or equal to 0 seconds. This is not supported. Instead, use RevealMode \"{RevealMode.Instant}\" or integer value {2}"); break; } spline.m_splineLength = 1f; spline.m_revealSpeed = revealTime; break; case RevealMode.ScaleByDistance: if (revealTime < 0f) { Log.Warn($"Attempted to set a custom scan with persistent id '{scan.PersistentID}' to reveal in less than 0 seconds. This is not supported."); } else if (revealTime != 0f) { spline.m_revealSpeed = revealTime; } break; case RevealMode.Instant: spline.m_revealSpeed = -1f; break; } } } public struct TierNames { public string Tier1 { get; set; } public string Tier2 { get; set; } public string Tier3 { get; set; } public string Tier4 { get; set; } public string Tier5 { get; set; } } } namespace MTFO.Custom.CCP.Patches { [HarmonyPatch(typeof(CP_Bioscan_Hud))] internal static class Patch_Bioscan_Hud { [HarmonyPatch("Awake")] [HarmonyPostfix] internal static void Post_Setup(CP_Bioscan_Hud __instance) { UpdateText(__instance); } [HarmonyPatch("SetVisible")] [HarmonyPostfix] internal static void Post_SetVisible(CP_Bioscan_Hud __instance) { UpdateText(__instance); } [HarmonyPatch("UpdateText")] [HarmonyPostfix] internal static void Post_UpdateText(CP_Bioscan_Hud __instance) { UpdateText(__instance); } private static void UpdateText(CP_Bioscan_Hud hud) { CorePuzzleData component = ((Component)hud).gameObject.GetComponent<CorePuzzleData>(); if ((Object)(object)component != (Object)null) { if (!CustomPuzzleManager.TryGetScanByID(component.PersistentID.Value, out var scan)) { Log.Error($"scanData missing... {component.PersistentID.Value}"); } else if (scan.BioScanGraphics.HideScanText) { ((TMP_Text)hud.m_bioscanWorldText).SetText(string.Empty, true); } else if (!string.IsNullOrWhiteSpace(scan.BioScanGraphics.ScanText)) { ((TMP_Text)hud.m_bioscanWorldText).SetText(scan.BioScanGraphics.ScanText, true); } } } } } namespace MTFO.Custom.CCP.Components { internal sealed class ClusterPuzzleData : MonoBehaviour { public Il2CppValueField<uint> PersistentID; public CP_Bioscan_Hud[] ChildHuds = Array.Empty<CP_Bioscan_Hud>(); } internal sealed class CorePuzzleData : MonoBehaviour { public Il2CppValueField<uint> PersistentID; } } namespace MTFO.API { public delegate void GameDataContentLoadEvent(string datablockName, string jsonContent, in List<string> jsonItemsToInject); public delegate void GameDataContentLoadedDelegate(string datablockName, string jsonContent); public static class MTFOGameDataAPI { public static event GameDataContentLoadEvent OnGameDataContentLoad; public static event GameDataContentLoadedDelegate OnGameDataContentLoaded; internal static void Invoke_OnGameDataContentLoad(string datablockName, Stream jsonContentStream, in List<string> jsonItemsToInject) { if (MTFOGameDataAPI.OnGameDataContentLoad != null) { MTFOGameDataAPI.OnGameDataContentLoad(datablockName, new StreamReader(jsonContentStream).ReadToEnd(), in jsonItemsToInject); } } internal static void Invoke_OnGameDataContentLoaded(string datablockName, string jsonContent) { MTFOGameDataAPI.OnGameDataContentLoaded?.Invoke(datablockName, jsonContent); } } public static class MTFOHotReloadAPI { public static bool HotReloadEnabled => ConfigManager.IsHotReloadEnabled; public static event Action OnHotReload; internal static void HotReloaded() { MTFOHotReloadAPI.OnHotReload?.Invoke(); } } public static class MTFOPathAPI { public static string RundownPath => ConfigManager.GameDataPath; public static bool HasRundownPath => ConfigManager.HasGameDataPath; public static string CustomPath => ConfigManager.CustomPath; public static bool HasCustomPath => ConfigManager.HasCustomContent; } }
plugins/net6/MTFO.Ext.PartialData.InjectLib.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using AIGraph; using AssetShards; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using GTFO.API.Utilities; using GameData; using Gear; using Globals; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppJsonNet; using Il2CppJsonNet.Linq; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using InjectLib.JsonNETInjection; using InjectLib.JsonNETInjection.Converter; using LevelGeneration; using Localization; using MTFO.Ext.PartialData.DTO; using MTFO.Ext.PartialData.DataBlockTypes; using MTFO.Ext.PartialData.JsonConverters; using MTFO.Ext.PartialData.JsonInjects; using MTFO.Ext.PartialData.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("MTFO.Ext.PartialData")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("MTFO.Ext.PartialData")] [assembly: AssemblyTitle("MTFO.Ext.PartialData")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [assembly: AssemblyVersion("0.1.0.0")] namespace MTFO.Ext.PartialData { [BepInPlugin("MTFO.Extension.PartialBlocks", "MTFO pDataBlock", "1.4.0")] [BepInProcess("GTFO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { private bool once; public override void Load() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0062: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) Logger.LogInstance = ((BasePlugin)this).Log; ConfigEntry<bool> val = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Logging", "UseLog"), false, new ConfigDescription("Using Log Message for Debug?", (AcceptableValueBase)null, Array.Empty<object>())); ConfigEntry<bool> obj = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Developer", "UseLiveEdit"), false, new ConfigDescription("Using Live Edit?", (AcceptableValueBase)null, Array.Empty<object>())); Logger.UsingLog = val.Value; PartialDataManager.CanLiveEdit = obj.Value; if (!DataBlockTypeManager.Initialize()) { Logger.Error("Unable to Initialize DataBlockTypeCache"); return; } if (!PartialDataManager.Initialize()) { Logger.Error("Unable to Initialize PartialData"); return; } PersistentIDManager.DumpToFile(Path.Combine(PartialDataManager.PartialDataPath, "_persistentID.json")); AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)OnAssetLoaded); new Harmony("MTFO.pBlock.Harmony").PatchAll(); JsonInjector.SetConverter<uint>((Il2CppJsonUnmanagedTypeConverter<uint>)new UintConverter()); } private void OnAssetLoaded() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (once) { return; } once = true; PartialDataManager.LoadPartialData(); GameDataTextLocalizationService val = ((Il2CppObjectBase)Text.TextLocalizationService).Cast<GameDataTextLocalizationService>(); val.m_textDataBlocks = null; val.m_texts.Clear(); Language currentLanguage = Text.TextLocalizationService.CurrentLanguage; TextDataBlock[] array = Il2CppArrayBase<TextDataBlock>.op_Implicit(GameDataBlockBase<TextDataBlock>.GetAllBlocks()); val.m_textDataBlocks = Il2CppReferenceArray<TextDataBlock>.op_Implicit(array); int num = array.Length; for (int i = 0; i < num; i++) { TextDataBlock val2 = array[i]; string text = val2.GetText(currentLanguage, false); if (string.IsNullOrWhiteSpace(text)) { text = val2.English; } val.m_texts[((GameDataBlockBase<TextDataBlock>)(object)val2).persistentID] = text; } Text.TextLocalizationService.SetCurrentLanguage(Text.TextLocalizationService.CurrentLanguage); Text.UpdateAllTexts(); PartialDataManager.WriteAllFile(Path.Combine(MTFOUtil.GameDataPath, "CompiledPartialData")); } } public static class LocalizedTextManager { public static Dictionary<LocalizedText, (uint, string)> _lookup = new Dictionary<LocalizedText, (uint, string)>(); public static void Register(LocalizedText localizedText, uint id, string unlocalized) { _lookup[localizedText] = (id, unlocalized); } public static void Get(LocalizedText localizedText) { } } internal class PartialDataCache { public string Name => DataBlockType.GetShortName(); public IDataBlockType DataBlockType { get; private set; } public Queue<string> JsonsToRead { get; private set; } = new Queue<string>(); private PartialDataCache() { } public PartialDataCache(IDataBlockType dbTypeCache) { DataBlockType = dbTypeCache; } } public class PartialDataManager { private static List<DataBlockDefinition> _Config; private static readonly List<string> _AddedFileList = new List<string>(); private static readonly List<PartialDataCache> _DataCache = new List<PartialDataCache>(); public static string PartialDataPath { get; private set; } public static string ConfigPath { get; private set; } public static bool Initialized { get; private set; } = false; public static bool CanLiveEdit { get; set; } = false; public static PersistentIDConverter IDConverter { get; private set; } = new PersistentIDConverter(); internal static bool Initialize() { if (Initialized) { return false; } if (!MTFOUtil.IsLoaded) { return false; } PartialDataPath = Path.GetFullPath(Path.Combine(MTFOUtil.GameDataPath, "PartialData")); if (!Directory.Exists(PartialDataPath)) { Logger.Error("Unable to setup PartialData::PartialData folder is missing"); return false; } ConfigPath = Path.GetFullPath(Path.Combine(PartialDataPath, "_config.json")); if (!File.Exists(ConfigPath)) { Logger.Error("Unable to setup PartialData::Config File (_config.json) is missing"); return false; } _AddedFileList.Clear(); _DataCache.Clear(); _Config = JSON.Deserialize<List<DataBlockDefinition>>(File.ReadAllText(ConfigPath)); Initialized = true; ReadAndAssignIDs(); return true; } private static void ReadAndAssignIDs() { foreach (DataBlockDefinition item in _Config) { DataBlockTypeManager.SetIDBuffer(item.TypeName, item.StartFromID, item.IncrementMode); } foreach (string item2 in from f in Directory.GetFiles(PartialDataPath, "*.json", SearchOption.AllDirectories) orderby f select f) { if (Path.GetFileName(item2).StartsWith("_")) { Logger.Log(item2 + " have discard prefix (_) excluding from loader!"); continue; } if (!File.Exists(item2)) { Logger.Error("File (" + item2 + ") is not exist somehow?"); continue; } if (_AddedFileList.Contains(item2)) { Logger.Error("File (" + item2 + ") has loaded multiple times!"); continue; } _AddedFileList.Add(item2); AssignPersistentID(item2); Logger.Log(" - " + item2); } } private static void AssignPersistentID(string file) { using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); JsonElement rootElement = jsonDocument.RootElement; switch (rootElement.ValueKind) { case JsonValueKind.Array: { foreach (JsonElement item in rootElement.EnumerateArray()) { Read(item, assignID: true, file); } break; } case JsonValueKind.Object: Read(rootElement, assignID: true, file); break; } } private static void ReadChangedFile(string content, string debugName) { using JsonDocument jsonDocument = JsonDocument.Parse(content, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); JsonElement rootElement = jsonDocument.RootElement; switch (rootElement.ValueKind) { case JsonValueKind.Array: { foreach (JsonElement item in rootElement.EnumerateArray()) { Read(item, assignID: false, debugName); } break; } case JsonValueKind.Object: Read(rootElement, assignID: false, debugName); break; } } private static void ReadChangedFile(string file) { ReadChangedFile(File.ReadAllText(file), file); } private static void Read(JsonElement objNode, bool assignID, string debugName) { if (!objNode.TryGetProperty("persistentID", out var value)) { Logger.Error("persistentID field is missing: " + debugName); return; } if (!objNode.TryGetProperty("datablock", out var value2)) { Logger.Error("datablock field is missing: " + debugName); return; } if (assignID && value.ValueKind == JsonValueKind.String) { if (!DataBlockTypeManager.TryGetNextID(value2.GetString(), out var id)) { Logger.Error($"datablock field is not valid: {debugName} {objNode}"); return; } PersistentIDManager.TryAssignId(value.GetString(), id); } string datablockName = DataBlockTypeManager.GetBlockName(value2.GetString()); if (!DataBlockTypeManager.TryFindCache(datablockName, out var cache)) { Logger.Error($"datablock field is not valid: {debugName} {objNode}"); return; } PartialDataCache partialDataCache = _DataCache.FirstOrDefault((PartialDataCache x) => x.Name.Equals(datablockName)); if (partialDataCache == null) { partialDataCache = new PartialDataCache(cache); _DataCache.Add(partialDataCache); } partialDataCache.JsonsToRead.Enqueue(objNode.ToString()); } internal static void LoadPartialData() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (Initialized) { if (CanLiveEdit) { LiveEdit.CreateListener(PartialDataPath, "*.json", true).FileChanged += new LiveEditEventHandler(Listener_FileChanged1); } AddAllCache(); } } private static void Listener_FileChanged1(LiveEditEventArgs e) { Logger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { ReadChangedFile(content, e.FullPath); AddAllCache(isLiveEdit: true); }); } internal static void WriteAllFile(string path) { if (!Directory.Exists(path)) { return; } foreach (PartialDataCache item in _DataCache) { string fullPath = Path.GetFullPath(Path.Combine(path, "GameData_" + item.DataBlockType.GetFullName() + "_bin.json")); item.DataBlockType.DoSaveToDisk(fullPath); } } private static void AddAllCache(bool isLiveEdit = false) { foreach (PartialDataCache item in _DataCache) { bool flag = false; while (item.JsonsToRead.Count > 0) { string json = item.JsonsToRead.Dequeue(); item.DataBlockType.AddJsonBlock(json); flag = true; } if (flag && isLiveEdit) { item.DataBlockType.OnChanged(); } } } public static uint GetID(string guid) { if (!Initialized) { return 0u; } return PersistentIDManager.GetId(guid); } } public class PartialDataPack { private readonly List<string> _AddedFiles = new List<string>(); private readonly List<PartialDataCache> _DataCaches = new List<PartialDataCache>(); public string Namespace { get; private set; } = string.Empty; public bool CheckFileChange { get; set; } = true; public PartialDataPack() { } public PartialDataPack(string namespaceString) : this() { Namespace = namespaceString; } public string GetGUIDFormat(string guid) { if (!string.IsNullOrEmpty(Namespace)) { guid = Namespace + "." + guid; } return guid; } public void ClearPack() { _AddedFiles.Clear(); _DataCaches.Clear(); } public void ReadPack(string packPath) { foreach (string item in from f in Directory.GetFiles(packPath, "*.json", SearchOption.AllDirectories) orderby f select f) { if (Path.GetFileName(item).StartsWith("_")) { Logger.Log(item + " have discard prefix (_) excluding from loader!"); continue; } if (!File.Exists(item)) { Logger.Error("File (" + item + ") is not exist somehow?"); continue; } if (_AddedFiles.Contains(item)) { Logger.Error("File (" + item + ") has loaded multiple times!"); continue; } _AddedFiles.Add(item); AllocateGUIDFromFile(item); Logger.Log(" - " + item); } _ = CheckFileChange; } public void AddToGame() { foreach (PartialDataCache dataCache in _DataCaches) { while (dataCache.JsonsToRead.Count > 0) { string json = dataCache.JsonsToRead.Dequeue(); dataCache.DataBlockType.AddJsonBlock(json); } } } public void WriteGameDataFile(string path) { if (!Directory.Exists(path)) { return; } foreach (PartialDataCache dataCache in _DataCaches) { string fullPath = Path.GetFullPath(Path.Combine(path, "GameData_" + dataCache.DataBlockType.GetFullName() + "_bin.json")); dataCache.DataBlockType.DoSaveToDisk(fullPath); } } private void AllocateGUIDFromFile(string file) { using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); JsonElement rootElement = jsonDocument.RootElement; switch (rootElement.ValueKind) { case JsonValueKind.Array: { foreach (JsonElement item in rootElement.EnumerateArray()) { Read(item, assignID: true, file); } break; } case JsonValueKind.Object: Read(rootElement, assignID: true, file); break; } } private void ReadChangedFile(string file) { using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(file), new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); JsonElement rootElement = jsonDocument.RootElement; switch (rootElement.ValueKind) { case JsonValueKind.Array: { foreach (JsonElement item in rootElement.EnumerateArray()) { Read(item, assignID: false, file); } break; } case JsonValueKind.Object: Read(rootElement, assignID: false, file); break; } } private void OnDatablockChanged() { foreach (PartialDataCache dataCache in _DataCaches) { bool flag = false; while (dataCache.JsonsToRead.Count > 0) { if (dataCache.Name.Equals("Rundown")) { dataCache.JsonsToRead.Clear(); Logger.Error("Editing Rundown DataBlock will leads to crash, Ignored"); } else { string json = dataCache.JsonsToRead.Dequeue(); dataCache.DataBlockType.AddJsonBlock(json); flag = true; } } if (flag) { dataCache.DataBlockType.OnChanged(); } } } private void Read(JsonElement objNode, bool assignID, string debugName) { if (!objNode.TryGetProperty("persistentID", out var value)) { Logger.Error("persistentID field is missing: " + debugName); return; } if (!objNode.TryGetProperty("datablock", out var value2)) { Logger.Error("datablock field is missing: " + debugName); return; } if (assignID && value.ValueKind == JsonValueKind.String) { if (!DataBlockTypeManager.TryGetNextID(value2.GetString(), out var id)) { Logger.Error($"datablock field is not valid: {debugName} {objNode}"); return; } PersistentIDManager.TryAssignId(value.GetString(), id); } string datablockName = DataBlockTypeManager.GetBlockName(value2.GetString()); if (!DataBlockTypeManager.TryFindCache(datablockName, out var cache)) { Logger.Error($"datablock field is not valid: {debugName} {objNode}"); return; } PartialDataCache partialDataCache = _DataCaches.FirstOrDefault((PartialDataCache x) => x.Name.Equals(datablockName)); if (partialDataCache == null) { partialDataCache = new PartialDataCache(cache); _DataCaches.Add(partialDataCache); } string text = objNode.ToString(); if (partialDataCache.DataBlockType.GetShortName() == "PlayerOfflineGear") { if (!objNode.TryGetProperty("GearJSON", out var value3)) { Logger.Warning("GearJSON field is missing, Ignore Stuff: " + debugName); } else if (value3.ValueKind == JsonValueKind.String) { string @string = value3.GetString(); if (GearJSONUtil.TryProcessGUID(@string, Namespace, out var processedJson)) { @string = @string.Replace("\"", "\\\""); processedJson = processedJson.Replace("\"", "\\\""); text = text.Replace(@string, processedJson); Logger.Warning(text); } } } partialDataCache.JsonsToRead.Enqueue(text); } } internal static class PersistentIDManager { private static readonly Dictionary<string, uint> _GUIDDict = new Dictionary<string, uint>(); public static bool TryAssignId(string guid, uint id) { if (_GUIDDict.ContainsKey(guid)) { Logger.Error("GUID is already used: " + guid); return false; } _GUIDDict.Add(guid, id); return true; } public static uint GetId(string guid) { if (!_GUIDDict.TryGetValue(guid, out var value)) { Logger.Error("GUID is Missing: " + guid); return 0u; } return value; } public static bool TryGetId(string guid, out uint id) { if (_GUIDDict.TryGetValue(guid, out id)) { return true; } id = 0u; return false; } public static void DumpToFile(string path) { string text = "[\n\t//AUTO-GENERATED PERSISTENT ID LIST\n"; foreach (KeyValuePair<string, uint> item in _GUIDDict) { text = text + "\t{ \"GUID\": \"" + item.Key + "\", \"ID\": " + item.Value + " },\n"; } if (text.Length > 2) { string text2 = text; text = text2.Substring(0, text2.Length - 2); } text += "\n]"; File.WriteAllText(path, text); } } } namespace MTFO.Ext.PartialData.Utils { public static class GearJSONUtil { private const string COMP_CHARS = "abcdefghijklmnopqrst"; public static bool TryProcessGUID(string gearjson, string namespaceStr, out string processedJson) { string text = gearjson; bool flag = false; using JsonDocument jsonDocument = JsonDocument.Parse(gearjson); if (!jsonDocument.RootElement.TryGetProperty("Packet", out var value)) { processedJson = string.Empty; return false; } if (!value.TryGetProperty("Comps", out var value2)) { processedJson = string.Empty; return false; } string text2 = "abcdefghijklmnopqrst"; for (int i = 0; i < text2.Length; i++) { if (value2.TryGetProperty(text2[i].ToString(), out var value3) && value3.TryGetProperty("v", out var value4) && value4.ValueKind == JsonValueKind.String) { string @string = value4.GetString(); Logger.Warning("Found String id: " + @string); uint id = PersistentIDManager.GetId(@string); if (id != 0) { text = new Regex("(\"v\")\\s*:\\s*(\"" + @string + "\")").Replace(text, $"\"v\":{id}"); flag = true; } } } if (flag) { Logger.Warning(gearjson); Logger.Warning(text); processedJson = text; return true; } processedJson = string.Empty; return false; } } public class IDBuffer { public uint CurrentID { get; set; } = 65535u; public IncrementMode IncrementMode { get; set; } public uint GetNext() { if (IncrementMode == IncrementMode.Increment) { return CurrentID++; } if (IncrementMode == IncrementMode.Decrement) { return CurrentID--; } return 0u; } } public enum IncrementMode { Decrement, Increment } internal static class JSON { private static readonly JsonSerializerOptions _Setting; static JSON() { _Setting = CreateSetting(); _Setting = CreateSetting(); _Setting.Converters.Add(new PersistentIDConverter()); } private static JsonSerializerOptions CreateSetting() { return new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = true, AllowTrailingCommas = true, WriteIndented = true, Converters = { (JsonConverter)new Il2CppListConverterFactory(), (JsonConverter)new ColorConverter(), (JsonConverter)new JsonStringEnumConverter(), (JsonConverter)new LocalizedTextConverter() } }; } public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, _Setting); } public static object Deserialize(string json, Type type) { return JsonSerializer.Deserialize(json, type, _Setting); } } internal static class Logger { public static ManualLogSource LogInstance; public static bool UsingLog; public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (UsingLog) { ManualLogSource logInstance = LogInstance; if (logInstance != null) { logInstance.Log((LogLevel)8, (object)str); } } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { ManualLogSource logInstance = LogInstance; if (logInstance != null) { logInstance.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { ManualLogSource logInstance = LogInstance; if (logInstance != null) { logInstance.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { ManualLogSource logInstance = LogInstance; if (logInstance != null) { logInstance.Log((LogLevel)32, (object)str); } } } internal static class MTFOUtil { public const string MTFOGUID = "com.dak.MTFO"; public static string GameDataPath { get; private set; } public static string CustomPath { get; private set; } public static bool HasCustomContent { get; private set; } public static bool IsLoaded { get; private set; } static MTFOUtil() { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info)) { return; } try { Type obj = (AppDomain.CurrentDomain.GetAssemblies().First((Assembly a) => !a.IsDynamic && a.Location == info.Location) ?? throw new Exception("Assembly is Missing!")).GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class"); FieldInfo field = obj.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = obj.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); FieldInfo? field3 = obj.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public); if ((object)field == null) { throw new Exception("Unable to Find Field: GameDataPath"); } if ((object)field2 == null) { throw new Exception("Unable to Find Field: CustomPath"); } if ((object)field3 == null) { throw new Exception("Unable to Find Field: HasCustomContent"); } GameDataPath = (string)field.GetValue(null); CustomPath = (string)field2.GetValue(null); HasCustomContent = (bool)field3.GetValue(null); IsLoaded = true; } catch (Exception value) { Console.WriteLine($"Exception thrown while reading path from Data Dumper (MTFO):\n{value}"); } } } } namespace MTFO.Ext.PartialData.JsonInjects { internal class UintConverter : Il2CppJsonUnmanagedTypeConverter<uint> { protected override uint Read(JToken jToken, uint existingValue, JsonSerializer serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if ((int)jToken.Type == 6) { return (uint)jToken; } if ((int)jToken.Type == 8) { return PartialDataManager.GetID((string)jToken); } Logger.Error($"{jToken} is not valid!"); return existingValue; } protected override Object ToIl2CppObject(uint value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt32 val = default(UInt32); val.m_value = value; return ((UInt32)(ref val)).BoxIl2CppObject(); } protected override void Write(JsonWriter writer, uint value, JsonSerializer serializer) { writer.WriteValue(value); } } } namespace MTFO.Ext.PartialData.JsonConverters { internal class ColorConverter : JsonConverter<Color> { public override bool HandleNull => false; public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0002: 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_00f0: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); switch (reader.TokenType) { case JsonTokenType.StartObject: while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return result; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? @string = reader.GetString(); reader.Read(); switch (@string.ToLower()) { case "r": result.r = reader.GetSingle(); break; case "g": result.g = reader.GetSingle(); break; case "b": result.b = reader.GetSingle(); break; case "a": result.a = reader.GetSingle(); break; } } throw new JsonException("Expected EndObject token"); case JsonTokenType.String: { string text = reader.GetString().Trim(); if (ColorUtility.TryParseHtmlString(text, ref result)) { return result; } throw new JsonException("Color format is not right: " + text); } default: throw new JsonException($"ColorJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) JsonSerializer.Serialize<Color>(writer, value, options); } } internal class Il2CppListConverter<T> : JsonConverter<List<T>> { public override bool HandleNull => false; public override List<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { List<T> val = new List<T>(); if (reader.TokenType == JsonTokenType.StartArray) { foreach (T item in JsonSerializer.Deserialize<List<T>>(ref reader, options)) { val.Add(item); } return val; } return null; } public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options) { writer.WriteStartArray(); Enumerator<T> enumerator = value.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; JsonSerializer.Serialize(writer, current, options); } writer.WriteEndArray(); } } internal class Il2CppListConverterFactory : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) { if (!typeToConvert.IsGenericType) { return false; } if (typeToConvert.GetGenericTypeDefinition() != typeof(List<>)) { return false; } return true; } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type type = typeToConvert.GetGenericArguments()[0]; return (JsonConverter)Activator.CreateInstance(typeof(Il2CppListConverter<>).MakeGenericType(type), BindingFlags.Instance | BindingFlags.Public, null, null, null); } } internal class LocalizedTextConverter : JsonConverter<LocalizedText> { public override bool HandleNull => false; public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //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: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //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) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown switch (reader.TokenType) { case JsonTokenType.String: { string @string = reader.GetString(); if (!PersistentIDManager.TryGetId(@string, out var id)) { return new LocalizedText { Id = 0u, UntranslatedText = @string }; } return new LocalizedText { Id = id, UntranslatedText = null }; } case JsonTokenType.Number: return new LocalizedText { Id = reader.GetUInt32(), UntranslatedText = null }; default: throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options) { JsonSerializer.Serialize<LocalizedText>(writer, value, options); } } public class PersistentIDConverter : JsonConverter<uint> { public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { return PersistentIDManager.GetId(reader.GetString()); } if (reader.TokenType == JsonTokenType.Number) { return reader.GetUInt32(); } throw new JsonException("TOKEN IS NOT VALID!"); } public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOptions options) { writer.WriteNumberValue(value); } } internal class Vector2Converter : JsonConverter<Vector2> { public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return JsonSerializer.Deserialize<Vector2>(ref reader); } public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) writer.WriteStartObject(); writer.WriteNumber("x", value.x); writer.WriteNumber("y", value.y); writer.WriteEndObject(); } } } namespace MTFO.Ext.PartialData.Injects { [HarmonyPatch(typeof(GearManager))] internal class Inject_GearManager { private const string COMP_CHARS = "abcdefghijklmnopqrst"; [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("LoadOfflineGearDatas")] private static void Pre_LoadOfflineGearDatas() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks()) { if (!((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).internalEnabled || string.IsNullOrEmpty(allBlock.GearJSON) || ((int)allBlock.Type != 1 && (int)allBlock.Type != 2)) { continue; } string text = allBlock.GearJSON; bool flag = false; using JsonDocument jsonDocument = JsonDocument.Parse(allBlock.GearJSON); if (!jsonDocument.RootElement.TryGetProperty("Packet", out var value) || !value.TryGetProperty("Comps", out var value2)) { continue; } string text2 = "abcdefghijklmnopqrst"; for (int i = 0; i < text2.Length; i++) { if (value2.TryGetProperty(text2[i].ToString(), out var value3) && value3.TryGetProperty("v", out var value4) && value4.ValueKind == JsonValueKind.String) { string @string = value4.GetString(); Logger.Warning("Found String id: " + @string); uint id = PersistentIDManager.GetId(@string); if (id != 0) { text = new Regex("(\"v\")\\s*:\\s*(\"" + @string + "\")").Replace(text, $"\"v\":{id}"); flag = true; } } } if (flag) { Logger.Warning(allBlock.GearJSON); Logger.Warning(text); allBlock.GearJSON = text; } } } } } namespace MTFO.Ext.PartialData.DTO { internal class DataBlockDefinition { public string TypeName { get; set; } = "DataBlock?"; public uint StartFromID { get; set; } = 65535u; public IncrementMode IncrementMode { get; set; } } internal class DatapackConfig { public string PackName { get; set; } = string.Empty; public string Author { get; set; } = string.Empty; public string Namespace { get; set; } = string.Empty; } } namespace MTFO.Ext.PartialData.DataBlockTypes { internal static class DataBlockTypeManager { private static readonly List<IDataBlockType> _DataBlockCache = new List<IDataBlockType>(); private static readonly List<IDBuffer> _DataBlockIdBuffers = new List<IDBuffer>(); public static bool Initialize() { try { Assembly assembly = (from a in AppDomain.CurrentDomain.GetAssemblies() where !a.IsDynamic && a.Location.Contains("interop", StringComparison.InvariantCultureIgnoreCase) select a).First((Assembly a) => a.Location.EndsWith("Modules-ASM.dll", StringComparison.InvariantCultureIgnoreCase)); List<Type> list = new List<Type>(); foreach (Type exportedType in assembly.ExportedTypes) { if (!(exportedType == null) && !string.IsNullOrEmpty(exportedType.Namespace) && exportedType.Namespace.Equals("GameData")) { Type baseType = exportedType.BaseType; if (!(baseType == null) && baseType.Name.Equals("GameDataBlockBase`1")) { list.Add(exportedType); } } } Type typeFromHandle = typeof(DataBlockTypeWrapper<>); foreach (Type item in list) { IDataBlockType dataBlockType = (IDataBlockType)Activator.CreateInstance(typeFromHandle.MakeGenericType(item)); AssignForceChangeMethod(dataBlockType); _DataBlockCache.Add(dataBlockType); _DataBlockIdBuffers.Add(new IDBuffer()); } return true; } catch (Exception value) { Logger.Error($"Can't make cache from Modules-ASM.dll!: {value}"); return false; } } public static void AssignForceChangeMethod(IDataBlockType blockTypeCache) { switch (blockTypeCache.GetShortName().ToLower()) { case "rundown": blockTypeCache.RegisterOnChangeEvent(delegate { CM_PageRundown_New pageRundownNew = MainMenuGuiLayer.Current.PageRundownNew; pageRundownNew.m_dataIsSetup = false; try { clearIcon(pageRundownNew.m_expIconsTier1); clearIcon(pageRundownNew.m_expIconsTier2); clearIcon(pageRundownNew.m_expIconsTier3); clearIcon(pageRundownNew.m_expIconsTier4); clearIcon(pageRundownNew.m_expIconsTier5); clearIcon(pageRundownNew.m_expIconsTierExt); } catch (Exception value) { Logger.Error($"{value}"); } pageRundownNew.m_currentRundownData = GameDataBlockBase<RundownDataBlock>.GetBlock(Global.RundownIdToLoad); if (pageRundownNew.m_currentRundownData != null) { pageRundownNew.PlaceRundown(pageRundownNew.m_currentRundownData); pageRundownNew.m_dataIsSetup = true; } }); break; case "fogsettings": blockTypeCache.RegisterOnChangeEvent(delegate { if (Builder.CurrentFloor.IsBuilt) { pEnvironmentState state = EnvironmentStateManager.Current.m_stateReplicator.State; EnvironmentStateManager.Current.UpdateFogSettingsForState(state); } }); break; case "lightsettings": blockTypeCache.RegisterOnChangeEvent(delegate { if (Builder.CurrentFloor.IsBuilt) { Enumerator<LG_Zone> enumerator2 = Builder.CurrentFloor.allZones.GetEnumerator(); while (enumerator2.MoveNext()) { LG_Zone current2 = enumerator2.Current; Enumerator<AIG_CourseNode> enumerator3 = current2.m_courseNodes.GetEnumerator(); while (enumerator3.MoveNext()) { AIG_CourseNode current3 = enumerator3.Current; LG_BuildZoneLightsJob.ApplyLightSettings(0u, current3.m_lightsInNode, current2.m_lightSettings, false); } } } }); break; } static void clearIcon(List<CM_ExpeditionIcon_New> tier) { if (tier != null) { Enumerator<CM_ExpeditionIcon_New> enumerator = tier.GetEnumerator(); while (enumerator.MoveNext()) { CM_ExpeditionIcon_New current = enumerator.Current; if ((Object)(object)((Component)current).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)current).gameObject); } } } } } public static bool TryFindCache(string blockTypeName, out IDataBlockType cache) { int index = GetIndex(blockTypeName); if (index != -1) { cache = _DataBlockCache[index]; return true; } cache = null; return false; } public static bool TryGetNextID(string blockTypeName, out uint id) { int index = GetIndex(blockTypeName); if (index != -1) { id = _DataBlockIdBuffers[index].GetNext(); return true; } id = 0u; return false; } public static void SetIDBuffer(string blockTypeName, uint id) { int index = GetIndex(blockTypeName); if (index != -1) { _DataBlockIdBuffers[index].CurrentID = id; } } public static void SetIDBuffer(string blockTypeName, uint id, IncrementMode mode) { int index = GetIndex(blockTypeName); if (index != -1) { IDBuffer iDBuffer = _DataBlockIdBuffers[index]; iDBuffer.CurrentID = id; iDBuffer.IncrementMode = mode; } } private static int GetIndex(string blockTypeName) { blockTypeName = GetBlockName(blockTypeName); return _DataBlockCache.FindIndex((IDataBlockType x) => x.GetShortName().Equals(blockTypeName, StringComparison.OrdinalIgnoreCase)); } public static string GetBlockName(string blockTypeName) { blockTypeName = blockTypeName.Trim(); if (blockTypeName.EndsWith("DataBlock")) { string text = blockTypeName; blockTypeName = text.Substring(0, text.Length - 9); } return blockTypeName; } } internal class DataBlockTypeWrapper<T> : IDataBlockType where T : GameDataBlockBase<T> { public Action OnForceChange; public string FullName { get; private set; } public string ShortenName { get; private set; } public DataBlockTypeWrapper() { FullName = typeof(T).Name.Trim(); ShortenName = FullName.Replace("DataBlock", ""); } public void OnChanged() { OnForceChange?.Invoke(); } public void AddBlock(T block) { T block2 = GameDataBlockBase<T>.GetBlock(((GameDataBlockBase<T>)block).persistentID); if (block2 != null) { CopyProperties(block, block2); Logger.Warning($"Replaced Block: {((GameDataBlockBase<T>)block2).persistentID}, {((GameDataBlockBase<T>)block2).name}"); } else { GameDataBlockBase<T>.AddBlock(block, -1); Logger.Log($"Added Block: {((GameDataBlockBase<T>)block).persistentID}, {((GameDataBlockBase<T>)block).name}"); } } public void AddJsonBlock(string json) { try { switch (JsonDocument.Parse(json, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }).RootElement.ValueKind) { case JsonValueKind.Array: { T[] array = (T[])JSON.Deserialize(json, typeof(T).MakeArrayType()); foreach (T block2 in array) { AddBlock(block2); } break; } case JsonValueKind.Object: { T block = (T)JSON.Deserialize(json, typeof(T)); AddBlock(block); break; } } } catch (Exception value) { Logger.Error($"Error While Adding Block: {value}"); } } public void DoSaveToDisk(string fullPath) { string filePathFull = GameDataBlockBase<T>.m_filePathFull; GameDataBlockBase<T>.m_filePathFull = fullPath; GameDataBlockBase<T>.DoSaveToDisk(false, false, true); GameDataBlockBase<T>.m_filePathFull = filePathFull; } private static object CopyProperties(object source, object target) { PropertyInfo[] properties = source.GetType().GetProperties(); foreach (PropertyInfo sourceProp in properties) { Type propertyType = sourceProp.PropertyType; PropertyInfo propertyInfo = target.GetType().GetProperties().FirstOrDefault((PropertyInfo x) => x.Name == sourceProp.Name && x.PropertyType == sourceProp.PropertyType && x.CanWrite); if (propertyInfo != null && !sourceProp.Name.Contains("_k__BackingField")) { if (propertyType == typeof(IntPtr)) { Logger.Error("Pointer has detected on CopyProperties!!!!"); } else { propertyInfo.SetValue(target, sourceProp.GetValue(source)); } } } return target; } public string GetShortName() { return ShortenName; } public string GetFullName() { return FullName; } public void RegisterOnChangeEvent(Action onChanged) { OnForceChange = (Action)Delegate.Combine(OnForceChange, onChanged); } } internal interface IDataBlockType { string GetShortName(); string GetFullName(); void DoSaveToDisk(string fullPath); void AddJsonBlock(string json); void OnChanged(); void RegisterOnChangeEvent(Action onChanged); } }
plugins/net6/PrequelCore.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using ChainedPuzzles; using EOSExt.Reactor.Managers; using Enemies; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using GTFO.API; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; 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 LEGACY.ExtraEvents; using LEGACY.LegacyOverride; using LEGACY.LegacyOverride.ElevatorCargo; using LEGACY.LegacyOverride.EnemyTagger; using LEGACY.LegacyOverride.ExtraExpeditionSettings; using LEGACY.LegacyOverride.FogBeacon; using LEGACY.LegacyOverride.SecDoorIntText; using LEGACY.Utils; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using ScanPosOverride.Managers; using TMPro; 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("PrequelCore")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PrequelCore")] [assembly: AssemblyTitle("PrequelCore")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [HarmonyPatch(typeof(PUI_Watermark), "UpdateWatermark")] internal static class Patch_WatermarkUpdateWatermark { private static void Postfix(PUI_Watermark __instance) { string text = "4.6.1+gitf831086-dirty-main".Remove("x.x.x".Length); ((TMP_Text)__instance.m_watermarkText).SetText("<color=red>MODDED</color> <color=orange>" + text + "</color>\n<color=#FF6781>criscriscris</color>", true); } } namespace LEGACY { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas07.PREQUELCore", "PREQUELCore", "2.0.1")] [BepInIncompatibility("Inas.LEGACY")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas07"; public const string RUNDOWN_NAME = "PREQUELCore"; public const string VERSION = "2.0.1"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("LEGACY"); m_Harmony.PatchAll(); LegacyOverrideManagers.Init(); LegacyExtraEvents.Init(); } } } namespace LEGACY.Reactor { [HarmonyPatch] internal class Patch_ReactorShutdown { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static void Post_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected I4, but got Unknown //IL_007e: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || oldState.status == newState.status) { return; } WardenObjectiveDataBlock val = null; if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null) { LegacyLogger.Error("Patch_ReactorShutdown: "); LegacyLogger.Error("Failed to get warden objective"); } else if ((int)val.Type == 2 && !val.OnActivateOnSolveItem) { eWardenObjectiveEventTrigger val2 = (eWardenObjectiveEventTrigger)0; eReactorStatus status = newState.status; switch (status - 7) { default: return; case 0: val2 = (eWardenObjectiveEventTrigger)1; break; case 1: val2 = (eWardenObjectiveEventTrigger)2; break; case 2: val2 = (eWardenObjectiveEventTrigger)3; break; } _ = __instance.SpawnNode.LayerType; WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val.EventsOnActivate, val2, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Pre_OnBuildDone_ChainedPuzzleMidObjectiveFix(LG_WardenObjective_Reactor __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = null; if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val) || val == null) { LegacyLogger.Error("Patch_ReactorShutdown: Failed to get warden objective"); } else if (val.ChainedPuzzleMidObjective != 0) { __instance.m_chainedPuzzleAlignMidObjective = __instance.m_chainedPuzzleAlign; } } [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")] private static bool Pre_Update(LG_WardenObjective_Reactor __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)__instance.m_currentState.status != 7) { return true; } if (!__instance.m_currentWaveData.HasVerificationTerminal) { return true; } __instance.SetGUIMessage(true, Text.Format(3000u, (Object[])(object)new Object[1] { Object.op_Implicit("<color=orange>" + __instance.m_currentWaveData.VerificationTerminalSerial + "</color>") }), (ePUIMessageStyle)3, false, "", ""); return false; } } [HarmonyPatch] internal class Patch_ReactorStartup_ExtraEventsExecution { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnTerminalStartupSequenceVerify")] private static void Post_ExecuteEventsOnEndOnClientSide(LG_WardenObjective_Reactor __instance) { if (!SNet.IsMaster) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static void Post_ExecuteOnNoneEventsOnDefenseStart(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (oldState.status != newState.status && (int)newState.status == 3) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)0, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Post_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 WardenObjectiveDataBlock db = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref db) || db == null) { LegacyLogger.Error("Patch_ReactorStartup_ExtraEventsExecution: "); LegacyLogger.Error("Failed to get warden objective"); } else if ((int)db.Type == 1 && !db.OnActivateOnSolveItem) { ChainedPuzzleInstance chainedPuzzleToStartSequence = __instance.m_chainedPuzzleToStartSequence; chainedPuzzleToStartSequence.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(db.EventsOnActivate, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); }); } } } } namespace LEGACY.VanillaFix { [HarmonyPatch] internal class Patch_FixHiddenCommandExecution { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] private static void Pre_TerminalInterpreter_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected I4, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 TERM_Command val = cmd; switch (val - 1) { default: if ((int)val != 43) { break; } goto case 0; case 0: case 1: case 2: case 3: case 11: case 13: case 14: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: if (__instance.m_terminal.CommandIsHidden(cmd)) { cmd = (TERM_Command)10; } break; case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 12: case 15: case 16: break; } } } [HarmonyPatch] internal class Patch_FixScoutFreeze { [HarmonyPrefix] [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] private static bool Prefix_Debug(ES_ScoutScream __instance) { if (((AgentAI)((ES_Base)__instance).m_ai).Target == null) { return false; } return true; } } [HarmonyPatch] internal class Patch_LG_SecurityDoor_Fix_EventsOnUnlockDoor_Powergenerator { [HarmonyPrefix] [HarmonyPatch(typeof(LG_SecurityDoor), "OnSyncDoorStatusChange")] private static void Pre_OnSyncDoorStatusChange(LG_SecurityDoor __instance, pDoorState state, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 eDoorStatus status = state.status; if ((status - 4 <= 1 || (int)status == 9) && (int)__instance.m_lastState.status == 6) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.LinkedToZoneData.EventsOnUnlockDoor, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } } [HarmonyPatch] internal class Patch_LockSecurityDoor_FixCustomText { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })] private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor door, LG_SecurityDoor_Locks __instance) { LocalizedText customText = door.LinkedToZoneData.ProgressionPuzzleToEnter.CustomText; __instance.m_lockedWithNoKeyInteractionText = customText; } } [HarmonyPatch] [HarmonyWrapSafe] internal class Patch_RepeatableCommandEventFix { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "SetupCommandEvents")] private static void Post_ResetupChainedPuzzleAfterExecution(LG_ComputerTerminalCommandInterpreter __instance) { //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected I4, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Invalid comparison between Unknown and I4 //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Invalid comparison between Unknown and I4 //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Invalid comparison between Unknown and I4 //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 uint num = 0u; if ((Object)(object)__instance.m_terminal.ConnectedReactor != (Object)null) { return; } if (__instance.m_terminal.SpawnNode.m_dimension.IsMainDimension) { LG_LayerType layerType = __instance.m_terminal.SpawnNode.LayerType; switch ((int)layerType) { case 0: num = RundownManager.ActiveExpedition.LevelLayoutData; break; case 1: num = RundownManager.ActiveExpedition.SecondaryLayout; break; case 2: num = RundownManager.ActiveExpedition.ThirdLayout; break; default: LegacyLogger.Error("Unimplemented layer type."); return; } } else { num = __instance.m_terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData; } LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num); List<CustomTerminalCommand> val = null; int num2 = __instance.m_terminal.SpawnNode.m_zone.TerminalsSpawnedInZone.IndexOf(__instance.m_terminal); ExpeditionZoneData val2 = null; Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.LocalIndex == __instance.m_terminal.SpawnNode.m_zone.LocalIndex) { val2 = current; break; } } if (val2 == null) { LegacyLogger.Error("Cannot find target zone data."); return; } if (num2 >= val2.TerminalPlacements.Count) { LegacyLogger.Debug("RepeatableCommand: TerminalDataIndex >= TargetZoneData.TerminalPlacements.Count: found sec-door terminal, skipping"); return; } val = val2.TerminalPlacements[num2].UniqueCommands; if (val.Count == 0) { return; } Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator(); TERM_Command val3 = default(TERM_Command); string text = default(string); string text2 = default(string); while (enumerator2.MoveNext()) { CustomTerminalCommand current2 = enumerator2.Current; if ((int)current2.SpecialCommandRule != 0 || !__instance.TryGetCommand(current2.Command, ref val3, ref text, ref text2) || ((int)val3 != 38 && (int)val3 != 39 && (int)val3 != 40 && (int)val3 != 41 && (int)val3 != 42)) { continue; } ChainedPuzzleInstance OldCPInstance = null; List<WardenObjectiveEventData> commandEvents = current2.CommandEvents; for (int i = 0; i < commandEvents.Count && (commandEvents[i].ChainPuzzle == 0 || !__instance.m_terminal.TryGetChainPuzzleForCommand(val3, i, ref OldCPInstance) || !((Object)(object)OldCPInstance != (Object)null)); i++) { } if (!((Object)(object)OldCPInstance == (Object)null)) { ChainedPuzzleInstance obj = OldCPInstance; obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate { Helper.ResetChainedPuzzle(OldCPInstance); }); } } } } } namespace LEGACY.Utils { public static class Helper { private static void ResetChild(iChainedPuzzleCore ICore) { CP_Bioscan_Core val = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val != (Object)null) { ((Il2CppObjectBase)val.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f); ((Il2CppObjectBase)val.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f); return; } CP_Cluster_Core val2 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>(); if ((Object)(object)val2 == (Object)null) { LegacyLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core..."); return; } ((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>().SetSplineProgress(0f); foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val2.m_childCores) { ResetChild(item); } } public static void ResetChainedPuzzle(ChainedPuzzleInstance chainedPuzzleInstance) { foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzleInstance.m_chainedPuzzleCores) { ResetChild(item); } if (SNet.IsMaster) { chainedPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)2); } } public static LG_WardenObjective_Reactor FindReactor(LG_LayerType layer) { //IL_001c: 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_0026: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor val = null; Enumerator<LayerChainIndex, iWardenObjectiveItem> enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<LayerChainIndex, iWardenObjectiveItem> current = enumerator.Current; if (current.Key.Layer == layer) { val = ((Il2CppObjectBase)current.Value).TryCast<LG_WardenObjective_Reactor>(); if (!((Object)(object)val == (Object)null)) { break; } } } return val; } public static bool TryGetComponent<T>(this GameObject obj, out T comp) { comp = obj.GetComponent<T>(); return comp != null; } public static bool IsPlayerInLevel(PlayerAgent player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 return (int)player.Owner.Load<pGameState>().gameState == 10; } public static ChainedPuzzleInstance GetChainedPuzzleForCommandOnTerminal(LG_ComputerTerminal terminal, string command) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Invalid comparison between Unknown and I4 //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Invalid comparison between Unknown and I4 //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Invalid comparison between Unknown and I4 //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Invalid comparison between Unknown and I4 uint num = 0u; if (terminal.SpawnNode.m_dimension.IsMainDimension) { LG_LayerType layerType = terminal.SpawnNode.LayerType; switch ((int)layerType) { case 0: num = RundownManager.ActiveExpedition.LevelLayoutData; break; case 1: num = RundownManager.ActiveExpedition.SecondaryLayout; break; case 2: num = RundownManager.ActiveExpedition.ThirdLayout; break; default: LegacyLogger.Error("Unimplemented layer type."); return null; } } else { num = terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData; } LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num); List<CustomTerminalCommand> val = null; List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone; int num2 = terminalsSpawnedInZone.IndexOf(terminal); ExpeditionZoneData val2 = null; Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.LocalIndex == terminal.SpawnNode.m_zone.LocalIndex) { val2 = current; break; } } if (val2 == null) { LegacyLogger.Error("Cannot find target zone data."); return null; } if (val2.TerminalPlacements.Count != terminalsSpawnedInZone.Count) { LegacyLogger.Error("The numbers of terminal placement and spawn, skipped for the zone terminal."); return null; } val = val2.TerminalPlacements[num2].UniqueCommands; if (val.Count == 0) { return null; } List<WardenObjectiveEventData> val3 = null; TERM_Command val4 = (TERM_Command)0; Enumerator<CustomTerminalCommand> enumerator2 = val.GetEnumerator(); string text = default(string); string text2 = default(string); while (enumerator2.MoveNext()) { CustomTerminalCommand current2 = enumerator2.Current; if (current2.Command == command) { val3 = current2.CommandEvents; if (!terminal.m_command.TryGetCommand(current2.Command, ref val4, ref text, ref text2)) { LegacyLogger.Error("Cannot get TERM_COMMAND for command {0} on the specified terminal."); } break; } } if (val3 == null || (int)val4 == 0) { return null; } if ((int)val4 != 38 && (int)val4 != 39 && (int)val4 != 40 && (int)val4 != 41 && (int)val4 != 42) { return null; } ChainedPuzzleInstance val5 = null; for (int i = 0; i < val3.Count && (val3[i].ChainPuzzle == 0 || !terminal.TryGetChainPuzzleForCommand(val4, i, ref val5) || !((Object)(object)val5 != (Object)null)); i++) { } return val5; } public static bool TryGetZoneEntranceSecDoor(LG_Zone zone, out LG_SecurityDoor door) { if ((Object)(object)zone == (Object)null) { door = null; return false; } if ((Object)(object)zone.m_sourceGate == (Object)null) { door = null; return false; } if (zone.m_sourceGate.SpawnedDoor == null) { door = null; return false; } door = ((Il2CppObjectBase)zone.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>(); return (Object)(object)door != (Object)null; } internal static bool isSecDoorToZoneOpened(LG_Zone zone14) { //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_0029: Invalid comparison between Unknown and I4 LG_SecurityDoor door = null; if (!TryGetZoneEntranceSecDoor(zone14, out door) || (Object)(object)door == (Object)null) { return false; } return (int)door.m_sync.GetCurrentSyncState().status == 10; } public static List<T> cast<T>(List<T> list) { List<T> list2 = new List<T>(); Enumerator<T> enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; list2.Add(current); } return list2; } private static eDimensionIndex GetCurrentDimensionIndex() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (PlayerManager.PlayerAgentsInLevel.Count <= 0) { throw new Exception("? You don't have any player agent in level? How could that happen?"); } return ((Agent)PlayerManager.PlayerAgentsInLevel[0]).DimensionIndex; } public static void GetMinLayerAndLocalIndex(out LG_LayerType MinLayer, out eLocalZoneIndex MinLocalIndex) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between I4 and Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between I4 and Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected I4, but got Unknown MinLayer = (LG_LayerType)2; MinLocalIndex = (eLocalZoneIndex)20; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (IsPlayerInLevel(current)) { if ((int)MinLayer > (int)current.m_courseNode.LayerType) { MinLayer = (LG_LayerType)(int)current.m_courseNode.LayerType; MinLocalIndex = (eLocalZoneIndex)20; } if ((int)MinLocalIndex >= (int)current.m_courseNode.m_zone.LocalIndex) { MinLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex; } } } } public static void GetMaxLayerAndLocalIndex(out LG_LayerType MaxLayer, out eLocalZoneIndex MaxLocalIndex) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between I4 and Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between I4 and Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected I4, but got Unknown MaxLayer = (LG_LayerType)0; MaxLocalIndex = (eLocalZoneIndex)0; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (IsPlayerInLevel(current)) { if ((int)MaxLayer < (int)current.m_courseNode.LayerType) { MaxLayer = (LG_LayerType)(int)current.m_courseNode.LayerType; MaxLocalIndex = (eLocalZoneIndex)0; } if ((int)MaxLocalIndex < (int)current.m_courseNode.m_zone.LocalIndex) { MaxLocalIndex = (eLocalZoneIndex)(int)current.m_courseNode.m_zone.LocalIndex; } } } } public static int GetMinAreaIndex(LG_Zone zone) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)zone == (Object)null) { return -1; } LG_LayerType type = zone.m_layer.m_type; eLocalZoneIndex localIndex = zone.LocalIndex; GetCurrentDimensionIndex(); int num = zone.m_areas.Count; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (current.m_courseNode.LayerType != type || current.m_courseNode.m_zone.LocalIndex != localIndex) { continue; } int i = 0; for (List<LG_Area> areas = zone.m_areas; i < areas.Count; i++) { if (((Object)((Component)areas[i]).gameObject).GetInstanceID() == ((Object)((Component)current.m_courseNode.m_area).gameObject).GetInstanceID()) { if (num > i) { num = i; } break; } } } return num; } public static LG_ComputerTerminal FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, int terminalIndex) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = null; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"FindTerminal: Didn't find LG_Zone {dimensionIndex}, {layerType}, {localIndex}"); return null; } if (val.TerminalsSpawnedInZone == null || terminalIndex >= val.TerminalsSpawnedInZone.Count) { LegacyLogger.Error($"FindTerminal: Invalid terminal index {terminalIndex} - {((val.TerminalsSpawnedInZone != null) ? val.TerminalsSpawnedInZone.Count : 0)} terminals are spawned in {dimensionIndex}, {layerType}, {localIndex}"); return null; } if (terminalIndex >= 0) { return val.TerminalsSpawnedInZone[terminalIndex]; } return null; } } internal static class Json { private static readonly JsonSerializerOptions _setting; static Json() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = false, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new JsonStringEnumConverter()); _setting.Converters.Add((JsonConverter)new LocalizedTextConverter()); } public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, _setting); } public static object Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize<T>(T value) { return JsonSerializer.Serialize(value, _setting); } public static void Load<T>(string filePath, out T config) where T : new() { config = Deserialize<T>(File.ReadAllText(filePath)); } } public class Vec3 { public float x { get; set; } public float y { get; set; } public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } public Quaternion ToQuaternion() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(x, y, z); } } internal static class LegacyLogger { private static ManualLogSource logger = Logger.CreateLogSource("LEGACYCore"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } public class SpawnHibernateEnemiesEvent { public eWardenObjectiveEventTrigger Trigger { get; set; } public int Type { get; set; } = 170; public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType Layer { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public string WorldEventObjectFilter { get; set; } = "RANDOM"; public uint EnemyID { get; set; } public int Count { get; set; } = 1; public float Delay { get; set; } public float Duration { get; set; } = 2f; } public class WeightedAreaSelector { private static readonly Dictionary<LG_Zone, WeightedAreaSelector> dict; private WeightedRandomBag<LG_Area> weightedRandomBag; public static WeightedAreaSelector Get(LG_Zone zone) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) //IL_0059: Expected I4, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!dict.ContainsKey(zone)) { WeightedAreaSelector weightedAreaSelector = new WeightedAreaSelector(); Enumerator<LG_Area> enumerator = zone.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { LG_Area current = enumerator.Current; float num = 0f; LG_AreaSize size = current.m_size; switch (size - 1) { case 4: num = 7f; break; case 0: num = 20f; break; case 1: num = 30f; break; case 2: num = 35f; break; case 3: num = 45f; break; default: LegacyLogger.Error($"Unhandled LG_AreaSize: {current.m_size}. Won't build."); return null; } weightedAreaSelector.AddEntry(current, num); } dict.Add(zone, weightedAreaSelector); } return dict[zone]; } public static WeightedAreaSelector Get(eDimensionIndex eDimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(eDimensionIndex, layerType, localIndex, ref val) || !Object.op_Implicit((Object)(object)val)) { return null; } return Get(val); } private WeightedAreaSelector() { weightedRandomBag = new WeightedRandomBag<LG_Area>(); } private void AddEntry(LG_Area area, float weight) { weightedRandomBag.AddEntry(area, weight); } public LG_Area GetRandom() { return weightedRandomBag.GetRandom(); } private static void OnBuildDone() { } private static void Clear() { dict.Clear(); } static WeightedAreaSelector() { dict = new Dictionary<LG_Zone, WeightedAreaSelector>(); LevelAPI.OnLevelCleanup += dict.Clear; } } public class WeightedRandomBag<T> { private struct Entry { public double accumulatedWeight; public T item; } private List<Entry> entries = new List<Entry>(); private double accumulatedWeight; private Random rand = new Random(); public void AddEntry(T item, double weight) { if (weight <= 0.0) { LegacyLogger.Error("AddEntry: no non-positive weight pls."); return; } accumulatedWeight += weight; entries.Add(new Entry { item = item, accumulatedWeight = accumulatedWeight }); } public T GetRandom() { double num = rand.NextDouble() * accumulatedWeight; foreach (Entry entry in entries) { if (entry.accumulatedWeight >= num) { return entry.item; } } return default(T); } } } namespace LEGACY.LegacyOverride { internal static class LegacyOverrideManagers { internal static readonly string LEGACY_CONFIG_PATH = Path.Combine(MTFOPathAPI.CustomPath, "LegacyOverride"); internal static void Init() { ElevatorCargoOverrideManager.Current.Init(); FogBeaconSettingManager.Current.Init(); EnemyTaggerSettingManager.Current.Init(); SecDoorIntTextOverrideManager.Current.Init(); ExpeditionSettingsManager.Current.Init(); } } } namespace LEGACY.LegacyOverride.SecDoorIntText { public class DoorToZone { public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType LayerType { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public LocalizedText Prefix { get; set; } public LocalizedText Postfix { get; set; } public LocalizedText TextToReplace { get; set; } } public class LevelSecDoorIntTextOverride { public uint MainLevelLayout { get; set; } public List<DoorToZone> doorToZones { get; set; } = new List<DoorToZone> { new DoorToZone() }; } internal class SecDoorIntTextOverrideManager { public static readonly SecDoorIntTextOverrideManager Current; private Dictionary<uint, LevelSecDoorIntTextOverride> SecDoorIntTextOverrides = new Dictionary<uint, LevelSecDoorIntTextOverride>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; internal LevelSecDoorIntTextOverride SettingForCurrentLevel { get; private set; } private void AddOverride(LevelSecDoorIntTextOverride _override) { if (_override != null) { if (SecDoorIntTextOverrides.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); SecDoorIntTextOverrides[_override.MainLevelLayout] = _override; } else { SecDoorIntTextOverrides.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new LevelSecDoorIntTextOverride())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<LevelSecDoorIntTextOverride>(item, out var config); AddOverride(config); } LevelAPI.OnBuildStart += UpdateSetting; liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { LevelSecDoorIntTextOverride @override = Json.Deserialize<LevelSecDoorIntTextOverride>(content); AddOverride(@override); if (GameStateManager.IsInExpedition) { UpdateSetting(); } }); } private void UpdateSetting() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; SettingForCurrentLevel = (SecDoorIntTextOverrides.ContainsKey(levelLayoutData) ? SecDoorIntTextOverrides[levelLayoutData] : null); } private SecDoorIntTextOverrideManager() { } static SecDoorIntTextOverrideManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "SecDoorIntText"); Current = new SecDoorIntTextOverrideManager(); } } } namespace LEGACY.LegacyOverride.Patches { [HarmonyPatch] internal class Patch_Customize_SecDoor_Interaction_Text { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")] private static void Post_Customize_SecDoor_Interaction_Text(pDoorState state, LG_SecurityDoor_Locks __instance) { //IL_001c: 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_0024: Invalid comparison between Unknown and I4 //IL_0026: 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_002d: Invalid comparison between Unknown and I4 //IL_0116: 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_0148: Unknown result type (might be due to invalid IL or missing references) LevelSecDoorIntTextOverride settingForCurrentLevel = SecDoorIntTextOverrideManager.Current.SettingForCurrentLevel; if (settingForCurrentLevel == null || ((int)state.status != 9 && (int)state.status != 5)) { return; } int num = settingForCurrentLevel.doorToZones.FindIndex((DoorToZone door) => door.DimensionIndex == __instance.m_door.Gate.DimensionIndex && door.LayerType == __instance.m_door.LinksToLayerType && door.LocalIndex == __instance.m_door.LinkedToZoneData.LocalIndex); if (num != -1) { DoorToZone doorToZone = settingForCurrentLevel.doorToZones[num]; _ = __instance.m_door; Interact_Timed intOpenDoor = __instance.m_intOpenDoor; string text = LocalizedText.op_Implicit(doorToZone.Prefix); string text2 = LocalizedText.op_Implicit(doorToZone.Postfix); string text3 = LocalizedText.op_Implicit(doorToZone.TextToReplace); if (string.IsNullOrEmpty(text)) { text = string.Empty; } if (string.IsNullOrEmpty(text2)) { text2 = string.Empty; } if (string.IsNullOrEmpty(text3)) { text3 = intOpenDoor.InteractionMessage; } intOpenDoor.InteractionMessage = text + "\n" + text3 + "\n" + text2; LegacyLogger.Debug($"SecDoorIntTextOverride: Override IntText. {doorToZone.LocalIndex}, {doorToZone.LayerType}, {doorToZone.DimensionIndex}"); } } } [HarmonyPatch] internal class Patch_ElevatorCargoOverride { [HarmonyPrefix] [HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")] private static bool Pre_ElevatorCargoOverride(ElevatorCargoCage __instance) { LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData); if (levelElevatorCargoItems == null) { return true; } if (levelElevatorCargoItems.ForceDisable) { ElevatorRide.Current.m_cargoCageInUse = false; return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(ElevatorCargoCage), "SpawnObjectiveItemsInLandingArea")] private static void Post_ElevatorCargoOverride(ElevatorCargoCage __instance) { LevelElevatorCargo levelElevatorCargoItems = ElevatorCargoOverrideManager.Current.GetLevelElevatorCargoItems(RundownManager.ActiveExpedition.LevelLayoutData); if (levelElevatorCargoItems == null || levelElevatorCargoItems.ElevatorCargoItems.Count < 1 || levelElevatorCargoItems.ForceDisable) { return; } foreach (ElevatorCargoItem elevatorCargoItem in levelElevatorCargoItems.ElevatorCargoItems) { LG_PickupItem val = LG_PickupItem.SpawnGenericPickupItem(ElevatorShaftLanding.CargoAlign); val.SpawnNode = Builder.GetElevatorArea().m_courseNode; switch (elevatorCargoItem.ItemType) { case ItemType.Consumable: val.SetupAsConsumable(Random.Range(0, int.MaxValue), elevatorCargoItem.ItemID); break; case ItemType.BigPickup: val.SetupAsBigPickupItem(Random.Range(0, int.MaxValue), elevatorCargoItem.ItemID, false, 0); break; default: LegacyLogger.Error($"Undefined Item Type {elevatorCargoItem.ItemType}"); continue; } __instance.m_itemsToMoveToCargo.Add(((Component)val).transform); ElevatorRide.Current.m_cargoCageInUse = true; } } } [HarmonyPatch] internal class Patch_SetupBigPickupItemWithItemId { private static void SetupAsObserver(LG_PickupItem __instance) { EnemyTaggerSetting setting = EnemyTaggerSettingManager.Current.SettingForCurrentLevel; CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>(); Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>(); LG_PickupItem_Sync obj = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>(); EnemyTaggerComponent tagger = ((Component)componentInChildren).gameObject.AddComponent<EnemyTaggerComponent>(); tagger.Parent = componentInChildren; ((Component)tagger).gameObject.SetActive(true); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; tagger.MaxTagPerScan = setting.MaxTagPerScan; tagger.TagInterval = setting.TagInterval; tagger.TagRadius = setting.TagRadius; tagger.WarmupTime = setting.WarmupTime; obj.OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)delegate(ePickupItemStatus status, pPickupPlacement placement, PlayerAgent playerAgent, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 if ((int)status != 0) { if ((int)status == 1) { ((Component)tagger).gameObject.SetActive(true); tagger.PickedByPlayer = playerAgent; tagger.ChangeState((!setting.TagWhenHold) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup); ((Interact_Timed)interact).InteractDuration = setting.TimeToPlace; } } else { tagger.PickedByPlayer = null; tagger.ChangeState((!setting.TagWhenPlaced) ? eEnemyTaggerState.Inactive : eEnemyTaggerState.Active_Warmup); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; } }); } private static void SetupAsFogBeacon(LG_PickupItem __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_01a1: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent<FogRepeller_Sphere>(); val.InfiniteDuration = false; val.LifeDuration = 99999f; val.GrowDuration = 99999f; val.ShrinkDuration = 99999f; val.Range = 1f; FogBeaconSetting setting = FogBeaconSettingManager.Current.SettingForCurrentLevel; FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>(); fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration; fogRepHold.GrowDuration = setting.RSHold.GrowDuration; fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration; fogRepHold.Range = setting.RSHold.Range; fogRepHold.Offset = Vector3.zero; FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent<FogRepeller_Sphere>(); fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration; fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration; fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration; fogRepPlaced.Range = setting.RSPlaced.Range; fogRepPlaced.Offset = Vector3.zero; CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>(); HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>(); iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState); byte byteId = default(byte); if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, __instance.m_root, ref val3, ref byteId)) { pItemData_Custom customData = ((Item)val2).GetCustomData(); customData.byteId = byteId; pItemData_Custom val4 = customData; ((Item)val2).SetCustomData(val4, true); } HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast<HeavyFogRepellerGlobalState>(); ((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false); ((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false); val5.m_repellerSphere = val; fogRepHold.m_sphereAllocator = new FogSphereAllocator(); fogRepPlaced.m_sphereAllocator = new FogSphereAllocator(); Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>(); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status; if ((int)val6 != 1) { if ((int)val6 == 2) { FogRepeller_Sphere obj = fogRepHold; if (obj != null) { obj.StopRepelling(); } FogRepeller_Sphere obj2 = fogRepPlaced; if (obj2 != null) { obj2.StartRepelling(); } ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; } } else { FogRepeller_Sphere obj3 = fogRepHold; if (obj3 != null) { obj3.StartRepelling(); } if (oldState.status != 0) { FogRepeller_Sphere obj4 = fogRepPlaced; if (obj4 != null) { obj4.StopRepelling(); } } ((Interact_Timed)interact).InteractDuration = setting.TimeToPlace; } if (isRecall) { FogRepeller_Sphere obj5 = fogRepHold; if (obj5 != null) { obj5.KillRepellerInstantly(); } FogRepeller_Sphere obj6 = fogRepPlaced; if (obj6 != null) { obj6.KillRepellerInstantly(); } } }); } [HarmonyPostfix] [HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")] private static void Post_SetupBigPickupItemWithItemId(LG_PickupItem __instance, uint itemId) { switch (itemId) { case 233u: SetupAsFogBeacon(__instance); break; case 234u: case 235u: SetupAsObserver(__instance); break; } } } } namespace LEGACY.LegacyOverride.FogBeacon { public class RepellerSphereSetting { public bool InfiniteDuration { get; set; } public float GrowDuration { get; set; } = 10f; public float ShrinkDuration { get; set; } = 10f; public float Range { get; set; } = 11f; } public class FogBeaconSetting { public uint MainLevelLayout { get; set; } public float TimeToPickup { get; set; } = 1f; public float TimeToPlace { get; set; } = 1f; public RepellerSphereSetting RSHold { get; set; } = new RepellerSphereSetting(); public RepellerSphereSetting RSPlaced { get; set; } = new RepellerSphereSetting(); } internal class FogBeaconSettingManager { public static readonly FogBeaconSettingManager Current; private Dictionary<uint, FogBeaconSetting> fogBeaconSettings = new Dictionary<uint, FogBeaconSetting>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; internal FogBeaconSetting SettingForCurrentLevel { get; private set; } private void AddOverride(FogBeaconSetting _override) { if (_override != null) { if (fogBeaconSettings.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); fogBeaconSettings[_override.MainLevelLayout] = _override; } else { fogBeaconSettings.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new FogBeaconSetting())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<FogBeaconSetting>(item, out var config); AddOverride(config); } LevelAPI.OnBuildStart += UpdateSetting; liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { FogBeaconSetting @override = Json.Deserialize<FogBeaconSetting>(content); AddOverride(@override); if (GameStateManager.IsInExpedition) { UpdateSetting(); } }); } private void UpdateSetting() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; SettingForCurrentLevel = (fogBeaconSettings.ContainsKey(levelLayoutData) ? fogBeaconSettings[levelLayoutData] : null); LegacyLogger.Debug($"FogBeaconSettingManager: updated setting for level with main level layout id {levelLayoutData}"); } private FogBeaconSettingManager() { } static FogBeaconSettingManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "FogBeaconSetting"); Current = new FogBeaconSettingManager(); } } } namespace LEGACY.LegacyOverride.ExtraExpeditionSettings { public class ExpeditionSettings { public uint MainLevelLayout { get; set; } } internal class ExpeditionSettingsManager { public static ExpeditionSettingsManager Current; private Dictionary<uint, ExpeditionSettings> expSettings = new Dictionary<uint, ExpeditionSettings>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; private void AddOverride(ExpeditionSettings _override) { if (_override != null) { if (expSettings.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); expSettings[_override.MainLevelLayout] = _override; } else { expSettings.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new ExpeditionSettings())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<ExpeditionSettings>(item, out var config); AddOverride(config); } liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { ExpeditionSettings @override = Json.Deserialize<ExpeditionSettings>(content); AddOverride(@override); }); } private void OnBuildDone() { if (expSettings.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { _ = expSettings[RundownManager.ActiveExpedition.LevelLayoutData]; } } private void OnBuildStart() { } private void OnLevelCleanup() { } private void OnEnterLevel() { } private ExpeditionSettingsManager() { } static ExpeditionSettingsManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ExpeditionSettings"); Current = new ExpeditionSettingsManager(); LevelAPI.OnBuildStart += Current.OnBuildStart; LevelAPI.OnEnterLevel += Current.OnEnterLevel; LevelAPI.OnBuildDone += Current.OnBuildDone; LevelAPI.OnLevelCleanup += Current.OnLevelCleanup; } } } namespace LEGACY.LegacyOverride.EnemyTagger { public enum eEnemyTaggerState { Uninitialized, Inactive, Active_Warmup, Active_Tagging } public class EnemyTaggerComponent : MonoBehaviour { private const float INACTIVE_SOUND_UPDATE_INTERVAL = 1f; internal int MaxTagPerScan = 12; internal float TagInterval = 3f; internal float TagRadius = 12f; internal float WarmupTime = 3f; private eEnemyTaggerState CurrentState; private CellSoundPlayer m_sound = new CellSoundPlayer(); private List<EnemyAgent> TaggableEnemies = new List<EnemyAgent>(); private float UpdateTime; internal CarryItemPickup_Core Parent { get; set; } internal PlayerAgent PickedByPlayer { get; set; } internal Vector3 Position { get { //IL_003e: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Parent == (Object)null)) { if (!((Object)(object)PickedByPlayer == (Object)null)) { return ((Component)PickedByPlayer).transform.position; } return ((Component)Parent).transform.position; } return Vector3.zero; } } public void ChangeState(eEnemyTaggerState newState) { if (CurrentState == newState) { return; } switch (newState) { case eEnemyTaggerState.Uninitialized: LegacyLogger.Error("Enemy Tagger changed to state 'uninitialized'?"); return; case eEnemyTaggerState.Inactive: UpdateTime = 0f; TaggableEnemies.Clear(); m_sound.Post(EVENTS.BULKHEAD_BUTTON_CLOSE, true); break; case eEnemyTaggerState.Active_Warmup: UpdateTime = 0f; m_sound.Post(EVENTS.BUTTONGENERICDEACTIVATE, true); break; case eEnemyTaggerState.Active_Tagging: if (CurrentState != eEnemyTaggerState.Active_Warmup) { UpdateTime = 0f; } break; default: LegacyLogger.Error($"Enemy Tagger: Undefined state {CurrentState}"); return; } CurrentState = newState; } private bool UpdateTaggableEnemies() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) TaggableEnemies.Clear(); bool result = false; Enumerator<EnemyAgent> enumerator = AIG_CourseGraph.GetReachableEnemiesInNodes(((Object)(object)PickedByPlayer == (Object)null) ? ((ItemInLevel)Parent).m_courseNode : ((Agent)PickedByPlayer).CourseNode, 2).GetEnumerator(); while (enumerator.MoveNext()) { EnemyAgent current = enumerator.Current; if (!((Agent)current).Alive) { continue; } Vector3 val = ((Component)current).transform.position - Position; if (!(((Vector3)(ref val)).magnitude > TagRadius)) { result = true; if (!current.IsTagged) { TaggableEnemies.Add(current); } if (TaggableEnemies.Count >= MaxTagPerScan) { break; } } } return result; } private void StartTagging() { if (!(UpdateTime >= TagInterval)) { return; } if (SNet.IsMaster) { UpdateTaggableEnemies(); foreach (EnemyAgent taggableEnemy in TaggableEnemies) { ToolSyncManager.WantToTagEnemy(taggableEnemy); } } m_sound.Post(EVENTS.MARKERGUNACTIVATE, true); UpdateTime = 0f; } private void StopTagging() { if (UpdateTime >= 1f) { m_sound.Post(EVENTS.BUTTONGENERICDEACTIVATE, true); UpdateTime = 0f; } } private void Warmup() { if (UpdateTime >= WarmupTime) { ChangeState(eEnemyTaggerState.Active_Tagging); UpdateTime = TagInterval; } } private void Update() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (CurrentState == eEnemyTaggerState.Uninitialized) { return; } if ((Object)(object)Parent == (Object)null) { LegacyLogger.Error("EnemyTagger: null parent"); return; } UpdateTime += Time.deltaTime; m_sound.UpdatePosition(Position); switch (CurrentState) { case eEnemyTaggerState.Active_Warmup: Warmup(); break; case eEnemyTaggerState.Active_Tagging: StartTagging(); break; case eEnemyTaggerState.Inactive: StopTagging(); break; } } private void OnDestroy() { StopTagging(); TaggableEnemies.Clear(); TaggableEnemies = null; if (m_sound != null) { m_sound.Stop(); m_sound.Recycle(); m_sound = null; } Parent = null; } } public class EnemyTaggerSetting { public uint MainLevelLayout { get; set; } public float TimeToPickup { get; set; } = 1f; public float TimeToPlace { get; set; } = 1f; public float WarmupTime { get; set; } = 5f; public int MaxTagPerScan { get; set; } = 12; public float TagInterval { get; set; } = 3f; public float TagRadius { get; set; } = 12f; public bool TagWhenPlaced { get; set; } = true; public bool TagWhenHold { get; set; } } internal class EnemyTaggerSettingManager { public static readonly EnemyTaggerSettingManager Current; private Dictionary<uint, EnemyTaggerSetting> enemyTaggerSettingSettings = new Dictionary<uint, EnemyTaggerSetting>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; private static readonly EnemyTaggerSetting DEFAULT; internal EnemyTaggerSetting SettingForCurrentLevel { get; private set; } = DEFAULT; private void AddOverride(EnemyTaggerSetting _override) { if (_override != null) { if (enemyTaggerSettingSettings.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); enemyTaggerSettingSettings[_override.MainLevelLayout] = _override; } else { enemyTaggerSettingSettings.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new EnemyTaggerSetting())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<EnemyTaggerSetting>(item, out var config); AddOverride(config); } LevelAPI.OnBuildStart += UpdateSetting; ClassInjector.RegisterTypeInIl2Cpp<EnemyTaggerComponent>(); liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { EnemyTaggerSetting @override = Json.Deserialize<EnemyTaggerSetting>(content); AddOverride(@override); if (GameStateManager.IsInExpedition) { UpdateSetting(); } }); } private void UpdateSetting() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; SettingForCurrentLevel = (enemyTaggerSettingSettings.ContainsKey(levelLayoutData) ? enemyTaggerSettingSettings[levelLayoutData] : DEFAULT); LegacyLogger.Debug($"EnemyTaggerSettingManager: updated setting for level with main level layout id {levelLayoutData}"); } private EnemyTaggerSettingManager() { } static EnemyTaggerSettingManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "EnemyTaggerSetting"); DEFAULT = new EnemyTaggerSetting(); Current = new EnemyTaggerSettingManager(); } } } namespace LEGACY.LegacyOverride.ElevatorCargo { internal class ElevatorCargoOverrideManager { public static readonly ElevatorCargoOverrideManager Current; private Dictionary<uint, LevelElevatorCargo> elevatorCargos = new Dictionary<uint, LevelElevatorCargo>(); private LiveEditListener liveEditListener; private static readonly string CONFIG_PATH; private void AddOverride(LevelElevatorCargo _override) { if (_override != null) { if (elevatorCargos.ContainsKey(_override.MainLevelLayout)) { LegacyLogger.Warning("Replaced MainLevelLayout {0}", _override.MainLevelLayout); elevatorCargos[_override.MainLevelLayout] = _override; } else { elevatorCargos.Add(_override.MainLevelLayout, _override); } } } public void Init() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown if (!Directory.Exists(CONFIG_PATH)) { Directory.CreateDirectory(CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(CONFIG_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new LevelElevatorCargo())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<LevelElevatorCargo>(item, out var config); AddOverride(config); } liveEditListener = LiveEdit.CreateListener(CONFIG_PATH, "*.json", true); liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } private void FileChanged(LiveEditEventArgs e) { LegacyLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { LevelElevatorCargo @override = Json.Deserialize<LevelElevatorCargo>(content); AddOverride(@override); }); } internal LevelElevatorCargo GetLevelElevatorCargoItems(uint MainLevelLayout) { if (!elevatorCargos.ContainsKey(MainLevelLayout)) { return null; } return elevatorCargos[MainLevelLayout]; } private ElevatorCargoOverrideManager() { } static ElevatorCargoOverrideManager() { CONFIG_PATH = Path.Combine(LegacyOverrideManagers.LEGACY_CONFIG_PATH, "ElevatorCargoOverride"); Current = new ElevatorCargoOverrideManager(); } } public enum ItemType { Consumable, BigPickup } public class ElevatorCargoItem { public uint ItemID { get; set; } public ItemType ItemType { get; set; } } public class LevelElevatorCargo { public uint MainLevelLayout { get; set; } public bool ForceDisable { get; set; } public List<ElevatorCargoItem> ElevatorCargoItems { get; set; } = new List<ElevatorCargoItem>(); } } namespace LEGACY.ExtraEvents { internal static class LegacyExtraEvents { private static bool initialized; private static void AlertEnemiesInArea(LG_Area area) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown AIG_CourseNode courseNode = area.m_courseNode; if (courseNode.m_enemiesInNode.Count > 0) { EnemyAgent obj = courseNode.m_enemiesInNode[0]; PlayerAgent val = null; if (PlayerManager.TryGetClosestAlivePlayerAgent(((Agent)obj).CourseNode, ref val) && (Object)(object)val != (Object)null) { Vector3 position = courseNode.m_enemiesInNode[0].Position; NoiseManager.MakeNoise(new NM_NoiseData { noiseMaker = null, position = position, radiusMin = 50f, radiusMax = 120f, yScale = 1f, node = courseNode, type = (NM_NoiseType)0, includeToNeightbourAreas = true, raycastFirstNode = false }); } else { LegacyLogger.Error($"AlertEnemies: failed to alert enemies in area in Zone_{area.m_zone.LocalIndex}, {area.m_zone.m_layer.m_type}, {area.m_zone.DimensionIndex}"); } } } private static void AlertEnemiesInZone(WardenObjectiveEventData e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004e: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"AlertEnemiesInZone: zone not found, {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); return; } LegacyLogger.Debug($"AlertEnemiesInZone: {e.LocalIndex}, {e.Layer}, {e.DimensionIndex}"); Enumerator<LG_Area> enumerator = val.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { AlertEnemiesInArea(enumerator.Current); } } private static void AlertEnemiesInArea(WardenObjectiveEventData e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004e: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"AlertEnemiesInArea: zone not found, {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); } else if (e.Count >= val.m_areas.Count && e.Count < 0) { LegacyLogger.Error($"AlertEnemiesInArea: invalid area index {e.Count} (specified by 'Count')"); } else { AlertEnemiesInArea(val.m_areas[e.Count]); } } private static void ActivateChainedPuzzle(WardenObjectiveEventData e) { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) uint chainPuzzle = e.ChainPuzzle; CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(chainPuzzle); CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(chainPuzzle); iChainedPuzzleOwner val; if ((Object)(object)bioscanCore != (Object)null) { val = PuzzleOverrideManager.Current.ChainedPuzzleInstanceOwner(bioscanCore); } else { if (!((Object)(object)clusterCore != (Object)null)) { LegacyLogger.Error($"ActivateChainedPuzzle: Cannot find puzzle with puzzle override index {chainPuzzle}!"); return; } val = clusterCore.m_owner; } ChainedPuzzleInstance val2 = ((Il2CppObjectBase)val).TryCast<ChainedPuzzleInstance>(); if ((Object)(object)val2 == (Object)null) { LegacyLogger.Error("ActivateChainedPuzzle: Cannot find ChainedPuzzleInstance!"); return; } if (SNet.IsMaster) { val2.AttemptInteract((eChainedPuzzleInteraction)0); } LegacyLogger.Debug($"ActivateChainedPuzzle: puzzle override index: {chainPuzzle}"); LegacyLogger.Debug($"ChainedPuzzleZone: Dim {val2.m_sourceArea.m_zone.DimensionIndex}, {val2.m_sourceArea.m_zone.m_layer.m_type}, Zone {val2.m_sourceArea.m_zone.Alias}"); LegacyLogger.Debug("ChainedPuzzle Alarm name: " + val2.Data.PublicAlarmName); } internal static IEnumerator AddReqItem(WardenObjectiveEventData e, float currentDuration) { uint puzzleOverrideIndex = e.ChainPuzzle; int count = e.Count; CarryItemPickup_Core itemToAdd = PuzzleReqItemManager.Current.GetBigPickupItem(count); if ((Object)(object)itemToAdd == (Object)null) { LegacyLogger.Error($"AddReqItem: Cannot find BigPickup Item with index {count}"); yield break; } CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(puzzleOverrideIndex); CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(puzzleOverrideIndex); if ((Object)(object)bioscanCore != (Object)null) { float num = Mathf.Max(e.Delay - currentDuration, 0f); if (num > 0f) { yield return (object)new WaitForSeconds(num); } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string text = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text); } } if ((double)e.Duration > 0.0 && (double)e.Duration < 1.0) { float duration = e.Duration; CP_PlayerScanner scanner = ((Il2CppObjectBase)bioscanCore.m_playerScanner).TryCast<CP_PlayerScanner>(); if ((Object)(object)scanner != (Object)null) { float CheckInterval = (((double)e.FogTransitionDuration > 0.0) ? e.FogTransitionDuration : 0.5f); LegacyLogger.Debug($"AddReqItem: item would be added on scan progression: {duration}, progression check interval: {CheckInterval} (seconds)"); while (scanner.m_scanProgression < e.Duration) { yield return (object)new WaitForSeconds(CheckInterval); } } else { LegacyLogger.Error("AddReqItem: Failed to get scanner for the CP_Bioscan_Core"); } } bioscanCore.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)itemToAdd).Pointer) })); LegacyLogger.Debug($"AddReqItem: puzzle override index: {puzzleOverrideIndex}"); LegacyLogger.Debug("Item name: " + ((Item)itemToAdd).ItemDataBlock.publicName); } else if ((Object)(object)clusterCore != (Object)null) { float num2 = Mathf.Max(e.Delay - currentDuration, 0f); if (num2 > 0f) { yield return (object)new WaitForSeconds(num2); } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string text2 = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text2)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text2); } } iWardenObjectiveItem[] array = (iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)itemToAdd).Pointer) }; foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)clusterCore.m_childCores) { item.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit(array)); } LegacyLogger.Debug($"AddReqItem: puzzle override index: {puzzleOverrideIndex}"); LegacyLogger.Debug("Item name: " + ((Item)itemToAdd).ItemDataBlock.publicName); } else { LegacyLogger.Error($"AddReqItem: cannot find puzzle core with index {puzzleOverrideIndex}"); } } internal static IEnumerator RemoveReqItem(WardenObjectiveEventData e, float currentDuration) { uint puzzleOverrideIndex = e.ChainPuzzle; int count = e.Count; CarryItemPickup_Core itemToRemove = PuzzleReqItemManager.Current.GetBigPickupItem(count); if ((Object)(object)itemToRemove == (Object)null) { LegacyLogger.Error($"RemoveReqItem: Cannot find BigPickup Item with index {count}"); yield break; } CP_Bioscan_Core bioscanCore = PuzzleOverrideManager.Current.GetBioscanCore(puzzleOverrideIndex); CP_Cluster_Core clusterCore = PuzzleOverrideManager.Current.GetClusterCore(puzzleOverrideIndex); if ((Object)(object)bioscanCore != (Object)null) { float num = Mathf.Max(e.Delay - currentDuration, 0f); if (num > 0f) { yield return (object)new WaitForSeconds(num); } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string text = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text); } } if ((double)e.Duration > 0.0 && (double)e.Duration < 1.0) { float duration = e.Duration; CP_PlayerScanner scanner = ((Il2CppObjectBase)bioscanCore.m_playerScanner).TryCast<CP_PlayerScanner>(); if ((Object)(object)scanner != (Object)null) { float CheckInterval = (((double)e.FogTransitionDuration > 0.0) ? e.FogTransitionDuration : 0.5f); LegacyLogger.Debug($"RemoveReqItem: item would be added on scan progression: {duration}, progression check interval: {CheckInterval} (seconds)"); while (scanner.m_scanProgression < e.Duration) { yield return (object)new WaitForSeconds(CheckInterval); } } else { LegacyLogger.Error("RemoveReqItem: Failed to get scanner for the CP_Bioscan_Core"); } } bioscanCore.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)itemToRemove).Pointer) }); LegacyLogger.Debug($"RemoveReqItem: puzzle override index: {puzzleOverrideIndex}"); LegacyLogger.Debug("Removed Item name: " + ((Item)itemToRemove).ItemDataBlock.publicName); } else if ((Object)(object)clusterCore != (Object)null) { float num2 = Mathf.Max(e.Delay - currentDuration, 0f); if (num2 > 0f) { yield return (object)new WaitForSeconds(num2); } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string text2 = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text2)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text2); } } iWardenObjectiveItem[] array = (iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)itemToRemove).Pointer) }; foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)clusterCore.m_childCores) { item.RemoveRequiredItems(array); } LegacyLogger.Debug($"RemoveReqItem: puzzle override index: {puzzleOverrideIndex}"); LegacyLogger.Debug("Removed Item name: " + ((Item)itemToRemove).ItemDataBlock.publicName); } else { LegacyLogger.Error($"RemoveReqItem: cannot find puzzle core with index {puzzleOverrideIndex}"); } } internal static void Init() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { LegacyLogger.Log("Adding Legacy warden event definitions..."); EOSWardenEventManager.Current.AddEventDefinition(EventType.CloseSecurityDoor_Custom.ToString(), 100u, (Action<WardenObjectiveEventData>)CloseSecurityDoor); EOSWardenEventManager.Current.AddEventDefinition(EventType.SetTimerTitle.ToString(), 102u, (Action<WardenObjectiveEventData>)SetTimerTitle); EOSWardenEventManager current = EOSWardenEventManager.Current; eWardenObjectiveEventType val = (eWardenObjectiveEventType)21; current.AddEventDefinition(((object)(eWardenObjectiveEventType)(ref val)).ToString(), 21u, (Action<WardenObjectiveEventData>)SetTerminalCommand_Custom); EOSWardenEventManager.Current.AddEventDefinition(EventType.AlertEnemiesInArea.ToString(), 108u, (Action<WardenObjectiveEventData>)AlertEnemiesInArea); EOSWardenEventManager.Current.AddEventDefinition(EventType.AlertEnemiesInZone.ToString(), 107u, (Action<WardenObjectiveEventData>)AlertEnemiesInZone); EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInArea.ToString(), 140u, (Action<WardenObjectiveEventData>)KillEnemiesInArea); EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInZone.ToString(), 141u, (Action<WardenObjectiveEventData>)KillEnemiesInZone); EOSWardenEventManager.Current.AddEventDefinition(EventType.KillEnemiesInDimension.ToString(), 142u, (Action<WardenObjectiveEventData>)KillEnemiesInDimension); EOSWardenEventManager.Current.AddEventDefinition(EventType.SpawnHibernate.ToString(), 170u, (Action<WardenObjectiveEventData>)SpawnHibernate); EOSWardenEventManager.Current.AddEventDefinition(EventType.Info_ZoneHibernate.ToString(), 250u, (Action<WardenObjectiveEventData>)Info_ZoneHibernate); EOSWardenEventManager.Current.AddEventDefinition(EventType.Info_LevelHibernate.ToString(), 251u, (Action<WardenObjectiveEventData>)Info_LevelEnemies); EOSWardenEventManager.Current.AddEventDefinition(EventType.Output_LevelHibernateSpawnEvent.ToString(), 252u, (Action<WardenObjectiveEventData>)Output_LevelHibernateSpawnEvent); EOSWardenEventManager.Current.AddEventDefinition(EventType.PlayGCEndSequence.ToString(), 180u, (Action<WardenObjectiveEventData>)PlayGCEndSequence); EOSWardenEventManager current2 = EOSWardenEventManager.Current; val = (eWardenObjectiveEventType)22; current2.AddEventDefinition(((object)(eWardenObjectiveEventType)(ref val)).ToString(), 22u, (Action<WardenObjectiveEventData>)ActivateChainedPuzzle); EOSWardenEventManager.Current.AddEventDefinition(EventType.Terminal_ShowTerminalInfoInZone.ToString(), 130u, (Action<WardenObjectiveEventData>)ShowTerminalInfoInZone); LegacyLogger.Log("Legacy warden event definitions setup completed"); initialized = true; } } private static IEnumerator Play(WardenObjectiveEventData e) { List<LG_PowerGenerator_Core> gcInZone = ((InstanceManager<LG_PowerGenerator_Core>)(object)PowerGeneratorInstanceManager.Current).GetInstancesInZone(e.DimensionIndex, e.Layer, e.LocalIndex); yield return (object)new WaitForSeconds(4f); CellSound.Post(EVENTS.DISTANT_EXPLOSION_SEQUENCE); yield return (object)new WaitForSeconds(2f); EnvironmentStateManager.AttemptSetExpeditionLightMode(false); CellSound.Post(EVENTS.LIGHTS_OFF_GLOBAL); yield return (object)new WaitForSeconds(3f); int g = 0; while (g < gcInZone.Count) { gcInZone[g].TriggerPowerFailureSequence(); yield return (object)new WaitForSeconds(Random.Range(0.3f, 1f)); int num = g + 1; g = num; } yield return (object)new WaitForSeconds(4f); EnvironmentStateManager.AttemptSetExpeditionLightMode(true); } private static void PlayGCEndSequence(WardenObjectiveEventData e) { Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Play(e)), (Action)null); WorldEventManager.m_worldEventEventCoroutines.Add(val); } private static void KillEnemiesInArea(LG_Area area) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) foreach (EnemyAgent item in area.m_courseNode.m_enemiesInNode.ToArray()) { if ((Object)(object)item != (Object)null && (Object)(object)item.Damage != (Object)null) { item.Damage.MeleeDamage(float.MaxValue, (Agent)null, Vector3.zero, Vector3.up, 0, 1f, 1f, 1f, 1f, false, (DamageNoiseLevel)0, 0u); } } } private static void KillEnemiesInArea(WardenObjectiveEventData e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004e: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"KillEnemiesInArea - Failed to find {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); } else if (e.Count < 0 || e.Count >= val.m_areas.Count) { LegacyLogger.Error($"KillEnemiesInArea - invalid area index {e.Count} (specified by 'Count')"); } else { KillEnemiesInArea(val.m_areas[e.Count]); } } private static void KillEnemiesInZone(WardenObjectiveEventData e) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error($"KillEnemiesInArea - Failed to find {(e.DimensionIndex, e.Layer, e.LocalIndex)}"); } else { Enumerator<LG_Area> enumerator = val.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { KillEnemiesInArea(enumerator.Current); } } } private static void KillEnemiesInDimension(WardenObjectiveEventData e) { //IL_0009: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 if (!SNet.IsMaster) { return; } Dimension val = default(Dimension); if (!Dimension.GetDimension(e.DimensionIndex, ref val)) { LegacyLogger.Error($"KillEnemiesInDimension: invalid dimension index {e.DimensionIndex}"); return; } for (int i = 0; i < val.Layers.Count; i++) { LG_Layer val2 = val.Layers[i]; for (int j = 0; j < val2.m_zones.Count; j++) { LG_Zone val3 = val2.m_zones[j]; Helper.TryGetZoneEntranceSecDoor(val3, out var door); if (j == 0 || ((Object)(object)door != (Object)null && (int)door.m_sync.GetCurrentSyncState().status == 10)) { Enumerator<LG_Area> enumerator = val3.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { KillEnemiesInArea(enumerator.Current); } } } } } private static void CloseSecurityDoor(WardenObjectiveEventData e) { //IL_0008: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 //IL_00c8: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = null; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(e.DimensionIndex, e.Layer, e.LocalIndex, ref val) || (Object)(object)val == (Object)null) { LegacyLogger.Error("CloseSecurityDoor_Custom: Failed to get zone {0}, layer {1}, dimensionIndex {2}", e.LocalIndex, e.Layer, e.DimensionIndex); return; } LG_SecurityDoor door = null; if (!Helper.TryGetZoneEntranceSecDoor(val, out door) || (Object)(object)door == (Object)null) { LegacyLogger.Error("CloseSecurityDoor_Custom: failed to get LG_SecurityDoor!"); return; } pDoorState currentSyncState = door.m_sync.GetCurrentSyncState(); if ((int)currentSyncState.status != 10 && (int)currentSyncState.status != 16) { return; } LegacyLogger.Debug("Door Closed!"); LG_Door_Sync val2 = ((Il2CppObjectBase)door.m_sync).TryCast<LG_Door_Sync>(); if (!((Object)(object)val2 == (Object)null)) { pDoorState currentSyncState2 = val2.GetCurrentSyncState(); currentSyncState2.status = (eDoorStatus)1; currentSyncState2.hasBeenOpenedDuringGame = false; pDoorState state = currentSyncState2; val2.m_stateReplicator.State = state; LG_Gate gate = door.Gate; gate.HasBeenOpenedDuringPlay = false; gate.IsTraversable = false; if (door.ActiveEnemyWaveData != null && door.ActiveEnemyWaveData.HasActiveEnemyWave) { door.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_START, true); } } } private static void SetTerminalCommand_Custom(WardenObjectiveEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0023: Invalid comparison between Unknown and I4 //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) LG_LayerType layer = e.Layer; eLocalZoneIndex localIndex = e.LocalIndex; eDimensionIndex dimensionIndex = e.DimensionIndex; TERM_Command terminalCommand = e.TerminalCommand; LG_ComputerTerminal val2; if (terminalCommand - 21 <= 2) { LG_WardenObjective_Reactor val = ReactorInstanceManager.FindVanillaReactor(layer, e.Count); if ((Object)(object)val == (Object)null) { val2 = Helper.FindTerminal(dimensionIndex, layer, localIndex, e.Count); if ((Object)(object)val2 == (Object)null) { LegacyLogger.Error($"SetTerminalCommand_Custom: Cannot find reactor for {layer} or instance index ({(dimensionIndex, layer, localIndex, e.Count)})"); return; } } else { val2 = val.m_terminal; } } else { val2 = Helper.FindTerminal(e.DimensionIndex, e.Layer, e.LocalIndex, e.Count); } if ((Object)(object)val2 == (Object)null) { LegacyLogger.Error("SetTerminalCommand_Custom: temrinal not found"); return; } if (e.Enabled) { val2.TrySyncSetCommandShow(e.TerminalCommand); } else { val2.TrySyncS
plugins/net6/ScanPosOverride.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; using AIGraph; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using GTFO.API; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Text; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using ScanPosOverride.JSON; using ScanPosOverride.Managers; using ScanPosOverride.PuzzleOverrideData; 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("ScanPosOverride")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ScanPosOverride")] [assembly: AssemblyTitle("ScanPosOverride")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ScanPosOverride { internal static class SPOLogger { private static readonly ManualLogSource logger = Logger.CreateLogSource("ScanPosOverride"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } public static void Log(BepInExDebugLogInterpolatedStringHandler logHandler) { logger.LogDebug(logHandler); } } [BepInPlugin("ScanPositionOverride", "ScanPositionOverride", "1.5.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class Plugin : BasePlugin { [CompilerGenerated] private static class <>O { public static LiveEditEventHandler <0>__LiveEdit_FileChanged; } private static Dictionary<uint, Dictionary<uint, PuzzleOverride>> PuzzleOverrides = new Dictionary<uint, Dictionary<uint, PuzzleOverride>>(); public static readonly string OVERRIDE_SCAN_POS_PATH = Path.Combine(MTFOPathAPI.CustomPath, "ScanPositionOverrides"); private static LiveEditListener listener = null; private static Harmony m_Harmony = null; public override void Load() { //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown SPOLogger.Error(OVERRIDE_SCAN_POS_PATH); if (!Directory.Exists(OVERRIDE_SCAN_POS_PATH)) { Directory.CreateDirectory(OVERRIDE_SCAN_POS_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(OVERRIDE_SCAN_POS_PATH, "Template.json")); streamWriter.WriteLine(Json.Serialize(new PuzzleOverrideJsonFile())); streamWriter.Flush(); streamWriter.Close(); return; } foreach (string item in Directory.EnumerateFiles(OVERRIDE_SCAN_POS_PATH, "*.json", SearchOption.AllDirectories)) { Json.Load<PuzzleOverrideJsonFile>(item, out var config); if (PuzzleOverrides.ContainsKey(config.MainLevelLayout)) { SPOLogger.Warning("Duplicate MainLevelLayout {0}, won't load.", config.MainLevelLayout); continue; } Dictionary<uint, PuzzleOverride> dictionary = new Dictionary<uint, PuzzleOverride>(); foreach (PuzzleOverride puzzle in config.Puzzles) { if (dictionary.ContainsKey(puzzle.Index)) { SPOLogger.Error("Duplicate Puzzle Override found. MainLevelLayout {0}, Index {1}.", config.MainLevelLayout, puzzle.Index); } else { dictionary.Add(puzzle.Index, puzzle); } } PuzzleOverrides.Add(config.MainLevelLayout, dictionary); } listener = LiveEdit.CreateListener(OVERRIDE_SCAN_POS_PATH, "*.json", true); LiveEditListener obj = listener; object obj2 = <>O.<0>__LiveEdit_FileChanged; if (obj2 == null) { LiveEditEventHandler val = LiveEdit_FileChanged; <>O.<0>__LiveEdit_FileChanged = val; obj2 = (object)val; } obj.FileChanged += (LiveEditEventHandler)obj2; m_Harmony = new Harmony("ScanPosOverride.Patches"); m_Harmony.PatchAll(); } private static void LiveEdit_FileChanged(LiveEditEventArgs e) { SPOLogger.Warning("LiveEdit File Changed: " + e.FullPath + "."); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { PuzzleOverrideJsonFile puzzleOverrideJsonFile = Json.Deserialize<PuzzleOverrideJsonFile>(content); if (!PuzzleOverrides.ContainsKey(puzzleOverrideJsonFile.MainLevelLayout)) { SPOLogger.Warning("MainLevelLayout not found, which is now not supported. Will not replace."); } else { Dictionary<uint, PuzzleOverride> dictionary = PuzzleOverrides[puzzleOverrideJsonFile.MainLevelLayout]; dictionary.Clear(); foreach (PuzzleOverride puzzle in puzzleOverrideJsonFile.Puzzles) { if (dictionary.ContainsKey(puzzle.Index)) { SPOLogger.Error("Duplicate Puzzle Override found. MainLevelLayout {0}, Index {1}.", puzzleOverrideJsonFile.MainLevelLayout, puzzle.Index); } else { dictionary.Add(puzzle.Index, puzzle); } } SPOLogger.Warning("Replaced Override Puzzle with MainLevelLayout {0}", puzzleOverrideJsonFile.MainLevelLayout); } }); } internal static PuzzleOverride GetOverride(uint mainLevelLayout, uint puzzleIndex) { if (!PuzzleOverrides.ContainsKey(mainLevelLayout)) { return null; } Dictionary<uint, PuzzleOverride> dictionary = PuzzleOverrides[mainLevelLayout]; if (!dictionary.ContainsKey(puzzleIndex)) { return null; } return dictionary[puzzleIndex]; } } } namespace ScanPosOverride.PuzzleOverrideData { internal sealed class PuzzleOverrideJsonFile { public uint MainLevelLayout { get; set; } public List<PuzzleOverride> Puzzles { get; set; } = new List<PuzzleOverride>(); } internal sealed class PuzzleOverride { public uint Index { get; set; } public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); public bool HideSpline { get; set; } public bool ConcurrentCluster { get; set; } public float TMoveSpeedMulti { get; set; } = -1f; public List<Vec3> TPositions { get; set; } = new List<Vec3>(); public List<int> RequiredItemsIndices { get; set; } = new List<int> { 0 }; public List<WardenObjectiveEventData> EventsOnPuzzleSolved { get; set; } = new List<WardenObjectiveEventData>(); } public class Vec3 { public float x { get; set; } public float y { get; set; } public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } public Quaternion ToQuaternion() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(x, y, z); } } } namespace ScanPosOverride.Patches { [HarmonyPatch] internal class Patch_CP_Bioscan_Core_OnSyncStateChange { [HarmonyPostfix] [HarmonyPatch(typeof(CP_Bioscan_Core), "OnSyncStateChange")] private static void Post_CP_Bioscan_Core_OnSyncStateChanged(CP_Bioscan_Core __instance, float progress, eBioscanStatus status, List<PlayerAgent> playersInScan) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Invalid comparison between Unknown and I4 //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Invalid comparison between Unknown and I4 //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Invalid comparison between Unknown and I4 //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) bool flag = PlayerScannerManager.Current.IsConcurrentCluster(__instance); if (flag && __instance.m_reqItemsEnabled) { SPOLogger.Warning($"OnSyncStateChange: status - {status}, playersInScan - {playersInScan.Count}, progress: {progress}"); } if ((int)status != 3) { if (flag) { if ((int)status == 4) { CP_Cluster_Core parentClusterCore = PlayerScannerManager.Current.GetParentClusterCore(__instance); if ((Object)(object)parentClusterCore == (Object)null) { SPOLogger.Error("Cannot find parent cluster core! The concurrent cluster may fail!"); } else { PlayerScannerManager.Current.CompleteConcurrentCluster(parentClusterCore); } } else { PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: false); } } if (__instance.m_reqItemsEnabled) { __instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4)); } } else { if (!__instance.IsMovable && !flag && !__instance.m_reqItemsEnabled) { return; } CP_PlayerScanner cacheScanner = PlayerScannerManager.Current.GetCacheScanner(__instance); if ((Object)(object)cacheScanner == (Object)null) { SPOLogger.Error("Null CP_PlayerScanner"); return; } int count = playersInScan.Count; List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel; float num = 0f; float[] cacheOriginalScanSpeed = PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance); if ((int)__instance.m_playerScanner.ScanPlayersRequired == 0) { num = ((count <= 0) ? 0f : cacheOriginalScanSpeed[count - 1]); } else if (((int)cacheScanner.m_playerRequirement == 1 && count == playerAgentsInLevel.Count) || ((int)cacheScanner.m_playerRequirement == 2 && count == 1)) { num = cacheOriginalScanSpeed[0]; } bool flag2 = num > 0f; if (flag2 && cacheScanner.m_reqItemsEnabled) { for (int i = 0; i < ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems).Length; i++) { Vector3 val = Vector3.zero; if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 0) { val = ((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].transform.position; } else if ((int)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickupItemStatus == 1) { if ((Object)(object)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer != (Object)null) { val = ((Agent)((Il2CppArrayBase<iWardenObjectiveItem>)(object)cacheScanner.m_reqItems)[i].PickedUpByPlayer).Position; } else { Debug.LogError(Object.op_Implicit("Playerscanner is looking for an item that has ePickupItemStatus.PickedUp but null player, how come!?")); } } Vector3 val2 = ((Component)cacheScanner).transform.position - val; if (((Vector3)(ref val2)).sqrMagnitude >= cacheScanner.m_scanRadiusSqr) { flag2 = false; break; } } } if (flag) { if (flag2) { flag2 = PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: true); } else { PlayerScannerManager.Current.ConcurrentClusterShouldProgress(__instance, IsThisScanShouldProgress: false); } } if (flag2) { if (flag) { CP_Cluster_Core parentClusterCore2 = PlayerScannerManager.Current.GetParentClusterCore(__instance); if ((Object)(object)parentClusterCore2 == (Object)null) { SPOLogger.Error("null clusterParent"); } PlayerScannerManager.Current.RestoreConcurrentClusterScanSpeed(parentClusterCore2); } if (__instance.IsMovable) { __instance.m_movingComp.ResumeMovement(); } if (cacheScanner.m_reqItemsEnabled) { if ((int)cacheScanner.m_playerRequirement == 0) { ((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = ((count > 0) ? cacheOriginalScanSpeed[count - 1] : 0f); } __instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)(__instance.m_hasAlarm ? 5 : 2)); } return; } if (flag) { CP_Cluster_Core parentClusterCore3 = PlayerScannerManager.Current.GetParentClusterCore(__instance); if ((Object)(object)parentClusterCore3 == (Object)null) { SPOLogger.Error("null clusterParent"); } PlayerScannerManager.Current.ZeroConcurrentClusterScanSpeed(parentClusterCore3); } if (__instance.IsMovable) { __instance.m_movingComp.PauseMovement(); } if (cacheScanner.m_reqItemsEnabled) { if ((int)cacheScanner.m_playerRequirement == 0) { PlayerScannerManager.Current.GetCacheOriginalScanSpeed(__instance); ((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[0] = 0f; } __instance.m_graphics.SetColorMode((eChainedPuzzleGraphicsColorMode)((!__instance.m_hasAlarm) ? 1 : 4)); } } } static Patch_CP_Bioscan_Core_OnSyncStateChange() { } } [HarmonyPatch] internal class Patch_CP_Bioscan_Core_Setup { [HarmonyPrefix] [HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")] private static void Pre_CP_Bioscan_Core_Setup(CP_Bioscan_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath, ref bool onlyShowHUDWhenPlayerIsClose) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) ChainedPuzzleInstance val = ((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>(); if ((Object)(object)val != (Object)null) { if (puzzleIndex != 0) { CP_Bioscan_Core val2 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val2 != (Object)null) { prevPuzzlePos = ((Component)val2).transform.position; } else { CP_Cluster_Core val3 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>(); if ((Object)(object)val3 == (Object)null) { SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???"); } else { prevPuzzlePos = ((Component)val3).transform.position; } } } } else { CP_Cluster_Core val4 = ((Il2CppObjectBase)owner).TryCast<CP_Cluster_Core>(); if ((Object)(object)val4 == (Object)null) { SPOLogger.Error("Onwer is not neither ChainedPuzzleInstance nor CP_Cluster_Core. What r u?"); return; } prevPuzzlePos = ((Component)val4).transform.position; val = ((Il2CppObjectBase)val4.m_owner).TryCast<ChainedPuzzleInstance>(); if ((Object)(object)val == (Object)null) { SPOLogger.Error("Failed to cast clusterOwner.m_owner to ChainedPuzzleInstance"); return; } if (val.Data.OnlyShowHUDWhenPlayerIsClose) { onlyShowHUDWhenPlayerIsClose = true; } } uint puzzleIndex2 = PuzzleOverrideManager.Current.Register(__instance); PuzzleOverride puzzleOverride = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, puzzleIndex2); if (puzzleOverride == null) { return; } if ((double)puzzleOverride.Position.x != 0.0 || (double)puzzleOverride.Position.y != 0.0 || (double)puzzleOverride.Position.z != 0.0 || (double)puzzleOverride.Rotation.x != 0.0 || (double)puzzleOverride.Rotation.y != 0.0 || (double)puzzleOverride.Rotation.z != 0.0) { ((Component)__instance).transform.SetPositionAndRotation(puzzleOverride.Position.ToVector3(), puzzleOverride.Rotation.ToQuaternion()); } if (puzzleOverride.EventsOnPuzzleSolved != null && puzzleOverride.EventsOnPuzzleSolved.Count > 0) { __instance.OnPuzzleDone += Action<int>.op_Implicit((Action<int>)delegate { foreach (WardenObjectiveEventData item in puzzleOverride.EventsOnPuzzleSolved) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f); } }); } if (puzzleOverride.HideSpline || ((Object)(object)__instance.m_movingComp != (Object)null && __instance.m_movingComp.IsMoveConfigured)) { revealWithHoloPath = false; } if (puzzleOverride.RequiredItemsIndices != null && puzzleOverride.RequiredItemsIndices.Count > 0) { PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, puzzleOverride.RequiredItemsIndices); } SPOLogger.Warning("Overriding CP_Bioscan_Core." + (((Object)(object)val == (Object)null) ? "" : $"Zone {val.m_sourceArea.m_zone.Alias}, Layer {val.m_sourceArea.m_zone.Layer.m_type}, Dim {val.m_sourceArea.m_zone.DimensionIndex}")); } } [HarmonyPatch] internal class Patch_ChainedPuzzleInstance_SetupMovement { [HarmonyPrefix] [HarmonyPatch(typeof(ChainedPuzzleInstance), "SetupMovement")] private static bool Pre_SetupMovement(ChainedPuzzleInstance __instance, GameObject gameObject) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) iChainedPuzzleMovable movingComp = gameObject.GetComponent<iChainedPuzzleMovable>(); if (movingComp == null || !movingComp.UsingStaticBioscanPoints) { return true; } CP_BasicMovable val = ((Il2CppObjectBase)movingComp).Cast<CP_BasicMovable>(); CP_Bioscan_Core val2 = ((Il2CppObjectBase)gameObject.GetComponent<iChainedPuzzleCore>()).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val2 == (Object)null) { SPOLogger.Error("Pre_SetupMovement: iChainedPuzzleCore -> CP_Bioscan_Core failed"); return true; } uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(((Il2CppObjectBase)val2).Pointer); if (bioscanCoreOverrideIndex == 0) { SPOLogger.Error("Did not find registered movable override for this movable scan."); return true; } PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex); if (@override == null || @override.TPositions.Count < 1) { SPOLogger.Error("No Override for this T-Scan, falling back to vanilla impl."); return true; } @override.TPositions.ForEach(delegate(Vec3 pos) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) movingComp.ScanPositions.Add(pos.ToVector3()); }); gameObject.transform.position = @override.TPositions[0].ToVector3(); SPOLogger.Warning("Overriding T-Scan pos!"); val.m_amountOfPositions = @override.TPositions.Count; if (@override.TMoveSpeedMulti > 0f) { val.m_movementSpeed *= @override.TMoveSpeedMulti; } return false; } } [HarmonyPatch] internal class Patch_CarryItemPickup_Core_Setup { [HarmonyPostfix] [HarmonyPatch(typeof(CarryItemPickup_Core), "Setup")] private static void Post_CarryItemPickup_Core_Setup(CarryItemPickup_Core __instance) { PuzzleReqItemManager.Current.Register(__instance); } } [HarmonyPatch] internal class Patch_CP_Cluster_Core_Setup { [HarmonyPrefix] [HarmonyPatch(typeof(CP_Cluster_Core), "Setup")] private static void Pre_CP_Cluster_Core_Setup(CP_Cluster_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, ref Vector3 prevPuzzlePos, ref bool revealWithHoloPath) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) ChainedPuzzleInstance val = new ChainedPuzzleInstance(((Il2CppObjectBase)owner).Pointer); if (puzzleIndex != 0) { CP_Bioscan_Core val2 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val2 != (Object)null) { prevPuzzlePos = ((Component)val2).transform.position; } else { CP_Cluster_Core val3 = ((Il2CppObjectBase)((Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_chainedPuzzleCores)[puzzleIndex - 1]).TryCast<CP_Cluster_Core>(); if ((Object)(object)val3 == (Object)null) { SPOLogger.Error($"Cannot cast m_chainedPuzzleCores[{puzzleIndex - 1}] to neither CP_Bioscan_Core or CP_Cluster_Core! WTF???"); } else { prevPuzzlePos = ((Component)val3).transform.position; } } } uint puzzleIndex2 = PuzzleOverrideManager.Current.Register(__instance); PuzzleOverride puzzleOverride = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, puzzleIndex2); if (puzzleOverride == null) { return; } if ((double)puzzleOverride.Position.x != 0.0 || (double)puzzleOverride.Position.y != 0.0 || (double)puzzleOverride.Position.z != 0.0 || (double)puzzleOverride.Rotation.x != 0.0 || (double)puzzleOverride.Rotation.y != 0.0 || (double)puzzleOverride.Rotation.z != 0.0) { ((Component)__instance).transform.SetPositionAndRotation(puzzleOverride.Position.ToVector3(), puzzleOverride.Rotation.ToQuaternion()); } if (puzzleOverride.EventsOnPuzzleSolved != null && puzzleOverride.EventsOnPuzzleSolved.Count > 0) { __instance.OnPuzzleDone += Action<int>.op_Implicit((Action<int>)delegate { foreach (WardenObjectiveEventData item in puzzleOverride.EventsOnPuzzleSolved) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f); } }); } if (puzzleOverride.RequiredItemsIndices != null && puzzleOverride.RequiredItemsIndices.Count > 0) { PuzzleReqItemManager.Current.QueueForAddingReqItems(__instance, puzzleOverride.RequiredItemsIndices); } if (puzzleOverride.HideSpline) { revealWithHoloPath = false; } SPOLogger.Warning("Overriding CP_Cluster_Core!"); } [HarmonyPostfix] [HarmonyPatch(typeof(CP_Cluster_Core), "Setup")] private static void Post_CP_Cluster_Core_Setup(CP_Cluster_Core __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores) { if (!item.IsMovable) { continue; } uint bioscanCoreOverrideIndex = PuzzleOverrideManager.Current.GetBioscanCoreOverrideIndex(((Il2CppObjectBase)item).Pointer); if (bioscanCoreOverrideIndex == 0) { continue; } PuzzleOverride @override = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, bioscanCoreOverrideIndex); if (@override == null || @override.TPositions == null || @override.TPositions.Count < 1) { SPOLogger.Error("No Override for this T-Scan, falling back to vanilla impl."); continue; } CP_Bioscan_Core val = new CP_Bioscan_Core(((Il2CppObjectBase)item).Pointer); if ((Object)(object)val.m_movingComp == (Object)null) { Debug.LogError(Object.op_Implicit("Chained puzzle instance set to movable but does not include iChainedPuzzleMovable.")); } else if (val.m_movingComp.UsingStaticBioscanPoints) { foreach (Vec3 tPosition in @override.TPositions) { val.m_movingComp.ScanPositions.Add(tPosition.ToVector3()); } ((Component)val).transform.position = @override.TPositions[0].ToVector3(); __instance.m_revealWithHoloPath = false; SPOLogger.Warning("Overriding T-Scan pos!"); } else { Debug.LogError(Object.op_Implicit("Unimplemented.")); } } uint clusterCoreOverrideIndex = PuzzleOverrideManager.Current.GetClusterCoreOverrideIndex(__instance); if (clusterCoreOverrideIndex != 0) { PuzzleOverride override2 = Plugin.GetOverride(PuzzleOverrideManager.MainLevelLayout, clusterCoreOverrideIndex); if (override2 != null && override2.ConcurrentCluster) { PlayerScannerManager.Current.RegisterConcurrentCluster(__instance); SPOLogger.Warning("Setting up CP_Cluster_Core as Concurrent Cluster!"); } } } } [HarmonyPatch] internal class Patches_CP_Cluster_Hud_ReqItems { private static Dictionary<IntPtr, List<bool>> clustersChildrenReqItemEnabled; private static Dictionary<IntPtr, List<string[]>> clustersChildrenReqItemNames; private static Dictionary<IntPtr, List<Il2CppStructArray<bool>>> clustersChildrenReqItemsStatus; [HarmonyPostfix] [HarmonyPatch(typeof(CP_Bioscan_Core), "AddRequiredItems")] private static void Post_CP_Bioscan_Core_AddRequiredItems(CP_Bioscan_Core __instance, Il2CppReferenceArray<iWardenObjectiveItem> requiredItems) { CP_Cluster_Core val = ((Il2CppObjectBase)__instance.Owner).TryCast<CP_Cluster_Core>(); if ((Object)(object)val == (Object)null) { return; } if (__instance.m_hud == null) { SPOLogger.Error("CP_Cluster_Hud_ReqItems: replacement Cluster_hud is null."); return; } CP_Cluster_Hud val2 = ((Il2CppObjectBase)__instance.m_hud).TryCast<CP_Cluster_Hud>(); if ((Object)(object)val2 == (Object)null) { SPOLogger.Error("CP_Cluster_Hud_ReqItems: Find cluster owner but cannot cast m_hud to CP_Cluster_hud"); return; } string[] array = new string[((Il2CppArrayBase<iWardenObjectiveItem>)(object)requiredItems).Count]; for (int i = 0; i < __instance.m_reqItems.Count; i++) { if (__instance.m_reqItems[i] != null) { array[i] = __instance.m_reqItems[i].PublicName; } else { SPOLogger.Error("Post_CP_Bioscan_Core_AddRequiredItems: CP_Bioscan_Core " + ((Object)__instance).name + " has a missing m_reqItem! " + i); } } List<bool> list; List<string[]> list2; if (clustersChildrenReqItemEnabled.ContainsKey(((Il2CppObjectBase)val2).Pointer)) { list = clustersChildrenReqItemEnabled[((Il2CppObjectBase)val2).Pointer]; list2 = clustersChildrenReqItemNames[((Il2CppObjectBase)val2).Pointer]; } else { list = Enumerable.Repeat(element: false, val.NRofPuzzles()).ToList(); list2 = Enumerable.Repeat(new string[0], val.NRofPuzzles()).ToList(); clustersChildrenReqItemEnabled.Add(((Il2CppObjectBase)val2).Pointer, list); clustersChildrenReqItemNames.Add(((Il2CppObjectBase)val2).Pointer, list2); } list[__instance.m_puzzleIndex] = __instance.m_reqItemsEnabled; list2[__instance.m_puzzleIndex] = array; } [HarmonyPrefix] [HarmonyPatch(typeof(CP_Cluster_Hud), "SetRequiredItemData")] private static bool Pre_CP_Cluster_Hud_SetRequiredItemData(CP_Cluster_Hud __instance, int puzzleIndex, Il2CppStructArray<bool> reqItemStatus) { List<Il2CppStructArray<bool>> list; if (!clustersChildrenReqItemsStatus.ContainsKey(((Il2CppObjectBase)__instance).Pointer)) { list = Enumerable.Repeat<Il2CppStructArray<bool>>(null, __instance.m_clusterSize).ToList(); clustersChildrenReqItemsStatus.Add(((Il2CppObjectBase)__instance).Pointer, list); } else { list = clustersChildrenReqItemsStatus[((Il2CppObjectBase)__instance).Pointer]; } list[puzzleIndex] = reqItemStatus; return false; } [HarmonyPostfix] [HarmonyPatch(typeof(CP_Cluster_Hud), "UpdateDataFor")] private static void Post_CP_Cluster_Hud_UpdateDataFor(CP_Cluster_Hud __instance, int index) { if (clustersChildrenReqItemsStatus.ContainsKey(((Il2CppObjectBase)__instance).Pointer)) { if (!clustersChildrenReqItemEnabled.ContainsKey(((Il2CppObjectBase)__instance).Pointer) || !clustersChildrenReqItemNames.ContainsKey(((Il2CppObjectBase)__instance).Pointer)) { SPOLogger.Error("CP_Cluster_Hud_UpdateDataFor: Found registered reqItemStatus but ReqItemEnabled or ReqItemNames is missing!"); return; } Il2CppStructArray<bool> val = clustersChildrenReqItemsStatus[((Il2CppObjectBase)__instance).Pointer][index]; __instance.m_hud.SetupRequiredItems(clustersChildrenReqItemEnabled[((Il2CppObjectBase)__instance).Pointer][index], Il2CppStringArray.op_Implicit(clustersChildrenReqItemNames[((Il2CppObjectBase)__instance).Pointer][index])); __instance.m_hud.SetRequiredItemData(__instance.m_puzzleIndex, val); } } private static void Clear() { clustersChildrenReqItemsStatus.Clear(); clustersChildrenReqItemNames.Clear(); clustersChildrenReqItemEnabled.Clear(); } static Patches_CP_Cluster_Hud_ReqItems() { clustersChildrenReqItemEnabled = new Dictionary<IntPtr, List<bool>>(); clustersChildrenReqItemNames = new Dictionary<IntPtr, List<string[]>>(); clustersChildrenReqItemsStatus = new Dictionary<IntPtr, List<Il2CppStructArray<bool>>>(); LevelAPI.OnLevelCleanup += Clear; } } } namespace ScanPosOverride.Managers { public class PlayerScannerManager { public static readonly PlayerScannerManager Current; private Dictionary<CP_Cluster_Core, List<CP_PlayerScanner>> ConcurrentClusterCores = new Dictionary<CP_Cluster_Core, List<CP_PlayerScanner>>(); private Dictionary<CP_Cluster_Core, List<CP_Bioscan_Core>> ConcurrentClusterChildCores = new Dictionary<CP_Cluster_Core, List<CP_Bioscan_Core>>(); private Dictionary<IntPtr, CP_Cluster_Core> ConcurrentScanClusterParents = new Dictionary<IntPtr, CP_Cluster_Core>(); private Dictionary<CP_Cluster_Core, HashSet<IntPtr>> ConcurrentClusterChildScanState = new Dictionary<CP_Cluster_Core, HashSet<IntPtr>>(); private Mutex ConcurrentClusterStateMutex; private Dictionary<CP_Cluster_Core, float[]> OriginalClusterScanSpeeds = new Dictionary<CP_Cluster_Core, float[]>(); private Dictionary<IntPtr, CP_PlayerScanner> Scanners = new Dictionary<IntPtr, CP_PlayerScanner>(); private Dictionary<IntPtr, float[]> OriginalScanSpeed = new Dictionary<IntPtr, float[]>(); private static readonly float[] ZERO_SCAN_SPEED; internal bool RegisterConcurrentCluster(CP_Cluster_Core core) { if (ConcurrentClusterCores.ContainsKey(core)) { return false; } List<CP_PlayerScanner> list = Enumerable.Repeat<CP_PlayerScanner>(null, core.m_amountOfPuzzles).ToList(); List<CP_Bioscan_Core> list2 = Enumerable.Repeat<CP_Bioscan_Core>(null, core.m_amountOfPuzzles).ToList(); float[] array = new float[4]; for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)core.m_childCores).Count; i++) { if ((Object)(object)list[i] != (Object)null) { SPOLogger.Error("SetupConcurrentClusterScanners: Duplicate child scanner for child scan. ??"); continue; } iChainedPuzzleCore val = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)core.m_childCores)[i]; CP_Bioscan_Core val2 = ((Il2CppObjectBase)val).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val2 == (Object)null) { SPOLogger.Error("SetupConcurrentClusterScanners: Failed to cast child to CP_Bioscan_Core"); continue; } CP_PlayerScanner val3 = ((Il2CppObjectBase)val2.PlayerScanner).TryCast<CP_PlayerScanner>(); if ((Object)(object)val3 == (Object)null) { SPOLogger.Error("SetupConcurrentClusterScanners: Failed to cast CP_Bioscan_Core.PlayerScanner to CP_PlayerScanner"); continue; } list[i] = val3; Scanners.Add(((Il2CppObjectBase)val).Pointer, val3); list2[i] = val2; if (!OriginalClusterScanSpeeds.ContainsKey(core)) { Il2CppStructArray<float> scanSpeeds = val3.m_scanSpeeds; for (int j = 0; j < 4; j++) { array[j] = ((Il2CppArrayBase<float>)(object)scanSpeeds)[j]; } OriginalClusterScanSpeeds.Add(core, array); } ConcurrentScanClusterParents.Add(((Il2CppObjectBase)val).Pointer, core); } ConcurrentClusterCores.Add(core, list); ConcurrentClusterChildCores.Add(core, list2); ConcurrentClusterChildScanState.Add(core, new HashSet<IntPtr>()); return true; } internal bool IsConcurrentCluster(CP_Cluster_Core core) { return ConcurrentClusterCores.ContainsKey(core); } internal bool IsConcurrentCluster(CP_Bioscan_Core core) { return ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer); } internal void ZeroConcurrentClusterScanSpeed(CP_Cluster_Core clusterCore) { if (!ConcurrentClusterCores.ContainsKey(clusterCore)) { return; } foreach (CP_PlayerScanner item in ConcurrentClusterCores[clusterCore]) { bool flag = true; for (int i = 0; i < 4; i++) { flag = flag && ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] == 0f; ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] = 0f; } if (flag) { break; } } } internal void RestoreConcurrentClusterScanSpeed(CP_Cluster_Core clusterCore) { if (!ConcurrentClusterCores.ContainsKey(clusterCore) || !OriginalClusterScanSpeeds.ContainsKey(clusterCore)) { return; } float[] array = OriginalClusterScanSpeeds[clusterCore]; foreach (CP_PlayerScanner item in ConcurrentClusterCores[clusterCore]) { bool flag = false; for (int i = 0; i < 4; i++) { flag = flag || ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] != 0f; ((Il2CppArrayBase<float>)(object)item.m_scanSpeeds)[i] = array[i]; } if (flag) { break; } } } internal float[] GetCacheOriginalScanSpeed(CP_Bioscan_Core core) { if (IsConcurrentCluster(core)) { if (!ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer)) { return ZERO_SCAN_SPEED; } CP_Cluster_Core key = ConcurrentScanClusterParents[((Il2CppObjectBase)core).Pointer]; if (!OriginalClusterScanSpeeds.ContainsKey(key)) { return ZERO_SCAN_SPEED; } return OriginalClusterScanSpeeds[key]; } if (OriginalScanSpeed.ContainsKey(((Il2CppObjectBase)core).Pointer)) { return OriginalScanSpeed[((Il2CppObjectBase)core).Pointer]; } CP_PlayerScanner cacheScanner = GetCacheScanner(core); if ((Object)(object)cacheScanner == (Object)null) { SPOLogger.Error("GetCacheOriginalScanSpeed: cannot get scanner for this CP_Bioscan_Core"); return ZERO_SCAN_SPEED; } float[] array = new float[4]; for (int i = 0; i < 4; i++) { array[i] = ((Il2CppArrayBase<float>)(object)cacheScanner.m_scanSpeeds)[i]; } OriginalScanSpeed.Add(((Il2CppObjectBase)core).Pointer, array); return array; } internal CP_Cluster_Core GetParentClusterCore(CP_Bioscan_Core core) { if (!ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer)) { return null; } return ConcurrentScanClusterParents[((Il2CppObjectBase)core).Pointer]; } public CP_PlayerScanner GetCacheScanner(CP_Bioscan_Core core) { if (Scanners.ContainsKey(((Il2CppObjectBase)core).Pointer)) { return Scanners[((Il2CppObjectBase)core).Pointer]; } CP_PlayerScanner val = ((Il2CppObjectBase)core.PlayerScanner).TryCast<CP_PlayerScanner>(); if ((Object)(object)val == (Object)null) { return null; } Scanners.Add(((Il2CppObjectBase)core).Pointer, val); return val; } internal bool ConcurrentClusterShouldProgress(CP_Bioscan_Core core, bool IsThisScanShouldProgress) { if (ConcurrentClusterStateMutex == null) { SPOLogger.Error("ConcurrentCluster: scan mutex uninitialized."); return false; } if (ConcurrentClusterStateMutex.WaitOne(2000)) { if (!ConcurrentScanClusterParents.ContainsKey(((Il2CppObjectBase)core).Pointer)) { SPOLogger.Error("ConcurrentClusterShouldProgress: failed to find cluster parent!"); ConcurrentClusterStateMutex.ReleaseMutex(); return false; } CP_Cluster_Core val = ConcurrentScanClusterParents[((Il2CppObjectBase)core).Pointer]; if (!ConcurrentClusterChildScanState.ContainsKey(val)) { SPOLogger.Error("ConcurrentClusterShouldProgress: ConcurrentClusterChildScanState initialization error!"); ConcurrentClusterStateMutex.ReleaseMutex(); return false; } HashSet<IntPtr> hashSet = ConcurrentClusterChildScanState[val]; bool result; if (IsThisScanShouldProgress) { hashSet.Add(((Il2CppObjectBase)core).Pointer); result = hashSet.Count == val.m_amountOfPuzzles; } else { hashSet.Remove(((Il2CppObjectBase)core).Pointer); result = false; } ConcurrentClusterStateMutex.ReleaseMutex(); return result; } SPOLogger.Debug("ConcurrentCluster: Failed to acquire scan mutex."); return false; } internal void CompleteConcurrentCluster(CP_Cluster_Core core) { if (!ConcurrentClusterChildCores.ContainsKey(core)) { return; } List<CP_Bioscan_Core> list = ConcurrentClusterChildCores[core]; ConcurrentClusterChildCores.Remove(core); foreach (CP_Bioscan_Core item in list) { item.m_sync.SetStateData((eBioscanStatus)4, 0f, (List<PlayerAgent>)null, 0, (Il2CppStructArray<bool>)null); } } public void Init() { ConcurrentClusterStateMutex = new Mutex(); } public void Clear() { ConcurrentClusterCores.Clear(); ConcurrentClusterChildCores.Clear(); ConcurrentScanClusterParents.Clear(); ConcurrentClusterChildScanState.Clear(); OriginalClusterScanSpeeds.Clear(); Scanners.Clear(); OriginalScanSpeed.Clear(); if (ConcurrentClusterStateMutex != null) { ConcurrentClusterStateMutex.Dispose(); } ConcurrentClusterStateMutex = null; } static PlayerScannerManager() { ZERO_SCAN_SPEED = new float[4]; Current = new PlayerScannerManager(); LevelAPI.OnBuildDone += Current.Init; LevelAPI.OnLevelCleanup += Current.Clear; } private PlayerScannerManager() { } } public class PuzzleReqItemManager { public static readonly PuzzleReqItemManager Current; private Dictionary<int, CarryItemPickup_Core> BigPickupItemsInLevel = new Dictionary<int, CarryItemPickup_Core>(); private int itemIndexCounter = 1; private List<(CP_Bioscan_Core, List<int>)> bioscanCoresToAddReqItems = new List<(CP_Bioscan_Core, List<int>)>(); private List<(CP_Cluster_Core, List<int>)> clusterCoresToAddReqItems = new List<(CP_Cluster_Core, List<int>)>(); private Dictionary<IntPtr, CP_Bioscan_Core> movableScansWithReqItems = new Dictionary<IntPtr, CP_Bioscan_Core>(); internal int Register(CarryItemPickup_Core item) { int num = itemIndexCounter; itemIndexCounter++; BigPickupItemsInLevel.Add(num, item); return num; } internal void QueueForAddingReqItems(CP_Bioscan_Core core, List<int> itemsIndices) { bioscanCoresToAddReqItems.Add((core, itemsIndices)); } internal void QueueForAddingReqItems(CP_Cluster_Core core, List<int> itemsIndices) { clusterCoresToAddReqItems.Add((core, itemsIndices)); } internal CP_Bioscan_Core GetMovableCoreWithReqItem(CP_PlayerScanner scanner) { if (!movableScansWithReqItems.ContainsKey(((Il2CppObjectBase)scanner).Pointer)) { return null; } return movableScansWithReqItems[((Il2CppObjectBase)scanner).Pointer]; } public CarryItemPickup_Core GetBigPickupItem(int bigPickupInLevelIndex) { if (!BigPickupItemsInLevel.ContainsKey(bigPickupInLevelIndex)) { return null; } return BigPickupItemsInLevel[bigPickupInLevelIndex]; } public bool AddReqItems(CP_Bioscan_Core puzzle, int itemIndex) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown if ((Object)(object)puzzle == (Object)null || itemIndex == 0L) { return false; } if (!BigPickupItemsInLevel.ContainsKey(itemIndex)) { SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}"); return false; } CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex]; puzzle.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer) })); return true; } public bool AddReqItems(CP_Cluster_Core puzzle, int itemIndex) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown if ((Object)(object)puzzle == (Object)null || itemIndex == 0L) { return false; } if (!BigPickupItemsInLevel.ContainsKey(itemIndex)) { SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}"); return false; } CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex]; foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)puzzle.m_childCores) { item.AddRequiredItems(Il2CppReferenceArray<iWardenObjectiveItem>.op_Implicit((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer) })); } return true; } public bool AddReqItems(CP_Bioscan_Core puzzle, List<int> itemsIndices) { if ((Object)(object)puzzle == (Object)null || itemsIndices == null || itemsIndices.Count < 1) { return false; } bool flag = false; foreach (int item in itemsIndices.ToHashSet()) { flag |= AddReqItems(puzzle, item); } if (puzzle.IsMovable && flag) { movableScansWithReqItems.Add(((Il2CppObjectBase)puzzle.m_playerScanner).Pointer, puzzle); } return flag; } public void RemoveReqItem(CP_Bioscan_Core puzzle, int itemIndex) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (!((Object)(object)puzzle == (Object)null)) { if (!BigPickupItemsInLevel.ContainsKey(itemIndex) && itemIndex != 0L) { SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}"); } else { CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex]; puzzle.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer) }); } } } public void RemoveReqItem(CP_Cluster_Core puzzle, int itemIndex) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if ((Object)(object)puzzle == (Object)null) { return; } if (!BigPickupItemsInLevel.ContainsKey(itemIndex) && itemIndex != 0L) { SPOLogger.Error($"Unregistered BigPickup Item with index {itemIndex}"); return; } CarryItemPickup_Core val = BigPickupItemsInLevel[itemIndex]; foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)puzzle.m_childCores) { item.RemoveRequiredItems((iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)val).Pointer) }); } } private void AddQueuedReqItems() { foreach (var (puzzle, itemsIndices) in bioscanCoresToAddReqItems) { AddReqItems(puzzle, itemsIndices); } foreach (var (val, itemsIndices2) in clusterCoresToAddReqItems) { foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val.m_childCores) { CP_Bioscan_Core val2 = ((Il2CppObjectBase)item).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val2 == (Object)null) { SPOLogger.Error("Failed to cast child core to CP_Bioscan_Core"); } else { AddReqItems(val2, itemsIndices2); } } } } public void OutputLevelBigPickupInfo() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) StringBuilder val = new StringBuilder(); val.AppendLine(); List<CarryItemPickup_Core> list = new List<CarryItemPickup_Core>(BigPickupItemsInLevel.Values); list.Sort(delegate(CarryItemPickup_Core b1, CarryItemPickup_Core b2) { //IL_0014: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode spawnNode = b1.SpawnNode; AIG_CourseNode spawnNode2 = b2.SpawnNode; if (spawnNode.m_dimension.DimensionIndex != spawnNode2.m_dimension.DimensionIndex) { if (spawnNode.m_dimension.DimensionIndex > spawnNode2.m_dimension.DimensionIndex) { return 1; } return -1; } if (spawnNode.LayerType != spawnNode2.LayerType) { if (spawnNode.LayerType >= spawnNode2.LayerType) { return 1; } return -1; } return (spawnNode.m_zone.LocalIndex != spawnNode2.m_zone.LocalIndex) ? ((spawnNode.m_zone.LocalIndex >= spawnNode2.m_zone.LocalIndex) ? 1 : (-1)) : 0; }); Dictionary<CarryItemPickup_Core, int> dictionary = new Dictionary<CarryItemPickup_Core, int>(); foreach (int key in BigPickupItemsInLevel.Keys) { dictionary.Add(BigPickupItemsInLevel[key], key); } foreach (CarryItemPickup_Core item in list) { val.AppendLine("Item Name: " + ((Item)item).ItemDataBlock.publicName); val.AppendLine($"Zone {item.SpawnNode.m_zone.Alias}, {item.SpawnNode.LayerType}, Dim {item.SpawnNode.m_dimension.DimensionIndex}"); val.AppendLine($"Item Index: {dictionary[item]}"); val.AppendLine(); } SPOLogger.Debug(((Object)val).ToString()); } internal void OnEnterLevel() { AddQueuedReqItems(); OutputLevelBigPickupInfo(); } public void Clear() { BigPickupItemsInLevel.Clear(); itemIndexCounter = 1; bioscanCoresToAddReqItems.Clear(); clusterCoresToAddReqItems.Clear(); movableScansWithReqItems.Clear(); } static PuzzleReqItemManager() { Current = new PuzzleReqItemManager(); LevelAPI.OnLevelCleanup += Current.Clear; LevelAPI.OnEnterLevel += Current.OnEnterLevel; } private PuzzleReqItemManager() { } } public class PuzzleOverrideManager { public static readonly PuzzleOverrideManager Current; private Dictionary<CP_Bioscan_Core, uint> bioscanCore2Index = new Dictionary<CP_Bioscan_Core, uint>(); private Dictionary<CP_Cluster_Core, uint> clusterCore2Index = new Dictionary<CP_Cluster_Core, uint>(); private Dictionary<uint, CP_Bioscan_Core> index2BioscanCore = new Dictionary<uint, CP_Bioscan_Core>(); private Dictionary<uint, CP_Cluster_Core> index2ClusterCore = new Dictionary<uint, CP_Cluster_Core>(); private Dictionary<IntPtr, uint> bioscanCoreIntPtr2Index = new Dictionary<IntPtr, uint>(); private Dictionary<IntPtr, uint> clusterCoreIntPtr2Index = new Dictionary<IntPtr, uint>(); private uint puzzleOverrideIndex = 1u; public static uint MainLevelLayout => RundownManager.ActiveExpedition.LevelLayoutData; public uint Register(CP_Bioscan_Core __instance) { if ((Object)(object)__instance == (Object)null) { return 0u; } uint num = puzzleOverrideIndex; puzzleOverrideIndex++; if (!bioscanCore2Index.ContainsKey(__instance)) { bioscanCore2Index.Add(__instance, num); bioscanCoreIntPtr2Index.Add(((Il2CppObjectBase)__instance).Pointer, num); index2BioscanCore.Add(num, __instance); return num; } return GetBioscanCoreOverrideIndex(__instance); } public uint Register(CP_Cluster_Core __instance) { if ((Object)(object)__instance == (Object)null) { return 0u; } uint num = puzzleOverrideIndex; puzzleOverrideIndex++; if (!clusterCore2Index.ContainsKey(__instance)) { clusterCore2Index.Add(__instance, num); clusterCoreIntPtr2Index.Add(((Il2CppObjectBase)__instance).Pointer, num); index2ClusterCore.Add(num, __instance); return num; } return GetClusterCoreOverrideIndex(__instance); } public void OutputLevelPuzzleInfo() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) List<ChainedPuzzleInstance> list = new List<ChainedPuzzleInstance>(); Enumerator<ChainedPuzzleInstance> enumerator = ChainedPuzzleManager.Current.m_instances.GetEnumerator(); while (enumerator.MoveNext()) { ChainedPuzzleInstance current = enumerator.Current; list.Add(current); } list.Sort(delegate(ChainedPuzzleInstance c1, ChainedPuzzleInstance c2) { //IL_0019: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) LG_Zone zone2 = c1.m_sourceArea.m_zone; LG_Zone zone3 = c2.m_sourceArea.m_zone; if (zone2.DimensionIndex != zone3.DimensionIndex) { if (zone2.DimensionIndex >= zone3.DimensionIndex) { return 1; } return -1; } if (zone2.Layer.m_type != zone3.Layer.m_type) { if (zone2.Layer.m_type >= zone3.Layer.m_type) { return 1; } return -1; } return (zone2.LocalIndex >= zone3.LocalIndex) ? 1 : (-1); }); StringBuilder stringBuilder = new StringBuilder(); foreach (ChainedPuzzleInstance item in list) { LG_Zone zone = item.m_sourceArea.m_zone; StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(15, 3, stringBuilder2); handler.AppendLiteral("\nZone "); handler.AppendFormatted(zone.Alias); handler.AppendLiteral(", "); handler.AppendFormatted<LG_LayerType>(zone.m_layer.m_type); handler.AppendLiteral(", Dim "); handler.AppendFormatted<eDimensionIndex>(zone.DimensionIndex); handler.AppendLiteral("\n"); stringBuilder3.Append(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(14, 1, stringBuilder2); handler.AppendLiteral("Alarm name: "); handler.AppendFormatted(item.Data.PublicAlarmName); handler.AppendLiteral(":\n"); stringBuilder4.Append(ref handler); for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)item.m_chainedPuzzleCores).Count; i++) { iChainedPuzzleCore val = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)item.m_chainedPuzzleCores)[i]; if (bioscanCoreIntPtr2Index.ContainsKey(((Il2CppObjectBase)val).Pointer)) { uint value = bioscanCoreIntPtr2Index[((Il2CppObjectBase)val).Pointer]; stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2); handler.AppendLiteral("puzzle index: "); handler.AppendFormatted(i); handler.AppendLiteral("\n"); stringBuilder5.Append(ref handler); stringBuilder.Append("type: CP_Bioscan_Core\n"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2); handler.AppendLiteral("PuzzleOverrideIndex: "); handler.AppendFormatted(value); handler.AppendLiteral("\n"); stringBuilder6.Append(ref handler); CP_Bioscan_Core val2 = ((Il2CppObjectBase)val).Cast<CP_Bioscan_Core>(); CP_PlayerScanner val3 = ((Il2CppObjectBase)val2.PlayerScanner).Cast<CP_PlayerScanner>(); stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2); handler.AppendLiteral("Position: "); handler.AppendFormatted<Vector3>(val2.m_position); handler.AppendLiteral("\n"); stringBuilder7.Append(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2); handler.AppendLiteral("Radius: "); handler.AppendFormatted(val3.Radius); handler.AppendLiteral("\n"); stringBuilder8.Append(ref handler); } else if (clusterCoreIntPtr2Index.ContainsKey(((Il2CppObjectBase)val).Pointer)) { uint value2 = clusterCoreIntPtr2Index[((Il2CppObjectBase)val).Pointer]; CP_Cluster_Core val4 = ((Il2CppObjectBase)val).TryCast<CP_Cluster_Core>(); if ((Object)(object)val4 == (Object)null) { SPOLogger.Error("Found cluster core Pointer, but TryCast failed."); continue; } stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2); handler.AppendLiteral("puzzle index: "); handler.AppendFormatted(i); handler.AppendLiteral("\n"); stringBuilder9.Append(ref handler); stringBuilder.Append("type: CP_Cluster_Core\n"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2); handler.AppendLiteral("PuzzleOverrideIndex: "); handler.AppendFormatted(value2); handler.AppendLiteral("\n"); stringBuilder10.Append(ref handler); stringBuilder.Append("=== Clustered puzzles info: ===\n"); for (int j = 0; j < val4.m_amountOfPuzzles; j++) { iChainedPuzzleCore val5 = ((Il2CppArrayBase<iChainedPuzzleCore>)(object)val4.m_childCores)[j]; if (!bioscanCoreIntPtr2Index.ContainsKey(((Il2CppObjectBase)val5).Pointer)) { SPOLogger.Error("Unregistered clustered iChainedPuzzleCore found..."); continue; } uint value3 = bioscanCoreIntPtr2Index[((Il2CppObjectBase)val5).Pointer]; stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(15, 1, stringBuilder2); handler.AppendLiteral("puzzle index: "); handler.AppendFormatted(j); handler.AppendLiteral("\n"); stringBuilder11.Append(ref handler); stringBuilder.Append("type: CP_Bioscan_Core\n"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder2); handler.AppendLiteral("PuzzleOverrideIndex: "); handler.AppendFormatted(value3); handler.AppendLiteral("\n"); stringBuilder12.Append(ref handler); CP_Bioscan_Core val6 = ((Il2CppObjectBase)val5).Cast<CP_Bioscan_Core>(); CP_PlayerScanner val7 = ((Il2CppObjectBase)val6.PlayerScanner).Cast<CP_PlayerScanner>(); stringBuilder2 = stringBuilder; StringBuilder stringBuilder13 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2); handler.AppendLiteral("Position: "); handler.AppendFormatted<Vector3>(val6.m_position); handler.AppendLiteral("\n"); stringBuilder13.Append(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder14 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2); handler.AppendLiteral("Radius: "); handler.AppendFormatted(val7.Radius); handler.AppendLiteral("\n"); stringBuilder14.Append(ref handler); } stringBuilder.Append("=== Clustered puzzles END ===\n"); } else { SPOLogger.Error("Unregistered iChainedPuzzleCore found..."); } } stringBuilder.Append('\n'); } SPOLogger.Debug(stringBuilder.ToString()); } public uint GetBioscanCoreOverrideIndex(CP_Bioscan_Core core) { if (bioscanCore2Index.ContainsKey(core)) { return bioscanCore2Index[core]; } return 0u; } public uint GetClusterCoreOverrideIndex(CP_Cluster_Core core) { if (clusterCore2Index.ContainsKey(core)) { return clusterCore2Index[core]; } return 0u; } public uint GetBioscanCoreOverrideIndex(IntPtr pointer) { if (bioscanCoreIntPtr2Index.ContainsKey(pointer)) { return bioscanCoreIntPtr2Index[pointer]; } return 0u; } public uint GetClusterCoreOverrideIndex(IntPtr pointer) { if (clusterCoreIntPtr2Index.ContainsKey(pointer)) { return clusterCoreIntPtr2Index[pointer]; } return 0u; } public CP_Bioscan_Core GetBioscanCore(uint puzzleOverrideIndex) { if (!index2BioscanCore.ContainsKey(puzzleOverrideIndex)) { return null; } return index2BioscanCore[puzzleOverrideIndex]; } public CP_Cluster_Core GetClusterCore(uint puzzleOverrideIndex) { if (!index2ClusterCore.ContainsKey(puzzleOverrideIndex)) { return null; } return index2ClusterCore[puzzleOverrideIndex]; } public void Clear() { puzzleOverrideIndex = 1u; bioscanCore2Index.Clear(); clusterCore2Index.Clear(); bioscanCoreIntPtr2Index.Clear(); clusterCoreIntPtr2Index.Clear(); index2BioscanCore.Clear(); index2ClusterCore.Clear(); } private PuzzleOverrideManager() { } static PuzzleOverrideManager() { Current = new PuzzleOverrideManager(); LevelAPI.OnEnterLevel += Current.OutputLevelPuzzleInfo; LevelAPI.OnLevelCleanup += Current.Clear; } public iChainedPuzzleOwner ChainedPuzzleInstanceOwner(CP_Bioscan_Core bioscanCore) { if ((Object)(object)bioscanCore == (Object)null) { return null; } iChainedPuzzleOwner owner = bioscanCore.Owner; if ((Object)(object)((Il2CppObjectBase)owner).TryCast<ChainedPuzzleInstance>() != (Object)null) { return owner; } CP_Cluster_Core val = ((Il2CppObjectBase)owner).TryCast<CP_Cluster_Core>(); if ((Object)(object)val != (Object)null) { return val.m_owner; } SPOLogger.Error("Failed to find CP_BioScan_Core owner (instance of ChainedPuzzleInstance)."); return null; } } } namespace ScanPosOverride.JSON { internal class LocalizedTextConverter : JsonConverter<LocalizedText> { public override bool HandleNull => false; public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown switch (reader.TokenType) { case JsonTokenType.String: { string @string = reader.GetString(); return new LocalizedText { Id = 0u, UntranslatedText = @string }; } case JsonTokenType.Number: return new LocalizedText { Id = reader.GetUInt32(), UntranslatedText = null }; default: throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options) { JsonSerializer.Serialize<LocalizedText>(writer, value, options); } } internal static class Json { private static readonly JsonSerializerOptions _setting; static Json() { _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = false, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new JsonStringEnumConverter()); if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized) { _setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter); _setting.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter); SPOLogger.Log("PartialData Support Found!"); } else { _setting.Converters.Add(new LocalizedTextConverter()); } } public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, _setting); } public static object Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize<T>(T value) { return JsonSerializer.Serialize(value, _setting); } public static void Load<T>(string file, out T config) where T : new() { if (file.Length < ".json".Length) { config = default(T); return; } if (file.Substring(file.Length - ".json".Length) != ".json") { file += ".json"; } file = File.ReadAllText(Path.Combine(Plugin.OVERRIDE_SCAN_POS_PATH, file)); config = Deserialize<T>(file); } } public static class MTFOPartialDataUtil { public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks"; public static JsonConverter PersistentIDConverter { get; private set; } public static JsonConverter LocalizedTextConverter { get; private set; } public static bool IsLoaded { get; private set; } public static bool Initialized { get; private set; } public static string PartialDataPath { get; private set; } public static string ConfigPath { get; private set; } static MTFOPartialDataUtil() { PersistentIDConverter = null; LocalizedTextConverter = null; IsLoaded = false; Initialized = false; PartialDataPath = string.Empty; ConfigPath = string.Empty; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type[] types = obj.GetTypes(); Type type = types.First((Type t) => t.Name == "PersistentIDConverter"); if ((object)type == null) { throw new Exception("Unable to Find PersistentIDConverter Class"); } Type type2 = types.First((Type t) => t.Name == "PartialDataManager"); if ((object)type2 == null) { throw new Exception("Unable to Find PartialDataManager Class"); } Type type3 = types.First((Type t) => t.Name == "LocalizedTextConverter") ?? throw new Exception("Unable to Find LocalizedTextConverter Class"); PropertyInfo property = type2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public); PropertyInfo property2 = type2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public); PropertyInfo? property3 = type2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public); if ((object)property == null) { throw new Exception("Unable to Find Property: Initialized"); } if ((object)property2 == null) { throw new Exception("Unable to Find Property: PartialDataPath"); } if ((object)property3 == null) { throw new Exception("Unable to Find Field: ConfigPath"); } Initialized = (bool)property.GetValue(null); PartialDataPath = (string)property2.GetValue(null); ConfigPath = (string)property3.GetValue(null); PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type); LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type3); IsLoaded = true; } catch (Exception value2) { SPOLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}"); } } } public static class MTFOUtil { public const string PLUGIN_GUID = "com.dak.MTFO"; public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public; public static string GameDataPath { get; private set; } public static string CustomPath { get; private set; } public static bool HasCustomContent { get; private set; } public static bool IsLoaded { get; private set; } static MTFOUtil() { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class"); FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public); if ((object)field == null) { throw new Exception("Unable to Find Field: GameDataPath"); } if ((object)field2 == null) { throw new Exception("Unable to Find Field: CustomPath"); } if ((object)field3 == null) { throw new Exception("Unable to Find Field: HasCustomContent"); } GameDataPath = (string)field.GetValue(null); CustomPath = (string)field2.GetValue(null); HasCustomContent = (bool)field3.GetValue(null); IsLoaded = true; } catch (Exception value2) { SPOLogger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}"); } } } }
plugins/net6/SecDoorTerminalInterface.dll
Decompiled 10 months agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using Agents; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using ChainedPuzzles; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using SecDoorTerminalInterface.Inject; using TMPro; 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("SecDoorTerminalInterface")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+git6952937-master")] [assembly: AssemblyProduct("SecDoorTerminalInterface")] [assembly: AssemblyTitle("SecDoorTerminalInterface")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SecDoorTerminalInterface { internal static class Assets { public static GameObject SecDoorTerminalPrefab; public static void Init() { SecDoorTerminalPrefab = AssetAPI.GetLoadedAsset<GameObject>("Assets/Modding/SecDoorTerminal/Terminal_SecDoor.prefab"); } } public struct CommandDescriptor { public TERM_Command Type; public string Command; public string Description; public TERM_CommandRule Rule; } public enum CPSolvedBehaviour { OpenDoor, AddOpenCommand, Nothing } [BepInPlugin("SecDoorTerminalInterface", "SecDoorTerminalInterface", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { private Harmony _Harmony; public override void Load() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown AssetAPI.OnAssetBundlesLoaded += AssetAPI_OnAssetBundlesLoaded; _Harmony = new Harmony("SecDoorTerminalInterface.Harmony"); _Harmony.PatchAll(); } private void AssetAPI_OnAssetBundlesLoaded() { Assets.Init(); } } internal static class Logger { private static readonly ManualLogSource _Logger; static Logger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _Logger = new ManualLogSource("SecDoorTerminalInterface"); Logger.Sources.Add((ILogSource)(object)_Logger); } private static string Format(object msg) { return msg.ToString(); } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { _Logger.LogInfo(handler); } public static void Info(string str) { _Logger.LogMessage((object)str); } public static void Info(object data) { _Logger.LogMessage((object)Format(data)); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { _Logger.LogDebug(handler); } public static void Debug(string str) { _Logger.LogDebug((object)str); } public static void Debug(object data) { _Logger.LogDebug((object)Format(data)); } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { _Logger.LogError(handler); } public static void Error(string str) { _Logger.LogError((object)str); } public static void Error(object data) { _Logger.LogError((object)Format(data)); } public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler) { _Logger.LogFatal(handler); } public static void Fatal(string str) { _Logger.LogFatal((object)str); } public static void Fatal(object data) { _Logger.LogFatal((object)Format(data)); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { _Logger.LogWarning(handler); } public static void Warn(string str) { _Logger.LogWarning((object)str); } public static void Warn(object data) { _Logger.LogWarning((object)Format(data)); } [Conditional("DEBUG")] public static void DebugOnly(object data) { } } public sealed class SecDoorTerminal { public const TERM_Command COMMAND_OPEN = 255; public const TERM_Command COMMAND_OVERRIDE = 254; private LocalizedText _GCTextHolder; private Vector3 _SavedIntOpenDoorPos; private Vector3 _SavedIntUseKeyPos; private Vector3 _SavedIntCustomMessagePos; private Vector3 _SavedIntHackPos; private SDT_StateBehaviour _StateBehaviour; private static readonly Vector3 BEGONE = Vector3.one * 10000f; public string OpenCommandName { get; set; } = "OPEN_LINKED"; public string OpenCommandDescription { get; set; } = "Open the linked security door"; public LG_SecurityDoor LinkedDoor { get; private set; } public LG_SecurityDoor_Locks LinkedDoorLocks { get; private set; } public LG_ComputerTerminal ComputerTerminal { get; private set; } public LG_ComputerTerminalCommandInterpreter CmdProcessor { get; private set; } public Interact_ComputerTerminal Interaction { get; private set; } public TextMeshPro IdleText { get; private set; } public SpriteRenderer IdleIcon { get; private set; } public AIG_CourseNode SpawnNode => ComputerTerminal.m_terminalItem.SpawnNode; public bool IsTerminalActive { get; private set; } = true; public CPSolvedBehaviour BioscanScanSolvedBehaviour { get; set; } = CPSolvedBehaviour.AddOpenCommand; public SDT_StateBehaviour StateBehaviour { get { return _StateBehaviour; } set { _StateBehaviour?.SetContext(null); _StateBehaviour = value; _StateBehaviour?.SetContext(this); } } public event Action<TERM_Command, string, string, string> OnCmdUsed; private void Setup_CommandModule() { Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced += OnReceiveCommand; } private void OnReceiveCommand(LG_ComputerTerminalCommandInterpreter interpreter, TERM_Command cmd, string inputLine, string param1, string param2) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (interpreter.m_terminal.m_syncID == ComputerTerminal.m_syncID) { this.OnCmdUsed?.Invoke(cmd, inputLine, param1, param2); } } public void AddCommand(CommandDescriptor descriptor, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null) { //IL_0027: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (CmdProcessor.HasRegisteredCommand(descriptor.Type)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Command Type: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TERM_Command>(descriptor.Type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is Already Added!!"); } Logger.Error(val); return; } _GCTextHolder = new LocalizedText { UntranslatedText = descriptor.Description, Id = 0u }; CmdProcessor.AddCommand(descriptor.Type, descriptor.Command, _GCTextHolder, descriptor.Rule); OnCmdUsed += delegate(TERM_Command cmdType, string cmdStr, string param1, string param2) { //IL_0000: 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) if (cmdType == descriptor.Type) { onCommandUsed?.Invoke(CmdProcessor); } }; } public void AddOverrideCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null) { //IL_0023: 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) CommandDescriptor commandDescriptor = default(CommandDescriptor); commandDescriptor.Type = (TERM_Command)254; commandDescriptor.Command = cmd; commandDescriptor.Description = helpText; commandDescriptor.Rule = (TERM_CommandRule)1; CommandDescriptor descriptor = commandDescriptor; AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter) { onCommandUsed?.Invoke(CmdProcessor); interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>OVERRIDE</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)4, "Decrypting Authorize ID..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)2, "Sending..", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)5, "<color=orange>OVERRIDE</color> Action sent!", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0); SetEndOfQueue(delegate { if (SNet.IsMaster) { LinkedDoorLocks.m_intOpenDoor.OnInteractionTriggered.Invoke(PlayerManager.GetLocalPlayerAgent()); } }); }); } public void AddOpenCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed = null) { //IL_0023: 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) CommandDescriptor commandDescriptor = default(CommandDescriptor); commandDescriptor.Type = (TERM_Command)255; commandDescriptor.Command = cmd; commandDescriptor.Description = helpText; commandDescriptor.Rule = (TERM_CommandRule)1; CommandDescriptor descriptor = commandDescriptor; AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter) { onCommandUsed?.Invoke(interpreter); interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>OPEN</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)4, "Decrypting Authorize ID..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)2, "Sending..", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0); interpreter.AddOutput((TerminalLineType)5, "<color=orange>OVERRIDE</color> Action sent!", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0); SetEndOfQueue(delegate { if (SNet.IsMaster) { LinkedDoorLocks.m_intOpenDoor.OnInteractionTriggered.Invoke(PlayerManager.GetLocalPlayerAgent()); } }); }); } public void SetEndOfQueue(Action onEndOfQueue) { CmdProcessor.OnEndOfQueue = Action.op_Implicit(onEndOfQueue); } private void Setup() { Setup_GraphicModule(); Setup_DoorInteractModule(); Setup_DoorStateModule(); Setup_CommandModule(); } public void SetTerminalActive(bool active) { IsTerminalActive = active; ((Behaviour)ComputerTerminal).enabled = active; Interact_ComputerTerminal componentInChildren = ((Component)ComputerTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = active; ((Interact_Base)componentInChildren).SetActive(active); } if (!active) { PlayerAgent localInteractionSource = ComputerTerminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { ComputerTerminal.ExitFPSView(); } if (SNet.IsMaster) { ComputerTerminal.ChangeState((TERM_State)0); } } } public void SetSpawnNode(AIG_CourseNode node) { ComputerTerminal.m_terminalItem.SpawnNode = node; } public void SetLocationTextToSpawnZone() { SetLocationText(SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7)); } public void SetLocationText(string text) { ComputerTerminal.m_terminalItem.FloorItemLocation = text; } private SecDoorTerminal() { } public void SetOpenInteractActive(bool active) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Interact_Timed intOpenDoor = LinkedDoorLocks.m_intOpenDoor; ((Component)intOpenDoor).transform.position = (active ? _SavedIntOpenDoorPos : BEGONE); ((Interact_Base)intOpenDoor).SetActive(active); } public void SetUseKeyInteractActive(bool active) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Interact_RequireKeyItem intUseKeyItem = LinkedDoorLocks.m_intUseKeyItem; ((Component)intUseKeyItem).transform.position = (active ? _SavedIntUseKeyPos : BEGONE); ((Interact_Base)intUseKeyItem).SetActive(active); } public void SetHackingInteractActive(bool active) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Interact_Hack intHack = LinkedDoorLocks.m_intHack; ((Component)intHack).transform.position = (active ? _SavedIntHackPos : BEGONE); ((Interact_Base)intHack).SetActive(active); } public void SetCustomMessageActive(bool active) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Interact_MessageOnScreen intCustomMessage = LinkedDoorLocks.m_intCustomMessage; ((Component)intCustomMessage).transform.position = (active ? _SavedIntCustomMessagePos : BEGONE); ((Interact_Base)intCustomMessage).SetActive(active); } public void OpenOrStartChainPuzzle() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) ChainedPuzzleInstance chainedPuzzleToSolve = LinkedDoorLocks.ChainedPuzzleToSolve; if ((Object)(object)chainedPuzzleToSolve != (Object)null && !chainedPuzzleToSolve.IsSolved) { LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)4, 0f, 0f, default(Vector3), (Agent)null); } else { LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null); } } public void ForceOpenDoor(float delay) { if (delay > 0f) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(OpenDoorWithDelay(delay)), (Action)null); } else { ForceOpenDoor(); } } private IEnumerator OpenDoorWithDelay(float delay) { yield return (object)new WaitForSeconds(delay); LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null); } public void ForceOpenDoor() { //IL_0018: 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) LinkedDoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null); } private void Setup_DoorInteractModule() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_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_0047: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) _SavedIntOpenDoorPos = ((Component)LinkedDoorLocks.m_intOpenDoor).transform.position; _SavedIntUseKeyPos = ((Component)LinkedDoorLocks.m_intUseKeyItem).transform.position; _SavedIntCustomMessagePos = ((Component)LinkedDoorLocks.m_intCustomMessage).transform.position; _SavedIntHackPos = ((Component)LinkedDoorLocks.m_intHack).transform.position; } private void Setup_DoorStateModule() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) StateBehaviour = new SDT_StateBehaviour(); LinkedDoor.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)OnStateChange); LinkedDoorLocks.OnChainedPuzzleSolved += Action.op_Implicit((Action)OnChainedPuzzleSolved); OnStateChange(LinkedDoor.m_sync.GetCurrentSyncState(), isRecall: false); } private void OnChainedPuzzleSolved() { switch (BioscanScanSolvedBehaviour) { case CPSolvedBehaviour.OpenDoor: if (SNet.IsMaster) { ForceOpenDoor(0.25f); } break; case CPSolvedBehaviour.AddOpenCommand: CmdProcessor.AddOutput((TerminalLineType)5, "Bioscan Sequence Completed - <color=orange>" + OpenCommandName + "</color> Command is now accessible!", 0f, (TerminalSoundType)0, (TerminalSoundType)0); AddOpenCommand(OpenCommandName, OpenCommandDescription); break; } } private void OnStateChange(pDoorState state, bool isRecall) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (StateBehaviour != null) { ActiveEnemyWaveData activeEnemyWaveData = LinkedDoor.ActiveEnemyWaveData; bool isBloodyDoor = activeEnemyWaveData != null && activeEnemyWaveData.HasActiveEnemyWave; SecDoorState secDoorState = default(SecDoorState); secDoorState.Status = state.status; secDoorState.State = state; secDoorState.IsBloodyDoor = isBloodyDoor; SecDoorState state2 = secDoorState; StateBehaviour.UpdateInteractionState(state2, isRecall); StateBehaviour.UpdateGraphicState(state2, isRecall); } } private void Setup_GraphicModule() { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ForceScreenOffOnDeactive()), (Action)null); } private IEnumerator ForceScreenOffOnDeactive() { while (true) { if (IsTerminalActive) { ((Behaviour)ComputerTerminal.m_text).enabled = true; } else { ((Behaviour)ComputerTerminal.m_text).enabled = false; ComputerTerminal.m_loginScreen.SetActive(true); ComputerTerminal.m_interfaceScreen.SetActive(true); } yield return null; } } public void SetIdleIconColor(Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) IdleIcon.color = color; } public void SetIdleText(string text) { ((TMP_Text)IdleText).text = text; } public void SetIdleTextFontSize(float size) { ((TMP_Text)IdleText).fontSize = size; } public static SecDoorTerminal Place(LG_SecurityDoor secDoor, TerminalStartStateData startData = null, TerminalPlacementData placementData = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) if ((int)secDoor.m_securityDoorType != 0) { return null; } Transform val = CustomExtensions.FindChildRecursive(((Component)secDoor).transform, "InteractionInterface", true); if ((Object)(object)val == (Object)null) { return null; } ((Component)val).gameObject.SetActiveRecursively(false); ((Component)val).gameObject.SetActive(true); GameObject obj = Object.Instantiate<GameObject>(Assets.SecDoorTerminalPrefab, val); obj.transform.localPosition = (((int)secDoor.Gate.Type == 0) ? new Vector3(0f, -0.006f, 0f) : new Vector3(0f, -0.026f, 0f)); obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one; iTerminalItem componentInChildren = obj.GetComponentInChildren<iTerminalItem>(); if (componentInChildren != null && TryGetSecDoorSpawnedNode(secDoor, out var spawnedNode)) { componentInChildren.SpawnNode = spawnedNode; } LG_ComputerTerminal component = obj.GetComponent<LG_ComputerTerminal>(); component.Setup(startData, placementData); MeshFilter[] array = Il2CppArrayBase<MeshFilter>.op_Implicit(((Component)secDoor).GetComponentsInChildren<MeshFilter>(true)); foreach (MeshFilter val2 in array) { if (!((Object)(object)val2.sharedMesh == (Object)null)) { string name = ((Object)val2.sharedMesh).name; if (!string.IsNullOrEmpty(name) && name.Equals("g_security_door_display")) { Transform transform = ((Component)val2).gameObject.transform; transform.localPosition += BEGONE; } } } SecDoorTerminal secDoorTerminal = new SecDoorTerminal(); secDoorTerminal.LinkedDoor = secDoor; secDoorTerminal.LinkedDoorLocks = ((Il2CppObjectBase)secDoor.m_locks).Cast<LG_SecurityDoor_Locks>(); secDoorTerminal.ComputerTerminal = component; secDoorTerminal.CmdProcessor = component.m_command; secDoorTerminal.Interaction = ((Component)component).GetComponentInChildren<Interact_ComputerTerminal>(true); secDoorTerminal.IdleIcon = component.m_loginScreen.GetComponent<SpriteRenderer>(); secDoorTerminal.IdleText = component.m_loginScreen.GetComponentInChildren<TextMeshPro>(); secDoorTerminal.Setup(); return secDoorTerminal; } private static bool TryGetSecDoorSpawnedNode(LG_SecurityDoor secDoor, out AIG_CourseNode spawnedNode) { if ((Object)(object)secDoor == (Object)null) { spawnedNode = null; return false; } if ((Object)(object)secDoor.Gate == (Object)null) { spawnedNode = null; return false; } if ((Object)(object)((LG_ZoneExpander)secDoor.Gate).m_linksFrom == (Object)null) { spawnedNode = null; return false; } spawnedNode = ((LG_ZoneExpander)secDoor.Gate).m_linksFrom.m_courseNode; return spawnedNode != null; } } public class SDT_StateBehaviour { public SecDoorTerminal Context { get; private set; } internal void SetContext(SecDoorTerminal secDoorTerminal) { Context = secDoorTerminal; } public virtual void UpdateInteractionState(SecDoorState state, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected I4, but got Unknown eDoorStatus status = state.Status; switch ((int)status) { case 0: case 1: case 2: case 4: case 5: case 7: case 9: case 12: case 13: case 14: Context.SetTerminalActive(active: true); Context.SetOpenInteractActive(active: false); Context.SetHackingInteractActive(active: false); Context.SetUseKeyInteractActive(active: false); Context.SetCustomMessageActive(active: false); break; case 3: Context.SetTerminalActive(active: false); Context.SetOpenInteractActive(active: false); Context.SetHackingInteractActive(active: false); Context.SetUseKeyInteractActive(active: true); Context.SetCustomMessageActive(active: false); break; case 6: case 15: Context.SetTerminalActive(active: false); Context.SetOpenInteractActive(active: false); Context.SetHackingInteractActive(active: false); Context.SetUseKeyInteractActive(active: false); Context.SetCustomMessageActive(active: true); break; case 8: case 10: case 11: case 16: Context.SetTerminalActive(active: false); Context.SetOpenInteractActive(active: false); Context.SetHackingInteractActive(active: false); Context.SetUseKeyInteractActive(active: false); Context.SetCustomMessageActive(active: false); break; } } public virtual void UpdateGraphicState(SecDoorState state, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) eDoorStatus status = state.Status; string text; Color? val; switch (status - 1) { case 14: text = "::<color=orange>Bulkhead Override</color> Required::"; val = Color.yellow; break; case 2: text = "::<color=orange>Keycard</color> Required::"; val = Color.red; break; case 4: text = "<color=orange>BIOSCAN Protocol</color> pending..."; val = Color.cyan; break; case 3: text = "<color=orange>BIOSCAN Protocol</color> pending..."; val = Color.red; break; case 5: text = "BOOT ERR://Power Level - <color=red>LOW</color>"; val = ColorExt.Hex("#FFA500"); break; case 6: text = "<color=orange>LOCKDOWN Protocol</color> engaged!"; val = Color.red; break; case 7: if (Context.LinkedDoorLocks.ChainedPuzzleToSolve.Data.TriggerAlarmOnActivate) { text = "<color=red>BIOSCAN Protocol</color> processing!"; val = Color.red; } else { text = "<color=blue>BIOSCAN Protocol</color> processing!"; val = Color.cyan; } break; case 9: case 15: text = "::DOOR OVERRIDING::"; val = Color.cyan; break; case 0: text = "::DOOR LOCKING::"; val = Color.cyan; break; default: text = "Waiting..."; val = Color.green; break; } if (val.HasValue) { Context.SetIdleIconColor(val.Value); } if (text != null) { Context.SetIdleText(text); } } } public struct SecDoorState { public eDoorStatus Status; public pDoorState State; public bool IsBloodyDoor; } [GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "SecDoorTerminalInterface"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "git6952937-master"; public const string SemVer = "1.0.0+git6952937-master"; public const string GitRevShort = "6952937"; public const string GitRevLong = "69529374dcbe6b589a13bfc0c363675c5cd3e803"; public const string GitBranch = "master"; public const string GitTag = null; public const int GitCommitsSinceTag = 0; public const bool GitIsDirty = false; } } namespace SecDoorTerminalInterface.Inject { [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] internal class Inject_Terminal_ReceiveCmd { public static event Action<LG_ComputerTerminalCommandInterpreter, TERM_Command, string, string, string> OnCmdUsed_LevelInstanced; static Inject_Terminal_ReceiveCmd() { LevelAPI.OnLevelCleanup += delegate { Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced = null; }; } private static void Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced?.Invoke(__instance, cmd, inputLine, param1, param2); } } }
plugins/net6/WeaponStatShower.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using GameData; using Gear; using HarmonyLib; using Localization; using Microsoft.CodeAnalysis; using Player; using UnityEngine; using WeaponStatShower.Patches; using WeaponStatShower.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("WeaponStatShower")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("WeaponStatShower")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("052b6857-9abd-4300-b5bd-ceb4b0c295db")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [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 WeaponStatShower { public static class BIEExtensions { public static ConfigEntry<T> GetConfigEntry<T>(this ConfigFile configFile, ConfigDefinition definition) { ConfigEntry<T> result = default(ConfigEntry<T>); if (!configFile.TryGetEntry<T>(definition, ref result)) { throw new InvalidOperationException("Config entry has not been added yet."); } return result; } } [BepInPlugin("WeaponStatShower", "Weapon Stat Shower", "1.2.0")] [BepInProcess("GTFO.exe")] public class WeaponStatShowerPlugin : BasePlugin { internal const string ModName = "Weapon Stat Shower"; internal const string GUID = "WeaponStatShower"; private const string SectionMain = "Config"; private static readonly ConfigDefinition configDefinition = new ConfigDefinition("Config", "Version"); private static readonly ConfigDefinition ConfigGameVersion = new ConfigDefinition("Config", "GameVersion"); private static Harmony HarmonyInstance; private static readonly Dictionary<Type, Patch> RegisteredPatches = new Dictionary<Type, Patch>(); public static WeaponStatShowerPlugin Instance { get; private set; } public WeaponStatShowerPlugin() { ((BasePlugin)this).Config.SaveOnConfigSet = false; } public override void Load() { Instance = this; ((BasePlugin)this).Config.SaveOnConfigSet = true; LogInfo("STARTED"); RegisterPatch<ShowStat>(); ((BasePlugin)this).Config.Save(); } public static void RegisterPatch<T>() where T : Patch, new() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (HarmonyInstance == null) { HarmonyInstance = new Harmony("WeaponStatShower"); } if (RegisteredPatches.ContainsKey(typeof(T))) { LogDebug("Ignoring duplicate patch: " + typeof(T).Name); return; } T val = new T { Harmony = HarmonyInstance }; val.Initialize(); if (val.Enabled) { LogInfo("Applying patch: " + val.Name); val.Execute(); } RegisteredPatches[typeof(T)] = val; } public static void LogDebug(object data) { ((BasePlugin)Instance).Log.LogDebug(data); } public static void LogError(object data) { ((BasePlugin)Instance).Log.LogError(data); } public static void LogFatal(object data) { ((BasePlugin)Instance).Log.LogFatal(data); } public static void LogInfo(object data) { ((BasePlugin)Instance).Log.LogInfo(data); } public static void LogMessage(object data) { ((BasePlugin)Instance).Log.LogMessage(data); } public static void LogWarning(object data) { ((BasePlugin)Instance).Log.LogWarning(data); } } } namespace WeaponStatShower.Utils { internal class SleepersDatas { private readonly Dictionary<string, float[]> EnemyDatas = new Dictionary<string, float[]>(); public SleepersDatas(string[] activatedSleepers) { foreach (string text in activatedSleepers) { switch (text.Trim()) { case "NONE": EnemyDatas.Clear(); return; case "ALL": EnemyDatas.TryAdd("STRK", new float[4] { 20f, 3f, 2f, 0f }); EnemyDatas.TryAdd("SHTR", new float[4] { 30f, 5f, 2f, 0f }); EnemyDatas.TryAdd("SCOUT", new float[4] { 42f, 3f, 2f, 0f }); EnemyDatas.TryAdd("B-STRK", new float[4] { 120f, 1.5f, 2f, 0f }); EnemyDatas.TryAdd("B-SHTR", new float[4] { 150f, 2f, 2f, 0f }); EnemyDatas.TryAdd("CHRG", new float[4] { 30f, 1f, 2f, 1f }); EnemyDatas.TryAdd("C-SCOUT", new float[4] { 60f, 1f, 2f, 1f }); return; case "STRIKER": EnemyDatas.TryAdd("STRK", new float[4] { 20f, 3f, 2f, 0f }); break; case "SHOOTER": EnemyDatas.TryAdd("SHTR", new float[4] { 30f, 5f, 2f, 0f }); break; case "SCOUT": EnemyDatas.TryAdd("SCOUT", new float[4] { 42f, 3f, 2f, 0f }); break; case "BIG_STRIKER": EnemyDatas.TryAdd("B-STRK", new float[4] { 120f, 1.5f, 2f, 0f }); break; case "BIG_SHOOTER": EnemyDatas.TryAdd("B-SHTR", new float[4] { 150f, 2f, 2f, 0f }); break; case "CHARGER": EnemyDatas.TryAdd("CHRG", new float[4] { 30f, 1f, 2f, 1f }); break; case "CHARGER_SCOUT": EnemyDatas.TryAdd("C-SCOUT", new float[4] { 60f, 1f, 2f, 1f }); break; default: WeaponStatShowerPlugin.LogWarning("You inserted an incorrect value in the config: " + text.Trim()); break; } } } public string VerboseKill(ArchetypeDataBlock archetypeDataBlock) { StringBuilder stringBuilder = new StringBuilder(); float damage = archetypeDataBlock.Damage * (float)((archetypeDataBlock.ShotgunBulletCount <= 0) ? 1 : archetypeDataBlock.ShotgunBulletCount); float precisionDamageMulti = archetypeDataBlock.PrecisionDamageMulti; int num = 0; for (int i = 0; i < EnemyDatas.Count; i++) { string text = EnemyDatas.Keys.ElementAt(i); List<char> list = new List<char>(); float[] currEnemyDatas = EnemyDatas[text]; if (canKillOnOccipit(damage, precisionDamageMulti, currEnemyDatas)) { list.Add('o'); } if (canKillOnHead(damage, precisionDamageMulti, currEnemyDatas)) { list.Add('h'); } if (canKillOnBack(damage, precisionDamageMulti, currEnemyDatas)) { list.Add('b'); } if (canKillOnChest(damage, currEnemyDatas)) { list.Add('c'); } if (list.Count > 0) { if (num % 2 == 1) { stringBuilder.Append(" | "); } list.Reverse(); stringBuilder.Append(text + ": [" + string.Join(",", list.ToArray()) + "]"); if (num++ % 2 == 1 && i != EnemyDatas.Count - 1) { stringBuilder.Append('\n'); } } } return stringBuilder.ToString(); } internal string? VerboseKill(MeleeArchetypeDataBlock archeTypeDataBlock) { StringBuilder stringBuilder = new StringBuilder(); float num = archeTypeDataBlock.ChargedAttackDamage * archeTypeDataBlock.ChargedSleeperMulti; float chargedPrecisionMulti = archeTypeDataBlock.ChargedPrecisionMulti; int num2 = 0; for (int i = 0; i < EnemyDatas.Count; i++) { string text = EnemyDatas.Keys.ElementAt(i); if (text.Contains("SCOUT")) { num /= archeTypeDataBlock.ChargedSleeperMulti; } List<char> list = new List<char>(); float[] currEnemyDatas = EnemyDatas[text]; if (canKillOnOccipit(num, chargedPrecisionMulti, currEnemyDatas)) { list.Add('o'); } if (canKillOnHead(num, chargedPrecisionMulti, currEnemyDatas)) { list.Add('h'); } if (canKillOnBack(num, chargedPrecisionMulti, currEnemyDatas)) { list.Add('b'); } if (canKillOnChest(num, currEnemyDatas)) { list.Add('c'); } if (list.Count > 0) { if (num2 % 2 == 1) { stringBuilder.Append(" | "); } list.Reverse(); stringBuilder.Append(text + ": [" + string.Join(",", list.ToArray()) + "]"); if (num2++ % 2 == 1 && i != EnemyDatas.Count - 1) { stringBuilder.Append('\n'); } } } return stringBuilder.ToString(); } private bool canKillOnChest(float damage, float[] currEnemyDatas) { if (isArmored(currEnemyDatas)) { return (double)damage * 0.7 >= (double)currEnemyDatas[0]; } return damage >= currEnemyDatas[0]; } private bool canKillOnBack(float damage, float prcsnMultiplier, float[] currEnemyDatas) { if (isArmored(currEnemyDatas)) { return damage * prcsnMultiplier * currEnemyDatas[2] >= currEnemyDatas[0]; } return damage * currEnemyDatas[2] >= currEnemyDatas[0]; } private bool canKillOnHead(float damage, float prcsnMultiplier, float[] currEnemyDatas) { if (isArmored(currEnemyDatas)) { return (double)damage * 0.7 * (double)currEnemyDatas[1] >= (double)currEnemyDatas[0]; } return damage * prcsnMultiplier * currEnemyDatas[1] >= currEnemyDatas[0]; } private bool canKillOnOccipit(float damage, float prcsnMultiplier, float[] currEnemyDatas) { if (isArmored(currEnemyDatas)) { return (double)damage * 0.7 * (double)currEnemyDatas[2] * (double)currEnemyDatas[1] >= (double)currEnemyDatas[0]; } return damage * prcsnMultiplier * currEnemyDatas[2] * currEnemyDatas[1] >= currEnemyDatas[0]; } private bool isArmored(float[] currEnemyDatas) { return currEnemyDatas[3] == 1f; } } internal class WeaponDescriptionBuilder { private SleepersDatas sleepersDatas; private uint categoryID; private GearCategoryDataBlock gearCatBlock; private ItemDataBlock itemDataBlock; private const string DIVIDER = " | "; private const string CLOSE_COLOR_TAG = "</color>"; private PlayerDataBlock _playerDataBlock { get; set; } private GearIDRange idRange { get; set; } private static string Short_MeleeLight { get; } = ".Lgt"; private static string Short_MeleeCharged { get; } = ".Hvy"; private static string Short_MeleeCanRunWhileCharging { get; } = "Run"; private static string Short_MeleeSleepingEnemiesMultiplier { get; } = "Slp"; private static string Short_EnvironmentMultiplier { get; } = "Env"; private static string Short_Damage { get; } = "Dmg"; private static string Short_Clip { get; } = "Clp"; private static string Short_MaxAmmo { get; } = "Max"; private static string Short_Falloff { get; } = "Dist"; private static string Short_Reload { get; } = "Rld"; private static string Short_Stagger { get; } = "Stgr"; private static string Short_Precision { get; } = "Prcn"; private static string Short_PierceCount { get; } = "Pierc"; private static string Short_RateOfFire { get; } = "RoF"; private static string Short_AimSpread { get; } = "ADS"; private static string Short_HipSpread { get; } = "HIP"; public void UpdateSleepersDatas(string[] activatedSleepers) { if (activatedSleepers[0].Length == 0) { WeaponStatShowerPlugin.LogWarning("Empty String in the config file, applying Default values"); activatedSleepers = new string[3] { "STRIKER", "SHOOTER", "SCOUT" }; } sleepersDatas = new SleepersDatas(activatedSleepers); } public string DescriptionFormatter(string GearDescription) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((int)itemDataBlock.inventorySlot == 10) { MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatBlock)); GearDescription = VerboseDescriptionFormatter(block); return GearDescription + "\n\n" + GetFormatedWeaponStats(block, itemDataBlock); } eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1); bool flag = categoryID == 12; ArchetypeDataBlock val2 = (flag ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val))); if (val2 == null) { return GearDescription; } GearDescription = VerboseDescriptionFormatter(val2, flag); return GearDescription + GetFormatedWeaponStats(val2, flag); } internal string FireRateFormatter(string gearPublicName) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((int)itemDataBlock.inventorySlot == 10) { MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatBlock)); return VerbosePublicNameMelee(block); } eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1); ArchetypeDataBlock val2 = ((categoryID == 12) ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val))); if (val2 == null) { return gearPublicName; } return VerbosePublicNameFireMode(val2); } private string VerbosePublicNameMelee(MeleeArchetypeDataBlock meleeArchetypeDataBlock) { return ((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)meleeArchetypeDataBlock).persistentID switch { 1u => "Hammer - Balanced", 2u => "Knife - Fast", 4u => "Bat - Fast", 3u => "Spear - Slow", _ => "", }; } private string VerbosePublicNameFireMode(ArchetypeDataBlock archetypeDataBlock) { //IL_0008: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected I4, but got Unknown StringBuilder stringBuilder = new StringBuilder(); eWeaponFireMode fireMode = archetypeDataBlock.FireMode; eWeaponFireMode val = fireMode; switch ((int)val) { case 2: case 11: stringBuilder.Append("Full-A ("); stringBuilder.Append("<#12FF50>"); stringBuilder.Append(Short_RateOfFire + " "); stringBuilder.Append(GetRateOfFire(archetypeDataBlock)); stringBuilder.Append("</color>"); stringBuilder.Append(")"); break; case 0: case 10: stringBuilder.Append("Semi-A ("); stringBuilder.Append("<#12FF50>"); stringBuilder.Append(Short_RateOfFire + " "); stringBuilder.Append(GetRateOfFire(archetypeDataBlock)); stringBuilder.Append("</color>"); stringBuilder.Append(")"); break; case 1: case 12: if (archetypeDataBlock.BurstShotCount != 1) { stringBuilder.Append("Burst ("); stringBuilder.Append("<#704dfa>"); stringBuilder.Append("#" + archetypeDataBlock.BurstShotCount); stringBuilder.Append("</color>"); stringBuilder.Append(" | "); stringBuilder.Append("<#12FF50>"); stringBuilder.Append(Short_RateOfFire + " "); stringBuilder.Append(GetRateOfFire(archetypeDataBlock)); stringBuilder.Append("</color>"); stringBuilder.Append(")"); } else { stringBuilder.Append("Semi-A ("); stringBuilder.Append("<#12FF50>"); stringBuilder.Append(Short_RateOfFire + " "); stringBuilder.Append(GetRateOfFire(archetypeDataBlock)); stringBuilder.Append("</color>"); stringBuilder.Append(")"); } break; case 3: stringBuilder.Append("S-Burst ("); stringBuilder.Append("<#12FF50>"); stringBuilder.Append("#" + archetypeDataBlock.BurstShotCount); stringBuilder.Append(" every " + archetypeDataBlock.SpecialSemiBurstCountTimeout + "'"); stringBuilder.Append("</color>"); stringBuilder.Append(")"); break; case 13: stringBuilder.Append("Shotgun-S ("); stringBuilder.Append("<#12FF50>"); stringBuilder.Append(Short_RateOfFire + " "); stringBuilder.Append(GetRateOfFire(archetypeDataBlock)); stringBuilder.Append("</color>"); stringBuilder.Append(")"); break; default: WeaponStatShowerPlugin.LogError("FireMode not found"); break; } return stringBuilder.ToString(); } private string VerboseDescriptionFormatter(MeleeArchetypeDataBlock meleeArchetypeDataBlock) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(((double)meleeArchetypeDataBlock.CameraDamageRayLength < 1.76) ? "Short Range" : (((double)meleeArchetypeDataBlock.CameraDamageRayLength < 2.5) ? "Medium Range" : "Long Range")); stringBuilder.Append(meleeArchetypeDataBlock.CanHitMultipleEnemies ? "Piercing\n" : ""); return "".Equals(stringBuilder.ToString()) ? "" : (stringBuilder.ToString() + "\n"); } private string VerboseDescriptionFormatter(ArchetypeDataBlock archetypeDataBlock, bool isSentryGun) { StringBuilder stringBuilder = new StringBuilder(); if (isSentryGun) { stringBuilder.AppendLine("Deployable"); } switch (archetypeDataBlock.ShotgunBulletSpread + archetypeDataBlock.ShotgunConeSize) { case 1: stringBuilder.AppendLine("Chocked Spread"); break; case 4: stringBuilder.AppendLine("Small Spread"); break; case 5: stringBuilder.AppendLine("Medium Spread"); break; case 7: stringBuilder.AppendLine("Large Spread"); break; case 9: stringBuilder.AppendLine("Huge Spread"); break; default: WeaponStatShowerPlugin.LogError(LocalizedText.op_Implicit(archetypeDataBlock.PublicName) + ": spread not considered{" + archetypeDataBlock.ShotgunBulletSpread + "/" + archetypeDataBlock.ShotgunConeSize + "}"); break; case 0: break; } if (archetypeDataBlock.SpecialChargetupTime > 0f) { stringBuilder.AppendLine(((double)archetypeDataBlock.SpecialChargetupTime > 0.4) ? ("Long Charge-up (" + FormatFloat(archetypeDataBlock.SpecialChargetupTime, 2) + ")") : ("Short Charge-up (" + FormatFloat(archetypeDataBlock.SpecialChargetupTime, 2) + ")")); } return "".Equals(stringBuilder.ToString()) ? "" : (stringBuilder.ToString() + "\n"); } private string GetFormatedWeaponStats(ArchetypeDataBlock archeTypeDataBlock, bool isSentryGun = false) { //IL_02dc: Unknown result type (might be due to invalid IL or missing references) if (archeTypeDataBlock == null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); int num = 0; stringBuilder.Append("<#9D2929>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendLiteral(" "); stringBuilder3.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.Damage, 2)); stringBuilder.Append((archeTypeDataBlock.ShotgunBulletCount > 0) ? ("(x" + archeTypeDataBlock.ShotgunBulletCount + ")") : ""); stringBuilder.Append("</color>"); num++; if (!isSentryGun) { stringBuilder.Append(" | "); stringBuilder.Append("<color=orange>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Clip); handler.AppendLiteral(" "); stringBuilder4.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.DefaultClipSize); stringBuilder.Append("</color>"); num++; } stringBuilder.Append(" | "); stringBuilder.Append("<#FFD306>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_MaxAmmo); handler.AppendLiteral(" "); stringBuilder5.Append(ref handler); stringBuilder.Append(GetTotalAmmo(archeTypeDataBlock, itemDataBlock, isSentryGun)); stringBuilder.Append("</color>"); num++; if (!isSentryGun) { stringBuilder.Append(" | "); stringBuilder.Append("<#C0FF00>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Reload); handler.AppendLiteral(" "); stringBuilder6.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.DefaultReloadTime, 2)); stringBuilder.Append("</color>"); num++; } if (archeTypeDataBlock.PrecisionDamageMulti != 1f) { Divider(ref num, stringBuilder); stringBuilder.Append("<#18A4A9>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendLiteral(" "); stringBuilder7.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.PrecisionDamageMulti, 2)); stringBuilder.Append("</color>"); num++; } Divider(ref num, stringBuilder); stringBuilder.Append("<#6764de>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Falloff); handler.AppendLiteral(" "); stringBuilder8.Append(ref handler); stringBuilder.Append((int)archeTypeDataBlock.DamageFalloff.x + "m"); stringBuilder.Append("</color>"); num++; if (archeTypeDataBlock.StaggerDamageMulti != 1f) { Divider(ref num, stringBuilder); stringBuilder.Append("<color=green>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendLiteral(" "); stringBuilder9.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.StaggerDamageMulti, 2)); stringBuilder.Append("</color>"); num++; } if (archeTypeDataBlock.HipFireSpread != 0f && archeTypeDataBlock.ShotgunBulletCount == 0) { Divider(ref num, stringBuilder); stringBuilder.Append("<#cc9347>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_HipSpread); handler.AppendLiteral(" "); stringBuilder10.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.HipFireSpread, 2)); stringBuilder.Append("</color>"); num++; } if (archeTypeDataBlock.AimSpread != 0f && archeTypeDataBlock.ShotgunBulletCount == 0) { Divider(ref num, stringBuilder); stringBuilder.Append("<#e6583c>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_AimSpread); handler.AppendLiteral(" "); stringBuilder11.Append(ref handler); stringBuilder.Append(FormatFloat(archeTypeDataBlock.AimSpread, 2)); stringBuilder.Append("</color>"); num++; } if (archeTypeDataBlock.PiercingBullets) { Divider(ref num, stringBuilder); stringBuilder.Append("<#097345>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_PierceCount); handler.AppendLiteral(" "); stringBuilder12.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.PiercingDamageCountLimit); stringBuilder.Append("</color>"); num++; } stringBuilder.AppendLine("\n"); stringBuilder.Append(sleepersDatas.VerboseKill(archeTypeDataBlock)); return stringBuilder.ToString(); static void Divider(ref int count, StringBuilder builder) { if (count >= 4) { builder.Append("\n"); count = 0; } else if (count > 0) { builder.Append(" | "); } } } private string GetFormatedWeaponStats(MeleeArchetypeDataBlock archeTypeDataBlock, ItemDataBlock itemDataBlock) { if (archeTypeDataBlock == null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<#9D2929>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder3.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.LightAttackDamage); stringBuilder.Append("</color>"); stringBuilder.Append(" | "); stringBuilder.Append("<color=orange>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder4.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.ChargedAttackDamage); stringBuilder.Append("</color>"); int count2 = 2; if (!archeTypeDataBlock.AllowRunningWhenCharging) { stringBuilder.Append(" | "); stringBuilder.Append("<#FFD306>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_MeleeCanRunWhileCharging); handler.AppendLiteral(" "); stringBuilder5.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.AllowRunningWhenCharging); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.LightStaggerMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#C0FF00>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder6.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.LightStaggerMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.ChargedStaggerMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<color=green>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder7.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.ChargedStaggerMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.LightPrecisionMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#004E2C>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder8.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.LightPrecisionMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.ChargedPrecisionMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#55022B>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder9.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.ChargedPrecisionMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.LightSleeperMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#A918A7>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder10.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.LightSleeperMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.ChargedSleeperMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#025531>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder11.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.ChargedSleeperMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.LightEnvironmentMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#18A4A9>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_EnvironmentMultiplier); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder12.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.LightEnvironmentMulti); stringBuilder.Append("</color>"); count2++; } if (archeTypeDataBlock.ChargedEnvironmentMulti != 1f) { Divider(ref count2, stringBuilder); stringBuilder.Append("<#75A2AA>"); stringBuilder2 = stringBuilder; StringBuilder stringBuilder13 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_EnvironmentMultiplier); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder13.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.ChargedEnvironmentMulti); stringBuilder.Append("</color>"); count2++; } stringBuilder.AppendLine("\n"); stringBuilder.Append(sleepersDatas.VerboseKill(archeTypeDataBlock)); return stringBuilder.ToString(); static void Divider(ref int count, StringBuilder builder) { if (count >= 3) { builder.Append("\n"); count = 0; } else if (count > 0) { builder.Append(" | "); } } } private static float FormatFloat(float value, int v) { return (float)Math.Round((decimal)value, v); } private int GetAmmoMax(ItemDataBlock itemDataBlock) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown AmmoType ammoTypeFromSlot = PlayerAmmoStorage.GetAmmoTypeFromSlot(itemDataBlock.inventorySlot); AmmoType val = ammoTypeFromSlot; AmmoType val2 = val; return (int)val2 switch { 0 => _playerDataBlock.AmmoStandardMaxCap, 1 => _playerDataBlock.AmmoSpecialMaxCap, 2 => _playerDataBlock.AmmoClassMaxCap, 5 => itemDataBlock.ConsumableAmmoMax, _ => -1, }; } private int GetTotalAmmo(ArchetypeDataBlock archetypeDataBlock, ItemDataBlock itemDataBlock, bool isSentryGun = false) { int ammoMax = GetAmmoMax(itemDataBlock); float num = archetypeDataBlock.CostOfBullet; if (isSentryGun) { num *= itemDataBlock.ClassAmmoCostFactor; if ((float)archetypeDataBlock.ShotgunBulletCount > 0f) { num *= (float)archetypeDataBlock.ShotgunBulletCount; } } int num2 = (int)((float)ammoMax / num); if (isSentryGun) { return num2; } return num2 + archetypeDataBlock.DefaultClipSize; } private string GetRateOfFire(ArchetypeDataBlock archetypeDataBlock) { //IL_0008: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 float value = -1f; eWeaponFireMode fireMode = archetypeDataBlock.FireMode; eWeaponFireMode val = fireMode; switch ((int)val) { default: if ((int)val != 12) { if ((int)val != 13) { break; } goto case 0; } goto case 1; case 0: case 2: value = 1f / (archetypeDataBlock.ShotDelay + archetypeDataBlock.SpecialChargetupTime); break; case 1: if (archetypeDataBlock.BurstShotCount != 1) { float num = 1f / (archetypeDataBlock.BurstDelay + archetypeDataBlock.SpecialChargetupTime + archetypeDataBlock.ShotDelay * (float)(archetypeDataBlock.BurstShotCount - 1)); value = num * (float)archetypeDataBlock.BurstShotCount; } else { value = 1f / (archetypeDataBlock.ShotDelay + archetypeDataBlock.SpecialChargetupTime); } break; } return FormatFloat(value, 1).ToString(); } internal void Inizialize(GearIDRange idRange, PlayerDataBlock playerDataBlock) { this.idRange = idRange; _playerDataBlock = playerDataBlock; categoryID = idRange.GetCompID((eGearComponent)2); gearCatBlock = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(categoryID); itemDataBlock = GameDataBlockBase<ItemDataBlock>.GetBlock(gearCatBlock.BaseItem); } } } namespace WeaponStatShower.Patches { public abstract class Patch { protected internal Harmony? Harmony { get; set; } public virtual string Name { get; } public virtual bool Enabled => true; public virtual void Initialize() { } public abstract void Execute(); public void PatchConstructor<TClass>(PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class { PatchConstructor<TClass>(null, patchType, prefixMethodName, postfixMethodName); } public void PatchConstructor<TClass>(Type[]? parameters, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class { ConstructorInfo methodBase = AccessTools.Constructor(typeof(TClass), parameters, false); PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName); } public void PatchMethod<TClass>(string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class { PatchMethod<TClass>(methodName, null, patchType, generics, prefixMethodName, postfixMethodName); } public void PatchMethod<TClass>(string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class { MethodInfo methodBase = AccessTools.Method(typeof(TClass), methodName, parameters, generics); PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName); } public void PatchMethod<TClass>(MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class { PatchMethod(typeof(TClass), methodBase, patchType, prefixMethodName, postfixMethodName); } public void PatchMethod(Type classType, string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) { PatchMethod(classType, methodName, null, patchType, generics, prefixMethodName, postfixMethodName); } public void PatchMethod(Type classType, string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) { MethodInfo methodBase = AccessTools.Method(classType, methodName, parameters, generics); PatchMethod(classType, methodBase, patchType, prefixMethodName, postfixMethodName); } public void PatchMethod(Type classType, MethodBase methodBase, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_0177: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown string text = classType.Name.Replace("`", "__"); string value = methodBase.ToString(); string text2 = (methodBase.IsConstructor ? "ctor" : methodBase.Name); MethodInfo methodInfo = null; MethodInfo methodInfo2 = null; if ((patchType & PatchType.Prefix) != 0) { try { methodInfo2 = AccessTools.Method(GetType(), prefixMethodName ?? (text + "__" + text2 + "__Prefix"), (Type[])null, (Type[])null); } catch (Exception value2) { LogFatal($"Failed to obtain the prefix patch method for {value}): {value2}"); } } if ((patchType & PatchType.Postfix) != 0) { try { methodInfo = AccessTools.Method(GetType(), postfixMethodName ?? (text + "__" + text2 + "__Postfix"), (Type[])null, (Type[])null); } catch (Exception value3) { LogFatal($"Failed to obtain the postfix patch method for {value}): {value3}"); } } try { if (methodInfo2 != null && methodInfo != null) { Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else if (methodInfo2 != null) { Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else if (methodInfo != null) { Harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception value4) { LogError($"Failed to patch method {value}: {value4}"); } } public void Log(LogLevel level, object data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExLogInterpolatedStringHandler val = new BepInExLogInterpolatedStringHandler(3, 2, level, ref flag); if (flag) { val.AppendLiteral("<"); val.AppendFormatted<string>(Name); val.AppendLiteral("> "); val.AppendFormatted<object>(data); } log.Log(level, val); } public void LogDebug(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogDebug(val); } public void LogError(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogError(val); } public void LogFatal(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExFatalLogInterpolatedStringHandler val = new BepInExFatalLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogFatal(val); } public void LogInfo(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogInfo(val); } public void LogMessage(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogMessage(val); } public void LogWarning(object data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)WeaponStatShowerPlugin.Instance).Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(3, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("<"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data); } log.LogWarning(val); } } [Flags] public enum PatchType : byte { Prefix = 1, Postfix = 2, Both = 3 } internal class ShowStat : Patch { private const string PatchName = "ShowStat"; private const PatchType patchType = PatchType.Postfix; private static readonly ConfigDefinition ConfigEnabled = new ConfigDefinition("ShowStat", "Enabled"); private static readonly ConfigDefinition ConfigSleepers = new ConfigDefinition("ShowStat", "SleepersShown"); private static string CurrShownSleepers; private static string PrevShownSleepers = "PLACEHOLDER"; private static WeaponDescriptionBuilder? _weaponDescriptionBuilder; public static Patch Instance { get; private set; } public override string Name { get; } = "ShowStat"; public override bool Enabled => ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.GetConfigEntry<bool>(ConfigEnabled).Value; public override void Initialize() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown Instance = this; ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<bool>(ConfigEnabled, true, new ConfigDescription("Show the stats of a weapon.", (AcceptableValueBase)null, Array.Empty<object>())); ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<string>(ConfigSleepers, "STRIKER, SHOOTER, SCOUT", new ConfigDescription("Select which Sleepers are shown, separeted by a comma.\nAcceptable values: ALL, NONE, STRIKER, SHOOTER, SCOUT, BIG_STRIKER, BIG_SHOOTER, CHARGER, CHARGER_SCOUT", (AcceptableValueBase)null, Array.Empty<object>())); _weaponDescriptionBuilder = new WeaponDescriptionBuilder(); } public override void Execute() { PatchMethod<CM_InventorySlotItem>("LoadData", PatchType.Postfix); } public static void CM_InventorySlotItem__LoadData__Postfix(CM_InventorySlotItem __instance, GearIDRange idRange, bool clickable, bool detailedInfo) { if ((Object)(object)__instance == (Object)null || !detailedInfo) { return; } if (_weaponDescriptionBuilder == null) { WeaponStatShowerPlugin.LogError("Something went wrong with the DescriptionBuilder"); return; } ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Reload(); CurrShownSleepers = ((BasePlugin)WeaponStatShowerPlugin.Instance).Config.GetConfigEntry<string>(ConfigSleepers).Value.Trim().ToUpper(); if (!PrevShownSleepers.Equals(CurrShownSleepers)) { _weaponDescriptionBuilder.UpdateSleepersDatas(CurrShownSleepers.Split(',')); PrevShownSleepers = CurrShownSleepers; } _weaponDescriptionBuilder.Inizialize(idRange, GameDataBlockBase<PlayerDataBlock>.GetBlock(1u)); __instance.GearDescription = _weaponDescriptionBuilder.DescriptionFormatter(__instance.GearDescription); __instance.GearPublicName = _weaponDescriptionBuilder.FireRateFormatter(__instance.GearPublicName); } } }
plugins/x64/Release/netstandard2.1/Oxygen.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.Json; using System.Text.Json.Serialization; using AK; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using GTFO.API; using GTFO.API.Utilities; using GameData; using GameEvent; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.Managers; using Microsoft.CodeAnalysis; using Oxygen.Components; using Oxygen.Config; using Oxygen.Utils; using Oxygen.Utils.PartialData; using Player; using SNetwork; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Oxygen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Oxygen")] [assembly: AssemblyTitle("Oxygen")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Oxygen { [BepInPlugin("Inas.Oxygen", "Oxygen", "1.3.2")] [BepInProcess("GTFO.exe")] [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 Plugin : BasePlugin { [CompilerGenerated] private static class <>O { public static Action <0>__OnBuildDone; public static Action <1>__OnLevelCleanup; public static Action <2>__Setup; public static Action <3>__OnLevelCleanup; public static Action <4>__OnBuildStart; public static Action <5>__OnLevelCleanup; public static LiveEditEventHandler <6>__Listener_FileChanged1; } public const string MODNAME = "Oxygen"; public const string AUTHOR = "Inas"; public const string GUID = "Inas.Oxygen"; public const string VERSION = "1.3.2"; public static readonly string OXYGEN_CONFIG_PATH = Path.Combine(ConfigManager.CustomPath, "Oxygen"); public static Dictionary<uint, OxygenBlock> lookup = new Dictionary<uint, OxygenBlock>(); private static LiveEditListener listener = null; public override void Load() { //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown if (!Directory.Exists(OXYGEN_CONFIG_PATH)) { Directory.CreateDirectory(OXYGEN_CONFIG_PATH); StreamWriter streamWriter = File.CreateText(Path.Combine(OXYGEN_CONFIG_PATH, "Template.json")); streamWriter.WriteLine(ConfigManager.Serialize(new OxygenConfig())); streamWriter.Flush(); streamWriter.Close(); } ClassInjector.RegisterTypeInIl2Cpp<AirManager>(); LevelAPI.OnBuildDone += AirManager.OnBuildDone; LevelAPI.OnLevelCleanup += AirManager.OnLevelCleanup; ClassInjector.RegisterTypeInIl2Cpp<AirBar>(); LevelAPI.OnBuildStart += AirBar.Setup; LevelAPI.OnLevelCleanup += AirBar.OnLevelCleanup; ClassInjector.RegisterTypeInIl2Cpp<AirPlane>(); LevelAPI.OnBuildStart += AirPlane.OnBuildStart; LevelAPI.OnLevelCleanup += AirPlane.OnLevelCleanup; new Harmony("Inas.Oxygen").PatchAll(); foreach (string item in Directory.EnumerateFiles(OXYGEN_CONFIG_PATH, "*.json", SearchOption.AllDirectories)) { ConfigManager.Load<OxygenConfig>(item, out var config); foreach (OxygenBlock block in config.Blocks) { foreach (uint fogSetting in block.FogSettings) { if (!lookup.ContainsKey(fogSetting)) { lookup.Add(fogSetting, block); } } } } listener = LiveEdit.CreateListener(OXYGEN_CONFIG_PATH, "*.json", true); LiveEditListener obj = listener; object obj2 = <>O.<6>__Listener_FileChanged1; if (obj2 == null) { LiveEditEventHandler val = Listener_FileChanged1; <>O.<6>__Listener_FileChanged1 = val; obj2 = (object)val; } obj.FileChanged += (LiveEditEventHandler)obj2; } private static void Listener_FileChanged1(LiveEditEventArgs e) { Log.Warning("LiveEdit File Changed: " + e.FullPath + "."); LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content) { foreach (OxygenBlock block in ConfigManager.Deserialize<OxygenConfig>(content).Blocks) { foreach (uint fogSetting in block.FogSettings) { if (lookup.ContainsKey(fogSetting)) { lookup.Remove(fogSetting); } lookup.Add(fogSetting, block); Log.Warning($"Replaced OxygenConfig for FogSetting: {fogSetting}."); } } if (GameStateManager.IsInExpedition) { AirManager.Current.UpdateAirConfig(AirManager.Current.FogSetting(), LiveEditForceUpdate: true); } }); } } } namespace Oxygen.Utils { internal static class Extension { public static T Instantiate<T>(this GameObject gameObject, string name) where T : Component { GameObject obj = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, false); ((Object)obj).name = name; return obj.GetComponent<T>(); } } internal class LocalizedTextConverter : JsonConverter<LocalizedText> { public override bool HandleNull => false; public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown switch (reader.TokenType) { case JsonTokenType.String: { string @string = reader.GetString(); return new LocalizedText { Id = 0u, UntranslatedText = @string }; } case JsonTokenType.Number: return new LocalizedText { Id = reader.GetUInt32(), UntranslatedText = null }; default: throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options) { JsonSerializer.Serialize<LocalizedText>(writer, value, options); } } internal static class Log { private static ManualLogSource source; static Log() { source = Logger.CreateLogSource("Oxygen"); } public static void Debug(object msg) { source.LogDebug(msg); } public static void Error(object msg) { source.LogError(msg); } public static void Fatal(object msg) { source.LogFatal(msg); } public static void Info(object msg) { source.LogInfo(msg); } public static void Message(object msg) { source.LogMessage(msg); } public static void Warning(object msg) { source.LogWarning(msg); } } } namespace Oxygen.Utils.PartialData { public static class MTFOPartialDataUtil { public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks"; public static JsonConverter PersistentIDConverter { get; private set; } public static JsonConverter LocalizedTextConverter { get; private set; } public static bool IsLoaded { get; private set; } public static bool Initialized { get; private set; } public static string PartialDataPath { get; private set; } public static string ConfigPath { get; private set; } static MTFOPartialDataUtil() { PersistentIDConverter = null; LocalizedTextConverter = null; IsLoaded = false; Initialized = false; PartialDataPath = string.Empty; ConfigPath = string.Empty; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type[] types = obj.GetTypes(); Type type = types.First((Type t) => t.Name == "PersistentIDConverter"); if ((object)type == null) { throw new Exception("Unable to Find PersistentIDConverter Class"); } Type type2 = types.First((Type t) => t.Name == "LocalizedTextConverter"); if ((object)type2 == null) { throw new Exception("Unable to Find LocalizedTextConverter Class"); } Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class"); PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public); PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public); PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public); if ((object)property == null) { throw new Exception("Unable to Find Property: Initialized"); } if ((object)property2 == null) { throw new Exception("Unable to Find Property: PartialDataPath"); } if ((object)property3 == null) { throw new Exception("Unable to Find Field: ConfigPath"); } Initialized = (bool)property.GetValue(null); PartialDataPath = (string)property2.GetValue(null); ConfigPath = (string)property3.GetValue(null); PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type); LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type2); IsLoaded = true; } catch (Exception value2) { Log.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}"); } } } public static class MTFOUtil { public const string PLUGIN_GUID = "com.dak.MTFO"; public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public; public static string GameDataPath { get; private set; } public static string CustomPath { get; private set; } public static bool HasCustomContent { get; private set; } public static bool IsLoaded { get; private set; } static MTFOUtil() { GameDataPath = string.Empty; CustomPath = string.Empty; HasCustomContent = false; IsLoaded = false; if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value)) { return; } try { Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null; if ((object)obj == null) { throw new Exception("Assembly is Missing!"); } Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class"); FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public); FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public); FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public); if ((object)field == null) { throw new Exception("Unable to Find Field: GameDataPath"); } if ((object)field2 == null) { throw new Exception("Unable to Find Field: CustomPath"); } if ((object)field3 == null) { throw new Exception("Unable to Find Field: HasCustomContent"); } GameDataPath = (string)field.GetValue(null); CustomPath = (string)field2.GetValue(null); HasCustomContent = (bool)field3.GetValue(null); IsLoaded = true; } catch (Exception value2) { Log.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}"); } } } } namespace Oxygen.Patches { [HarmonyPatch] internal class Patches_Dam_PlayerDamageLocal { [HarmonyPrefix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveNoAirDamage")] public static bool Pre_ReceiveNoAirDamage(Dam_PlayerDamageLocal __instance, pMiniDamageData data) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); ((Dam_PlayerDamageBase)__instance).m_nextRegen = Clock.Time + ((Dam_PlayerDamageBase)__instance).Owner.PlayerData.healthRegenStartDelayAfterDamage; if (((Agent)((Dam_PlayerDamageBase)__instance).Owner).IsLocallyOwned) { DramaManager.CurrentState.OnLocalDamage(num); GameEventManager.PostEvent((eGameEvent)13, ((Dam_PlayerDamageBase)__instance).Owner, num, "", (Dictionary<string, string>)null); } else { DramaManager.CurrentState.OnTeammatesDamage(num); } if (((Dam_PlayerDamageBase)__instance).IgnoreAllDamage) { return false; } if (SNet.IsMaster && !((Dam_SyncedDamageBase)__instance).RegisterDamage(num)) { ((Dam_SyncedDamageBase)__instance).SendSetHealth(((Dam_SyncedDamageBase)__instance).Health); } __instance.Hitreact(((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax), Vector3.zero, true, false, false); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveBulletDamage")] public static void Post_ReceiveBulletDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveMeleeDamage")] public static void Post_ReceiveMeleeDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveFireDamage")] public static void Post_ReceiveFireDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveShooterProjectileDamage")] public static void Post_ReceiveShooterProjectileDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveTentacleAttackDamage")] public static void Post_ReceiveTentacleAttackDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceivePushDamage")] public static void Post_ReceivePushDamage() { AirManager.Current.ResetHealthToRegen(); } [HarmonyPostfix] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveSetDead")] public static void Post_ReceiveSetDead() { AirManager.Current.ResetHealthToRegen(); } } [HarmonyPatch(typeof(EnvironmentStateManager), "UpdateFog")] internal class EnvironmentStateManager_UpdateFog { public static void Prefix(EnvironmentStateManager __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)AirManager.Current == (Object)null) { return; } FogState val = ((Il2CppArrayBase<FogState>)(object)__instance.m_stateReplicator.State.FogStates)[__instance.m_latestKnownLocalDimensionCreationIndex]; if (val.FogDataID != 0) { AirManager.Current.UpdateAirConfig(val.FogDataID); if (!AirManager.Current.HasAirConfig()) { AirManager.Current.StopInfectionLoop(); } } } } [HarmonyPatch(typeof(FogRepeller_Sphere), "StartRepelling")] internal class FogRepeller_Sphere_StartRepelling { public static void Postfix(ref FogRepeller_Sphere __instance) { if (__instance.m_infectionShield != null) { EffectVolumeManager.UnregisterVolume((EffectVolume)(object)__instance.m_infectionShield); ((EffectVolume)__instance.m_infectionShield).contents = (eEffectVolumeContents)0; EffectVolumeManager.RegisterVolume((EffectVolume)(object)__instance.m_infectionShield); } } } [HarmonyPatch(typeof(LocalPlayerAgentSettings), "UpdateBlendTowardsTargetFogSetting")] internal class LocalPlayerAgentSettings_UpdateBlendTowardsTargetFogSetting { public static void Postfix(LocalPlayerAgentSettings __instance, float amount) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!AirManager.Current.HasAirConfig()) { AirPlane.Current.Unregister(); } else { if (__instance.m_targetFogSettings == null || !SNet.LocalPlayer.HasPlayerAgent) { return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent.FPSCamera == (Object)null) { return; } AirPlane current = AirPlane.Current; if (!((Object)(object)current == (Object)null) && RundownManager.ExpeditionIsStarted) { float num = 0f; Dimension val = default(Dimension); if (Dimension.GetDimension(((Agent)localPlayerAgent).DimensionIndex, ref val)) { num = val.GroundY; } PreLitVolume prelitVolume = localPlayerAgent.FPSCamera.PrelitVolume; ((EffectVolume)current.airPlane).invert = (double)prelitVolume.m_densityHeightMaxBoost > (double)prelitVolume.m_fogDensity; ((EffectVolume)current.airPlane).contents = (eEffectVolumeContents)1; ((EffectVolume)current.airPlane).modification = (eEffectVolumeModification)0; ((EffectVolume)current.airPlane).modificationScale = AirManager.Current.AirLoss(); current.airPlane.lowestAltitude = prelitVolume.m_densityHeightAltitude + num; current.airPlane.highestAltitude = prelitVolume.m_densityHeightAltitude + prelitVolume.m_densityHeightRange + num; AirPlane.Current.Register(); } } } } [HarmonyPatch] internal class Patch_PlayerAgent { [HarmonyPrefix] [HarmonyPatch(typeof(PlayerAgent), "ReceiveModification")] public static void ReceiveModification(PlayerAgent __instance, ref EV_ModificationData data) { if (AirManager.Current.HasAirConfig()) { if ((double)data.health != 0.0) { AirManager.Current.RemoveAir(data.health); } else { AirManager.Current.AddAir(); } data.health = 0f; } } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerAgent), "Setup")] internal static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { AirManager.Setup(__instance); } } } } namespace Oxygen.Config { public class ConfigManager { private static readonly JsonSerializerOptions s_SerializerOptions; public static T Deserialize<T>(string json) { return JsonSerializer.Deserialize<T>(json, s_SerializerOptions); } public static string Serialize<T>(T value) { return JsonSerializer.Serialize(value, s_SerializerOptions); } static ConfigManager() { s_SerializerOptions = new JsonSerializerOptions { AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip, PropertyNameCaseInsensitive = true, WriteIndented = true }; s_SerializerOptions.Converters.Add(new JsonStringEnumConverter()); if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized) { s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter); s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter); Log.Message("PartialData Support Found!"); } else { s_SerializerOptions.Converters.Add(new LocalizedTextConverter()); } } public static void Load<T>(string file, out T config) where T : new() { if (file.Length < ".json".Length) { config = default(T); return; } if (file.Substring(file.Length - ".json".Length) != ".json") { file += ".json"; } file = File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "Oxygen", file)); config = Deserialize<T>(file); } } public class AirText { public float x { get; set; } public float y { get; set; } public LocalizedText Text { get; set; } } public class OxygenConfig { public List<OxygenBlock> Blocks { get; set; } = new List<OxygenBlock> { new OxygenBlock() }; } public class OxygenBlock { public float AirLoss { get; set; } public float AirGain { get; set; } = 1f; public float DamageTime { get; set; } = 1f; public float DamageAmount { get; set; } public bool ShatterGlass { get; set; } public float ShatterAmount { get; set; } public float DamageThreshold { get; set; } = 0.1f; public bool AlwaysDisplayAirBar { get; set; } public float HealthRegenProportion { get; set; } = 1f; public float TimeToStartHealthRegen { get; set; } = 3f; public float TimeToCompleteHealthRegen { get; set; } = 5f; public AirText AirText { get; set; } public List<uint> FogSettings { get; set; } = new List<uint> { 0u }; } } namespace Oxygen.Components { public class AirBar : MonoBehaviour { public static AirBar Current; private TextMeshPro m_airText; private TextMeshPro m_airTextLocalization; private float m_airTextX; private float m_airTextY; private float m_airTextZ; private RectTransform m_air1; private RectTransform m_air2; private SpriteRenderer m_airBar1; private SpriteRenderer m_airBar2; private float m_airWidth = 100f; private float m_barHeightMin = 3f; private float m_barHeightMax = 9f; private Color m_airLow = new Color(0f, 0.5f, 0.5f); private Color m_airHigh = new Color(0f, 0.3f, 0.8f); public AirBar(IntPtr value) : base(value) { }//IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) public static void Setup() { if ((Object)(object)Current == (Object)null) { Current = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus).gameObject.AddComponent<AirBar>(); Current.Init(); } } private void Init() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_airText == (Object)null) { m_airText = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_healthText).gameObject.Instantiate<TextMeshPro>("AirText"); TextMeshPro airText = m_airText; ((TMP_Text)airText).fontSize = ((TMP_Text)airText).fontSize / 1.25f; m_airText.transform.Translate(0f, -30f, 0f); } if ((Object)(object)m_airTextLocalization == (Object)null) { m_airTextLocalization = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_pulseText).gameObject.Instantiate<TextMeshPro>("AirText Localization"); ((Behaviour)m_airTextLocalization).enabled = true; m_airTextLocalization.transform.Translate(300f - m_airWidth, -45f, 0f); m_airTextX = m_airTextLocalization.transform.position.x; m_airTextY = m_airTextLocalization.transform.position.y; m_airTextZ = m_airTextLocalization.transform.position.z; } if ((Object)(object)m_air1 == (Object)null) { m_air1 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health1).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Right"); ((Component)m_air1).transform.Translate(0f, -30f, 0f); SpriteRenderer component = ((Component)((Transform)m_air1).GetChild(0)).GetComponent<SpriteRenderer>(); component.size = new Vector2(m_airWidth, component.size.y); m_airBar1 = ((Component)((Transform)m_air1).GetChild(1)).GetComponent<SpriteRenderer>(); ((Renderer)((Component)((Transform)m_air1).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false; } if ((Object)(object)m_air2 == (Object)null) { m_air2 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health2).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Left"); ((Component)m_air2).transform.Translate(0f, 30f, 0f); SpriteRenderer component2 = ((Component)((Transform)m_air2).GetChild(0)).GetComponent<SpriteRenderer>(); component2.size = new Vector2(m_airWidth, component2.size.y); m_airBar2 = ((Component)((Transform)m_air2).GetChild(1)).GetComponent<SpriteRenderer>(); ((Renderer)((Component)((Transform)m_air2).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false; } UpdateAirBar(1f); SetVisible(vis: false); } public void UpdateAirBar(float air) { SetAirPercentageText(air); SetAirBar(m_airBar1, air); SetAirBar(m_airBar2, air); } private void SetAirBar(SpriteRenderer bar, float val) { //IL_001b: 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_002d: 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) bar.size = new Vector2(val * m_airWidth, Mathf.Lerp(m_barHeightMin, m_barHeightMax, val)); bar.color = Color.Lerp(m_airLow, m_airHigh, val); } private void SetAirPercentageText(float val) { //IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Color color = Color.Lerp(m_airLow, m_airHigh, val); ((TMP_Text)m_airText).text = "O<size=75%>2</size>"; ((Graphic)m_airText).color = color; ((TMP_Text)m_airText).ForceMeshUpdate(true, false); ((Graphic)m_airTextLocalization).color = color; ((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false); } public void UpdateAirText(OxygenBlock config) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (config != null) { string text = LocalizedText.op_Implicit(config.AirText.Text); float x = config.AirText.x; float y = config.AirText.y; ((TMP_Text)m_airTextLocalization).text = text; ((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false); CoroutineManager.BlinkIn(((Component)m_airTextLocalization).gameObject, 0f); m_airTextLocalization.transform.SetPositionAndRotation(new Vector3(m_airTextX + x, m_airTextY + y, m_airTextZ), m_airTextLocalization.transform.rotation); } } public void SetVisible(bool vis) { ((Component)m_airText).gameObject.SetActive(vis); ((Component)m_airTextLocalization).gameObject.SetActive(vis); ((Component)m_air1).gameObject.SetActive(vis); ((Component)m_air2).gameObject.SetActive(vis); } public static void OnLevelCleanup() { if (!((Object)(object)Current == (Object)null)) { Current.SetVisible(vis: false); } } } public class AirManager : MonoBehaviour { public static AirManager Current; public PlayerAgent m_playerAgent; private HUDGlassShatter m_hudGlass; private Dam_PlayerDamageBase Damage; public OxygenBlock config; private uint fogSetting; private FogSettingsDataBlock fogSettingDB; private float airAmount = 1f; private float damageTick; private float glassShatterAmount; private bool m_isInInfectionLoop; private bool isRegeningHealth; private float healthToRegen; private float healthRegenTick; private float tickUntilHealthRegenHealthStart; private readonly float regenHealthTickInterval = 0.25f; private float healthRegenAmountPerInterval; internal bool PlayerShouldCough; private readonly float CoughPerLoss = 0.1f; private float CoughLoss; public AirManager(IntPtr value) : base(value) { } public static void Setup(PlayerAgent playerAgent) { Current = ((Component)playerAgent).gameObject.AddComponent<AirManager>(); } public static void OnBuildDone() { if (!((Object)(object)Current == (Object)null)) { Current.m_playerAgent = PlayerManager.GetLocalPlayerAgent(); Current.m_hudGlass = ((Component)Current.m_playerAgent.FPSCamera).GetComponent<HUDGlassShatter>(); Current.Damage = ((Component)Current.m_playerAgent).gameObject.GetComponent<Dam_PlayerDamageBase>(); Current.UpdateAirConfig(RundownManager.ActiveExpedition.Expedition.FogSettings); AirBar.Current.UpdateAirText(Current.config); } } public static void OnLevelCleanup() { if (!((Object)(object)Current == (Object)null)) { if (Current.m_isInInfectionLoop) { Current.StopInfectionLoop(); } Current.config = null; Current.fogSetting = 0u; Current.fogSettingDB = null; Current.airAmount = 0f; Current.damageTick = 0f; Current.glassShatterAmount = 0f; Current.healthToRegen = 0f; Current.m_playerAgent = null; Current.m_hudGlass = null; Current.Damage = null; } } private void Update() { if (!RundownManager.ExpeditionIsStarted) { return; } if (!HasAirConfig()) { AirBar.Current.SetVisible(vis: false); return; } if (airAmount == 1f) { if (config.AlwaysDisplayAirBar) { AirBar.Current.SetVisible(vis: true); } else { AirBar.Current.SetVisible(vis: false); } } else { AirBar.Current.SetVisible(vis: true); } if (airAmount <= config.DamageThreshold) { damageTick += Time.deltaTime; if (damageTick > config.DamageTime && ((Agent)m_playerAgent).Alive) { AirDamage(); } isRegeningHealth = false; } else if (healthToRegen > 0f) { tickUntilHealthRegenHealthStart += Time.deltaTime; if (tickUntilHealthRegenHealthStart > config.TimeToStartHealthRegen) { if (healthRegenAmountPerInterval == 0f) { healthRegenAmountPerInterval = healthToRegen * (regenHealthTickInterval / config.TimeToCompleteHealthRegen); } RegenHealth(); if (!isRegeningHealth) { Damage.m_nextRegen = Clock.Time + config.TimeToStartHealthRegen + config.TimeToCompleteHealthRegen; isRegeningHealth = true; } } } else { isRegeningHealth = false; } } public void AddAir() { if (HasAirConfig()) { float airGain = config.AirGain; airAmount = Mathf.Clamp01(airAmount + airGain); AirBar.Current.UpdateAirBar(airAmount); if (fogSettingDB.Infection <= 0f && m_isInInfectionLoop) { StopInfectionLoop(); } } } public void RemoveAir(float amount) { if (HasAirConfig()) { amount = config.AirLoss; airAmount = Mathf.Clamp01(airAmount - amount); AirBar.Current.UpdateAirBar(airAmount); if (fogSettingDB.Infection <= 0f && amount > 0f) { StartInfectionLoop(); } } } public void AirDamage() { float health = ((Dam_SyncedDamageBase)Damage).Health; float damageAmount = config.DamageAmount; Damage.m_nextRegen = Clock.Time + config.TimeToStartHealthRegen; if (!(health <= 1f)) { ((Dam_SyncedDamageBase)Damage).NoAirDamage(damageAmount); if (config.ShatterGlass) { glassShatterAmount += config.ShatterAmount; m_hudGlass.SetGlassShatterProgression(glassShatterAmount); } damageTick = 0f; tickUntilHealthRegenHealthStart = 0f; healthRegenAmountPerInterval = 0f; healthToRegen += damageAmount * config.HealthRegenProportion; CoughLoss += damageAmount; if (CoughLoss > CoughPerLoss) { PlayerShouldCough = true; CoughLoss = 0f; } } } public void RegenHealth() { if (healthToRegen <= 0f) { return; } tickUntilHealthRegenHealthStart = config.TimeToStartHealthRegen; healthRegenTick += Time.deltaTime; if (healthRegenTick > regenHealthTickInterval) { float num = healthRegenAmountPerInterval; if (num >= healthToRegen) { num = healthToRegen; healthToRegen = 0f; tickUntilHealthRegenHealthStart = 0f; healthRegenAmountPerInterval = 0f; isRegeningHealth = false; } else { healthToRegen -= num; } ((Dam_SyncedDamageBase)Damage).AddHealth(num, (Agent)(object)m_playerAgent); healthRegenTick = 0f; } } public void UpdateAirConfig(uint fogsetting, bool LiveEditForceUpdate = false) { if (fogsetting != 0 && (fogsetting != fogSetting || LiveEditForceUpdate)) { if (Plugin.lookup.ContainsKey(fogsetting)) { config = Plugin.lookup[fogsetting]; } else if (Plugin.lookup.ContainsKey(0u)) { config = Plugin.lookup[0u]; } else { config = null; airAmount = 1f; } fogSetting = fogsetting; fogSettingDB = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(fogsetting); if (GameStateManager.IsInExpedition) { AirBar.Current.UpdateAirText(config); } } } public void ResetHealthToRegen() { healthRegenTick = 0f; healthToRegen = 0f; tickUntilHealthRegenHealthStart = 0f; } public float AirLoss() { if (config != null) { return config.AirLoss; } return 0f; } public bool AlwaysDisplayAirBar() { if (config != null) { return config.AlwaysDisplayAirBar; } return false; } public uint FogSetting() { return fogSetting; } public float HealthToRegen() { return healthToRegen; } public string AirText() { return LocalizedText.op_Implicit((config == null) ? null : config.AirText.Text); } public float AirTextX() { if (config != null) { return config.AirText.x; } return 0f; } public float AirTextY() { if (config != null) { return config.AirText.y; } return 0f; } public bool HasAirConfig() { return config != null; } public void StartInfectionLoop() { if (!m_isInInfectionLoop) { m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_START, true); m_isInInfectionLoop = true; } } public void StopInfectionLoop() { if (m_isInInfectionLoop) { if ((Object)(object)m_playerAgent != (Object)null && m_playerAgent.Sound != null) { m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_STOP, true); } m_isInInfectionLoop = false; } } } public class AirPlane : MonoBehaviour { public static AirPlane Current; public EV_Plane airPlane; private bool isAirPlaneRegistered; public AirPlane(IntPtr value) : base(value) { } public static void OnBuildStart() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if ((Object)(object)Current == (Object)null) { Current = ((Component)LocalPlayerAgentSettings.Current).gameObject.AddComponent<AirPlane>(); } Current.airPlane = new EV_Plane(); uint num = RundownManager.ActiveExpedition.Expedition.FogSettings; if (num == 0) { num = 21u; } OxygenBlock oxygenBlock = (Plugin.lookup.ContainsKey(num) ? Plugin.lookup[num] : ((!Plugin.lookup.ContainsKey(0u)) ? null : Plugin.lookup[0u])); FogSettingsDataBlock block = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(num); ((EffectVolume)Current.airPlane).invert = block.DensityHeightMaxBoost > block.FogDensity; ((EffectVolume)Current.airPlane).contents = (eEffectVolumeContents)1; ((EffectVolume)Current.airPlane).modification = (eEffectVolumeModification)0; Current.airPlane.lowestAltitude = block.DensityHeightAltitude; Current.airPlane.highestAltitude = block.DensityHeightAltitude + block.DensityHeightRange; if (oxygenBlock != null) { ((EffectVolume)Current.airPlane).modificationScale = oxygenBlock.AirLoss; Current.Register(); } } public static void OnLevelCleanup() { if (!((Object)(object)Current == (Object)null)) { Current.Unregister(); Current.isAirPlaneRegistered = false; Current.airPlane = null; } } public void Register() { if (airPlane != null && !isAirPlaneRegistered) { EffectVolumeManager.RegisterVolume((EffectVolume)(object)airPlane); isAirPlaneRegistered = true; } } public void Unregister() { if (airPlane != null && isAirPlaneRegistered) { EffectVolumeManager.UnregisterVolume((EffectVolume)(object)airPlane); isAirPlaneRegistered = false; } } } }