using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using DarkMachine.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WKLib.Core;
using WKLib.UI.Components;
using WKLib.UI.Settings;
using WKLib.Utilities;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WKLib")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.2.0")]
[assembly: AssemblyInformationalVersion("0.0.2+d49d720d92a1e2524ad24c037d0e9aabe712bee4")]
[assembly: AssemblyProduct("WKLib")]
[assembly: AssemblyTitle("WKLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace WKLib
{
[BepInPlugin("WKLib", "WKLib", "0.0.2")]
public class WkLib : BaseUnityPlugin
{
private void Awake()
{
WKLog.Initialize(((BaseUnityPlugin)this).Logger);
WKLog.Info("Plugin WKLib v0.0.2 is loaded!");
UIManager.TryInitialize();
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (!(((Scene)(ref scene)).name != "Main-Menu"))
{
TextMeshProUGUI component = GameObject.Find("Canvas - Main Menu/Main Menu/Version Text").GetComponent<TextMeshProUGUI>();
if (component != null)
{
((TMP_Text)component).text = ((TMP_Text)component).text + string.Format(" (wklib-{0}) ({1} Mods)", "0.0.2", Chainloader.PluginInfos.Count);
}
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "WKLib";
public const string PLUGIN_NAME = "WKLib";
public const string PLUGIN_VERSION = "0.0.2";
}
}
namespace WKLib.Utilities
{
public static class WKLog
{
private static ManualLogSource _log;
internal static void Initialize(ManualLogSource logSource)
{
_log = logSource;
}
public static void Info(object msg)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogInfo((object)$"[WKLib] {msg}");
}
}
public static void Warn(object msg)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogWarning((object)$"[WKLib] {msg}");
}
}
public static void Error(object msg)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogError((object)$"[WKLib] {msg}");
}
}
public static void Debug(object msg)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)$"[WKLib] {msg}");
}
}
}
}
namespace WKLib.UI
{
public static class UIBuilder
{
public static WKSlider CreateSlider(UIColumn parentColumn, string settingName, string displayName, float defaultValue = 0f, float minValue = 0f, float maxValue = 1f)
{
return new WKSlider(parentColumn, settingName, displayName, defaultValue, minValue, maxValue);
}
public static WKToggle CreateToggle(UIColumn parentColumn, string settingName, string displayName, bool defaultValue = false)
{
return new WKToggle(parentColumn, settingName, displayName, defaultValue);
}
public static WKDropdown CreateDropdown(UIColumn parentColumn, string settingName, string displayName, List<string> options, int defaultValue = 0)
{
return new WKDropdown(parentColumn, settingName, displayName, options, defaultValue);
}
}
}
namespace WKLib.UI.Settings
{
public static class WKSettings
{
public class SettingInfo
{
public string Name;
public Type Type;
public object DefaultValue;
public object CurrentValue;
}
[Serializable]
private class SaveData
{
public List<SettingEntry> settings = new List<SettingEntry>();
}
[Serializable]
private class SettingEntry
{
public string key = "";
public string value = "";
public string type = "";
}
private static Dictionary<string, SettingInfo> _customSettings = new Dictionary<string, SettingInfo>();
private static Dictionary<string, object> _runtimeValues = new Dictionary<string, object>();
private static bool _isInitialized = false;
public static void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
if (_isInitialized)
{
return;
}
try
{
Harmony harmony = new Harmony("wklib.settings");
ApplyHarmonyPatches(harmony);
LoadCustomSettings();
_isInitialized = true;
WKLog.Info("WKSettings: Initialized successfully");
}
catch (Exception ex)
{
WKLog.Error("WKSettings: Failed to initialize: " + ex.Message);
}
}
public static void RegisterSetting<T>(string settingName, T defaultValue)
{
if (_customSettings.ContainsKey(settingName))
{
WKLog.Warn("WKSettings: Setting '" + settingName + "' already registered");
return;
}
SettingInfo settingInfo = new SettingInfo();
settingInfo.Name = settingName;
settingInfo.Type = typeof(T);
settingInfo.DefaultValue = defaultValue;
settingInfo.CurrentValue = defaultValue;
SettingInfo settingInfo2 = settingInfo;
_customSettings[settingName] = settingInfo2;
if (_runtimeValues.ContainsKey(settingName))
{
try
{
object obj = _runtimeValues[settingName];
T val2 = ((!(obj is T val) || 1 == 0) ? ((T)ConvertValueToType(obj.ToString(), typeof(T))) : val);
settingInfo2.CurrentValue = val2;
_runtimeValues[settingName] = val2;
WKLog.Info($"WKSettings: Loaded saved value '{val2}' for setting '{settingName}'");
}
catch (Exception ex)
{
WKLog.Warn("WKSettings: Failed to load saved value for '" + settingName + "': " + ex.Message + ", using default");
_runtimeValues[settingName] = defaultValue;
settingInfo2.CurrentValue = defaultValue;
}
}
else
{
_runtimeValues[settingName] = defaultValue;
}
WKLog.Info($"WKSettings: Registered setting '{settingName}' with value '{settingInfo2.CurrentValue}'");
}
public static T GetSetting<T>(string settingName, T fallback = default(T))
{
if (_runtimeValues.TryGetValue(settingName, out var value))
{
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
return fallback;
}
}
return fallback;
}
public static void SetSetting<T>(string settingName, T value)
{
if (_customSettings.ContainsKey(settingName))
{
_customSettings[settingName].CurrentValue = value;
_runtimeValues[settingName] = value;
SaveCustomSettings();
}
else
{
WKLog.Warn("WKSettings: Attempted to set unregistered setting '" + settingName + "'");
}
}
public static bool IsCustomSetting(string settingName)
{
return _customSettings.ContainsKey(settingName);
}
public static Dictionary<string, SettingInfo> GetAllCustomSettings()
{
return new Dictionary<string, SettingInfo>(_customSettings);
}
private static void ApplyHarmonyPatches(Harmony harmony)
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Expected O, but got Unknown
try
{
MethodInfo method = typeof(SettingsManager).GetMethod("GetSetting", new Type[1] { typeof(string) });
MethodInfo method2 = typeof(SettingsManager).GetMethod("SetSetting", new Type[1] { typeof(string[]) });
MethodInfo method3 = typeof(SettingsManager).GetMethod("SaveSettings");
MethodInfo method4 = typeof(SettingsManager).GetMethod("LoadSettings");
harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(WKSettings), "GetSetting_Patch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
harmony.Patch((MethodBase)method2, new HarmonyMethod(typeof(WKSettings), "SetSetting_Patch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(typeof(WKSettings), "SaveSettings_Patch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
harmony.Patch((MethodBase)method4, (HarmonyMethod)null, new HarmonyMethod(typeof(WKSettings), "LoadSettings_Patch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
catch (Exception ex)
{
WKLog.Error("WKSettings: Failed to apply Harmony patches: " + ex.Message);
}
}
private static bool GetSetting_Patch(string variableName, ref string __result)
{
if (IsCustomSetting(variableName))
{
__result = _runtimeValues[variableName]?.ToString() ?? _customSettings[variableName].DefaultValue?.ToString();
return false;
}
return true;
}
private static bool SetSetting_Patch(string[] args)
{
if (args.Length >= 2 && IsCustomSetting(args[0]))
{
try
{
SettingInfo settingInfo = _customSettings[args[0]];
object value = (settingInfo.CurrentValue = ConvertValueToType(args[1], settingInfo.Type));
_runtimeValues[args[0]] = value;
SaveCustomSettings();
}
catch (Exception ex)
{
WKLog.Error("WKSettings: Failed to set '" + args[0] + "': " + ex.Message);
}
return false;
}
return true;
}
private static void SaveSettings_Patch()
{
SaveCustomSettings();
}
private static void LoadSettings_Patch()
{
LoadCustomSettings();
}
private static string GetCustomSettingsPath()
{
return Path.Combine(Application.persistentDataPath, "WKLib_Settings.json");
}
private static void SaveCustomSettings()
{
try
{
SaveData saveData = new SaveData();
foreach (KeyValuePair<string, SettingInfo> customSetting in _customSettings)
{
SettingEntry item = new SettingEntry
{
key = customSetting.Key,
value = (customSetting.Value.CurrentValue?.ToString() ?? ""),
type = customSetting.Value.Type.FullName
};
saveData.settings.Add(item);
}
string contents = JsonConvert.SerializeObject((object)saveData, (Formatting)1);
File.WriteAllText(GetCustomSettingsPath(), contents);
WKLog.Info($"WKSettings: Saved {_customSettings.Count} custom settings");
}
catch (Exception ex)
{
WKLog.Error("WKSettings: Failed to save custom settings: " + ex.Message);
}
}
private static void LoadCustomSettings()
{
try
{
string customSettingsPath = GetCustomSettingsPath();
if (!File.Exists(customSettingsPath))
{
WKLog.Info("WKSettings: No custom settings file found, using defaults");
return;
}
string text = File.ReadAllText(customSettingsPath);
SaveData saveData = JsonConvert.DeserializeObject<SaveData>(text);
if (saveData?.settings == null)
{
return;
}
foreach (SettingEntry setting in saveData.settings)
{
try
{
Type type = Type.GetType(setting.type);
if (type != null)
{
object value = ConvertValueToType(setting.value, type);
_runtimeValues[setting.key] = value;
}
}
catch (Exception ex)
{
WKLog.Warn("WKSettings: Failed to load setting '" + setting.key + "': " + ex.Message);
}
}
WKLog.Info($"WKSettings: Loaded {saveData.settings.Count} custom settings from file");
}
catch (Exception ex2)
{
WKLog.Error("WKSettings: Failed to load custom settings: " + ex2.Message);
}
}
private static object ConvertValueToType(string valueString, Type targetType)
{
if (targetType == typeof(bool))
{
return bool.Parse(valueString);
}
if (targetType == typeof(int))
{
return int.Parse(valueString);
}
if (targetType == typeof(float))
{
return float.Parse(valueString);
}
if (targetType == typeof(string))
{
return valueString;
}
return Convert.ChangeType(valueString, targetType);
}
}
}
namespace WKLib.UI.Components
{
public interface IWKComponent
{
void Reset();
void CreateGameObject();
}
public abstract class WKComponent : IWKComponent
{
protected UIColumn ParentColumn;
protected bool IsCreated = false;
public GameObject GameObject { get; protected set; }
public string SettingName { get; protected set; }
public string LabelText { get; protected set; }
public TextMeshProUGUI Label { get; protected set; }
protected WKComponent(UIColumn parentColumn, string settingName, string displayName)
{
ParentColumn = parentColumn;
SettingName = settingName;
LabelText = displayName;
UIManager.RegisterComponent(this);
}
public void Reset()
{
IsCreated = false;
GameObject = null;
Label = null;
}
public void CreateGameObject()
{
if (IsCreated)
{
return;
}
try
{
string columnPath = UIManager.GetColumnPath(ParentColumn);
Transform val = UIManager.FindUIPath(columnPath);
if ((Object)(object)val == (Object)null)
{
WKLog.Error("WkComponent: Could not find parent path: " + columnPath);
return;
}
GameObject = CreateFromTemplate(val);
if ((Object)(object)GameObject != (Object)null)
{
Configure();
IsCreated = true;
WKLog.Info("WkComponent: Successfully created " + GetType().Name + " '" + SettingName + "'");
}
}
catch (Exception ex)
{
WKLog.Error("WkComponent: Failed to create " + GetType().Name + " '" + SettingName + "': " + ex.Message);
}
}
protected GameObject CreateFromTemplate(Transform parent)
{
string templatePath = GetTemplatePath();
GameObject val = UIManager.FindTemplate(templatePath);
if ((Object)(object)val == (Object)null)
{
WKLog.Error(GetType().Name + ": Could not find template at path: " + templatePath);
return null;
}
GameObject val2 = Object.Instantiate<GameObject>(val, parent);
((Object)val2).name = SettingName;
val2.SetActive(true);
return val2;
}
protected void SetLabelText()
{
if ((Object)(object)GameObject == (Object)null)
{
WKLog.Warn("WkComponent: Cannot set label text - GameObject is null for '" + SettingName + "'");
return;
}
if (string.IsNullOrEmpty(LabelText))
{
WKLog.Warn("WkComponent: LabelText is null or empty for '" + SettingName + "'");
return;
}
TextMeshProUGUI[] componentsInChildren = GameObject.GetComponentsInChildren<TextMeshProUGUI>();
if (componentsInChildren.Length != 0)
{
Label = componentsInChildren[0];
((TMP_Text)Label).text = LabelText;
WKLog.Info("WkComponent: Set label to '" + LabelText + "' for '" + SettingName + "'");
}
else
{
WKLog.Warn("WkComponent: No TextMeshPro components found for '" + SettingName + "'");
}
}
protected void RemoveOldBinders<T>() where T : Component
{
T[] componentsInChildren = GameObject.GetComponentsInChildren<T>();
T[] array = componentsInChildren;
foreach (T val in array)
{
Object.DestroyImmediate((Object)(object)val);
}
}
protected abstract string GetTemplatePath();
protected abstract void Configure();
}
public class WKDropdown : WKComponent
{
private Action<WKDropdown> _onValueChanged;
public int DefaultValue { get; private set; }
public List<string> Options { get; private set; }
public WKDropdown(UIColumn parentColumn, string settingName, string displayName, List<string> options, int defaultValue = 0)
: base(parentColumn, settingName, displayName)
{
Options = options ?? new List<string>();
DefaultValue = Mathf.Clamp(defaultValue, 0, Options.Count - 1);
}
protected override string GetTemplatePath()
{
return UIManager.DropdownTemplatePath;
}
protected override void Configure()
{
if (!((Object)(object)base.GameObject == (Object)null))
{
WKSettings.RegisterSetting(base.SettingName, DefaultValue);
RemoveOldBinders<DropdownBinder>();
RemoveOldBinders<Settings_Resolution>();
TMP_Dropdown componentInChildren = base.GameObject.GetComponentInChildren<TMP_Dropdown>();
if ((Object)(object)componentInChildren == (Object)null)
{
WKLog.Error("WkDropdown: No TMP_Dropdown found in " + ((Object)base.GameObject).name);
return;
}
((UnityEventBase)componentInChildren.onValueChanged).RemoveAllListeners();
componentInChildren.ClearOptions();
componentInChildren.AddOptions(Options);
int value = GetValue();
componentInChildren.SetValueWithoutNotify(value);
((UnityEvent<int>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<int>)OnValueChanged);
SetLabelText();
_onValueChanged?.Invoke(this);
WKLog.Info("WkDropdown: Configured '" + base.SettingName + "' successfully");
}
}
private void OnValueChanged(int value)
{
WKSettings.SetSetting(base.SettingName, value);
_onValueChanged?.Invoke(this);
}
public int GetValue()
{
int setting = WKSettings.GetSetting(base.SettingName, DefaultValue);
return Mathf.Clamp(setting, 0, Options.Count - 1);
}
public string GetText()
{
int value = GetValue();
return (value >= 0 && value < Options.Count) ? Options[value] : "";
}
public WKDropdown SetValue(int value)
{
value = Mathf.Clamp(value, 0, Options.Count - 1);
WKSettings.SetSetting(base.SettingName, value);
if ((Object)(object)base.GameObject != (Object)null)
{
TMP_Dropdown componentInChildren = base.GameObject.GetComponentInChildren<TMP_Dropdown>();
if (componentInChildren != null)
{
componentInChildren.SetValueWithoutNotify(value);
}
}
return this;
}
public WKDropdown SetValue(string text)
{
int num = Options.IndexOf(text);
if (num >= 0)
{
SetValue(num);
}
return this;
}
public WKDropdown SetOptions(List<string> newOptions)
{
Options = newOptions ?? new List<string>();
if ((Object)(object)base.GameObject != (Object)null)
{
TMP_Dropdown componentInChildren = base.GameObject.GetComponentInChildren<TMP_Dropdown>();
if ((Object)(object)componentInChildren != (Object)null)
{
componentInChildren.ClearOptions();
componentInChildren.AddOptions(Options);
int value = GetValue();
componentInChildren.SetValueWithoutNotify(value);
}
}
return this;
}
public WKDropdown SetListener(Action<WKDropdown> listener)
{
_onValueChanged = listener;
if ((Object)(object)base.GameObject != (Object)null)
{
_onValueChanged?.Invoke(this);
}
return this;
}
protected new void SetLabelText()
{
if ((Object)(object)base.GameObject == (Object)null)
{
WKLog.Warn("WkDropdown: Cannot set label text - GameObject is null for '" + base.SettingName + "'");
return;
}
if (string.IsNullOrEmpty(base.LabelText))
{
WKLog.Warn("WkDropdown: LabelText is null or empty for '" + base.SettingName + "'");
return;
}
TextMeshProUGUI component = base.GameObject.GetComponent<TextMeshProUGUI>();
if ((Object)(object)component != (Object)null)
{
base.Label = component;
((TMP_Text)base.Label).text = base.LabelText;
WKLog.Info("WkDropdown: Set label to '" + base.LabelText + "' for '" + base.SettingName + "' on parent GameObject");
}
else
{
WKLog.Warn("WkDropdown: No TextMeshPro component found on parent GameObject for '" + base.SettingName + "'");
}
}
}
public class WKSlider : WKComponent
{
private Action<WKSlider> _onValueChanged;
public float DefaultValue { get; private set; }
public float MinValue { get; private set; }
public float MaxValue { get; private set; }
public WKSlider(UIColumn parentColumn, string settingName, string displayName, float defaultValue = 0f, float minValue = 0f, float maxValue = 1f)
: base(parentColumn, settingName, displayName)
{
DefaultValue = defaultValue;
MinValue = minValue;
MaxValue = maxValue;
}
protected override string GetTemplatePath()
{
return UIManager.SliderTemplatePath;
}
protected override void Configure()
{
if (!((Object)(object)base.GameObject == (Object)null))
{
WKSettings.RegisterSetting(base.SettingName, DefaultValue);
RemoveOldBinders<SliderSettingBinder>();
RemoveOldBinders<TextSettingsBinder>();
SubmitSlider componentInChildren = base.GameObject.GetComponentInChildren<SubmitSlider>();
if ((Object)(object)componentInChildren == (Object)null)
{
WKLog.Error("WkSlider: No SubmitSlider found in " + ((Object)base.GameObject).name);
return;
}
((UnityEventBase)componentInChildren.onValueChanged).RemoveAllListeners();
componentInChildren.minValue = MinValue;
componentInChildren.maxValue = MaxValue;
float value = GetValue();
componentInChildren.SetValueWithoutNotify(value);
componentInChildren.value = value;
((UnityEvent<float>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<float>)OnValueChanged);
SetLabelText();
UpdateValueDisplay(value);
_onValueChanged?.Invoke(this);
WKLog.Info("WkSlider: Configured '" + base.SettingName + "' successfully");
}
}
private void OnValueChanged(float value)
{
WKSettings.SetSetting(base.SettingName, value);
UpdateValueDisplay(value);
_onValueChanged?.Invoke(this);
}
private void UpdateValueDisplay(float value)
{
if ((Object)(object)base.GameObject == (Object)null)
{
return;
}
Transform val = base.GameObject.transform.Find("Value (1)");
if ((Object)(object)val != (Object)null)
{
TMP_Text component = ((Component)val).GetComponent<TMP_Text>();
if ((Object)(object)component != (Object)null)
{
component.text = ((float)Math.Round(value, 2)).ToString();
}
}
}
public WKSlider SetListener(Action<WKSlider> listener)
{
_onValueChanged = listener;
if ((Object)(object)base.GameObject != (Object)null)
{
_onValueChanged?.Invoke(this);
}
return this;
}
public float GetValue()
{
return WKSettings.GetSetting(base.SettingName, DefaultValue);
}
public WKSlider SetValue(float value)
{
value = Mathf.Clamp(value, MinValue, MaxValue);
WKSettings.SetSetting(base.SettingName, value);
if ((Object)(object)base.GameObject != (Object)null)
{
SubmitSlider componentInChildren = base.GameObject.GetComponentInChildren<SubmitSlider>();
if ((Object)(object)componentInChildren != (Object)null)
{
componentInChildren.SetValueWithoutNotify(value);
UpdateValueDisplay(value);
}
}
return this;
}
}
public class WKToggle : WKComponent
{
private Action<WKToggle> _onValueChanged;
private Toggle _toggleComponent;
public bool DefaultValue { get; private set; }
public WKToggle(UIColumn parentColumn, string settingName, string displayName, bool defaultValue = false)
: base(parentColumn, settingName, displayName)
{
DefaultValue = defaultValue;
}
protected override string GetTemplatePath()
{
return UIManager.ToggleTemplatePath;
}
protected override void Configure()
{
if (!((Object)(object)base.GameObject == (Object)null))
{
WKSettings.RegisterSetting(base.SettingName, DefaultValue);
RemoveOldBinders<ToggleSettingsBinder>();
_toggleComponent = base.GameObject.GetComponentInChildren<Toggle>();
if ((Object)(object)_toggleComponent == (Object)null)
{
WKLog.Error("WkToggle: No Toggle found in " + ((Object)base.GameObject).name);
return;
}
((UnityEventBase)_toggleComponent.onValueChanged).RemoveAllListeners();
bool value = GetValue();
_toggleComponent.SetIsOnWithoutNotify(value);
((UnityEvent<bool>)(object)_toggleComponent.onValueChanged).AddListener((UnityAction<bool>)OnValueChanged);
SetLabelText();
_onValueChanged?.Invoke(this);
WKLog.Info("WkToggle: Configured '" + base.SettingName + "' successfully");
}
}
private void OnValueChanged(bool value)
{
WKSettings.SetSetting(base.SettingName, value);
_onValueChanged?.Invoke(this);
}
public WKToggle SetListener(Action<WKToggle> listener)
{
_onValueChanged = listener;
if ((Object)(object)base.GameObject != (Object)null)
{
_onValueChanged?.Invoke(this);
}
return this;
}
public bool GetValue()
{
return WKSettings.GetSetting(base.SettingName, DefaultValue);
}
public WKToggle SetValue(bool value)
{
WKSettings.SetSetting(base.SettingName, value);
if ((Object)(object)base.GameObject != (Object)null)
{
_toggleComponent.SetIsOnWithoutNotify(value);
}
return this;
}
}
}
namespace WKLib.Gamemodes.Builders
{
public class GamemodeBuilder
{
private List<M_Region> _regions = new List<M_Region>();
private string _modeName = "Custom Gamemode";
private string _introText = "ASCEND";
private bool _isEndless;
private bool _hasPerks;
private bool _hasRevives;
private Sprite _capsuleSprite;
private Sprite _screenArtSprite;
private List<SpawnItem> _spawnItems;
private GameType _gameType;
public GamemodeBuilder WithRegions(List<M_Region> regions)
{
_regions = regions ?? new List<M_Region>();
return this;
}
public GamemodeBuilder WithName(string modeName)
{
_modeName = modeName;
return this;
}
public GamemodeBuilder WithIntroText(string introText)
{
_introText = introText;
return this;
}
public GamemodeBuilder IsEndless(bool isEndless)
{
_isEndless = isEndless;
return this;
}
public GamemodeBuilder HasPerks(bool hasPerks)
{
_hasPerks = hasPerks;
return this;
}
public GamemodeBuilder HasRevives(bool hasRevives)
{
_hasRevives = hasRevives;
return this;
}
public GamemodeBuilder WithCapsuleSprite(Sprite sprite)
{
_capsuleSprite = sprite;
return this;
}
public GamemodeBuilder WithScreenArt(Sprite sprite)
{
_screenArtSprite = sprite;
return this;
}
public GamemodeBuilder WithStartItems(List<SpawnItem> spawnItems)
{
_spawnItems = spawnItems;
return this;
}
public GamemodeBuilder WithGameType(string gameType)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
string text = gameType.ToLower();
if (1 == 0)
{
}
GameType gameType2 = (GameType)(text switch
{
"endless" => 3,
"standard" => 0,
"playlist" => 1,
"playlist-shuffle" => 2,
"single" => 4,
_ => _gameType,
});
if (1 == 0)
{
}
_gameType = gameType2;
return this;
}
public M_Gamemode Build()
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Expected O, but got Unknown
//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Invalid comparison between Unknown and I4
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_025a: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0528: Unknown result type (might be due to invalid IL or missing references)
//IL_052d: Unknown result type (might be due to invalid IL or missing references)
//IL_0539: Expected O, but got Unknown
M_Gamemode gm = ScriptableObject.CreateInstance<M_Gamemode>();
gm.allowAchievements = false;
gm.allowCheatedScores = false;
gm.allowCheats = true;
gm.allowLeaderboardScoring = true;
gm.steamLeaderboardName = "";
gm.allowHeightAchievements = false;
gm.baseGamemode = true;
gm.modeType = (GameType)((!_isEndless) ? 1 : 3);
gm.capsuleName = _modeName;
gm.gamemodeName = _modeName;
gm.introText = _introText;
gm.isEndless = _isEndless;
gm.hasPerks = _hasPerks;
gm.hasRevives = _hasRevives;
gm.gamemodeScene = "Game-Main";
gm.roachBankID = "custom-" + _modeName;
gm.gamemodePanel = ((IEnumerable<UI_GamemodeScreen_Panel>)Resources.FindObjectsOfTypeAll<UI_GamemodeScreen_Panel>()).FirstOrDefault((Func<UI_GamemodeScreen_Panel, bool>)((UI_GamemodeScreen_Panel x) => ((Object)x).name == "Gamemode_Panel_Base"));
gm.loseScreen = ((IEnumerable<UI_ScoreScreen>)Resources.FindObjectsOfTypeAll<UI_ScoreScreen>()).FirstOrDefault((Func<UI_ScoreScreen, bool>)((UI_ScoreScreen x) => ((Object)x).name == "ScorePanel_Standard_Death"));
gm.winScreen = ((IEnumerable<UI_ScoreScreen>)Resources.FindObjectsOfTypeAll<UI_ScoreScreen>()).FirstOrDefault((Func<UI_ScoreScreen, bool>)((UI_ScoreScreen x) => ((Object)x).name == "ScorePanel_Standard_Win"));
gm.modeTags = new List<string>(1) { "" };
gm.unlockAchievement = "";
GamemodeModule_Standard gamemodeModule = new GamemodeModule_Standard
{
winScoreMultiplier = 1f
};
gm.gamemodeModule = (GamemodeModule)(object)gamemodeModule;
int numLevelsToLoad = 0;
_regions.ForEach(delegate(M_Region reg)
{
reg.subregionGroups.ForEach(delegate(SubregionGroup subRegGroup)
{
subRegGroup.subregions.ForEach(delegate(M_Subregion subReg)
{
numLevelsToLoad += subReg.levels.Count;
});
});
});
WKLog.Debug($"[Gamemode Builder] Will load {numLevelsToLoad} levels for {_modeName}");
int num = numLevelsToLoad;
int num2 = num;
if (num2 <= 1)
{
if (num2 == 1)
{
gm.modeType = (GameType)4;
gm.playlistLevels = new List<M_Level>(1) { _regions[0].subregionGroups[0].subregions[0].levels[0] };
WKLog.Debug("[Gamemode Builder] Loading one singular level");
}
}
else if ((int)_gameType == 4)
{
gm.modeType = (GameType)1;
_regions.ForEach(delegate(M_Region reg)
{
reg.subregionGroups.ForEach(delegate(SubregionGroup subRegGroup)
{
subRegGroup.subregions.ForEach(delegate(M_Subregion subReg)
{
gm.playlistLevels.AddRange(subReg.levels);
});
});
});
}
else
{
gm.modeType = _gameType;
List<M_Level> list = new List<M_Level>();
int num3 = 0;
foreach (M_Level item2 in from region in _regions
from subRegionGroup in region.subregionGroups
from subRegion in subRegionGroup.subregions
from level in subRegion.levels
select level)
{
try
{
list.Add(item2);
num3++;
}
catch (Exception ex)
{
WKLog.Error("[Gamemode Builder] Failed to load: " + ex.Message);
}
}
WKLog.Debug($"[Gamemode Builder] Loaded {num3}/{numLevelsToLoad} levels");
gm.playlistLevels = list;
}
gm.levelsToGenerate = numLevelsToLoad;
((Object)gm).name = _modeName;
if (_capsuleSprite != null)
{
gm.capsuleArt = _capsuleSprite;
}
if (_screenArtSprite != null)
{
gm.screenArt = _screenArtSprite;
}
gm.regions = _regions;
GameObject val = ((IEnumerable<GameObject>)Resources.FindObjectsOfTypeAll<GameObject>()).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == "World_Root"));
gm.gamemodeObjects = ((val != null) ? new List<GameObject>(1) { val } : new List<GameObject>());
SpawnItem item = new SpawnItem
{
itemid = "Item_Hammer"
};
gm.startItems = _spawnItems ?? new List<SpawnItem>(1) { item };
return gm;
}
}
public class RegionBuilder
{
private string _name = "New Region";
private List<M_Subregion> _subregions = new List<M_Subregion>();
private bool _hasStartingLevel = true;
public RegionBuilder WithName(string regionName)
{
_name = regionName;
return this;
}
public RegionBuilder WithSubregions(List<M_Subregion> subregions)
{
_subregions = subregions ?? new List<M_Subregion>();
return this;
}
[Obsolete("Game Handles this automatically, Let the game decide")]
public RegionBuilder WithStartingLevel(bool hasStartingLevel)
{
_hasStartingLevel = hasStartingLevel;
return this;
}
public M_Region Build()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Expected O, but got Unknown
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
M_Region val = ScriptableObject.CreateInstance<M_Region>();
val.regionName = _name;
((Object)val).name = _name;
List<SubregionGroup> list = new List<SubregionGroup>();
foreach (M_Subregion subregion in _subregions)
{
list.Add(new SubregionGroup
{
subregions = new List<M_Subregion>(1) { subregion }
});
}
val.subregionGroups = list;
if (_subregions.Count > 1 && _subregions[0].levels.Count > 1)
{
List<TransitionLevels> list2 = new List<TransitionLevels>(1);
TransitionLevels val2 = new TransitionLevels
{
fromRegion = _name
};
List<M_Level> list3 = new List<M_Level>(1);
List<M_Level> levels = _subregions[0].levels;
list3.Add(levels[levels.Count - 1]);
val2.levels = list3;
list2.Add(val2);
val.transitionLevels = list2;
_subregions[0].levels.RemoveAt(_subregions[0].levels.Count - 1);
}
val.regionHeight = _subregions.Sum((M_Subregion sr) => sr.subregionHeight);
GameObject val3 = ((IEnumerable<GameObject>)CL_AssetManager.instance.assetDatabase.levelPrefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject pref) => ((Object)pref).name == "M1_Intro_01"));
M_Level val4 = ((val3 != null) ? val3.GetComponent<M_Level>() : null);
if (val4 != null && _hasStartingLevel)
{
val.startLevels = new List<M_Level>(1) { val4 };
}
val.regionOrder = (RegionOrder)1;
val.introText = _name;
val.sessionEventLists = _subregions.SelectMany((M_Subregion sr) => sr.sessionEventLists).ToList();
return val;
}
}
public class SubRegionBuilder
{
private string _name = "New Subregion";
private List<M_Level> _levels = new List<M_Level>();
public SubRegionBuilder WithName(string subregionName)
{
_name = subregionName;
return this;
}
public SubRegionBuilder WithLevels(List<M_Level> levels)
{
_levels = levels ?? new List<M_Level>();
return this;
}
public M_Subregion Build()
{
M_Subregion val = ScriptableObject.CreateInstance<M_Subregion>();
val.subregionName = _name;
((Object)val).name = _name;
val.levels = _levels;
val.subregionHeight = _levels.Sum((M_Level lv) => lv.GetHeight());
val.sessionEventLists = _levels.SelectMany((M_Level lv) => lv.sessionEventLists).ToList();
return val;
}
}
}
namespace WKLib.Core
{
public class ModContext
{
public string ModID { get; }
public string Version { get; }
internal ModContext(string modID, string version = null)
{
ModID = modID;
Version = version;
}
}
public static class ModRegistry
{
private static readonly Dictionary<string, ModContext> Contexts = new Dictionary<string, ModContext>();
public static ModContext Register(string modID, string version = null)
{
if (Contexts.TryGetValue(modID, out var value))
{
return value;
}
ModContext modContext = new ModContext(modID, version);
Contexts[modID] = modContext;
return modContext;
}
public static ModContext Get(string modID)
{
if (!Contexts.TryGetValue(modID, out var value))
{
throw new KeyNotFoundException("Mod '" + modID + "' not registered.");
}
return value;
}
}
public enum UIColumn
{
AccessibilityInterface,
AccessibilityVisuals,
AccessibilityOther,
VideoScreenInfo,
VideoGraphics,
VideoAudio,
ControlsCamera,
ControlsToggles
}
public static class UIManager
{
private static bool _initialized;
private static string _currentSceneName;
private static readonly List<IWKComponent> RegisteredComponents;
private static readonly List<Action> RegisteredActions;
private static readonly List<IWKComponent> PendingComponents;
private static readonly List<Action> PendingActions;
public static string SliderTemplatePath { get; private set; }
public static string ToggleTemplatePath { get; private set; }
public static string DropdownTemplatePath { get; private set; }
public static string AccessibilityInterfaceColumn { get; private set; }
public static string AccessibilityVisualsColumn { get; private set; }
public static string AccessibilityOtherColumn { get; private set; }
public static string VideoScreenInfoColumn { get; private set; }
public static string VideoGraphicsColumn { get; private set; }
public static string VideoAudioColumn { get; private set; }
public static string ControlsCameraColumn { get; private set; }
public static string ControlsTogglesColumn { get; private set; }
static UIManager()
{
_initialized = false;
_currentSceneName = "";
RegisteredComponents = new List<IWKComponent>();
RegisteredActions = new List<Action>();
PendingComponents = new List<IWKComponent>();
PendingActions = new List<Action>();
SceneManager.sceneLoaded += OnSceneLoaded;
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
string text = (_currentSceneName = ((Scene)(ref scene)).name);
WKLog.Info("UIManager: Scene loaded - " + text);
if (text == "Main-Menu" || text == "Game-Main")
{
WKLog.Info("UIManager: Compatible scene detected, attempting initialization...");
_initialized = false;
foreach (IWKComponent registeredComponent in RegisteredComponents)
{
registeredComponent.Reset();
}
PendingComponents.AddRange(RegisteredComponents);
PendingActions.AddRange(RegisteredActions);
TryInitialize();
}
else
{
WKLog.Info("UIManager: Non-compatible scene, UI components will wait for next compatible scene");
_initialized = false;
}
}
public static void RegisterComponent(IWKComponent component)
{
if (!RegisteredComponents.Contains(component))
{
RegisteredComponents.Add(component);
}
ExecuteWhenReady(component.CreateGameObject);
}
public static void ExecuteWhenReady(Action action)
{
if (!RegisteredActions.Contains(action))
{
RegisteredActions.Add(action);
}
if (_initialized)
{
action?.Invoke();
}
else if (!PendingActions.Contains(action))
{
PendingActions.Add(action);
}
}
public static bool TryInitialize()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (_initialized)
{
return true;
}
Scene activeScene = SceneManager.GetActiveScene();
_currentSceneName = ((Scene)(ref activeScene)).name;
if (!IsValidUIScene(_currentSceneName))
{
return false;
}
Initialize();
return _initialized;
}
private static bool IsValidUIScene(string sceneName)
{
return sceneName == "Main-Menu" || sceneName == "Game-Main";
}
public static void Initialize()
{
if (_initialized)
{
return;
}
WKSettings.Initialize();
string text = FindObjectPath("Accessibility Settings");
string text2 = FindObjectPath("Video Settings");
string text3 = FindObjectPath("Controls Page");
if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2) || string.IsNullOrEmpty(text3))
{
WKLog.Warn("UIManager: Could not find UI template paths in scene '" + _currentSceneName + "'. Will retry when entering compatible scene.");
return;
}
BuildPaths(text, text2, text3);
_initialized = true;
WKLog.Info("UIManager: Successfully initialized in scene '" + _currentSceneName + "'");
foreach (IWKComponent pendingComponent in PendingComponents)
{
try
{
pendingComponent.CreateGameObject();
}
catch (Exception ex)
{
WKLog.Error("UIManager: Error creating pending component: " + ex.Message);
}
}
PendingComponents.Clear();
foreach (Action pendingAction in PendingActions)
{
try
{
pendingAction?.Invoke();
}
catch (Exception ex2)
{
WKLog.Error("UIManager: Error executing pending action: " + ex2.Message);
}
}
PendingActions.Clear();
WKLog.Info("UIManager: Processed all pending components and actions");
}
private static void BuildPaths(string accessibilityPath, string videoPath, string controlsPath)
{
AccessibilityInterfaceColumn = accessibilityPath + "/Options Tab/Interface Column";
AccessibilityVisualsColumn = accessibilityPath + "/Options Tab/Accessibility";
AccessibilityOtherColumn = accessibilityPath + "/Options Tab/Other Column";
VideoScreenInfoColumn = videoPath + "/Options Tab/Video";
VideoGraphicsColumn = videoPath + "/Options Tab/Other";
VideoAudioColumn = videoPath + "/Options Tab/Audio";
ControlsCameraColumn = controlsPath + "/Options Tab/Column 01";
ControlsTogglesColumn = controlsPath + "/Options Tab/Toggles";
SliderTemplatePath = AccessibilityInterfaceColumn + "/SliderAsset - UI Scale";
ToggleTemplatePath = AccessibilityVisualsColumn + "/Item High Visibility";
DropdownTemplatePath = VideoScreenInfoColumn + "/Screen Resolution";
}
private static string FindObjectPath(string uniqueName)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
foreach (GameObject val in rootGameObjects)
{
Transform val2 = ((IEnumerable<Transform>)val.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)((Component)t).gameObject).name == uniqueName));
if ((Object)(object)val2 != (Object)null)
{
LinkedList<string> linkedList = new LinkedList<string>();
Transform val3 = val2;
while ((Object)(object)val3 != (Object)null)
{
linkedList.AddFirst(((Object)val3).name);
val3 = val3.parent;
}
return string.Join("/", linkedList);
}
}
return null;
}
public static bool IsUIReady()
{
return _initialized;
}
public static string GetColumnPath(UIColumn column)
{
if (!_initialized)
{
WKLog.Warn($"UIManager: Attempted to resolve {column} before initialization");
return null;
}
if (1 == 0)
{
}
string result = column switch
{
UIColumn.AccessibilityInterface => AccessibilityInterfaceColumn,
UIColumn.AccessibilityVisuals => AccessibilityVisualsColumn,
UIColumn.AccessibilityOther => AccessibilityOtherColumn,
UIColumn.VideoScreenInfo => VideoScreenInfoColumn,
UIColumn.VideoGraphics => VideoGraphicsColumn,
UIColumn.VideoAudio => VideoAudioColumn,
UIColumn.ControlsCamera => ControlsCameraColumn,
UIColumn.ControlsToggles => ControlsTogglesColumn,
_ => throw new ArgumentException($"Unknown UIColumn: {column}"),
};
if (1 == 0)
{
}
return result;
}
public static Transform FindUIPath(string path)
{
if (!IsUIReady())
{
WKLog.Warn("UIManager.FindUIPath called before UI was ready. Path: " + path);
return null;
}
if (string.IsNullOrEmpty(path))
{
return null;
}
GameObject val = GameObject.Find(path);
if ((Object)(object)val == (Object)null)
{
WKLog.Warn("UIManager: Could not find object at path: " + path);
}
return (val != null) ? val.transform : null;
}
public static GameObject FindTemplate(string templatePath)
{
if (!IsUIReady())
{
WKLog.Warn("UIManager.FindTemplate called before UI was ready. Path: " + templatePath);
return null;
}
if (string.IsNullOrEmpty(templatePath))
{
return null;
}
return GameObject.Find(templatePath);
}
}
}
namespace WKLib.Assets
{
public class AssetService
{
private readonly ModContext _modContext;
private readonly string _assemblyFolder;
private readonly Dictionary<string, AssetBundle> _bundleCache = new Dictionary<string, AssetBundle>();
private readonly Dictionary<string, Dictionary<string, M_Level>> _loadedLevelsCache = new Dictionary<string, Dictionary<string, M_Level>>();
private readonly Dictionary<string, M_Gamemode> _gamemodeCache = new Dictionary<string, M_Gamemode>();
private readonly CancellationTokenSource _sQuitCts = new CancellationTokenSource();
public AssetService(ModContext modContext)
{
_modContext = modContext ?? throw new ArgumentNullException("modContext");
string location = Assembly.GetExecutingAssembly().Location;
_assemblyFolder = Path.GetDirectoryName(location) ?? string.Empty;
Application.quitting += delegate
{
WKLog.Debug("[AssetService] Quitting...");
_sQuitCts.Cancel();
};
}
public async Task<AssetBundle> LoadBundleRelativeAsync(string relativePath, IProgress<float> progress = null)
{
progress?.Report(0f);
if (string.IsNullOrEmpty(relativePath))
{
WKLog.Error("[AssetService] Path is null or empty.");
progress?.Report(1f);
return null;
}
string cacheKey = _modContext.ModID + ":" + Path.GetFileNameWithoutExtension(relativePath);
if (_bundleCache.TryGetValue(cacheKey, out var cached) && cached != null)
{
WKLog.Debug("[AssetService] Returning cached bundle: " + cacheKey);
progress?.Report(1f);
return cached;
}
string fullPath = Path.Combine(_assemblyFolder, relativePath);
if (!File.Exists(fullPath))
{
WKLog.Error("[AssetService] Bundle not found at " + fullPath);
progress?.Report(1f);
return null;
}
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(fullPath);
if (request == null)
{
WKLog.Error("[AssetService] Failed to load bundle: " + fullPath + " (request)");
progress?.Report(1f);
return null;
}
try
{
while (!((AsyncOperation)request).isDone)
{
_sQuitCts.Token.ThrowIfCancellationRequested();
progress?.Report(((AsyncOperation)request).progress * 1.1f);
await Task.Yield();
}
}
catch (OperationCanceledException)
{
WKLog.Debug("[AssetService] Asset Bundle Load cancelled");
return null;
}
AssetBundle bundle = request.assetBundle;
if (bundle == null)
{
WKLog.Error("[AssetService] Failed to load bundle at " + fullPath + " (bundle)");
progress?.Report(1f);
return null;
}
_bundleCache[cacheKey] = bundle;
WKLog.Debug("[AssetService] Loaded & cached bundle: " + cacheKey);
progress?.Report(1f);
return bundle;
}
public void UnloadBundleRelative(string relativePath, bool unloadAllLoadedObjects = false)
{
string text = _modContext.ModID + ":" + relativePath;
if (_bundleCache.TryGetValue(text, out var value) && value != null)
{
try
{
value.Unload(unloadAllLoadedObjects);
}
catch
{
WKLog.Error("[AssetService] Failed to unload bundle: " + text);
return;
}
WKLog.Debug("[AssetService] Unloaded bundle: " + text);
_bundleCache.Remove(text);
}
}
public void UnloadAllBundles(bool unloadAllLoadedObjects = false)
{
List<string> list = _bundleCache.Keys.Where((string k) => k.StartsWith(_modContext.ModID + ":")).ToList();
foreach (string item in list)
{
if (_bundleCache[item] != null)
{
try
{
_bundleCache[item].Unload(unloadAllLoadedObjects);
}
catch
{
WKLog.Error("[AssetService] Failed to unload bundle: " + item);
continue;
}
WKLog.Debug("[AssetService] Unloaded bundle: " + item);
}
_bundleCache.Remove(item);
}
}
public async Task<Dictionary<string, M_Level>> LoadAllLevelsFromBundle(AssetBundle bundle, IProgress<float> progress = null)
{
Dictionary<string, M_Level> foundLevels = new Dictionary<string, M_Level>();
if (bundle == null)
{
WKLog.Error("[AssetService] LoadAllLevelsFromBundle called with null bundle.");
progress?.Report(1f);
return foundLevels;
}
string cacheKey = _modContext.ModID + ":" + ((Object)bundle).name;
if (_loadedLevelsCache.ContainsKey(cacheKey))
{
WKLog.Debug("[AssetService] Returning Cached loaded levels for bundle: " + cacheKey);
progress?.Report(1f);
return _loadedLevelsCache.GetValueOrDefault(cacheKey);
}
AssetBundleRequest request = bundle.LoadAllAssetsAsync<GameObject>();
try
{
while (!((AsyncOperation)request).isDone)
{
_sQuitCts.Token.ThrowIfCancellationRequested();
progress?.Report(((AsyncOperation)request).progress * 0.5f);
await Task.Yield();
}
}
catch (OperationCanceledException)
{
WKLog.Debug("[AssetService] LoadAllLevelsFromBundle canceled.");
return null;
}
List<GameObject> allGOs = request.allAssets.Cast<GameObject>().ToList();
int total = allGOs.Count;
M_Level level = default(M_Level);
for (int i = 0; i < total; i += 20)
{
for (int j = i; j < i + 20 && j < total; j++)
{
GameObject go = allGOs[j];
if (go.TryGetComponent<M_Level>(ref level))
{
if (!CL_AssetManager.instance.assetDatabase.levelPrefabs.Contains(go))
{
CL_AssetManager.instance.assetDatabase.levelPrefabs.Add(go);
}
WKLog.Debug("[AssetService] Found level: " + ((Object)level).name);
if (!foundLevels.TryAdd(((Object)level).name, level))
{
WKLog.Debug("[AssetService] Duplicate prefab.name '" + ((Object)level).name + "' found; skipping the duplicate.");
}
}
level = null;
}
progress?.Report(0.5f + (float)i / (float)total * 0.5f);
await Task.Yield();
}
_loadedLevelsCache[cacheKey] = foundLevels;
progress?.Report(1f);
return foundLevels;
}
public List<M_Level> FindLevelsByName(string nameContains)
{
return (from prefab in CL_AssetManager.instance.assetDatabase.levelPrefabs
where ((Object)prefab).name.Contains(nameContains)
select prefab.GetComponent<M_Level>() into level
where level != null
select level).ToList();
}
public async Task<M_Gamemode> LoadGameModeFromBundle(AssetBundle bundle, string assetName, IProgress<float> progress = null)
{
if (bundle == null)
{
WKLog.Error("[AssetService] Bundle is null; cannot load gamemode.");
progress?.Report(1f);
return null;
}
string cacheKey = _modContext.ModID + ":" + assetName;
if (_gamemodeCache.TryGetValue(cacheKey, out var cachedGamemode))
{
WKLog.Debug("[AssetService] Returning cached gamemode: '" + cacheKey + "'");
progress?.Report(1f);
return cachedGamemode;
}
AssetBundleRequest request = bundle.LoadAssetAsync<ScriptableObject>(assetName);
while (!((AsyncOperation)request).isDone)
{
progress?.Report(((AsyncOperation)request).progress);
await Task.Yield();
}
Object asset = request.asset;
M_Gamemode gamemode = (M_Gamemode)(object)((asset is M_Gamemode) ? asset : null);
if (gamemode == null)
{
WKLog.Error("[AssetService] Gamemode '" + assetName + "' not found in bundle " + ((Object)bundle).name);
progress?.Report(1f);
return null;
}
if (string.IsNullOrEmpty(gamemode.unlockAchievement))
{
gamemode.unlockAchievement = "ACH_TUTORIAL";
}
gamemode.gamemodePanel = ((IEnumerable<UI_GamemodeScreen_Panel>)Resources.FindObjectsOfTypeAll<UI_GamemodeScreen_Panel>()).FirstOrDefault((Func<UI_GamemodeScreen_Panel, bool>)((UI_GamemodeScreen_Panel x) => ((Object)x).name == "Gamemode_Panel_Base"));
gamemode.loseScreen = ((IEnumerable<UI_ScoreScreen>)Resources.FindObjectsOfTypeAll<UI_ScoreScreen>()).FirstOrDefault((Func<UI_ScoreScreen, bool>)((UI_ScoreScreen x) => ((Object)x).name == "ScorePanel_Standard_Death"));
gamemode.winScreen = ((IEnumerable<UI_ScoreScreen>)Resources.FindObjectsOfTypeAll<UI_ScoreScreen>()).FirstOrDefault((Func<UI_ScoreScreen, bool>)((UI_ScoreScreen x) => ((Object)x).name == "ScorePanel_Standard_Win"));
_gamemodeCache[cacheKey] = gamemode;
progress?.Report(1f);
WKLog.Debug("[AssetService] Loaded and cached gamemode: '" + assetName + "'");
return gamemode;
}
public Sprite LoadPngAsSpriteRelative(string relativePngPath)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
string text = Path.Combine(_assemblyFolder, relativePngPath);
if (!File.Exists(text))
{
WKLog.Error("[AssetService] PNG not found at: " + text);
return null;
}
byte[] array = File.ReadAllBytes(text);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!ImageConversion.LoadImage(val, array))
{
WKLog.Error("[AssetService] Failed to load image: " + relativePngPath);
return null;
}
Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
((Object)val2).name = Path.GetFileNameWithoutExtension(relativePngPath);
return val2;
}
public Sprite LoadPngAsSprite(string pngFileName)
{
//IL_002e: 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)
Texture2D val = LoadPngTexture(pngFileName);
if (val == null)
{
return null;
}
Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
((Object)val2).name = pngFileName.Split(".png")[0];
return val2;
}
private Texture2D LoadPngTexture(string pngFileName)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
string text = Path.Combine(_assemblyFolder, "Assets", pngFileName);
if (!File.Exists(text))
{
WKLog.Error("[AssetService] PNG not found at: " + text);
return null;
}
byte[] array = File.ReadAllBytes(text);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (ImageConversion.LoadImage(val, array))
{
return val;
}
WKLog.Error("[AssetService] Failed to decode PNG: " + text);
return null;
}
}
}