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();
}
}
}
}