Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of REPOLib v3.0.4
plugins/REPOLib.dll
Decompiled a month 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.4.0")] [assembly: AssemblyInformationalVersion("3.0.4+7aff16cd6a9070e4eea6ec89ae2085084d00ffbb")] [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.4")] 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.4"; } } 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.4" }; [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