Decompiled source of REPOLib v3.0.3
plugins/REPOLib.dll
Decompiled a day 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.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using REPOLib.Extensions; using REPOLib.Modules; using REPOLib.Objects; using REPOLib.Objects.Sdk; using REPOLib.Patches; using TMPro; using UnityEngine; using UnityEngine.Audio; 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("Zehs")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2025 Zehs")] [assembly: AssemblyDescription("Library for adding content to R.E.P.O.")] [assembly: AssemblyFileVersion("3.0.3.0")] [assembly: AssemblyInformationalVersion("3.0.3+99c6abc788bb83af8f8dd98c7c5e1a7adba2b314")] [assembly: AssemblyProduct("REPOLib")] [assembly: AssemblyTitle("REPOLib")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ZehsTeam/REPOLib")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.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.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPOLib { public static class BundleLoader { private class LoadOperation { public enum State { LoadingBundle, LoadingContent } public string Path { get; } public DateTime StartTime { get; } public State CurrentState { get; set; } public bool LoadContents { get; } public Func<AssetBundle, IEnumerator>? OnBundleLoaded { get; } public AssetBundleCreateRequest BundleRequest { get; } public TimeSpan ElapsedTime => DateTime.Now - StartTime; public string FileName => System.IO.Path.GetFileNameWithoutExtension(Path); public LoadOperation(string path, Func<AssetBundle, IEnumerator>? onBundleLoaded = null, bool loadContents = true) { Path = path; StartTime = DateTime.Now; LoadContents = loadContents; OnBundleLoaded = onBundleLoaded; BundleRequest = AssetBundle.LoadFromFileAsync(path); base..ctor(); } } [CompilerGenerated] private sealed class <>c__DisplayClass10_0 { public Action<AssetBundle> onLoaded; public string path; } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <>c__DisplayClass14_0 { public LoadOperation operation; } [CompilerGenerated] private sealed class <FinishLoadOperation>d__14 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public LoadOperation operation; private <>c__DisplayClass14_0 <>8__1; private AssetBundle <bundle>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FinishLoadOperation>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = default(<>c__DisplayClass14_0); <bundle>5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1.operation = operation; <>2__current = <>8__1.operation.BundleRequest; <>1__state = 1; return true; case 1: <>1__state = -1; <bundle>5__2 = <>8__1.operation.BundleRequest.assetBundle; if ((Object)(object)<bundle>5__2 == (Object)null) { Logger.LogError("Failed to load bundle " + <>8__1.operation.FileName + "!"); <FinishLoadOperation>g__Finish|14_0(ref <>8__1); return false; } if (<>8__1.operation.LoadContents) { <>2__current = LoadBundleContent(<>8__1.operation, <bundle>5__2); <>1__state = 2; return true; } goto IL_00f6; case 2: <>1__state = -1; goto IL_00f6; case 3: { <>1__state = -1; break; } IL_00f6: if (<>8__1.operation.OnBundleLoaded != null) { <>2__current = <>8__1.operation.OnBundleLoaded(<bundle>5__2); <>1__state = 3; return true; } break; } if (ConfigManager.ExtendedLogging.Value) { Logger.LogInfo($"Loaded bundle {<>8__1.operation.FileName} in {<>8__1.operation.ElapsedTime.TotalSeconds:N1}s"); } <FinishLoadOperation>g__Finish|14_0(ref <>8__1); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <FinishLoadOperationsRoutine>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MonoBehaviour behaviour; private float <lastUpdate>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FinishLoadOperationsRoutine>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; AllBundlesLoaded = false; LoadOperation[] array = _operations.ToArray(); foreach (LoadOperation operation in array) { behaviour.StartCoroutine(FinishLoadOperation(operation)); } BundleLoaderLoadingText.Create(); <lastUpdate>5__2 = Time.time; break; } case 2: <>1__state = -1; break; } while (_operations.Count > 0) { if (Time.time - <lastUpdate>5__2 > 1f) { <lastUpdate>5__2 = Time.time; string arg = ((_operations.Count == 1) ? "bundle" : "bundles"); BundleLoaderLoadingText.SetText($"REPOLib: Waiting for {_operations.Count} {arg} to load..."); if (!ConfigManager.ExtendedLogging.Value) { continue; } foreach (LoadOperation operation2 in _operations) { string text = $"Loading {operation2.FileName}: {operation2.CurrentState}"; float? num = ((operation2.CurrentState != 0) ? null : new float?(((AsyncOperation)operation2.BundleRequest).progress)); float? num2 = num; if (num2.HasValue) { text += $" {num2.Value:P0}"; } Logger.LogDebug(text); } } <>2__current = null; <>1__state = 2; return true; } Logger.LogInfo("Finished loading bundles."); BundleLoaderLoadingText.Hide(); AllBundlesLoaded = true; Utilities.SafeInvokeEvent(BundleLoader.OnAllBundlesLoaded); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadBundleContent>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public LoadOperation operation; public AssetBundle bundle; private AssetBundleRequest <assetRequest>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadBundleContent>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <assetRequest>5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; operation.CurrentState = LoadOperation.State.LoadingContent; <assetRequest>5__2 = bundle.LoadAllAssetsAsync<ScriptableObject>(); <>2__current = <assetRequest>5__2; <>1__state = 1; return true; case 1: { <>1__state = -1; Object[] allAssets = <assetRequest>5__2.allAssets; Mod[] array = allAssets.OfType<Mod>().ToArray(); int num = array.Length; if (num <= 1) { if (num == 0) { Logger.LogError("Bundle " + operation.FileName + " contains no mods!"); return false; } Mod mod = array[0]; foreach (Content item in allAssets.OfType<Content>().OrderByTypeFirst<Content, LevelContent>()) { try { item.Initialize(mod); } catch (Exception ex) { Logger.LogError($"Failed to load {item.Name} ({((object)item).GetType().Name}) from bundle {operation.FileName} ({mod.Identifier}): {ex}"); } } return false; } Logger.LogError("Bundle " + operation.FileName + " contains more than one mod!"); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly List<LoadOperation> _operations = new List<LoadOperation>(); internal static bool AllBundlesLoaded { get; private set; } public static event Action? OnAllBundlesLoaded; internal static void LoadAllBundles(string root, string withExtension) { Logger.LogInfo("Loading all bundles with extension " + withExtension + " from root " + root, extended: true); string[] files = Directory.GetFiles(root, "*" + withExtension, SearchOption.AllDirectories); string[] array = files; foreach (string path in array) { LoadBundleAndContent(path); } } public static void LoadBundleAndContent(string path) { LoadBundle(path, (Func<AssetBundle, IEnumerator>?)null, loadContents: true); } public static void LoadBundle(string path, Action<AssetBundle> onLoaded, bool loadContents = false) { <>c__DisplayClass10_0 CS$<>8__locals0 = new <>c__DisplayClass10_0(); CS$<>8__locals0.onLoaded = onLoaded; CS$<>8__locals0.path = path; LoadBundle(CS$<>8__locals0.path, (Func<AssetBundle, IEnumerator>?)OnLoaded, loadContents); [IteratorStateMachine(typeof(<>c__DisplayClass10_0.<<LoadBundle>g__OnLoaded|0>d))] IEnumerator OnLoaded(AssetBundle bundle) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass10_0.<<LoadBundle>g__OnLoaded|0>d(0) { <>4__this = CS$<>8__locals0, bundle = bundle }; } } public static void LoadBundle(string path, Func<AssetBundle, IEnumerator>? onLoaded = null, bool loadContents = false) { Logger.LogInfo("Loading bundle at " + path + "..."); _operations.Add(new LoadOperation(path, onLoaded, loadContents)); } internal static void FinishLoadOperations(MonoBehaviour behaviour) { behaviour.StartCoroutine(FinishLoadOperationsRoutine(behaviour)); } [IteratorStateMachine(typeof(<FinishLoadOperationsRoutine>d__13))] private static IEnumerator FinishLoadOperationsRoutine(MonoBehaviour behaviour) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FinishLoadOperationsRoutine>d__13(0) { behaviour = behaviour }; } [IteratorStateMachine(typeof(<FinishLoadOperation>d__14))] private static IEnumerator FinishLoadOperation(LoadOperation operation) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FinishLoadOperation>d__14(0) { operation = operation }; } [IteratorStateMachine(typeof(<LoadBundleContent>d__15))] private static IEnumerator LoadBundleContent(LoadOperation operation, AssetBundle bundle) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadBundleContent>d__15(0) { operation = operation, bundle = bundle }; } [Obsolete("Use LoadBundleAndContent instead")] public static void LoadBundle(string path, string relativePath) { LoadBundleAndContent(path); } [CompilerGenerated] internal static void <FinishLoadOperation>g__Finish|14_0(ref <>c__DisplayClass14_0 P_0) { _operations.Remove(P_0.operation); } } internal static class BundleLoaderLoadingText { private static TMP_Text? _text; public static void Create() { //IL_003b: 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_008c: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("HUD Canvas"); TMP_Text val2 = Object.FindObjectOfType<TMP_Text>(); _text = Object.Instantiate<TMP_Text>(val2, val.transform); ((Object)((Component)_text).gameObject).name = "REPOLibText"; ((Graphic)_text).color = Color.white; _text.fontStyle = (FontStyles)1; _text.alignment = (TextAlignmentOptions)514; RectTransform component = ((Component)_text).GetComponent<RectTransform>(); component.anchoredPosition = Vector2.zero; component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; ((Component)_text).gameObject.SetActive(false); SetText("REPOLib is loading bundles... Hang tight!"); } public static void Show() { VideoOverlay.Instance.Override(999f, 0.02f, 2f); TMP_Text? text = _text; if (text != null) { ((Component)text).gameObject.SetActive(true); } } public static void Hide() { VideoOverlay.Instance.Override(0f, 0.02f, 2f); TMP_Text? text = _text; if (text != null) { ((Component)text).gameObject.SetActive(false); } } public static void SetText(string value) { if (!((Object)(object)_text == (Object)null)) { _text.text = value; } } } internal static class ConfigManager { public static ConfigFile ConfigFile { get; private set; } public static ConfigEntry<bool> ExtendedLogging { get; private set; } public static ConfigEntry<bool> DeveloperMode { get; private set; } public static ConfigEntry<bool> VanillaDeveloperMode { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { ExtendedLogging = ConfigFile.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging."); DeveloperMode = ConfigFile.Bind<bool>("General", "DeveloperMode", false, "Enable developer mode chat commands for testing."); VanillaDeveloperMode = ConfigFile.Bind<bool>("General", "VanillaDeveloperMode", false, "Enable vanilla developer mode cheats and chat commands for testing."); VanillaDeveloperMode.SettingChanged += delegate { SteamManagerPatch.UpdateDeveloperMode(); }; } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data) { Log((LogLevel)32, data); } public static void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } public static void LogMessage(object data, bool extended = false) { Log((LogLevel)8, data, extended); } public static void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } public static void LogError(object data, bool extended = false) { Log((LogLevel)2, data, extended); } public static void LogFatal(object data, bool extended = false) { Log((LogLevel)1, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!extended || IsExtendedLoggingEnabled()) { ManualLogSource manualLogSource = ManualLogSource; if (manualLogSource != null) { manualLogSource.Log(logLevel, data); } } } public static bool IsExtendedLoggingEnabled() { return ConfigManager.ExtendedLogging?.Value ?? false; } } [BepInPlugin("REPOLib", "REPOLib", "3.0.3")] public class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("REPOLib"); public static Plugin Instance { get; private set; } private void Awake() { Instance = this; Logger.Initialize(Logger.CreateLogSource("REPOLib")); Logger.LogInfo("REPOLib has awoken!"); _harmony.PatchAll(typeof(RunManagerPatch)); _harmony.PatchAll(typeof(EnemyDirectorPatch)); _harmony.PatchAll(typeof(StatsManagerPatch)); _harmony.PatchAll(typeof(SemiFuncPatch)); _harmony.PatchAll(typeof(AudioManagerPatch)); _harmony.PatchAll(typeof(SteamManagerPatch)); _harmony.PatchAll(typeof(PlayerControllerPatch)); _harmony.PatchAll(typeof(DebugCommandHandlerPatch)); _harmony.PatchAll(typeof(DefaultPoolPatch)); _harmony.PatchAll(typeof(PrefabRefPatch)); _harmony.PatchAll(typeof(SplashScreenPatch)); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); Upgrades.Initialize(); BundleLoader.LoadAllBundles(Paths.PluginPath, ".repobundle"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "REPOLib"; public const string PLUGIN_NAME = "REPOLib"; public const string PLUGIN_VERSION = "3.0.3"; } } namespace REPOLib.Patches { [HarmonyPatch(typeof(AudioManager))] internal static class AudioManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { Utilities.FixAudioMixerGroupsOnPrefabs(); LevelAmbiences.RegisterLevelAmbiences(); } } [HarmonyPatch(typeof(DebugCommandHandler))] internal static class DebugCommandHandlerPatch { [HarmonyPatch("Start")] [HarmonyPrefix] private static void StartPatch() { Commands.RegisterCommands(); } } [HarmonyPatch(typeof(DefaultPool))] internal static class DefaultPoolPatch { [HarmonyPatch("Instantiate")] [HarmonyPrefix] private static bool InstantiatePatch(string prefabId, Vector3 position, Quaternion rotation, ref GameObject __result) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!NetworkPrefabs.TryGetNetworkPrefab(prefabId, out GameObject prefab)) { return true; } bool activeSelf = prefab.activeSelf; if (activeSelf) { prefab.SetActive(false); } __result = Object.Instantiate<GameObject>(prefab, position, rotation); if (activeSelf) { prefab.SetActive(true); } return false; } } [HarmonyPatch(typeof(EnemyDirector))] internal static class EnemyDirectorPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch() { Enemies.RegisterEnemies(); } } [HarmonyPatch(typeof(PlayerController))] internal static class PlayerControllerPatch { [CompilerGenerated] private sealed class <LateStartTranspiler>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private bool <found>5__2; private List<CodeInstruction>.Enumerator <>7__wrap2; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LateStartTranspiler>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap2 = default(List<CodeInstruction>.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerController), "playerAvatarScript"); MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), "PlayerGetSteamID", new Type[1] { typeof(PlayerAvatar) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Upgrades), "InvokeStartActions", new Type[1] { typeof(string) }, (Type[])null); <found>5__2 = false; int num = 0; List<CodeInstruction> list = new List<CodeInstruction>(); foreach (CodeInstruction instruction in instructions) { list.Add(instruction); if (num switch { 0 => instruction.opcode == OpCodes.Ldloc_1, 1 => instruction.opcode == OpCodes.Ldfld && CodeInstructionExtensions.LoadsField(instruction, fieldInfo, false), 2 => instruction.opcode == OpCodes.Call && CodeInstructionExtensions.Calls(instruction, methodInfo), 3 => instruction.opcode == OpCodes.Stloc_2, _ => false, }) { num++; if (num > 3) { <found>5__2 = true; num = 0; list.Add(new CodeInstruction(OpCodes.Ldloc_2, (object)null)); list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2)); } } else { num = 0; } } <>7__wrap2 = list.GetEnumerator(); <>1__state = -3; break; } case 1: <>1__state = -3; break; } if (<>7__wrap2.MoveNext()) { CodeInstruction current2 = <>7__wrap2.Current; <>2__current = current2; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap2 = default(List<CodeInstruction>.Enumerator); if (!<found>5__2) { Logger.LogWarning("Failed to patch PlayerController.LateStart!"); } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap2).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <LateStartTranspiler>d__0 <LateStartTranspiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <LateStartTranspiler>d__ = this; } else { <LateStartTranspiler>d__ = new <LateStartTranspiler>d__0(0); } <LateStartTranspiler>d__.instructions = <>3__instructions; return <LateStartTranspiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<LateStartTranspiler>d__0))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> LateStartTranspiler(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LateStartTranspiler>d__0(-2) { <>3__instructions = instructions }; } } [HarmonyPatch(typeof(PrefabRef))] internal static class PrefabRefPatch { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool PrefabPatch(PrefabRef __instance, ref GameObject __result) { if (NetworkPrefabs.TryGetNetworkPrefab(__instance.resourcePath, out GameObject prefab)) { __result = prefab; return false; } return true; } } [HarmonyPatch(typeof(RunManager))] internal static class RunManagerPatch { private static bool _patchedAwake; [HarmonyPatch("Awake")] [HarmonyPostfix] [HarmonyPriority(0)] private static void AwakePatch(RunManager __instance) { if (!_patchedAwake) { _patchedAwake = true; NetworkingEvents.Initialize(); ValuablePresets.Initialize(); Levels.RegisterInitialLevels(); Valuables.RegisterInitialValuables(); BundleLoader.FinishLoadOperations((MonoBehaviour)(object)__instance); } } } [HarmonyPatch(typeof(SemiFunc))] internal static class SemiFuncPatch { [HarmonyPatch("DebugTester")] [HarmonyPrefix] private static bool DebugTesterPatch(ref bool __result) { if (ConfigManager.DeveloperMode.Value) { __result = true; return false; } return true; } [HarmonyPatch("EnemySpawn")] [HarmonyPrefix] private static bool EnemySpawnPatch(ref bool __result) { if (Enemies.SpawnNextEnemiesNotDespawned > 0) { Enemies.SpawnNextEnemiesNotDespawned--; __result = true; return false; } return true; } } [HarmonyPatch(typeof(SplashScreen))] internal static class SplashScreenPatch { private static bool _showedBundleLoaderLoadingText; [HarmonyPatch("StateWarning")] [HarmonyPostfix] private static void StateWarningPatch(SplashScreen __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.state == 3) { ((Component)SplashScreenUI.instance.warningTransform).gameObject.SetActive(false); } } [HarmonyPatch("StateDone")] [HarmonyPrefix] private static bool StateDonePatch() { if (BundleLoader.AllBundlesLoaded) { return true; } if (_showedBundleLoaderLoadingText) { return false; } _showedBundleLoaderLoadingText = true; int childCount = ((Component)SplashScreenUI.instance).transform.childCount; for (int i = 1; i < childCount; i++) { Transform child = ((Component)SplashScreenUI.instance).transform.GetChild(i); ((Component)child).gameObject.SetActive(false); } BundleLoaderLoadingText.Show(); return false; } } [HarmonyPatch(typeof(StatsManager))] internal static class StatsManagerPatch { [HarmonyPatch("RunStartStats")] [HarmonyPostfix] private static void RunStartStatsPatch() { Items.RegisterItems(); Upgrades.RegisterUpgrades(); } } [HarmonyPatch(typeof(SteamManager))] internal static class SteamManagerPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] public static void AwakePatch(SteamManager __instance) { UpdateDeveloperMode(); } public static void UpdateDeveloperMode() { if (ConfigManager.VanillaDeveloperMode == null || (Object)(object)SteamManager.instance == (Object)null) { return; } bool value = ConfigManager.VanillaDeveloperMode.Value; if (SteamManager.instance.developerMode != value) { if (value) { Logger.LogInfo("Enabling vanilla developer mode."); } else { Logger.LogInfo("Disabling vanilla developer mode."); } } SteamManager.instance.developerMode = value; } } } namespace REPOLib.Objects { internal class PrefabRefComparer : IEqualityComparer<PrefabRef> { public StringComparison ComparisonType { get; } public PrefabRefComparer(StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { ComparisonType = comparisonType; } public bool Equals(PrefabRef x, PrefabRef y) { if (x == y) { return true; } if (x == null || y == null) { return false; } if (string.Equals(x.PrefabName, y.PrefabName, ComparisonType)) { return string.Equals(x.ResourcePath, y.ResourcePath, ComparisonType); } return false; } public int GetHashCode(PrefabRef obj) { if (obj == null) { return 0; } int num = 17; num = num * 23 + (obj.PrefabName?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0); return num * 23 + (obj.ResourcePath?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0); } } internal enum PrefabRefResult { Success, PrefabIdNullOrEmpty, PrefabNull, PrefabAlreadyRegistered, DifferentPrefabAlreadyRegistered } internal struct PrefabRefResponse { public PrefabRefResult Result { get; set; } public PrefabRef? PrefabRef { get; set; } public PrefabRefResponse(PrefabRefResult result, PrefabRef? prefabRef) { Result = result; PrefabRef = prefabRef; } } internal class UnityObjectNameComparer<T> : IEqualityComparer<T> where T : Object { public StringComparison ComparisonType { get; private set; } public UnityObjectNameComparer(StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { ComparisonType = comparisonType; } public bool Equals(T x, T y) { if ((Object)(object)x == (Object)(object)y) { return true; } if ((Object)(object)x == (Object)null || (Object)(object)y == (Object)null) { return false; } return ((Object)x).name.Equals(((Object)y).name, ComparisonType); } public int GetHashCode(T obj) { if (!((Object)(object)obj != (Object)null)) { return 0; } return ((Object)obj).name.GetHashCode(); } } } namespace REPOLib.Objects.Sdk { public abstract class Content : ScriptableObject { public abstract string Name { get; } public abstract void Initialize(Mod mod); } [CreateAssetMenu(menuName = "REPOLib/Enemy", order = 3, fileName = "New Enemy")] public class EnemyContent : Content { [SerializeField] private EnemySetup? _setup; [SerializeField] private List<GameObject> _spawnObjects = new List<GameObject>(); public EnemySetup? Setup => _setup; public List<GameObject> SpawnObjects => _spawnObjects; public override string Name { get { EnemySetup? setup = Setup; return ((setup != null) ? ((Object)setup).name : null) ?? string.Empty; } } public override void Initialize(Mod mod) { Enemies.RegisterEnemy(this); } } [CreateAssetMenu(menuName = "REPOLib/Item", order = 2, fileName = "New Item")] public class ItemContent : Content { [SerializeField] private ItemAttributes? _prefab; public ItemAttributes? Prefab => _prefab; public override string Name { get { ItemAttributes? prefab = Prefab; return ((prefab != null) ? ((Object)prefab).name : null) ?? string.Empty; } } public override void Initialize(Mod mod) { Items.RegisterItem(this); } } [CreateAssetMenu(menuName = "REPOLib/Level", order = 4, fileName = "New Level")] public class LevelContent : Content { [SerializeField] private Level? _level; [SerializeField] private GameObject? _connectObject; [SerializeField] private GameObject? _blockObject; [SerializeField] private List<GameObject> _startRooms = new List<GameObject>(); [Space] [Header("Difficulty 1")] [SerializeField] private List<GameObject> _modulesNormal1 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesPassage1 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesDeadEnd1 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesExtraction1 = new List<GameObject>(); [Space] [Header("Difficulty 2")] [SerializeField] private List<GameObject> _modulesNormal2 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesPassage2 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesDeadEnd2 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesExtraction2 = new List<GameObject>(); [Space] [Header("Difficulty 3")] [SerializeField] private List<GameObject> _modulesNormal3 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesPassage3 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesDeadEnd3 = new List<GameObject>(); [SerializeField] private List<GameObject> _modulesExtraction3 = new List<GameObject>(); public Level? Level => _level; public override string Name { get { Level? level = Level; return ((level != null) ? ((Object)level).name : null) ?? string.Empty; } } public GameObject? ConnectObject => _connectObject; public GameObject? BlockObject => _blockObject; public List<GameObject> StartRooms => _startRooms; public List<GameObject> ModulesNormal1 => _modulesNormal1; public List<GameObject> ModulesPassage1 => _modulesPassage1; public List<GameObject> ModulesDeadEnd1 => _modulesDeadEnd1; public List<GameObject> ModulesExtraction1 => _modulesExtraction1; public List<GameObject> ModulesNormal2 => _modulesNormal2; public List<GameObject> ModulesPassage2 => _modulesPassage2; public List<GameObject> ModulesDeadEnd2 => _modulesDeadEnd2; public List<GameObject> ModulesExtraction2 => _modulesExtraction2; public List<GameObject> ModulesNormal3 => _modulesNormal3; public List<GameObject> ModulesPassage3 => _modulesPassage3; public List<GameObject> ModulesDeadEnd3 => _modulesDeadEnd3; public List<GameObject> ModulesExtraction3 => _modulesExtraction3; public override void Initialize(Mod mod) { Levels.RegisterLevel(this); } } [CreateAssetMenu(menuName = "REPOLib/Mod", order = 0, fileName = "New Mod")] public class Mod : ScriptableObject { [SerializeField] private string _name; [SerializeField] private string _author; [SerializeField] private string _version = "1.0.0"; [SerializeField] private string _description; [SerializeField] private string _websiteUrl; [SerializeField] private string[] _dependencies = new string[1] { "Zehs-REPOLib-3.0.3" }; [SerializeField] private Sprite? _icon; [SerializeField] private TextAsset? _readme; public string Name => _name; public string Author => _author; public string Version => _version; public string Description => _description; public string WebsiteUrl => _websiteUrl; public IReadOnlyList<string> Dependencies => _dependencies; public Sprite? Icon => _icon; public TextAsset? Readme => _readme; public string FullName => Author + "-" + Name; public string Identifier => Author + "-" + Name + "-" + Version; } [CreateAssetMenu(menuName = "REPOLib/Valuable", order = 1, fileName = "New Valuable")] public class ValuableContent : Content { [SerializeField] private ValuableObject? _prefab; [SerializeField] private string[] _valuablePresets = new string[1] { "Valuables - Generic" }; public ValuableObject? Prefab => _prefab; public IReadOnlyList<string> ValuablePresets => _valuablePresets; public override string Name { get { ValuableObject? prefab = Prefab; return ((prefab != null) ? ((Object)prefab).name : null) ?? string.Empty; } } public override void Initialize(Mod mod) { Valuables.RegisterValuable(this); } } } namespace REPOLib.Modules { public static class Commands { private static readonly List<ChatCommand> _commandsToRegister = new List<ChatCommand>(); private static readonly List<ChatCommand> _commandsRegistered = new List<ChatCommand>(); public static IReadOnlyList<ChatCommand> AllCommands => GetCommands(); public static IReadOnlyList<ChatCommand> RegisteredCommands => _commandsRegistered; internal static void RegisterCommands() { if ((Object)(object)DebugCommandHandler.instance == (Object)null) { Logger.LogError("Failed to register commands. DebugCommandHandler instance is null."); return; } Logger.LogInfo("Adding commands."); _commandsRegistered.Clear(); foreach (ChatCommand item in _commandsToRegister) { DebugCommandHandler.instance.Register(item); _commandsRegistered.Add(item); } } public static void RegisterCommand(ChatCommand chatCommand) { ChatCommand chatCommand2 = chatCommand; if (chatCommand2 == null) { throw new ArgumentException("Failed to register command. ChatCommand is null."); } if (chatCommand2.Execute == null) { Logger.LogError("Failed to register command \"" + chatCommand2.Name + "\". Execute method is null."); } else if (_commandsToRegister.Contains(chatCommand2)) { Logger.LogError("Failed to register command \"" + chatCommand2.Name + "\". Command is already registered!"); } else if (_commandsToRegister.Any((ChatCommand x) => x.Name == chatCommand2.Name)) { Logger.LogError("Failed to register command \"" + chatCommand2.Name + "\". Command already exists with the same name."); } else { _commandsToRegister.Add(chatCommand2); } } private static IReadOnlyList<ChatCommand> GetCommands() { if ((Object)(object)DebugCommandHandler.instance == (Object)null) { return Array.Empty<ChatCommand>(); } return DebugCommandHandler.instance._commands.Values.ToList(); } } public static class Enemies { internal static int SpawnNextEnemiesNotDespawned = 0; private static readonly List<EnemySetup> _enemiesToRegister = new List<EnemySetup>(); public static IReadOnlyList<EnemySetup> AllEnemies => EnemyDirector.instance?.GetEnemies() ?? new List<EnemySetup>(); public static IReadOnlyList<EnemySetup> RegisteredEnemies => _enemiesToRegister; internal static void RegisterEnemies() { Logger.LogInfo("Adding enemies."); foreach (EnemySetup item in _enemiesToRegister) { RegisterEnemyWithGame(item); } } private static void RegisterEnemyWithGame(EnemySetup enemySetup) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!enemySetup.TryGetEnemyParent(out EnemyParent enemyParent)) { Logger.LogError("Failed to register enemy \"" + ((Object)enemySetup).name + "\" to game. Could not find EnemyParent component."); } else if (EnemyDirector.instance.AddEnemy(enemySetup)) { Logger.LogInfo($"Added enemy \"{enemyParent.enemyName}\" to difficulty {enemyParent.difficulty}", extended: true); } } public static void RegisterEnemy(EnemyContent? enemyContent) { if ((Object)(object)enemyContent == (Object)null) { Logger.LogError("Failed to register enemy. EnemyContent is null."); return; } EnemySetup enemySetup = enemyContent.Setup; List<GameObject> spawnObjects = enemyContent.SpawnObjects; if ((Object)(object)enemySetup == (Object)null) { Logger.LogError("Failed to register enemy. EnemySetup is null."); return; } if (spawnObjects == null || spawnObjects.Count == 0) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\". No spawn objects found."); return; } if (_enemiesToRegister.Contains(enemySetup)) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\". Enemy is already registered!"); return; } if (_enemiesToRegister.Any((EnemySetup x) => ((Object)x).name == ((Object)enemySetup).name)) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\". Enemy already exists with the same name."); return; } List<PrefabRef> list = new List<PrefabRef>(); foreach (GameObject item in spawnObjects) { if ((Object)(object)item == (Object)null) { Logger.LogWarning("Enemy \"" + enemyContent.Name + "\" has a null spawn object."); continue; } string prefabId = "Enemies/" + ((Object)item).name; PrefabRefResponse prefabRefResponse = NetworkPrefabs.RegisterNetworkPrefabInternal(prefabId, item); PrefabRef prefabRef = prefabRefResponse.PrefabRef; if (prefabRefResponse.Result == PrefabRefResult.DifferentPrefabAlreadyRegistered) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\" spawn object. A prefab is already registered with the same name."); continue; } if (prefabRefResponse.Result != 0 && prefabRefResponse.Result != PrefabRefResult.PrefabAlreadyRegistered) { Logger.LogError($"Failed to register enemy \"{enemyContent.Name}\" spawn object. (Reason: {prefabRefResponse.Result})"); continue; } if (prefabRef == null) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\" spawn object. PrefabRef is null."); continue; } if (prefabRefResponse.Result == PrefabRefResult.Success) { Utilities.FixAudioMixerGroups(item); } list.Add(prefabRef); } if (list.Count == 0) { Logger.LogError("Failed to register enemy \"" + enemyContent.Name + "\". No valid spawn objects found."); return; } enemySetup.spawnObjects = list; _enemiesToRegister.Add(enemySetup); } public static List<EnemyParent>? SpawnEnemy(EnemySetup? enemySetup, Vector3 position, Quaternion rotation, bool spawnDespawned = false) { //IL_0107: 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_025f: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemySetup == (Object)null) { Logger.LogError("Failed to spawn enemy. EnemySetup is null."); return null; } if (!enemySetup.TryGetEnemyParent(out EnemyParent enemyParent)) { Logger.LogError("Failed to spawn enemy. EnemyParent is null."); return null; } if ((Object)(object)LevelGenerator.Instance == (Object)null) { Logger.LogError("Failed to spawn enemy \"" + enemyParent.enemyName + "\". EnemySetup instance is null."); return null; } if ((Object)(object)RunManager.instance == (Object)null) { Logger.LogError("Failed to spawn enemy \"" + enemyParent.enemyName + "\". RunManager instance is null."); return null; } if ((Object)(object)EnemyDirector.instance == (Object)null) { Logger.LogError("Failed to spawn enemy \"" + enemyParent.enemyName + "\". EnemyDirector instance is null."); return null; } RunManager.instance.EnemiesSpawnedRemoveStart(); List<EnemyParent> list = new List<EnemyParent>(); EnemyParent val2 = default(EnemyParent); foreach (PrefabRef spawnObject in enemySetup.spawnObjects) { GameObject prefab = spawnObject.Prefab; if ((Object)(object)prefab == (Object)null) { Logger.LogError("Failed to spawn enemy \"" + enemyParent.enemyName + "\" spawn object. GameObject is null."); continue; } GameObject val = NetworkPrefabs.SpawnNetworkPrefab(spawnObject, position, rotation, 0); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to spawn enemy \"" + enemyParent.enemyName + "\" spawn object \"" + ((Object)prefab).name + "\""); } else if (val.TryGetComponent<EnemyParent>(ref val2)) { list.Add(val2); if (!spawnDespawned) { SpawnNextEnemiesNotDespawned++; } val2.SetupDone = true; Enemy componentInChildren = val.GetComponentInChildren<Enemy>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.EnemyTeleported(position); } else { Logger.LogError("Enemy \"" + enemyParent.enemyName + "\" spawn object \"" + ((Object)prefab).name + "\" does not have an enemy component."); } val2.firstSpawnPointUsed = true; LevelGenerator instance = LevelGenerator.Instance; instance.EnemiesSpawnTarget++; EnemyDirector.instance.FirstSpawnPointAdd(val2); } } RunManager.instance.EnemiesSpawnedRemoveEnd(); if (list.Count == 0) { Logger.LogInfo("Failed to spawn enemy \"" + enemyParent.enemyName + "\". No spawn objects where spawned."); return list; } Logger.LogInfo($"Spawned enemy \"{enemyParent.enemyName}\" at position {position}", extended: true); return list; } [Obsolete("This is no longer supported. Use AllEnemies or RegisteredEnemies instead.", true)] public static IReadOnlyList<EnemySetup> GetEnemies() { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return AllEnemies; } [Obsolete("This is no longer supported. Use AllEnemies or RegisteredEnemies instead.", true)] public static bool TryGetEnemyByName(string name, [NotNullWhen(true)] out EnemySetup? enemySetup) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); enemySetup = null; return false; } [Obsolete("This is no longer supported. Use AllEnemies or RegisteredEnemies instead.", true)] public static EnemySetup? GetEnemyByName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } [Obsolete("This is no longer supported. Use AllEnemies or RegisteredEnemies instead.", true)] public static bool TryGetEnemyThatContainsName(string name, [NotNullWhen(true)] out EnemySetup? enemySetup) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); enemySetup = null; return false; } [Obsolete("This is no longer supported. Use AllEnemies or RegisteredEnemies instead.", true)] public static EnemySetup? GetEnemyThatContainsName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } } public static class Items { private static readonly List<Item> _itemsToRegister = new List<Item>(); private static readonly List<Item> _itemsRegistered = new List<Item>(); private static bool _initialItemsRegistered; public static IReadOnlyList<Item> AllItems => StatsManager.instance?.GetItems() ?? new List<Item>(); public static IReadOnlyList<Item> RegisteredItems => _itemsRegistered; internal static void RegisterItems() { Logger.LogInfo("Adding items."); foreach (Item item in _itemsToRegister) { RegisterItemWithGame(item); } _initialItemsRegistered = true; } private static void RegisterItemWithGame(Item item) { if (StatsManager.instance.AddItem(item)) { if (!_itemsRegistered.Contains(item)) { _itemsRegistered.Add(item); } Logger.LogInfo("Added item \"" + item.itemName + "\" to StatsManager.", extended: true); } else { Logger.LogWarning("Failed to add item \"" + item.itemName + "\" to StatsManager.", extended: true); } } public static PrefabRef? RegisterItem(ItemAttributes? itemAttributes) { if ((Object)(object)itemAttributes == (Object)null) { Logger.LogError("Failed to register item. ItemAttributes is null."); return null; } Item item = itemAttributes.item; if ((Object)(object)item == (Object)null) { Logger.LogError("Failed to register item. Item is null."); return null; } GameObject gameObject = ((Component)itemAttributes).gameObject; string prefabId = "Items/" + ((Object)gameObject).name; PrefabRefResponse prefabRefResponse = NetworkPrefabs.RegisterNetworkPrefabInternal(prefabId, gameObject); PrefabRef prefabRef = prefabRefResponse.PrefabRef; if (prefabRefResponse.Result == PrefabRefResult.PrefabAlreadyRegistered) { Logger.LogWarning("Failed to register item \"" + item.itemName + "\". Item is already registered!"); return null; } if (prefabRefResponse.Result == PrefabRefResult.DifferentPrefabAlreadyRegistered) { Logger.LogError("Failed to register item \"" + item.itemName + "\". A item prefab is already registered with the same name."); return null; } if (prefabRefResponse.Result != 0) { Logger.LogError($"Failed to register item \"{((Object)gameObject).name}\". (Reason: {prefabRefResponse.Result})"); return null; } if (prefabRef == null) { Logger.LogError("Failed to register item \"" + ((Object)gameObject).name + "\". PrefabRef is null."); return null; } item.prefab = prefabRef; Utilities.FixAudioMixerGroups(gameObject); _itemsToRegister.Add(item); if (_initialItemsRegistered) { RegisterItemWithGame(item); } return prefabRef; } public static PrefabRef? RegisterItem(ItemContent? itemContent) { if ((Object)(object)itemContent == (Object)null) { Logger.LogError("Failed to register item. ItemContent is null."); return null; } return RegisterItem(itemContent.Prefab); } public static GameObject? SpawnItem(Item? item, Vector3 position, Quaternion rotation) { //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_00a5: 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) if ((Object)(object)item == (Object)null) { Logger.LogError("Failed to spawn item. Item is null."); return null; } if (!item.prefab.IsValid()) { Logger.LogError("Failed to spawn item \"" + item.itemName + "\". PrefabRef is not valid."); return null; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { Logger.LogError("Failed to spawn item \"" + item.itemName + "\". You are not the host."); return null; } GameObject val = NetworkPrefabs.SpawnNetworkPrefab(item.prefab, position, rotation, 0); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to spawn item \"" + item.itemName + "\". Spawned GameObject is null."); return null; } Logger.LogInfo($"Spawned item \"{item.itemName}\" at position {position}, rotation: {((Quaternion)(ref rotation)).eulerAngles}", extended: true); return val; } [Obsolete("This is no longer supported. Use AllItems or RegisteredItems instead.", true)] public static IReadOnlyList<Item> GetItems() { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return AllItems; } [Obsolete("This is no longer supported. Use AllItems or RegisteredItems instead.", true)] public static bool TryGetItemByName(string name, [NotNullWhen(true)] out Item? item) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); item = null; return false; } [Obsolete("This is no longer supported. Use AllItems or RegisteredItems instead.", true)] public static Item? GetItemByName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } [Obsolete("This is no longer supported. Use AllItems or RegisteredItems instead.", true)] public static bool TryGetItemThatContainsName(string name, [NotNullWhen(true)] out Item? item) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); item = null; return false; } [Obsolete("This is no longer supported. Use AllItems or RegisteredItems instead.", true)] public static Item? GetItemThatContainsName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } } internal static class LevelAmbiences { private static readonly List<LevelAmbience> _levelAmbiencesRegistered = new List<LevelAmbience>(); private static readonly List<Level> _levelToProcess = new List<Level>(); private static readonly List<Level> _levelsProcessed = new List<Level>(); private static bool _initialLevelAmbiencesRegistered; public static IReadOnlyList<LevelAmbience> AllLevelAmbiences => AudioManager.instance?.levelAmbiences ?? new List<LevelAmbience>(); public static IReadOnlyList<LevelAmbience> RegisteredLevelAmbiences => _levelAmbiencesRegistered; internal static void RegisterLevelAmbiences() { if (_initialLevelAmbiencesRegistered) { foreach (LevelAmbience item in _levelAmbiencesRegistered) { AddLevelAmbienceToAudioManager(item); } return; } Logger.LogInfo("Adding level ambiences."); foreach (Level item2 in _levelToProcess) { RegisterLevelAmbiencesWithGame(item2); } _initialLevelAmbiencesRegistered = true; } private static void AddLevelAmbienceToAudioManager(LevelAmbience levelAmbience) { if (!AllLevelAmbiences.Contains(levelAmbience)) { AudioManager.instance.levelAmbiences.Add(levelAmbience); Logger.LogInfo("Added level ambience \"" + ((Object)levelAmbience).name + "\" to AudioManager.", extended: true); } } private static void RegisterLevelAmbiencesWithGame(Level level) { if (_levelsProcessed.Contains(level)) { return; } for (int i = 0; i < level.AmbiencePresets.Count; i++) { LevelAmbience val = level.AmbiencePresets[i]; if (!AudioManager.instance.levelAmbiences.Contains(val)) { if (TryGetLevelAmbience(((Object)val).name, out LevelAmbience levelAmbience)) { level.AmbiencePresets[i] = levelAmbience; Logger.LogInfo("Replaced existing level ambience \"" + ((Object)val).name + "\" in level \"" + ((Object)level).name + "\"", extended: true); } else { AddLevelAmbienceToAudioManager(val); _levelAmbiencesRegistered.Add(val); Logger.LogInfo("Registered level ambience \"" + ((Object)val).name + "\" from level \"" + ((Object)level).name + "\"", extended: true); } } } _levelsProcessed.Add(level); } public static void RegisterLevelAmbience(Level? level) { if ((Object)(object)level == (Object)null) { Logger.LogError("Failed to register level ambience for level. Level is null."); return; } if (_levelToProcess.Contains(level)) { Logger.LogWarning("Failed to register level ambience for level \"" + ((Object)level).name + "\". Level has already been processed!"); return; } _levelToProcess.Add(level); if (_initialLevelAmbiencesRegistered) { RegisterLevelAmbiencesWithGame(level); } } private static bool TryGetLevelAmbience(string name, [NotNullWhen(true)] out LevelAmbience? levelAmbience) { string name2 = name; levelAmbience = ((IEnumerable<LevelAmbience>)AllLevelAmbiences).FirstOrDefault((Func<LevelAmbience, bool>)((LevelAmbience x) => ((Object)x).name == name2)); return (Object)(object)levelAmbience != (Object)null; } } public static class Levels { private enum ModuleType { StartRoom, Normal, Passage, DeadEnd, Extraction } private static readonly List<Level> _levelsToRegister = new List<Level>(); private static readonly List<Level> _levelsRegistered = new List<Level>(); private static bool _initialLevelsRegistered; public static IReadOnlyList<Level> AllLevels => RunManager.instance?.levels ?? new List<Level>(); public static IReadOnlyList<Level> RegisteredLevels => _levelsRegistered; internal static void RegisterInitialLevels() { if (_initialLevelsRegistered) { return; } Logger.LogInfo("Adding levels."); foreach (Level item in _levelsToRegister) { RegisterLevelWithGame(item); } _initialLevelsRegistered = true; } private static void RegisterLevelWithGame(Level level) { if (!_levelsRegistered.Contains(level)) { RegisterLevelValuablePresets(level); LevelAmbiences.RegisterLevelAmbience(level); RunManager.instance.levels.Add(level); Logger.LogInfo("Added level \"" + ((Object)level).name + "\"", extended: true); _levelsRegistered.Add(level); } } private static void RegisterLevelValuablePresets(Level level) { if (level.ValuablePresets.Count == 0) { Logger.LogWarning("Level \"" + ((Object)level).name + "\" does not have any valuable presets! Adding generic preset."); level.ValuablePresets.Add(ValuablePresets.GenericValuablePreset); return; } for (int i = 0; i < level.ValuablePresets.Count; i++) { LevelValuables val = level.ValuablePresets[i]; if (!ValuablePresets.AllValuablePresets.Values.Contains(val)) { if (ValuablePresets.AllValuablePresets.TryGetValue(((Object)val).name, out LevelValuables value)) { level.ValuablePresets[i] = value; Logger.LogInfo("Replaced proxy valuable preset \"" + ((Object)val).name + "\" in level \"" + ((Object)level).name + "\"", extended: true); } else { ValuablePresets.RegisterValuablePreset(val); Logger.LogInfo("Registered valuable preset \"" + ((Object)val).name + "\" from level \"" + ((Object)level).name + "\"", extended: true); } } } } public static void RegisterLevel(LevelContent? levelContent) { if ((Object)(object)levelContent == (Object)null) { Logger.LogError("Failed to register level. LevelContent is null."); return; } Level level = levelContent.Level; if ((Object)(object)level == (Object)null) { Logger.LogError("Failed to register level. Level is null."); return; } if (_levelsToRegister.Contains(level)) { Logger.LogWarning("Failed to register level \"" + ((Object)level).name + "\". Level is already registered!"); return; } if (_levelsToRegister.Any((Level x) => ((Object)x).name.Equals(((Object)level).name, StringComparison.OrdinalIgnoreCase))) { Logger.LogError("Failed to register level \"" + ((Object)level).name + "\". Level already exists with the same name."); return; } GameObject connectObject = levelContent.ConnectObject; if ((Object)(object)connectObject != (Object)null) { RegisterLevelPrefab("Level/" + level.ResourcePath + "/Other/" + ((Object)connectObject).name, connectObject); level.ConnectObject = connectObject; } GameObject blockObject = levelContent.BlockObject; if ((Object)(object)blockObject != (Object)null) { RegisterLevelPrefab("Level/" + level.ResourcePath + "/Other/" + ((Object)blockObject).name, blockObject); level.BlockObject = blockObject; } level.StartRooms = RegisterLevelModules(level, ModuleType.StartRoom, levelContent.StartRooms); level.ModulesNormal1 = RegisterLevelModules(level, ModuleType.Normal, levelContent.ModulesNormal1); level.ModulesPassage1 = RegisterLevelModules(level, ModuleType.Passage, levelContent.ModulesPassage1); level.ModulesDeadEnd1 = RegisterLevelModules(level, ModuleType.DeadEnd, levelContent.ModulesDeadEnd1); level.ModulesExtraction1 = RegisterLevelModules(level, ModuleType.Extraction, levelContent.ModulesExtraction1); level.ModulesNormal2 = RegisterLevelModules(level, ModuleType.Normal, levelContent.ModulesNormal2); level.ModulesPassage2 = RegisterLevelModules(level, ModuleType.Passage, levelContent.ModulesPassage2); level.ModulesDeadEnd2 = RegisterLevelModules(level, ModuleType.DeadEnd, levelContent.ModulesDeadEnd2); level.ModulesExtraction2 = RegisterLevelModules(level, ModuleType.Extraction, levelContent.ModulesExtraction2); level.ModulesNormal3 = RegisterLevelModules(level, ModuleType.Normal, levelContent.ModulesNormal3); level.ModulesPassage3 = RegisterLevelModules(level, ModuleType.Passage, levelContent.ModulesPassage3); level.ModulesDeadEnd3 = RegisterLevelModules(level, ModuleType.DeadEnd, levelContent.ModulesDeadEnd3); level.ModulesExtraction3 = RegisterLevelModules(level, ModuleType.Extraction, levelContent.ModulesExtraction3); _levelsToRegister.Add(level); if (_initialLevelsRegistered) { RegisterLevelWithGame(level); } } private static List<PrefabRef> RegisterLevelModules(Level level, ModuleType moduleType, List<GameObject> modules) { List<PrefabRef> list = new List<PrefabRef>(); foreach (GameObject module in modules) { string prefabId = $"Level/{((Object)level).name}/{moduleType}/{((Object)module).name}"; PrefabRef val = RegisterLevelPrefab(prefabId, module); if (val != null) { list.Add(val); } } return list; } private static PrefabRef? RegisterLevelPrefab(string prefabId, GameObject prefab) { PrefabRefResponse prefabRefResponse = NetworkPrefabs.RegisterNetworkPrefabInternal(prefabId, prefab); if (prefabRefResponse.Result == PrefabRefResult.Success) { Utilities.FixAudioMixerGroups(prefab); return prefabRefResponse.PrefabRef; } if (prefabRefResponse.Result == PrefabRefResult.PrefabAlreadyRegistered) { return prefabRefResponse.PrefabRef; } if (prefabRefResponse.Result == PrefabRefResult.DifferentPrefabAlreadyRegistered) { Logger.LogError("Failed to register level network prefab \"" + prefabId + "\". A prefab is already registered with the same prefab ID."); return null; } Logger.LogError($"Failed to register level network prefab \"{prefabId}\". (Reason: {prefabRefResponse.Result})"); return null; } [Obsolete("This is no longer supported. Use AllLevels or RegisteredLevels instead.", true)] public static IReadOnlyList<Level> GetLevels() { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return AllLevels; } [Obsolete("This is no longer supported. Use AllLevels or RegisteredLevels instead.", true)] public static bool TryGetLevelByName(string name, [NotNullWhen(true)] out Level? level) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); level = null; return false; } [Obsolete("This is no longer supported. Use AllLevels or RegisteredLevels instead.", true)] public static Level? GetLevelByName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } [Obsolete("This is no longer supported. Use AllLevels or RegisteredLevels instead.", true)] public static bool TryGetLevelThatContainsName(string name, [NotNullWhen(true)] out Level? level) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); level = null; return false; } [Obsolete("This is no longer supported. Use AllLevels or RegisteredLevels instead.", true)] public static Level? GetLevelThatContainsName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } } public static class NetworkingEvents { public static readonly byte[] ReservedEventCodes = new byte[3] { 0, 1, 2 }; private static readonly List<NetworkedEvent> _customEvents = new List<NetworkedEvent>(); public static readonly RaiseEventOptions RaiseAll = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; public static readonly RaiseEventOptions RaiseOthers = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; public static readonly RaiseEventOptions RaiseMasterClient = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; public static IReadOnlyList<NetworkedEvent> CustomEvents => _customEvents; internal static void Initialize() { PhotonNetwork.NetworkingClient.EventReceived += OnEvent; Application.quitting += delegate { PhotonNetwork.NetworkingClient.EventReceived -= OnEvent; }; } internal static void AddCustomEvent(NetworkedEvent networkedEvent) { if (!_customEvents.Contains(networkedEvent)) { _customEvents.Add(networkedEvent); } } private static void OnEvent(EventData photonEvent) { EventData photonEvent2 = photonEvent; _customEvents.FirstOrDefault((NetworkedEvent e) => e.EventCode == photonEvent2.Code)?.EventAction?.Invoke(photonEvent2); } internal static bool TryGetUniqueEventCode(out byte eventCode) { eventCode = 0; while (IsEventCodeTaken(eventCode) && eventCode < 200) { eventCode++; } if (eventCode > 200 || (eventCode == 200 && IsEventCodeTaken(eventCode))) { eventCode = 0; return false; } return true; } public static bool IsEventCodeTaken(byte eventCode) { if (ReservedEventCodes.Any((byte x) => x == eventCode)) { return true; } if (_customEvents.Any((NetworkedEvent x) => x.EventCode == eventCode)) { return true; } return false; } } public class NetworkedEvent { public string Name { get; private set; } public byte EventCode { get; private set; } public Action<EventData> EventAction { get; private set; } public NetworkedEvent(string name, Action<EventData> eventAction) { Name = name; EventAction = eventAction; if (NetworkingEvents.TryGetUniqueEventCode(out var eventCode)) { EventCode = eventCode; NetworkingEvents.AddCustomEvent(this); Logger.LogInfo($"Registered NetworkedEvent \"{Name}\" with event code: {EventCode}", extended: true); } else { Logger.LogError("Failed to register NetworkedEvent \"" + Name + "\". Could not get unique event code."); } } public void RaiseEvent(object eventContent, RaiseEventOptions raiseEventOptions, SendOptions sendOptions) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMultiplayer()) { PhotonNetwork.RaiseEvent(EventCode, eventContent, raiseEventOptions, sendOptions); } else if ((int)raiseEventOptions.Receivers != 0) { RaiseEventSingleplayer(eventContent); } } private void RaiseEventSingleplayer(object eventContent) { //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_001a: Expected O, but got Unknown if (!SemiFunc.IsMultiplayer()) { EventData val = new EventData { Code = EventCode }; val.Parameters[val.CustomDataKey] = eventContent; val.Parameters[val.SenderKey] = 1; EventAction?.Invoke(val); } } } public static class NetworkPrefabs { private static readonly Dictionary<string, GameObject> _prefabs = new Dictionary<string, GameObject>(); private static readonly Dictionary<string, PrefabRef> _prefabRefs = new Dictionary<string, PrefabRef>(); public static IReadOnlyDictionary<string, GameObject> Prefabs => _prefabs; public static IReadOnlyDictionary<string, PrefabRef> PrefabRefs => _prefabRefs; public static PrefabRef? RegisterNetworkPrefab(GameObject prefab) { return RegisterNetworkPrefab(((Object)prefab).name, prefab); } public static PrefabRef? RegisterNetworkPrefab(string prefabId, GameObject prefab) { PrefabRefResponse prefabRefResponse = RegisterNetworkPrefabInternal(prefabId, prefab); switch (prefabRefResponse.Result) { case PrefabRefResult.Success: return prefabRefResponse.PrefabRef; case PrefabRefResult.PrefabIdNullOrEmpty: Logger.LogError("Failed to register network prefab. PrefabId is null."); return null; case PrefabRefResult.PrefabNull: Logger.LogError("Failed to register network prefab. Prefab is null."); return null; case PrefabRefResult.PrefabAlreadyRegistered: Logger.LogWarning("Failed to register network prefab \"" + prefabId + "\". Prefab is already registered."); return prefabRefResponse.PrefabRef; case PrefabRefResult.DifferentPrefabAlreadyRegistered: Logger.LogError("Failed to register network prefab \"" + prefabId + "\". A prefab is already registered with the same ID. (GameObject: \"" + ((Object)prefabRefResponse.PrefabRef.Prefab).name + "\")"); return null; default: return prefabRefResponse.PrefabRef; } } internal static PrefabRefResponse RegisterNetworkPrefabInternal(string prefabId, GameObject prefab) { //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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if (string.IsNullOrEmpty(prefabId)) { return new PrefabRefResponse(PrefabRefResult.PrefabIdNullOrEmpty, null); } if ((Object)(object)prefab == (Object)null) { return new PrefabRefResponse(PrefabRefResult.PrefabNull, null); } PrefabRef networkPrefabRef = GetNetworkPrefabRef(prefabId); if (networkPrefabRef != null) { GameObject prefab2 = networkPrefabRef.Prefab; if ((Object)(object)prefab == (Object)(object)prefab2) { return new PrefabRefResponse(PrefabRefResult.PrefabAlreadyRegistered, networkPrefabRef); } return new PrefabRefResponse(PrefabRefResult.DifferentPrefabAlreadyRegistered, networkPrefabRef); } PrefabRef val = new PrefabRef { prefabName = ((Object)prefab).name, resourcePath = prefabId }; _prefabs.Add(prefabId, prefab); _prefabRefs.Add(prefabId, val); return new PrefabRefResponse(PrefabRefResult.Success, val); } public static bool HasNetworkPrefab(string prefabId) { return _prefabs.ContainsKey(prefabId); } public static PrefabRef? GetNetworkPrefabRef(string prefabId) { return _prefabRefs.GetValueOrDefault(prefabId); } public static bool TryGetNetworkPrefabRef(string prefabId, [NotNullWhen(true)] out PrefabRef? prefabRef) { prefabRef = GetNetworkPrefabRef(prefabId); return prefabRef != null; } internal static bool TryGetNetworkPrefab(string prefabId, [NotNullWhen(true)] out GameObject? prefab) { prefab = _prefabs.GetValueOrDefault(prefabId); return (Object)(object)prefab != (Object)null; } public static GameObject? SpawnNetworkPrefab(PrefabRef prefabRef, Vector3 position, Quaternion rotation, byte group = 0, object[]? data = null) { //IL_0057: 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_0046: 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 (!prefabRef.IsValid()) { Logger.LogError("Failed to spawn network prefab. PrefabRef is not valid."); return null; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { Logger.LogError("Failed to spawn network prefab \"" + prefabRef.PrefabName + "\". You are not the host."); return null; } if (SemiFunc.IsMultiplayer()) { return PhotonNetwork.InstantiateRoomObject(prefabRef.ResourcePath, position, rotation, group, data); } return Object.Instantiate<GameObject>(prefabRef.Prefab, position, rotation); } } public static class Upgrades { private static readonly Dictionary<string, PlayerUpgrade> _playerUpgrades = new Dictionary<string, PlayerUpgrade>(); private static NetworkedEvent? _upgradeEvent; public static IReadOnlyList<PlayerUpgrade> PlayerUpgrades => _playerUpgrades.Values.ToList(); internal static void Initialize() { _upgradeEvent = new NetworkedEvent("REPOLib Upgrade", HandleUpgradeEvent); } internal static void RegisterUpgrades() { if ((Object)(object)StatsManager.instance == (Object)null) { Logger.LogError("Upgrades: Failed to register upgrades. StatsManager instance is null."); return; } foreach (KeyValuePair<string, PlayerUpgrade> playerUpgrade in _playerUpgrades) { string text = "playerUpgrade" + playerUpgrade.Key; Dictionary<string, int> playerDictionary = playerUpgrade.Value.PlayerDictionary; if (StatsManager.instance.dictionaryOfDictionaries.TryGetValue(text, out var value)) { playerDictionary = value; Logger.LogInfo("Upgrades: Loaded upgrade \"" + text + "\" from StatsManager.", extended: true); } else { playerDictionary.Clear(); StatsManager.instance.dictionaryOfDictionaries.Add(text, playerDictionary); Logger.LogInfo("Upgrades: Added upgrade \"" + text + "\" to StatsManager.", extended: true); } } } internal static void InvokeStartActions(string steamId) { PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(steamId); if ((Object)(object)val == (Object)null) { return; } string arg = SemiFunc.PlayerGetName(val); foreach (PlayerUpgrade playerUpgrade in PlayerUpgrades) { if (playerUpgrade.StartAction != null) { try { int level = playerUpgrade.GetLevel(steamId); playerUpgrade.StartAction(val, level); Logger.LogDebug($"Upgrades: Invoked start action for upgrade \"{playerUpgrade.UpgradeId}\" on player \"{arg}\" at level {level}"); } catch (Exception arg2) { Logger.LogError($"Upgrades: Failed to invoke start action for upgrade \"{playerUpgrade.UpgradeId}\" on player \"{arg}\". {arg2}"); } } } } internal static void RaiseUpgradeEvent(string upgradeId, string steamId, int level) { //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_0019: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0037: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (_upgradeEvent != null) { Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"UpgradeId", (object)upgradeId); ((Dictionary<object, object>)val).Add((object)"SteamId", (object)steamId); ((Dictionary<object, object>)val).Add((object)"Level", (object)level); Hashtable eventContent = val; _upgradeEvent.RaiseEvent(eventContent, NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } } private static void HandleUpgradeEvent(EventData eventData) { object customData = eventData.CustomData; Hashtable val = (Hashtable)((customData is Hashtable) ? customData : null); if (val != null) { string upgradeId = (string)val[(object)"UpgradeId"]; string steamId = (string)val[(object)"SteamId"]; int level = (int)val[(object)"Level"]; if (TryGetUpgrade(upgradeId, out PlayerUpgrade playerUpgrade)) { playerUpgrade.ApplyUpgrade(steamId, level); } } } public static PlayerUpgrade? RegisterUpgrade(string upgradeId, Item? item, Action<PlayerAvatar, int>? startAction, Action<PlayerAvatar, int>? upgradeAction) { if (_playerUpgrades.ContainsKey(upgradeId)) { Logger.LogError("Failed to register upgrade \"" + upgradeId + "\". An upgrade with this UpgradeId has already been registered."); return null; } PlayerUpgrade playerUpgrade = new PlayerUpgrade(upgradeId, item, startAction, upgradeAction); _playerUpgrades.Add(upgradeId, playerUpgrade); return playerUpgrade; } public static PlayerUpgrade? GetUpgrade(string upgradeId) { if (_playerUpgrades.TryGetValue(upgradeId, out PlayerUpgrade value)) { return value; } return null; } public static bool TryGetUpgrade(string upgradeId, [NotNullWhen(true)] out PlayerUpgrade? playerUpgrade) { playerUpgrade = GetUpgrade(upgradeId); return playerUpgrade != null; } } public class PlayerUpgrade { public readonly string UpgradeId; public readonly Item? Item; public Dictionary<string, int> PlayerDictionary = new Dictionary<string, int>(); internal readonly Action<PlayerAvatar, int>? StartAction; private readonly Action<PlayerAvatar, int>? _upgradeAction; internal PlayerUpgrade(string upgradeId, Item? item, Action<PlayerAvatar, int>? startAction, Action<PlayerAvatar, int>? upgradeAction) { UpgradeId = upgradeId; Item = item; StartAction = startAction; _upgradeAction = upgradeAction; } public int GetLevel(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return 0; } return GetLevel(playerAvatar.steamID); } public int GetLevel(string steamId) { if (PlayerDictionary.TryGetValue(steamId, out var value)) { return value; } return 0; } public int AddLevel(PlayerAvatar playerAvatar, int amount = 1) { if ((Object)(object)playerAvatar == (Object)null) { return 0; } return AddLevel(playerAvatar.steamID, amount); } public int AddLevel(string steamId, int amount = 1) { return ChangeLevelBy(steamId, amount); } public int RemoveLevel(PlayerAvatar playerAvatar, int amount = 1) { if ((Object)(object)playerAvatar == (Object)null) { return 0; } return RemoveLevel(playerAvatar.steamID, amount); } public int RemoveLevel(string steamId, int amount = 1) { return ChangeLevelBy(steamId, -amount); } public int SetLevel(PlayerAvatar playerAvatar, int level) { if ((Object)(object)playerAvatar == (Object)null) { return 0; } return SetLevel(playerAvatar.steamID, level); } public int SetLevel(string steamId, int level) { level = Mathf.Max(level, 0); PlayerDictionary[steamId] = level; ApplyUpgrade(steamId, level); Upgrades.RaiseUpgradeEvent(UpgradeId, steamId, level); return level; } private int ChangeLevelBy(string steamId, int amount) { int level = GetLevel(steamId); level += amount; return SetLevel(steamId, level); } internal void ApplyUpgrade(string steamId, int level) { PlayerDictionary[steamId] = level; if (_upgradeAction == null) { return; } PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(steamId); if ((Object)(object)val == (Object)null) { return; } string arg = SemiFunc.PlayerGetName(val); try { _upgradeAction(val, GetLevel(steamId)); Logger.LogDebug($"PlayerUpgrade: Invoked upgrade action for upgrade \"{UpgradeId}\" on player \"{arg}\" at level {level}"); } catch (Exception arg2) { Logger.LogError($"PlayerUpgrade: Failed to invoke upgrade action for upgrade \"{UpgradeId}\" on player \"{arg}\". {arg2}"); } } } public class REPOLibItemUpgrade : MonoBehaviour { [SerializeField] private string _upgradeId; private ItemToggle _itemToggle; public string UpgradeId => _upgradeId; private void Start() { _itemToggle = ((Component)this).GetComponent<ItemToggle>(); } public void Upgrade() { if ((Object)(object)_itemToggle == (Object)null) { Logger.LogError("REPOLibItemUpgrade: Failed to upgrade \"" + UpgradeId + "\". ItemToggle is null."); return; } int playerTogglePhotonID = _itemToggle.playerTogglePhotonID; PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(playerTogglePhotonID); if ((Object)(object)val == (Object)null) { Logger.LogError($"REPOLibItemUpgrade: Failed to upgrade \"{UpgradeId}\". Could not find PlayerAvatar from ItemToggle's playerTogglePhotonID {playerTogglePhotonID}."); } else if (val.isLocal) { if (!Upgrades.TryGetUpgrade(UpgradeId, out PlayerUpgrade playerUpgrade)) { Logger.LogError("REPOLibItemUpgrade: Failed to upgrade \"" + UpgradeId + "\". Could not find PlayerUpgrade from UpgradeId."); } else { playerUpgrade.AddLevel(val); } } } } public static class Utilities { private static readonly List<GameObject> _prefabsToFix = new List<GameObject>(); private static readonly List<GameObject> _fixedPrefabs = new List<GameObject>(); internal static void FixAudioMixerGroupsOnPrefabs() { foreach (GameObject item in _prefabsToFix) { item.FixAudioMixerGroups(); _fixedPrefabs.Add(item); } _prefabsToFix.Clear(); } public static void FixAudioMixerGroups(GameObject prefab) { if (!((Object)(object)prefab == (Object)null) && !_prefabsToFix.Contains(prefab) && !_fixedPrefabs.Contains(prefab)) { if ((Object)(object)AudioManager.instance == (Object)null) { _prefabsToFix.Add(prefab); return; } prefab.FixAudioMixerGroups(); _fixedPrefabs.Add(prefab); } } internal static void SafeInvokeEvent(Action? action) { try { action?.Invoke(); } catch (Exception arg) { Logger.LogError($"Exception occured while invoking event: {arg}"); } } internal static string GetStackTrace() { StackTrace stackTrace = new StackTrace(1, fNeedFileInfo: true); return stackTrace.ToString(); } } public static class ValuablePresets { private static readonly Dictionary<string, LevelValuables> _valuablePresets = new Dictionary<string, LevelValuables>(); public const string GenericValuablePresetName = "Valuables - Generic"; public static IReadOnlyDictionary<string, LevelValuables> AllValuablePresets => _valuablePresets; public static LevelValuables GenericValuablePreset => AllValuablePresets.GetValueOrDefault("Valuables - Generic"); [Obsolete("Use GenericValuablePreset instead.", true)] public static LevelValuables GenericPreset => GenericValuablePreset; internal static void Initialize() { if ((Object)(object)RunManager.instance == (Object)null) { Logger.LogError("Failed to initialize ValuablePresets. RunManager instance is null."); return; } AddValuablePresets(RunManager.instance.levelArena.ValuablePresets); foreach (Level level in RunManager.instance.levels) { AddValuablePresets(level.ValuablePresets); } AddGenericValuablePresetToVanillaLevels(); } private static void AddGenericValuablePresetToVanillaLevels() { LevelValuables genericValuablePreset = GenericValuablePreset; if ((Object)(object)genericValuablePreset == (Object)null) { Logger.LogError("Failed to add \"Valuables - Generic\" valuable preset to vanilla levels. Valuable preset is null."); return; } genericValuablePreset.tiny.Clear(); genericValuablePreset.small.Clear(); genericValuablePreset.medium.Clear(); genericValuablePreset.big.Clear(); genericValuablePreset.wide.Clear(); genericValuablePreset.tall.Clear(); genericValuablePreset.veryTall.Clear(); foreach (Level level in RunManager.instance.levels) { if (level.ValuablePresets.Contains(genericValuablePreset)) { Logger.LogInfo("Level \"" + ((Object)level).name + "\" already has the valuable preset \"" + ((Object)genericValuablePreset).name + "\"", extended: true); } else { level.ValuablePresets.Add(genericValuablePreset); Logger.LogInfo("Added valuable preset \"" + ((Object)genericValuablePreset).name + "\" to level \"" + ((Object)level).name + "\"", extended: true); } } } private static void AddValuablePresets(List<LevelValuables> valuablePresets) { foreach (LevelValuables valuablePreset in valuablePresets) { _valuablePresets.TryAdd(((Object)valuablePreset).name, valuablePreset); } } internal static void RegisterValuablePreset(LevelValuables valuablePreset) { RemoveMissingValuables(valuablePreset, valuablePreset.tiny); RemoveMissingValuables(valuablePreset, valuablePreset.small); RemoveMissingValuables(valuablePreset, valuablePreset.medium); RemoveMissingValuables(valuablePreset, valuablePreset.big); RemoveMissingValuables(valuablePreset, valuablePreset.wide); RemoveMissingValuables(valuablePreset, valuablePreset.tall); RemoveMissingValuables(valuablePreset, valuablePreset.veryTall); _valuablePresets.Add(((Object)valuablePreset).name, valuablePreset); } private static void RemoveMissingValuables(LevelValuables valuablePreset, List<PrefabRef> prefabRefs) { int count = prefabRefs.Count; for (int num = count - 1; num >= 0; num--) { PrefabRef val = prefabRefs[num]; if (!val.IsValid() || (Object)(object)Resources.Load<GameObject>(val.ResourcePath) == (Object)null) { Logger.LogWarning($"Valuable preset \"{((Object)valuablePreset).name}\" has an invalid vanilla valuable PrefabRef at index {num} (PrefabName: \"{val.PrefabName}\", ResourcePath: \"{val.ResourcePath}\")"); prefabRefs.RemoveAt(num); } } } } public static class Valuables { private static readonly Dictionary<PrefabRef, List<string>> _valuablesToRegister = new Dictionary<PrefabRef, List<string>>(); private static readonly List<PrefabRef> _valuablesRegistered = new List<PrefabRef>(); private static bool _initialValuablesRegistered; public static IReadOnlyList<PrefabRef> AllValuables { get { if ((Object)(object)RunManager.instance == (Object)null) { return Array.Empty<PrefabRef>(); } return ValuablePresets.AllValuablePresets.Values.Select((LevelValuables levelValuables) => levelValuables.GetCombinedList()).SelectMany((List<PrefabRef> list) => list).Distinct() .ToList(); } } public static IReadOnlyList<PrefabRef> RegisteredValuables => _valuablesRegistered; internal static void RegisterInitialValuables() { if (_initialValuablesRegistered) { return; } Logger.LogInfo("Adding valuables to valuable presets."); foreach (PrefabRef key in _valuablesToRegister.Keys) { RegisterValuableWithGame(key); } _valuablesToRegister.Clear(); _initialValuablesRegistered = true; } private static void RegisterValuableWithGame(PrefabRef prefabRef) { if (_valuablesRegistered.Contains(prefabRef)) { return; } List<string> list = _valuablesToRegister[prefabRef]; if (!list.Any((string x) => ValuablePresets.AllValuablePresets.Keys.Any((string y) => x == y))) { Logger.LogWarning("Valuable \"" + prefabRef.PrefabName + "\" does not have any valid valuable preset names set. Adding generic valuable preset name."); list = new List<string>(1) { "Valuables - Generic" }; } foreach (string item in list) { if (item == null || !ValuablePresets.AllValuablePresets.ContainsKey(item)) { Logger.LogWarning("Failed to add valuable \"" + prefabRef.PrefabName + "\" to valuable preset \"" + item + "\". The valuable preset does not exist."); } else if (ValuablePresets.AllValuablePresets[item].AddValuable(prefabRef)) { _valuablesRegistered.Add(prefabRef); Logger.LogDebug("Added valuable \"" + prefabRef.PrefabName + "\" to valuable preset \"" + item + "\""); } else { Logger.LogWarning("Failed to add valuable \"" + prefabRef.PrefabName + "\" to valuable preset \"" + item + "\"", extended: true); } } } public static PrefabRef? RegisterValuable(ValuableObject? valuableObject, List<string> presetNames) { if ((Object)(object)valuableObject == (Object)null) { Logger.LogError("Failed to register valuable. ValuableObject is null."); return null; } GameObject gameObject = ((Component)valuableObject).gameObject; string prefabId = "Valuables/" + ((Object)gameObject).name; if (presetNames == null || presetNames.Count == 0) { Logger.LogWarning("Valuable \"" + ((Object)gameObject).name + "\" does not have any valid valuable preset names set. Adding generic valuable preset name.", extended: true); presetNames = new List<string>(1) { "Valuables - Generic" }; } PrefabRefResponse prefabRefResponse = NetworkPrefabs.RegisterNetworkPrefabInternal(prefabId, gameObject); PrefabRef prefabRef = prefabRefResponse.PrefabRef; if (prefabRefResponse.Result == PrefabRefResult.PrefabAlreadyRegistered) { Logger.LogWarning("Failed to register valuable \"" + ((Object)gameObject).name + "\". Valuable is already registered!"); return null; } if (prefabRefResponse.Result == PrefabRefResult.DifferentPrefabAlreadyRegistered) { Logger.LogError("Failed to register valuable \"" + ((Object)gameObject).name + "\". A valuable prefab is already registered with the same name."); return null; } if (prefabRefResponse.Result != 0) { Logger.LogError($"Failed to register valuable \"{((Object)gameObject).name}\". (Reason: {prefabRefResponse.Result})"); return null; } if (prefabRef == null) { Logger.LogError("Failed to register valuable \"" + ((Object)gameObject).name + "\". PrefabRef is null."); return null; } Utilities.FixAudioMixerGroups(gameObject); _valuablesToRegister.Add(prefabRef, presetNames); if (_initialValuablesRegistered) { RegisterValuableWithGame(prefabRef); } return prefabRef; } public static PrefabRef? RegisterValuable(ValuableObject? valuableObject) { return RegisterValuable(valuableObject, new List<string>()); } public static PrefabRef? RegisterValuable(ValuableObject? valuableObject, List<LevelValuables> presets) { return RegisterValuable(valuableObject, presets.Select((LevelValuables preset) => ((Object)preset).name).ToList()); } public static PrefabRef? RegisterValuable(ValuableContent? valuableContent) { if ((Object)(object)valuableContent == (Object)null) { Logger.LogError("Failed to register valuable. ValuableContent is null."); return null; } return RegisterValuable(valuableContent.Prefab, valuableContent.ValuablePresets.ToList()); } public static PrefabRef? RegisterValuable(GameObject? prefab, List<string> presetNames) { if ((Object)(object)prefab == (Object)null) { Logger.LogError("Failed to register valuable. Prefab is null."); return null; } ValuableObject valuableObject = default(ValuableObject); if (!prefab.TryGetComponent<ValuableObject>(ref valuableObject)) { Logger.LogError("Failed to register valuable \"" + ((Object)prefab).name + "\". Prefab does not have a ValuableObject component."); return null; } return RegisterValuable(valuableObject, presetNames); } public static PrefabRef? RegisterValuable(GameObject? prefab, List<LevelValuables> presets) { return RegisterValuable(prefab, presets.Select((LevelValuables preset) => ((Object)preset).name).ToList()); } public static PrefabRef? RegisterValuable(GameObject? prefab) { return RegisterValuable(prefab, new List<string>()); } public static GameObject? SpawnValuable(PrefabRef? prefabRef, Vector3 position, Quaternion rotation) { //IL_004a: 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_0085: 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 (prefabRef == null) { Logger.LogError("Failed to spawn valuable. PrefabRef is null."); return null; } if (!prefabRef.IsValid()) { Logger.LogError("Failed to spawn valuable. PrefabRef is not valid."); return null; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { Logger.LogError("Failed to spawn valuable \"" + prefabRef.PrefabName + "\". You are not the host."); return null; } GameObject val = NetworkPrefabs.SpawnNetworkPrefab(prefabRef, position, rotation, 0); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to spawn valuable \"" + prefabRef.prefabName + "\". Spawned GameObject is null."); return null; } Logger.LogInfo($"Spawned valuable \"{prefabRef.prefabName}\" at position {position}, rotation: {((Quaternion)(ref rotation)).eulerAngles}", extended: true); return val; } [Obsolete("This is no longer supported. Use AllValuables or RegisteredValuables instead.", true)] public static IReadOnlyList<GameObject> GetValuables() { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return Array.Empty<GameObject>(); } [Obsolete("This is no longer supported. Use AllValuables or RegisteredValuables instead.", true)] public static bool TryGetValuableByName(string name, [NotNullWhen(true)] out ValuableObject? prefabRef) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); prefabRef = null; return false; } [Obsolete("This is no longer supported. Use AllValuables or RegisteredValuables instead.", false)] public static ValuableObject? GetValuableByName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } [Obsolete("This is no longer supported. Use AllValuables or RegisteredValuables instead.", true)] public static bool TryGetValuableThatContainsName(string name, [NotNullWhen(true)] out ValuableObject? prefabRef) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); prefabRef = null; return false; } [Obsolete("This is no longer supported. Use AllValuables or RegisteredValuables instead.", true)] public static ValuableObject? GetValuableThatContainsName(string name) { Logger.LogError("This method is deprecated! " + Utilities.GetStackTrace()); return null; } } } namespace REPOLib.Extensions { internal static class AudioSourceExtensions { public static void FixAudioMixerGroup(this AudioSource audioSource) { audioSource.FixAudioMixerGroup(((Component)audioSource).gameObject); } public static void FixAudioMixerGroup(this AudioSource audioSource, GameObject rootObject) { if ((Object)(object)audioSource == (Object)null) { return; } string text = ((!((Object)(object)rootObject == (Object)(object)((Component)audioSource).gameObject)) ? (((Object)rootObject).name + "/" + ((Object)((Component)audioSource).gameObject).name) : ((Object)((Component)audioSource).gameObject).name); if ((Object)(object)AudioManager.instance == (Object)null) { Logger.LogWarning("Failed to fix AudioMixerGroup on GameObject \"" + text + "\". AudioManager instance is null."); return; } if ((Object)(object)audioSource.outputAudioMixerGroup == (Object)null) { Logger.LogWarning("Failed to fix AudioMixerGroup on GameObject \"" + text + "\". No AudioMixerGroup is assigned."); return; } AudioMixer val = (AudioMixer)(((Object)audioSource.outputAudioMixerGroup.audioMixer).name switch { "Master" => AudioManager.instance.MasterMixer, "Music" => AudioManager.instance.MusicMasterGroup.audioMixer, "Sound" => AudioManager.instance.SoundMasterGroup.audioMixer, "Spectate" => AudioManager.instance.MicrophoneSpectateGroup.audioMixer, _ => AudioManager.instance.SoundMasterGroup.audioMixer, }); AudioMixerGroup[] array = val.FindMatchingGroups(((Object)audioSource.outputAudioMixerGroup).name); AudioMixerGroup val2; if (array.Length >= 1) { val2 = array[0]; } else { val = AudioManager.instance.SoundMasterGroup.audioMixer; val2 = val.FindMatchingGroups("Sound Effects")[0]; Logger.LogWarning("Could not find matching AudioMixerGroup for GameObject \"" + text + "\". Using default AudioMixerGroup \"" + ((Object)val).name + "/" + ((Object)val2).name + "\"", extended: true); } audioSource.outputAudioMixerGroup = val2; Logger.LogDebug("Fixed AudioMixerGroup on GameObject \"" + text + "\". AudioMixerGroup \"" + ((Object)val).name + "/" + ((Object)val2).name + "\""); } } internal static class CollectionExtensions { public static IEnumerable<T> OrderByTypePriority<T>(this IEnumerable<T> source, Type[] types) where T : Content { Dictionary<Type, int> typesMap = new Dictionary<Type, int>(); for (int i = 0; i < types.Length; i++) { typesMap[types[i]] = i; } int value; return source.OrderBy((T x) => typesMap.TryGetValue(((object)x).GetType(), out value) ? value : int.MaxValue); } public static IEnumerable<T> OrderByTypeFirst<T, TFirst>(this IEnumerable<T> source) { return source.OrderBy((T x) => (!(x is TFirst)) ? 1 : 0); } } internal static class EnemyDirectorExtensions { public static bool HasEnemy(this EnemyDirector enemyDirector, EnemySetup enemySetup) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemySetup == (Object)null || enemySetup.spawnObjects.Count == 0) { return false; } if (!enemySetup.TryGetEnemyParent(out EnemyParent enemyParent)) { return false; } if (!enemyDirector.TryGetList(enemyParent.difficulty, out List<EnemySetup> list)) { return false; } return list.Contains(enemySetup); } internal static bool AddEnemy(this EnemyDirector enemyDirector, EnemySetup enemySetup) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemySetup == (Object)null) { return false; } if (!enemySetup.TryGetEnemyParent(out EnemyParent enemyParent)) { return false; } if (!enemyDirector.TryGetList(enemyParent.difficulty, out List<EnemySetup> list)) { return false; } if (list.Contains(enemySetup)) { return false; } list.Add(enemySetup); return true; } public static bool TryGetList(this EnemyDirector enemyDirector, Difficulty difficultyType, [NotNullWhen(true)] out List<EnemySetup>? list) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown list = (int)difficultyType switch { 0 => enemyDirector.enemiesDifficulty1, 1 => enemyDirector.enemiesDifficulty2, 2 => enemyDirector.enemiesDifficulty3, _ => null, }; return list != null; } public static List<EnemySetup> GetEnemies(this EnemyDirector enemyDirector) { List<EnemySetup> enemiesDifficulty = enemyDirector.enemiesDifficulty1; List<EnemySetup> enemiesDifficulty2 = enemyDirector.enemiesDifficulty2; List<EnemySetup> enemiesDifficulty3 = enemyDirector.enemiesDifficulty3; List<EnemySetup> list = new List<EnemySetup>(enemiesDifficulty.Count + enemiesDifficulty2.Count + enemiesDifficulty3.Count); list.AddRange(enemiesDifficulty); list.AddRange(enemiesDifficulty2); list.AddRange(enemiesDifficulty3); return list; } } internal static class EnemySetupExtensions { public static List<PrefabRef> GetDistinctSpawnObjects(this EnemySetup enemySetup) { return enemySetup.spawnObjects.Where((PrefabRef x) => x != null).Distinct(new PrefabRefComparer()).ToList(); } public static EnemyParent? GetEnemyParent(this EnemySetup enemySetup) { EnemyParent result = default(EnemyParent); foreach (PrefabRef distinctSpawnObject in enemySetup.GetDistinctSpawnObjects()) { if (distinctSpawnObject.Prefab.TryGetComponent<EnemyParent>(ref result)) { return result; } } return null; } public static bool TryGetEnemyParent(this EnemySetup enemySetup, [NotNullWhen(true)] out EnemyParent? enemyParent) { enemyParent = enemySetup.GetEnemyParent(); return (Object)(object)enemyParent != (Object)null; } } internal static class GameObjectExtensions { public static void FixAudioMixerGroups(this GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return; } if ((Object)(object)AudioManager.instance == (Object)null) { Logger.LogWarning("Failed to fix audio mixer groups on GameObject \"" + ((Object)gameObject).name + "\". AudioManager instance is null."); return; } AudioSource[] componentsInChildren = gameObject.GetComponentsInChildren<AudioSource>(); foreach (AudioSource audioSource in componentsInChildren) { audioSource.FixAudioMixerGroup(gameObject); } } } internal static class LevelValuablesExtensions { public static bool AddValuable(this LevelValuables levelValuables, PrefabRef prefabRef) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = prefabRef.Prefab; if ((O