Decompiled source of OpenShot v1.2.0

OpenShot.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OpenShot.Core;
using OpenShot.Events;
using OpenShot.UI;
using Shooterlatro.Gameplay;
using Shooterlatro.Player;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("OpenShot")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OpenShot")]
[assembly: AssemblyTitle("OpenShot")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 OpenShot
{
	[BepInPlugin("com.liamgaming.openshot", "OpenShot API", "1.0.0")]
	public class OpenShotPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.liamgaming.openshot";

		public const string PluginName = "OpenShot API";

		public const string PluginVersion = "1.0.0";

		private Harmony harmony;

		public static OpenShotPlugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"[OpenShot API] Initializing API...");
			SaveAPI.Initialize();
			GameEvents.Initialize();
			AssetLoader.LoadAllBundles();
			LocalizationAPI.LoadLanguage("en");
			GameObject val = new GameObject("OpenShotAPIs");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<ModMenu>();
			val.AddComponent<DevConsole>();
			val.AddComponent<MainMenuInjector>();
			UpdateChecker updateChecker = val.AddComponent<UpdateChecker>();
			AudioAPI.Initialize(val);
			InputAPI.Initialize(val);
			updateChecker.CheckForUpdate("LiamGaming-OpenShot", "1.1.0");
			AttributeScanner.ScanAndRegister();
			harmony = new Harmony("com.liamgaming.openshot");
			harmony.PatchAll(typeof(OpenShotPlugin).Assembly);
			Log.LogInfo((object)"[OpenShot API] Successfully loaded and patched.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}
namespace OpenShot.UI
{
	public static class UIHelper
	{
		private static GUIStyle labelStyle;

		private static GUIStyle buttonStyle;

		private static Texture2D MakeTex(int width, int height, Color col)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		public static void InitializeStyles()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			if (labelStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					wordWrap = true
				};
				val.normal.textColor = new Color(0.9f, 0.9f, 0.9f);
				labelStyle = val;
			}
			if (buttonStyle == null)
			{
				GUIStyle val2 = new GUIStyle(GUI.skin.button)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1,
					padding = new RectOffset(15, 15, 10, 10)
				};
				val2.normal.textColor = Color.white;
				val2.normal.background = MakeTex(2, 2, new Color(0.15f, 0.15f, 0.15f, 0.95f));
				val2.hover.textColor = new Color(0f, 1f, 0.8f);
				val2.hover.background = MakeTex(2, 2, new Color(0.25f, 0.25f, 0.25f, 1f));
				val2.active.textColor = Color.black;
				val2.active.background = MakeTex(2, 2, new Color(0f, 1f, 0.8f, 1f));
				buttonStyle = val2;
			}
		}

		public static void DrawLabel(string text)
		{
			InitializeStyles();
			GUILayout.Label(text, labelStyle, Array.Empty<GUILayoutOption>());
		}

		public static bool DrawButton(string text)
		{
			InitializeStyles();
			return GUILayout.Button(text, buttonStyle, Array.Empty<GUILayoutOption>());
		}

		public static void DrawHeader(string text)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = 18,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			GUILayout.Label(text, val, Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
		}

		public static bool DrawSettings(object settingsObj)
		{
			bool result = false;
			if (settingsObj == null)
			{
				return false;
			}
			Type type = settingsObj.GetType();
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(fieldInfo.Name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
				if (fieldInfo.FieldType == typeof(bool))
				{
					bool flag = (bool)fieldInfo.GetValue(settingsObj);
					bool flag2 = GUILayout.Toggle(flag, "", Array.Empty<GUILayoutOption>());
					if (flag2 != flag)
					{
						fieldInfo.SetValue(settingsObj, flag2);
						result = true;
					}
				}
				else if (fieldInfo.FieldType == typeof(string))
				{
					string text = ((string)fieldInfo.GetValue(settingsObj)) ?? "";
					string text2 = GUILayout.TextField(text, Array.Empty<GUILayoutOption>());
					if (text2 != text)
					{
						fieldInfo.SetValue(settingsObj, text2);
						result = true;
					}
				}
				else if (fieldInfo.FieldType == typeof(int))
				{
					int num = (int)fieldInfo.GetValue(settingsObj);
					string s = GUILayout.TextField(num.ToString(), Array.Empty<GUILayoutOption>());
					if (int.TryParse(s, out var result2) && result2 != num)
					{
						fieldInfo.SetValue(settingsObj, result2);
						result = true;
					}
				}
				else if (fieldInfo.FieldType == typeof(float))
				{
					float num2 = (float)fieldInfo.GetValue(settingsObj);
					string s2 = GUILayout.TextField(num2.ToString(), Array.Empty<GUILayoutOption>());
					if (float.TryParse(s2, out var result3) && result3 != num2)
					{
						fieldInfo.SetValue(settingsObj, result3);
						result = true;
					}
				}
				GUILayout.EndHorizontal();
			}
			return result;
		}
	}
	public class ModMenu : MonoBehaviour
	{
		private bool isVisible = false;

		private Rect windowRect = new Rect((float)(Screen.width / 2 - 200), (float)(Screen.height / 2 - 250), 400f, 500f);

		private Vector2 scrollPosition;

		private static readonly List<Action> ModDrawCallbacks = new List<Action>();

		public static ModMenu Instance { get; private set; }

		public static void RegisterTab(Action drawCallback)
		{
			ModDrawCallbacks.Add(drawCallback);
		}

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)282))
			{
				isVisible = !isVisible;
				ToggleGameState(isVisible);
			}
		}

		private void ToggleGameState(bool showMenu)
		{
			if (showMenu)
			{
				Time.timeScale = 0f;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			else
			{
				Time.timeScale = 1f;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
		}

		private void OnGUI()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (isVisible)
			{
				windowRect = GUILayout.Window(1001, windowRect, new WindowFunction(DrawWindow), "OpenShot Mod Menu", Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawWindow(int windowID)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			UIHelper.DrawHeader("Installed Mods");
			foreach (Action modDrawCallback in ModDrawCallbacks)
			{
				GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
				try
				{
					modDrawCallback();
				}
				catch (Exception ex)
				{
					GUILayout.Label("Error drawing mod UI: " + ex.Message, Array.Empty<GUILayoutOption>());
				}
				GUILayout.EndVertical();
				GUILayout.Space(10f);
			}
			if (ModDrawCallbacks.Count == 0)
			{
				UIHelper.DrawLabel("No mods have registered menu elements yet.");
			}
			GUILayout.EndScrollView();
			if (UIHelper.DrawButton("Close Menu (F1)"))
			{
				isVisible = false;
				ToggleGameState(showMenu: false);
			}
			GUI.DragWindow();
		}
	}
	public class DevConsole : MonoBehaviour
	{
		private bool isVisible = false;

		private string input = "";

		private Vector2 scrollPosition;

		private Rect windowRect = new Rect(10f, 10f, 600f, 300f);

		private static List<string> logs = new List<string>();

		private static Dictionary<string, Action<string[]>> commands = new Dictionary<string, Action<string[]>>();

		public static DevConsole Instance { get; private set; }

		public static void RegisterCommand(string commandName, Action<string[]> handler)
		{
			commands[commandName.ToLower()] = handler;
		}

		public static void Log(string message)
		{
			logs.Add($"[{DateTime.Now:HH:mm:ss}] {message}");
			if (logs.Count > 100)
			{
				logs.RemoveAt(0);
			}
		}

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			RegisterCommand("help", delegate
			{
				Log("Available commands:");
				foreach (string key in commands.Keys)
				{
					Log("- " + key);
				}
			});
			RegisterCommand("clear", delegate
			{
				logs.Clear();
			});
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)96) || Input.GetKeyDown((KeyCode)94))
			{
				isVisible = !isVisible;
				if (isVisible)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
			}
		}

		private void OnGUI()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (isVisible)
			{
				GUI.depth = -100;
				windowRect = GUILayout.Window(1002, windowRect, new WindowFunction(DrawConsole), "Developer Console", Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawConsole(int windowID)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(230f) });
			foreach (string log in logs)
			{
				GUILayout.Label(log, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.SetNextControlName("ConsoleInput");
			input = GUILayout.TextField(input, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if ((GUILayout.Button("Submit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }) || ((int)Event.current.type == 4 && (int)Event.current.keyCode == 13)) && !string.IsNullOrWhiteSpace(input))
			{
				Log("> " + input);
				ExecuteCommand(input);
				input = "";
			}
			GUILayout.EndHorizontal();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}

		private void ExecuteCommand(string inputLine)
		{
			string[] array = inputLine.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0)
			{
				return;
			}
			string text = array[0].ToLower();
			if (commands.ContainsKey(text))
			{
				string[] array2 = new string[array.Length - 1];
				Array.Copy(array, 1, array2, 0, array2.Length);
				try
				{
					commands[text](array2);
					return;
				}
				catch (Exception ex)
				{
					Log("Error executing command: " + ex.Message);
					return;
				}
			}
			Log("Unknown command: " + text);
		}
	}
	public class MainMenuInjector : MonoBehaviour
	{
		private bool injected = false;

		private GameObject modsButton;

		private GameObject originalMenuRoot;

		private GameObject modSubmenuRoot;

		private static Dictionary<string, Action> custom3DButtons = new Dictionary<string, Action>();

		public static void Register3DButton(string label, Action onClick)
		{
			if (!custom3DButtons.ContainsKey(label))
			{
				custom3DButtons.Add(label, onClick);
			}
		}

		private void Start()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			injected = false;
			((MonoBehaviour)this).Invoke("TryInjectMainMenu", 1f);
		}

		private void TryInjectMainMenu()
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			if (injected)
			{
				return;
			}
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			GameObject val = null;
			TextMeshProUGUI[] array2 = array;
			foreach (TextMeshProUGUI val2 in array2)
			{
				if (((TMP_Text)val2).text != null && ((TMP_Text)val2).text.ToUpper().Contains("COLLECTIONS"))
				{
					Button componentInParent = ((Component)val2).GetComponentInParent<Button>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						val = ((Component)componentInParent).gameObject;
						originalMenuRoot = ((Component)val.transform.parent).gameObject;
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null && (Object)(object)originalMenuRoot != (Object)null)
			{
				modsButton = Object.Instantiate<GameObject>(val, originalMenuRoot.transform);
				((Object)modsButton).name = "OpenShot_ModsButton";
				TextMeshProUGUI componentInChildren = modsButton.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = "MODS";
				}
				modsButton.transform.SetAsLastSibling();
				Transform transform = modsButton.transform;
				transform.localPosition += new Vector3(0f, -50f, 0f);
				Button component = modsButton.GetComponent<Button>();
				if ((Object)(object)component != (Object)null)
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
					((UnityEvent)component.onClick).AddListener(new UnityAction(OnModsButtonClicked));
				}
				CreateModSubmenu(val);
				injected = true;
				OpenShotPlugin.Log.LogInfo((object)"[MainMenuInjector] Successfully injected 3D Mods button into the main menu!");
			}
		}

		private void OnModsButtonClicked()
		{
			if ((Object)(object)originalMenuRoot != (Object)null)
			{
				originalMenuRoot.SetActive(false);
			}
			if ((Object)(object)modSubmenuRoot != (Object)null)
			{
				modSubmenuRoot.SetActive(true);
			}
		}

		private void OnBackButtonClicked()
		{
			if ((Object)(object)modSubmenuRoot != (Object)null)
			{
				modSubmenuRoot.SetActive(false);
			}
			if ((Object)(object)originalMenuRoot != (Object)null)
			{
				originalMenuRoot.SetActive(true);
			}
		}

		private void CreateModSubmenu(GameObject templateButton)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			modSubmenuRoot = new GameObject("OpenShot_ModSubmenu");
			modSubmenuRoot.transform.SetParent(originalMenuRoot.transform.parent, false);
			modSubmenuRoot.transform.localPosition = originalMenuRoot.transform.localPosition;
			modSubmenuRoot.transform.localRotation = originalMenuRoot.transform.localRotation;
			modSubmenuRoot.transform.localScale = originalMenuRoot.transform.localScale;
			LayoutGroup component = originalMenuRoot.GetComponent<LayoutGroup>();
			if ((Object)(object)component != (Object)null)
			{
				modSubmenuRoot.AddComponent(((object)component).GetType());
			}
			GameObject val = Object.Instantiate<GameObject>(templateButton, modSubmenuRoot.transform);
			((Object)val).name = "Btn_Back";
			((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).text = "BACK";
			Button component2 = val.GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			((UnityEvent)component2.onClick).AddListener(new UnityAction(OnBackButtonClicked));
			foreach (KeyValuePair<string, Action> custom3DButton in custom3DButtons)
			{
				GameObject val2 = Object.Instantiate<GameObject>(templateButton, modSubmenuRoot.transform);
				((Object)val2).name = "Btn_" + custom3DButton.Key;
				TextMeshProUGUI componentInChildren = val2.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = custom3DButton.Key.ToUpper();
				}
				Button component3 = val2.GetComponent<Button>();
				((UnityEventBase)component3.onClick).RemoveAllListeners();
				Action capturedAction = custom3DButton.Value;
				((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
				{
					capturedAction?.Invoke();
				});
			}
			modSubmenuRoot.SetActive(false);
		}
	}
}
namespace OpenShot.Utils
{
	public static class PlayerUtils
	{
		public static PlayerCameraController GetPlayerCamera()
		{
			return PlayerCameraController.Instance;
		}

		public static Vector3 GetPlayerPosition()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerCameraController.Instance != (Object)null)
			{
				return ((Component)PlayerCameraController.Instance).transform.position;
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				return ((Component)Camera.main).transform.position;
			}
			return Vector3.zero;
		}
	}
}
namespace OpenShot.Events
{
	public delegate void CancelableEvent(ref bool cancel);
	public delegate void CancelableEvent<T>(T arg1, ref bool cancel);
	public delegate void CancelableEvent<T1, T2>(T1 arg1, T2 arg2, ref bool cancel);
	public static class GameEvents
	{
		public static event Action<Target> OnTargetSpawned;

		public static event Action<Scene, LoadSceneMode> OnSceneLoaded;

		public static event CancelableEvent OnShotFired;

		public static event CancelableEvent<object, int> OnWeaponReloaded;

		public static event CancelableEvent<int> OnShopTryBuy;

		public static event Action<object> OnMoneyAmountChanged;

		public static event Action<object> OnTicketAmountChanged;

		public static event Action<object> OnAmmoDisplayUpdated;

		public static event Action<object> OnTargetSpawnerStarted;

		public static event Action<int> OnTargetMaxCapCalculated;

		public static event Action<object> OnPlayerCameraUpdated;

		internal static void Initialize()
		{
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				GameEvents.OnSceneLoaded?.Invoke(scene, mode);
			};
		}

		internal static void TriggerTargetSpawned(Target target)
		{
			GameEvents.OnTargetSpawned?.Invoke(target);
		}

		internal static bool TriggerShotFired()
		{
			bool cancel = false;
			GameEvents.OnShotFired?.Invoke(ref cancel);
			return cancel;
		}

		internal static bool TriggerWeaponReloaded(object weapon, int amount)
		{
			bool cancel = false;
			GameEvents.OnWeaponReloaded?.Invoke(weapon, amount, ref cancel);
			return cancel;
		}

		internal static bool TriggerShopTryBuy(int cost)
		{
			bool cancel = false;
			GameEvents.OnShopTryBuy?.Invoke(cost, ref cancel);
			return cancel;
		}

		internal static void TriggerMoneyAmountChanged(object view)
		{
			GameEvents.OnMoneyAmountChanged?.Invoke(view);
		}

		internal static void TriggerTicketAmountChanged(object view)
		{
			GameEvents.OnTicketAmountChanged?.Invoke(view);
		}

		internal static void TriggerAmmoDisplayUpdated(object view)
		{
			GameEvents.OnAmmoDisplayUpdated?.Invoke(view);
		}

		internal static void TriggerTargetSpawnerStarted(object spawner)
		{
			GameEvents.OnTargetSpawnerStarted?.Invoke(spawner);
		}

		internal static void TriggerTargetMaxCapCalculated(int cap)
		{
			GameEvents.OnTargetMaxCapCalculated?.Invoke(cap);
		}

		internal static void TriggerPlayerCameraUpdated(object camera)
		{
			GameEvents.OnPlayerCameraUpdated?.Invoke(camera);
		}
	}
	[HarmonyPatch(typeof(Target), "OnEnable")]
	internal static class Target_OnEnable_EventPatch
	{
		internal static void Postfix(Target __instance)
		{
			GameEvents.TriggerTargetSpawned(__instance);
		}
	}
	[HarmonyPatch]
	internal static class GameManager_HandleShotFired_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("GameManager"), "HandleShotFired", (Type[])null, (Type[])null);
		}

		private static bool Prefix()
		{
			bool flag = GameEvents.TriggerShotFired();
			return !flag;
		}
	}
	[HarmonyPatch]
	internal static class Weapon_AddNormalBullets_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("Weapon"), "AddNormalBulletsToMagazine", (Type[])null, (Type[])null);
		}

		private static bool Prefix(object __instance, int amount)
		{
			bool flag = GameEvents.TriggerWeaponReloaded(__instance, amount);
			return !flag;
		}
	}
	[HarmonyPatch]
	internal static class ShopManager_TryBuy_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("ShopManager"), "TryBuy", (Type[])null, (Type[])null);
		}

		private static bool Prefix(int cost)
		{
			bool flag = GameEvents.TriggerShopTryBuy(cost);
			return !flag;
		}
	}
	[HarmonyPatch]
	internal static class ShopMoneyView_SetDisplayedAmount_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("ShopMoneyViewController"), "SetDisplayedAmount", (Type[])null, (Type[])null);
		}

		private static void Postfix(object __instance)
		{
			GameEvents.TriggerMoneyAmountChanged(__instance);
		}
	}
	[HarmonyPatch]
	internal static class TicketView_SetDisplayedAmount_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("TicketViewController"), "SetDisplayedAmount", (Type[])null, (Type[])null);
		}

		private static void Postfix(object __instance)
		{
			GameEvents.TriggerTicketAmountChanged(__instance);
		}
	}
	[HarmonyPatch]
	internal static class HudMagazineViewController_RenderMagazine_EventPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("HudMagazineViewController"), "RenderMagazine", (Type[])null, (Type[])null);
		}

		private static void Postfix(object __instance)
		{
			GameEvents.TriggerAmmoDisplayUpdated(__instance);
		}
	}
	[HarmonyPatch(typeof(FairTargetSpawner), "Start")]
	internal static class FairTargetSpawner_Start_EventPatch
	{
		internal static void Postfix(FairTargetSpawner __instance)
		{
			GameEvents.TriggerTargetSpawnerStarted(__instance);
		}
	}
	[HarmonyPatch(typeof(FairTargetSpawner), "GetDesiredMaxActiveTargets")]
	internal static class FairTargetSpawner_GetDesiredMaxActiveTargets_EventPatch
	{
		internal static void Postfix(ref int __result)
		{
			GameEvents.TriggerTargetMaxCapCalculated(__result);
		}
	}
	[HarmonyPatch(typeof(PlayerCameraController), "Update")]
	internal static class PlayerCameraController_Update_EventPatch
	{
		internal static void Postfix(PlayerCameraController __instance)
		{
			GameEvents.TriggerPlayerCameraUpdated(__instance);
		}
	}
}
namespace OpenShot.Core
{
	public static class ModMessaging
	{
		private static readonly Dictionary<string, Action<object>> channels = new Dictionary<string, Action<object>>();

		public static void Subscribe(string channel, Action<object> handler)
		{
			if (!channels.ContainsKey(channel))
			{
				channels[channel] = handler;
				return;
			}
			Dictionary<string, Action<object>> dictionary = channels;
			dictionary[channel] = (Action<object>)Delegate.Combine(dictionary[channel], handler);
		}

		public static void Unsubscribe(string channel, Action<object> handler)
		{
			if (channels.ContainsKey(channel))
			{
				Dictionary<string, Action<object>> dictionary = channels;
				dictionary[channel] = (Action<object>)Delegate.Remove(dictionary[channel], handler);
			}
		}

		public static void Send(string channel, object message)
		{
			if (channels.ContainsKey(channel) && channels[channel] != null)
			{
				channels[channel](message);
			}
		}
	}
	public static class SaveAPI
	{
		[Serializable]
		private class SaveWrapper
		{
			public List<SaveEntry> entries;
		}

		[Serializable]
		private class SaveEntry
		{
			public string key;

			public string jsonValue;
		}

		private static Dictionary<string, string> saveStore = new Dictionary<string, string>();

		private static string SavePath => Path.Combine(Paths.ConfigPath, "OpenShot.SaveData.json");

		public static void Initialize()
		{
			LoadAll();
		}

		public static void SetData<T>(string modKey, T data)
		{
			try
			{
				string value = JsonUtility.ToJson((object)data);
				saveStore[modKey] = value;
				SaveAll();
			}
			catch (Exception ex)
			{
				OpenShotPlugin.Log.LogError((object)("[SaveAPI] Error setting data for " + modKey + ": " + ex.Message));
			}
		}

		public static T GetData<T>(string modKey)
		{
			if (saveStore.TryGetValue(modKey, out var value))
			{
				try
				{
					return JsonUtility.FromJson<T>(value);
				}
				catch (Exception ex)
				{
					OpenShotPlugin.Log.LogError((object)("[SaveAPI] Error getting data for " + modKey + ": " + ex.Message));
				}
			}
			return default(T);
		}

		private static void SaveAll()
		{
			try
			{
				SaveWrapper saveWrapper = new SaveWrapper
				{
					entries = new List<SaveEntry>()
				};
				foreach (KeyValuePair<string, string> item in saveStore)
				{
					saveWrapper.entries.Add(new SaveEntry
					{
						key = item.Key,
						jsonValue = item.Value
					});
				}
				File.WriteAllText(SavePath, JsonUtility.ToJson((object)saveWrapper, true));
			}
			catch (Exception ex)
			{
				OpenShotPlugin.Log.LogError((object)("[SaveAPI] Error saving file: " + ex.Message));
			}
		}

		private static void LoadAll()
		{
			if (!File.Exists(SavePath))
			{
				return;
			}
			try
			{
				string text = File.ReadAllText(SavePath);
				SaveWrapper saveWrapper = JsonUtility.FromJson<SaveWrapper>(text);
				saveStore.Clear();
				if (saveWrapper?.entries == null)
				{
					return;
				}
				foreach (SaveEntry entry in saveWrapper.entries)
				{
					saveStore[entry.key] = entry.jsonValue;
				}
			}
			catch (Exception ex)
			{
				OpenShotPlugin.Log.LogError((object)("[SaveAPI] Error loading file: " + ex.Message));
			}
		}
	}
	public static class AssetRegistry
	{
		private static Dictionary<string, GameObject> prefabs = new Dictionary<string, GameObject>();

		public static bool RegisterPrefab(string uniqueId, GameObject prefab)
		{
			if (prefabs.ContainsKey(uniqueId))
			{
				OpenShotPlugin.Log.LogWarning((object)("[AssetRegistry] ID " + uniqueId + " is already registered!"));
				return false;
			}
			prefabs[uniqueId] = prefab;
			OpenShotPlugin.Log.LogInfo((object)("[AssetRegistry] Registered prefab: " + uniqueId));
			return true;
		}

		public static GameObject GetPrefab(string uniqueId)
		{
			if (prefabs.TryGetValue(uniqueId, out var value))
			{
				return value;
			}
			return null;
		}
	}
	public class AudioAPI : MonoBehaviour
	{
		public static AudioAPI Instance { get; private set; }

		internal static void Initialize(GameObject parent)
		{
			Instance = parent.AddComponent<AudioAPI>();
		}

		public static void PlaySound(string filePath, float volume = 1f)
		{
			if (!File.Exists(filePath))
			{
				OpenShotPlugin.Log.LogError((object)("[AudioAPI] File not found: " + filePath));
			}
			else if ((Object)(object)Instance != (Object)null)
			{
				((MonoBehaviour)Instance).StartCoroutine(Instance.LoadAndPlaySound(filePath, volume));
			}
		}

		private IEnumerator LoadAndPlaySound(string filePath, float volume)
		{
			string url = "file:///" + filePath.Replace("\\", "/");
			UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, (AudioType)0);
			try
			{
				yield return www.SendWebRequest();
				if ((int)www.result == 2 || (int)www.result == 3)
				{
					OpenShotPlugin.Log.LogError((object)("[AudioAPI] Error loading sound: " + www.error));
					yield break;
				}
				AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
				if ((Object)(object)clip != (Object)null)
				{
					GameObject audioObj = new GameObject("OpenShot_TempAudio");
					AudioSource source = audioObj.AddComponent<AudioSource>();
					source.clip = clip;
					source.volume = volume;
					source.Play();
					Object.Destroy((Object)(object)audioObj, clip.length + 0.1f);
				}
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}
	}
	public class InputAPI : MonoBehaviour
	{
		private static Dictionary<KeyCode, Action> keyPressCallbacks = new Dictionary<KeyCode, Action>();

		public static InputAPI Instance { get; private set; }

		internal static void Initialize(GameObject parent)
		{
			Instance = parent.AddComponent<InputAPI>();
		}

		public static bool IsKeyPressed(KeyCode key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyDown(key);
		}

		public static void RegisterKeyCallback(KeyCode key, Action callback)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!keyPressCallbacks.ContainsKey(key))
			{
				keyPressCallbacks[key] = callback;
				return;
			}
			Dictionary<KeyCode, Action> dictionary = keyPressCallbacks;
			dictionary[key] = (Action)Delegate.Combine(dictionary[key], callback);
		}

		private void Update()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (keyPressCallbacks.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<KeyCode, Action> keyPressCallback in keyPressCallbacks)
			{
				if (Input.GetKeyDown(keyPressCallback.Key))
				{
					try
					{
						keyPressCallback.Value?.Invoke();
					}
					catch (Exception ex)
					{
						OpenShotPlugin.Log.LogError((object)$"[InputAPI] Error in key callback for {keyPressCallback.Key}: {ex.Message}");
					}
				}
			}
		}
	}
	public class BulletRegistry
	{
		public class BulletData
		{
			public string TypeName;

			public string ModAuthor;

			public float DamageMultiplier;
		}

		private static Dictionary<string, BulletData> registeredBullets = new Dictionary<string, BulletData>();

		public static bool RegisterBulletType(string typeName, string modAuthor, float damageMultiplier = 1f)
		{
			string key = typeName.ToLower();
			if (registeredBullets.ContainsKey(key))
			{
				OpenShotPlugin.Log.LogWarning((object)("[BulletRegistry] Bullet type '" + typeName + "' is already registered!"));
				return false;
			}
			registeredBullets[key] = new BulletData
			{
				TypeName = typeName,
				ModAuthor = modAuthor,
				DamageMultiplier = damageMultiplier
			};
			OpenShotPlugin.Log.LogInfo((object)("[BulletRegistry] Registered new bullet type: " + typeName + " by " + modAuthor));
			return true;
		}

		public static IEnumerable<BulletData> GetAllBulletTypes()
		{
			return registeredBullets.Values;
		}

		public static bool IsBulletRegistered(string typeName)
		{
			return registeredBullets.ContainsKey(typeName.ToLower());
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
	public class ConsoleCommandAttribute : Attribute
	{
		public string CommandName { get; }

		public string Description { get; }

		public ConsoleCommandAttribute(string commandName, string description = "")
		{
			CommandName = commandName;
			Description = description;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
	public class OpenShotMenuTabAttribute : Attribute
	{
		public string TabName { get; }

		public OpenShotMenuTabAttribute(string tabName)
		{
			TabName = tabName;
		}
	}
	public static class AttributeScanner
	{
		public static void ScanAndRegister()
		{
			OpenShotPlugin.Log.LogInfo((object)"[AttributeScanner] Scanning assemblies for custom OpenShot attributes...");
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				string fullName = assembly.FullName;
				if (fullName.StartsWith("System") || fullName.StartsWith("UnityEngine") || fullName.StartsWith("Unity.") || fullName.StartsWith("mscorlib"))
				{
					continue;
				}
				try
				{
					Type[] types = assembly.GetTypes();
					Type[] array2 = types;
					foreach (Type type in array2)
					{
						MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						MethodInfo[] array3 = methods;
						foreach (MethodInfo methodInfo in array3)
						{
							ConsoleCommandAttribute consoleCommandAttribute = (ConsoleCommandAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(ConsoleCommandAttribute));
							if (consoleCommandAttribute != null)
							{
								ParameterInfo[] parameters = methodInfo.GetParameters();
								if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string[]))
								{
									Action<string[]> handler = (Action<string[]>)Delegate.CreateDelegate(typeof(Action<string[]>), methodInfo);
									DevConsole.RegisterCommand(consoleCommandAttribute.CommandName, handler);
									OpenShotPlugin.Log.LogInfo((object)("[AttributeScanner] Registered command: " + consoleCommandAttribute.CommandName));
								}
								else
								{
									OpenShotPlugin.Log.LogWarning((object)("[AttributeScanner] Method " + methodInfo.Name + " has [ConsoleCommand] but invalid signature (must be Action<string[]>)."));
								}
							}
							OpenShotMenuTabAttribute openShotMenuTabAttribute = (OpenShotMenuTabAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(OpenShotMenuTabAttribute));
							if (openShotMenuTabAttribute != null)
							{
								if (methodInfo.GetParameters().Length == 0)
								{
									Action drawCallback = (Action)Delegate.CreateDelegate(typeof(Action), methodInfo);
									ModMenu.RegisterTab(drawCallback);
									OpenShotPlugin.Log.LogInfo((object)("[AttributeScanner] Registered ModMenu Tab via Attribute on " + methodInfo.Name));
								}
								else
								{
									OpenShotPlugin.Log.LogWarning((object)("[AttributeScanner] Method " + methodInfo.Name + " has [OpenShotMenuTab] but invalid signature (must be Action())."));
								}
							}
						}
					}
				}
				catch (ReflectionTypeLoadException)
				{
				}
				catch (Exception ex2)
				{
					OpenShotPlugin.Log.LogError((object)("[AttributeScanner] Error scanning assembly " + assembly.FullName + ": " + ex2.Message));
				}
			}
			OpenShotPlugin.Log.LogInfo((object)"[AttributeScanner] Scan complete.");
		}
	}
	public static class AssetLoader
	{
		private static class Paths
		{
			public static string BepInExRootPath => Path.Combine(Directory.GetCurrentDirectory(), "BepInEx");
		}

		private static Dictionary<string, GameObject> prefabCache = new Dictionary<string, GameObject>();

		private static List<AssetBundle> loadedBundles = new List<AssetBundle>();

		public static void LoadAllBundles()
		{
			string path = Path.Combine(Paths.BepInExRootPath, "plugins");
			if (Directory.Exists(path))
			{
				string[] files = Directory.GetFiles(path, "*.bundle", SearchOption.AllDirectories);
				string[] array = files;
				foreach (string path2 in array)
				{
					LoadBundle(path2);
				}
			}
		}

		private static void LoadBundle(string path)
		{
			try
			{
				AssetBundle val = AssetBundle.LoadFromFile(path);
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				loadedBundles.Add(val);
				OpenShotPlugin.Log.LogInfo((object)("[AssetLoader] Loaded AssetBundle: " + Path.GetFileName(path)));
				GameObject[] array = val.LoadAllAssets<GameObject>();
				GameObject[] array2 = array;
				foreach (GameObject val2 in array2)
				{
					string key = ((Object)val2).name.ToLower();
					if (!prefabCache.ContainsKey(key))
					{
						prefabCache.Add(key, val2);
					}
				}
			}
			catch (Exception ex)
			{
				OpenShotPlugin.Log.LogError((object)("[AssetLoader] Failed to load bundle at " + path + ": " + ex.Message));
			}
		}

		public static GameObject GetPrefab(string name)
		{
			string key = name.ToLower();
			if (prefabCache.TryGetValue(key, out var value))
			{
				return value;
			}
			OpenShotPlugin.Log.LogWarning((object)("[AssetLoader] Prefab not found in cache: " + name));
			return null;
		}
	}
	public static class LocalizationAPI
	{
		private static Dictionary<string, string> localizedStrings = new Dictionary<string, string>();

		public static string CurrentLanguage = "en";

		public static void LoadLanguage(string languageCode)
		{
			CurrentLanguage = languageCode;
			localizedStrings.Clear();
			string path = Path.Combine(Directory.GetCurrentDirectory(), "BepInEx", "plugins");
			if (!Directory.Exists(path))
			{
				return;
			}
			string searchPattern = "lang_" + languageCode + ".json";
			string[] files = Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories);
			string[] array = files;
			foreach (string text in array)
			{
				try
				{
					string json = File.ReadAllText(text);
					Dictionary<string, string> dictionary = ParseFlatJson(json);
					foreach (KeyValuePair<string, string> item in dictionary)
					{
						localizedStrings[item.Key] = item.Value;
					}
					OpenShotPlugin.Log.LogInfo((object)("[LocalizationAPI] Loaded language file: " + text));
				}
				catch (Exception ex)
				{
					OpenShotPlugin.Log.LogError((object)("[LocalizationAPI] Failed to parse " + text + ": " + ex.Message));
				}
			}
		}

		public static string GetString(string key)
		{
			if (localizedStrings.TryGetValue(key, out var value))
			{
				return value;
			}
			return key;
		}

		private static Dictionary<string, string> ParseFlatJson(string json)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			json = json.Trim();
			if (json.StartsWith("{") && json.EndsWith("}"))
			{
				json = json.Substring(1, json.Length - 2);
				string[] array = json.Split(new char[1] { ',' });
				string[] array2 = array;
				foreach (string text in array2)
				{
					string[] array3 = text.Split(new char[1] { ':' });
					if (array3.Length >= 2)
					{
						string key = array3[0].Trim(' ', '"', '\n', '\r');
						string value = array3[1].Trim(' ', '"', '\n', '\r');
						dictionary[key] = value;
					}
				}
			}
			return dictionary;
		}
	}
	public static class ObjectPoolAPI
	{
		private class Pool
		{
			public GameObject Prefab;

			public Queue<GameObject> InactiveObjects = new Queue<GameObject>();

			public Transform ParentTransform;
		}

		private static Dictionary<string, Pool> pools = new Dictionary<string, Pool>();

		private static GameObject globalPoolParent;

		public static void RegisterPrefab(string id, GameObject prefab, int initialSize = 10)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if (pools.ContainsKey(id))
			{
				OpenShotPlugin.Log.LogWarning((object)("[ObjectPoolAPI] Pool with ID '" + id + "' already exists."));
				return;
			}
			if ((Object)(object)globalPoolParent == (Object)null)
			{
				globalPoolParent = new GameObject("OpenShot_ObjectPools");
				Object.DontDestroyOnLoad((Object)(object)globalPoolParent);
			}
			GameObject val = new GameObject("Pool_" + id);
			val.transform.SetParent(globalPoolParent.transform);
			Pool pool = new Pool
			{
				Prefab = prefab,
				ParentTransform = val.transform
			};
			for (int i = 0; i < initialSize; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(prefab, val.transform);
				val2.SetActive(false);
				pool.InactiveObjects.Enqueue(val2);
			}
			pools.Add(id, pool);
			OpenShotPlugin.Log.LogInfo((object)$"[ObjectPoolAPI] Registered pool '{id}' with {initialSize} objects.");
		}

		public static GameObject Spawn(string id, Vector3 position, Quaternion rotation)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!pools.TryGetValue(id, out var value))
			{
				OpenShotPlugin.Log.LogError((object)("[ObjectPoolAPI] No pool found for ID '" + id + "'. Call RegisterPrefab first."));
				return null;
			}
			GameObject val = ((value.InactiveObjects.Count <= 0) ? Object.Instantiate<GameObject>(value.Prefab, value.ParentTransform) : value.InactiveObjects.Dequeue());
			val.transform.position = position;
			val.transform.rotation = rotation;
			val.SetActive(true);
			return val;
		}

		public static void Despawn(string id, GameObject obj)
		{
			if (!pools.TryGetValue(id, out var value))
			{
				OpenShotPlugin.Log.LogError((object)("[ObjectPoolAPI] No pool found for ID '" + id + "'. Destroying object instead."));
				Object.Destroy((Object)(object)obj);
			}
			else
			{
				obj.SetActive(false);
				obj.transform.SetParent(value.ParentTransform);
				value.InactiveObjects.Enqueue(obj);
			}
		}
	}
	public class UpdateChecker : MonoBehaviour
	{
		private const string ThunderstoreApiUrl = "https://thunderstore.io/api/experimental/package/";

		public static List<string> ModsWithUpdatesAvailable { get; private set; } = new List<string>();

		public void CheckForUpdate(string authorAndName, string currentVersion)
		{
			((MonoBehaviour)this).StartCoroutine(CheckUpdateCoroutine(authorAndName, currentVersion));
		}

		private IEnumerator CheckUpdateCoroutine(string authorAndName, string currentVersion)
		{
			string[] parts = authorAndName.Split(new char[1] { '-' });
			if (parts.Length != 2)
			{
				OpenShotPlugin.Log.LogWarning((object)("[UpdateChecker] Invalid authorAndName format: " + authorAndName + ". Expected 'Author-Name'."));
				yield break;
			}
			string url = "https://thunderstore.io/api/experimental/package/" + parts[0] + "/" + parts[1] + "/";
			UnityWebRequest request = UnityWebRequest.Get(url);
			try
			{
				yield return request.SendWebRequest();
				if (request.isNetworkError || request.isHttpError)
				{
					OpenShotPlugin.Log.LogError((object)("[UpdateChecker] Failed to check for updates for " + authorAndName + ": " + request.error));
					yield break;
				}
				string json = request.downloadHandler.text;
				string versionSearchStr = "\"version_number\": \"";
				int idx = json.IndexOf(versionSearchStr);
				if (idx == -1)
				{
					yield break;
				}
				idx += versionSearchStr.Length;
				int endIdx = json.IndexOf("\"", idx);
				if (endIdx == -1)
				{
					yield break;
				}
				string latestVersion = json.Substring(idx, endIdx - idx);
				if (latestVersion != currentVersion)
				{
					OpenShotPlugin.Log.LogInfo((object)("[UpdateChecker] UPDATE AVAILABLE for " + authorAndName + "! Current: " + currentVersion + ", Latest: " + latestVersion));
					if (!ModsWithUpdatesAvailable.Contains(authorAndName))
					{
						ModsWithUpdatesAvailable.Add(authorAndName);
					}
				}
				else
				{
					OpenShotPlugin.Log.LogInfo((object)("[UpdateChecker] " + authorAndName + " is up to date (" + currentVersion + ")."));
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}
	}
}