Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Hard Item Randomizer v1.11.18
BepInEx/plugins/AssetChainFixer.dll
Decompiled 2 weeks agousing System; using System.Collections; 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.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceLocations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; [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: AssemblyVersion("0.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 AssetChainFixer { [BepInPlugin("com.assetchain.fixer", "AssetChainFixer", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static Plugin Instance; internal static bool ManualPlayEnabled = true; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[AssetChainFixer] 已加载。"); } private void Update() { if (Input_GetKeyDown_F5()) { ChainFixer.RunDemoSpawn(); } if (Input_GetKeyDown_F6()) { ManualPlayEnabled = !ManualPlayEnabled; } } private static bool Input_GetKeyDown_F5() { return Input.GetKeyDown((KeyCode)286); } private static bool Input_GetKeyDown_F6() { return Input.GetKeyDown((KeyCode)287); } } public static class ChainFixer { public enum BundleType { Unknown, Normal, StreamedScene } private static readonly Regex BundleSuffixRegex = new Regex("_[0-9a-fA-F]{32}\\.bundle+$", RegexOptions.Compiled); private static Dictionary<string, string> _bundleKeys; private static Dictionary<string, GameObject> _prefabCache = new Dictionary<string, GameObject>(StringComparer.Ordinal); private static tk2dSpriteCollectionData _cachedCoinRocksCollection; private static bool _coinRocksLoadAttempted; private static Dictionary<string, Sprite> _spriteCache; public static void EnsureBundleKeyMap() { if (_bundleKeys != null) { return; } Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); try { foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators) { foreach (object key2 in resourceLocator.Keys) { if (key2 is string text) { Match match = BundleSuffixRegex.Match(text); if (match.Success) { string key = BundleSuffixRegex.Replace(text, ""); dictionary[key] = text; } } } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[ChainFixer] 构建 bundle key 映射异常: " + ex.Message)); } } _bundleKeys = ((dictionary.Count > 0) ? dictionary : null); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[ChainFixer] bundle key 映射: {dictionary.Count} 个"); } } public static string ToBundleKey(string name) { EnsureBundleKeyMap(); if (_bundleKeys == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[ChainFixer] bundle key 映射未就绪(Addressables 未加载 catalog)"); } return name; } if (BundleSuffixRegex.IsMatch(name)) { name = BundleSuffixRegex.Replace(name, ""); } else if (name.EndsWith(".bundle", StringComparison.OrdinalIgnoreCase)) { name = name.Substring(0, name.Length - 7); } if (_bundleKeys.TryGetValue(name, out var value)) { return value; } throw new Exception("Bundle " + name + " not found in lookup."); } public static List<string> FindKeysContaining(string fragment, string logTag = "ChainFixer") { List<string> list = new List<string>(); try { foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators) { foreach (object key in resourceLocator.Keys) { if (key is string text && text.IndexOf(fragment, StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(text); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] key 匹配 '" + fragment + "': " + text)); } } } } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] 匹配 '{fragment}' 共 {list.Count} 个"); } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[" + logTag + "] 遍历 key 异常: " + ex.Message)); } } return list; } public static T LoadNativeDataSet<T>(string keyFragment, string assetPath, string logTag = "ChainFixer") where T : Object { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0091: Invalid comparison between Unknown and I4 List<string> list = FindKeysContaining(keyFragment, logTag); if (list.Count == 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] 未找到含 '" + keyFragment + "' 的数据集 key")); } return default(T); } string text = list[0]; AssetBundle val = null; try { AsyncOperationHandle<IAssetBundleResource> val2 = default(AsyncOperationHandle<IAssetBundleResource>); val2 = Addressables.LoadAssetAsync<IAssetBundleResource>((object)text); val2.WaitForCompletion(); if ((int)val2.Status != 1 || val2.Result == null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"[{logTag}] 数据集加载失败: {text} → {val2.OperationException}"); } return default(T); } val = val2.Result.GetAssetBundle(); } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[" + logTag + "] 数据集加载异常 " + text + ": " + ex.Message)); } return default(T); } if ((Object)(object)val == (Object)null) { return default(T); } T val3 = val.LoadAsset<T>(assetPath); if ((Object)(object)val3 == (Object)null) { val3 = val.LoadAllAssets<T>().FirstOrDefault(); } if ((Object)(object)val3 != (Object)null) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("[" + logTag + "] 数据集命中: key=" + text + " asset=" + assetPath + " → " + ((Object)val3).name)); } } else { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[" + logTag + "] 数据集未命中: key=" + text + " asset=" + assetPath)); } } return val3; } public static SavedItem LoadDataSavedItem(string keyFragment, string assetName, string logTag = "ChainFixer") { //IL_0028: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 List<string> list = FindKeysContaining(keyFragment, logTag); if (list.Count == 0) { return null; } string text = list[0]; try { AsyncOperationHandle<IAssetBundleResource> val = default(AsyncOperationHandle<IAssetBundleResource>); val = Addressables.LoadAssetAsync<IAssetBundleResource>((object)text); val.WaitForCompletion(); if ((int)val.Status != 1 || val.Result == null) { return null; } AssetBundle assetBundle = val.Result.GetAssetBundle(); if ((Object)(object)assetBundle == (Object)null) { return null; } SavedItem val2 = assetBundle.LoadAsset<SavedItem>(assetName); if ((Object)(object)val2 != (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] 数据集命中 SavedItem '" + assetName + "' @ " + text)); } return val2; } GameObject val3 = assetBundle.LoadAsset<GameObject>(assetName); if ((Object)(object)val3 != (Object)null) { SavedItem component = val3.GetComponent<SavedItem>(); if ((Object)(object)component != (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] 数据集命中 GameObject→SavedItem '" + assetName + "' @ " + text)); } return component; } PrefabCollectable component2 = val3.GetComponent<PrefabCollectable>(); if ((Object)(object)component2 != (Object)null) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] 数据集命中 GameObject→PrefabCollectable '" + assetName + "' @ " + text)); } return (SavedItem)(object)component2; } } ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[" + logTag + "] 数据集未找到 '" + assetName + "' @ " + text)); } } catch (Exception ex) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[" + logTag + "] 数据集加载异常 " + text + ": " + ex.Message)); } } return null; } public static AssetBundle LoadBundleWithDeps(string bundleName, string logTag = "ChainFixer") { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Invalid comparison between Unknown and I4 string text; try { text = ToBundleKey(bundleName); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] bundle key 映射未命中 " + bundleName + ",尝试直接 key 加载: " + ex.Message)); } text = bundleName; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] Addressables 加载 " + bundleName + " → key=" + text)); } AsyncOperationHandle<IAssetBundleResource> val = default(AsyncOperationHandle<IAssetBundleResource>); try { val = Addressables.LoadAssetAsync<IAssetBundleResource>((object)text); val.WaitForCompletion(); if ((int)val.Status != 1 || val.Result == null) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"[{logTag}] Addressables 加载失败: {val.OperationException}"); } return null; } AssetBundle assetBundle = val.Result.GetAssetBundle(); ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("[" + logTag + "] bundle 依赖链加载成功: " + ((Object)assetBundle).name)); } return assetBundle; } catch (Exception ex2) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[" + logTag + "] Addressables 加载异常 " + bundleName + ": " + ex2.Message)); } return null; } } public static List<RuntimeAnimatorController> WarmupBundle(AssetBundle bundle, string logTag = "ChainFixer") { List<RuntimeAnimatorController> list = new List<RuntimeAnimatorController>(); int num = 0; int num2 = 0; int num3 = 0; try { Object[] array = bundle.LoadAllAssets(); foreach (Object val in array) { if (val == (Object)null) { continue; } num3++; if (val is Sprite) { num++; continue; } RuntimeAnimatorController val2 = (RuntimeAnimatorController)(object)((val is RuntimeAnimatorController) ? val : null); if (val2 != null) { list.Add(val2); } else if (val is AnimationClip) { num2++; } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] 预热异常: " + ex.Message)); } } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] 预热(全量): total={num3} sprites={num} controllers={list.Count} clips={num2}"); } return list; } public static int FixAnimatorControllers(GameObject root, List<RuntimeAnimatorController> loadedCtrls, string logTag = "ChainFixer") { if (loadedCtrls == null || loadedCtrls.Count == 0) { return 0; } Dictionary<string, RuntimeAnimatorController> dictionary = new Dictionary<string, RuntimeAnimatorController>(StringComparer.OrdinalIgnoreCase); foreach (RuntimeAnimatorController loadedCtrl in loadedCtrls) { if (!dictionary.ContainsKey(((Object)loadedCtrl).name)) { dictionary[((Object)loadedCtrl).name] = loadedCtrl; } } int num = 0; Animator[] componentsInChildren = root.GetComponentsInChildren<Animator>(true); foreach (Animator val in componentsInChildren) { if ((Object)(object)val == (Object)null || val.layerCount > 0) { continue; } string text = (((Object)(object)val.runtimeAnimatorController != (Object)null) ? ((Object)val.runtimeAnimatorController).name : ((Object)((Component)val).gameObject).name); if (!string.IsNullOrEmpty(text) && dictionary.TryGetValue(text, out var value)) { val.runtimeAnimatorController = value; num++; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] 回填 Controller: {text} → {((Object)((Component)val).gameObject).name}, Layers={val.layerCount}"); } } } return num; } public static GameObject SpawnWithFullChain(string bundleName, string prefabPath, Transform parent, string logTag = "ChainFixer") { AssetBundle val = LoadBundleWithDeps(bundleName, logTag); if ((Object)(object)val == (Object)null) { return null; } List<RuntimeAnimatorController> loadedCtrls = WarmupBundle(val, logTag); GameObject val2 = val.LoadAsset<GameObject>(prefabPath); if ((Object)(object)val2 == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] prefab 加载失败: " + prefabPath)); } return null; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] prefab 加载成功: " + ((Object)val2).name)); } GameObject val3 = Object.Instantiate<GameObject>(val2); if ((Object)(object)parent != (Object)null) { val3.transform.SetParent(parent, false); } val3.SetActive(false); FixAnimatorControllers(val3, loadedCtrls, logTag); return val3; } public static void DumpSceneExtractDiagnostics(string sceneAddress, string sceneBundleKey, Func<GameObject, bool> matcher, string logTag = "ChainFixer") { //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Invalid comparison between Unknown and I4 //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) try { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] ===== F4 场景提取诊断开始 =====")); } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] 目标场景 address: '" + sceneAddress + "',目标 bundle key: '" + sceneBundleKey + "'")); } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] --- 1. 遍历全部 locator keys ---")); } int num = 0; List<string> list = new List<string>(); List<string> list2 = new List<string>(); foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators) { foreach (object key in resourceLocator.Keys) { if (key is string text) { num++; if (text.IndexOf("aspid", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(text); } if (text.StartsWith("Scenes/", StringComparison.OrdinalIgnoreCase)) { list2.Add(text); } } } } ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[{logTag}] locator 总 key 数: {num}"); } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)string.Format("[{0}] 含 'aspid' 的 key ({1}): {2}", logTag, list.Count, string.Join(" | ", list))); } ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogInfo((object)string.Format("[{0}] 以 'Scenes/' 开头的 key ({1}): {2}", logTag, list2.Count, string.Join(" | ", list2.Take(50)))); } ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogInfo((object)("[" + logTag + "] --- 2. LoadResourceLocations 定位场景 " + sceneAddress + " ---")); } try { AsyncOperationHandle<IList<IResourceLocation>> val = Addressables.LoadResourceLocationsAsync((object)sceneAddress, typeof(Scene)); val.WaitForCompletion(); ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)string.Format("[{0}] LoadResourceLocations(Scene) Status={1} Result={2} loc", logTag, val.Status, (val.Result == null) ? "null" : val.Result.Count.ToString())); } if (val.Result != null) { foreach (IResourceLocation item in val.Result) { ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogInfo((object)$"[{logTag}] Scene location: InternalId='{item.InternalId}' PrimaryKey='{item.PrimaryKey}' ResourceType={item.ResourceType} Data={item.Data}"); } } } } catch (Exception ex) { ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogWarning((object)("[" + logTag + "] LoadResourceLocations(Scene) 异常: " + ex.Message)); } } ManualLogSource log11 = Plugin.Log; if (log11 != null) { log11.LogInfo((object)("[" + logTag + "] --- 3. 尝试用场景 address 加载 bundle (IAssetBundleResource) ---")); } try { AsyncOperationHandle<IAssetBundleResource> val2 = Addressables.LoadAssetAsync<IAssetBundleResource>((object)sceneAddress); val2.WaitForCompletion(); ManualLogSource log12 = Plugin.Log; if (log12 != null) { object[] obj = new object[4] { logTag, sceneAddress, val2.Status, null }; object obj2; if (val2.Result != null) { AssetBundle assetBundle = val2.Result.GetAssetBundle(); obj2 = ((assetBundle != null) ? ((Object)assetBundle).name : null); } else { obj2 = "Result=null"; } obj[3] = obj2; log12.LogInfo((object)string.Format("[{0}] LoadAssetAsync<IAssetBundleResource>('{1}') Status={2} {3}", obj)); } if ((int)val2.Status == 1 && val2.Result != null) { AssetBundle assetBundle2 = val2.Result.GetAssetBundle(); if ((Object)(object)assetBundle2 != (Object)null) { ManualLogSource log13 = Plugin.Log; if (log13 != null) { log13.LogInfo((object)("[" + logTag + "] bundle 名: '" + ((Object)assetBundle2).name + "'")); } DumpBundleAssets(assetBundle2, matcher, logTag); } } } catch (Exception ex2) { ManualLogSource log14 = Plugin.Log; if (log14 != null) { log14.LogWarning((object)("[" + logTag + "] 场景 address 加载 bundle 异常: " + ex2.Message)); } } ManualLogSource log15 = Plugin.Log; if (log15 != null) { log15.LogInfo((object)("[" + logTag + "] --- 4. 尝试直接 LoadBundleWithDeps ---")); } AssetBundle val3 = LoadBundleWithDeps(sceneBundleKey, logTag); if ((Object)(object)val3 != (Object)null) { ManualLogSource log16 = Plugin.Log; if (log16 != null) { log16.LogInfo((object)("[" + logTag + "] LoadBundleWithDeps 成功: '" + ((Object)val3).name + "'")); } DumpBundleAssets(val3, matcher, logTag); } else { ManualLogSource log17 = Plugin.Log; if (log17 != null) { log17.LogWarning((object)("[" + logTag + "] LoadBundleWithDeps 失败 (返回 null)")); } } ManualLogSource log18 = Plugin.Log; if (log18 != null) { log18.LogInfo((object)("[" + logTag + "] --- 5. 尝试 AssetBundle.LoadFromFile 直接读磁盘 ---")); } try { string text2 = Application.streamingAssetsPath + "/aa/StandaloneWindows64"; string[] array = new string[3] { text2 + "/scenes_scenes_scenes/aspid_01.bundle", text2 + "/" + sceneBundleKey, text2 + "/aspid_01.bundle" }; string[] array2 = array; foreach (string text3 in array2) { ManualLogSource log19 = Plugin.Log; if (log19 != null) { log19.LogInfo((object)$"[{logTag}] 检查磁盘路径: {text3} exists={File.Exists(text3)}"); } if (File.Exists(text3)) { AssetBundle val4 = AssetBundle.LoadFromFile(text3); ManualLogSource log20 = Plugin.Log; if (log20 != null) { log20.LogInfo((object)("[" + logTag + "] LoadFromFile 结果: " + (((Object)(object)val4 == (Object)null) ? "null" : ((Object)val4).name))); } if ((Object)(object)val4 != (Object)null) { DumpBundleAssets(val4, matcher, logTag); val4.Unload(false); } } } } catch (Exception ex3) { ManualLogSource log21 = Plugin.Log; if (log21 != null) { log21.LogWarning((object)("[" + logTag + "] LoadFromFile 异常: " + ex3.Message)); } } ManualLogSource log22 = Plugin.Log; if (log22 != null) { log22.LogInfo((object)("[" + logTag + "] ===== F4 场景提取诊断结束 =====")); } } catch (Exception arg) { ManualLogSource log23 = Plugin.Log; if (log23 != null) { log23.LogError((object)$"[{logTag}] DumpSceneExtractDiagnostics 异常: {arg}"); } } } private static void DumpBundleAssets(AssetBundle bundle, Func<GameObject, bool> matcher, string logTag) { try { Object[] array = bundle.LoadAllAssets(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] bundle '{((Object)bundle).name}' LoadAllAssets 总数: {array.Length}"); } int num = 0; int num2 = 0; List<GameObject> list = new List<GameObject>(); Object[] array2 = array; foreach (Object val in array2) { if (!(val == (Object)null)) { GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null); if (val2 != null) { num++; list.Add(val2); } else { num2++; } } } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] GameObject 资产: {num} 个,其他资产: {num2} 个"); } foreach (GameObject item in list.Take(80)) { bool flag = false; try { flag = matcher(item); } catch { } if (flag) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] ★命中★ GameObject: '" + ((Object)item).name + "' components=" + string.Join(",", Array.ConvertAll(item.GetComponents<Component>(), (Component c) => ((object)c).GetType().Name)))); } } else { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[{logTag}] GameObject: '{((Object)item).name}' hit={flag}"); } } } } catch (Exception ex) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[" + logTag + "] DumpBundleAssets 异常: " + ex.Message)); } } } public static GameObject ExtractSceneObjectAsTemplate(string bundleName, Func<GameObject, bool> matcher, string logTag = "ChainFixer") { //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Invalid comparison between Unknown and I4 try { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] 从 bundle " + bundleName + " 提取模板")); } AssetBundle val = null; string text = bundleName; int num = text.LastIndexOf('/'); if (num >= 0) { text = text.Substring(num + 1); } string text2 = Regex.Replace(text, "_[0-9a-fA-F]{32}\\.bundle$", ".bundle"); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] 遍历已加载 bundle,匹配名: '" + text2 + "' (来源 '" + bundleName + "')")); } foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if (!((Object)(object)allLoadedAssetBundle == (Object)null)) { bool flag = ((Object)allLoadedAssetBundle).name == text2 || ((Object)allLoadedAssetBundle).name.EndsWith("/" + text2, StringComparison.OrdinalIgnoreCase) || ((Object)allLoadedAssetBundle).name.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"[{logTag}] 已加载 bundle: '{((Object)allLoadedAssetBundle).name}' nameMatch={flag}"); } if (flag) { val = allLoadedAssetBundle; break; } } } if ((Object)(object)val == (Object)null && (bundleName.IndexOf("/", StringComparison.Ordinal) >= 0 || bundleName.StartsWith("Scenes", StringComparison.OrdinalIgnoreCase))) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("[" + logTag + "] 参数为场景 address,尝试 LoadAssetAsync<IAssetBundleResource> 直接取场景 bundle")); } try { AsyncOperationHandle<IAssetBundleResource> val2 = Addressables.LoadAssetAsync<IAssetBundleResource>((object)bundleName); val2.WaitForCompletion(); ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[{logTag}] LoadAssetAsync<IAssetBundleResource> Status={val2.Status}"); } if ((int)val2.Status == 1 && val2.Result != null) { val = val2.Result.GetAssetBundle(); } } catch (Exception ex) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogWarning((object)("[" + logTag + "] 场景 address 加载 bundle 异常: " + ex.Message)); } } } if ((Object)(object)val == (Object)null) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogInfo((object)("[" + logTag + "] 尝试 LoadBundleWithDeps 加载")); } val = LoadBundleWithDeps(bundleName, logTag); } if ((Object)(object)val == (Object)null) { ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)("[" + logTag + "] 尝试 AssetBundle.LoadFromFile 磁盘直读")); } try { string text3 = Application.streamingAssetsPath + "/aa/StandaloneWindows64"; string text4 = text2.Replace(".bundle", "_3f5daa59bb73e1ff0f6bb2d9a0e72e54.bundle"); string[] array = new string[3] { text3 + "/scenes_scenes_scenes/" + text2, text3 + "/scenes_scenes_scenes/" + text4, text3 + "/" + text2 }; string[] array2 = array; foreach (string text5 in array2) { if (File.Exists(text5)) { ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogInfo((object)("[" + logTag + "] LoadFromFile: " + text5)); } AssetBundle val3 = AssetBundle.LoadFromFile(text5); if ((Object)(object)val3 != (Object)null) { val = val3; break; } } } } catch (Exception ex2) { ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogWarning((object)("[" + logTag + "] LoadFromFile 异常: " + ex2.Message)); } } } if ((Object)(object)val == (Object)null) { ManualLogSource log11 = Plugin.Log; if (log11 != null) { log11.LogWarning((object)("[" + logTag + "] bundle 加载失败: " + bundleName)); } return null; } GameObject val4 = null; GameObject[] array3 = val.LoadAllAssets<GameObject>(); ManualLogSource log12 = Plugin.Log; if (log12 != null) { log12.LogInfo((object)$"[{logTag}] bundle 内 GameObject 资产数: {array3.Length}"); } GameObject[] array4 = array3; foreach (GameObject val5 in array4) { if (!((Object)(object)val5 == (Object)null) && matcher(val5)) { val4 = val5; break; } } if ((Object)(object)val4 == (Object)null) { ManualLogSource log13 = Plugin.Log; if (log13 != null) { log13.LogWarning((object)$"[{logTag}] bundle {bundleName} 中未找到匹配对象 (GameObject资产={array3.Length})"); } return null; } GameObject val6 = Object.Instantiate<GameObject>(val4); ((Object)val6).name = ((Object)val4).name + " [Template]"; Object.DontDestroyOnLoad((Object)(object)val6); ManualLogSource log14 = Plugin.Log; if (log14 != null) { log14.LogInfo((object)("[" + logTag + "] 模板提取成功: " + ((Object)val6).name + "(源自 bundle " + bundleName + ",未加载场景)")); } return val6; } catch (Exception arg) { ManualLogSource log15 = Plugin.Log; if (log15 != null) { log15.LogError((object)$"[{logTag}] ExtractSceneObjectAsTemplate 异常: {arg}"); } return null; } } public static GameObject LoadPrefabFixed(string bundleName, string prefabPath, string logTag = "ChainFixer") { string key = bundleName + "|" + prefabPath; if (_prefabCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] prefab 缓存命中: " + prefabPath)); } return value; } AssetBundle val = LoadBundleWithDeps(bundleName, logTag); if ((Object)(object)val == (Object)null) { return null; } List<RuntimeAnimatorController> loadedCtrls = WarmupBundle(val, logTag); GameObject val2 = val.LoadAsset<GameObject>(prefabPath); if ((Object)(object)val2 == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[" + logTag + "] prefab 加载失败: " + prefabPath)); } return null; } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] prefab 加载成功: " + ((Object)val2).name)); } FixAnimatorControllers(val2, loadedCtrls, logTag); _prefabCache[key] = val2; return val2; } public static string ReportSpriteState(GameObject root) { StringBuilder stringBuilder = new StringBuilder(); SpriteRenderer[] componentsInChildren = root.GetComponentsInChildren<SpriteRenderer>(true); foreach (SpriteRenderer val in componentsInChildren) { string text = (((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name : "null"); string text2 = ""; if ((Object)(object)val.sprite != (Object)null) { text2 = (((Object)(object)val.sprite.texture != (Object)null) ? ((Object)val.sprite.texture).name : "noTex"); text2 += (((Object)(object)val.sprite.texture != (Object)null) ? $"({((Texture)val.sprite.texture).width}x{((Texture)val.sprite.texture).height})" : ""); } stringBuilder.AppendLine(" SpriteRenderer '" + ((Object)((Component)val).gameObject).name + "': sprite=" + text + " texture=" + text2); } return stringBuilder.ToString(); } public static tk2dSpriteCollectionData FindSpriteCollection(string collectionName, string logTag = "ChainFixer") { tk2dSpriteCollectionData[] array = Resources.FindObjectsOfTypeAll<tk2dSpriteCollectionData>(); foreach (tk2dSpriteCollectionData val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == collectionName) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] 找到 sprite collection: '{collectionName}' sprites={val.Count}"); } return val; } } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[" + logTag + "] 未找到 sprite collection: '" + collectionName + "'")); } return null; } public static BundleType DetectBundleType(AssetBundle bundle, string logTag = "ChainFixer") { if ((Object)(object)bundle == (Object)null) { return BundleType.Unknown; } try { Object[] array = bundle.LoadAllAssets(); int num = array.Length; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] bundle '{((Object)bundle).name}' 是普通 bundle,LoadAllAssets={num} 个资产"); } return BundleType.Normal; } catch (InvalidOperationException) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] bundle '" + ((Object)bundle).name + "' 是 streamed scene bundle(LoadAllAssets 抛异常)")); } return BundleType.StreamedScene; } catch (Exception ex2) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[" + logTag + "] bundle '" + ((Object)bundle).name + "' 类型检测异常: " + ex2.Message)); } return BundleType.Unknown; } } public static GameObject ExtractFromSceneBundle(string bundleName, Func<GameObject, bool> matcher, string logTag = "ChainFixer") { //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Invalid comparison between Unknown and I4 //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] 从 streamed scene bundle 提取对象: " + bundleName)); } string text = ExtractSceneNameFromBundle(bundleName); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] 推断场景名: '" + text + "'")); } List<string> list = new List<string>(); foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators) { foreach (object key in resourceLocator.Keys) { if (key is string text2 && text2.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(text2); } } } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)string.Format("[{0}] locator 中匹配的 key ({1}): {2}", logTag, list.Count, string.Join(" | ", list.Take(20)))); } foreach (string item in list) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("[" + logTag + "] 尝试 LoadResourceLocations: '" + item + "'")); } try { AsyncOperationHandle<IList<IResourceLocation>> val = Addressables.LoadResourceLocationsAsync((object)item, typeof(SceneInstance)); val.WaitForCompletion(); if (val.Result != null && val.Result.Count > 0) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[{logTag}] LoadResourceLocations 命中 {val.Result.Count} 个"); } foreach (IResourceLocation item2 in val.Result) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogInfo((object)("[" + logTag + "] location: InternalId='" + item2.InternalId + "' PrimaryKey='" + item2.PrimaryKey + "'")); } } AsyncOperationHandle<SceneInstance> val2 = Addressables.LoadSceneAsync((object)item, (LoadSceneMode)1, true, 100, (SceneReleaseMode)0); try { val2.WaitForCompletion(); } catch (Exception ex) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogWarning((object)("[" + logTag + "] WaitForCompletion 异常: " + ex.Message)); } } if ((int)val2.Status == 1) { SceneInstance result = val2.Result; Scene scene = ((SceneInstance)(ref result)).Scene; ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)$"[{logTag}] 场景加载成功: '{((Scene)(ref scene)).name}' rootObjects={((Scene)(ref scene)).rootCount}"); } GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); int num = 0; GameObject val3 = null; GameObject[] array = rootGameObjects; foreach (GameObject val4 in array) { Transform[] componentsInChildren = val4.GetComponentsInChildren<Transform>(true); foreach (Transform val5 in componentsInChildren) { num++; if (((Component)val5).gameObject.activeSelf || ((Component)val5).gameObject.activeInHierarchy) { bool flag = false; try { flag = matcher(((Component)val5).gameObject); } catch { } if (flag) { val3 = ((Component)val5).gameObject; break; } } } if ((Object)(object)val3 != (Object)null) { break; } } ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogInfo((object)$"[{logTag}] 场景内扫描: {num} 个活跃对象, 命中={(Object)(object)val3 != (Object)null}"); } if ((Object)(object)val3 != (Object)null) { GameObject val6 = Object.Instantiate<GameObject>(val3); ((Object)val6).name = ((Object)val3).name + " [Extracted]"; Object.DontDestroyOnLoad((Object)(object)val6); ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogInfo((object)("[" + logTag + "] ★ 模板提取成功: " + ((Object)val6).name)); } try { Addressables.UnloadSceneAsync(val2, true); ManualLogSource log11 = Plugin.Log; if (log11 != null) { log11.LogInfo((object)("[" + logTag + "] 场景已卸载")); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[" + logTag + "] 场景卸载异常: " + ex2.Message)); } return val6; } ManualLogSource log12 = Plugin.Log; if (log12 != null) { log12.LogInfo((object)("[" + logTag + "] 未命中,打印场景对象:")); } GameObject[] array2 = rootGameObjects; foreach (GameObject val7 in array2) { Component[] componentsInChildren2 = val7.GetComponentsInChildren<Component>(true); foreach (Component val8 in componentsInChildren2) { if (!(val8 is Transform) && !(val8 is MeshFilter)) { ManualLogSource log13 = Plugin.Log; if (log13 != null) { log13.LogInfo((object)("[" + logTag + "] '" + ((Object)val8.gameObject).name + "' → " + ((object)val8).GetType().Name)); } } } } try { Addressables.UnloadSceneAsync(val2, true); } catch { } continue; } ManualLogSource log14 = Plugin.Log; if (log14 != null) { log14.LogWarning((object)$"[{logTag}] 场景加载失败: Status={val2.Status}"); } try { if (val2.IsValid()) { Addressables.Release<SceneInstance>(val2); } } catch { } } else { ManualLogSource log15 = Plugin.Log; if (log15 != null) { log15.LogInfo((object)("[" + logTag + "] LoadResourceLocations 无结果")); } } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[" + logTag + "] key '" + item + "' 加载异常: " + ex3.Message)); } } ManualLogSource log16 = Plugin.Log; if (log16 != null) { log16.LogWarning((object)("[" + logTag + "] 所有 key 尝试完毕,未成功提取")); } return null; } private static string ExtractSceneNameFromBundle(string bundleName) { string text = bundleName; int num = text.LastIndexOf('/'); if (num >= 0) { text = text.Substring(num + 1); } text = BundleSuffixRegex.Replace(text, ""); if (text.EndsWith(".bundle", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 7); } int num2 = text.IndexOf('_'); if (num2 > 0) { text = text.Substring(num2 + 1); } int num3 = text.LastIndexOf('_'); if (num3 > 0 && text.Length - num3 == 33) { text = text.Substring(0, num3); } return text; } public static List<Object> ProbeBundleAssets(AssetBundle bundle, Func<Object, bool> matcher = null, string logTag = "ChainFixer") { List<Object> list = new List<Object>(); if ((Object)(object)bundle == (Object)null) { return list; } switch (DetectBundleType(bundle, logTag)) { case BundleType.Normal: { Object[] array = bundle.LoadAllAssets(); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] 普通 bundle '{((Object)bundle).name}' 全量资产: {array.Length}"); } Object[] array2 = array; foreach (Object val in array2) { if (val == (Object)null) { continue; } bool flag = matcher?.Invoke(val) ?? false; if (flag) { list.Add(val); } GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null); if (val2 != null) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)string.Format("[{0}] GO: '{1}' components=[{2}] hit={3}", logTag, ((Object)val2).name, string.Join(",", Array.ConvertAll(val2.GetComponents<Component>(), (Component c) => ((object)c)?.GetType().Name ?? "?")), flag)); } } else { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[{logTag}] Asset: '{val.name}' type={((object)val).GetType().Name} hit={flag}"); } } } break; } case BundleType.StreamedScene: { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] streamed scene bundle '" + ((Object)bundle).name + "' → 需要通过加载场景访问内容")); } break; } } return list; } public static bool SetSpriteFromCollection(tk2dSprite sprite, tk2dSpriteCollectionData collection, string spriteName, string logTag = "ChainFixer") { if ((Object)(object)sprite == (Object)null || (Object)(object)collection == (Object)null) { return false; } int spriteIdByName = collection.GetSpriteIdByName(spriteName); if (spriteIdByName < 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] collection '" + ((Object)collection).name + "' 中未找到 sprite: '" + spriteName + "'")); } return false; } ((tk2dBaseSprite)sprite).SetSprite(collection, spriteIdByName); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] sprite 设置成功: '" + spriteName + "' (collection='" + ((Object)collection).name + "')")); } return true; } public static GameObject CreateTemplate(string name, Action<GameObject> builder, string logTag = "ChainFixer") { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown GameObject val = new GameObject(name); val.SetActive(false); try { builder(val); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[" + logTag + "] CreateTemplate builder 异常: " + ex.Message)); } } Object.DontDestroyOnLoad((Object)(object)val); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[" + logTag + "] 模板创建完成: '" + name + "'")); } return val; } public static tk2dSpriteCollectionData LoadTk2dCollectionBundle(string logTag = "ChainFixer") { if ((Object)(object)_cachedCoinRocksCollection != (Object)null) { return _cachedCoinRocksCollection; } if (_coinRocksLoadAttempted) { return null; } _coinRocksLoadAttempted = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[" + logTag + "] 搜索全内存 tk2dSpriteCollectionData...")); } tk2dSpriteCollectionData[] array = Resources.FindObjectsOfTypeAll<tk2dSpriteCollectionData>(); foreach (tk2dSpriteCollectionData val in array) { if ((Object)(object)val == (Object)null || val.spriteDefinitions == null) { continue; } for (int j = 0; j < val.spriteDefinitions.Length; j++) { if (val.spriteDefinitions[j] != null && val.spriteDefinitions[j].name == "rosary_rock_type_020000") { _cachedCoinRocksCollection = val; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] ★ 找到 Coin Rocks collection: sprites={val.spriteDefinitions.Length} target_index={j}"); } return _cachedCoinRocksCollection; } } } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] 全内存未命中,遍历已加载 bundle...")); } foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle == (Object)null) { continue; } try { tk2dSpriteCollectionData[] array2 = allLoadedAssetBundle.LoadAllAssets<tk2dSpriteCollectionData>(); tk2dSpriteCollectionData[] array3 = array2; foreach (tk2dSpriteCollectionData val2 in array3) { if ((Object)(object)val2 == (Object)null || val2.spriteDefinitions == null) { continue; } for (int l = 0; l < val2.spriteDefinitions.Length; l++) { if (val2.spriteDefinitions[l] != null && val2.spriteDefinitions[l].name == "rosary_rock_type_020000") { _cachedCoinRocksCollection = val2; ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[{logTag}] ★ 从 bundle '{((Object)allLoadedAssetBundle).name}' 找到 Coin Rocks collection: sprites={val2.spriteDefinitions.Length}"); } return _cachedCoinRocksCollection; } } } } catch { } } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[" + logTag + "] 全内存+全 bundle 搜索均未找到 Coin Rocks collection")); } return null; } public static void RunDemoSpawn() { try { Transform val = UIManagerFindCanvas(); GameObject val2 = SpawnWithFullChain("prompts_assets_all.bundle", "Assets/Prefabs/UI/Messages/UI Msg Crest Evolve.prefab", ((Object)(object)val != (Object)null) ? ((Component)val).transform : null, "F5Demo"); if ((Object)(object)val2 == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[F5Demo] 修复流程失败"); } return; } val2.SetActive(true); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[F5Demo] 实例化成功: " + ((Object)val2).name)); } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[F5Demo] " + ReportSpriteState(val2))); } } catch (Exception arg) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogError((object)$"[F5Demo] 异常: {arg}"); } } } private static Transform UIManagerFindCanvas() { try { Type type = Type.GetType("UIManager, Assembly-CSharp"); if (type != null) { Object val = Object.FindObjectOfType(type); if (val != (Object)null) { PropertyInfo property = type.GetProperty("UICanvas"); if (property != null) { object? value = property.GetValue(val); Canvas val2 = (Canvas)((value is Canvas) ? value : null); if (val2 != null) { return ((Component)val2).transform; } } } } } catch { } Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>(); foreach (Canvas val3 in array) { if ((Object)(object)val3 != (Object)null && !val3.overrideSorting) { return ((Component)val3).transform; } } return null; } public static void StartNativeClipPlay(GameObject go, string logTag = "原生采样") { if (!((Object)(object)go == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(NativeClipCoroutine(go, logTag)); } } private static IEnumerator NativeClipCoroutine(GameObject go, string logTag) { int fsmCount = 0; PlayMakerFSM[] componentsInChildren = go.GetComponentsInChildren<PlayMakerFSM>(true); foreach (PlayMakerFSM f in componentsInChildren) { ((Behaviour)f).enabled = false; fsmCount++; } int animCount = 0; Animator[] componentsInChildren2 = go.GetComponentsInChildren<Animator>(true); foreach (Animator a in componentsInChildren2) { ((Behaviour)a).enabled = false; animCount++; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] 已禁用 FSM x{fsmCount} Animator x{animCount}"); } Animator anim = null; Animator[] componentsInChildren3 = go.GetComponentsInChildren<Animator>(true); foreach (Animator a2 in componentsInChildren3) { if ((Object)(object)a2.runtimeAnimatorController != (Object)null) { anim = a2; break; } } if ((Object)(object)anim == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[" + logTag + "] 无 Animator")); } yield break; } RuntimeAnimatorController controller = anim.runtimeAnimatorController; AnimationClip clip = null; string clipName = ""; try { AnimationClip[] clips = controller.animationClips; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[" + logTag + "] controller=" + ((Object)controller).name + " clips=" + ((clips == null) ? "null" : clips.Length.ToString()))); } if (clips != null && clips.Length != 0) { clip = clips[0]; clipName = (((Object)(object)clip != (Object)null) ? $"{((Object)clip).name} len={clip.length}" : "null"); } } catch (Exception ex) { Exception ex2 = ex; ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogError((object)("[" + logTag + "] 取 clip 异常: " + ex2.Message)); } } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)("[" + logTag + "] clip0 = " + clipName)); } Transform lvl1 = go.transform.Find("Tool_Socket_Evolve_lvl1"); if ((Object)(object)lvl1 == (Object)null) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogWarning((object)("[" + logTag + "] 找不到 lvl1")); } yield break; } Transform icon = lvl1.Find("Pivot/Icon"); SpriteRenderer srIcon = (((Object)(object)icon != (Object)null) ? ((Component)icon).GetComponent<SpriteRenderer>() : null); if ((Object)(object)clip == (Object)null) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogWarning((object)("[" + logTag + "] clip 为空,回退手动演出")); } yield return ManualPlayCoroutine(go, logTag); yield break; } AnimationEvent[] evts = clip.events; if (evts != null && evts.Length != 0) { Array.Sort(evts, (AnimationEvent val, AnimationEvent b) => val.time.CompareTo(b.time)); ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)("[" + logTag + "] 事件表: " + string.Join(", ", Array.ConvertAll(evts, (AnimationEvent e) => $"{e.functionName}@{e.time:F2}s")))); } } float t = 0f; float dur = Mathf.Max(0.1f, clip.length); int evtIdx = 0; while (t < dur) { clip.SampleAnimation(((Component)anim).gameObject, t); if (evts != null) { for (; evtIdx < evts.Length && t >= evts[evtIdx].time; evtIdx++) { string fn = evts[evtIdx].functionName; ManualLogSource log9 = Plugin.Log; if (log9 != null) { log9.LogInfo((object)$"[{logTag}] 事件@{t:F2}s: {fn}"); } ((Component)anim).gameObject.SendMessage(fn, (SendMessageOptions)1); if ((Object)(object)go != (Object)null && (Object)(object)go != (Object)(object)((Component)anim).gameObject) { go.SendMessage(fn, (SendMessageOptions)1); } } } t += Time.deltaTime; yield return null; } clip.SampleAnimation(((Component)anim).gameObject, dur - 0.001f); string spriteAtEnd = (((Object)(object)srIcon != (Object)null && (Object)(object)srIcon.sprite != (Object)null) ? ((Object)srIcon.sprite).name : "nullSprite"); ManualLogSource log10 = Plugin.Log; if (log10 != null) { log10.LogInfo((object)$"[{logTag}] 采样完成 dur={dur:F2} 终帧Icon={spriteAtEnd}"); } yield return (object)new WaitForSeconds(1f); Object.Destroy((Object)(object)go); } public static Sprite FindLoadedSprite(string name) { if (_spriteCache != null && _spriteCache.TryGetValue(name, out var value)) { return value; } if (_spriteCache == null) { _spriteCache = new Dictionary<string, Sprite>(); } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if (!((Object)(object)val == (Object)null) && !(((Object)val).name != name)) { _spriteCache[name] = val; return val; } } _spriteCache[name] = null; return null; } public static void StartManualPlay(GameObject go, string logTag = "手动演出") { if (!((Object)(object)go == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ManualPlayCoroutine(go, logTag)); } } private static IEnumerator ManualPlayCoroutine(GameObject go, string logTag) { int disabled = 0; Animator[] componentsInChildren = go.GetComponentsInChildren<Animator>(true); foreach (Animator a in componentsInChildren) { ((Behaviour)a).enabled = false; disabled++; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[{logTag}] 已禁用 Animator x{disabled}"); } int fsmCount = 0; PlayMakerFSM[] componentsInChildren2 = go.GetComponentsInChildren<PlayMakerFSM>(true); foreach (PlayMakerFSM f in componentsInChildren2) { ((Behaviour)f).enabled = false; fsmCount++; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[{logTag}] 已禁用 PlayMakerFSM x{fsmCount}"); } Transform lvl1 = go.transform.Find("Tool_Socket_Evolve_lvl1"); if ((Object)(object)lvl1 == (Object)null) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[" + logTag + "] 找不到 Tool_Socket_Evolve_lvl1")); } yield break; } Transform icon = lvl1.Find("Pivot/Icon"); Transform iconGlow = lvl1.Find("Pivot/Icon_Glow"); Transform crest = lvl1.Find("Pivot/Crest"); Transform crestGlow = lvl1.Find("Pivot/Crest_Glow"); Transform flash = lvl1.Find("white_flash"); Transform burst = lvl1.Find("evolve_burst"); Transform loop = lvl1.Find("evolve_loop"); Transform bg = go.transform.Find("BG"); SpriteRenderer srIcon = GetSR(icon); SpriteRenderer srIconGlow = GetSR(iconGlow); SpriteRenderer srCrest = GetSR(crest); SpriteRenderer srCrestGlow = GetSR(crestGlow); SpriteRenderer srFlash = GetSR(flash); SpriteRenderer srBG = GetSR(bg); Sprite sprSingle = FindLoadedSprite("UI_tool_slot_extra_sockets_single"); Sprite sprTiny = FindLoadedSprite("UI_tool_slot_extra_sockets_0000_filled_tiny"); Sprite sprGlow = FindLoadedSprite("UI_tool_slot_extra_sockets_0000_filled_glow"); Sprite sprIcon = FindLoadedSprite("hornet_prompts_tool_sockets_0001_explorer_socket"); sprSingle = snap(srCrest, sprSingle); sprTiny = snap(srCrest, sprTiny); sprGlow = snap(srCrestGlow, sprGlow); sprIcon = snap(srIcon, sprIcon); ManualLogSource log4 = Plugin.Log; if (log4 != null) { string[] obj = new string[12] { "[", logTag, "] sprite: single=", null, null, null, null, null, null, null, null, null }; Sprite obj2 = sprSingle; obj[3] = ((obj2 != null) ? ((Object)obj2).name : null) ?? "null"; obj[4] = " tiny="; Sprite obj3 = sprTiny; obj[5] = ((obj3 != null) ? ((Object)obj3).name : null) ?? "null"; obj[6] = " glow="; Sprite obj4 = sprGlow; obj[7] = ((obj4 != null) ? ((Object)obj4).name : null) ?? "null"; obj[8] = " icon="; Sprite obj5 = sprIcon; obj[9] = ((obj5 != null) ? ((Object)obj5).name : null) ?? "null"; obj[10] = " bg="; object obj6; if (srBG == null) { obj6 = null; } else { Sprite sprite = srBG.sprite; obj6 = ((sprite != null) ? ((Object)sprite).name : null); } if (obj6 == null) { obj6 = "null"; } obj[11] = (string)obj6; log4.LogInfo((object)string.Concat(obj)); } ParticleSystem psBurst = (((Object)(object)burst != (Object)null) ? ((Component)burst).GetComponent<ParticleSystem>() : null); ParticleSystem psLoop = (((Object)(object)loop != (Object)null) ? ((Component)loop).GetComponent<ParticleSystem>() : null); if ((Object)(object)psBurst != (Object)null) { EmissionModule e = psBurst.emission; ((EmissionModule)(ref e)).enabled = false; e = default(EmissionModule); } if ((Object)(object)psLoop != (Object)null) { EmissionModule e2 = psLoop.emission; ((EmissionModule)(ref e2)).enabled = false; psLoop.Stop(true, (ParticleSystemStopBehavior)0); e2 = default(EmissionModule); } if ((Object)(object)srBG != (Object)null) { srBG.color = new Color(0f, 0f, 0f, 0f); bg.SetAsFirstSibling(); } if ((Object)(object)srIcon != (Object)null) { srIcon.sprite = sprIcon; srIcon.color = new Color(1f, 1f, 1f, 0f); } if ((Object)(object)srIconGlow != (Object)null) { srIconGlow.color = new Color(1f, 1f, 1f, 0f); } if ((Object)(object)srCrest != (Object)null) { srCrest.sprite = sprSingle; srCrest.color = new Color(1f, 1f, 1f, 0f); } if ((Object)(object)srCrestGlow != (Object)null) { srCrestGlow.sprite = sprGlow; srCrestGlow.color = new Color(1f, 1f, 1f, 0f); } if ((Object)(object)srFlash != (Object)null) { srFlash.color = new Color(1f, 1f, 1f, 0f); } crest.localScale = Vector3.one * 0.4f; float t = 0f; float bgIn = 0.28f; while (t < 0.58000004f) { t += Time.deltaTime; float kb = Mathf.Clamp01(t / bgIn) * 0.85f; if ((Object)(object)srBG != (Object)null) { srBG.color = new Color(0f, 0f, 0f, kb); } float ki = Mathf.Clamp01((t - 0.05f) / 0.22f); if ((Object)(object)srIcon != (Object)null) { srIcon.color = new Color(1f, 1f, 1f, ki); } if ((Object)(object)srIconGlow != (Object)null) { srIconGlow.color = new Color(1f, 1f, 1f, ki * 0.5f); } yield return null; } while (t < 1f) { t += Time.deltaTime; float k = Mathf.Clamp01((t - 0.58f) / 0.42f); float e3 = 1f - Mathf.Pow(1f - k, 3f); crest.localScale = Vector3.one * Mathf.Lerp(0.4f, 1.12f, e3); if ((Object)(object)srCrest != (Object)null) { srCrest.color = new Color(1f, 1f, 1f, e3); } if ((Object)(object)srCrestGlow != (Object)null) { srCrestGlow.color = new Color(1f, 1f, 1f, e3); ((Component)srCrestGlow).transform.localScale = Vector3.one * Mathf.Lerp(2.2f, 2.8f, e3); } yield return null; } if ((Object)(object)srCrest != (Object)null && (Object)(object)sprTiny != (Object)null) { srCrest.sprite = sprTiny; } yield return (object)new WaitForSeconds(0.12f); if ((Object)(object)srCrest != (Object)null && (Object)(object)sprGlow != (Object)null) { srCrest.sprite = sprGlow; } if ((Object)(object)psBurst != (Object)null) { psBurst.Play(); } if ((Object)(object)srFlash != (Object)null) { float ft = 0f; while (ft < 0.22f) { ft += Time.deltaTime; float k2 = ((ft < 0.07f) ? (ft / 0.07f) : (1f - (ft - 0.07f) / 0.15f)); srFlash.color = new Color(1f, 1f, 1f, Mathf.Clamp01(k2) * 0.95f); yield return null; } srFlash.color = new Color(1f, 1f, 1f, 0f); } if ((Object)(object)psBurst != (Object)null) { psBurst.Stop(true, (ParticleSystemStopBehavior)0); } yield return (object)new WaitForSeconds(1.2f); float ot = 0f; while (ot < 0.5f) { ot += Time.deltaTime; float k3 = 1f - Mathf.Clamp01(ot / 0.5f); if ((Object)(object)srBG != (Object)null && (Object)(object)srBG != (Object)null) { srBG.color = new Color(0f, 0f, 0f, 0.85f * k3); } if ((Object)(object)srIcon != (Object)null) { srIcon.color = new Color(1f, 1f, 1f, k3); } if ((Object)(object)srIconGlow != (Object)null) { srIconGlow.color = new Color(1f, 1f, 1f, k3 * 0.5f); } if ((Object)(object)srCrest != (Object)null) { srCrest.color = new Color(1f, 1f, 1f, k3); } if ((Object)(object)srCrestGlow != (Object)null) { srCrestGlow.color = new Color(1f, 1f, 1f, k3); } yield return null; } Object.Destroy((Object)(object)go); ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)("[" + logTag + "] 演出完成,已销毁")); } static SpriteRenderer GetSR(Transform val) { return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<SpriteRenderer>() : null; } static Sprite snap(SpriteRenderer sr, Sprite fallback) { if ((Object)(object)sr != (Object)null && (Object)(object)sr.sprite != (Object)null) { return sr.sprite; } return fallback; } } } }
BepInEx/plugins/HKSilksong_SceneRandomizer.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using SilksongItemRandomizer; using StartingAbilityPicker; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace HKSilksong_Randomizer; public static class RoomMapGenerator { private static readonly bool[,] letters; static RoomMapGenerator() { letters = new bool[128, 25]; string[] array = new string[26] { "01110100011000111111000110001", "11110100011111010001100011111", "01110100011000010000100000111", "11110100011000110001100011110", "11111100001111010000100011111", "11111100001111010000100010000", "01110100011000010111100001111", "10001100011111110001100011000", "01110001000010000100001000111", "00111000100001000100011001100", "10001100101110010010100011000", "10000100001000010000100001111", "10001110111010110001100011000", "10001110011010110011100011000", "01110100011000110001100010111", "11110100011111010000100010000", "01110100011000110001101010101", "11110100011111010010100011001", "01111100000111000001100011110", "11111001000010000100001000010", "10001100011000110001100001110", "10001100011000101010001000100", "10001100011000110101101011010", "10001010100010001010100010001", "10001010100010000100001000010", "11111000100010001000100011111" }; for (int i = 0; i < 26; i++) { string text = array[i]; for (int j = 0; j < 25; j++) { letters[65 + i, j] = text[j] == '1'; } } string[] array2 = new string[10] { "01110100011000110001100010111", "00100011000010000100001000111", "01110100010001000100010001111", "11110000111100000011100011110", "10001100111110000010000100010", "11111100001111000001100011111", "01110100001111010001100010111", "11111000010001000100001000010", "01110100011000101110100010111", "01110100011000101111000011110" }; for (int k = 0; k < 10; k++) { string text2 = array2[k]; for (int l = 0; l < 25; l++) { letters[48 + k, l] = text2[l] == '1'; } } string text3 = "00000000000000000000011111"; for (int m = 0; m < 25; m++) { letters[95, m] = text3[m] == '1'; } } public static bool GenerateFromFile(string connectionsFilePath, string outputImagePath) { if (!File.Exists(connectionsFilePath)) { Debug.LogWarning((object)("File not found: " + connectionsFilePath)); return false; } string[] array = File.ReadAllLines(connectionsFilePath); Dictionary<string, HashSet<string>> dictionary = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase); string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string text = array2[i]?.Trim(); if (string.IsNullOrEmpty(text) || text.StartsWith("#")) { continue; } string[] array3 = text.Split(new char[1] { '|' }); if (array3.Length != 4) { continue; } string text2 = array3[0]; string text3 = array3[2]; if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(text3)) { if (!dictionary.ContainsKey(text2)) { dictionary[text2] = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } if (!dictionary.ContainsKey(text3)) { dictionary[text3] = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } dictionary[text2].Add(text3); dictionary[text3].Add(text2); } } if (dictionary.Count == 0) { Debug.LogWarning((object)"No connections found."); return false; } GenerateMapTexture(dictionary, outputImagePath); Debug.Log((object)("Map saved to " + outputImagePath)); return true; } private static void GenerateMapTexture(Dictionary<string, HashSet<string>> graph, string outputPath) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0077: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) int num = 250; int num2 = 120; int num3 = 100; int num4 = 80; List<string> list = graph.Keys.ToList(); int num5 = (int)Math.Ceiling(Math.Sqrt(list.Count)); int num6 = (int)Math.Ceiling((double)list.Count / (double)num5); int num7 = num5 * (num + num3) + num3; int num8 = num6 * (num2 + num4) + num4; Texture2D val = new Texture2D(num7, num8, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[num7 * num8]; for (int i = 0; i < array.Length; i++) { array[i] = Color.black; } val.SetPixels(array); Dictionary<string, Vector2> dictionary = new Dictionary<string, Vector2>(); int num9 = 0; int num10 = 0; foreach (string item in list) { dictionary[item] = new Vector2((float)(num3 + num9 * (num + num3)), (float)(num4 + num10 * (num2 + num4))); num9++; if (num9 >= num5) { num9 = 0; num10++; } } foreach (KeyValuePair<string, HashSet<string>> item2 in graph) { if (!dictionary.TryGetValue(item2.Key, out var value)) { continue; } foreach (string item3 in item2.Value) { if (dictionary.TryGetValue(item3, out var value2)) { DrawLine(val, (int)(value.x + (float)(num / 2)) + 2, (int)(value.y + (float)(num2 / 2)) + 2, (int)(value2.x + (float)(num / 2)) + 2, (int)(value2.y + (float)(num2 / 2)) + 2, Color.gray, 3); } } } foreach (KeyValuePair<string, Vector2> item4 in dictionary) { DrawEmptyRectangle(val, (int)item4.Value.x, (int)item4.Value.y, num, num2, Color.gray); DrawTextBitmap(val, (int)item4.Value.x + 10, (int)item4.Value.y + 35, item4.Key, Color.white); } val.Apply(); string directoryName = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllBytes(outputPath, ImageConversion.EncodeToPNG(val)); Object.DestroyImmediate((Object)(object)val); } private static void DrawEmptyRectangle(Texture2D tex, int x, int y, int w, int h, Color color) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) for (int i = x; i < x + w; i++) { if (i >= 0 && i < ((Texture)tex).width) { if (y >= 0 && y < ((Texture)tex).height) { tex.SetPixel(i, y, color); } if (y + h - 1 >= 0 && y + h - 1 < ((Texture)tex).height) { tex.SetPixel(i, y + h - 1, color); } } } for (int j = y; j < y + h; j++) { if (j >= 0 && j < ((Texture)tex).height) { if (x >= 0 && x < ((Texture)tex).width) { tex.SetPixel(x, j, color); } if (x + w - 1 >= 0 && x + w - 1 < ((Texture)tex).width) { tex.SetPixel(x + w - 1, j, color); } } } } private static void DrawTextBitmap(Texture2D tex, int x, int y, string text, Color color) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) int num = x; int num2 = 4; int num3 = 1; string text2 = text.ToUpper(); foreach (char c in text2) { if ((c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_') { num += 5 * num2 + num2; continue; } for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { if (!letters[(uint)c, j * 5 + k]) { continue; } int num4 = ((c != '_') ? (4 - j) : (4 - j - num3)); for (int l = 0; l < num2; l++) { for (int m = 0; m < num2; m++) { int num5 = num + k * num2 + l; int num6 = y + num4 * num2 + m; if (num5 >= 0 && num5 < ((Texture)tex).width && num6 >= 0 && num6 < ((Texture)tex).height) { tex.SetPixel(num5, num6, color); } } } } } num += 5 * num2 + num2; } } private static void DrawLine(Texture2D tex, int x0, int y0, int x1, int y1, Color color, int thickness = 2) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) int num = Math.Abs(x1 - x0); int num2 = ((x0 < x1) ? 1 : (-1)); int num3 = -Math.Abs(y1 - y0); int num4 = ((y0 < y1) ? 1 : (-1)); int num5 = num + num3; while (true) { for (int i = -thickness / 2; i <= thickness / 2; i++) { for (int j = -thickness / 2; j <= thickness / 2; j++) { int num6 = x0 + i; int num7 = y0 + j; if (num6 >= 0 && num6 < ((Texture)tex).width && num7 >= 0 && num7 < ((Texture)tex).height) { tex.SetPixel(num6, num7, color); } } } if (x0 != x1 || y0 != y1) { int num8 = 2 * num5; if (num8 >= num3) { num5 += num3; x0 += num2; } if (num8 <= num) { num5 += num; y0 += num4; } continue; } break; } } } [BepInPlugin("HardItemRandomizer.HKSilksong_SceneRandomizer", "Random Scene Loader", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RandomSceneLoader : BaseUnityPlugin { internal class SceneConfig { public List<string> Exits; public SceneConfig(List<string> exits) { Exits = exits ?? new List<string>(); } } internal ManualLogSource log; private Random rng; internal readonly Dictionary<string, SceneConfig> sceneConfigs = new Dictionary<string, SceneConfig>(StringComparer.OrdinalIgnoreCase) { { "Tut_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "top1" }) }, { "Tut_01b", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Tut_02", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Tut_03", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Bonetown", new SceneConfig(new List<string> { "bot1", "bot2", "left1", "left2", "right1", "right2", "top1", "top2", "top3", "top4", "top5", "top6" }) }, { "Weave_02", new SceneConfig(new List<string> { "left2", "left3", "left4", "right1", "right2", "right3" }) }, { "Weave_03", new SceneConfig(new List<string> { "right1" }) }, { "Weave_04", new SceneConfig(new List<string> { "left1", "right2" }) }, { "Weave_05b", new SceneConfig(new List<string> { "left1" }) }, { "Weave_07", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Weave_08", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Weave_10", new SceneConfig(new List<string> { "left1" }) }, { "Weave_11", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Weave_12", new SceneConfig(new List<string> { "left1" }) }, { "Weave_13", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Weave_14", new SceneConfig(new List<string> { "bot1" }) }, { "Bone_01", new SceneConfig(new List<string> { "left2", "right1", "right2", "top2" }) }, { "Bone_04", new SceneConfig(new List<string> { "bot2", "left1", "left2", "right1", "top1" }) }, { "Bone_05", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_03", new SceneConfig(new List<string> { "bot1", "left1", "left2", "left4", "right1", "right3", "top1" }) }, { "Bone_05b", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Bone_06", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_07", new SceneConfig(new List<string> { "left1", "right1", "right2", "top1" }) }, { "Bone_08", new SceneConfig(new List<string> { "bot1", "left2", "left3", "right2", "right3" }) }, { "Bone_09", new SceneConfig(new List<string> { "left1", "right1", "right2", "top1" }) }, { "Bone_10", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_11", new SceneConfig(new List<string> { "bot1", "left1", "right1", "right2", "top1" }) }, { "Bone_14", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bone_15", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Bone_16", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Bone_17", new SceneConfig(new List<string> { "right1" }) }, { "Bone_18", new SceneConfig(new List<string> { "left1" }) }, { "Bone_19", new SceneConfig(new List<string> { "bot1" }) }, { "Bone_East_01", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Bone_East_02", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Bone_East_04", new SceneConfig(new List<string> { "bot1", "left1", "right1", "right2", "top2" }) }, { "Bone_East_05", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bone_East_07", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3", "right4", "right5", "top1" }) }, { "Bone_East_09", new SceneConfig(new List<string> { "left2", "left3", "right1", "right2", "top1" }) }, { "Bone_East_10", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Bone_East_11", new SceneConfig(new List<string> { "bot1", "left1", "right1", "right2" }) }, { "Bone_East_12", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_East_13", new SceneConfig(new List<string> { "left1" }) }, { "Bone_East_14", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Bone_East_15", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_East_16", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Bone_East_17", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_East_18", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Bone_East_18b", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Bone_East_18c", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bone_East_20", new SceneConfig(new List<string> { "right1" }) }, { "Bone_East_22", new SceneConfig(new List<string> { "left1" }) }, { "Bone_East_24", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_East_25", new SceneConfig(new List<string> { "left1" }) }, { "Bone_East_26", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Bone_East_27", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Bone_East_04c", new SceneConfig(new List<string> { "left1" }) }, { "Bone_East_04b", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Bone_East_09b", new SceneConfig(new List<string> { "bot1", "left1", "top1" }) }, { "Bone_East_14b", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Ant_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_03", new SceneConfig(new List<string> { "left2", "right3" }) }, { "Ant_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_04_left", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_04_mid", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_05b", new SceneConfig(new List<string> { "bot1", "bot2", "right1" }) }, { "Ant_05c", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_09", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Ant_14", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "left5", "right2", "right3" }) }, { "Ant_17", new SceneConfig(new List<string> { "right1" }) }, { "Ant_19", new SceneConfig(new List<string> { "left1" }) }, { "Ant_20", new SceneConfig(new List<string> { "left1" }) }, { "Ant_21", new SceneConfig(new List<string> { "right1" }) }, { "Ant_Merchant", new SceneConfig(new List<string> { "right1" }) }, { "Ant_Queen", new SceneConfig(new List<string> { "left1" }) }, { "Aspid_01", new SceneConfig(new List<string> { "bot1", "bot2", "bot3", "bot4", "bot5", "bot6", "bot7", "bot8", "left1", "left2", "right2", "right3", "right4", "top1", "top2", "top3", "top4", "top5", "top6", "top7" }) }, { "Belltown_04", new SceneConfig(new List<string> { "bot1", "left1", "left2" }) }, { "Belltown_06", new SceneConfig(new List<string> { "left1", "left3", "right1" }) }, { "Belltown_Room_shellwood", new SceneConfig(new List<string> { "left1" }) }, { "Belltown_Shrine", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Belltown_basement_03", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Bellshrine", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bellshrine_03", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bonegrave", new SceneConfig(new List<string> { "right1", "right2", "top1" }) }, { "Bone_01c", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Bone_02", new SceneConfig(new List<string> { "left1", "right1", "top1", "top2" }) }, { "Bellshrine_05", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bellway_03", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Greymoor_01", new SceneConfig(new List<string> { "bot1", "left1", "left2", "right1", "right2", "right3" }) }, { "Bellshrine_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Greymoor_02", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Greymoor_15", new SceneConfig(new List<string> { "left1", "left3", "right2", "right3" }) }, { "Greymoor_15b", new SceneConfig(new List<string> { "left2", "left3", "right1", "top1" }) }, { "Room_CrowCourt", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Room_CrowCourt_02", new SceneConfig(new List<string> { "top1" }) }, { "Clover_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Greymoor_22", new SceneConfig(new List<string> { "bot1" }) }, { "Greymoor_12", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Greymoor_03", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3", "right4", "right5" }) }, { "Dust_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Dust_02", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3", "top1" }) }, { "Dust_03", new SceneConfig(new List<string> { "bot1", "left1", "top1" }) }, { "Dust_Chef", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Dust_04", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Dust_Shack", new SceneConfig(new List<string> { "left1" }) }, { "Dust_10", new SceneConfig(new List<string> { "right1" }) }, { "Dust_05", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Dust_06", new SceneConfig(new List<string> { "left1", "right1", "right2", "right3" }) }, { "Dust_12", new SceneConfig(new List<string> { "left1" }) }, { "Dust_11", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Greymoor_17", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Halfway_01", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Greymoor_04", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2" }) }, { "Greymoor_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Greymoor_06", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3", "right4", "top1" }) }, { "Greymoor_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Wisp_03", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Wisp_06", new SceneConfig(new List<string> { "bot1" }) }, { "Greymoor_07", new SceneConfig(new List<string> { "bot1", "left1", "right1", "right2" }) }, { "Greymoor_20b", new SceneConfig(new List<string> { "right1" }) }, { "Greymoor_20c", new SceneConfig(new List<string> { "left1" }) }, { "Greymoor_08", new SceneConfig(new List<string> { "left2", "right1", "top1" }) }, { "Greymoor_16", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Bellway_04", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Greymoor_05", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Belltown", new SceneConfig(new List<string> { "left3", "right2" }) }, { "Memory_Needolin", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Belltown_07", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_01", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Shellwood_02", new SceneConfig(new List<string> { "left2", "left3", "right1", "right2" }) }, { "Shellwood_16", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_03", new SceneConfig(new List<string> { "bot1", "left1", "left3", "right1", "right2", "right3" }) }, { "Shellwood_04b", new SceneConfig(new List<string> { "left1", "right1", "top1", "top2" }) }, { "Shellwood_08c", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_04c", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Shellwood_08", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Coral_19", new SceneConfig(new List<string> { "bot1", "bot2", "bot3", "bot4", "bot5", "bot6", "bot7", "right1", "top1", "top2", "top3", "top4", "top5", "top6", "top7", "top8" }) }, { "Shellwood_19", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_14", new SceneConfig(new List<string> { "left1" }) }, { "Shellwood_10", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Shellwood_11", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Shellwood_26", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Shellwood_18", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Shellwood_13", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Shellwood_01b", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Shellwood_20", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_Witch", new SceneConfig(new List<string> { "right1" }) }, { "Dock_08", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Dock_01", new SceneConfig(new List<string> { "left1", "right1", "right2" }) }, { "Bellway_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Dock_16", new SceneConfig(new List<string> { "right1" }) }, { "Bone_East_03", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Room_Forge", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Dock_04", new SceneConfig(new List<string> { "left1", "right1", "right2", "right3" }) }, { "Dock_06_Church", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Dock_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Dock_15", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Dock_13", new SceneConfig(new List<string> { "right1" }) }, { "Dock_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Dock_12", new SceneConfig(new List<string> { "left1" }) }, { "Dock_14", new SceneConfig(new List<string> { "left1" }) }, { "Dock_09", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Dock_02", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Dock_02b", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2" }) }, { "Dock_03c", new SceneConfig(new List<string> { "left2", "top1", "top2" }) }, { "Dock_03", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Dock_03b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shellwood_15", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_19b", new SceneConfig(new List<string> { "bot1" }) }, { "Coral_02", new SceneConfig(new List<string> { "bot2", "right1" }) }, { "Coral_03", new SceneConfig(new List<string> { "bot1", "bot2", "bot3", "bot4", "bot5", "bot6", "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Coral_12", new SceneConfig(new List<string> { "left2", "left3", "right1" }) }, { "Coral_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_11b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_34", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Coral_25", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Coral_23", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Coral_39", new SceneConfig(new List<string> { "right1" }) }, { "Coral_35b", new SceneConfig(new List<string> { "bot1", "left2", "left3", "left4", "left5", "right1", "right2" }) }, { "Coral_40", new SceneConfig(new List<string> { "right1" }) }, { "Coral_41", new SceneConfig(new List<string> { "right1" }) }, { "Coral_35", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "top1" }) }, { "Coral_24", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_26", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Coral_38", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Coral_44", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_29", new SceneConfig(new List<string> { "left1" }) }, { "Coral_27", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_28", new SceneConfig(new List<string> { "right1" }) }, { "Coral_Tower_01", new SceneConfig(new List<string> { "left1" }) }, { "Coral_42", new SceneConfig(new List<string> { "right1" }) }, { "Coral_43", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bellway_08", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_32", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Coral_Judge_Arena", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Coral_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Song_19_entrance", new SceneConfig(new List<string> { "left1", "right1", "right2" }) }, { "Song_01c", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Song_01", new SceneConfig(new List<string> { "bot1", "right2", "top1" }) }, { "Under_07b", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Song_01b", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Song_05", new SceneConfig(new List<string> { "left3", "left4", "left5", "right2", "right3", "right4" }) }, { "Song_02", new SceneConfig(new List<string> { "left2", "right1" }) }, { "Ward_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Ward_02", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Ward_02b", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Ward_03", new SceneConfig(new List<string> { "bot1", "left1", "top1" }) }, { "Ward_07", new SceneConfig(new List<string> { "bot1" }) }, { "Ward_06", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Song_07", new SceneConfig(new List<string> { "right1" }) }, { "Song_27", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Song_20", new SceneConfig(new List<string> { "left1", "left2", "right4", "right5", "right6", "top1" }) }, { "Bellway_City", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Library_13", new SceneConfig(new List<string> { "left1", "right1", "right2" }) }, { "Song_11", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3" }) }, { "Song_15", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Song_17", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Hang_01", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Hang_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Hang_03", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "top1" }) }, { "Hang_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Hang_03_top", new SceneConfig(new List<string> { "bot1" }) }, { "Hang_13", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Hang_08", new SceneConfig(new List<string> { "bot1", "left1", "left2", "left3", "left4", "right1" }) }, { "Hang_09", new SceneConfig(new List<string> { "right1" }) }, { "Hang_16", new SceneConfig(new List<string> { "right1" }) }, { "Hang_06", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1" }) }, { "Hang_06b", new SceneConfig(new List<string> { "left1" }) }, { "Hang_17b", new SceneConfig(new List<string> { "left1" }) }, { "Hang_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Hang_12", new SceneConfig(new List<string> { "right1" }) }, { "Hang_07", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1" }) }, { "Song_09", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Song_09b", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Cog_05", new SceneConfig(new List<string> { "left1", "right2", "top1" }) }, { "Cog_Dancers", new SceneConfig(new List<string> { "bot1", "bot2", "left1", "right1", "top1" }) }, { "Cog_04", new SceneConfig(new List<string> { "left2", "right2", "right3", "top1", "top2" }) }, { "Cog_Bench", new SceneConfig(new List<string> { "left1" }) }, { "Song_25", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1", "top2" }) }, { "Song_Enclave", new SceneConfig(new List<string> { "bot1", "left1", "left2", "top1" }) }, { "Song_Enclave_Tube", new SceneConfig(new List<string> { "bot1" }) }, { "Under_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1" }) }, { "Under_27", new SceneConfig(new List<string> { "left1", "right1", "right2" }) }, { "Shellwood_22", new SceneConfig(new List<string> { "right1" }) }, { "Shellwood_11b", new SceneConfig(new List<string> { "right1" }) }, { "Under_01b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Under_02", new SceneConfig(new List<string> { "left1", "left3", "right1", "right2", "right3", "right4" }) }, { "Under_14", new SceneConfig(new List<string> { "left1" }) }, { "Under_16", new SceneConfig(new List<string> { "right1" }) }, { "Under_03b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Under_07", new SceneConfig(new List<string> { "left3", "right2" }) }, { "Under_07c", new SceneConfig(new List<string> { "left2", "top1" }) }, { "Under_06", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Under_08", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Under_05", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Under_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Under_23", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Wisp_09", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Wisp_05", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Wisp_02", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Belltown_08", new SceneConfig(new List<string> { "right1" }) }, { "Wisp_04", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Wisp_08", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Wisp_07", new SceneConfig(new List<string> { "left1" }) }, { "Under_04", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Under_03c", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Under_03", new SceneConfig(new List<string> { "right1" }) }, { "Under_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Under_12", new SceneConfig(new List<string> { "left1" }) }, { "Under_13", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3" }) }, { "Under_22", new SceneConfig(new List<string> { "right1" }) }, { "Under_21", new SceneConfig(new List<string> { "right1" }) }, { "Under_19", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Under_19c", new SceneConfig(new List<string> { "bot1", "left1", "left2" }) }, { "Under_19b", new SceneConfig(new List<string> { "right1" }) }, { "Under_18", new SceneConfig(new List<string> { "left1", "right1", "top1", "top2" }) }, { "Under_17", new SceneConfig(new List<string> { "bot1", "bot2", "left1", "right1", "top1" }) }, { "Library_11b", new SceneConfig(new List<string> { "left3", "right1" }) }, { "Library_11", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2" }) }, { "Library_13b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Library_04", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3", "right4", "right5", "right6", "top1" }) }, { "Library_16", new SceneConfig(new List<string> { "right1" }) }, { "Library_10", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Library_12b", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Library_12", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Library_05", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Library_06", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Library_07", new SceneConfig(new List<string> { "bot1", "bot2", "bot3", "left1", "left2", "top1" }) }, { "Library_08", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Library_09", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Library_14", new SceneConfig(new List<string> { "left1" }) }, { "Library_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2" }) }, { "Library_15", new SceneConfig(new List<string> { "right1" }) }, { "Library_03", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Song_24", new SceneConfig(new List<string> { "right1" }) }, { "Song_20b", new SceneConfig(new List<string> { "bot1", "left2", "left4", "right2", "right3", "top1" }) }, { "Library_02", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Song_29", new SceneConfig(new List<string> { "right1" }) }, { "Arborium_01", new SceneConfig(new List<string> { "bot1", "left1", "left2", "left3", "right1", "right2", "right3", "right4", "right5" }) }, { "Cog_10", new SceneConfig(new List<string> { "bot1" }) }, { "Cog_07", new SceneConfig(new List<string> { "left1" }) }, { "Cog_06", new SceneConfig(new List<string> { "left2", "right1" }) }, { "Arborium_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Arborium_03", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2" }) }, { "Arborium_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Arborium_05", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Arborium_06", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Arborium_09", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Arborium_Tube", new SceneConfig(new List<string> { "right1" }) }, { "Arborium_07", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Arborium_08", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Song_13", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Song_18", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Song_03", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Song_04", new SceneConfig(new List<string> { "bot1", "left1", "right1", "right2" }) }, { "Song_10", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Song_12", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3" }) }, { "Song_14", new SceneConfig(new List<string> { "left1" }) }, { "Song_26", new SceneConfig(new List<string> { "right1" }) }, { "Song_28", new SceneConfig(new List<string> { "right1" }) }, { "Song_08", new SceneConfig(new List<string> { "right1" }) }, { "Slab_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Slab_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Slab_03", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "left5", "left6", "left7", "left8", "right1", "right2", "right3", "right4", "right5", "right7", "right8", "right9" }) }, { "Slab_04", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Slab_23", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Slab_21", new SceneConfig(new List<string> { "left1", "left3", "top1" }) }, { "Slab_22", new SceneConfig(new List<string> { "bot1", "bot2" }) }, { "Slab_Cell_Creature", new SceneConfig(new List<string> { "left1" }) }, { "Slab_20", new SceneConfig(new List<string> { "left1" }) }, { "Slab_17", new SceneConfig(new List<string> { "left1" }) }, { "Slab_18", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Slab_16", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1" }) }, { "Slab_15", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1" }) }, { "Peak_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "left4", "right1", "right2", "right3", "right4", "top1", "top2", "top3", "top4" }) }, { "Slab_14", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Slab_13", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Slab_05", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Slab_06", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Peak_07", new SceneConfig(new List<string> { "bot1", "bot2", "bot3", "bot4", "bot5", "top1", "top2" }) }, { "Peak_08b", new SceneConfig(new List<string> { "bot4", "bot5", "bot6", "left1", "left2" }) }, { "Peak_08", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Peak_05d", new SceneConfig(new List<string> { "bot1" }) }, { "Peak_05", new SceneConfig(new List<string> { "bot1", "right3", "top2" }) }, { "Peak_05c", new SceneConfig(new List<string> { "left2", "right1" }) }, { "Peak_05e", new SceneConfig(new List<string> { "left1", "right1", "right2" }) }, { "Peak_06b", new SceneConfig(new List<string> { "left1" }) }, { "Peak_02", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3", "right4" }) }, { "Peak_04d", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Peak_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Bellway_Peak", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "top1" }) }, { "Bellway_Peak_02", new SceneConfig(new List<string> { "left1" }) }, { "Peak_04c", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Peak_10", new SceneConfig(new List<string> { "right1" }) }, { "Slab_08", new SceneConfig(new List<string> { "left1" }) }, { "Slab_Cell_Quiet", new SceneConfig(new List<string> { "left1", "left2" }) }, { "Slab_19b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Slab_07", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Slab_12", new SceneConfig(new List<string> { "left1" }) }, { "Slab_10c", new SceneConfig(new List<string> { "left1" }) }, { "Slab_10b", new SceneConfig(new List<string> { "left1" }) }, { "Cog_10_Destroyed", new SceneConfig(new List<string> { "bot1", "left1" }) }, { "Cog_09_Destroyed", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Song_Tower_Destroyed", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Arborium_10", new SceneConfig(new List<string> { "left1" }) }, { "Arborium_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Aqueduct_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Aqueduct_02", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3" }) }, { "Bellway_Aqueduct", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Aqueduct_07", new SceneConfig(new List<string> { "right1" }) }, { "Aqueduct_04", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Aqueduct_03", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Aqueduct_06", new SceneConfig(new List<string> { "bot1", "left1", "left2" }) }, { "Aqueduct_08", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Aqueduct_05", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_01", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1", "right2", "right3", "top1" }) }, { "Shadow_18", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_12", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_19", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Shadow_24", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_10", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Shadow_25", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_08", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Shadow_27", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_26", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2" }) }, { "Shadow_16", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_15", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Shadow_14", new SceneConfig(new List<string> { "right1", "right2" }) }, { "Shadow_02", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Shadow_11", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_13", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_23", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_03", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Shadow_21", new SceneConfig(new List<string> { "bot1" }) }, { "Shadow_09", new SceneConfig(new List<string> { "left1", "left2", "left3", "right1" }) }, { "Shadow_Weavehome", new SceneConfig(new List<string> { "left1" }) }, { "Shadow_05", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_04b", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Shadow_04", new SceneConfig(new List<string> { "left1", "right1", "right2", "top1" }) }, { "Shadow_20", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Bellway_Shadow", new SceneConfig(new List<string> { "left1" }) }, { "Tube_Hub", new SceneConfig(new List<string> { "left1", "left3", "left4" }) }, { "Cradle_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Cradle_02", new SceneConfig(new List<string> { "left2", "right1", "right2" }) }, { "Cradle_02b", new SceneConfig(new List<string> { "right1" }) }, { "Cradle_03", new SceneConfig(new List<string> { "left2", "right2" }) }, { "Crawl_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Crawl_02", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Crawl_06", new SceneConfig(new List<string> { "left1" }) }, { "Crawl_01", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Crawl_03", new SceneConfig(new List<string> { "bot1", "left1", "right1", "top1" }) }, { "Crawl_08", new SceneConfig(new List<string> { "bot1" }) }, { "Crawl_05", new SceneConfig(new List<string> { "right1" }) }, { "Crawl_03b", new SceneConfig(new List<string> { "bot1", "right1", "top1" }) }, { "Crawl_07", new SceneConfig(new List<string> { "bot1", "left1", "top1" }) }, { "Crawl_09", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Crawl_10", new SceneConfig(new List<string> { "right1" }) }, { "Abyss_12", new SceneConfig(new List<string> { "left1", "right2" }) }, { "Abyss_05", new SceneConfig(new List<string> { "left2", "right1" }) }, { "Abyss_08", new SceneConfig(new List<string> { "left1" }) }, { "Abyss_07", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Abyss_01", new SceneConfig(new List<string> { "left1", "right2", "right3", "right4" }) }, { "Abyss_06", new SceneConfig(new List<string> { "right1" }) }, { "Abyss_04", new SceneConfig(new List<string> { "left1" }) }, { "Abyss_02b", new SceneConfig(new List<string> { "left2", "right1", "top1" }) }, { "Abyss_02", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Abyss_03", new SceneConfig(new List<string> { "left1", "left2" }) }, { "Abyss_13", new SceneConfig(new List<string> { "left1", "right1", "top1" }) }, { "Abyss_11", new SceneConfig(new List<string> { "bot1", "right1" }) }, { "Abyss_09", new SceneConfig(new List<string> { "bot1", "top1" }) }, { "Greymoor_13", new SceneConfig(new List<string> { "bot1", "left1", "right1" }) }, { "Clover_01b", new SceneConfig(new List<string> { "right1" }) }, { "Clover_02c", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Clover_05c", new SceneConfig(new List<string> { "left1", "left2", "right1", "right2", "right3" }) }, { "Clover_21", new SceneConfig(new List<string> { "right1" }) }, { "Clover_16", new SceneConfig(new List<string> { "right1", "top1" }) }, { "Clover_06", new SceneConfig(new List<string> { "bot1", "bot2" }) }, { "Clover_19", new SceneConfig(new List<string> { "left1", "top1" }) }, { "Clover_04b", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Clover_11", new SceneConfig(new List<string> { "right1" }) }, { "Clover_03", new SceneConfig(new List<string> { "left1", "left2", "right1" }) }, { "Clover_18", new SceneConfig(new List<string> { "left1" }) }, { "Tut_04", new SceneConfig(new List<string> { "left1", "right1" }) }, { "Cog_09", new SceneConfig(new List<string> { "bot1" }) }, { "Cog_08", new SceneConfig(new List<string> { "bot1", "top1" }) } }; private string lastEntryGateUsed; private string previousSceneName; private string currentSceneName = "(unknown)"; private bool isTransitioning; private bool loadRequested; public static bool SuppressTransitionPatch; private bool autoDiscoveryMode; private HashSet<string> discoveredScenes = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private string discoveryFilePath; private readonly List<string> preferredSceneSubstrings = new List<string>(); private List<string> _cachedPreferredLowered; private WaitForSeconds waitHalfSecond; private WaitForSeconds waitThirdSecond; private WaitForSeconds waitTenthSecond; private WaitForSeconds waitFifthSecond; private GUIStyle sceneLabelStyle; private string cachedSceneLabel = ""; private string lastRenderedScene = ""; private ConfigEntry<bool> cfgShowSceneLabel; private ConfigEntry<string> cfgTeleportScene; private ConfigEntry<bool> cfgTeleportConfirm; private HashSet<string> visitedScenesF6 = new HashSet<string>(StringComparer.OrdinalIgnoreCase); public static bool EnableRandomization; private ConfigEntry<bool> cfgEnableRandomization; private ConfigEntry<bool> cfgInstantMusicTransition; private bool _apiInitialized; public static int CurrentSeed { get; internal set; } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_003a: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown log = ((BaseUnityPlugin)this).Logger; rng = new Random(); Scene activeScene = SceneManager.GetActiveScene(); currentSceneName = ((Scene)(ref activeScene)).name; waitHalfSecond = new WaitForSeconds(0.5f); waitThirdSecond = new WaitForSeconds(0.3f); waitTenthSecond = new WaitForSeconds(0.1f); waitFifthSecond = new WaitForSeconds(0.2f); sceneLabelStyle = new GUIStyle(); cfgShowSceneLabel = GlobalConfig.ShowSceneLabel; cfgTeleportScene = GlobalConfig.TeleportScene; cfgTeleportConfirm = GlobalConfig.TeleportConfirm; cfgEnableRandomization = GlobalConfig.EnableRandomization; EnableRandomization = cfgEnableRandomization.Value; cfgInstantMusicTransition = GlobalConfig.InstantMusicTransition; discoveryFilePath = Path.Combine(Paths.PluginPath, "discovered_exits.txt"); log.LogInfo((object)("RandomSceneLoader loaded. Current scene: " + currentSceneName + ". F5=random, F7=discover")); try { if (sceneConfigs != null) { discoveredScenes.UnionWith(sceneConfigs.Keys); log.LogInfo((object)$"Preloaded {discoveredScenes.Count} known scenes into discovered set"); } } catch { } try { string path = Path.Combine(Paths.PluginPath, "roomrando_connections.txt"); if (File.Exists(path)) { string[] array = File.ReadAllLines(path); foreach (string text in array) { if (text.StartsWith("#seed|", StringComparison.OrdinalIgnoreCase)) { string[] array2 = text.Split(new char[1] { '|' }); if (array2.Length >= 2 && int.TryParse(array2[1], out var result)) { CurrentSeed = result; log.LogInfo((object)$"Preloaded room random seed: {CurrentSeed}"); break; } } } } } catch (Exception ex) { log.LogWarning((object)("Failed to preload room random seed: " + ex.Message)); } if (autoDiscoveryMode) { log.LogInfo((object)("Auto-discovery mode enabled. RoomRando disabled. Results saved to: " + discoveryFilePath)); return; } try { new Harmony("HardItemRandomizer.HKSilksong_SceneRandomizer").PatchAll(); log.LogInfo((object)"Harmony patches applied successfully"); } catch (Exception ex2) { log.LogError((object)("Failed to apply Harmony patches: " + ex2.Message)); } try { if ((Object)(object)GameObject.Find("__RoomRando") == (Object)null) { GameObject val = new GameObject("__RoomRando"); val.AddComponent<RoomRando>().Initialize(this); Object.DontDestroyOnLoad((Object)val); } } catch (Exception ex3) { log.LogError((object)("Failed to create RoomRando: " + ex3.Message)); } try { if ((Object)(object)GameObject.Find("__SeedManager") == (Object)null) { GameObject val2 = new GameObject("__SeedManager"); val2.AddComponent<SeedManager>().Initialize(this); Object.DontDestroyOnLoad((Object)val2); } } catch (Exception ex4) { log.LogError((object)("Failed to create SeedManager: " + ex4.Message)); } GameObject obj2 = GameObject.Find("__RoomRando"); RoomRando rando = ((obj2 != null) ? obj2.GetComponent<RoomRando>() : null); HKSilksong_RandomizerAPI.Initialize(this, rando); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.activeSceneChanged += OnActiveSceneChanged; _apiInitialized = true; } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.activeSceneChanged -= OnActiveSceneChanged; } public string GetCurrentSceneName() { return currentSceneName; } public void SetShowSceneLabel(bool show) { if (cfgShowSceneLabel != null) { cfgShowSceneLabel.Value = show; } } public bool GetShowSceneLabel() { return cfgShowSceneLabel?.Value ?? true; } public void SetLastEntryGate(string gateName) { lastEntryGateUsed = gateName; } public void TeleportToScene(string sceneName) { try { if (isTransitioning) { log.LogInfo((object)"Teleport skipped: transition already in progress"); return; } if (string.IsNullOrWhiteSpace(sceneName)) { log.LogWarning((object)"TeleportToScene called with empty scene name"); return; } string text = null; string scenePart = sceneName.Trim(); int num = scenePart.LastIndexOf(' '); if (num > 0) { text = scenePart.Substring(num + 1).Trim(); scenePart = scenePart.Substring(0, num).Trim(); if (string.IsNullOrEmpty(text)) { text = null; } } string text2 = null; SceneConfig value = null; string text3 = null; if (sceneConfigs != null && sceneConfigs.TryGetValue(scenePart, out value)) { text3 = scenePart; } else if (sceneConfigs != null) { List<string> source = sceneConfigs.Keys.ToList(); string inputLetters = new string(scenePart.Where(char.IsLetter).ToArray()); string inputDigits = new string(scenePart.Where(char.IsDigit).ToArray()); text3 = source.FirstOrDefault((string s) => string.Equals(s, scenePart, StringComparison.OrdinalIgnoreCase)); if (text3 == null && !string.IsNullOrEmpty(inputLetters) && !string.IsNullOrEmpty(inputDigits)) { text3 = source.FirstOrDefault(delegate(string s) { string text4 = new string(s.Where(char.IsDigit).ToArray()); string text5 = new string(s.Where(char.IsLetter).ToArray()); return !string.IsNullOrEmpty(text4) && text5.IndexOf(inputLetters, StringComparison.OrdinalIgnoreCase) >= 0 && text4.IndexOf(inputDigits, StringComparison.OrdinalIgnoreCase) >= 0; }); } if (text3 == null && !string.IsNullOrEmpty(inputLetters) && string.IsNullOrEmpty(inputDigits)) { text3 = source.FirstOrDefault((string s) => string.IsNullOrEmpty(new string(s.Where(char.IsDigit).ToArray())) && s.IndexOf(inputLetters, StringComparison.OrdinalIgnoreCase) >= 0); } if (text3 == null) { text3 = source.FirstOrDefault((string s) => s.IndexOf(scenePart, StringComparison.OrdinalIgnoreCase) >= 0); } } if (text3 != null && sceneConfigs.TryGetValue(text3, out value)) { if (text != null) { if (value.Exits != null && value.Exits.Contains<string>(text, StringComparer.OrdinalIgnoreCase)) { text2 = text; } else { log.LogWarning((object)("TeleportToScene: entry '" + text + "' not valid for scene '" + text3 + "', will pick random.")); if (value.Exits != null && value.Exits.Count > 0) { text2 = value.Exits[rng.Next(value.Exits.Count)]; } } } else if (value.Exits != null && value.Exits.Count > 0) { text2 = value.Exits[rng.Next(value.Exits.Count)]; } log.LogInfo((object)("Teleport: " + scenePart + " -> " + text3 + " (entry '" + (text2 ?? "(null)") + "')")); } else { log.LogWarning((object)("TeleportToScene: scene '" + scenePart + "' not found in sceneConfigs. Attempting direct load.")); text3 = scenePart; if (text != null) { text2 = text; } } SuppressTransitionPatch = true; ((MonoBehaviour)this).StartCoroutine(LoadSceneCoroutine(text3, text2)); } catch (Exception arg) { log.LogError((object)$"TeleportToScene failed: {arg}"); } } private List<string> GetCachedPreferredLowered() { if (_cachedPreferredLowered == null) { _cachedPreferredLowered = (from s in preferredSceneSubstrings where !string.IsNullOrWhiteSpace(s) select s.ToLower()).ToList(); } return _cachedPreferredLowered; } private void LoadRandomUniqueScene() { if (isTransitioning) { log.LogInfo((object)"LoadRandomUniqueScene skipped: transition already in progress"); return; } List<string> list = sceneConfigs.Keys.Where((string k) => !string.Equals(k, currentSceneName, StringComparison.OrdinalIgnoreCase) && !visitedScenesF6.Contains(k)).ToList(); if (list.Count == 0) { log.LogInfo((object)"F6: All scenes have been visited already (or no candidates available). Clearing visited list."); visitedScenesF6.Clear(); list = sceneConfigs.Keys.Where((string k) => !string.Equals(k, currentSceneName, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count == 0) { return; } } List<string> list2 = null; try { List<string> lowered = GetCachedPreferredLowered(); list2 = list.Where((string c) => lowered.Any((string sub) => c.ToLower().Contains(sub))).ToList(); } catch { } List<string> list3 = ((list2 != null && list2.Count > 0) ? list2 : list); string text = list3[rng.Next(list3.Count)]; SceneConfig sceneConfig = (sceneConfigs.ContainsKey(text) ? sceneConfigs[text] : null); string text2 = null; if (sceneConfig != null && sceneConfig.Exits != null && sceneConfig.Exits.Count > 0) { text2 = sceneConfig.Exits[rng.Next(sceneConfig.Exits.Count)]; } visitedScenesF6.Add(text); lastEntryGateUsed = text2; log.LogInfo((object)("[F6] Selected unique random scene: " + text + " (enter via gate '" + (text2 ?? "(null)") + "')")); SuppressTransitionPatch = true; ((MonoBehaviour)this).StartCoroutine(LoadSceneCoroutine(text, text2)); } private void LoadRandomScene() { if (isTransitioning) { log.LogInfo((object)"LoadRandomScene skipped: transition already in progress"); return; } loadRequested = true; List<string> list = sceneConfigs.Keys.Where((string k) => !string.Equals(k, currentSceneName, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count == 0) { log.LogWarning((object)"No candidate scenes found in sceneConfigs."); return; } List<string> list2 = null; try { List<string> lowered = GetCachedPreferredLowered(); list2 = list.Where((string c) => lowered.Any((string sub) => c.ToLower().Contains(sub))).ToList(); } catch { } List<string> list3 = ((list2 != null && list2.Count > 0) ? list2 : list); string text = list3[rng.Next(list3.Count)]; SceneConfig sceneConfig = (sceneConfigs.ContainsKey(text) ? sceneConfigs[text] : null); string text2 = null; if (sceneConfig != null && sceneConfig.Exits != null && sceneConfig.Exits.Count > 0) { text2 = sceneConfig.Exits[rng.Next(sceneConfig.Exits.Count)]; } lastEntryGateUsed = text2; log.LogInfo((object)("Selected random scene: " + text + " (enter via gate '" + (text2 ?? "(null)") + "')")); SuppressTransitionPatch = true; ((MonoBehaviour)this).StartCoroutine(LoadSceneCoroutine(text, text2)); } private IEnumerator LoadSceneCoroutine(string sceneName, string entryGate) { if (!isTransitioning) { loadRequested = false; isTransitioning = true; lastEntryGateUsed = entryGate; float timeout = 8f; float startTime = Time.time; if (!string.IsNullOrEmpty(sceneName) && (Object)(object)GameManager.instance != (Object)null) { try { GameManager.instance.BeginSceneTransition(new SceneLoadInfo { SceneName = sceneName, EntryGateName = entryGate, PreventCameraFadeOut = false, WaitForSceneTransitionCameraFade = true, Visualization = (SceneLoadVisualizations)0 }); } catch (Exception ex) { log.LogWarning((object)("BeginSceneTransition failed: " + ex.Message)); isTransitioning = false; SuppressTransitionPatch = false; yield break; } while (true) { Scene activeScene = SceneManager.GetActiveScene(); if (!(((Scene)(ref activeScene)).name != sceneName)) { break; } if (Time.time - startTime > timeout) { log.LogWarning((object)("LoadSceneCoroutine timeout waiting for scene " + sceneName)); isTransitioning = false; SuppressTransitionPatch = false; yield break; } yield return waitTenthSecond; } yield return waitFifthSecond; isTransitioning = false; } else { try { SceneManager.LoadScene(sceneName); } catch (Exception ex2) { log.LogWarning((object)("SceneManager.LoadScene failed: " + ex2.Message)); } finally { isTransitioning = false; } } } SuppressTransitionPatch = false; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { currentSceneName = ((Scene)(ref scene)).name; cachedSceneLabel = Locale.Get("Scene: ") + currentSceneName; lastRenderedScene = currentSceneName; log.LogInfo((object)("Scene loaded: " + currentSceneName)); if (autoDiscoveryMode) { ((MonoBehaviour)this).StartCoroutine(AutoDiscoverAfterLoad()); } else { ((MonoBehaviour)this).StartCoroutine(DetectEntryGateAfterLoad()); } if (cfgInstantMusicTransition != null && cfgInstantMusicTransition.Value) { SetMusicRegionsInstantTransition(); } if (_apiInitialized && ((Scene)(ref scene)).name != "Menu_Title" && ((Scene)(ref scene)).name != "Menu" && ((Scene)(ref scene)).name != "Loading" && (Object)(object)HeroController.instance != (Object)null) { HKSilksong_RandomizerAPI.MarkGameReady(); } } private IEnumerator AutoDiscoverAfterLoad() { yield return waitHalfSecond; DiscoverGatesInCurrentScene(); } private void DiscoverGatesInCurrentScene() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) log.LogInfo((object)"=== DISCOVERING GATES ==="); log.LogInfo((object)("Scene: " + currentSceneName)); try { List<GameObject> list = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0).Where(delegate(GameObject obj) { string text2 = ((Object)obj).name.ToLower(); return (text2.StartsWith("left") || text2.StartsWith("right") || text2.StartsWith("top") || text2.StartsWith("bot")) && text2.Length <= 6 && char.IsDigit(text2[text2.Length - 1]); }).ToList(); log.LogInfo((object)$"Found {list.Count} gates:"); IOrderedEnumerable<IGrouping<string, GameObject>> orderedEnumerable = from g in list group g by ((Object)g).name into g orderby g.Key select g; foreach (IGrouping<string, GameObject> item in orderedEnumerable) { log.LogInfo((object)$" - {item.Key} (count: {item.Count()}, pos: {item.First().transform.position})"); } List<string> list2 = orderedEnumerable.Select((IGrouping<string, GameObject> g) => g.Key).ToList(); if (list2.Count > 0) { string text = "{ \"" + currentSceneName + "\", new SceneConfig(new List<string> { " + string.Join(", ", list2.Select((string e) => "\"" + e + "\"")) + " }) },"; log.LogInfo((object)("Suggested: " + text)); if (autoDiscoveryMode) { SaveDiscoveryToFile(currentSceneName, list2, text); } } } catch (Exception ex) { log.LogError((object)("DiscoverGates failed: " + ex.Message)); } } private void SaveDiscoveryToFile(string sceneName, List<string> exitNames, string configLine) { try { if (!discoveredScenes.Contains(sceneName)) { if (sceneConfigs != null && sceneConfigs.ContainsKey(sceneName)) { log.LogInfo((object)("Discovery skipped for " + sceneName + ": already exists in sceneConfigs.")); discoveredScenes.Add(sceneName); return; } discoveredScenes.Add(sceneName); File.AppendAllText(discoveryFilePath, string.Format("\n[{0:yyyy-MM-dd HH:mm:ss}] {1}\n Gates found: {2}\n Config: {3}\n", DateTime.Now, sceneName, string.Join(", ", exitNames), configLine)); log.LogInfo((object)$"Saved discovery for {sceneName} to file ({exitNames.Count} exits)"); } } catch (Exception ex) { log.LogError((object)("Failed to save discovery to file: " + ex.Message)); } } private IEnumerator DetectEntryGateAfterLoad() { yield return waitThirdSecond; try { HeroController instance = HeroController.instance; if (!((Object)(object)instance != (Object)null)) { yield break; } Vector3 position = ((Component)instance).transform.position; GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0); foreach (GameObject val in array) { string text = ((Object)val).name.ToLower(); if ((text.StartsWith("left") || text.StartsWith("right") || text.StartsWith("top") || text.StartsWith("bot")) && text.Length <= 6 && char.IsDigit(text[text.Length - 1]) && (double)Vector3.Distance(position, val.transform.position) < 10.0) { if (string.IsNullOrEmpty(lastEntryGateUsed)) { lastEntryGateUsed = ((Object)val).name; log.LogInfo((object)("Auto-detected entry gate: " + ((Object)val).name)); } break; } } } catch (Exception ex) { log.LogWarning((object)("DetectEntryGate failed: " + ex.Message)); } } private void OnActiveSceneChanged(Scene prev, Scene next) { if (((Scene)(ref next)).name == "Menu_Title" || ((Scene)(ref next)).name == "Quit_To_Menu") { lastEntryGateUsed = null; return; } previousSceneName = currentSceneName; currentSceneName = ((Scene)(ref next)).name; try { GameObject obj = GameObject.Find("__RoomRando"); RoomRando roomRando = ((obj != null) ? obj.GetComponent<RoomRando>() : null); if ((Object)(object)roomRando != (Object)null && !string.IsNullOrEmpty(previousSceneName) && !string.IsNullOrEmpty(lastEntryGateUsed)) { roomRando.OnExitUsed(previousSceneName, lastEntryGateUsed); } } catch (Exception ex) { log.LogWarning((object)("RoomRando notify failed: " + ex.Message)); } lastEntryGateUsed = null; } private void OnGUI() { //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) try { if (sceneLabelStyle.normal.textColor != Color.white || sceneLabelStyle.fontSize != 14) { GUIStyle val = new GUIStyle(GUI.skin.label); val.normal.textColor = Color.white; val.fontSize = 14; sceneLabelStyle = val; } if (cfgShowSceneLabel == null || cfgShowSceneLabel.Value) { if (currentSceneName != lastRenderedScene) { cachedSceneLabel = Locale.Get("Scene: ") + currentSceneName; lastRenderedScene = currentSceneName; } GUI.Label(new Rect(8f, 8f, 300f, 20f), cachedSceneLabel, sceneLabelStyle); } } catch { } } private void SetMusicRegionsInstantTransition() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) try { Type type = Type.GetType("MusicRegion, Assembly-CSharp"); if (type == null) { return; } Object[] array = Resources.FindObjectsOfTypeAll(type); FieldInfo field = type.GetField("enterTransitionTime"); FieldInfo field2 = type.GetField("exitTransitionTime"); FieldInfo field3 = type.GetField("delay"); if (field == null || field2 == null) { return; } int num = 0; Object[] array2 = array; foreach (Object val in array2) { if (val == (Object)null) { continue; } Object obj = ((val is Component) ? val : null); GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)val2 != (Object)null && val2.scene == SceneManager.GetActiveScene()) { field.SetValue(val, 0f); field2.SetValue(val, 0f); if (field3 != null) { field3.SetValue(val, 0); } num++; } } if (num > 0) { log.LogInfo((object)$"Set {num} MusicRegion transition times to 0."); } } catch (Exception ex) { log.LogWarning((object)("SetMusicRegionsInstantTransition error: " + ex.Message)); } } } public class RoomRando : MonoBehaviour { private Dictionary<string, (string targetScene, string targetGate)> connections = new Dictionary<string, (string, string)>(StringComparer.OrdinalIgnoreCase); private List<string> availableScenes = new List<string>(); private bool enableRandomization = true; private RandomSceneLoader sceneLoader; private string saveFilePath; private Random rng; private int generationSeed; private bool enableMapGeneration; private List<(string beforeScene, string afterScene)> precedencePairs = new List<(string, string)>(); private bool forceExactSeed; private static readonly HashSet<string> BlacklistedExits = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Bone_11_top1", "Bellshrine_right1", "Bellshrine_05_right1", "Dock_06_Church_right1", "Bone_East_09_top1", "Bellshrine_02_left1", "Dust_04_right1", "Dust_05_right1", "Dust_06_left1", "Shadow_20_bot1", "Bellshrine_03_right1", "Shellwood_19_left1", "Shellwood_01b_right2", "Bellshrine_02_right1", "Dust_06_right1", "Mosstown_03_top1", "Coral_10_left1", "Song_27_left1", "Dock_01_right1", "Dock_01_right2", "Bone_East_14_right1", "Bone_East_14_right2", "Greymoor_01_right1", "Greymoor_01_right2", "Dust_02_right1", "Dust_02_right2", "Dust_04_left1", "Dust_04_left2", "Song_25_top1", "Song_25_top2", "Arborium_05_top1", "Hang_07_top1", "Hang_07_left1", "Slab_02_left1", "Slab_05_right1", "Cog_06_right1", "Library_11b_right1", "Dock_03_bot1", "Dock_03c_top1", "Dock_03c_left2", "Dock_02_left1", "Shellwood_02_right2", "Shellwood_01_left2", "Dust_Chef_left1", "Song_11_left4", "Slab_03_right1", "Slab_03_right2", "Slab_03_right5", "Slab_03_right7", "Slab_03_left6", "Under_05_left2", "Under_02_right4", "Under_02_left1", "Bone_East_12_right1", "Shadow_27_right1", "Halfway_01_right1", "Wisp_03_top1", "Arborium_01_right1", "Arborium_04_left1", "Library_13_left1", "Hang_03_right2", "Aqueduct_02_right3", "Song_19_entrance_left1", "Weave_04_right2", "Slab_16_right1", "Bone_East_04_left1", "Bone_East_10_right1", "Bone_East_18c_left1", "Greymoor_05_left1", "Hang_08_left1", "Arborium_08_left1" }; private static readonly Dictionary<string, int> SingleExitPairedCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> HighPriorityRooms = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Bonegrave", "Shellwood_04c", "Coral_02", "Coral_35", "Coral_32", "Coral_24", "Coral_23", "Coral_25", "Dust_03", "Dust_06", "Shadow_05", "Shadow_08", "Shadow_09", "Shadow_16", "Shadow_10", "Shadow_19", "Shadow_24", "Shadow_01", "Shadow_14", "Aqueduct_04", "Aqueduct_03", "Aqueduct_01", "Arborium_11", "Arborium_09", "Arborium_05", "Song_Enclave", "Song_09b", "Song_11", "Song_01", "Song_19_entrance", "Under_02", "Under_07c", "Under_27", "Under_17", "Under_10", "Under_19c", "Library_11", "Library_12", "Library_12b", "Library_02", "Song_20b", "Song_20", "Library_03", "Slab_06", "Slab_05", "Slab_19b", "Slab_15", "Coral_27", "Coral_44", "Abyss_13", "Abyss_01", "Cog_08", "Cog_09", "Ward_02", "Wisp_05", "Wisp_08", "Slab_07", "Weave_08", "Song_03", "Abyss_05", "Cradle_02", "Hang_02", "Hang_03", "Hang_13", "Hang_10", "Hang_16", "Bone_East_15", "Cog_04", "Arborium_08", "Under_23", "Bellway_03", "Dock_15", "Dust_04" }; private static readonly HashSet<string> SkipExits = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Bone_01_bot1", "Bone_01_left4", "Bone_01_right3", "Aspid_01_bot8", "Aspid_01_left2", "Aspid_01_right4", "Crawl_03b_right1", "Shellwood_10_left3", "Shellwood_10_right3", "Dust_02_left2", "Dust_02_right2", "Coral_24_left1", "Coral_24_right1", "Coral_35b_bot1", "Coral_35b_left5", "Coral_35b_right2", "Peak_07_bot5", "Peak_07_top2", "Peak_01_left4", "Peak_01_right4", "Peak_01_top4", "Peak_02_left3", "Peak_02_right4", "Peak_04_left1", "Peak_04_right1", "Peak_05_bot1", "Peak_05_right3", "Peak_05_top2", "Peak_05c_left2", "Peak_05c_right1", "Peak_05e_left1", "Peak_05e_right2", "Song_05_left5", "Song_05_right4", "Song_11_right3", "Song_01c" }; private RoomRandomConfig _cachedConfig; private bool _hasPendingConfig; private bool _isInitialized; private Dictionary<string, HashSet<string>> _blacklistedExitsByScene; private Dictionary<string, int> _cachedActualExitCounts; public void Initialize(RandomSceneLoader loader) { sceneLoader = loader; if ((Object)(object)sceneLoader != (Object)null) { foreach (string key in sceneLoader.sceneConfigs.Keys) { if (key.StartsWith("Peak_", StringComparison.OrdinalIgnoreCase)) { HighPriorityRooms.Add(key); } if (key.StartsWith("Ward_", StringComparison.OrdinalIgnoreCase)) { HighPriorityRooms.Add(key); } if (key.StartsWith("Clover_", StringComparison.OrdinalIgnoreCase)) { HighPriorityRooms.Add(key); } } } _isInitialized = true; if (_hasPendingConfig && _cachedConfig != null) { ApplyConfig(); } else { InitializeRoomRando(); } } public void SetConfig(RoomRandomConfig config) { _cachedConfig = config; _hasPendingConfig = true; if (_isInitialized) { ApplyConfig(); } } private void ApplyConfig() { if (_cachedConfig != null) { generationSeed = _cachedConfig.Seed; enableRandomization = _cachedConfig.EnableRandomization; enableMapGeneration = _cachedConfig.EnableMapGeneration; precedencePairs = new List<(string, string)>(_cachedConfig.PrecedencePairs); _hasPendingConfig = false; if (enableRandomization) { InitializeRoomRando(); } } } private void InitializeRoomRando() { try { availableScenes = sceneLoader.sceneConfigs.Keys.ToList(); BuildCaches(); } catch (Exception ex) { Debug.LogWarning((object)("RoomRando: failed to populate availableScenes from sceneLoader: " + ex.Message)); } try { saveFilePath = Path.Combine(Paths.PluginPath, "roomrando_connections.txt"); } catch { saveFilePath = "roomrando_connections.txt"; } Debug.Log((object)$"RoomRando: saveFilePath set to '{saveFilePath}' (exists={File.Exists(saveFilePath)})"); if (!enableRandomization) { return; } if (TryLoadConnectionsFromFile()) { bool flag = false; foreach (KeyValuePair<string, (string, string)> connection in connections) { int num = connection.Key.LastIndexOf('_'); if (num > 0) { string sceneA = connection.Key.Substring(0, num); string exitA = connection.Key.Substring(num + 1); string item = connection.Value.Item1; string item2 = connection.Value.Item2; if (!IsConnectionAllowed(sceneA, exitA, item, item2)) { flag = true; break; } } } if (flag) { Debug.LogWarning((object)"RoomRando: Loaded connections conflict with current rules. Forcing regeneration..."); connections.Clear(); GenerateAllConnectionsAtStart(); SaveConnectionsToFile(); } else { Debug.Log((object)("RoomRando: loaded randomized connections from " + saveFilePath)); } } else { GenerateAllConnectionsAtStart(); SaveConnectionsToFile(); } if (enableMapGeneration) { TryGenerateMap(); } } private void GenerateAllConnectionsAtStart() { int num = ((generationSeed == 0) ? Environment.TickCount : generationSeed); int finalConnectionCount = 0; RandomSceneLoader.SceneConfig value3; List<string> list = availableScenes.Where((string s) => (Object)(object)sceneLoader != (Object)null && sceneLoader.sceneConfigs.TryGetValue(s, out value3) && value3.Exits != null && value3.Exits.Count > 0).ToList(); List<string> list2 = new List<string>(); List<string> list3 = new List<string>(); List<string> list4 = new List<string>(); foreach (string item4 in list) { if (GetActualExitCount(item4) == 1) { list4.Add(item4); } else if (HighPriorityRooms.Contains(item4)) { list3.Add(item4); } else { list2.Add(item4); } } Debug.Log((object)$"RoomRando: 普通房间(>1出口)数量: {list2.Count}, 高房间(>1出口)数量: {list3.Count}, 单出口房间数量: {list4.Count}"); bool flag = false; int num2 = (forceExactSeed ? 1 : 8); for (int num3 = 0; num3 < num2; num3++) { if (flag) { break; } int num4 = (forceExactSeed ? num : (num + num3)); rng = new Random(num4); connections.Clear(); finalConnectionCount = 0; Debug.Log((object)$"RoomRando: generation attempt {num3 + 1}/{num2} using seed={num4}"); Dictionary<string, List<string>> dictionary = BuildFreeExits(list2); SingleExitPairedCounts.Clear(); foreach (KeyValuePair<string, (string, string)> item5 in connections.ToList()) { int num5 = item5.Key.LastIndexOf('_'); if (num5 > 0) { string key = item5.Key.Substring(0, num5); string item = item5.Key.Substring(num5 + 1); if (dictionary.ContainsKey(key)) { dictionary[key].Remove(item); } } } try { foreach (var (text, text2) in precedencePairs) { if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2) && dictionary.ContainsKey(text) && dictionary.ContainsKey(text2) && dictionary[text].Count > 0 && dictionary[text2].Count > 0) { ConnectScenesWithFreeExits(text, text2, dictionary); } } } catch (Exception ex) { Debug.LogWarning((object)("precedencePairs error: " + ex.Message)); } List<string> list5 = new List<string>(list2); Shuffle(list5); for (int num6 = 1; num6 < list5.Count; num6++) { string text3 = null; string text4 = null; for (int num7 = num6 - 1; num7 >= 0; num7--) { if (dictionary[list5[num7]].Count > 0) { text3 = list5[num7]; break; } } for (int num8 = num6; num8 < list5.Count; num8++) { if (dictionary[list5[num8]].Count > 0) { text4 = list5[num8]; break; } } if (text3 != null && text4 != null && !string.Equals(text3, text4, StringComparison.OrdinalIgnoreCase)) { ConnectScenesWithFreeExits(text3, text4, dictionary); } } Dictionary<string, HashSet<string>> neighbors = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair<string, (string, string)> connection in connections) { int num9 = connection.Key.LastIndexOf('_'); if (num9 > 0) { AddNeighborEdge(neighbors, connection.Key.Substring(0, num9), connection.Value.Item1); } } List<(string, string)> collection = dictionary.SelectMany((KeyValuePair<string, List<string>> kv) => kv.Value.Select((string e) => (Key: kv.Key, e: e))).ToList(); bool flag2 = false; int num10 = 6; for (int num11 = 0; num11 < num10; num11++) { if (flag2) { break; } List<(string, string)> list6 = new List<(string, string)>(collection); Shuffle(list6); HashSet<int> hashSet = new HashSet<int>(); List<((string, string), (string, string))> list7 = new List<((string, string), (string, string))>(); bool flag3 = false; for (int num12 = 0; num12 < list6.Count; num12++) { if (hashSet.Contains(num12)) { continue; } (string, string) tuple2 = list6[num12]; int num13 = -1; int num14 = int.MinValue; for (int num15 = num12 + 1; num15 < list6.Count; num15++) { if (hashSet.Contains(num15)) { continue; } (string, string) tuple3 = list6[num15]; if (!string.Equals(tuple2.Item1, tuple3.Item1, StringComparison.OrdinalIgnoreCase)) { int num16 = 0; if (!IsOriginalSingle(tuple3.Item1)) { num16 += 20; } if (!IsOriginalSingle(tuple2.Item1)) { num16 += 10; } if (IsOriginalSingle(tuple2.Item1) && IsOriginalSingle(tuple3.Item1)) { num16 -= 1000; } neighbors.TryGetValue(tuple2.Item1, out var value); neighbors.TryGetValue(tuple3.Item1, out var value2); int num17 = value?.Count((string n) => IsLeaf(neighbors, n)) ?? 0; int num18 = value2?.Count((string n) => IsLeaf(neighbors, n)) ?? 0; bool flag4 = IsLeaf(neighbors, tuple3.Item1); bool flag5 = IsLeaf(neighbors, tuple2.Item1); if (num17 + (flag4 ? 1 : 0) > 1) { num16 -= 50; } if (num18 + (flag5 ? 1 : 0) > 1) { num16 -= 50; } if (num16 > num14) { num14 = num16; num13 = num15; } } } if (num13 < 0) { flag3 = true; break; } hashSet.Add(num12); hashSet.Add(num13); list7.Add((list6[num12], list6[num13])); AddNeighborEdge(neighbors, list6[num12].Item1, list6[num13].Item1); } if (flag3) { neighbors.Clear(); foreach (KeyValuePair<string, (string, string)> connection2 in connections) { int num19 = connection2.Key.LastIndexOf('_'); if (num19 > 0) { AddNeighborEdge(neighbors, connection2.Key.Substring(0, num19), connection2.Value.Item1); } } continue; } bool flag6 = false; foreach (var (tuple5, tuple6) in list7) { if (IsOriginalSingle(tuple5.Item1) && IsOriginalSingle(tuple6.Item1)) { flag6 = true; break; } } Dictionary<string, int> dictionary2 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair<string, HashSet<string>> item6 in neighbors) { dictionary2[item6.Key] = item6.Value.Count((string n) => IsLeaf(neighbors, n)); } if (dictionary2.Values.Any((int c) => c > 1)) { flag6 = true; } if (flag6) { neighbors.Clear(); foreach (KeyValuePair<string, (string, string)> connection3 in connections) { int num20 = connection3.Key.LastIndexOf('_'); if (num20 > 0) { AddNeighborEdge(neighbors, connection3.Key.Substring(0, num20), connection3.Value.Item1); } } continue; } foreach (var item7 in list7) { (string, string) item2 = item7.Item1; (string, string) item3 = item7.Item2; string key2 = MakeKey(item2.Item1, item2.Item2); string key3 = MakeKey(item3.Item1, item3.Item2); if (!connections.ContainsKey(key2) && !connections.ContainsKey(key3)) { connections[key2] = (item3.Item1, item3.Item2); connections[key3] = (item2.Item1, item2.Item2); dictionary[item2.Item1].Remove(item2.Item2); dictionary[item3.Item1].Remove(item3.Item2); finalConnectionCount++; } } flag2 = true; } if (!flag2) { Debug.LogWarning((object)"第一阶段智能配对失败,使用贪心配对"); List<(string, string)> list8 = new List<(string, string)>(collection); Shuffle(list8); for (int num21 = 0; num21 + 1 < list8.Count; num21 += 2) { (string, string) tuple7 = list8[num21]; (string, string) tuple8 = list8[num21 + 1]; if (!string.Equals(tuple7.Item1, tuple8.Item1, StringComparison.OrdinalIgnoreCase)) { string key4 = MakeKey(tuple7.Item1, tuple7.Item2); string key5 = MakeKey(tuple8.Item1, tuple8.Item2); if (!connections.ContainsKey(key4) && !connections.ContainsKey(key5)) { connections[key4] = (tuple8.Item1, tuple8.Item2); connections[key5] = (tuple7.Item1, tuple7.Item2); finalConnectionCount++; dictionary[tuple7.Item1].Remove(tuple7.Item2); dictionary[tuple8.Item1].Remove(tuple8.Item2); } } } } List<(string, string)> list9 = dictionary.SelectMany((KeyValuePair<string, List<string>> kv) => kv.Value.Select((string e) => (Key: kv.Key, e: e))).ToList(); if (list9.Count > 0) { Debug.LogWarning((object)$"第一阶段剩余 {list9.Count} 个未配对出口"); } Dictionary<string, List<string>> dictionary3 = BuildFreeExits(list3); List<(string, string)> list10 = new List<(string, string)>(); list10.AddRange(list9); foreach (KeyValuePair<string, List<string>> item8 in dictionary3) { foreach (string item9 in item8.Value) { list10.Add((item8.Key, item9)); } } if (list10.Count > 0) { Debug.Log((object)$"第二阶段开始,共 {list10.Count} 个出口"); PairExitsSimple(list10); } neighbors.Clear(); foreach (KeyValuePair<string, (string, string)> connection4 in connections) { int num22 = connection4.Key.LastIndexOf('_'); if (num22 > 0) { AddNeighborEdge(neighbors, connection4.Key.Substring(0, num22), connection4.Value.Item1); } } bool flag7 = false; foreach (KeyValuePair<string, HashSet<string>> item10 in neighbors) { if (item10.Value.Count((string n) => IsLeaf(neighbors, n)) > 3) { flag7 = true; break; } } if (!flag7) { flag = true; generationSeed = num4; RandomSceneLoader.CurrentSeed = generationSeed; Debug.Log((object)$"成功,种子={num4}"); } else { Debug.LogWarning((object)$"尝试 {num3 + 1} 失败:叶子节点过多"); } } if (!flag) { Debug.LogWarning((object)$"所有尝试失败,使用最后一次结果,种子={generationSeed}"); } Debug.Log((object)$"生成了 {finalConnectionCount} 对双向连接 ({connections.Count} 条单向)"); static void AddNeighborEdge(Dictionary<string, HashSet<string>> graph, string s1, string s2) { if (!string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)) { if (!graph.ContainsKey(s1)) { graph[s1] = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } if (!graph.ContainsKey(s2)) { graph[s2] = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } graph[s1].Add(s2); graph[s2].Add(s1); } } void ConnectScenesWithFreeExits(string scA, string scB, Dictionary<string, List<string>> freeExits) { if (freeExits.ContainsKey(scA) && freeExits.ContainsKey(scB) && freeExits[scA].Count != 0 && freeExits[scB].Count != 0) { string text5 = freeExits[scA][rng.Next(freeExits[scA].Count)]; string text6 = freeExits[scB][rng.Next(freeExits[scB].Count)]; if (IsConnectionAllowed(scA, text5, scB, text6)) { string key6 = MakeKey(scA, text5); string key7 = MakeKey(scB, text6); if (!connections.ContainsKey(key6) && !connections.ContainsKey(key7)) { connections[key6] = (scB, text6); connections[key7] = (scA, text5); freeExits[scA].Remove(text5); freeExits[scB].Remove(text6); finalConnectionCount++; UpdateSingleExitCount(scA, scB); } } } } static bool IsLeaf(Dictionary<string, HashSet<string>> graph, string scene) { if (graph.TryGetValue(scene, out value3)) { return value3.Count == 1; } return false; } bool IsOriginalSingle(string scene) { if (sceneLoader.sceneConfigs.TryGetValue(scene, out value3) && value3.Exits != null) { return value3.Exits.Count == 1; } return false; } } private Dictionary<string, List<string>> BuildFreeExits(List<string> scenes) { Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); foreach (string scene in scenes) { List<string> list = new List<string>(sceneLoader.sceneConfigs[scene].Exits); if (_blacklistedExitsByScene != null && _blacklistedExitsByScene.TryGetValue(scene, out var value)) { foreach (string item in value) { list.Remove(item); } } dictionary[scene] = list; } return dictionary; } private void PairExitsSimple(List<(string scene, string exit)> exitPool) { List<(string, string)> list = new List<(string, string)>(exitPool); Shuffle(list); HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < list.Count; i++) { if (hashSet.Contains(i)) { continue; } (string, string) tuple = list[i]; int num = -1; for (int j = i + 1; j < list.Count; j++) { if (!hashSet.Contains(j)) { (string, string) tuple2 = list[j]; if (!string.Equals(tuple.Item1, tuple2.Item1, StringComparison.OrdinalIgnoreCase) && (!(tuple.Item1 == "Tut_01") || !HighPriorityRooms.Contains(tuple2.Item1)) && (!(tuple2.Item1 == "Tut_01") || !HighPriorityRooms.Contains(tuple.Item1))) { num = j; break; } } } if (num >= 0) { hashSet.Add(i); hashSet.Add(num); (string, string) tuple3 = list[num]; string key = MakeKey(tuple.Item1, tuple.Item2); string key2 = MakeKey(tuple3.Item1, tuple3.Item2); if (!connections.ContainsKey(key) && !connections.ContainsKey(key2)) { connections[key] = (tuple3.Item1, tuple3.Item2); connections[key2] = (tuple.Item1, tuple.Item2); } } } if (list.Count - hashSet.Count > 0) { Debug.LogWarning((object)$"第二阶段配对后剩余 {list.Count - hashSet.Count} 个未配对出口"); } } private int GetActualExitCount(string scene) { if (_cachedActualExitCounts == null || !_cachedActualExitCounts.TryGetValue(scene, out var value)) { return 0; } return value; } private bool IsConnectionAllowed(string sceneA, string exitA, string sceneB, string exitB) { if (string.Equals(sceneA, sceneB, StringComparison.OrdinalIgnoreCase)) { return false; } if ((sceneA == "Tut_01" && HighPriorityRooms.Contains(sceneB)) || (sceneB == "Tut_01" && HighPriorityRooms.Contains(sceneA))) { return false; } string text = MakeKey(sceneA, exitA); string text2 = MakeKey(sceneB, exitB); if (BlacklistedExits.Contains(text) || BlacklistedExits.Contains(text2)) { return false; } int value; int num = ((_cachedActualExitCounts != null && _cachedActualExitCounts.TryGetValue(sceneA, out value)) ? value : 0); int value2; int num2 = ((_cachedActualExitCounts != null && _cachedActualExitCounts.TryGetValue(sceneB, out value2)) ? value2 : 0); if (num == 1 && num2 < 3) { return false; } if (num2 == 1 && num < 3) { return false; } if (num == 1 && num2 >= 3 && (SingleExitPairedCounts.TryGetValue(sceneB, out var value3) ? value3 : 0) >= num2 - 2) { return false; } if (num2 == 1 && num >= 3 && (SingleExitPairedCounts.TryGetValue(sceneA, out var value4) ? value4 : 0) >= num - 2) { return false; } if (text == "Tut_01_left3" || text2 == "Tut_01_left3") { _ = text == "Tut_01_left3"; _ = text == "Tut_01_left3"; string item = ((text == "Tut_01_left3") ? text2 : text); if (((text == "Tut_01_left3") ? num2 : num) == 1) { return false; } if (new HashSet<string>(StringComparer.OrdinalIgnoreCase).Contains(item)) { return false; } } return true; } private void UpdateSingleExitCount(string sceneA, string sceneB) { int value; int num = ((_cachedActualExitCounts != null && _cachedActualExitCounts.TryGetValue(sceneA, out value)) ? value : 0); int value2; int num2 = ((_cachedActualExitCounts != null && _cachedActualExitCounts.TryGetValue(sceneB, out value2)) ? value2 : 0); if (num == 1 && num2 >= 3) { if (!SingleExitPairedCounts.ContainsKey(sceneB)) { SingleExitPairedCounts[sceneB] = 1; } else { SingleExitPairedCounts[sceneB]++; } } if (num2 == 1 && num >= 3) { if (!SingleExitPairedCounts.ContainsKey(sceneA)) { SingleExitPairedCounts[sceneA] = 1; } else { SingleExitPairedCounts[sceneA]++; } } } private bool TryLoadConnectionsFromFile() { try { if (string.IsNullOrWhiteSpace(saveFilePath)) { Debug.LogWarning((object)"RoomRando: saveFilePath is empty or null"); return false; } if (!File.Exists(saveFilePath)) { Debug.Log((object)("RoomRando: connections file not found at " + saveFilePath)); return false; } string[] array = File.ReadAllLines(saveFilePath); Debug.Log((object)$"RoomRando: read {array.Length} lines from {saveFilePath}"); int num = 0; for (int i = 0; i < array.Length; i++) { string text = array[i]?.Trim(); if (string.IsNullOrWhiteSpace(text)) { num = i + 1; continue; } if (text.StartsWith("#seed|", StringComparison.OrdinalIgnoreCase)) { string[] array2 = text.Split(new char[1] { '|' }); if (array2.Length >= 2 && int.TryParse(array2[1], out var result)) { generationSeed = result; RandomSceneLoader.CurrentSeed = generationSeed; rng = new Random(generationSeed); Debug.Log((object)$"RoomRando: loaded generation seed {generationSeed} from {saveFilePath}"); } num = i + 1; } else { num = i; } break; } int num2 = 0; int num3 = 0; for (int j = num; j < array.Length; j++) { string text2 = array[j]; if (string.IsNullOrWhiteSpace(text2) || text2.StartsWith("#")) { continue; } string[] array3 = text2.Split(new char[1] { '|' }); if (array3.Length != 4) { num3++; continue; } string text3 = array3[0] + "_" + array3[1]; string item = array3[2] + "_" + array3[3]; if (BlacklistedExits.Contains(text3) || BlacklistedExits.Contains(item)) { num3++; continue; } connections[text3] = (array3[2], array3[3]); num2++; } Debug.Log((object)$"RoomRando: parsed {num2} connection lines, skipped {num3} invalid lines, total connections now {connections.Count}"); if (num2 != 0 || generationSeed == 0) { return connections.Count > 0; } Debug.Log((object)$"RoomRando: file contained seed {generationSeed} but no explicit connections; will regenerate deterministically using that seed"); return false; } catch (Exception ex) { Debug.LogWarning((object)("RoomRando: failed to load connections file: " + ex.Message)); return false; } } private void SaveConnectionsToFile() { try { using (StreamWriter streamWriter = new StreamWriter(saveFilePath, append: false)) { if (generationSeed == 0) { generationSeed = Environment.TickCount; } streamWriter.WriteLine($"#seed|{generationSeed}"); foreach (KeyValuePair<string, (string, string)> connection in connections) { string key = connection.Key; int num = key.LastIndexOf('_'); if (num > 0) { string text = key.Substring(0, num); string text2 = key.Substring(num + 1); streamWriter.WriteLine(text + "|" + text2 + "|" + connection.Value.Item1 + "|" + connection.Value.Item2); } } } Debug.Log((object)$"RoomRando: saved {connections.Count} connections to {saveFilePath}"); } catch (Exception ex) { Debug.LogWarning((object)("RoomRando: failed to save connections: " + ex.Message)); } } private void TryGenerateMap() { if (!enableMapGeneration) { Debug.Log((object)"RoomRando: map generation is disabled"); return; } try { string text = Path.Combine(Paths.PluginPath, "RoomRandoMap.png"); if (RoomMapGenerator.GenerateFromFile(saveFilePath, text)) { Debug.Log((object)("RoomRando: generated map image at " + text)); } else { Debug.LogWarning((object)"RoomRando: map generation reported failure or no data."); } } catch (Exception ex) { Debug.LogWarning((object)("RoomRando: map generation failed: " + ex.Message)); } } private string MakeKey(string scene, string exit) { return scene + "_" + exit; } private void BuildCaches() { _blacklistedExitsByScene = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase); _cachedActualExitCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); if ((Object)(object)sceneLoader == (Object)null) { return; } foreach (KeyValuePair<string, RandomSceneLoader.SceneConfig> sceneConfig in sceneLoader.sceneConfigs) { string key = sceneConfig.Key; RandomSceneLoader.SceneConfig value = sceneConfig.Value; HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); int num = 0; foreach (string exit in value.Exits) { string item = MakeKey(key, exit); if (BlacklistedExits.Contains(item)) { hashSet.Add(exit); num++; } } _blacklistedExitsByScene[key] = hashSet; _cachedActualExitCounts[key] = value.Exits.Count - num; } } private void Shuffle<T>(IList<T> list) { for (int num = list.Count - 1; num > 0; num--) { int index = rng.Next(num + 1); T value = list[num]; list[num] = list[index]; list[index] = value; } } public (string targetScene, string targetGate)? GetConnection(string currentScene, string exitName) { if (string.IsNullOrEmpty(exitName)) { return null; } if (!connections.TryGetValue(MakeKey(currentScene, exitName), out (string, string) value)) { return null; } return value; } public List<string> GetValidExitsForScene(string sceneName) { if (!((Object)(object)sceneLoader != (Object)null) || !sceneLoader.sceneConfigs.TryGetValue(sceneName, out va
BepInEx/plugins/MenuChanger.dll
Decompiled 2 weeks agousing System; using System.Collections; 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.Text; using BepInEx; using GlobalEnums; using HKSilksong_Randomizer; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using NativeUIMaker; using PharloomCore; using PharloomCore.Data; using PharloomCore.Logic; using PharloomCore.Model; using SilksongItemRandomizer; using StartingAbilityPicker; using UnityEngine; using UnityEngine.Audio; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.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 MenuChanger { [BepInPlugin("YourName.MenuChanger", "Menu Changer", "1.0.0")] public class MenuChangerMod : BaseUnityPlugin { private Coroutine _delayedFullApplyCoroutine; private bool _uiRebuildInProgress; private static readonly PropertyInfo EnemyRandoEnabledProp = Type.GetType("SilksongItemRandomizer.EnemyRandoAdjuster, SilksongItemRandomizer")?.GetProperty("Enabled", BindingFlags.Static | BindingFlags.Public); private static readonly WaitForSeconds PointOneSecond = new WaitForSeconds(0.1f); private static readonly WaitForSeconds ThirtySeconds = new WaitForSeconds(30f); private static readonly Action[] ApplyActions = new Action[25] { delegate { StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); }, delegate { StartingAbilityPickerAPI.SetSkillRandomMode(SharedRuntimeSettings.UseTypeMode); }, delegate { StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); }, delegate { StartingAbilityPickerAPI.SetStartingItemCount(SharedRuntimeSettings.ItemCount); }, delegate { StartingAbilityPickerAPI.SetSeed(SharedRuntimeSettings.Seed); }, delegate { StartingAbilityPickerAPI.SetResetSeedWorld(SharedRuntimeSettings.ResetSeedWorld); }, delegate { StartingAbilityPickerAPI.SetFullRandomMode(SharedRuntimeSettings.FullRandomMode); }, delegate { StartingAbilityPickerAPI.SetForceCompletionDisplay(SharedRuntimeSettings.ForceCompletionDisplay); }, delegate { StartingAbilityPickerAPI.SetMovementPermissions(NativeConfigPanel.BuildCurrentDirectionPermissions()); }, delegate { SilksongItemRandomizerAPI.SetEnabled(SharedRuntimeSettings.ItemRandomEnabled); }, delegate { SilksongItemRandomizerAPI.SetCrestRandomEnabled(SharedRuntimeSettings.CrestRandomEnabled); }, delegate { SilksongItemRandomizerAPI.SetSkillItemRandomEnabled(SharedRuntimeSettings.SkillItemRandomEnabled); }, delegate { SilksongItemRandomizerAPI.SetRelicRandomEnabled(SharedRuntimeSettings.RelicRandomEnabled); }, delegate { SilksongItemRandomizerAPI.SetSilkRandomEnabled(SharedRuntimeSettings.SilkRandomEnabled); }, delegate { SilksongItemRandomizerAPI.SetTrapEnabled(SharedRuntimeSettings.TrapEnabled); }, delegate { SilksongItemRandomizerAPI.SetTrapMovementEnabled(SharedRuntimeSettings.TrapMovementEnabled); }, delegate { SilksongItemRandomizerAPI.SetTrapDifficulty(SharedRuntimeSettings.TrapDifficulty); }, delegate { SilksongItemRandomizerAPI.SetCurrencyThresholds(SharedRuntimeSettings.CurrencyFirstThreshold, SharedRuntimeSettings.CurrencySecondThreshold); }, delegate { SilksongItemRandomizerAPI.SetSilkSpearPityCount(SharedRuntimeSettings.SilkSpearPityCount); }, delegate { HKSilksong_RandomizerAPI.SetMode(SharedRuntimeSettings.RoomRandomizerMode); }, delegate { HKSilksong_RandomizerAPI.SetEnabled(SharedRuntimeSettings.SceneRandomEnabled); }, delegate { HKSilksong_RandomizerAPI.SetShowSceneLabel(SharedRuntimeSettings.ShowSceneLabel); }, delegate { HKSilksong_RandomizerAPI.SetShowSeedOnScreen(SharedRuntimeSettings.ShowSeedLabel); }, delegate { if (SharedRuntimeSettings.RoomSeed != 0) { HKSilksong_RandomizerAPI.RegenerateWithSeed(SharedRuntimeSettings.RoomSeed); } }, delegate { EnemyRandoEnabledProp?.SetValue(null, SharedRuntimeSettings.EnemyRandomEnabled); } }; internal static MenuChangerMod Instance { get; private set; } private void Awake() { Instance = this; Harmony.CreateAndPatchAll(typeof(PlayModeMenuPatch), (string)null); Harmony.CreateAndPatchAll(typeof(SkipToFirstAct), (string)null); SceneManager.sceneLoaded += OnSceneLoaded; ((MonoBehaviour)this).StartCoroutine(DelayedInit()); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "Menu_Title") { ((MonoBehaviour)this).StartCoroutine(EnsureUIRebuiltAfterSceneReload()); } } private IEnumerator EnsureUIRebuiltAfterSceneReload() { if (_uiRebuildInProgress) { yield break; } _uiRebuildInProgress = true; try { UIManager ui = null; while ((Object)(object)ui == (Object)null) { ui = Object.FindObjectOfType<UIManager>(); if ((Object)(object)ui == (Object)null) { yield return PointOneSecond; } else { yield return null; } } while ((Object)(object)ui.UICanvas == (Object)null) { yield return null; } yield return null; if (UIManagerEx.IsUIReady && UIManagerEx.IsUIDestroyed()) { Debug.Log((object)"[MenuChanger] 检测到 UI 已随场景销毁,开始重建 UI..."); UIManagerEx.ResetUI(); NativeConfigPanel.Instance.Reset(); yield return PerformUIFullInit(); } } finally { _uiRebuildInProgress = false; } } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private IEnumerator DelayedInit() { yield return PerformUIFullInit(); } private IEnumerator PerformUIFullInit() { UIManager ui = null; while ((Object)(object)ui == (Object)null) { ui = Object.FindObjectOfType<UIManager>(); if ((Object)(object)ui == (Object)null) { yield return PointOneSecond; } else { yield return null; } } while ((Object)(object)ui.UICanvas == (Object)null) { yield return null; } yield return null; PrefabMenuObjects.Initialize(); yield return null; NativeConfigPanel.Instance.Initialize(); yield return null; string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "NativeUIMaker_Config.json"); if (!File.Exists(text)) { text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "PageConfigs", "NativeUIMaker_Config.json"); } UIManagerEx.InitializeUI(text); yield return null; while (!UIManagerEx.IsUIReady) { yield return null; } LoadSharedSettingsFromAPIs(); NativeConfigPanel.Instance.RefreshPageList(); NativeConfigPanel.Instance.RefreshAllValues(); Canvas.ForceUpdateCanvases(); Debug.Log((object)"[MenuChanger] 初始化完成"); ApplyModeSelectButtonIcons(); ApplySharedSettingsToModules(); if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.ShowUI) { Plugin.Instance.ShowUI = false; Plugin.Instance.ShowUI = true; } } private void ApplyModeSelectButtonIcons() { try { Dictionary<string, string> dictionary = new Dictionary<string, string> { { "ClassicModeBtn", "Icons/classic.png" }, { "SteelModeBtn", "Icons/steel.png" }, { "RandomModeBtn", "Icons/random.png" } }; foreach (NativeButton allInstance in NativeButton.AllInstances) { if (allInstance != null && !((Object)(object)allInstance.gameObject == (Object)null) && dictionary.TryGetValue(((Object)allInstance.gameObject).name, out var value)) { allInstance.SetIconFromFile(value); allInstance.SetIconScale(2f / 3f); } } } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 应用模式按钮图标失败: " + ex.Message)); } } private void LoadSharedSettingsFromAPIs() { try { SharedRuntimeSettings.SceneRandomEnabled = HKSilksong_RandomizerAPI.IsSceneRandomEnabled(); SharedRuntimeSettings.ShowSceneLabel = HKSilksong_RandomizerAPI.GetShowSceneLabel(); SharedRuntimeSettings.ShowSeedLabel = HKSilksong_RandomizerAPI.GetShowSeedOnScreen(); SharedRuntimeSettings.RoomSeed = HKSilksong_RandomizerAPI.GetCurrentRoomSeed(); SharedRuntimeSettings.RoomRandomizerMode = HKSilksong_RandomizerAPI.GetMode(); } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 加载 SceneRandomizer 配置失败: " + ex.Message)); } try { SharedRuntimeSettings.ItemRandomEnabled = SilksongItemRandomizerAPI.IsEnabled(); SharedRuntimeSettings.CrestRandomEnabled = SilksongItemRandomizerAPI.IsCrestRandomEnabled(); SharedRuntimeSettings.SkillItemRandomEnabled = SilksongItemRandomizerAPI.IsSkillItemRandomEnabled(); SharedRuntimeSettings.RelicRandomEnabled = SilksongItemRandomizerAPI.IsRelicRandomEnabled(); SharedRuntimeSettings.SilkRandomEnabled = SilksongItemRandomizerAPI.IsSilkRandomEnabled(); SharedRuntimeSettings.TrapEnabled = SilksongItemRandomizerAPI.IsTrapEnabled(); SharedRuntimeSettings.TrapMovementEnabled = SilksongItemRandomizerAPI.IsTrapMovementEnabled(); SharedRuntimeSettings.TrapDifficulty = SilksongItemRandomizerAPI.GetTrapDifficulty(); ValueTuple<int, int> currencyThresholds = SilksongItemRandomizerAPI.GetCurrencyThresholds(); SharedRuntimeSettings.CurrencyFirstThreshold = currencyThresholds.Item1; SharedRuntimeSettings.CurrencySecondThreshold = currencyThresholds.Item2; SharedRuntimeSettings.SilkSpearPityCount = SilksongItemRandomizerAPI.GetSilkSpearPityCount(); SharedRuntimeSettings.AttackUp = GlobalConfig.AttackUp.Value; SharedRuntimeSettings.AttackLeft = GlobalConfig.AttackLeft.Value; SharedRuntimeSettings.AttackRight = GlobalConfig.AttackRight.Value; } catch (Exception ex2) { Debug.LogWarning((object)("[MenuChanger] 加载 SilksongItemRandomizer 配置失败: " + ex2.Message)); } try { if ((Object)(object)Plugin.Instance != (Object)null) { SharedRuntimeSettings.Seed = Plugin.RandomSeed.Value; SharedRuntimeSettings.FullRandomMode = Plugin.CfgFullRandomMode.Value; SharedRuntimeSettings.DashLeft = Plugin.CfgAllowDashLeft.Value; SharedRuntimeSettings.DashRight = Plugin.CfgAllowDashRight.Value; SharedRuntimeSettings.HarpoonLeft = Plugin.CfgAllowHarpoonLeft.Value; SharedRuntimeSettings.HarpoonRight = Plugin.CfgAllowHarpoonRight.Value; SharedRuntimeSettings.FloatLeft = Plugin.CfgAllowFloatLeft.Value; SharedRuntimeSettings.FloatRight = Plugin.CfgAllowFloatRight.Value; SharedRuntimeSettings.WallJumpLeft = Plugin.CfgAllowWallJumpLeft.Value; SharedRuntimeSettings.WallJumpRight = Plugin.CfgAllowWallJumpRight.Value; SharedRuntimeSettings.AllowHeal = Plugin.CfgAllowHeal.Value; } } catch (Exception ex3) { Debug.LogWarning((object)("[MenuChanger] 加载 StartingAbilityPicker 配置失败: " + ex3.Message)); } try { SharedRuntimeSettings.SkillTriggerEnabled = false; } catch (Exception ex4) { Debug.LogWarning((object)("[MenuChanger] SkillTriggerMod 已停用: " + ex4.Message)); } try { if (EnemyRandoEnabledProp != null) { SharedRuntimeSettings.EnemyRandomEnabled = (bool)EnemyRandoEnabledProp.GetValue(null); } } catch (Exception ex5) { Debug.LogWarning((object)("[MenuChanger] 加载 EnemyRandomizer 配置失败: " + ex5.Message)); } Debug.Log((object)"[MenuChanger] SharedRuntimeSettings 已从各模块配置填充"); } public void ApplySharedSettingsToModules() { for (int i = 0; i < ApplyActions.Length; i++) { ApplyActions[i](); } } public IEnumerator ApplySharedSettingsStaggered() { for (int i = 0; i < ApplyActions.Length; i++) { ApplyActions[i](); yield return null; } } public static void HideAllMenuPages() { if (NativeConfigPanel.Instance != null && NativeConfigPanel.Instance.IsShowing) { NativeConfigPanel.Instance.Hide(); } } public void StartDelayedFullApply() { if (_delayedFullApplyCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_delayedFullApplyCoroutine); } _delayedFullApplyCoroutine = ((MonoBehaviour)this).StartCoroutine(DelayedFullApplyCoroutine()); } private IEnumerator DelayedFullApplyCoroutine() { yield return ThirtySeconds; Debug.Log((object)"[MenuChanger] 30秒延迟到达,开始重置所有随机数据..."); SilksongItemRandomizerAPI.ResetAllData(); ApplySharedSettingsToModules(); _delayedFullApplyCoroutine = null; } } [HarmonyPatch(typeof(UIManager))] public static class PlayModeMenuPatch { private static readonly MethodInfo SetMenuStateMethod = typeof(UIManager).GetMethod("SetMenuState", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly object[] SetMenuStateArgs = new object[1]; [HarmonyPrefix] [HarmonyPatch("UIGoToPlayModeMenu")] public static bool Prefix(UIManager __instance) { if (!UIManagerEx.IsUIReady) { return true; } ((MonoBehaviour)__instance).StartCoroutine(ShowModeSelect(__instance)); return false; } private static IEnumerator ShowModeSelect(UIManager ui) { ManagerSingleton<InputHandler>.Instance.StopUIInput(); if ((int)ui.menuState == 6) { yield return ui.HideSaveProfileMenu(true); } UIManagerEx.ShowPage("ModeSelect"); NativeConfigPanel.Instance.RefreshAllValues(); ManagerSingleton<InputHandler>.Instance.StartUIInput(); SetMenuStateArgs[0] = (object)(MainMenuState)18; SetMenuStateMethod?.Invoke(ui, SetMenuStateArgs); } } public class NativeConfigPanel { private static NativeConfigPanel _instance; private GameObject root; private CanvasGroup canvasGroup; private UIManager uiManager; private NativePage parentPage; private NativeLabel pageIndicator; private List<string> pageOrder = new List<string>(); private bool _seedRolling; private bool _seedRolledOnce; private bool _seedRollCanceled; private bool _seedUserProvided; private List<NativeInput> _repeatLimitInputs = new List<NativeInput>(); private static readonly Type EnemyRandoAdjusterType = Type.GetType("SilksongItemRandomizer.EnemyRandoAdjuster, SilksongItemRandomizer"); private static readonly PropertyInfo EnemyEnabledProp = EnemyRandoAdjusterType?.GetProperty("Enabled", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo ScaleRandomEnabledProp = EnemyRandoAdjusterType?.GetProperty("ScaleRandomEnabled", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo ScaleMinProp = EnemyRandoAdjusterType?.GetProperty("ScaleMin", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo ScaleMaxProp = EnemyRandoAdjusterType?.GetProperty("ScaleMax", BindingFlags.Static | BindingFlags.Public); private static readonly Type ExtraCurrencyType = Type.GetType("SilksongItemRandomizer.Extracurrencypickup, SilksongItemRandomizer"); private static readonly MethodInfo ExtraCurrencyResetAll = ExtraCurrencyType?.GetMethod("ResetAll", BindingFlags.Static | BindingFlags.Public); private static readonly Type TrapRandomizerType = Type.GetType("SilksongItemRandomizer.TrapRandomizer, SilksongItemRandomizer"); private static readonly MethodInfo ResetFrostBanned = TrapRandomizerType?.GetMethod("ResetFrostBannedScenes", BindingFlags.Static | BindingFlags.Public); private readonly Dictionary<string, NativeButton> _buttonCache = new Dictionary<string, NativeButton>(); private readonly Dictionary<string, NativeSlider> _sliderCache = new Dictionary<string, NativeSlider>(); private readonly Dictionary<string, NativeInput> _inputCache = new Dictionary<string, NativeInput>(); private readonly Dictionary<string, NativeOption> _optionCache = new Dictionary<string, NativeOption>(); private readonly Dictionary<string, NativeLabel> _labelCache = new Dictionary<string, NativeLabel>(); private static readonly string[] CategoryButtonNames = new string[6] { "CategoryBtn1", "CategoryBtn2", "CategoryBtn3", "CategoryBtn4", "CategoryBtn5", "CategoryBtn6" }; private static readonly Color DisabledTextColor = new Color(0.8f, 0.8f, 0.8f); private static readonly string[] TrapDifficultyNames = new string[3] { "初猎", "专注", "满溢" }; private EventHandler<NativeUIEventArgs> _uiEventHandler; public static NativeConfigPanel Instance => _instance ?? (_instance = new NativeConfigPanel()); public bool IsShowing { get { if ((Object)(object)root != (Object)null) { return root.activeSelf; } return false; } } private NativeButton GetCachedButton(string name) { if (!_buttonCache.TryGetValue(name, out var value)) { value = ((IEnumerable<NativeButton>)NativeButton.AllInstances).FirstOrDefault((Func<NativeButton, bool>)((NativeButton b) => ((Object)b.gameObject).name == name)); if (value != null) { _buttonCache[name] = value; } } return value; } private NativeSlider GetCachedSlider(string name) { if (!_sliderCache.TryGetValue(name, out var value)) { value = ((IEnumerable<NativeSlider>)NativeSlider.AllInstances).FirstOrDefault((Func<NativeSlider, bool>)((NativeSlider sl) => ((Object)sl.gameObject).name == name)); if (value != null) { _sliderCache[name] = value; } } return value; } private NativeInput GetCachedInput(string name) { if (!_inputCache.TryGetValue(name, out var value)) { value = ((IEnumerable<NativeInput>)NativeInput.AllInstances).FirstOrDefault((Func<NativeInput, bool>)((NativeInput inp) => ((Object)inp.gameObject).name == name)); if (value != null) { _inputCache[name] = value; } } return value; } private NativeOption GetCachedOption(string name) { if (!_optionCache.TryGetValue(name, out var value)) { value = ((IEnumerable<NativeOption>)NativeOption.AllInstances).FirstOrDefault((Func<NativeOption, bool>)((NativeOption opt) => ((Object)opt.gameObject).name == name)); if (value != null) { _optionCache[name] = value; } } return value; } private NativeLabel GetCachedLabel(string name) { if (!_labelCache.TryGetValue(name, out var value)) { value = ((IEnumerable<NativeLabel>)NativeLabel.AllInstances).FirstOrDefault((Func<NativeLabel, bool>)((NativeLabel lb) => ((Object)lb.gameObject).name == name)); if (value != null) { _labelCache[name] = value; } } return value; } private NativeConfigPanel() { } public void Reset() { root = null; canvasGroup = null; uiManager = null; parentPage = null; pageIndicator = null; pageOrder.Clear(); _repeatLimitInputs.Clear(); _buttonCache.Clear(); _sliderCache.Clear(); _inputCache.Clear(); _optionCache.Clear(); _labelCache.Clear(); } public void Initialize() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)root != (Object)null)) { PrefabMenuObjects.Initialize(); uiManager = UIManager.instance; if (!((Object)(object)uiManager == (Object)null)) { root = new GameObject("NativeConfigPanel"); root.transform.SetParent(((Component)uiManager.UICanvas).transform, false); canvasGroup = root.AddComponent<CanvasGroup>(); canvasGroup.alpha = 0f; canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; root.SetActive(false); GameObject val = new GameObject("Panel"); val.transform.SetParent(root.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(1200f, 800f); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; pageIndicator = NativeLabel.Create(val2); pageIndicator.SetText("1/1"); pageIndicator.SetFontSize(32); pageIndicator.SetPosition(new Vector2(0f, -420f)); pageIndicator.SetSize(200f, 60f); pageIndicator.SetAlignment((TextAnchor)4); pageIndicator.gameObject.SetActive(false); SubscribeToGlobalEvents(); BindRepeatLimitInputs(); RefreshAllValues(); } } } public void StartAutoSeedRoll() { if (!_seedRolledOnce) { _seedRolledOnce = true; if ((Object)(object)uiManager != (Object)null) { ((MonoBehaviour)uiManager).StartCoroutine(RollSeedCoroutine()); } } } public void ResetAllToDefaults() { SharedRuntimeSettings.SceneRandomEnabled = false; SharedRuntimeSettings.ItemRandomEnabled = true; SharedRuntimeSettings.TrapEnabled = false; SharedRuntimeSettings.FullRandomMode = false; SharedRuntimeSettings.CrestRandomEnabled = false; SharedRuntimeSettings.SkillItemRandomEnabled = SilksongItemRandomizerAPI.IsSkillItemRandomEnabled(); SharedRuntimeSettings.RelicRandomEnabled = SilksongItemRandomizerAPI.IsRelicRandomEnabled(); SharedRuntimeSettings.SilkRandomEnabled = false; SharedRuntimeSettings.EnemyRandomEnabled = false; StartingAbilityPickerAPI.SetEnemyRandomEnabled(false); SharedRuntimeSettings.ShowSceneLabel = true; SharedRuntimeSettings.ShowSeedLabel = true; SharedRuntimeSettings.TrapMovementEnabled = false; SharedRuntimeSettings.ForceCompletionDisplay = true; SilksongItemRandomizerAPI.SetEnabled(true); SilksongItemRandomizerAPI.SetTrapEnabled(false); SilksongItemRandomizerAPI.SetTrapMovementEnabled(false); SilksongItemRandomizerAPI.SetCrestRandomEnabled(false); SilksongItemRandomizerAPI.SetRelicRandomEnabled(SilksongItemRandomizerAPI.IsRelicRandomEnabled()); SilksongItemRandomizerAPI.SetSilkRandomEnabled(false); SharedRuntimeSettings.SkillTotal = 0; SharedRuntimeSettings.SkillVertical = 0; SharedRuntimeSettings.SkillHorizontal = 0; SharedRuntimeSettings.SkillSpecial = 0; SharedRuntimeSettings.SkillAttack = 0; StartingAbilityPickerAPI.SetSkillCounts(0, 0, 0, 0, 0); SharedRuntimeSettings.ItemCount = 0; StartingAbilityPickerAPI.SetStartingItemCount(0); if (ScaleRandomEnabledProp != null) { ScaleRandomEnabledProp.SetValue(null, true); } if (ScaleMinProp != null) { ScaleMinProp.SetValue(null, 1f); } if (ScaleMaxProp != null) { ScaleMaxProp.SetValue(null, 1f); } SharedRuntimeSettings.AllowHeal = false; SharedRuntimeSettings.DashLeft = false; SharedRuntimeSettings.DashRight = false; SharedRuntimeSettings.HarpoonLeft = false; SharedRuntimeSettings.HarpoonRight = false; SharedRuntimeSettings.FloatLeft = false; SharedRuntimeSettings.FloatRight = false; SharedRuntimeSettings.WallJumpLeft = false; SharedRuntimeSettings.WallJumpRight = false; StartingAbilityPickerAPI.SetAttackPermissions(true, true, true); SharedRuntimeSettings.ColdResistOwned = false; SharedRuntimeSettings.SwimOwned = false; SharedRuntimeSettings.TrapDifficulty = 0; StartingAbilityPickerAPI.SaveAllSettingsToConfig(); RefreshAllValues(); try { SilksongItemRandomizerAPI.ResetAllData(); } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 重置 SIR 本地数据失败: " + ex.Message)); } if ((Object)(object)MenuChangerMod.Instance != (Object)null) { ((MonoBehaviour)MenuChangerMod.Instance).StartCoroutine(MenuChangerMod.Instance.ApplySharedSettingsStaggered()); } } private void BindRepeatLimitInputs() { NativePage val = ((IEnumerable<NativePage>)NativePage.AllInstances).FirstOrDefault((Func<NativePage, bool>)((NativePage p) => ((Object)p.gameObject).name == "RepeatLimitPage")); if (val == null) { return; } _repeatLimitInputs = val.gameObject.GetComponentsInChildren<NativeInput>(true).ToList(); if (_repeatLimitInputs.Count == 0) { Debug.LogWarning((object)"[NativeConfigPanel] RepeatLimitPage 下没有找到任何 NativeInput 控件"); return; } foreach (NativeInput repeatLimitInput in _repeatLimitInputs) { string name = ((Object)repeatLimitInput.gameObject).name; repeatLimitInput.AddTextChangedListener((Action<string>)delegate(string text) { if (int.TryParse(text, out var result)) { int limitValue = GetLimitValue(name); switch (name) { case "Input_LimitSkillItem": ItemLimitConfig.LimitSkillItem = result; break; case "Input_LimitRelic": ItemLimitConfig.LimitRelic = result; break; case "Input_LimitOtherItem": ItemLimitConfig.LimitOtherItem = result; break; case "Input_LimitUpSlash": ItemLimitConfig.LimitUpSlash = result; break; case "Input_LimitLeftSlash": ItemLimitConfig.LimitLeftSlash = result; break; case "Input_LimitRightSlash": ItemLimitConfig.LimitRightSlash = result; break; case "Input_LimitDashLeft": ItemLimitConfig.LimitDashLeft = result; break; case "Input_LimitDashRight": ItemLimitConfig.LimitDashRight = result; break; case "Input_LimitHarpoonLeft": ItemLimitConfig.LimitHarpoonLeft = result; break; case "Input_LimitHarpoonRight": ItemLimitConfig.LimitHarpoonRight = result; break; case "Input_LimitFloatLeft": ItemLimitConfig.LimitFloatLeft = result; break; case "Input_LimitFloatRight": ItemLimitConfig.LimitFloatRight = result; break; case "Input_LimitWallJumpLeft": ItemLimitConfig.LimitWallJumpLeft = result; break; case "Input_LimitWallJumpRight": ItemLimitConfig.LimitWallJumpRight = result; break; case "Input_LimitHeal": ItemLimitConfig.LimitHeal = result; break; case "Input_LimitNeedleThrow": ItemLimitConfig.LimitNeedleThrow = result; break; case "Input_LimitThreadSphere": ItemLimitConfig.LimitThreadSphere = result; break; case "Input_LimitHarpoonDash": ItemLimitConfig.LimitHarpoonDash = result; break; case "Input_LimitSilkCharge": ItemLimitConfig.LimitSilkCharge = result; break; case "Input_LimitSilkBomb": ItemLimitConfig.LimitSilkBomb = result; break; case "Input_LimitSilkBossNeedle": ItemLimitConfig.LimitSilkBossNeedle = result; break; case "Input_LimitNeedolin": ItemLimitConfig.LimitNeedolin = result; break; case "Input_LimitParry": ItemLimitConfig.LimitParry = result; break; case "Input_LimitNeedolinMemory": ItemLimitConfig.LimitNeedolinMemory = result; break; case "Input_LimitFastTravel": ItemLimitConfig.LimitFastTravel = result; break; case "Input_LimitEvaHeal": ItemLimitConfig.LimitEvaHeal = result; break; case "Input_LimitDash": ItemLimitConfig.LimitDash = result; break; case "Input_LimitBrolly": ItemLimitConfig.LimitBrolly = result; break; case "Input_LimitDoubleJump": ItemLimitConfig.LimitDoubleJump = result; break; case "Input_LimitSuperJump": ItemLimitConfig.LimitSuperJump = result; break; case "Input_LimitWallJump": ItemLimitConfig.LimitWallJump = result; break; case "Input_LimitChargeSlash": ItemLimitConfig.LimitChargeSlash = result; break; case "Input_LimitHeartPiece": ItemLimitConfig.LimitHeartPiece = result; break; case "Input_LimitSpoolPart": ItemLimitConfig.LimitSpoolPart = result; break; case "Input_LimitMaxSilkRegenUp": ItemLimitConfig.LimitMaxSilkRegenUp = result; break; case "Input_LimitUnlockCrestSlot": ItemLimitConfig.LimitUnlockCrestSlot = result; break; } if (GetLimitValue(name) != limitValue) { SilksongItemRandomizerAPI.SaveLimitsAndRegenerateMappings(); } } }); repeatLimitInput.SetText(GetLimitValue(name).ToString()); } } private int GetLimitValue(string inputName) { return inputName switch { "Input_LimitSkillItem" => ItemLimitConfig.LimitSkillItem, "Input_LimitRelic" => ItemLimitConfig.LimitRelic, "Input_LimitOtherItem" => ItemLimitConfig.LimitOtherItem, "Input_LimitUpSlash" => ItemLimitConfig.LimitUpSlash, "Input_LimitLeftSlash" => ItemLimitConfig.LimitLeftSlash, "Input_LimitRightSlash" => ItemLimitConfig.LimitRightSlash, "Input_LimitDashLeft" => ItemLimitConfig.LimitDashLeft, "Input_LimitDashRight" => ItemLimitConfig.LimitDashRight, "Input_LimitHarpoonLeft" => ItemLimitConfig.LimitHarpoonLeft, "Input_LimitHarpoonRight" => ItemLimitConfig.LimitHarpoonRight, "Input_LimitFloatLeft" => ItemLimitConfig.LimitFloatLeft, "Input_LimitFloatRight" => ItemLimitConfig.LimitFloatRight, "Input_LimitWallJumpLeft" => ItemLimitConfig.LimitWallJumpLeft, "Input_LimitWallJumpRight" => ItemLimitConfig.LimitWallJumpRight, "Input_LimitHeal" => ItemLimitConfig.LimitHeal, "Input_LimitNeedleThrow" => ItemLimitConfig.LimitNeedleThrow, "Input_LimitThreadSphere" => ItemLimitConfig.LimitThreadSphere, "Input_LimitHarpoonDash" => ItemLimitConfig.LimitHarpoonDash, "Input_LimitSilkCharge" => ItemLimitConfig.LimitSilkCharge, "Input_LimitSilkBomb" => ItemLimitConfig.LimitSilkBomb, "Input_LimitSilkBossNeedle" => ItemLimitConfig.LimitSilkBossNeedle, "Input_LimitNeedolin" => ItemLimitConfig.LimitNeedolin, "Input_LimitParry" => ItemLimitConfig.LimitParry, "Input_LimitNeedolinMemory" => ItemLimitConfig.LimitNeedolinMemory, "Input_LimitFastTravel" => ItemLimitConfig.LimitFastTravel, "Input_LimitEvaHeal" => ItemLimitConfig.LimitEvaHeal, "Input_LimitDash" => ItemLimitConfig.LimitDash, "Input_LimitBrolly" => ItemLimitConfig.LimitBrolly, "Input_LimitDoubleJump" => ItemLimitConfig.LimitDoubleJump, "Input_LimitSuperJump" => ItemLimitConfig.LimitSuperJump, "Input_LimitWallJump" => ItemLimitConfig.LimitWallJump, "Input_LimitChargeSlash" => ItemLimitConfig.LimitChargeSlash, "Input_LimitHeartPiece" => ItemLimitConfig.LimitHeartPiece, "Input_LimitSpoolPart" => ItemLimitConfig.LimitSpoolPart, "Input_LimitMaxSilkRegenUp" => ItemLimitConfig.LimitMaxSilkRegenUp, "Input_LimitUnlockCrestSlot" => ItemLimitConfig.LimitUnlockCrestSlot, _ => 0, }; } private void RefreshRepeatLimitInputs() { foreach (NativeInput repeatLimitInput in _repeatLimitInputs) { repeatLimitInput.SetText(GetLimitValue(((Object)repeatLimitInput.gameObject).name).ToString()); } } private void SubscribeToGlobalEvents() { if (_uiEventHandler != null) { NativeUIEventDispatcher.OnNativeUIEvent -= _uiEventHandler; } _uiEventHandler = delegate(object sender, NativeUIEventArgs args) { //IL_0001: 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_0017: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 if ((int)args.EventType == 0) { HandleClickEvent(args); } else if ((int)args.EventType == 1) { HandleValueChangedEvent(args); } else if ((int)args.EventType == 2) { HandleOptionChangedEvent(args); } }; NativeUIEventDispatcher.OnNativeUIEvent += _uiEventHandler; } private void HandleClickEvent(NativeUIEventArgs args) { if (args.ControlName == "CalcStartGameBtn") { Plugin.BlackoutShow(); } if (args.ControlName == "RandomModeBtn") { ResetAllToDefaults(); ShowPage(pageOrder.Contains("Main") ? "Main" : pageOrder[0]); } else if (args.ControlName == "ClassicModeBtn") { StartGame(permaDeath: false); } else if (args.ControlName == "SteelModeBtn") { StartGame(permaDeath: true); } else if (args.ControlName == "DetailBtn") { UIManagerEx.ShowPage("Detail0"); } else if (args.ControlName == "BackToMainBtn_Calc") { _seedRollCanceled = true; NativeLabel cachedLabel = GetCachedLabel("SeedCalcStatus"); if (cachedLabel != null) { cachedLabel.SetText(UILocale.Get("计算已取消,返回设置页")); } ShowPage("Main"); } else if (args.ControlName.StartsWith("BackToMainBtn")) { ShowPage("Main"); } else if (args.ControlName == "BackToModeSelectBtn") { ShowPage("ModeSelect"); } else if (args.ControlName == "ItemPoolBtn") { ShowPage("ItemPoolPage"); } else if (args.ControlName == "StartLocationBtn") { ShowPage("StartLocationPage"); } else if (args.ControlName == "RepeatBtn") { ShowPage("RepeatLimitPage"); } else if (args.ControlName.StartsWith("LeftArrow")) { SwitchPage(-1); } else if (args.ControlName.StartsWith("RightArrow")) { SwitchPage(1); } if (args.ControlType == "Button") { object source = args.Source; NativeButton val = (NativeButton)((source is NativeButton) ? source : null); if (val == null) { return; } switch (args.ControlName) { case "RoomBtn": StartingAbilityPickerAPI.SetSceneRandomEnabled(SharedRuntimeSettings.SceneRandomEnabled = !SharedRuntimeSettings.SceneRandomEnabled); break; case "ItemBtn": StartingAbilityPickerAPI.SetItemRandomEnabled(SharedRuntimeSettings.ItemRandomEnabled = !SharedRuntimeSettings.ItemRandomEnabled); break; case "TrapBtn": StartingAbilityPickerAPI.SetTrapRandomEnabled(SharedRuntimeSettings.TrapEnabled = !SharedRuntimeSettings.TrapEnabled); break; case "EnemyBtn": StartingAbilityPickerAPI.SetEnemyRandomEnabled(SharedRuntimeSettings.EnemyRandomEnabled = !SharedRuntimeSettings.EnemyRandomEnabled); break; case "FullRandomBtn": case "RandomModeMainBtn": StartingAbilityPickerAPI.SetFullRandomMode(SharedRuntimeSettings.FullRandomMode = !SharedRuntimeSettings.FullRandomMode); UpdateFullRandomUI(); break; case "TrapMovementBtn": SilksongItemRandomizerAPI.SetTrapMovementEnabled(SharedRuntimeSettings.TrapMovementEnabled = !SharedRuntimeSettings.TrapMovementEnabled); break; case "EnemyScaleRandomBtn": if (ScaleRandomEnabledProp != null) { bool flag2 = (bool)ScaleRandomEnabledProp.GetValue(null); ScaleRandomEnabledProp.SetValue(null, !flag2); } break; case "SilkRandomBtn": SilksongItemRandomizerAPI.SetSilkRandomEnabled(SharedRuntimeSettings.SilkRandomEnabled = !SharedRuntimeSettings.SilkRandomEnabled); break; case "UpBtn": { bool flag = (SharedRuntimeSettings.AttackUp = !SharedRuntimeSettings.AttackUp); (bool, bool, bool) attackPermissions = StartingAbilityPickerAPI.GetAttackPermissions(); StartingAbilityPickerAPI.SetAttackPermissions(flag, attackPermissions.Item2, attackPermissions.Item3); UpdateCategoryButtonStates(); break; } case "LeftBtn": { bool flag = (SharedRuntimeSettings.AttackLeft = !SharedRuntimeSettings.AttackLeft); (bool, bool, bool) attackPermissions = StartingAbilityPickerAPI.GetAttackPermissions(); StartingAbilityPickerAPI.SetAttackPermissions(attackPermissions.Item1, flag, attackPermissions.Item3); UpdateCategoryButtonStates(); break; } case "RightBtn": { bool flag = (SharedRuntimeSettings.AttackRight = !SharedRuntimeSettings.AttackRight); (bool, bool, bool) attackPermissions = StartingAbilityPickerAPI.GetAttackPermissions(); StartingAbilityPickerAPI.SetAttackPermissions(attackPermissions.Item1, attackPermissions.Item2, flag); UpdateCategoryButtonStates(); break; } case "ShowRoomNameBtn": HKSilksong_RandomizerAPI.SetShowSceneLabel(SharedRuntimeSettings.ShowSceneLabel = !SharedRuntimeSettings.ShowSceneLabel); break; case "ShowRoomSeedBtn": HKSilksong_RandomizerAPI.SetShowSeedOnScreen(SharedRuntimeSettings.ShowSeedLabel = !SharedRuntimeSettings.ShowSeedLabel); break; case "RoomModeBtn": HKSilksong_RandomizerAPI.SetMode(SharedRuntimeSettings.RoomRandomizerMode = ((SharedRuntimeSettings.RoomRandomizerMode != 1) ? 1 : 0)); break; case "SilkHeartBtn": RoomRandomMode.Toggle(); break; case "CompletionBtn": StartingAbilityPickerAPI.SetForceCompletionDisplay(SharedRuntimeSettings.ForceCompletionDisplay = !SharedRuntimeSettings.ForceCompletionDisplay); break; case "TrapDifficultyBtn": SilksongItemRandomizerAPI.SetTrapDifficulty(SharedRuntimeSettings.TrapDifficulty = (SharedRuntimeSettings.TrapDifficulty + 1) % 3); if (SharedRuntimeSettings.TrapEnabled) { SilksongItemRandomizerAPI.RegenerateTrapsNow(); } break; case "CategoryBtn1": if (SharedRuntimeSettings.FullRandomMode) { SharedRuntimeSettings.DashRight = (SharedRuntimeSettings.DashLeft = !SharedRuntimeSettings.DashLeft); StartingAbilityPickerAPI.SetMovementPermissions(BuildCurrentDirectionPermissions()); } break; case "CategoryBtn2": if (SharedRuntimeSettings.FullRandomMode) { SharedRuntimeSettings.HarpoonRight = (SharedRuntimeSettings.HarpoonLeft = !SharedRuntimeSettings.HarpoonLeft); StartingAbilityPickerAPI.SetMovementPermissions(BuildCurrentDirectionPermissions()); } break; case "CategoryBtn3": if (SharedRuntimeSettings.FullRandomMode) { SharedRuntimeSettings.FloatRight = (SharedRuntimeSettings.FloatLeft = !SharedRuntimeSettings.FloatLeft); StartingAbilityPickerAPI.SetMovementPermissions(BuildCurrentDirectionPermissions()); } break; case "CategoryBtn4": if (SharedRuntimeSettings.FullRandomMode) { SharedRuntimeSettings.WallJumpRight = (SharedRuntimeSettings.WallJumpLeft = !SharedRuntimeSettings.WallJumpLeft); StartingAbilityPickerAPI.SetMovementPermissions(BuildCurrentDirectionPermissions()); } break; case "CategoryBtn5": if (SharedRuntimeSettings.FullRandomMode) { bool flag = !SharedRuntimeSettings.AllowHeal; SharedRuntimeSettings.AllowHeal = flag; StartingAbilityPickerAPI.SetMovementPermissions(BuildCurrentDirectionPermissions()); } break; case "CategoryBtn6": { bool flag = (SharedRuntimeSettings.AttackRight = (SharedRuntimeSettings.AttackLeft = (SharedRuntimeSettings.AttackUp = !SharedRuntimeSettings.AttackUp || !SharedRuntimeSettings.AttackLeft || !SharedRuntimeSettings.AttackRight))); StartingAbilityPickerAPI.SetAttackPermissions(flag, flag, flag); break; } case "CrestTypeBtn": { bool flag = (SharedRuntimeSettings.CrestRandomEnabled = !SharedRuntimeSettings.CrestRandomEnabled); SilksongItemRandomizerAPI.SetCrestRandomEnabled(flag); UpdateTypeButtonColor(val, flag); break; } case "SkillTypeBtn": { bool flag = (SharedRuntimeSettings.SkillItemRandomEnabled = !SharedRuntimeSettings.SkillItemRandomEnabled); SilksongItemRandomizerAPI.SetSkillItemRandomEnabled(flag); UpdateTypeButtonColor(val, flag); break; } case "RelicTypeBtn": { bool flag = (SharedRuntimeSettings.RelicRandomEnabled = !SharedRuntimeSettings.RelicRandomEnabled); SilksongItemRandomizerAPI.SetRelicRandomEnabled(flag); UpdateTypeButtonColor(val, flag); break; } } } switch (args.ControlName) { case "ConfirmBtn": StartSeedCalc(); break; case "CalcStartGameBtn": Confirm(); break; case "ResetShopBtn": SilksongItemRandomizerAPI.ResetAllData(); break; case "ResetPickupBtn": ExtraCurrencyResetAll?.Invoke(null, null); break; case "ResetFrostBlacklistBtn": ResetFrostBanned?.Invoke(null, null); break; } } private IEnumerator RollSeedCoroutine() { if (_seedRolling) { yield break; } _seedRolling = true; _seedRollCanceled = false; NativeLabel statusLabel = GetCachedLabel("SeedCalcStatus"); NativeLabel resultLabel = GetCachedLabel("SeedCalcResult"); try { SetStatus("正在准备检查点数据…"); NativeInput seedInput = GetCachedInput("SeedInput"); int wait; if (seedInput == null) { for (wait = 0; wait < 120; wait++) { if (seedInput != null) { break; } seedInput = GetCachedInput("SeedInput"); yield return null; } if (seedInput == null) { Debug.LogWarning((object)"[MenuChanger] SeedInput 控件 2 秒内未出现,跳过随机种子"); SetStatus("SeedInput 控件未就绪,跳过随机种子"); yield break; } } long baseTicks = DateTime.UtcNow.Ticks; int tickCount = Environment.TickCount; wait = 0; while (!_seedRollCanceled) { SetStatus("正在用真实映射判定候选种子(第 " + (wait + 1) + "/∞ 轮)…"); for (int i = 0; i < 20; i++) { if (_seedRollCanceled) { SetStatus("计算已取消,保留当前种子"); yield break; } int s = GameSeedValidator.NextDynamicSeed(baseTicks, tickCount, wait * 20 + i); seedInput.SetTextSilent(s.ToString()); SetResult("判定中… 候选: " + s); yield return null; try { if (HKSilksong_RandomizerAPI.IsSceneRandomEnabled()) { HKSilksong_RandomizerAPI.RegenerateWithSeed(s); } } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 候选种子房间连接生成失败: " + ex.Message)); } if (GameSeedValidator.IsGameLive(s)) { Debug.Log((object)("[MenuChanger] 已筛选出可行随机种子: " + s)); ApplySeed(s, seedInput); SetStatus("活种确认完成,可以开始游戏"); SetResult("可行种子: " + s); yield break; } SetResult("候选 " + s + " 非活种,继续寻找…"); yield return null; } wait++; } SetStatus("计算已取消,保留当前种子"); } finally { _seedRolling = false; } void SetResult(string text) { if (resultLabel != null) { resultLabel.SetText(UILocale.Get(text)); } } void SetStatus(string text) { if (statusLabel != null) { statusLabel.SetText(UILocale.Get(text)); } } } private void StartSeedCalc() { if (_seedRolling) { Debug.Log((object)"[MenuChanger] 活种计算正在进行中,忽略重复点击"); return; } UIManagerEx.ShowPage("SeedCalcPage"); NativeLabel cachedLabel = GetCachedLabel("SeedCalcStatus"); NativeLabel cachedLabel2 = GetCachedLabel("SeedCalcResult"); if (_seedUserProvided) { int seed = SharedRuntimeSettings.Seed; Debug.Log((object)("[MenuChanger] 检测到手填种子 " + seed + ",直接采用不重新计算")); if (cachedLabel != null) { cachedLabel.SetText(UILocale.Get("已采用手填种子")); } if (cachedLabel2 != null) { cachedLabel2.SetText(UILocale.Get("种子: ") + seed); } } else { if (cachedLabel != null) { cachedLabel.SetText(UILocale.Get("正在计算可行种子,请稍候…")); } if ((Object)(object)uiManager != (Object)null) { ((MonoBehaviour)uiManager).StartCoroutine(RollSeedCoroutine()); } } } private void ApplySeed(int seed, NativeInput seedInput) { SharedRuntimeSettings.Seed = seed; StartingAbilityPickerAPI.SetSeed(seed); SilksongItemRandomizerAPI.SetSeed(seed); _seedUserProvided = false; seedInput.SetTextSilent(seed.ToString()); } private void HandleValueChangedEvent(NativeUIEventArgs args) { if (args.ControlType == "Slider") { float num = (float)args.Value; string controlName = args.ControlName; if (controlName == null) { return; } switch (controlName.Length) { case 7: switch (controlName[0]) { case 'V': if (controlName == "VSlider") { SharedRuntimeSettings.SkillVertical = (int)num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, (int)num, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); } break; case 'H': if (controlName == "HSlider") { SharedRuntimeSettings.SkillHorizontal = (int)num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, (int)num, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); } break; case 'S': if (controlName == "SSlider") { SharedRuntimeSettings.SkillSpecial = (int)num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, (int)num, SharedRuntimeSettings.SkillAttack); } break; case 'A': if (controlName == "ASlider") { SharedRuntimeSettings.SkillAttack = (int)num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, (int)num); } break; } break; case 19: switch (controlName[11]) { case 'i': if (controlName == "EnemyScaleMinSlider") { ScaleMinProp?.SetValue(null, num); } break; case 'a': if (controlName == "EnemyScaleMaxSlider") { ScaleMaxProp?.SetValue(null, num); } break; } break; case 15: if (controlName == "ItemCountSlider") { SharedRuntimeSettings.ItemCount = (int)num; StartingAbilityPickerAPI.SetStartingItemCount((int)num); } break; case 16: if (controlName == "TotalSkillSlider") { SharedRuntimeSettings.SkillTotal = (int)num; StartingAbilityPickerAPI.SetSkillCounts((int)num, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); } break; } } else { if (!(args.ControlType == "Input")) { return; } string s = (string)args.Value; switch (args.ControlName) { case "CurrencyFirstThresholdInput": { if (int.TryParse(s, out var result4)) { SharedRuntimeSettings.CurrencyFirstThreshold = result4; SilksongItemRandomizerAPI.SetCurrencyThresholds(result4, SharedRuntimeSettings.CurrencySecondThreshold); } break; } case "CurrencySecondThresholdInput": { if (int.TryParse(s, out var result2)) { SharedRuntimeSettings.CurrencySecondThreshold = result2; SilksongItemRandomizerAPI.SetCurrencyThresholds(SharedRuntimeSettings.CurrencyFirstThreshold, result2); } break; } case "SilkSpearPityInput": { if (int.TryParse(s, out var result3)) { SharedRuntimeSettings.SilkSpearPityCount = result3; SilksongItemRandomizerAPI.SetSilkSpearPityCount(result3); } break; } case "SeedInput": { if (int.TryParse(s, out var result)) { _seedRollCanceled = true; _seedUserProvided = true; SharedRuntimeSettings.Seed = result; StartingAbilityPickerAPI.SetSeed(result); SilksongItemRandomizerAPI.SetSeed(result); } break; } } } } private void HandleOptionChangedEvent(NativeUIEventArgs args) { if (!(args.ControlType == "Option")) { return; } int num = (int)args.Value; string controlName = args.ControlName; if (!(controlName == "SkillModeOption")) { if (controlName == "ResetOption") { SharedRuntimeSettings.ResetSeedWorld = num == 1; StartingAbilityPickerAPI.SetResetSeedWorld(num == 1); } } else { SharedRuntimeSettings.UseTypeMode = num == 1; StartingAbilityPickerAPI.SetSkillRandomMode(num == 1); UpdateSlidersVisibility(); } } private bool IsFullRandomEnabled() { return SharedRuntimeSettings.FullRandomMode; } internal static DirectionPermissions BuildCurrentDirectionPermissions() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown return new DirectionPermissions { DashLeft = SharedRuntimeSettings.DashLeft, DashRight = SharedRuntimeSettings.DashRight, HarpoonLeft = SharedRuntimeSettings.HarpoonLeft, HarpoonRight = SharedRuntimeSettings.HarpoonRight, FloatLeft = SharedRuntimeSettings.FloatLeft, FloatRight = SharedRuntimeSettings.FloatRight, WallJumpLeft = SharedRuntimeSettings.WallJumpLeft, WallJumpRight = SharedRuntimeSettings.WallJumpRight, AllowHeal = SharedRuntimeSettings.AllowHeal }; } private void UpdateFullRandomUI() { bool interactable = IsFullRandomEnabled(); string[] categoryButtonNames = CategoryButtonNames; foreach (string name in categoryButtonNames) { NativeButton cachedButton = GetCachedButton(name); if (cachedButton != null && (Object)(object)cachedButton.menuButton != (Object)null) { ((Selectable)cachedButton.menuButton).interactable = interactable; } } NativeButton cachedButton2 = GetCachedButton("UpBtn"); NativeButton cachedButton3 = GetCachedButton("LeftBtn"); NativeButton cachedButton4 = GetCachedButton("RightBtn"); if (cachedButton2 != null && (Object)(object)cachedButton2.menuButton != (Object)null) { ((Selectable)cachedButton2.menuButton).interactable = true; } if (cachedButton3 != null && (Object)(object)cachedButton3.menuButton != (Object)null) { ((Selectable)cachedButton3.menuButton).interactable = true; } if (cachedButton4 != null && (Object)(object)cachedButton4.menuButton != (Object)null) { ((Selectable)cachedButton4.menuButton).interactable = true; } } private void UpdateCategoryButtonStates() { if (IsFullRandomEnabled()) { NativeButton cachedButton = GetCachedButton("CategoryBtn1"); if (cachedButton != null) { cachedButton.SetToggleIndex((SharedRuntimeSettings.DashLeft && SharedRuntimeSettings.DashRight) ? 1 : 0); } NativeButton cachedButton2 = GetCachedButton("CategoryBtn2"); if (cachedButton2 != null) { cachedButton2.SetToggleIndex((SharedRuntimeSettings.HarpoonLeft && SharedRuntimeSettings.HarpoonRight) ? 1 : 0); } NativeButton cachedButton3 = GetCachedButton("CategoryBtn3"); if (cachedButton3 != null) { cachedButton3.SetToggleIndex((SharedRuntimeSettings.FloatLeft && SharedRuntimeSettings.FloatRight) ? 1 : 0); } NativeButton cachedButton4 = GetCachedButton("CategoryBtn4"); if (cachedButton4 != null) { cachedButton4.SetToggleIndex((SharedRuntimeSettings.WallJumpLeft && SharedRuntimeSettings.WallJumpRight) ? 1 : 0); } NativeButton cachedButton5 = GetCachedButton("CategoryBtn5"); if (cachedButton5 != null) { cachedButton5.SetToggleIndex(SharedRuntimeSettings.AllowHeal ? 1 : 0); } NativeButton cachedButton6 = GetCachedButton("CategoryBtn6"); if (cachedButton6 != null) { cachedButton6.SetToggleIndex((SharedRuntimeSettings.AttackUp && SharedRuntimeSettings.AttackLeft && SharedRuntimeSettings.AttackRight) ? 1 : 0); } } } private void UpdateTypeButtonColor(NativeButton btn, bool isEnabled) { //IL_0024: 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) if (btn != null) { Text componentInChildren = btn.gameObject.GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (isEnabled ? Color.white : DisabledTextColor); ((Graphic)componentInChildren).SetVerticesDirty(); } } } private void UpdateSlidersVisibility() { bool flag = !SharedRuntimeSettings.UseTypeMode; NativeSlider cachedSlider = GetCachedSlider("TotalSkillSlider"); if (cachedSlider != null) { cachedSlider.gameObject.SetActive(flag); } NativeSlider cachedSlider2 = GetCachedSlider("VSlider"); NativeSlider cachedSlider3 = GetCachedSlider("HSlider"); NativeSlider cachedSlider4 = GetCachedSlider("SSlider"); NativeSlider cachedSlider5 = GetCachedSlider("ASlider"); bool active = !flag; if (cachedSlider2 != null) { cachedSlider2.gameObject.SetActive(active); } if (cachedSlider3 != null) { cachedSlider3.gameObject.SetActive(active); } if (cachedSlider4 != null) { cachedSlider4.gameObject.SetActive(active); } if (cachedSlider5 != null) { cachedSlider5.gameObject.SetActive(active); } } public void RefreshAllValues() { SyncButtonState("RoomBtn", SharedRuntimeSettings.SceneRandomEnabled); SyncButtonState("ItemBtn", SharedRuntimeSettings.ItemRandomEnabled); SyncButtonState("TrapBtn", SharedRuntimeSettings.TrapEnabled); SyncButtonState("FullRandomBtn", SharedRuntimeSettings.FullRandomMode); SyncButtonState("RandomModeMainBtn", SharedRuntimeSettings.FullRandomMode); SyncButtonState("TrapMovementBtn", SharedRuntimeSettings.TrapMovementEnabled); SyncButtonState("ShowRoomNameBtn", SharedRuntimeSettings.ShowSceneLabel); SyncButtonState("ShowRoomSeedBtn", SharedRuntimeSettings.ShowSeedLabel); NativeButton cachedButton = GetCachedButton("RoomModeBtn"); if (cachedButton != null) { cachedButton.SetToggleIndex((SharedRuntimeSettings.RoomRandomizerMode == 1) ? 1 : 0); } NativeButton cachedButton2 = GetCachedButton("EnemyScaleRandomBtn"); if (cachedButton2 != null && ScaleRandomEnabledProp != null) { cachedButton2.SetToggleIndex(((bool)ScaleRandomEnabledProp.GetValue(null)) ? 1 : 0); } SyncButtonState("CompletionBtn", SharedRuntimeSettings.ForceCompletionDisplay); SyncButtonState("CrestTypeBtn", SharedRuntimeSettings.CrestRandomEnabled); SyncButtonState("SkillTypeBtn", SharedRuntimeSettings.SkillItemRandomEnabled); SyncButtonState("RelicTypeBtn", SharedRuntimeSettings.RelicRandomEnabled); bool value = GlobalConfig.AttackUp.Value; bool value2 = GlobalConfig.AttackLeft.Value; bool value3 = GlobalConfig.AttackRight.Value; SharedRuntimeSettings.AttackUp = value; SharedRuntimeSettings.AttackLeft = value2; SharedRuntimeSettings.AttackRight = value3; NativeButton cachedButton3 = GetCachedButton("UpBtn"); if (cachedButton3 != null) { cachedButton3.SetToggleIndex((!value) ? 1 : 0); } NativeButton cachedButton4 = GetCachedButton("LeftBtn"); if (cachedButton4 != null) { cachedButton4.SetToggleIndex((!value2) ? 1 : 0); } NativeButton cachedButton5 = GetCachedButton("RightBtn"); if (cachedButton5 != null) { cachedButton5.SetToggleIndex((!value3) ? 1 : 0); } NativeButton cachedButton6 = GetCachedButton("SilkHeartBtn"); if (cachedButton6 != null) { cachedButton6.SetToggleIndex(RoomRandomMode.IsPending ? 1 : 0); } SetSliderValue("ItemCountSlider", SharedRuntimeSettings.ItemCount); SetSliderValue("TotalSkillSlider", SharedRuntimeSettings.SkillTotal); SetSliderValue("VSlider", SharedRuntimeSettings.SkillVertical); SetSliderValue("HSlider", SharedRuntimeSettings.SkillHorizontal); SetSliderValue("SSlider", SharedRuntimeSettings.SkillSpecial); SetSliderValue("ASlider", SharedRuntimeSettings.SkillAttack); if (ScaleMinProp != null) { SetSliderValue("EnemyScaleMinSlider", (float)ScaleMinProp.GetValue(null)); } if (ScaleMaxProp != null) { SetSliderValue("EnemyScaleMaxSlider", (float)ScaleMaxProp.GetValue(null)); } SetOptionValue("SkillModeOption", SharedRuntimeSettings.UseTypeMode ? 1 : 0); SetOptionValue("ResetOption", SharedRuntimeSettings.ResetSeedWorld ? 1 : 0); NativeInput cachedInput = GetCachedInput("CurrencyFirstThresholdInput"); if (cachedInput != null) { cachedInput.SetText(SharedRuntimeSettings.CurrencyFirstThreshold.ToString()); } NativeInput cachedInput2 = GetCachedInput("CurrencySecondThresholdInput"); if (cachedInput2 != null) { cachedInput2.SetText(SharedRuntimeSettings.CurrencySecondThreshold.ToString()); } NativeInput cachedInput3 = GetCachedInput("SilkSpearPityInput"); if (cachedInput3 != null) { cachedInput3.SetText(SharedRuntimeSettings.SilkSpearPityCount.ToString()); } NativeLabel cachedLabel = GetCachedLabel("CurrentSeedValue"); if (cachedLabel != null) { cachedLabel.SetText(SharedRuntimeSettings.Seed.ToString()); } NativeButton cachedButton7 = GetCachedButton("TrapDifficultyBtn"); if (cachedButton7 != null) { int trapDifficulty = SharedRuntimeSettings.TrapDifficulty; if (trapDifficulty >= 0 && trapDifficulty < TrapDifficultyNames.Length) { cachedButton7.SetTitle(TrapDifficultyNames[trapDifficulty]); } } RefreshRepeatLimitInputs(); UpdateFullRandomUI(); UpdateCategoryButtonStates(); UpdateSlidersVisibility(); } private void SetSliderValue(string sliderName, float value) { NativeSlider cachedSlider = GetCachedSlider(sliderName); if (cachedSlider != null) { cachedSlider.SetValueWithoutNotify(value); } } private void SetOptionValue(string optName, int value) { NativeOption cachedOption = GetCachedOption(optName); if (cachedOption != null) { cachedOption.SetValueWithoutNotify(value); } } private void SyncButtonState(string buttonName, bool isEnabled) { NativeButton cachedButton = GetCachedButton(buttonName); if (cachedButton != null) { cachedButton.SetToggleIndex(isEnabled ? 1 : 0); } } private void Confirm() { if (_seedRolling) { Debug.LogWarning((object)"[MenuChanger] 种子尚未确定,禁止开始游戏"); return; } Plugin instance = Plugin.Instance; if ((Object)(object)instance != (Object)null) { instance.SetPendingOpeningSettings(SharedRuntimeSettings.UseTypeMode, SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack, SharedRuntimeSettings.ItemCount); } SilksongItemRandomizerAPI.ResetAllData(); PreGeneratedMap.Reset(); PreGeneratedMap.Initialize(); try { if (HKSilksong_RandomizerAPI.IsSceneRandomEnabled()) { int seed = SharedRuntimeSettings.Seed; HKSilksong_RandomizerAPI.RegenerateWithSeed(seed); Debug.Log((object)("[MenuChanger] 房间随机化已开启,连接已按种子 " + seed + " 生成")); } else { Debug.Log((object)"[MenuChanger] 房间随机化未开启,场景图走原生流程"); } } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 房间连接定档生成失败: " + ex.Message)); } StartingAbilityPickerAPI.SetEnemyRandomEnabled(SharedRuntimeSettings.EnemyRandomEnabled); SilksongItemRandomizerAPI.PrimeAllTemplates(); SkipToFirstAct.EnableSkip(); StartingAbilityPickerAPI.SaveAllSettingsToConfig(); UIManager.instance.StartNewGame(false, false); Hide(); if ((Object)(object)MenuChangerMod.Instance != (Object)null) { MenuChangerMod.Instance.StartDelayedFullApply(); } } private void ApplyVanillaSettings() { SharedRuntimeSettings.ItemRandomEnabled = false; SharedRuntimeSettings.CrestRandomEnabled = false; SharedRuntimeSettings.SkillItemRandomEnabled = false; SharedRuntimeSettings.RelicRandomEnabled = false; SharedRuntimeSettings.TrapEnabled = false; SharedRuntimeSettings.TrapMovementEnabled = false; SharedRuntimeSettings.SceneRandomEnabled = false; SharedRuntimeSettings.SkillTriggerEnabled = false; SharedRuntimeSettings.EnemyRandomEnabled = false; SharedRuntimeSettings.FullRandomMode = false; SharedRuntimeSettings.ResetSeedWorld = false; SilksongItemRandomizerAPI.SetEnabled(false); SilksongItemRandomizerAPI.SetCrestRandomEnabled(false); SilksongItemRandomizerAPI.SetSkillItemRandomEnabled(false); SilksongItemRandomizerAPI.SetRelicRandomEnabled(false); SilksongItemRandomizerAPI.SetTrapEnabled(false); SilksongItemRandomizerAPI.SetTrapMovementEnabled(false); HKSilksong_RandomizerAPI.SetEnabled(false); EnemyEnabledProp?.SetValue(null, false); StartingAbilityPickerAPI.SetFullRandomMode(false); StartingAbilityPickerAPI.SetResetSeedWorld(false); } private void StartGame(bool permaDeath) { if (_seedRolling) { Debug.LogWarning((object)"[MenuChanger] 种子尚未确定,禁止开始游戏"); return; } ApplyVanillaSettings(); Plugin instance = Plugin.Instance; if ((Object)(object)instance != (Object)null) { instance.SetPendingOpeningSettings(SharedRuntimeSettings.UseTypeMode, SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack, SharedRuntimeSettings.ItemCount); } StartingAbilityPickerAPI.SetEnemyRandomEnabled(SharedRuntimeSettings.EnemyRandomEnabled); SilksongItemRandomizerAPI.PrimeAllTemplates(); SkipToFirstAct.EnableSkip(); StartingAbilityPickerAPI.SaveAllSettingsToConfig(); UIManager.instance.StartNewGame(permaDeath, false); Hide(); if ((Object)(object)MenuChangerMod.Instance != (Object)null) { MenuChangerMod.Instance.StartDelayedFullApply(); } } public void RefreshPageList() { pageOrder = NativePage.AllInstances.Select((NativePage p) => ((Object)p.gameObject).name).ToList(); } public void ShowPage(string pageName) { if (!string.IsNullOrEmpty(pageName)) { UIManagerEx.ShowPage(pageName); UpdatePageIndicator(); } } public void UpdatePageIndicator() { if (pageIndicator == null) { return; } string currentShowingPageName = GetCurrentShowingPageName(); if (!string.IsNullOrEmpty(currentShowingPageName) && pageOrder.Count != 0) { int num = pageOrder.IndexOf(currentShowingPageName); if (num >= 0) { pageIndicator.SetText($"{num + 1}/{pageOrder.Count}"); pageIndicator.gameObject.SetActive(pageOrder.Count > 1); } } } public void SwitchPage(int delta) { if (pageOrder.Count != 0) { string currentShowingPageName = GetCurrentShowingPageName(); if (!string.IsNullOrEmpty(currentShowingPageName)) { int index = (pageOrder.IndexOf(currentShowingPageName) + delta + pageOrder.Count) % pageOrder.Count; ShowPage(pageOrder[index]); } } } private string GetCurrentShowingPageName() { foreach (NativePage allInstance in NativePage.AllInstances) { if (allInstance != null && allInstance.isShowing) { return ((Object)allInstance.gameObject).name; } } return null; } public void Show(NativePage fromPage = null) { parentPage = fromPage; RefreshAllValues(); root.SetActive(true); ((MonoBehaviour)uiManager).StartCoroutine(FadeIn()); if (pageOrder.Contains("Main")) { ShowPage("Main"); } else if (pageOrder.Count > 0) { ShowPage(pageOrder[0]); } } public void Hide() { ((MonoBehaviour)uiManager).StartCoroutine(FadeOut()); } private IEnumerator FadeIn() { canvasGroup.alpha = 0f; canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; while (canvasGroup.alpha < 1f) { CanvasGroup obj = canvasGroup; obj.alpha += Time.unscaledDeltaTime * 3f; yield return null; } canvasGroup.alpha = 1f; } private IEnumerator FadeOut() { canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; while (canvasGroup.alpha > 0f) { CanvasGroup obj = canvasGroup; obj.alpha -= Time.unscaledDeltaTime * 3f; yield return null; } canvasGroup.alpha = 0f; if ((Object)(object)root != (Object)null) { root.SetActive(false); } if (parentPage != null) { parentPage.Show(true); } } } [HarmonyPatch] public static class SkipToFirstAct { private static bool _shouldSkip = false; private static bool _skipTriggered = false; private static bool _tutorialRestorePending = false; private static bool _tutorialSkipped = false; private static readonly WaitForSeconds SkipInterval = new WaitForSeconds(0.2f); private static readonly MethodInfo SendHeroInPositionMethod = typeof(HeroController).GetMethod("SendHeroInPosition", BindingFlags.Instance | BindingFlags.NonPublic); private static Type _csmCachedType; private static readonly FieldInfo[] CsmFields = new FieldInfo[5]; private static void EnsureCsmFieldCache(Type type) { if (!(type == _csmCachedType)) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic; CsmFields[0] = type.GetField("musicCue", bindingAttr); CsmFields[1] = type.GetField("musicSnapshot", bindingAttr); CsmFields[2] = type.GetField("musicDelayTime", bindingAttr); CsmFields[3] = type.GetField("musicTransitionTime", bindingAttr); CsmFields[4] = type.GetField("atmosCue", bindingAttr); _csmCachedType = type; } } public static void EnableSkip() { _tutorialSkipped = false; if (!_shouldSkip) { _shouldSkip = true; _skipTriggered = false; SceneManager.sceneLoaded += OnSceneLoaded; Debug.Log((object)"[SkipToFirstAct] 已启用跳过开场模式"); } } public static void DisableSkip() { if (_shouldSkip) { _shouldSkip = false; SceneManager.sceneLoaded -= OnSceneLoaded; } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (!_shouldSkip) { return; } if (((Scene)(ref scene)).name != "Opening_Sequence" && ((Scene)(ref scene)).name != "Main_Menu") { if (((Scene)(ref scene)).name == "Tut_01" || ((Scene)(ref scene)).name == "tut_01") { _tutorialRestorePending = true; } else { GameManager instance = GameManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(RestoreSceneMusic()); } } } if (((Scene)(ref scene)).name == "Opening_Sequence") { if (!_skipTriggered) { _skipTriggered = true; Debug.Log((object)"[SkipToFirstAct] 检测到开场动画,开始跳过..."); GameManager instance2 = GameManager.instance; if ((Object)(object)instance2 == (Object)null) { _skipTriggered = false; } else { ((MonoBehaviour)instance2).StartCoroutine(SkipCutscenes()); } } } else { if ((!(((Scene)(ref scene)).name == "Tut_01") && !(((Scene)(ref scene)).name == "tut_01")) || _tutorialSkipped) { return; } GameManager instance3 = GameManager.instance; try { if ((Object)(object)instance3 != (Object)null && instance3.GetPlayerDataBool("bindCutscenePlayed")) { _tutorialSkipped = true; return; } } catch { } GameManager instance4 = GameManager.instance; if (!((Object)(object)instance4 == (Object)null)) { _tutorialSkipped = true; ((MonoBehaviour)instance4).StartCoroutine(SkipEntireTutorial()); } } } private static IEnumerator SkipCutscenes() { yield return null; GameManager gm = GameManager.instance; if ((Object)(object)gm == (Object)null) { Debug.LogError((object)"[SkipToFirstAct] GameManager 不可用"); yield break; } for (int i = 0; i < 5; i++) { gm.SkipCutscene(); yield return SkipInterval; } _skipTriggered = false; Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (!_tutorialSkipped && (name == "Tut_01" || name == "tut_01")) { _tutorialRestorePending = true; _tutorialSkipped = true; ((MonoBehaviour)gm).StartCoroutine(SkipEntireTutorial()); } } private static IEnumerator RestoreSceneMusic() { GameManager gm = null; for (int wait = 0; wait < 600; wait++) { gm = GameManager.instance; if ((Object)(object)gm != (Object)null && gm.HasFinishedEnteringScene && (Object)(object)gm.AudioManager != (Object)null) { break; } yield return null; } if ((Object)(object)gm == (Object)null || (Object)(object)gm.AudioManager == (Object)null) { Debug.LogWarning((object)"[SkipToFirstAct] 场景进入未完成/音频系统不可用,整体音乐恢复中止"); yield break; } yield return null; AudioManager audioManager = gm.AudioManager; bool flag = string.Equals(gm.GetSceneNameString(), "tut_01", StringComparison.OrdinalIgnoreCase); try { HeroController instance = HeroController.instance; if ((Object)(object)instance != (Object)null && !instance.isHeroInPosition) { bool flag2 = false; try { MethodInfo sendHeroInPositionMethod = SendHeroInPositionMethod; if (sendHeroInPositionMethod != null) { sendHeroInPositionMethod.Invoke(instance, new object[1] { true }); flag2 = true; } } catch (Exception ex) { Debug.LogWarning((object)("[SkipToFirstAct] SendHeroInPosition 反射调用失败,走字段兜底: " + ex.Message)); } if (!flag2) { instance.isHeroInPosition = true; } Debug.Log((object)"[SkipToFirstAct] HeroController 就位标记已置位(isHeroInPosition=true),解锁音频/相机全链"); } } catch (Exception ex2) { Debug.LogWarning((object)("[SkipToFirstAct] HeroController 就位恢复异常: " + ex2.Message)); } try { CameraController cameraCtrl = gm.cameraCtrl; if ((Object)(object)cameraCtrl != (Object)null && !cameraCtrl.HasBeenPositionedAtHero && !CameraController.IsPositioningCamera) { cameraCtrl.PositionToHero(true); Debug.Log((object)"[SkipToFirstAct] 相机未定位,主动触发 PositionToHero 解锁音频/相机链"); } } catch (Exception ex3) { Debug.LogWarning((object)("[SkipToFirstAct] 相机定位恢复异常: " + ex3.Message)); } try { if (AudioListener.pause) { AudioListener.pause = false; Debug.Log((object)"[SkipToFirstAct] AudioListener.pause 已复位为 false(Control FSM 静音演出残留)"); } } catch (Exception ex4) { Debug.LogWarning((object)("[SkipToFirstAct] AudioListener.pause 复位异常: " + ex4.Message)); } try { GameCameras instance2 = GameCameras.instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.forceCameraAspect != (Object)null) { instance2.forceCameraAspect.SetFovOffset(0f, 0f, (AnimationCurve)null); Debug.Log((object)"[SkipToFirstAct] 相机 FOV offset 已复位为 0"); } } catch (Exception ex5) { Debug.LogWarning((object)("[SkipToFirstAct] 相机 FOV 复位异常: " + ex5.Message)); } Plugin.BlackoutHide(); if (flag) { try { PlayMakerFSM[] array = Object.FindObjectsByType<PlayMakerFSM>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PlayMakerFSM val in array) { if ((Object)(object)val == (Object)null || val.FsmStates == null || !HasFsmState(val, "Moss Music Up")) { continue; } FsmState state = val.Fsm.GetState("Moss Music Up"); if (state == null || state.Actions == null) { continue; } for (int j = 0; j < state.Actions.Length; j++) { FsmStateAction obj = state.Actions[j]; ApplyMusicCue val2 = (ApplyMusicCue)(object)((obj is ApplyMusicCue) ? obj : null); if (val2 != null) { Object value = val2.musicCue.Value; MusicCue val3 = (MusicCue)(object)((value is MusicCue) ? value : null); if ((Object)(object)val3 != (Object)null) { val3.Preload(((Component)val).gameObject); audioManager.ApplyMusicCue(val3, 0f, 0f, false); Debug.Log((object)("[SkipToFirstAct] tut_01 教程 BGM 重放: " + ((Object)val3).name)); } continue; } FsmStateAction obj2 = state.Actions[j]; TransitionToAudioSnapshot val4 = (TransitionToAudioSnapshot)(object)((obj2 is TransitionToAudioSnapshot) ? obj2 : null); if (val4 != null) { Object value2 = val4.snapshot.Value; AudioMixerSnapshot val5 = (AudioMixerSnapshot)(object)((value2 is AudioMixerSnapshot) ? value2 : null); if (val5 != null) { audioManager.ApplyMusicSnapshot(val5, 0f, val4.transitionTime.Value); Debug.Log((object)("[SkipToFirstAct] tut_01 音乐快照恢复: " + ((Object)val5).name)); } } } break; } } catch (Exception ex6) { Debug.LogWarning((object)("[SkipToFirstAct] tut_01 教程 BGM 重放异常: " + ex6.Message)); } } try { CustomSceneManager[] array2 = Object.FindObjectsByType<CustomSceneManager>((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array2 != null && array2.Length != 0) { CustomSceneManager val6 = array2[0]; EnsureCsmFieldCache(((object)val6).GetType()); object? obj3 = CsmFields[0]?.GetValue(val6); MusicCue val7 = (MusicCue)((obj3 is MusicCue) ? obj3 : null); object? obj4 = CsmFields[1]?.GetValue(val6); AudioMixerSnapshot val8 = (AudioMixerSnapshot)((obj4 is AudioMixerSnapshot) ? obj4 : null); float num = ((CsmFields[2]?.GetValue(val6) is float num2) ? num2 : 0f); float num3 = ((CsmFields[3]?.GetValue(val6) is float num4) ? num4 : 0f); if ((Object)(object)val7 != (Object)null && (Object)(object)audioManager.CurrentMusicCue == (Object)null) { val7.Preload(((Component)val6).gameObject); audioManager.ApplyMusicCue(val7, num, num3, false); Debug.Log((object)("[SkipToFirstAct] 场景音乐配置恢复: cue=" + ((Object)val7).name)); } if ((Object)(object)val8 != (Object)null) { audioManager.ApplyMusicSnapshot(val8, num, num3); } object? obj5 = CsmFields[4]?.GetValue(val6); AtmosCue val9 = (AtmosCue)((obj5 is AtmosCue) ? obj5 : null); if ((Object)(object)val9 != (Object)null) { audioManager.ClearAtmosOverrides(); audioManager.ApplyAtmosCue(val9, val6.transitionTime, true); } if ((Object)(object)val6.atmosSnapshot != (Object)null) { AudioManager.TransitionToAtmosOverride(val6.atmosSnapshot, val6.transitionTime); } } } catch (Exception ex7) { Debug.LogWarning((object)("[SkipToFirstAct] 场景音乐配置恢复异常: " + ex7.Message)); } try { MusicRegion[] array3 = Object.FindObjectsByType<MusicRegion>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MusicRegion val10 in array3) { if (!((Object)(object)val10 == (Object)null)) { if ((Object)(object)val10.enterMusicSnapshot != (Object)null) { audioManager.ApplyMusicSnapshot(val10.enterMusicSnapshot, 0f, val10.enterTransitionTime); } if ((Object)(object)val10.enterMusicCue != (Object)null && (Object)(object)audioManager.CurrentMusicCue == (Object)null) { val10.enterMusicCue.Preload(((Component)val10).gameObject); audioManager.ApplyMusicCue(val10.enterMusicCue, 0f, 0f, false); Debug.Log((object)("[SkipToFirstAct] 音乐区域恢复: " + ((Object)val10).name)); } } } } catch (Exception ex8) { Debug.LogWarning((object)("[SkipToFirstAct] 音乐区域恢复异常: " + ex8.Message)); } Debug.Log((object)"[SkipToFirstAct] 整体音乐恢复完成"); } private static IEnumerator SkipEntireTutorial() { yield return null; GameManager instance = GameManager.instance; if ((Object)(object)instance == (Object)null) { Debug.LogError((object)"[SkipToFirstAct] GameManager 不可用,教程跳过中止"); yield break; } try { instance.SetPlayerDataBool("bindCutscenePlayed", true); instance.SetPlayerDataBool("completedTutorial", true); instance.SetPlayerDataBool("enteredTutorialFirstTime", true); instance.SetPlayerDataBool("entered_Tut01b", true); } catch (Exception arg) { Debug.LogError((object)$"[SkipToFirstAct] 写入教程标志失败: {arg}"); } PlayMakerFSM val = null; PlayMakerFSM val2 = null; try { PlayMakerFSM[] array = Object.FindObjectsByType<PlayMakerFSM>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null) && !(array[i].FsmName != "Control")) { if ((Object)(object)val == (Object)null && HasFsmState(array[i], "Hornet Down")) { val = array[i]; } else if ((Object)(object)val2 == (Object)null && HasFsmState(array[i], "Weak Start")) { val2 = array[i]; } } } if ((Object)(object)val != (Object)null && HasFsmState(val, "End")) { val.SetState("End"); } if ((Object)(object)val2 != (Object)null && HasFsmState(val2, "Resume")) { val2.SetState("Resume"); } } catch (Exception ex) { Debug.LogWarning((object)("[SkipToFirstAct] FSM 瞬跳异常: " + ex.Message)); } try { Color colour = ScreenFaderUtils.GetColour(); Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); ScreenFaderUtils.Fade(colour, val3, 0.5f); Plugin.BlackoutHide(); } catch (Exception ex2) { Debug.LogWarning((object)("[SkipToFirstAct] 清除黑幕异常: " + ex2.Message)); } try { if ((Object)(object)HeroController.instance != (Object)null) { HeroController.instance.RegainControl(); } } catch (Exception ex3) { Debug.LogWarning((object)("[SkipToFirstAct] RegainControl 异常: " + ex3.Message)); } try { if ((Object)(object)HeroController.instance != (Object)null) { HeroController.instance.RefillHealthToMax(); } } catch (Exception ex4) { Debug.LogWarning((object)("[SkipToFirstAct] 回满血异常: " + ex4.Message)); } try { GameCameras instance2 = GameCameras.instance; if ((Object)(object)instance2 != (Object)null) { EventRegister.SendEvent("SHOW HP", (GameObject)null); EventRegister.SendEvent("SPOOL APPEAR", (GameObject)null); try { SilkSpool silkSpool = instance2.silkSpool; if ((Object)(object)silkSpool != (Object)null) { silkSpool.DrawSpool(); silkSpool.RefreshSilk(); } } catch (Exception ex5) { Debug.LogWarning((object)("[SkipToFirstAct] 丝卷初始化异常: " + ex5.Message)); } try { BindOrbHudFrame[] array2 = Object.FindObjectsByType<BindOrbHudFrame>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int j = 0; j < array2.Length; j++) { array2[j].AlreadyAppeared(); } } catch (Exception ex6) { Debug.LogWarning((object)("[SkipToFirstAct] 纹章框初始化异常: " + ex6.Message)); } EventRegister.SendEvent("HEALTH UPDATE", (GameObject)null); EventRegister.SendEvent("HERO HEALED TO MAX", (GameObject)null); EventRegister.SendEvent("TOOL EQUIPS CHANGED", (GameObject)null); EventRegister.SendEvent("POST TOOL EQUIPS CHANGED", (GameObject)null); instance2.HUDIn(); HudGlobalHide.IsHidden = false; HudScalePositioner.IsReduced = false; if (!instance2.IsHudVisible) { Debug.LogWarning((object)"[SkipToFirstAct] HUD 初始化完成但 IsHudVisible 仍为 false"); } } } catch (Exception ex7) { Debug.LogWarning((object)("[SkipToFirstAct] HUD 初始化异常: " + ex7.Message)); } if (_tutorialRestorePending) { _tutorialRestorePending = false; ((MonoBehaviour)instance).StartCoroutine(RestoreSceneMusic()); } Debug.Log((object)"[SkipToFirstAct] 教程跳过完成,玩家原地留在 tut_01"); } private static bool HasFsmState(PlayMakerFSM fsm, string stateName) { if ((Object)(object)fsm == (Object)null || fsm.FsmStates == null) { return false; } for (int i = 0; i < fsm.FsmStates.Length; i++) { if (fsm.FsmStates[i] != null && fsm.FsmStates[i].Name == stateName) { return true; } } return false; } } public static class GameSeedValidator { private static PharloomCore _core; private static bool _initialized; private static string _lastError; private const string ConnectionsFileName = "roomrando_connections.txt"; private static bool _connEnabled; private static string _connSig; private static bool _connSynced; public static string LastError => _lastError; public static bool IsReady { get { EnsureInit(); return _core != null; } } private static void EnsureInit() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; try { _core = new PharloomCore(true); Debug.Log((object)("[MenuChanger] GameSeedValidator 初始化成功: " + _core.Regions.Length + " 区域")); } catch (Exception ex) { _lastError = ex.Message; Debug.LogWarning((object)("[MenuChanger] GameSeedValidator 初始化失败: " + ex)); } } public static bool IsSimulatedLive(int seed) { EnsureInit(); if (_core == null) { return false; } try { SyncSceneConnections(); return _core.IsSeedLive(seed, IsFullRandomEnabled()); } catch (Exception ex) { _lastError = ex.Message; return false; } } public static int ScoreSeed(int seed) { EnsureInit(); if (_core == null) { Debug.LogWarning((object)("[MenuChanger] ScoreSeed: PharloomCore 初始化失败: " + _lastError)); return int.MaxValue; } try { SyncSceneConnections(); return _core.ScoreSeed(seed, IsFullRandomEnabled()); } catch (Exception ex) { _lastError = ex.Message; Debug.LogWarning((object)("[MenuChanger] ScoreSeed(" + seed + ") 评分异常: " + ex)); return int.MaxValue; } } private static bool IsFullRandomEnabled() { try { return SharedRuntimeSettings.FullRandomMode; } catch { return false; } } public static bool IsGameLive(int seed) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Invalid comparison between Unknown and I4 EnsureInit(); if (_core == null) { return false; } try { SilksongItemRandomizerAPI.SetSeed(seed); PreGeneratedMap.Reset(); PreGeneratedMap.Initialize(); Dictionary<string, string> preGeneratedMappings = Plugin.SaveData.PreGeneratedMappings; if (preGeneratedMappings == null || preGeneratedMappings.Count == 0) { return false; } SyncSceneConnections(); Dictionary<ItemSlot, Item> dictionary = new Dictionary<ItemSlot, Item>(); int num = 0; int num2 = 0; foreach (KeyValuePair<string, string> item in preGeneratedMappings) { Region val = ResolveRegion(item.Key); if (val == null) { num++; continue; } Item val2 = ParseGameItem(item.Value); if (val2 == null) { num2++; continue; } dictionary[new ItemSlot { Id = item.Key, Region = val, AccessGate = _core.FindPointGate(item.Key) }] = val2; } SeedVerdict val3 = _core.Detector.Evaluate((IReadOnlyDictionary<ItemSlot, Item>)dictionary, IsFullRandomEnabled()); if (val3.IsDead) { int count = preGeneratedMappings.Count; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[GameSeedValidator] 种子 ").Append(seed).Append(" 真实映射判定为死种。总键=") .Append(count) .Append(", 区域解析忽略=") .Append(num) .Append(", 奖励解析失败=") .Append(num2) .Append(", 入assignment=") .Append(dictionary.Count) .Append(", 死因=") .Append(val3.Reason ?? "(无)") .Append(", 未达区域=") .Append(val3.UnreachedRegions.Count) .Append(" -> ") .Append(string.Join(",", val3.UnreachedRegions)) .Append(", 阻塞点位=") .Append(val3.BlockedSlotIds.Count); List<string> list = new List<string>(); foreach (KeyValuePair<string, string> item2 in preGeneratedMappings) { if (ResolveRegion(item2.Key) != null) { continue; } Item val4 = ParseGameItem(item2.Value); if (val4 != null) { if ((int)val4.Kind == 0 || (int)val4.Kind == 1) { list.Add(item2.Key + "=" + item2.Value); } if (list.Count >= 8) { break; } } } if (list.Count > 0) { stringBuilder.Append(" [忽略键含能力/权限]: ").Append(string.Join(",", list)); } if (num > 0 || num2 > 0) { List<string> list2 = new List<string>(); List<string> list3 = new List<string>(); foreach (KeyValuePair<string, string> item3 in preGeneratedMappings) { if (list2.Count < 8 && ResolveRegion(item3.Key) == null) { list2.Add(item3.Key); } else if (list3.Count < 8 && ResolveRegion(item3.Key) != null && ParseGameItem(item3.Value) == null) { list3.Add(item3.Key + "=" + item3.Value); } if (list2.Count >= 8 && list3.Count >= 8) { break; } } if (list2.Count > 0) { stringBuilder.Append(" [区域解析忽略示例]: ").Append(string.Join(",", list2)); } if (list3.Count > 0) { stringBuilder.Append(" [奖励解析失败示例]: ").Append(string.Join(",", list3)); } } Debug.LogWarning((object)stringBuilder.ToString()); } return !val3.IsDead; } catch (Exception ex) { _lastError = ex.Message; Debug.LogWarning((object)("[MenuChanger] 验证种子 " + seed + " 失败: " + ex)); return false; } } public static int NextDynamicSeed(long baseTicks, int tickCount, int index) { int num = ((int)(baseTicks + index) ^ tickCount) & 0x7FFFFFFF; if (num > 0) { return num; } return 1; } public static int FindLiveSeed() { EnsureInit(); if (_core == null) { return -1; } long ticks = DateTime.UtcNow.Ticks; int tickCount = Environment.TickCount; for (int i = 0; i < 2000; i++) { int num = NextDynamicSeed(ticks, tickCount, i); if (IsSimulatedLive(num) && IsGameLive(num)) { return num; } } return -1; } private static void SyncSceneConnections() { if (_core == null) { return; } bool flag = false; try { flag = HKSilksong_RandomizerAPI.IsSceneRandomEnabled(); } catch (Exception ex) { Debug.LogWarning((object)("[MenuChanger] 读取房间随机化开关失败: " + ex.Message)); } string text = Path.Combine(Paths.PluginPath, "roomrando_connections.txt"); bool flag2 = flag && File.Exists(text); string text2 = null; if (flag2) { FileInfo fileInfo = new FileInfo(text); text2 = fileInfo.LastWriteTimeUtc.Ticks + ":" + fileInfo.Length; } if (_connSynced && flag == _connEnabled && text2 == _connSig) { return; } _connSynced = true; _connEnabled = flag; _connSig = text2; try { if (!flag2) { _core.RestoreNativeSceneConnections(); Debug.Log((object)"[MenuChanger] 场景图: 原生连接(房间随机化未启用或连接文件缺失)"); } else { _core.MergeSceneConnections((IEnumerable<string>)File.ReadAllLines(text)); Debug.Log((object)"[MenuChanger] 场景图: 随机连接已合并(txt 覆盖的出口用随机目标,其余走原生)"); } } catch (Exception ex2) { _lastError = ex2.Message; _connSynced = false; Debug.LogWarning((object)("[MenuChanger] 场景连接切换失败,回退原生连接: " + ex2.Message)); try { _core.RestoreNativeSceneConnections(); } catch { } } } private static Region ResolveRegion(string key) { string value = null; if (key.StartsWith("lore:") || key.StartsWith("event:")) { string[] array = key.Split(new char[1] { ':' }); if (array.Length >= 2) { value = array[1]; } } else if (key.StartsWith("shop:")) { value = key.Substring("shop:".Length).Split(new char[1] { '_' })[0]; } else if (key.StartsWith("check:")) { PreGeneratedMap.CheckSceneMap.TryGetValue(key, out value); } else if (key.StartsWith("heart:") || key.StartsWith("spool:") || key.StartsWith("moss:") || key.StartsWith("flower:")) { value = key.Substring(key.IndexOf(':') + 1); } else if (key.StartsWith("flea:")) { string text = key.Substring("flea:".Length); value = ((!int.TryParse(text, out var result)) ? text : FleaSceneMap.IndexToScene(result)); } else { string[] array2 = key.Split(new char[1] { '_' }); if (array2.Length < 4) { return null; } if (!float.TryParse(array2[^1], out var result2)) { return null; } if (!float.TryParse(array2[^2], out result2)) { return null; } if (!float.TryParse(array2[^3], out result2)) { return null; } value = string.Join("_", array2, 0, array2.Length - 3); } if (string.IsNullOrEmpty(value)) { return null; } return _core.Resolver.Resolve(value); } private static Item ParseGameItem(string reward) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown if (string.IsNullOrEmpty(reward) || !reward.StartsWith("reward:")) { return null; } string text = reward.Substring("reward:".Length); if (text.StartsWith("perm:")) { string text2 = text.Substring("perm:".Length); if (text2.EndsWith("_R")) { return BuildPermission(text2.Substring(0, text2.Length - 2), (PermissionSide)1); } if (text2.EndsWith("_L")) { return BuildPermission(text2.Substring(0, text2.Length - 2), (PermissionSide)0); } return BuildAttackAbility(text); } if (!text.StartsWith("virt:")) { foreach (Ability value in AbilitiesData.All.Values) { if (value.Key == text) { return new Item { Kind = (ItemKind)0, AbilityId = value.Id }; } } return new Item { Kind = (ItemKind)2, ItemName = text }; } return new Item { Kind = (ItemKind)4, ItemName = text.Substring("virt:".Length) }; } private static Item BuildAttackAbility(string id) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown foreach (Ability value in AbilitiesData.All.Values) { if (value.Key == id) { return new Item { Kind = (ItemKind)0, AbilityId = value.Id }; } } return null; } private static Item BuildPermission(string skillField, PermissionSide side) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_004b: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Invalid comparison between Unknown and I4 //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) switch (skillField) { case "upward": return new Item { Kind = (ItemKind)0, AbilityId = (AbilityId)18 }; case "left": return new Item { Kind = (ItemKind)0, AbilityId = (AbilityId)19 }; case "right": return new Item { Kind = (ItemKind)0, AbilityId = (AbilityId)20 }; case "heal": return new Item { Kind = (ItemKind)0, AbilityId = (AbilityId)21 }; default: { string text = (skillField.StartsWith("has") ? skillField.Substring(3) : skillField); string permissionId = text + "_" + (((int)side == 1) ? "R" : "L"); AbilityId abilityId; switch (text) { case "Dash": abilityId = (AbilityId)1; break; case "HarpoonDash": abilityId = (AbilityId)6; break; case "Brolly": abilityId = (AbilityId)3; break; case "Walljump": abilityId = (AbilityId)5; break; case "SuperJump": abilityId = (AbilityId)4; break; default: return null; } return new Item { Kind = (ItemKind)1, PermissionId = permissionId, AbilityId = abilityId }; } } } } }
BepInEx/plugins/NativeUIMaker.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using GlobalEnums; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 NativeUIMaker { [Serializable] public class UIControlConfig { public string name; public string type; public string page; public Vector2 position; public Vector2 size; public string title; public string description; public string[] toggleTexts; public int toggleIndex; public string labelText; public int fontSize; public Color color; public float minValue; public float maxValue; public float value; public bool wholeNumbers; public int optionIndex; public string[] options; public int direction; public bool playAnim; public bool clickable; public bool draggable; public string inputText; public string placeholderText; public int style; public Vector2 iconOffset; public Vector2 titleOffset; public Vector2 descOffset; public float sliderXOffset; public float sliderWidth; public float labelXOffset; public float valueXOffset; } [Serializable] public class ConfigData { public List<UIControlConfig> controls = new List<UIControlConfig>(); } internal static class SlimJson { internal static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { Formatting = (Formatting)1, NullValueHandling = (NullValueHandling)1, DefaultValueHandling = (DefaultValueHandling)1 }; } public class DebugWindow : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Predicate<NativeButton> <>9__189_0; public static Predicate<NativeLabel> <>9__189_1; public static Predicate<NativeSlider> <>9__189_2; public static Predicate<NativeOption> <>9__189_3; public static Predicate<NativeArrow> <>9__189_4; public static Predicate<NativeInput> <>9__189_5; public static Func<NativePage, bool> <>9__208_0; public static Func<string, string> <>9__211_0; public static UnityAction <>9__211_1; public static UnityAction <>9__216_0; public static Func<string, string> <>9__234_0; public static Func<string, string> <>9__237_0; public static UnityAction <>9__248_0; public static Predicate<NativeButton> <>9__250_0; public static Predicate<NativeLabel> <>9__250_1; public static Predicate<NativeSlider> <>9__250_2; public static Predicate<NativeOption> <>9__250_3; public static Predicate<NativeArrow> <>9__250_4; public static Predicate<NativeInput> <>9__250_5; public static Predicate<NativeButton> <>9__253_0; public static UnityAction <>9__256_7; internal bool <CleanAllExternalLists>b__189_0(NativeButton b) { if (b != null) { return (Object)(object)b.gameObject == (Object)null; } return true; } internal bool <CleanAllExternalLists>b__189_1(NativeLabel l) { if (l != null) { return (Object)(object)l.gameObject == (Object)null; } return true; } internal bool <CleanAllExternalLists>b__189_2(NativeSlider s) { if (s != null) { return (Object)(object)s.gameObject == (Object)null; } return true; } internal bool <CleanAllExternalLists>b__189_3(NativeOption o) { if (o != null) { return (Object)(object)o.gameObject == (Object)null; } return true; } internal bool <CleanAllExternalLists>b__189_4(NativeArrow a) { if (a != null) { return (Object)(object)a.gameObject == (Object)null; } return true; } internal bool <CleanAllExternalLists>b__189_5(NativeInput i) { if (i != null) { return (Object)(object)i.gameObject == (Object)null; } return true; } internal bool <RefreshPageDropdownList>b__208_0(NativePage p) { return p != null; } internal string <DrawCreateButtonSection>b__211_0(string s) { return s.Trim(); } internal void <DrawCreateButtonSection>b__211_1() { Debug.Log((object)UILocale.Get("按钮被点击")); } internal void <CreateArrow>b__216_0() { Debug.Log((object)UILocale.Get("箭头被点击")); } internal string <DrawButtonEditor>b__234_0(string s) { return s.Trim(); } internal string <DrawOptionEditor>b__237_0(string s) { return s.Trim(); } internal void <ApplyConfigToControlInPage>b__248_0() { Debug.Log((object)UILocale.Get("箭头被点击")); } internal bool <CleanInvalidControls>b__250_0(NativeButton b) { if (b != null) { return (Object)(object)b.gameObject == (Object)null; } return true; } internal bool <CleanInvalidControls>b__250_1(NativeLabel l) { if (l != null) { return (Object)(object)l.gameObject == (Object)null; } return true; } internal bool <CleanInvalidControls>b__250_2(NativeSlider s) { if (s != null) { return (Object)(object)s.gameObject == (Object)null; } return true; } internal bool <CleanInvalidControls>b__250_3(NativeOption o) { if (o != null) { return (Object)(object)o.gameObject == (Object)null; } return true; } internal bool <CleanInvalidControls>b__250_4(NativeArrow a) { if (a != null) { return (Object)(object)a.gameObject == (Object)null; } return true; } internal bool <CleanInvalidControls>b__250_5(NativeInput i) { if (i != null) { return (Object)(object)i.gameObject == (Object)null; } return true; } internal bool <SaveConfigToFile>b__253_0(NativeButton btn) { <>c__DisplayClass253_0 CS$<>8__locals1 = new <>c__DisplayClass253_0 { btn = btn }; return NativeArrow.AllInstances.Any((NativeArrow arr) => arr != null && (Object)(object)arr.gameObject == (Object)(object)CS$<>8__locals1.btn.gameObject); } internal void <LoadConfigFromFile>b__256_7() { Debug.Log((object)UILocale.Get("箭头被点击")); } } [CompilerGenerated] private sealed class <>c__DisplayClass253_0 { public NativeButton btn; internal bool <SaveConfigToFile>b__1(NativeArrow arr) { if (arr != null) { return (Object)(object)arr.gameObject == (Object)(object)btn.gameObject; } return false; } } private static DebugWindow _instance; private Rect _windowRect = new Rect(50f, 50f, 800f, 1500f); private Vector2 _scrollPos; private bool _showWindow = true; private int _selectedTab; private HashSet<GameObject> _arrowGameObjectSet = new HashSet<GameObject>(); private HashSet<NativeButton> _localButtonSet = new HashSet<NativeButton>(); private HashSet<NativeLabel> _localLabelSet = new HashSet<NativeLabel>(); private HashSet<NativeSlider> _localSliderSet = new HashSet<NativeSlider>(); private HashSet<NativeOption> _localOptionSet = new HashSet<NativeOption>(); private HashSet<NativeArrow> _localArrowSet = new HashSet<NativeArrow>(); private HashSet<NativeInput> _localInputSet = new HashSet<NativeInput>(); private object _selectedControl; private string _editTitle = ""; private string _editDesc = ""; private Vector2 _editPos = Vector2.zero; private Vector2 _editSize = Vector2.zero; private string _editLabelText = ""; private int _editFontSize = 30; private Color _editColor = Color.white; private float _editSliderMin; private float _editSliderMax; private float _editSliderValue; private bool _editSliderWhole; private string _editSliderLabel = ""; private float _editSliderXOffset; private float _editSliderWidth; private float _editLabelXOffset; private float _editValueXOffset; private string _editOptionLabel = ""; private string _editOptionDesc = ""; private string[] _editOptionOptions; private int _editOptionIndex; private int _editArrowDirection; private bool _editArrowPlayAnim; private bool _editArrowClickable; private bool _editArrowDraggable; private string _editInputText = ""; private string _editInputPlaceholder = ""; private string _editToggleTextsInput = ""; private Vector2 _editIconOffset = Vector2.zero; private Vector2 _editTitleOffset = Vector2.zero; private Vector2 _editDescOffset = Vector2.zero; private string _strPosX = "0"; private string _strPosY = "0"; private string _strSizeW = "0"; private string _strSizeH = "0"; private string _strIconOffX = "0"; private string _strIconOffY = "0"; private string _strTitleOffX = "0"; private string _strTitleOffY = "0"; private string _strDescOffX = "0"; private string _strDescOffY = "0"; private string _strFontSize = "30"; private string _strColor = "1.00,1.00,1.00"; private string _lastParsedColor = ""; private string _strSliderMin = "0"; private string _strSliderMax = "100"; private string _strSliderValue = "0"; private string _strSliderXOff = "0"; private string _strSliderWidth = "0"; private string _strLabelXOff = "0"; private string _strValueXOff = "0"; private List<NativeButton> _allButtons = new List<NativeButton>(); private List<NativeLabel> _allLabels = new List<NativeLabel>(); private List<NativeSlider> _allSliders = new List<NativeSlider>(); private List<NativeOption> _allOptions = new List<NativeOption>(); private List<NativeArrow> _allArrows = new List<NativeArrow>(); private List<NativeInput> _allInputs = new List<NativeInput>(); private ButtonStyle _selectedCreateStyle; private string[] _styleNames = new string[3] { "图标按钮", "纯文字按钮", "小型按钮" }; private string _toggleTextsInput = "选项1,选项2,选项3"; private string _iconPathInput = ""; private NativePage _selectedCreateTargetPage; private string[] _pageNamesForDropdown = new string[0]; private int _selectedPageDropdownIndex; private int _pageDropdownVersion = -1; private List<NativeButton> _externalButtons = new List<NativeButton>(); private List<NativeLabel> _externalLabels = new List<NativeLabel>(); private List<NativeSlider> _externalSliders = new List<NativeSlider>(); private List<NativeOption> _externalOptions = new List<NativeOption>(); private List<NativeArrow> _externalArrows = new List<NativeArrow>(); private List<NativeInput> _externalInputs = new List<NativeInput>(); private bool _externalScanned; private NativePage _selectedPage; private List<UIControlConfig> _pageControlsCache = new List<UIControlConfig>(); private bool _cachedIsChinese; private bool _localeCacheValid; private string _locApplyChanges; private string _locDeleteControl; private string _locDestroyed; private string _locNoSelection; private string _locDraggable; private string _locHideWindow; private string _locLocal; private string _locExternal; private string _locPageMgmt; private string _locTitle; private string _locDesc; private string _locPosXY; private string _locSizeWH; private string _locApplyIcon; private string _locApplyTitle; private string _locApplyDesc; private string _locText; private string _locFontSize; private string _locColorRGB; private string _locLabel; private string _locSliderXOff; private string _locSliderWidth; private string _locLabelXOff; private string _locValueXOff; private string _locMin; private string _locMax; private string _locIntStep; private string _locOptions; private string _locSelected; private string _locPrev; private string _locNext; private string _locDir; private string _locLeft; private string _locRight; private string _locUp; private string _locDown; private string _locFlash; private string _locClickable; private string _locPlaceholder; private string _locEnter; private string _locScanExternal; private string _locSaveConfig; private string _locLoadConfig; private string _locClickScanHint; private string _locExtBtns; private string _locExtLabels; private string _locExtSliders; private string _locExtOptions; private string _locExtArrows; private string _locExtInputs; private string _locPages; private string _locSavePage; private string _locLoadPage; private string _locRefresh; private string _locPageControls; private string _locPos; private string _locTarget; private string _locGlobalCanvas; private string _locGlobal; private string _locCurr; private string _locCreateBtn; private string _locCreateLabel; private string _locCreateSlider; private string _locCreateOption; private string _locCreateArrow; private string _locCreateInput; private string _locStyle; private string _locIcon; private string _locTextBtn; private string _locSmall; private string _locIconPath; private string _locToggleTexts; private string _locSetToggleTexts; private string _locApplyToggle; private string _locNewBtn; private string _locNewLabel; private string _locNewSlider; private string _locNewOpt; private string _locDescText; private string _locDescTextLabel; private string _locArrowClicked; private string _locClicked; private string _locEditButton; private string _locEditLabel; private string _locEditSlider; private string _locEditOption; private string _locEditArrow; private string _locEditInput; private string _locIconOffset; private string _locTitleOffset; private string _locDescOffset; private string _locCurrentValue; private string _locTextContent; private string _locWindowTitle; private string _locAuto; private string _locPinToPage; private const int EXTERNAL_CLEAN_INTERVAL = 30; private int _externalCleanFrameCounter; private static bool _tempDragEnabled; private static GameObject _tempDragTarget; public static DebugWindow Instance => _instance; private string PluginDirectory => NativeUIMakerMod.PluginDirectory; public static GameObject CurrentlySelectedForDrag { get; private set; } public static bool TempDragEnabled => _tempDragEnabled; public static GameObject TempDragTarget => _tempDragTarget; private void RefreshLocaleCache() { _locApplyChanges = UILocale.Get("应用更改"); _locDeleteControl = UILocale.Get("删除此控件"); _locDestroyed = UILocale.Get("控件已被销毁"); _locNoSelection = UILocale.Get("未选中任何控件"); _locDraggable = UILocale.Get("允许拖拽 (按住鼠标左键拖动)"); _locHideWindow = UILocale.Get("隐藏窗口"); _locLocal = UILocale.Get("本地控件"); _locExternal = UILocale.Get("外部控件"); _locPageMgmt = UILocale.Get("页面管理"); _locTitle = UILocale.Get("标题:"); _locDesc = UILocale.Get("描述:"); _locPosXY = UILocale.Get("位置 (x, y):"); _locSizeWH = UILocale.Get("尺寸 (宽, 高):"); _locApplyIcon = UILocale.Get("应用图标偏移"); _locApplyTitle = UILocale.Get("应用标题偏移"); _locApplyDesc = UILocale.Get("应用描述偏移"); _locText = UILocale.Get("文本:"); _locFontSize = UILocale.Get("字体大小:"); _locColorRGB = UILocale.Get("颜色 (R,G,B):"); _locLabel = UILocale.Get("标签:"); _locSliderXOff = UILocale.Get("滑块 X 偏移:"); _locSliderWidth = UILocale.Get("滑块宽度 (0=原生):"); _locLabelXOff = UILocale.Get("标签 X 偏移:"); _locValueXOff = UILocale.Get("数值 X 偏移:"); _locMin = UILocale.Get("最小值: {0}"); _locMax = UILocale.Get("最大值: {0}"); _locIntStep = UILocale.Get("整数步进"); _locOptions = UILocale.Get("选项列表 (用逗号分隔):"); _locSelected = UILocale.Get("当前选中: {0} (索引 {1})"); _locPrev = UILocale.Get("上一个"); _locNext = UILocale.Get("下一个"); _locDir = UILocale.Get("方向:"); _locLeft = UILocale.Get("左"); _locRight = UILocale.Get("右"); _locUp = UILocale.Get("上"); _locDown = UILocale.Get("下"); _locFlash = UILocale.Get("播放动画 (闪烁)"); _locClickable = UILocale.Get("可点击 (添加按钮)"); _locPlaceholder = UILocale.Get("占位符:"); _locEnter = UILocale.Get("输入..."); _locScanExternal = UILocale.Get("扫描外部控件"); _locSaveConfig = UILocale.Get("保存配置"); _locLoadConfig = UILocale.Get("加载配置"); _locClickScanHint = UILocale.Get("点击“扫描外部控件”以发现其他模组创建的UI元素。"); _locExtBtns = UILocale.Get("外部按钮"); _locExtLabels = UILocale.Get("外部标签"); _locExtSliders = UILocale.Get("外部滑块"); _locExtOptions = UILocale.Get("外部选项行"); _locExtArrows = UILocale.Get("外部箭头"); _locExtInputs = UILocale.Get("外部输入框"); _locPages = UILocale.Get("可用页面:"); _locSavePage = UILocale.Get("保存页面配置"); _locLoadPage = UILocale.Get("加载页面配置"); _locRefresh = UILocale.Get("刷新"); _locPageControls = UILocale.Get("页面内控件列表:"); _locPos = UILocale.Get("位置"); _locTarget = UILocale.Get("创建目标:"); _locGlobalCanvas = UILocale.Get("全局画布 (独立于页面)"); _locGlobal = UILocale.Get("全局画布"); _locCurr = UILocale.Get("当前:"); _locCreateBtn = UILocale.Get("=== 创建新按钮 ==="); _locStyle = UILocale.Get("选择按钮样式:"); _locIcon = UILocale.Get("图标按钮"); _locTextBtn = UILocale.Get("纯文字按钮"); _locSmall = UILocale.Get("小型按钮"); _locIconPath = UILocale.Get("图标文件路径 (绝对或相对路径,留空则不设置):"); _locToggleTexts = UILocale.Get("切换文字序列(逗号分隔):"); _locSetToggleTexts = UILocale.Get("设置切换文字序列(逗号分隔):"); _locApplyToggle = UILocale.Get("应用切换序列"); _locNewBtn = UILocale.Get("新按钮"); _locNewLabel = UILocale.Get("新标签"); _locNewSlider = UILocale.Get("新滑块"); _locNewOpt = UILocale.Get("新选项"); _locDescText = UILocale.Get("这是描述文字"); _locDescTextLabel = UILocale.Get("可编辑描述"); _locArrowClicked = UILocale.Get("箭头被点击"); _locClicked = UILocale.Get("按钮被点击"); _locEditButton = UILocale.Get("编辑按钮: {0}"); _locEditLabel = UILocale.Get("编辑标签: {0}"); _locEditSlider = UILocale.Get("编辑滑块: {0}"); _locEditOption = UILocale.Get("编辑选项行: {0}"); _locEditArrow = UILocale.Get("编辑箭头: {0}"); _locEditInput = UILocale.Get("编辑输入框"); _locIconOffset = UILocale.Get("图标偏移 (x, y):"); _locTitleOffset = UILocale.Get("标题文字偏移 (x, y):"); _locDescOffset = UILocale.Get("描述文字偏移 (x, y):"); _locCurrentValue = UILocale.Get("当前值: {0}"); _locTextContent = UILocale.Get("文本内容:"); _locWindowTitle = UILocale.Get("NativeUIMaker 调试窗口"); _locAuto = UILocale.Get("Auto"); _locPinToPage = UILocale.Get("固定到当前页面"); _locCreateLabel = UILocale.Get("创建文本标签 (StandardLabel)"); _locCreateSlider = UILocale.Get("创建滑块 (NativeSlider)"); _locCreateOption = UILocale.Get("创建选项行 (NativeOption)"); _locCreateArrow = UILocale.Get("创建新箭头"); _locCreateInput = UILocale.Get("创建输入框"); _cachedIsChinese = UILocale.IsChinese; _localeCacheValid = true; } private void CleanAllExternalLists() { if (_externalCleanFrameCounter++ % 30 == 0) { _externalButtons.RemoveAll((NativeButton b) => b == null || (Object)(object)b.gameObject == (Object)null); _externalLabels.RemoveAll((NativeLabel l) => l == null || (Object)(object)l.gameObject == (Object)null); _externalSliders.RemoveAll((NativeSlider s) => s == null || (Object)(object)s.gameObject == (Object)null); _externalOptions.RemoveAll((NativeOption o) => o == null || (Object)(object)o.gameObject == (Object)null); _externalArrows.RemoveAll((NativeArrow a) => a == null || (Object)(object)a.gameObject == (Object)null); _externalInputs.RemoveAll((NativeInput i) => i == null || (Object)(object)i.gameObject == (Object)null); } } public static void Create() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("DebugWindow"); _instance = val.AddComponent<DebugWindow>(); Object.DontDestroyOnLoad((Object)val); } } public GameObject GetSelectedGameObject() { if (_selectedControl == null) { return null; } if (_selectedControl is NativeButton nativeButton) { return nativeButton.gameObject; } if (_selectedControl is NativeLabel nativeLabel) { return nativeLabel.gameObject; } if (_selectedControl is NativeSlider nativeSlider) { return nativeSlider.gameObject; } if (_selectedControl is NativeOption nativeOption) { return nativeOption.gameObject; } if (_selectedControl is NativeArrow nativeArrow) { return nativeArrow.gameObject; } if (_selectedControl is NativeInput nativeInput) { return nativeInput.gameObject; } return null; } public void RefreshEditFieldsForSelected() { if (_selectedControl != null) { UpdateEditFieldsFromControl(); } } private void OnGUI() { //IL_002b: 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) //IL_0047: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (_showWindow) { if (!_localeCacheValid || _cachedIsChinese != UILocale.IsChinese) { RefreshLocaleCache(); } _windowRect = GUI.Window(123456, _windowRect, new WindowFunction(DrawWindow), _locWindowTitle); } } private void DrawWindow(int id) { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("CN", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { UILocale.SetForceChinese(true); _localeCacheValid = false; } if (GUILayout.Button("EN", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { UILocale.SetForceChinese(false); _localeCacheValid = false; } if (GUILayout.Button(_locAuto, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { UILocale.SetForceChinese(null); _localeCacheValid = false; } GUILayout.EndHorizontal(); GUILayout.Space(10f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locLocal, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { _selectedTab = 0; } if (GUILayout.Button(_locExternal, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { _selectedTab = 1; } if (GUILayout.Button(_locPageMgmt, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { _selectedTab = 2; } GUILayout.EndHorizontal(); _scrollPos = GUILayout.BeginScrollView(_scrollPos, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); if (_selectedTab == 0) { DrawLocalControlsTab(); } else if (_selectedTab == 1) { DrawExternalControlsTab(); } else { DrawPageManagementTab(); } GUILayout.EndScrollView(); DrawUnifiedEditor(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locHideWindow, Array.Empty<GUILayoutOption>())) { _showWindow = false; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); } private void DrawLocalControlsTab() { DrawCreateTargetSelector(); GUILayout.Space(10f); DrawCreateButtonSection(); DrawLocalButtonsList(); GUILayout.Space(10f); DrawCreateLabelSection(); DrawLocalLabelsList(); GUILayout.Space(10f); DrawCreateSliderSection(); DrawLocalSlidersList(); GUILayout.Space(10f); DrawCreateOptionSection(); DrawLocalOptionsList(); GUILayout.Space(10f); DrawCreateArrowSection(); DrawLocalArrowsList(); GUILayout.Space(10f); DrawCreateInputSection(); DrawLocalInputsList(); } private void RefreshPageDropdownList() { int count = NativePage.AllInstances.Count; bool flag = _pageDropdownVersion != count; if (!flag && _pageNamesForDropdown.Length > 1) { for (int i = 0; i < NativePage.AllInstances.Count; i++) { if (NativePage.AllInstances[i] == null) { flag = true; break; } } } if (!flag) { return; } _pageDropdownVersion = count; List<NativePage> list = NativePage.AllInstances.Where((NativePage p) => p != null).ToList(); _pageNamesForDropdown = new string[list.Count + 1]; _pageNamesForDropdown[0] = UILocale.Get("全局画布 (独立于页面)"); for (int num = 0; num < list.Count; num++) { _pageNamesForDropdown[num + 1] = ((Object)list[num].gameObject).name; } if (_selectedCreateTargetPage != null) { int num2 = list.IndexOf(_selectedCreateTargetPage); if (num2 >= 0) { _selectedPageDropdownIndex = num2 + 1; return; } _selectedCreateTargetPage = null; _selectedPageDropdownIndex = 0; } else { _selectedPageDropdownIndex = 0; } } private void DrawCreateTargetSelector() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(UILocale.Get("创建目标:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); RefreshPageDropdownList(); int num = GUILayout.SelectionGrid(_selectedPageDropdownIndex, _pageNamesForDropdown, 1, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (num != _selectedPageDropdownIndex) { _selectedPageDropdownIndex = num; if (num == 0) { _selectedCreateTargetPage = null; } else { List<NativePage> list = NativePage.AllInstances.ToList(); if (num - 1 < list.Count) { _selectedCreateTargetPage = list[num - 1]; } else { _selectedCreateTargetPage = null; } } } if (_selectedCreateTargetPage != null) { GUILayout.Label(UILocale.Get("当前:") + " " + ((Object)_selectedCreateTargetPage.gameObject).name, Array.Empty<GUILayoutOption>()); } else { GUILayout.Label(UILocale.Get("当前:") + " " + UILocale.Get("全局画布"), Array.Empty<GUILayoutOption>()); } GUILayout.EndHorizontal(); } private RectTransform GetCurrentParent() { if (_selectedCreateTargetPage != null && (Object)(object)_selectedCreateTargetPage.rectTransform != (Object)null) { return _selectedCreateTargetPage.rectTransform; } return UIParent.GetDefaultParent(); } private void DrawCreateButtonSection() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown GUILayout.Label(UILocale.Get("=== 创建新按钮 ==="), Array.Empty<GUILayoutOption>()); GUILayout.Label(UILocale.Get("选择按钮样式:"), Array.Empty<GUILayoutOption>()); _selectedCreateStyle = (ButtonStyle)GUILayout.Toolbar((int)_selectedCreateStyle, new string[3] { UILocale.Get("图标按钮"), UILocale.Get("纯文字按钮"), UILocale.Get("小型按钮") }, Array.Empty<GUILayoutOption>()); if (_selectedCreateStyle == ButtonStyle.IconButton) { GUILayout.Label(UILocale.Get("图标文件路径 (绝对或相对路径,留空则不设置):"), Array.Empty<GUILayoutOption>()); _iconPathInput = GUILayout.TextField(_iconPathInput, Array.Empty<GUILayoutOption>()); } GUILayout.Label(UILocale.Get("切换文字序列(逗号分隔):"), Array.Empty<GUILayoutOption>()); _toggleTextsInput = GUILayout.TextField(_toggleTextsInput, Array.Empty<GUILayoutOption>()); if (!GUILayout.Button(string.Format(UILocale.Get("创建 {0}"), _styleNames[(int)_selectedCreateStyle]), Array.Empty<GUILayoutOption>())) { return; } NativeButton nativeButton = NativeButton.Create(GetCurrentParent(), _selectedCreateStyle); if (nativeButton == null) { return; } nativeButton.SetPosition(Vector2.zero); nativeButton.SetSize(400f, 100f); nativeButton.SetTitle(UILocale.Get("新按钮")); nativeButton.SetDescription(UILocale.Get("可编辑描述")); if (_selectedCreateStyle == ButtonStyle.IconButton && !string.IsNullOrEmpty(_iconPathInput)) { Sprite val = NativeButton.LoadSpriteFromFile(_iconPathInput); if ((Object)(object)val != (Object)null) { nativeButton.SetIcon(val); } } string[] array = (from s in _toggleTextsInput.Split(new char[1] { ',' }) select s.Trim()).ToArray(); if (array.Length >= 2) { nativeButton.SetToggleTexts(array); } else if (array.Length == 1) { nativeButton.SetTitle(array[0]); nativeButton.SetDescription(array[0]); } else { object obj = <>c.<>9__211_1; if (obj == null) { UnityAction val2 = delegate { Debug.Log((object)UILocale.Get("按钮被点击")); }; <>c.<>9__211_1 = val2; obj = (object)val2; } nativeButton.AddClickListener((UnityAction)obj); } _allButtons.Add(nativeButton); _selectedControl = nativeButton; UpdateEditFieldsFromControl(); } private void DrawCreateLabelSection() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(UILocale.Get("=== 创建新标签 ==="), Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("创建文本标签 (StandardLabel)"), Array.Empty<GUILayoutOption>())) { NativeLabel nativeLabel = NativeLabel.Create(GetCurrentParent()); if (nativeLabel != null) { nativeLabel.SetPosition(Vector2.zero); nativeLabel.SetSize(400f, 60f); nativeLabel.SetText(UILocale.Get("新标签")); _allLabels.Add(nativeLabel); _selectedControl = nativeLabel; UpdateEditFieldsFromControl(); } } } private void DrawCreateSliderSection() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(UILocale.Get("=== 创建新滑块 ==="), Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("创建滑块 (NativeSlider)"), Array.Empty<GUILayoutOption>())) { NativeSlider nativeSlider = NativeSlider.Create(GetCurrentParent()); if (nativeSlider != null) { nativeSlider.SetPosition(Vector2.zero); nativeSlider.SetSize(600f, 60f); nativeSlider.SetLabel(UILocale.Get("新滑块")); nativeSlider.SetMinMax(0f, 100f); nativeSlider.Value = 50f; _allSliders.Add(nativeSlider); _selectedControl = nativeSlider; UpdateEditFieldsFromControl(); } } } private void DrawCreateOptionSection() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(UILocale.Get("=== 创建新选项行 (无滑块) ==="), Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("创建选项行 (NativeOption)"), Array.Empty<GUILayoutOption>())) { NativeOption nativeOption = NativeOption.Create(GetCurrentParent()); if (nativeOption != null) { nativeOption.SetPosition(Vector2.zero); nativeOption.SetSize(600f, 80f); nativeOption.SetLabel(UILocale.Get("新选项")); nativeOption.SetDescription(UILocale.Get("这是描述文字")); nativeOption.SetOptions(new string[2] { UILocale.Get("选项1"), UILocale.Get("选项2") }); _allOptions.Add(nativeOption); _selectedControl = nativeOption; UpdateEditFieldsFromControl(); } } } private void DrawCreateArrowSection() { GUILayout.Label(UILocale.Get("=== 创建新箭头 ==="), Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("左箭头"), Array.Empty<GUILayoutOption>())) { CreateArrow(NativeArrow.Direction.Left); } if (GUILayout.Button(UILocale.Get("右箭头"), Array.Empty<GUILayoutOption>())) { CreateArrow(NativeArrow.Direction.Right); } if (GUILayout.Button(UILocale.Get("上箭头"), Array.Empty<GUILayoutOption>())) { CreateArrow(NativeArrow.Direction.Up); } if (GUILayout.Button(UILocale.Get("下箭头"), Array.Empty<GUILayoutOption>())) { CreateArrow(NativeArrow.Direction.Down); } GUILayout.EndHorizontal(); } private void CreateArrow(NativeArrow.Direction dir) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //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_004c: Expected O, but got Unknown NativeArrow nativeArrow = NativeArrow.Create(GetCurrentParent(), dir); if (nativeArrow == null) { return; } nativeArrow.SetPosition(Vector2.zero); nativeArrow.SetSize(80f, 80f); object obj = <>c.<>9__216_0; if (obj == null) { UnityAction val = delegate { Debug.Log((object)UILocale.Get("箭头被点击")); }; <>c.<>9__216_0 = val; obj = (object)val; } nativeArrow.SetClickable(clickable: true, (UnityAction)obj); _allArrows.Add(nativeArrow); _selectedControl = nativeArrow; UpdateEditFieldsFromControl(); } private void DrawCreateInputSection() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(UILocale.Get("=== 创建新输入框 ==="), Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("创建输入框"), Array.Empty<GUILayoutOption>())) { NativeInput nativeInput = NativeInput.Create(GetCurrentParent()); if (nativeInput != null) { nativeInput.SetPosition(Vector2.zero); nativeInput.SetSize(300f, 60f); nativeInput.SetText(""); _allInputs.Add(nativeInput); _selectedControl = nativeInput; UpdateEditFieldsFromControl(); } } } private void DrawLocalButtonsList() { GUILayout.Label(UILocale.Get("=== 已创建的按钮 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allButtons.Count; i++) { NativeButton nativeButton = _allButtons[i]; if (nativeButton != null && !((Object)(object)nativeButton.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("按钮 {0}: {1}"), i, nativeButton.GetTitle()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeButton; UpdateEditFieldsFromControl(); } } } private void DrawLocalLabelsList() { GUILayout.Label(UILocale.Get("=== 已创建的标签 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allLabels.Count; i++) { NativeLabel nativeLabel = _allLabels[i]; if (nativeLabel != null && !((Object)(object)nativeLabel.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("标签 {0}: {1}"), i, nativeLabel.GetText()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeLabel; UpdateEditFieldsFromControl(); } } } private void DrawLocalSlidersList() { GUILayout.Label(UILocale.Get("=== 已创建的滑块 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allSliders.Count; i++) { NativeSlider nativeSlider = _allSliders[i]; if (nativeSlider != null && !((Object)(object)nativeSlider.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("滑块 {0}: {1} 当前值={2}"), i, nativeSlider.GetLabel(), nativeSlider.Value), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeSlider; UpdateEditFieldsFromControl(); } } } private void DrawLocalOptionsList() { GUILayout.Label(UILocale.Get("=== 已创建的选项行 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allOptions.Count; i++) { NativeOption nativeOption = _allOptions[i]; if (nativeOption != null && !((Object)(object)nativeOption.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("选项 {0}: {1} 当前值={2}"), i, nativeOption.GetLabel(), nativeOption.GetCurrentValue()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeOption; UpdateEditFieldsFromControl(); } } } private void DrawLocalArrowsList() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(UILocale.Get("=== 已创建的箭头 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allArrows.Count; i++) { NativeArrow nativeArrow = _allArrows[i]; if (nativeArrow != null && !((Object)(object)nativeArrow.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("箭头 {0}: {1} 位置={2}"), i, nativeArrow.GetDirection(), nativeArrow.GetPosition()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeArrow; UpdateEditFieldsFromControl(); } } } private void DrawLocalInputsList() { GUILayout.Label(UILocale.Get("=== 已创建的输入框 ==="), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _allInputs.Count; i++) { NativeInput nativeInput = _allInputs[i]; if (nativeInput != null && !((Object)(object)nativeInput.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("输入框 {0}: {1}"), i, nativeInput.GetText()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeInput; UpdateEditFieldsFromControl(); } } } private void DrawExternalControlsTab() { CleanAllExternalLists(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("扫描外部控件"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { ScanExternalControls(); _externalScanned = true; } if (GUILayout.Button(UILocale.Get("保存配置"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { SaveConfigToFile(); } if (GUILayout.Button(UILocale.Get("加载配置"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { LoadConfigFromFile(); } GUILayout.EndHorizontal(); if (!_externalScanned) { GUILayout.Label(UILocale.Get("点击“扫描外部控件”以发现其他模组创建的UI元素。"), Array.Empty<GUILayoutOption>()); return; } DrawExternalButtonsList(); GUILayout.Space(10f); DrawExternalLabelsList(); GUILayout.Space(10f); DrawExternalSlidersList(); GUILayout.Space(10f); DrawExternalOptionsList(); GUILayout.Space(10f); DrawExternalArrowsList(); GUILayout.Space(10f); DrawExternalInputsList(); } private void ScanExternalControls() { CleanInvalidControls(); _externalButtons.Clear(); _externalLabels.Clear(); _externalSliders.Clear(); _externalOptions.Clear(); _externalArrows.Clear(); _externalInputs.Clear(); _arrowGameObjectSet.Clear(); foreach (NativeArrow allInstance in NativeArrow.AllInstances) { if (allInstance != null && (Object)(object)allInstance.gameObject != (Object)null) { _arrowGameObjectSet.Add(allInstance.gameObject); } } BuildLocalControlSets(); foreach (NativeButton allInstance2 in NativeButton.AllInstances) { if (allInstance2 != null && !((Object)(object)allInstance2.gameObject == (Object)null) && !_arrowGameObjectSet.Contains(allInstance2.gameObject) && !_localButtonSet.Contains(allInstance2)) { _externalButtons.Add(allInstance2); } } foreach (NativeLabel allInstance3 in NativeLabel.AllInstances) { if (allInstance3 != null && !((Object)(object)allInstance3.gameObject == (Object)null) && !_localLabelSet.Contains(allInstance3)) { _externalLabels.Add(allInstance3); } } foreach (NativeSlider allInstance4 in NativeSlider.AllInstances) { if (allInstance4 != null && !((Object)(object)allInstance4.gameObject == (Object)null) && !_localSliderSet.Contains(allInstance4)) { _externalSliders.Add(allInstance4); } } foreach (NativeOption allInstance5 in NativeOption.AllInstances) { if (allInstance5 != null && !((Object)(object)allInstance5.gameObject == (Object)null) && !_localOptionSet.Contains(allInstance5)) { _externalOptions.Add(allInstance5); } } foreach (NativeArrow allInstance6 in NativeArrow.AllInstances) { if (allInstance6 != null && !((Object)(object)allInstance6.gameObject == (Object)null) && !_localArrowSet.Contains(allInstance6)) { _externalArrows.Add(allInstance6); } } foreach (NativeInput allInstance7 in NativeInput.AllInstances) { if (allInstance7 != null && !((Object)(object)allInstance7.gameObject == (Object)null) && !_localInputSet.Contains(allInstance7)) { _externalInputs.Add(allInstance7); } } Debug.Log((object)$"扫描完成: 按钮={_externalButtons.Count}, 标签={_externalLabels.Count}, 滑块={_externalSliders.Count}, 选项={_externalOptions.Count}, 箭头={_externalArrows.Count}, 输入框={_externalInputs.Count}"); } private void BuildLocalControlSets() { _localButtonSet.Clear(); foreach (NativeButton allButton in _allButtons) { if (allButton != null) { _localButtonSet.Add(allButton); } } _localLabelSet.Clear(); foreach (NativeLabel allLabel in _allLabels) { if (allLabel != null) { _localLabelSet.Add(allLabel); } } _localSliderSet.Clear(); foreach (NativeSlider allSlider in _allSliders) { if (allSlider != null) { _localSliderSet.Add(allSlider); } } _localOptionSet.Clear(); foreach (NativeOption allOption in _allOptions) { if (allOption != null) { _localOptionSet.Add(allOption); } } _localArrowSet.Clear(); foreach (NativeArrow allArrow in _allArrows) { if (allArrow != null) { _localArrowSet.Add(allArrow); } } _localInputSet.Clear(); foreach (NativeInput allInput in _allInputs) { if (allInput != null) { _localInputSet.Add(allInput); } } } private void DrawExternalButtonsList() { GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部按钮"), _externalButtons.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalButtons.Count; i++) { NativeButton nativeButton = _externalButtons[i]; if (nativeButton != null && !((Object)(object)nativeButton.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("按钮 {0}: {1}"), i, nativeButton.GetTitle()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeButton; UpdateEditFieldsFromControl(); } } } private void DrawExternalLabelsList() { GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部标签"), _externalLabels.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalLabels.Count; i++) { NativeLabel nativeLabel = _externalLabels[i]; if (nativeLabel != null && !((Object)(object)nativeLabel.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("标签 {0}: {1}"), i, nativeLabel.GetText()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeLabel; UpdateEditFieldsFromControl(); } } } private void DrawExternalSlidersList() { GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部滑块"), _externalSliders.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalSliders.Count; i++) { NativeSlider nativeSlider = _externalSliders[i]; if (nativeSlider != null && !((Object)(object)nativeSlider.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("滑块 {0}: {1} 值={2}"), i, nativeSlider.GetLabel(), nativeSlider.Value), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeSlider; UpdateEditFieldsFromControl(); } } } private void DrawExternalOptionsList() { GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部选项行"), _externalOptions.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalOptions.Count; i++) { NativeOption nativeOption = _externalOptions[i]; if (nativeOption != null && !((Object)(object)nativeOption.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("选项 {0}: {1} 当前={2}"), i, nativeOption.GetLabel(), nativeOption.GetCurrentValue()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeOption; UpdateEditFieldsFromControl(); } } } private void DrawExternalArrowsList() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部箭头"), _externalArrows.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalArrows.Count; i++) { NativeArrow nativeArrow = _externalArrows[i]; if (nativeArrow != null && !((Object)(object)nativeArrow.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("箭头 {0}: {1} 位置={2}"), i, nativeArrow.GetDirection(), nativeArrow.GetPosition()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeArrow; UpdateEditFieldsFromControl(); } } } private void DrawExternalInputsList() { GUILayout.Label(string.Format("{0} ({1})", UILocale.Get("外部输入框"), _externalInputs.Count), Array.Empty<GUILayoutOption>()); for (int i = 0; i < _externalInputs.Count; i++) { NativeInput nativeInput = _externalInputs[i]; if (nativeInput != null && !((Object)(object)nativeInput.gameObject == (Object)null) && GUILayout.Button(string.Format(UILocale.Get("输入框 {0}: {1}"), i, nativeInput.GetText()), Array.Empty<GUILayoutOption>())) { _selectedControl = nativeInput; UpdateEditFieldsFromControl(); } } } private void DrawUnifiedEditor() { if (_selectedControl == null) { GUILayout.Label(_locNoSelection, Array.Empty<GUILayoutOption>()); return; } GameObject val = null; if (_selectedControl is NativeButton nativeButton) { val = nativeButton.gameObject; } else if (_selectedControl is NativeLabel nativeLabel) { val = nativeLabel.gameObject; } else if (_selectedControl is NativeSlider nativeSlider) { val = nativeSlider.gameObject; } else if (_selectedControl is NativeOption nativeOption) { val = nativeOption.gameObject; } else if (_selectedControl is NativeArrow nativeArrow) { val = nativeArrow.gameObject; } else if (_selectedControl is NativeInput nativeInput) { val = nativeInput.gameObject; } if ((Object)(object)val == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>()); if (_selectedControl is NativeButton btn) { DrawButtonEditor(btn); } else if (_selectedControl is NativeLabel lbl) { DrawLabelEditor(lbl); } else if (_selectedControl is NativeSlider sld) { DrawSliderEditor(sld); } else if (_selectedControl is NativeOption opt) { DrawOptionEditor(opt); } else if (_selectedControl is NativeArrow arr) { DrawArrowEditor(arr); } else if (_selectedControl is NativeInput inp) { DrawInputEditor(inp); } GUILayout.Space(10f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locPinToPage, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { PinSelectedControlToTargetPage(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void DrawButtonEditor(NativeButton btn) { //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) if (btn == null || (Object)(object)btn.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(string.Format(_locEditButton, btn.GetTitle()), Array.Empty<GUILayoutOption>()); GUILayout.Label(_locTitle, Array.Empty<GUILayoutOption>()); _editTitle = GUILayout.TextField(_editTitle, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locDesc, Array.Empty<GUILayoutOption>()); _editDesc = GUILayout.TextField(_editDesc, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); if (btn.HasIcon()) { GUILayout.Label(_locIconOffset, Array.Empty<GUILayoutOption>()); _strIconOffX = GUILayout.TextField(_strIconOffX, Array.Empty<GUILayoutOption>()); _strIconOffY = GUILayout.TextField(_strIconOffY, Array.Empty<GUILayoutOption>()); float.TryParse(_strIconOffX, out _editIconOffset.x); float.TryParse(_strIconOffY, out _editIconOffset.y); if (GUILayout.Button(_locApplyIcon, Array.Empty<GUILayoutOption>())) { btn.SetIconOffset(_editIconOffset); } } GUILayout.Label(_locTitleOffset, Array.Empty<GUILayoutOption>()); _strTitleOffX = GUILayout.TextField(_strTitleOffX, Array.Empty<GUILayoutOption>()); _strTitleOffY = GUILayout.TextField(_strTitleOffY, Array.Empty<GUILayoutOption>()); float.TryParse(_strTitleOffX, out _editTitleOffset.x); float.TryParse(_strTitleOffY, out _editTitleOffset.y); if (GUILayout.Button(_locApplyTitle, Array.Empty<GUILayoutOption>())) { btn.SetTitleOffset(_editTitleOffset); } GUILayout.Label(_locDescOffset, Array.Empty<GUILayoutOption>()); _strDescOffX = GUILayout.TextField(_strDescOffX, Array.Empty<GUILayoutOption>()); _strDescOffY = GUILayout.TextField(_strDescOffY, Array.Empty<GUILayoutOption>()); float.TryParse(_strDescOffX, out _editDescOffset.x); float.TryParse(_strDescOffY, out _editDescOffset.y); if (GUILayout.Button(_locApplyDesc, Array.Empty<GUILayoutOption>())) { btn.SetDescOffset(_editDescOffset); } bool flag = btn.IsDraggable(); bool flag2 = GUILayout.Toggle(flag, _locDraggable, Array.Empty<GUILayoutOption>()); if (flag2 != flag) { btn.SetDraggable(flag2); } GUILayout.Label(_locSetToggleTexts, Array.Empty<GUILayoutOption>()); _editToggleTextsInput = GUILayout.TextField(_editToggleTextsInput, Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locApplyToggle, Array.Empty<GUILayoutOption>())) { string[] array = (from s in _editToggleTextsInput.Split(new char[1] { ',' }) select s.Trim()).ToArray(); if (array.Length >= 2) { btn.SetToggleTexts(array); UpdateEditFieldsFromControl(); } else if (array.Length == 1) { btn.SetTitle(array[0]); btn.SetDescription(array[0]); btn.SetToggleTexts(null); } else { btn.SetToggleTexts(null); } } if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { btn.SetTitle(_editTitle); btn.SetDescription(_editDesc); btn.SetPosition(_editPos); btn.SetSize(_editSize.x, _editSize.y); if (btn.HasIcon()) { btn.SetIconOffset(_editIconOffset); } btn.SetTitleOffset(_editTitleOffset); btn.SetDescOffset(_editDescOffset); } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { btn.Destroy(); RemoveFromList(btn); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void DrawLabelEditor(NativeLabel lbl) { //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) if (lbl == null || (Object)(object)lbl.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(string.Format(_locEditLabel, lbl.GetText()), Array.Empty<GUILayoutOption>()); GUILayout.Label(_locText, Array.Empty<GUILayoutOption>()); _editLabelText = GUILayout.TextField(_editLabelText, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); GUILayout.Label(_locFontSize, Array.Empty<GUILayoutOption>()); _strFontSize = GUILayout.TextField(_strFontSize, Array.Empty<GUILayoutOption>()); int.TryParse(_strFontSize, out _editFontSize); GUILayout.Label(_locColorRGB, Array.Empty<GUILayoutOption>()); _strColor = GUILayout.TextField(_strColor, Array.Empty<GUILayoutOption>()); if (_strColor != _lastParsedColor) { _lastParsedColor = _strColor; string[] array = _strColor.Split(new char[1] { ',' }); if (array.Length == 3 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3)) { _editColor = new Color(result, result2, result3, 1f); } } bool flag = lbl.IsDraggable(); bool flag2 = GUILayout.Toggle(flag, _locDraggable, Array.Empty<GUILayoutOption>()); if (flag2 != flag) { lbl.SetDraggable(flag2); } if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { lbl.SetText(_editLabelText); lbl.SetPosition(_editPos); lbl.SetSize(_editSize.x, _editSize.y); lbl.SetFontSize(_editFontSize); lbl.SetColor(_editColor); } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { lbl.Destroy(); RemoveFromList(lbl); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void DrawSliderEditor(NativeSlider sld) { //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) if (sld == null || (Object)(object)sld.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(string.Format(_locEditSlider, sld.GetLabel()), Array.Empty<GUILayoutOption>()); GUILayout.Label(_locLabel, Array.Empty<GUILayoutOption>()); _editSliderLabel = GUILayout.TextField(_editSliderLabel, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); GUILayout.Label(_locSliderXOff, Array.Empty<GUILayoutOption>()); _strSliderXOff = GUILayout.TextField(_strSliderXOff, Array.Empty<GUILayoutOption>()); float.TryParse(_strSliderXOff, out _editSliderXOffset); GUILayout.Label(_locSliderWidth, Array.Empty<GUILayoutOption>()); _strSliderWidth = GUILayout.TextField(_strSliderWidth, Array.Empty<GUILayoutOption>()); float.TryParse(_strSliderWidth, out _editSliderWidth); GUILayout.Label(_locLabelXOff, Array.Empty<GUILayoutOption>()); _strLabelXOff = GUILayout.TextField(_strLabelXOff, Array.Empty<GUILayoutOption>()); float.TryParse(_strLabelXOff, out _editLabelXOffset); GUILayout.Label(_locValueXOff, Array.Empty<GUILayoutOption>()); _strValueXOff = GUILayout.TextField(_strValueXOff, Array.Empty<GUILayoutOption>()); float.TryParse(_strValueXOff, out _editValueXOffset); GUILayout.Label(string.Format(_locMin, _editSliderMin), Array.Empty<GUILayoutOption>()); _strSliderMin = GUILayout.TextField(_strSliderMin, Array.Empty<GUILayoutOption>()); float.TryParse(_strSliderMin, out _editSliderMin); GUILayout.Label(string.Format(_locMax, _editSliderMax), Array.Empty<GUILayoutOption>()); _strSliderMax = GUILayout.TextField(_strSliderMax, Array.Empty<GUILayoutOption>()); float.TryParse(_strSliderMax, out _editSliderMax); GUILayout.Label(string.Format(_locCurrentValue, _editSliderValue), Array.Empty<GUILayoutOption>()); _strSliderValue = GUILayout.TextField(_strSliderValue, Array.Empty<GUILayoutOption>()); float.TryParse(_strSliderValue, out _editSliderValue); _editSliderWhole = GUILayout.Toggle(_editSliderWhole, _locIntStep, Array.Empty<GUILayoutOption>()); bool flag = sld.IsDraggable(); bool flag2 = GUILayout.Toggle(flag, _locDraggable, Array.Empty<GUILayoutOption>()); if (flag2 != flag) { sld.SetDraggable(flag2); } if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { Vector2 position = sld.GetPosition(); Vector2 size = sld.GetSize(); sld.SetLabel(_editSliderLabel); sld.SetSliderXOffset(_editSliderXOffset); sld.SetSliderWidth(_editSliderWidth); sld.SetLabelXOffset(_editLabelXOffset); sld.SetValueXOffset(_editValueXOffset); sld.SetMinMax(_editSliderMin, _editSliderMax, _editSliderWhole); sld.Value = _editSliderValue; sld.SetPosition(position); sld.SetSize(size.x, size.y); } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { sld.Destroy(); RemoveFromList(sld); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void DrawOptionEditor(NativeOption opt) { //IL_0309: Unknown result type (might be due to invalid IL or missing references) if (opt == null || (Object)(object)opt.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(string.Format(_locEditOption, opt.GetLabel()), Array.Empty<GUILayoutOption>()); GUILayout.Label(_locLabel, Array.Empty<GUILayoutOption>()); _editOptionLabel = GUILayout.TextField(_editOptionLabel, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locDesc, Array.Empty<GUILayoutOption>()); _editOptionDesc = GUILayout.TextField(_editOptionDesc, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); GUILayout.Label(_locOptions, Array.Empty<GUILayoutOption>()); string text = ((_editOptionOptions != null) ? string.Join(",", _editOptionOptions) : ""); string text2 = GUILayout.TextField(text, Array.Empty<GUILayoutOption>()); if (text2 != text) { _editOptionOptions = (from s in text2.Split(new char[1] { ',' }) select s.Trim()).ToArray(); } if (_editOptionOptions != null && _editOptionOptions.Length != 0) { _editOptionIndex = Mathf.Clamp(_editOptionIndex, 0, _editOptionOptions.Length - 1); GUILayout.Label(string.Format(_locSelected, _editOptionOptions[_editOptionIndex], _editOptionIndex), Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locPrev, Array.Empty<GUILayoutOption>())) { _editOptionIndex = (_editOptionIndex - 1 + _editOptionOptions.Length) % _editOptionOptions.Length; } if (GUILayout.Button(_locNext, Array.Empty<GUILayoutOption>())) { _editOptionIndex = (_editOptionIndex + 1) % _editOptionOptions.Length; } GUILayout.EndHorizontal(); } bool flag = opt.IsDraggable(); bool flag2 = GUILayout.Toggle(flag, _locDraggable, Array.Empty<GUILayoutOption>()); if (flag2 != flag) { opt.SetDraggable(flag2); } if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { opt.SetLabel(_editOptionLabel); opt.SetDescription(_editOptionDesc); opt.SetPosition(_editPos); opt.SetSize(_editSize.x, _editSize.y); if (_editOptionOptions != null && _editOptionOptions.Length != 0) { opt.SetOptions(_editOptionOptions, _editOptionIndex); } } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { opt.Destroy(); RemoveFromList(opt); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void DrawArrowEditor(NativeArrow arr) { //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown if (arr == null || (Object)(object)arr.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(string.Format(_locEditArrow, arr.GetDirection()), Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); _editArrowClickable = GUILayout.Toggle(_editArrowClickable, _locClickable, Array.Empty<GUILayoutOption>()); _editArrowDraggable = GUILayout.Toggle(_editArrowDraggable, _locDraggable, Array.Empty<GUILayoutOption>()); if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { arr.SetPosition(_editPos); arr.SetSize(_editSize.x, _editSize.y); arr.SetClickable(_editArrowClickable, (UnityAction)delegate { Debug.Log((object)_locArrowClicked); }); arr.SetDraggable(_editArrowDraggable); } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { arr.Destroy(); RemoveFromList(arr); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void DrawInputEditor(NativeInput inp) { //IL_01c9: Unknown result type (might be due to invalid IL or missing references) if (inp == null || (Object)(object)inp.gameObject == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; GUILayout.Label(_locDestroyed, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(_locEditInput, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locTextContent, Array.Empty<GUILayoutOption>()); _editInputText = GUILayout.TextField(_editInputText, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPlaceholder, Array.Empty<GUILayoutOption>()); _editInputPlaceholder = GUILayout.TextField(_editInputPlaceholder, Array.Empty<GUILayoutOption>()); GUILayout.Label(_locPosXY, Array.Empty<GUILayoutOption>()); _strPosX = GUILayout.TextField(_strPosX, Array.Empty<GUILayoutOption>()); _strPosY = GUILayout.TextField(_strPosY, Array.Empty<GUILayoutOption>()); float.TryParse(_strPosX, out _editPos.x); float.TryParse(_strPosY, out _editPos.y); GUILayout.Label(_locSizeWH, Array.Empty<GUILayoutOption>()); _strSizeW = GUILayout.TextField(_strSizeW, Array.Empty<GUILayoutOption>()); _strSizeH = GUILayout.TextField(_strSizeH, Array.Empty<GUILayoutOption>()); float.TryParse(_strSizeW, out _editSize.x); float.TryParse(_strSizeH, out _editSize.y); bool flag = inp.IsDraggable(); bool flag2 = GUILayout.Toggle(flag, _locDraggable, Array.Empty<GUILayoutOption>()); if (flag2 != flag) { inp.SetDraggable(flag2); } if (GUILayout.Button(_locApplyChanges, Array.Empty<GUILayoutOption>())) { inp.SetText(_editInputText); Graphic placeholder = inp.inputField.placeholder; Text val = (Text)(object)((placeholder is Text) ? placeholder : null); if ((Object)(object)val != (Object)null) { val.text = _editInputPlaceholder; } inp.SetPosition(_editPos); inp.SetSize(_editSize.x, _editSize.y); } if (GUILayout.Button(_locDeleteControl, Array.Empty<GUILayoutOption>())) { inp.Destroy(); RemoveFromList(inp); _selectedControl = null; CurrentlySelectedForDrag = null; } } private void UpdateEditFieldsFromControl() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) if (_tempDragEnabled) { _tempDragEnabled = false; _tempDragTarget = null; Debug.Log((object)"[DebugWindow] 由于选中新控件,临时拖拽模式已关闭"); } if (_selectedControl == null) { CurrentlySelectedForDrag = null; return; } GameObject val = null; if (_selectedControl is NativeButton nativeButton) { val = nativeButton.gameObject; } else if (_selectedControl is NativeLabel nativeLabel) { val = nativeLabel.gameObject; } else if (_selectedControl is NativeSlider nativeSlider) { val = nativeSlider.gameObject; } else if (_selectedControl is NativeOption nativeOption) { val = nativeOption.gameObject; } else if (_selectedControl is NativeArrow nativeArrow) { val = nativeArrow.gameObject; } else if (_selectedControl is NativeInput nativeInput) { val = nativeInput.gameObject; } if ((Object)(object)val == (Object)null) { _selectedControl = null; CurrentlySelectedForDrag = null; return; } if (_selectedControl is NativeButton nativeButton2) { _editTitle = nativeButton2.GetTitle(); _editDesc = nativeButton2.GetDescription(); _editPos = nativeButton2.GetPosition(); _editSize = nativeButton2.GetSize(); _editIconOffset = nativeButton2.GetIconOffset(); _editTitleOffset = nativeButton2.GetTitleOffset(); _editDescOffset = nativeButton2.GetDescOffset(); if (nativeButton2.toggleTexts != null && nativeButton2.toggleTexts.Length != 0) { _editToggleTextsInput = string.Join(",", nativeButton2.toggleTexts); } else { _editToggleTextsInput = ""; } } else if (_selectedControl is NativeLabel nativeLabel2) { _editLabelText = nativeLabel2.GetText(); _editPos = nativeLabel2.GetPosition(); _editSize = nativeLabel2.GetSize(); Text textComponent = nativeLabel2.textComponent; _editFontSize = ((textComponent != null) ? textComponent.fontSize : 30); Text textComponent2 = nativeLabel2.textComponent; _editColor = ((textComponent2 != null) ? ((Graphic)textComponent2).color : Color.white); } else if (_selectedControl is NativeSlider nativeSlider2) { _editSliderLabel = nativeSlider2.GetLabel(); _editPos = nativeSlider2.GetPosition(); _editSize = nativeSlider2.GetSize(); Slider slider = nativeSlider2.slider; _editSliderMin = ((slider != null) ? slider.minValue : 0f); Slider slider2 = nativeSlider2.slider; _editSliderMax = ((slider2 != null) ? slider2.maxValue : 100f); _editSliderValue = nativeSlider2.Value; Slider slider3 = nativeSlider2.slider; _editSliderWhole = slider3 == null || slider3.wholeNumbers; _editSliderXOffset = nativeSlider2.GetSliderXOffset(); _editSliderWidth = nativeSlider2.GetSliderWidth(); _editLabelXOffset = nativeSlider2.GetLabelXOffset(); _editValueXOffset = nativeSlider2.GetValueXOffset(); } else if (_selectedControl is NativeOption nativeOption2) { _editOptionLabel = nativeOption2.GetLabel(); _editOptionDesc = nativeOption2.GetDescription(); _editPos = nativeOption2.GetPosition(); _editSize = nativeOption2.GetSize(); _editOptionOptions = nativeOption2.GetOptions(); _editOptionIndex = nativeOption2.GetCurrentIndex(); } else if (_selectedControl is NativeArrow nativeArrow2) { _editPos = nativeArrow2.GetPosition(); _editSize = nativeArrow2.GetSize(); _editArrowDirection = (int)nativeArrow2.GetDirection(); _editArrowClickable = nativeArrow2.IsClickable(); _editArrowDraggable = nativeArrow2.IsDraggable(); } else if (_selectedControl is NativeInput nativeInput2) { _editInputText = nativeInput2.GetText(); _editPos = nativeInput2.GetPosition(); _editSize = nativeInput2.GetSize(); Graphic placeholder = nativeInput2.inputField.placeholder; Text val2 = (Text)(object)((placeholder is Text) ? placeholder : null); _editInputPlaceholder = (((Object)(object)val2 != (Object)null) ? val2.text : UILocale.Get("输入...")); } _strPosX = _editPos.x.ToString("F0"); _strPosY = _editPos.y.ToString("F0"); _strSizeW = _editSize.x.ToString("F0"); _strSizeH = _editSize.y.ToString("F0"); _strIconOffX = _editIconOffset.x.ToString("F0"); _strIconOffY = _editIconOffset.y.ToString("F0"); _strTitleOffX = _editTitleOffset.x.ToString("F0"); _strTitleOffY = _editTitleOffset.y.ToString("F0"); _strDescOffX = _editDescOffset.x.ToString("F0"); _strDescOffY = _editDescOffset.y.ToString("F0"); _strFontSize = _editFontSize.ToString(); _strColor = $"{_editColor.r:F2},{_editColor.g:F2},{_editColor.b:F2}"; _lastParsedColor = _strColor; _strSliderMin = _editSliderMin.ToString("F1"); _strSliderMax = _editSliderMax.ToString("F1"); _strSliderValue = _editSliderValue.ToString("F1"); _strSliderXOff = _editSliderXOffset.ToString("F1"); _strSliderWidth = _editSliderWidth.ToString("F1"); _strLabelXOff = _editLabelXOffset.ToString("F1"); _strValueXOff = _editValueXOffset.ToString("F1"); CurrentlySelectedForDrag = GetSelectedGameObject(); } private void RemoveFromList(object control) { if (control is NativeButton item) { _allButtons.Remove(item); } else if (control is NativeLabel item2) { _allLabels.Remove(item2); } else if (control is NativeSlider item3) { _allSliders.Remove(item3); } else if (control is NativeOption item4) { _allOptions.Remove(item4); } else if (control is NativeArrow item5) { _allArrows.Remove(item5); } else if (control is NativeInput item6) { _externalInputs.Remove(item6); _allInputs.Remove(item6); } } private void DrawPageManagementTab() { List<NativePage> allInstances = NativePage.AllInstances; GUILayout.Label(UILocale.Get("可用页面:"), Array.Empty<GUILayoutOption>()); for (int i = 0; i < allInstances.Count; i++) { NativePage nativePage = allInstances[i]; if (nativePage != null && GUILayout.Button(string.Format(UILocale.Get("页面 {0}: {1}"), i, ((Object)nativePage.gameObject).name), Array.Empty<GUILayoutOption>())) { _selectedPage = nativePage; RefreshPageControlsCache(); } } if (_selectedPage == null) { return; } GUILayout.Label(string.Format(UILocale.Get("当前页面: {0} 包含控件: {1}"), ((Object)_selectedPage.gameObject).name, _pageControlsCache.Count), Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(UILocale.Get("保存页面配置"), Array.Empty<GUILayoutOption>())) { SavePageConfig(); } if (GUILayout.Button(UILocale.Get("加载页面配置"), Array.Empty<GUILayoutOption>())) { LoadPageConfig(); } if (GUILayout.Button(UILocale.Get("刷新"), Array.Empty<GUILayoutOption>())) { RefreshPageControlsCache(); } GUILayout.EndHorizontal(); GUILayout.Label(UILocale.Get("页面内控件列表:"), Array.Empty<GUILayoutOption>()); foreach (UIControlConfig item in _pageControlsCache) { GUILayout.Label(string.Format(" {0}: {1} - {2}({3:F0},{4:F0})", item.type, item.name, UILocale.Get("位置"), item.position.x, item.position.y), Array.Empty<GUILayoutOption>()); } } private void RefreshPageControlsCache() { if (_selectedPage != null) { _pageControlsCache.Clear(); AddIfChild<NativeButton>(NativeButton.AllInstances); AddIfChild<NativeLabel>(NativeLabel.AllInstances); AddIfChild<NativeSlider>(NativeSlider.AllInstances); AddIfChild<NativeOption>(NativeOption.AllInstances); AddIfChild<NativeArrow>(NativeArrow.AllInstances); AddIfChild<NativeInput>(NativeInput.AllInstances); } void AddIfChild<T>(List<T> instances) where T : class { foreach (T instance in instances) { GameObject val = null; if (instance is NativeButton nativeButton) { val = nativeButton.gameObject; } else if (instance is NativeLabel nativeLabel) { val = nativeLabel.gameObject; } else if (instance is NativeSlider nativeSlider) { val = nativeSlider.gameObject; } else if (instance is NativeOption nativeOption) { val = nativeOption.gameObject; } else if (instance is NativeArrow nativeArrow) { val = nativeArrow.gameObject; } else if (instance is NativeInput nativeInput) { val = nativeInput.gameObject; } if ((Object)(object)val != (Object)null && IsChildOf(val.transform, _selectedPage.gameObject.transform)) { _pageControlsCache.Add(GetControlConfig(instance)); } } } } private bool IsChildOf(Transform child, Transform parent) { while ((Object)(object)child != (Object)null) { if ((Object)(object)child == (Object)(object)parent) { return true; } child = child.parent; } return false; } private UIControlConfig GetControlConfig(object ctrl) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_006d: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) UIControlConfig uIControlConfig = new UIControlConfig(); if (ctrl is NativeButton nativeButton) { uIControlConfig.type = "Button"; uIControlConfig.name = ((Object)nativeButton.gameObject).name; uIControlConfig.position = nativeButton.GetPosition(); uIControlConfig.size = nativeButton.GetSize(); uIControlConfig.title = nativeButton.GetTitle(); uIControlConfig.description = nativeButton.GetDescription(); uIControlConfig.draggable = nativeButton.IsDraggable(); uIControlConfig.iconOffset = nativeButton.GetIconOffset(); uIControlConfig.titleOffset = nativeButton.GetTitleOffset(); uIControlConfig.descOffset = nativeButton.GetDescOffset(); uIControlConfig.style = (int)nativeButton.Style; if (nativeButton.toggleTexts != null && nativeButton.toggleTexts.Length != 0) { uIControlConfig.toggleTexts = nativeButton.toggleTexts; uIControlConfig.toggleIndex = nativeButton.currentToggleIndex; } } else if (ctrl is NativeLabel nativeLabel) { uIControlConfig.type = "Label"; uIControlConfig.name = ((Object)nativeLabel.gameObject).name; uIControlConfig.position = nativeLabel.GetPosition(); uIControlConfig.size = nativeLabel.GetSize(); uIControlConfig.labelText = nativeLabel.GetText(); Text textComponent = nativeLabel.textComponent; uIControlConfig.fontSize = ((textComponent != null) ? textComponent.fontSize : 30); Text textComponent2 = nativeLabel.textComponent; uIControlConfig.color = ((textComponent2 != null) ? ((Graphic)textComponent2).color : Color.white); uIControlConfig.draggable = nativeLabel.IsDraggable(); } else if (ctrl is NativeSlider nativeSlider) { uIControlConfig.type = "Slider"; uIControlConfig.name = ((Object)nativeSlider.gameObject).name; uIControlConfig.position = nativeSlider.GetPosition(); uIControlConfig.size = nativeSlider.GetSize(); uIControlConfig.labelText = nativeSlider.GetLabel(); Slider slider = nativeSlider.slider; uIControlConfig.minValue = ((slider != null) ? slider.minValue : 0f); Slider slider2 = nativeSlider.slider; uIControlConfig.maxValue = ((slider2 != null) ? slider2.maxValue : 100f); uIControlConfig.value = nativeSlider.Value; Slider slider3 = nativeSlider.slider; uIControlConfig.wholeNumbers = slider3 == null || slider3.wholeNumbers; uIControlConfig.draggable = nativeSlider.IsDraggable(); uIControlConfig.sliderXOffset = nativeSlider.GetSliderXOffset(); uIControlConfig.sliderWidth = nativeSlider.GetSliderWidth(); uIControlConfig.labelXOffset = nativeSlider.GetLabelXOffset(); uIControlConfig.valueXOffset = nativeSlider.GetValueXOffset(); } else if (ctrl is NativeOption nativeOption) { uIControlConfig.type = "Option"; uIControlConfig.name = ((Object)nativeOption.gameObject).name; uIControlConfig.position = nativeOption.GetPosition(); uIControlConfig.size = nativeOption.GetSize(); uIControlConfig.labelText = nativeOption.GetLabel(); uIControlConfig.description = nativeOption.GetDescription(); uIControlConfig.options = nativeOption.GetOptions(); uIControlConfig.optionIndex = nativeOption.GetCurrentIndex(); uIControlConfig.draggable = nativeOption.IsDraggable(); } else if (ctrl is NativeArrow nativeArrow) { uIControlConfig.type = "Arrow"; uIControlConfig.name = ((Object)nativeArrow.gameObject).name; uIControlConfig.position = nativeArrow.GetPosition(); uIControlConfig.size = nativeArrow.GetSize(); uIControlConfig.direction = (int)nativeArrow.GetDirection(); uIControlConfig.clickable = nativeArrow.IsClickable(); uIControlConfig.draggable = nativeArrow.IsDraggable(); } else if (ctrl is NativeInput nativeInput) { uIControlConfig.type = "Input"; uIControlConfig.name = ((Object)nativeInput.gameObject).name; uIControlConfig.position = nativeInput.GetPosition(); uIControlConfig.size = nativeInput.rectTransform.sizeDelta; uIControlConfig.inputText = nativeInput.GetText(); Graphic placeholder = nativeInput.inputField.placeholder; Text val = (Text)(object)((placeholder is Text) ? placeholder : null); uIControlConfig.placeholderText = (((Object)(object)val != (Object)null) ? val.text : ""); } return uIControlConfig; } private void SavePageConfig() { if (_selectedPage != null) { RefreshPageControlsCache(); ConfigData configData = new ConfigData { controls = _pageControlsCache }; string text = ((Object)_selectedPage.gameObject).name.Replace(" ", "_"); string text2 = Path.Combine(PluginDirectory, "PageConfigs"); Directory.CreateDirectory(text2); string text3 = Path.Combine(text2, "PageConfig_" + text + ".json"); File.WriteAllText(text3, JsonConvert.SerializeObject((object)configData, SlimJson.Settings)); Debug.Log((object)("页面配置已保存至 " + text3)); } } private void LoadPageConfig() { if (_selectedPage == null) { return; } string text = ((Object)_selectedPage.gameObject).name.Replace(" ", "_"); string text2 = Path.Combine(Path.Combine(PluginDirectory, "PageConfigs"), "PageConfig_" + text + ".json"); if (!File.Exists(text2)) { return; } ConfigData configData = JsonConvert.DeserializeObject<ConfigData>(File.ReadAllText(text2)); if (configData == null) { return; } foreach (UIControlConfig control in configData.controls) { ApplyConfigToControlInPage(control); } Canvas.ForceUpdateCanvases(); Debug.Log((object)("已加载页面配置 " + text2)); } private void ApplyConfigToControlInPage(UIControlConfig cfg) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Expected O, but got Unknown GameObject val = FindChildByName(_selectedPage.gameObject.transform, cfg.name); if ((Object)(object)val == (Object)null) { return; } if (cfg.type == "Button") { NativeButton component = val.GetComponent<NativeButton>(); if (component == null) { return; } if (component.Style != (ButtonStyle)cfg.style) { component.SetStyle((ButtonStyle)cfg.style); } component.SetPosition(cfg.position); component.SetSize(cfg.size.x, cfg.size.y); if (!string.IsNullOrEmpty(cfg.title)) { component.SetTitle(cfg.title.Trim()); } if (!string.IsNullOrEmpty(cfg.description)) { component.SetDescription(cfg.description.Trim()); } component.SetDraggable(cfg.draggable); component.SetIconOffset(cfg.iconOffset); component.SetTitleOffset(cfg.titleOffset); component.SetDescOffset(cfg.descOffset); if (cfg.toggleTexts != null && cfg.toggleTexts.Length != 0) { component.SetToggleTexts(cfg.toggleTexts); if (cfg.toggleIndex >= 0 && cfg.toggleIndex < cfg.toggleTexts.Length) { component.SetToggleIndex(cfg.toggleIndex); } } } else if (cfg.type == "Label") { NativeLabel component2 = val.GetComponent<NativeLabel>(); if (component2 != null) { component2.SetPosition(cfg.position); component2.SetSize(cfg.size.x, cfg.size.y); if (!string.IsNullOrEmpty(cfg.labelText)) { component2.SetText(cfg.labelText.Trim()); } if (cfg.fontSize > 0) { component2.SetFontSize(cfg.fontSize); } component2.SetColor(cfg.color); component2.SetDraggable(cfg.draggable); } } else if (cfg.type == "Slider") { NativeSlider component3 = val.GetComponent<NativeSlider>(); if (component3 != null) { if (!string.IsNullOrEmpty(cfg.labelText)) { component3.SetLabel(cfg.labelText.Trim()); } component3.SetMinMax(cfg.minValue, cfg.maxValue, cfg.wholeNumbers); component3.SetValueWithoutNotify(cfg.value); component3.SetDraggable(cfg.draggable); component3.SetSliderXOffset(cfg.sliderXOffset); component3.SetSliderWidth(cfg.sliderWidth); component3.SetLabelXOffset(cfg.labelXOffset); component3.SetValueXOffset(cfg.valueXOffset); component3.SetPosition(cfg.position); component3.SetSize(cfg.size.x, cfg.size.y); } } else if (cfg.type == "Option") { NativeOption component4 = val.GetComponent<NativeOption>(); if (component4 != null) { component4.SetPosition(cfg.position); component4.SetSize(cfg.size.x, cfg.size.y); if (!string.IsNullOrEmpty(cfg.labelText)) { component4.SetLabel(cfg.labelText.Trim()); } if (!string.IsNullOrEmpty(cfg.description)) { component4.SetDescription(cfg.description.Trim()); } if (cfg.options != null && cfg.options.Length != 0) { component4.SetOptions(cfg.options, cfg.optionIndex); } component4.SetDraggable(cfg.draggable); } } else if (cfg.type == "Arrow") { NativeArrow component5 = val.GetComponent<NativeArrow>(); if (component5 == null) { return; } component5.SetPosition(cfg.position); component5.SetSize(cfg.size.x, cfg.size.y); bool clickable = cfg.clickable; object obj = <>c.<>9__248_0; if (obj == null) { UnityAction val2 = delegate { Debug.Log((object)UILocale.Get("箭头被点击")); }; <>c.<>9__248_0 = val2; obj = (object)val2; } component5.SetClickable(clickable, (UnityAction)obj); component5.SetDraggable(cfg.draggable); } else { if (!(cfg.type == "Input")) { return; } NativeInput component6 = val.GetComponent<NativeInput>(); if (component6 != null) { component6.SetPosition(cfg.position); component6.SetSize(cfg.size.x, cfg.size.y); component6.SetText(cfg.inputText); Graphic placeholder = component6.inputField.placeholder; Text val3 = (Text)(object)((placeholder is Text) ? placeholder : null); if ((Object)(object)val3 != (Object)null) { val3.text = cfg.placeholderText; } } } } private GameObject FindChildByName(Transform parent, string name) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (((Object)parent).name == name) { return ((Component)parent).gameObject; } foreach (Transform item in parent) { Transform parent2 = item; GameObject val = FindChildByName(parent2, name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void CleanInvalidControls() { _externalButtons.RemoveAll((NativeButton b) => b == null || (Object)(object)b.gameObject == (Object)null); _externalLabels.RemoveAll((NativeLabel l) => l == null || (Object)(object)l.gameObject == (Object)null); _externalSliders.RemoveAll((NativeSlider s) => s == null || (Object)(object)s.gameObject == (Object)null); _externalOptions.RemoveAll((NativeOption o) => o == null || (Object)(object)o.gameObject == (Object)null); _externalArrows.RemoveAll((NativeArrow a) => a == null || (Object)(object)a.gameObject == (Object)null); _externalInputs.RemoveAll((NativeInput i) => i == null || (Object)(object)i.gameObject == (Object)null); } private void EnsureUniqueNames() { EnsureUniqueNamesInList(_externalButtons); EnsureUniqueNamesInList(_externalLabels); EnsureUniqueNamesInList(_externalSliders); EnsureUniqueNamesInList(_externalOptions); EnsureUniqueNamesInList(_externalArrows); EnsureUniqueNamesInList(_externalInputs); } private void EnsureUniqueNamesInList<T>(List<T> list) where T : class { if (list == null) { return; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); List<GameObject> list2 = new List<GameObject>(); foreach (T item in list) { GameObject val = null; if (item is NativeButton nativeButton) { val = nativeButton.gameObject; } else if (item is NativeLabel nativeLabel) { val = nativeLabel.gameObject; } else if (item is NativeSlider nativeSlider) { val = nativeSlider.gameObject; } else if (item is NativeOption nativeOption) { val = nativeOption.gameObject; } else if (item is NativeArrow nativeArrow) { val = nativeArrow.gameObject; } else if (item is NativeInput nativeInput) { val = nativeInput.gameObject; } if ((Object)(object)val != (Object)null) { list2.Add(val); } } foreach (GameObject item2 in list2) { string name = ((Object)item2).name; if (dictionary.ContainsKey(name)) { dictionary[name]++; } else { dictionary[name] = 1; } } Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); foreach (GameObject item3 in list2) { string name2 = ((Object)item3).name; if (dictionary[name2] > 1) { if (!dictionary2.ContainsKey(name2)) { dictionary2[name2] = 1; } else { dictionary2[name2]++; } if (dictionary2[name2] > 1) { string text = (((Object)item3).name = $"{name2}_{dictionary2[name2]}"); Debug.Log((object)("[DebugWindow] 为避免重名,已将控件 " + name2 + " 重命名为 " + text)); } } } } private void SaveConfigToFile() { CleanInvalidControls(); _externalButtons.RemoveAll((NativeButton btn) => NativeArrow.AllInstances.Any((NativeArrow arr) => arr != null && (Object)(object)arr.gameObject == (Object)(object)btn.gameObject)); EnsureUniqueNames(); string text = Path.Combine(PluginDirectory, "NativeUIMaker_Config.json"); ConfigData configData = new ConfigData(); CollectControls(_allButtons, "Button", configData); CollectControls(_allLabels, "Label", configData); CollectControls(_allSliders, "Slider", configData); CollectControls(_allOptions, "Option", configData); CollectControls(_allArrows, "Arrow", configData); CollectControls(_allInputs, "Input", configData); CollectControls(_externalButtons, "Button", configData); CollectControls(_externalLabels, "Label", configData); CollectControls(_externalSliders, "Slider", configData); CollectControls(_externalOptions, "Option", configData); CollectControls(_externalArrows, "Arrow", configData); CollectControls(_externalInputs, "Input", configData); File.WriteAllText(text, JsonConvert.SerializeObject((object)configData, SlimJson.Settings)); Debug.Log((object)$"配置已保存至 {text},共 {configData.controls.Count} 项"); } private string GetPageNameForControl(GameObject go) { Transform val = go.transform; while ((Object)(object)val != (Object)null) { foreach (NativePage allInstance in NativePage.AllInstances) { if ((Object)(object)allInstance.gameObject == (Object)(object)((Component)val).gameObject) { return ((Object)allInstance.gameObject).name; } } val = val.parent; } return null; } private void CollectControls<T>(List<T> list, string typeName, ConfigData data) where T : class { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might
BepInEx/plugins/Newtonsoft.Json.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Data; using System.Data.SqlTypes; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Xml; using System.Xml.Linq; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq.JsonPath; using Newtonsoft.Json.Schema; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")] [assembly: CLSCompliant(true)] [assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] [assembly: AssemblyCompany("Newtonsoft")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © James Newton-King 2008")] [assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")] [assembly: AssemblyFileVersion("13.0.4.30916")] [assembly: AssemblyInformationalVersion("13.0.4+4e13299d4b0ec96bd4df9954ef646bd2d1b5bf2a")] [assembly: AssemblyProduct("Json.NET")] [assembly: AssemblyTitle("Json.NET .NET 4.0")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyVersion("13.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)] internal sealed class DynamicallyAccessedMembersAttribute : Attribute { public DynamicallyAccessedMemberTypes MemberTypes { get; } public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) { MemberTypes = memberTypes; } } [Flags] internal enum DynamicallyAccessedMemberTypes { None = 0, PublicParameterlessConstructor = 1, PublicConstructors = 3, NonPublicConstructors = 4, PublicMethods = 8, NonPublicMethods = 0x10, PublicFields = 0x20, NonPublicFields = 0x40, PublicNestedTypes = 0x80, NonPublicNestedTypes = 0x100, PublicProperties = 0x200, NonPublicProperties = 0x400, PublicEvents = 0x800, NonPublicEvents = 0x1000, Interfaces = 0x2000, All = -1 } [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class FeatureGuardAttribute : Attribute { public Type FeatureType { get; } public FeatureGuardAttribute(Type featureType) { FeatureType = featureType; } } [AttributeUsage(AttributeTargets.Property, Inherited = false)] internal sealed class FeatureSwitchDefinitionAttribute : Attribute { public string SwitchName { get; } public FeatureSwitchDefinitionAttribute(string switchName) { SwitchName = switchName; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)] internal sealed class RequiresDynamicCodeAttribute : Attribute { public string Message { get; } public string? Url { get; set; } public RequiresDynamicCodeAttribute(string message) { Message = message; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)] internal sealed class RequiresUnreferencedCodeAttribute : Attribute { public string Message { get; } public string? Url { get; set; } public RequiresUnreferencedCodeAttribute(string message) { Message = message; } } [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] internal sealed class UnconditionalSuppressMessageAttribute : Attribute { public string Category { get; } public string CheckId { get; } public string? Scope { get; set; } public string? Target { get; set; } public string? MessageId { get; set; } public string? Justification { get; set; } public UnconditionalSuppressMessageAttribute(string category, string checkId) { Category = category; CheckId = checkId; } } } namespace Newtonsoft.Json { public enum ConstructorHandling { Default, AllowNonPublicDefaultConstructor } public enum DateFormatHandling { IsoDateFormat, MicrosoftDateFormat } public enum DateParseHandling { None, DateTime, DateTimeOffset } public enum DateTimeZoneHandling { Local, Utc, Unspecified, RoundtripKind } public class DefaultJsonNameTable : JsonNameTable { private class Entry { internal readonly string Value; internal readonly int HashCode; internal Entry Next; internal Entry(string value, int hashCode, Entry next) { Value = value; HashCode = hashCode; Next = next; } } private static readonly int HashCodeRandomizer; private int _count; private Entry[] _entries; private int _mask = 31; static DefaultJsonNameTable() { HashCodeRandomizer = Environment.TickCount; } public DefaultJsonNameTable() { _entries = new Entry[_mask + 1]; } public override string? Get(char[] key, int start, int length) { if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; num += (num << 7) ^ key[start]; int num2 = start + length; for (int i = start + 1; i < num2; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; int num3 = Thread.VolatileRead(ref _mask); int num4 = num & num3; for (Entry entry = _entries[num4]; entry != null; entry = entry.Next) { if (entry.HashCode == num && TextEquals(entry.Value, key, start, length)) { return entry.Value; } } return null; } public string Add(string key) { if (key == null) { throw new ArgumentNullException("key"); } int length = key.Length; if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; for (int i = 0; i < key.Length; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next) { if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal)) { return entry.Value; } } return AddEntry(key, num); } private string AddEntry(string str, int hashCode) { int num = hashCode & _mask; Entry entry = new Entry(str, hashCode, _entries[num]); _entries[num] = entry; if (_count++ == _mask) { Grow(); } return entry.Value; } private void Grow() { Entry[] entries = _entries; int num = _mask * 2 + 1; Entry[] array = new Entry[num + 1]; for (int i = 0; i < entries.Length; i++) { Entry entry = entries[i]; while (entry != null) { int num2 = entry.HashCode & num; Entry next = entry.Next; entry.Next = array[num2]; array[num2] = entry; entry = next; } } _entries = array; Thread.VolatileWrite(ref _mask, num); } private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length) { if (str1.Length != str2Length) { return false; } for (int i = 0; i < str1.Length; i++) { if (str1[i] != str2[str2Start + i]) { return false; } } return true; } } [Flags] public enum DefaultValueHandling { Include = 0, Ignore = 1, Populate = 2, IgnoreAndPopulate = 3 } public enum FloatFormatHandling { String, Symbol, DefaultValue } public enum FloatParseHandling { Double, Decimal } public enum Formatting { None, Indented } public interface IArrayPool<T> { T[] Rent(int minimumLength); void Return(T[]? array); } public interface IJsonLineInfo { int LineNumber { get; } int LinePosition { get; } bool HasLineInfo(); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonArrayAttribute : JsonContainerAttribute { private bool _allowNullItems; public bool AllowNullItems { get { return _allowNullItems; } set { _allowNullItems = value; } } public JsonArrayAttribute() { } public JsonArrayAttribute(bool allowNullItems) { _allowNullItems = allowNullItems; } public JsonArrayAttribute(string id) : base(id) { } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] public sealed class JsonConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class JsonContainerAttribute : Attribute { internal bool? _isReference; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; private Type? _namingStrategyType; private object[]? _namingStrategyParameters; public string? Id { get; set; } public string? Title { get; set; } public string? Description { get; set; } public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get { return _namingStrategyType; } set { _namingStrategyType = value; NamingStrategyInstance = null; } } public object[]? NamingStrategyParameters { get { return _namingStrategyParameters; } set { _namingStrategyParameters = value; NamingStrategyInstance = null; } } internal NamingStrategy? NamingStrategyInstance { get; set; } public bool IsReference { get { return _isReference == true; } set { _isReference = value; } } public bool ItemIsReference { get { return _itemIsReference == true; } set { _itemIsReference = value; } } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } protected JsonContainerAttribute() { } protected JsonContainerAttribute(string id) { Id = id; } } public static class JsonConvert { public static readonly string True = "true"; public static readonly string False = "false"; public static readonly string Null = "null"; public static readonly string Undefined = "undefined"; public static readonly string PositiveInfinity = "Infinity"; public static readonly string NegativeInfinity = "-Infinity"; public static readonly string NaN = "NaN"; public static Func<JsonSerializerSettings>? DefaultSettings { get; set; } public static string ToString(DateTime value) { return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); } public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) { DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(DateTimeOffset value) { return ToString(value, DateFormatHandling.IsoDateFormat); } public static string ToString(DateTimeOffset value, DateFormatHandling format) { using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(bool value) { if (!value) { return False; } return True; } public static string ToString(char value) { return ToString(char.ToString(value)); } public static string ToString(Enum value) { return value.ToString("D"); } public static string ToString(int value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(short value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ushort value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(uint value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(long value) { return value.ToString(null, CultureInfo.InvariantCulture); } private static string ToStringInternal(BigInteger value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ulong value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(float value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value))) { return text; } if (floatFormatHandling == FloatFormatHandling.DefaultValue) { if (nullable) { return Null; } return "0.0"; } return quoteChar + text + quoteChar; } public static string ToString(double value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureDecimalPlace(double value, string text) { if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1) { return text; } return text + ".0"; } private static string EnsureDecimalPlace(string text) { if (StringUtils.IndexOf(text, '.') != -1) { return text; } return text + ".0"; } public static string ToString(byte value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(sbyte value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(decimal value) { return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); } public static string ToString(Guid value) { return ToString(value, '"'); } internal static string ToString(Guid value, char quoteChar) { string text = value.ToString("D", CultureInfo.InvariantCulture); string text2 = quoteChar.ToString(CultureInfo.InvariantCulture); return text2 + text + text2; } public static string ToString(TimeSpan value) { return ToString(value, '"'); } internal static string ToString(TimeSpan value, char quoteChar) { return ToString(value.ToString(), quoteChar); } public static string ToString(Uri? value) { if (value == null) { return Null; } return ToString(value, '"'); } internal static string ToString(Uri value, char quoteChar) { return ToString(value.OriginalString, quoteChar); } public static string ToString(string? value) { return ToString(value, '"'); } public static string ToString(string? value, char delimiter) { return ToString(value, delimiter, StringEscapeHandling.Default); } public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling) { if (delimiter != '"' && delimiter != '\'') { throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); } return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling); } public static string ToString(object? value) { if (value == null) { return Null; } return ConvertUtils.GetTypeCode(value.GetType()) switch { PrimitiveTypeCode.String => ToString((string)value), PrimitiveTypeCode.Char => ToString((char)value), PrimitiveTypeCode.Boolean => ToString((bool)value), PrimitiveTypeCode.SByte => ToString((sbyte)value), PrimitiveTypeCode.Int16 => ToString((short)value), PrimitiveTypeCode.UInt16 => ToString((ushort)value), PrimitiveTypeCode.Int32 => ToString((int)value), PrimitiveTypeCode.Byte => ToString((byte)value), PrimitiveTypeCode.UInt32 => ToString((uint)value), PrimitiveTypeCode.Int64 => ToString((long)value), PrimitiveTypeCode.UInt64 => ToString((ulong)value), PrimitiveTypeCode.Single => ToString((float)value), PrimitiveTypeCode.Double => ToString((double)value), PrimitiveTypeCode.DateTime => ToString((DateTime)value), PrimitiveTypeCode.Decimal => ToString((decimal)value), PrimitiveTypeCode.DBNull => Null, PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), PrimitiveTypeCode.Guid => ToString((Guid)value), PrimitiveTypeCode.Uri => ToString((Uri)value), PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), _ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), }; } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value) { return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, Formatting formatting) { return SerializeObject(value, formatting, (JsonSerializerSettings?)null); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, JsonSerializerSettings? settings) { return SerializeObject(value, null, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); return SerializeObjectInternal(value, type, jsonSerializer); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings) { return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); jsonSerializer.Formatting = formatting; return SerializeObjectInternal(value, type, jsonSerializer); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer) { StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) { jsonTextWriter.Formatting = jsonSerializer.Formatting; jsonSerializer.Serialize(jsonTextWriter, value, type); } return stringWriter.ToString(); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static object? DeserializeObject(string value) { return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static object? DeserializeObject(string value, JsonSerializerSettings settings) { return DeserializeObject(value, null, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static object? DeserializeObject(string value, Type type) { return DeserializeObject(value, type, (JsonSerializerSettings?)null); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static T? DeserializeObject<T>(string value) { return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject) { return DeserializeObject<T>(value); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings) { return DeserializeObject<T>(value, settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static T? DeserializeObject<T>(string value, params JsonConverter[] converters) { return (T)DeserializeObject(value, typeof(T), converters); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings) { return (T)DeserializeObject(value, typeof(T), settings); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return DeserializeObject(value, type, settings); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings) { ValidationUtils.ArgumentNotNull(value, "value"); JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); if (!jsonSerializer.IsCheckAdditionalContentSet()) { jsonSerializer.CheckAdditionalContent = true; } using JsonTextReader reader = new JsonTextReader(new StringReader(value)); return jsonSerializer.Deserialize(reader, type); } [DebuggerStepThrough] [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static void PopulateObject(string value, object target) { PopulateObject(value, target, null); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static void PopulateObject(string value, object target, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); using JsonReader jsonReader = new JsonTextReader(new StringReader(value)); jsonSerializer.Populate(jsonReader, target); if (settings == null || !settings.CheckAdditionalContent) { return; } while (jsonReader.Read()) { if (jsonReader.TokenType != JsonToken.Comment) { throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object."); } } } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXmlNode(XmlNode? node) { return SerializeXmlNode(node, Formatting.None); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXmlNode(XmlNode? node, Formatting formatting) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); return SerializeObject(node, formatting, xmlNodeConverter); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XmlDocument? DeserializeXmlNode(string value) { return DeserializeXmlNode(value, null); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXNode(XObject? node) { return SerializeXNode(node, Formatting.None); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXNode(XObject? node, Formatting formatting) { return SerializeXNode(node, formatting, omitRootObject: false); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XDocument? DeserializeXNode(string value) { return DeserializeXNode(value, null); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter); } } public abstract class JsonConverter { public virtual bool CanRead => true; public virtual bool CanWrite => true; public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer); public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer); public abstract bool CanConvert(Type objectType); } public abstract class JsonConverter<T> : JsonConverter { public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T)))) { throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } WriteJson(writer, (T)value, serializer); } public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer); public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { bool flag = existingValue == null; if (!flag && !(existingValue is T)) { throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer); } public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer); public sealed override bool CanConvert(Type objectType) { return typeof(T).IsAssignableFrom(objectType); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonConverterAttribute : Attribute { private readonly Type _converterType; public Type ConverterType => _converterType; public object[]? ConverterParameters { get; } public JsonConverterAttribute(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } _converterType = converterType; } public JsonConverterAttribute(Type converterType, params object[] converterParameters) : this(converterType) { ConverterParameters = converterParameters; } } public class JsonConverterCollection : Collection<JsonConverter> { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonDictionaryAttribute : JsonContainerAttribute { public JsonDictionaryAttribute() { } public JsonDictionaryAttribute(string id) : base(id) { } } [Serializable] public class JsonException : Exception { public JsonException() { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception? innerException) : base(message, innerException) { } public JsonException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) { message = JsonPosition.FormatMessage(lineInfo, path, message); return new JsonException(message); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class JsonExtensionDataAttribute : Attribute { public bool WriteData { get; set; } public bool ReadData { get; set; } public JsonExtensionDataAttribute() { WriteData = true; ReadData = true; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonIgnoreAttribute : Attribute { } public abstract class JsonNameTable { public abstract string? Get(char[] key, int start, int length); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonObjectAttribute : JsonContainerAttribute { private MemberSerialization _memberSerialization; internal MissingMemberHandling? _missingMemberHandling; internal Required? _itemRequired; internal NullValueHandling? _itemNullValueHandling; public MemberSerialization MemberSerialization { get { return _memberSerialization; } set { _memberSerialization = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling.GetValueOrDefault(); } set { _missingMemberHandling = value; } } public NullValueHandling ItemNullValueHandling { get { return _itemNullValueHandling.GetValueOrDefault(); } set { _itemNullValueHandling = value; } } public Required ItemRequired { get { return _itemRequired.GetValueOrDefault(); } set { _itemRequired = value; } } public JsonObjectAttribute() { } public JsonObjectAttribute(MemberSerialization memberSerialization) { MemberSerialization = memberSerialization; } public JsonObjectAttribute(string id) : base(id) { } } internal enum JsonContainerType { None, Object, Array, Constructor } internal struct JsonPosition { private static readonly char[] SpecialCharacters = new char[18] { '.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t', '\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029' }; internal JsonContainerType Type; internal int Position; internal string? PropertyName; internal bool HasIndex; public JsonPosition(JsonContainerType type) { Type = type; HasIndex = TypeHasIndex(type); Position = -1; PropertyName = null; } internal int CalculateLength() { switch (Type) { case JsonContainerType.Object: return PropertyName.Length + 5; case JsonContainerType.Array: case JsonContainerType.Constructor: return MathUtils.IntLength((ulong)Position) + 2; default: throw new ArgumentOutOfRangeException("Type"); } } internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer) { switch (Type) { case JsonContainerType.Object: { string propertyName = PropertyName; if (propertyName.IndexOfAny(SpecialCharacters) != -1) { sb.Append("['"); if (writer == null) { writer = new StringWriter(sb); } JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer); sb.Append("']"); } else { if (sb.Length > 0) { sb.Append('.'); } sb.Append(propertyName); } break; } case JsonContainerType.Array: case JsonContainerType.Constructor: sb.Append('['); sb.Append(Position); sb.Append(']'); break; } } internal static bool TypeHasIndex(JsonContainerType type) { if (type != JsonContainerType.Array) { return type == JsonContainerType.Constructor; } return true; } internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition) { int num = 0; if (positions != null) { for (int i = 0; i < positions.Count; i++) { num += positions[i].CalculateLength(); } } if (currentPosition.HasValue) { num += currentPosition.GetValueOrDefault().CalculateLength(); } StringBuilder stringBuilder = new StringBuilder(num); StringWriter writer = null; char[] buffer = null; if (positions != null) { foreach (JsonPosition position in positions) { position.WriteTo(stringBuilder, ref writer, ref buffer); } } currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer); return stringBuilder.ToString(); } internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message) { if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal)) { message = message.Trim(); if (!StringUtils.EndsWith(message, '.')) { message += "."; } message += " "; } message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); if (lineInfo != null && lineInfo.HasLineInfo()) { message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); } message += "."; return message; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonPropertyAttribute : Attribute { internal NullValueHandling? _nullValueHandling; internal DefaultValueHandling? _defaultValueHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal ObjectCreationHandling? _objectCreationHandling; internal TypeNameHandling? _typeNameHandling; internal bool? _isReference; internal int? _order; internal Required? _required; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get; set; } public object[]? NamingStrategyParameters { get; set; } public NullValueHandling NullValueHandling { get { return _nullValueHandling.GetValueOrDefault(); } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling.GetValueOrDefault(); } set { _defaultValueHandling = value; } } public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling.GetValueOrDefault(); } set { _referenceLoopHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling.GetValueOrDefault(); } set { _objectCreationHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling.GetValueOrDefault(); } set { _typeNameHandling = value; } } public bool IsReference { get { return _isReference == true; } set { _isReference = value; } } public int Order { get { return _order.GetValueOrDefault(); } set { _order = value; } } public Required Required { get { return _required.GetValueOrDefault(); } set { _required = value; } } public string? PropertyName { get; set; } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } public bool ItemIsReference { get { return _itemIsReference == true; } set { _itemIsReference = value; } } public JsonPropertyAttribute() { } public JsonPropertyAttribute(string propertyName) { PropertyName = propertyName; } } public abstract class JsonReader : IDisposable { protected internal enum State { Start, Complete, Property, ObjectStart, Object, ArrayStart, Array, Closed, PostValue, ConstructorStart, Constructor, Error, Finished } private JsonToken _tokenType; private object? _value; internal char _quoteChar; internal State _currentState; private JsonPosition _currentPosition; private CultureInfo? _culture; private DateTimeZoneHandling _dateTimeZoneHandling; private int? _maxDepth; private bool _hasExceededMaxDepth; internal DateParseHandling _dateParseHandling; internal FloatParseHandling _floatParseHandling; private string? _dateFormatString; private List<JsonPosition>? _stack; protected State CurrentState => _currentState; public bool CloseInput { get; set; } public bool SupportMultipleContent { get; set; } public virtual char QuoteChar { get { return _quoteChar; } protected internal set { _quoteChar = value; } } public DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling; } set { if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind) { throw new ArgumentOutOfRangeException("value"); } _dateTimeZoneHandling = value; } } public DateParseHandling DateParseHandling { get { return _dateParseHandling; } set { if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset) { throw new ArgumentOutOfRangeException("value"); } _dateParseHandling = value; } } public FloatParseHandling FloatParseHandling { get { return _floatParseHandling; } set { if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal) { throw new ArgumentOutOfRangeException("value"); } _floatParseHandling = value; } } public string? DateFormatString { get { return _dateFormatString; } set { _dateFormatString = value; } } public int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; } } public virtual JsonToken TokenType => _tokenType; public virtual object? Value => _value; public virtual Type? ValueType => _value?.GetType(); public virtual int Depth { get { int num = _stack?.Count ?? 0; if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) { return num; } return num + 1; } } public virtual string Path { get { if (_currentPosition.Type == JsonContainerType.None) { return string.Empty; } JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : ((JsonPosition?)null)); return JsonPosition.BuildPath(_stack, currentPosition); } } public CultureInfo Culture { get { return _culture ?? CultureInfo.InvariantCulture; } set { _culture = value; } } internal JsonPosition GetPosition(int depth) { if (_stack != null && depth < _stack.Count) { return _stack[depth]; } return _currentPosition; } protected JsonReader() { _currentState = State.Start; _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; _dateParseHandling = DateParseHandling.DateTime; _floatParseHandling = FloatParseHandling.Double; _maxDepth = 64; CloseInput = true; } private void Push(JsonContainerType value) { UpdateScopeWithFinishedValue(); if (_currentPosition.Type == JsonContainerType.None) { _currentPosition = new JsonPosition(value); return; } if (_stack == null) { _stack = new List<JsonPosition>(); } _stack.Add(_currentPosition); _currentPosition = new JsonPosition(value); if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth) { return; } _hasExceededMaxDepth = true; throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); } private JsonContainerType Pop() { JsonPosition currentPosition; if (_stack != null && _stack.Count > 0) { currentPosition = _currentPosition; _currentPosition = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); } else { currentPosition = _currentPosition; _currentPosition = default(JsonPosition); } if (_maxDepth.HasValue && Depth <= _maxDepth) { _hasExceededMaxDepth = false; } return currentPosition.Type; } private JsonContainerType Peek() { return _currentPosition.Type; } public abstract bool Read(); public virtual int? ReadAsInt32() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is int) { return (int)value; } int num; if (value is BigInteger bigInteger) { num = (int)bigInteger; } else { try { num = Convert.ToInt32(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Integer, num, updateIndex: false); return num; } case JsonToken.String: { string s = (string)Value; return ReadInt32String(s); } default: throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal int? ReadInt32String(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (int.TryParse(s, NumberStyles.Integer, Culture, out var result)) { SetToken(JsonToken.Integer, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual string? ReadAsString() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.String: return (string)Value; default: if (JsonTokenUtils.IsPrimitiveToken(contentToken)) { object value = Value; if (value != null) { string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture)); SetToken(JsonToken.String, text, updateIndex: false); return text; } } throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } public virtual byte[]? ReadAsBytes() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.StartObject: { ReadIntoWrappedTypeObject(); byte[] array2 = ReadAsBytes(); ReaderReadAndAssert(); if (TokenType != JsonToken.EndObject) { throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } SetToken(JsonToken.Bytes, array2, updateIndex: false); return array2; } case JsonToken.String: { string text = (string)Value; Guid g; byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray())); SetToken(JsonToken.Bytes, array3, updateIndex: false); return array3; } case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Bytes: if (Value is Guid guid) { byte[] array = guid.ToByteArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } return (byte[])Value; case JsonToken.StartArray: return ReadArrayIntoByteArray(); default: throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal byte[] ReadArrayIntoByteArray() { List<byte> list = new List<byte>(); do { if (!Read()) { SetToken(JsonToken.None); } } while (!ReadArrayElementIntoByteArrayReportDone(list)); byte[] array = list.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer) { switch (TokenType) { case JsonToken.None: throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); case JsonToken.Integer: buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); return false; case JsonToken.EndArray: return true; case JsonToken.Comment: return false; default: throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } public virtual double? ReadAsDouble() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is double) { return (double)value; } double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger)); SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDoubleString((string)Value); default: throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal double? ReadDoubleString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual bool? ReadAsBoolean() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L)); SetToken(JsonToken.Boolean, flag, updateIndex: false); return flag; } case JsonToken.String: return ReadBooleanString((string)Value); case JsonToken.Boolean: return (bool)Value; default: throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal bool? ReadBooleanString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (bool.TryParse(s, out var result)) { SetToken(JsonToken.Boolean, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual decimal? ReadAsDecimal() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is decimal) { return (decimal)value; } decimal num; if (value is BigInteger bigInteger) { num = (decimal)bigInteger; } else { try { num = Convert.ToDecimal(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDecimalString((string)Value); default: throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal decimal? ReadDecimalString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTime? ReadAsDateTime() { switch (GetContentToken()) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTimeOffset dateTimeOffset) { SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false); } return (DateTime)Value; case JsonToken.String: return ReadDateTimeString((string)Value); default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } internal DateTime? ReadDateTimeString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTimeOffset? ReadAsDateTimeOffset() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTime dateTime) { SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false); } return (DateTimeOffset)Value; case JsonToken.String: { string s = (string)Value; return ReadDateTimeOffsetString(s); } default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal DateTimeOffset? ReadDateTimeOffsetString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } internal void ReaderReadAndAssert() { if (!Read()) { throw CreateUnexpectedEndException(); } } internal JsonReaderException CreateUnexpectedEndException() { return JsonReaderException.Create(this, "Unexpected end when reading JSON."); } internal void ReadIntoWrappedTypeObject() { ReaderReadAndAssert(); if (Value != null && Value.ToString() == "$type") { ReaderReadAndAssert(); if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal)) { ReaderReadAndAssert(); if (Value.ToString() == "$value") { return; } } } throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); } public void Skip() { if (TokenType == JsonToken.PropertyName) { Read(); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (Read() && depth < Depth) { } } } protected void SetToken(JsonToken newToken) { SetToken(newToken, null, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value) { SetToken(newToken, value, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value, bool updateIndex) { _tokenType = newToken; _value = value; switch (newToken) { case JsonToken.StartObject: _currentState = State.ObjectStart; Push(JsonContainerType.Object); break; case JsonToken.StartArray: _currentState = State.ArrayStart; Push(JsonContainerType.Array); break; case JsonToken.StartConstructor: _currentState = State.ConstructorStart; Push(JsonContainerType.Constructor); break; case JsonToken.EndObject: ValidateEnd(JsonToken.EndObject); break; case JsonToken.EndArray: ValidateEnd(JsonToken.EndArray); break; case JsonToken.EndConstructor: ValidateEnd(JsonToken.EndConstructor); break; case JsonToken.PropertyName: _currentState = State.Property; _currentPosition.PropertyName = (string)value; break; case JsonToken.Raw: case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.Undefined: case JsonToken.Date: case JsonToken.Bytes: SetPostValueState(updateIndex); break; case JsonToken.Comment: break; } } internal void SetPostValueState(bool updateIndex) { if (Peek() != JsonContainerType.None || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } if (updateIndex) { UpdateScopeWithFinishedValue(); } } private void UpdateScopeWithFinishedValue() { if (_currentPosition.HasIndex) { _currentPosition.Position++; } } private void ValidateEnd(JsonToken endToken) { JsonContainerType jsonContainerType = Pop(); if (GetTypeForCloseToken(endToken) != jsonContainerType) { throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType)); } if (Peek() != JsonContainerType.None || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } } protected void SetStateBasedOnCurrent() { JsonContainerType jsonContainerType = Peek(); switch (jsonContainerType) { case JsonContainerType.Object: _currentState = State.Object; break; case JsonContainerType.Array: _currentState = State.Array; break; case JsonContainerType.Constructor: _currentState = State.Constructor; break; case JsonContainerType.None: SetFinished(); break; default: throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType)); } } private void SetFinished() { _currentState = ((!SupportMultipleContent) ? State.Finished : State.Start); } private JsonContainerType GetTypeForCloseToken(JsonToken token) { return token switch { JsonToken.EndObject => JsonContainerType.Object, JsonToken.EndArray => JsonContainerType.Array, JsonToken.EndConstructor => JsonContainerType.Constructor, _ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), }; } void IDisposable.Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_currentState != State.Closed && disposing) { Close(); } } public virtual void Close() { _currentState = State.Closed; _tokenType = JsonToken.None; _value = null; } internal void ReadAndAssert() { if (!Read()) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter) { if (!ReadForType(contract, hasConverter)) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal bool ReadForType(JsonContract? contract, bool hasConverter) { if (hasConverter) { return Read(); } switch (contract?.InternalReadType ?? ReadType.Read) { case ReadType.Read: return ReadAndMoveToContent(); case ReadType.ReadAsInt32: ReadAsInt32(); break; case ReadType.ReadAsInt64: { bool result = ReadAndMoveToContent(); if (TokenType == JsonToken.Undefined) { throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long))); } return result; } case ReadType.ReadAsDecimal: ReadAsDecimal(); break; case ReadType.ReadAsDouble: ReadAsDouble(); break; case ReadType.ReadAsBytes: ReadAsBytes(); break; case ReadType.ReadAsBoolean: ReadAsBoolean(); break; case ReadType.ReadAsString: ReadAsString(); break; case ReadType.ReadAsDateTime: ReadAsDateTime(); break; case ReadType.ReadAsDateTimeOffset: ReadAsDateTimeOffset(); break; default: throw new ArgumentOutOfRangeException(); } return TokenType != JsonToken.None; } internal bool ReadAndMoveToContent() { if (Read()) { return MoveToContent(); } return false; } internal bool MoveToContent() { JsonToken tokenType = TokenType; while (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { if (!Read()) { return false; } tokenType = TokenType; } return true; } private JsonToken GetContentToken() { JsonToken tokenType; do { if (!Read()) { SetToken(JsonToken.None); return JsonToken.None; } tokenType = TokenType; } while (tokenType == JsonToken.Comment); return tokenType; } } [Serializable] public class JsonReaderException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonReaderException() { } public JsonReaderException(string message) : base(message) { } public JsonReaderException(string message, Exception innerException) : base(message, innerException) { } public JsonReaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonReaderException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonReaderException(message, path, lineNumber, linePosition, ex); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonRequiredAttribute : Attribute { } [Serializable] public class JsonSerializationException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonSerializationException() { } public JsonSerializationException(string message) : base(message) { } public JsonSerializationException(string message, Exception innerException) : base(message, innerException) { } public JsonSerializationException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonSerializationException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonSerializationException(message, path, lineNumber, linePosition, ex); } } [RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")] [RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")] public class JsonSerializer { internal TypeNameHandling _typeNameHandling; internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling; internal PreserveReferencesHandling _preserveReferencesHandling; internal ReferenceLoopHandling _referenceLoopHandling; internal MissingMemberHandling _missingMemberHandling; internal ObjectCreationHandling _objectCreationHandling; internal NullValueHandling _nullValueHandling; internal DefaultValueHandling _defaultValueHandling; internal ConstructorHandling _constructorHandling; internal MetadataPropertyHandling _metadataPropertyHandling; internal JsonConverterCollection? _converters; internal IContractResolver _contractResolver; internal ITraceWriter? _traceWriter; internal IEqualityComparer? _equalityComparer; internal ISerializationBinder _serializationBinder; internal StreamingContext _context; private IReferenceResolver? _referenceResolver; private Formatting? _formatting; private DateFormatHandling? _dateFormatHandling; private DateTimeZoneHandling? _dateTimeZoneHandling; private DateParseHandling? _dateParseHandling; private FloatFormatHandling? _floatFormatHandling; private FloatParseHandling? _floatParseHandling; private StringEscapeHandling? _stringEscapeHandling; private CultureInfo _culture; private int? _maxDepth; private bool _maxDepthSet; private bool? _checkAdditionalContent; private string? _dateFormatString; private bool _dateFormatStringSet; public virtual IReferenceResolver? ReferenceResolver { get { return GetReferenceResolver(); } set { if (value == null) { throw new ArgumentNullException("value", "Reference resolver cannot be null."); } _referenceResolver = value; } } [Obsolete("Binder is obsolete. Use SerializationBinder instead.")] public virtual SerializationBinder Binder { get { if (_serializationBinder is SerializationBinder result) { return result; } if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter) { return serializationBinderAdapter.SerializationBinder; } throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set."); } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value); } } public virtual ISerializationBinder SerializationBinder { get { return _serializationBinder; } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = value; } } public virtual ITraceWriter? TraceWriter { get { return _traceWriter; } set { _traceWriter = value; } } public virtual IEqualityComparer? EqualityComparer { get { return _equalityComparer; } set { _equalityComparer = value; } } public virtual TypeNameHandling TypeNameHandling { get { return _typeNameHandling; } set { if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) { throw new ArgumentOutOfRangeException("value"); } _typeNameHandling = value; } } [Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")] public virtual FormatterAssemblyStyle TypeNameAssemblyFormat { get { return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling; } set { if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value; } } public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling { get { return _typeNameAssemblyFormatHandling; } set { if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = value; } } public virtual PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling; } set { if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) { throw new ArgumentOutOfRangeException("value"); } _preserveReferencesHandling = value; } } public virtual ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling; } set { if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) { throw new ArgumentOutOfRangeException("value"); } _referenceLoopHandling = value; } } public virtual MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling; } set { if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) { throw new ArgumentOutOfRangeException("value"); } _missingMemberHandling = value; } } public virtual NullValueHandling NullValueHandling { get { return _nullValueHandling; } set { if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _nullValueHandling = value; } } public virtual DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling; } set { if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) { throw new ArgumentOutOfRangeException("value"); } _defaultValueHandling = value; } } public virtual ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling; } set { if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) { throw new ArgumentOutOfRangeException("value"); } _objectCreationHandling = value; } } public virtual ConstructorHandling ConstructorHandling { get { return _constructorHandling; } set { if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) { throw new ArgumentOutOfRangeException("value"); } _constructorHandling = value; } } public virtual MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling; } set { if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _metadataPropertyHandling = value; } } public virtual JsonConverterCollection Converters { get { if (_converters == null) { _converters = new JsonConverterCollection(); } return _converters; } } public virtual IContractResolver ContractResolver { get { return _contractResolver; } set { _contractResolver = value ?? DefaultContractResolver.Instance; } } public virtual StreamingContext Context { get { return _context; } set { _context = value; } } public virtual Formatting Formatting { get { return _formatting.GetValueOrDefault(); } set { _formatting = value; } } public virtual DateFormatHandling DateFormatHandling { get { return _dateFormatHandling.GetValueOrDefault(); } set { _dateFormatHandling = value; } } public virtual DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind; } set { _dateTimeZoneHandling = value; } } public virtual DateParseHandling DateParseHandling { get { return _dateParseHandling ?? DateParseHandling.DateTime; } set { _dateParseHandling = value; } } public virtual FloatParseHandling FloatParseHandling { get { return _floatParseHandling.GetValueOrDefault(); } set { _floatParseHandling = value; } } public virtual FloatFormatHandling FloatFormatHandling { get { return _floatFormatHandling.GetValueOrDefault(); } set { _floatFormatHandling = value; } } public virtual StringEscapeHandling StringEscapeHandling { get { return _stringEscapeHandling.GetValueOrDefault(); } set { _stringEscapeHandling = value; } } public virtual string DateFormatString { get { return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; } set { _dateFormatString = value; _dateFormatStringSet = true; } } public virtual CultureInfo Culture { get { return _culture ?? JsonSerializerSettings.DefaultCulture; } set { _culture = value; } } public virtual int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; _maxDepthSet = true; } } public virtual bool CheckAdditionalContent { get { return _checkAdditionalContent == true; } set { _checkAdditionalContent = value; } } public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error; internal bool IsCheckAdditionalContentSet() { return _checkAdditionalContent.HasValue; } public JsonSerializer() { _referenceLoopHandling = ReferenceLoopHandling.Error; _missingMemberHandling = MissingMemberHandling.Ignore; _nullValueHandling = NullValueHandling.Include; _defaultValueHandling = DefaultValueHandling.Include; _objectCreationHandling = ObjectCreationHandling.Auto; _preserveReferencesHandling = PreserveReferencesHandling.None; _constructorHandling = ConstructorHandling.Default; _typeNameHandling = TypeNameHandling.None; _metadataPropertyHandling = MetadataPropertyHandling.Default; _context = JsonSerializerSettings.DefaultContext; _serializationBinder = DefaultSerializationBinder.Instance; _culture = JsonSerializerSettings.DefaultCulture; _contractResolver = DefaultContractResolver.Instance; } public static JsonSerializer Create() { return new JsonSerializer(); } public static JsonSerializer Create(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = Create(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } public static JsonSerializer CreateDefault() { return Create(JsonConvert.DefaultSettings?.Invoke()); } public static JsonSerializer CreateDefault(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = CreateDefault(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) { if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) { for (int i = 0; i < settings.Converters.Count; i++) { serializer.Converters.Insert(i, settings.Converters[i]); } } if (settings._typeNameHandling.HasValue) { serializer.TypeNameHandling = settings.TypeNameHandling; } if (settings._metadataPropertyHandling.HasValue) { serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling; } if (settings._typeNameAssemblyFormatHandling.HasValue) { serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling; } if (settings._preserveReferencesHandling.HasValue) { serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; } if (settings._referenceLoopHandling.HasValue) { serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; } if (settings._missingMemberHandling.HasValue) { serializer.MissingMemberHandling = settings.MissingMemberHandling; } if (settings._objectCreationHandling.HasValue) { serializer.ObjectCreationHandling = settings.ObjectCreationHandling; } if (settings._nullValueHandling.HasValue) { serializer.NullValueHandling = settings.NullValueHandling; } if (settings._defaultValueHandling.HasValue) { serializer.DefaultValueHandling = settings.DefaultValueHandling; } if (settings._constructorHandling.HasValue) { serializer.ConstructorHandling = settings.ConstructorHandling; } if (settings._context.HasValue) { serializer.Context = settings.Context; } if (settings._checkAdditionalContent.HasValue) { serializer._checkAdditionalContent = settings._checkAdditionalContent; } if (settings.Error != null) { serializer.Error += settings.Error; } if (settings.ContractResolver != null) { serializer.ContractResolver = settings.ContractResolver; } if (settings.ReferenceResolverProvider != null) { serializer.ReferenceResolver = settings.ReferenceResolverProvider(); } if (settings.TraceWriter != null) { serializer.TraceWriter = settings.TraceWriter; } if (settings.EqualityComparer != null) { serializer.EqualityComparer = settings.EqualityComparer; } if (settings.SerializationBinder != null) { serializer.SerializationBinder = settings.SerializationBinder; } if (settings._formatting.HasValue) { serializer._formatting = settings._formatting; } if (settings._dateFormatHandling.HasValue) { serializer._dateFormatHandling = settings._dateFormatHandling; } if (settings._dateTimeZoneHandling.HasValue) { serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; } if (settings._dateParseHandling.HasValue) { serializer._dateParseHandling = settings._dateParseHandling; } if (settings._dateFormatStringSet) { serializer._dateFormatString = settings._dateFormatString; serializer._dateFormatStringSet = settings._dateFormatStringSet; } if (settings._floatFormatHandling.HasValue) { serializer._floatFormatHandling = settings._floatFormatHandling; } if (settings._floatParseHandling.HasValue) { serializer._floatParseHandling = settings._floatParseHandling; } if (settings._stringEscapeHandling.HasValue) { serializer._stringEscapeHandling = settings._stringEscapeHandling; } if (settings._culture != null) { serializer._culture = settings._culture; } if (settings._maxDepthSet) { serializer._maxDepth = settings._maxDepth; serializer._maxDepthSet = settings._maxDepthSet; } } [DebuggerStepThrough] public void Populate(TextReader reader, object target) { Populate(new JsonTextReader(reader), target); } [DebuggerStepThrough] public void Populate(JsonReader reader, object target) { PopulateInternal(reader, target); } internal virtual void PopulateInternal(JsonReader reader, object target) { ValidationUtils.ArgumentNotNull(reader, "reader"); ValidationUtils.ArgumentNotNull(target, "target"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader) { return Deserialize(reader, null); } [DebuggerStepThrough] public object? Deserialize(TextReader reader, Type objectType) { return Deserialize(new JsonTextReader(reader), objectType); } [DebuggerStepThrough] public T? Deserialize<T>(JsonReader reader) { return (T)Deserialize(reader, typeof(T)); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader, Type? objectType) { return DeserializeInternal(reader, objectType); } internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType) { ValidationUtils.ArgumentNotNull(reader, "reader"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); return result; } internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString) { if (_culture != null && !_culture.Equals(reader.Culture)) { previousCulture = reader.Culture; reader.Culture = _culture; } else { previousCulture = null; } if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling) { previousDateTimeZoneHandling = reader.DateTimeZoneHandling; reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } else { previousDateTimeZoneHandling = null; } if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling) { previousDateParseHandling = reader.DateParseHandling; reader.DateParseHandling = _dateParseHandling.GetValueOrDefault(); } else { previousDateParseHandling = null; } if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling) { previousFloatParseHandling = reader.FloatParseHandling; reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault(); } else { previousFloatParseHandling = null; } if (_maxDepthSet && reader.MaxDepth != _maxDepth) { previousMaxDepth = reader.MaxDepth; reader.MaxDepth = _maxDepth; } else { previousMaxDepth = null; } if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString) { previousDateFormatString = reader.DateFormatString; reader.DateFormatString = _dateFormatString; } else { previousDateFormatString = null; } if (reader is JsonTextReader { PropertyNameTable: null } jsonTextReader && _contractResolver is DefaultContractResolver defaultContractResolver) { jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable(); } } private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString) { if (previousCulture != null) { reader.Culture = previousCulture; } if (previousDateTimeZoneHandling.HasValue) { reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault(); } if (previousDateParseHandling.HasValue) { reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault(); } if (previousFloatParseHandling.HasValue) { reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault(); } if (_maxDepthSet) { reader.MaxDepth = previousMaxDepth; } if (_dateFormatStringSet) { reader.DateFormatString = previousDateFormatString; } if (reader is JsonTextReader { PropertyNameTable: not null } jsonTextReader && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable()) { jsonTextReader.PropertyNameTable = null; } } public void Serialize(TextWriter textWriter, object? value) { Serialize(new JsonTextWriter(textWriter), value); } public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType) { SerializeInternal(jsonWriter, value, objectType); } public void Serialize(TextWriter textWriter, object? value, Type objectType) { Serialize(new JsonTextWriter(textWriter), value, objectType); } public void Serialize(JsonWriter jsonWriter, object? value) { SerializeInternal(jsonWriter, value, null); } private TraceJsonReader CreateTraceJsonReader(JsonReader reader) { TraceJsonReader traceJsonReader = new TraceJsonReader(reader); if (reader.TokenType != JsonToken.None) { traceJsonReader.WriteCurrentToken(); } return traceJsonReader; } internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); Formatting? formatting = null; if (_formatting.HasValue && jsonWriter.Formatting != _formatting) { formatting = jsonWriter.Formatting; jsonWriter.Formatting = _formatting.GetValueOrDefault(); } DateFormatHandling? dateFormatHandling = null; if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling) { dateFormatHandling = jsonWriter.DateFormatHandling; jsonWriter.DateFormatHandling = _date
BepInEx/plugins/PharloomCore.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; using PharloomCore.Data; using PharloomCore.Logic; using PharloomCore.Model; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("PharloomCore")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c907a5441a34f4759975824f4eedc9f306ab5a89")] [assembly: AssemblyProduct("PharloomCore")] [assembly: AssemblyTitle("PharloomCore")] [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 PharloomCore { public class PharloomCore { private readonly string[] _nativeConnLines; private readonly RoomGraph _roomGraphTemplate; private readonly Func<RoomGraph, PlacementSimulator> _placementFactory; private RoomGraph _roomGraph; public Region[] Regions { get; } public PlacementSimulator Placement { get; private set; } public DeadSeedDetector Detector { get; private set; } public SceneGraphBuilder SceneGraph { get; } public PrefixResolver Resolver { get; } public RoomGraph RoomGraph => _roomGraph; public RoomGapSet RoomGaps { get; private set; } public bool RoomPrecision => _roomGraph != null; public IReadOnlyDictionary<string, string> PointScenes { get; } public PharloomCore(string sceneConnectionPath, string checkpointsPath = null, string pointConditionsPath = null, bool roomPrecision = true) { PharloomCore pharloomCore = this; _nativeConnLines = File.ReadAllLines(sceneConnectionPath); Regions = RegionsData.All; SceneGraph = new SceneGraphBuilder(Regions); SceneGraph.Build(_nativeConnLines); Resolver = new PrefixResolver(Regions); _roomGraphTemplate = RoomGraphBuilder.Build(_nativeConnLines, Resolver, Regions); Dictionary<string, Gate> conditions = PointConditionLoader.LoadFile(pointConditionsPath); PointScenes = PointConditionLoader.LoadSceneMapFile(pointConditionsPath); string path = checkpointsPath; _placementFactory = (RoomGraph rg) => new PlacementSimulator(pharloomCore.Regions, path, 0, conditions, rg); _roomGraph = (roomPrecision ? _roomGraphTemplate : null); Attach(); } public PharloomCore(bool roomPrecision = true) { PharloomCore pharloomCore = this; _nativeConnLines = ReadEmbeddedLines("PharloomCore.Data.场景连接.txt").ToArray(); Regions = RegionsData.All; SceneGraph = new SceneGraphBuilder(Regions); SceneGraph.Build(_nativeConnLines); Resolver = new PrefixResolver(Regions); _roomGraphTemplate = RoomGraphBuilder.Build(_nativeConnLines, Resolver, Regions); Dictionary<string, Gate> conditions = PointConditionLoader.LoadLines(ReadEmbeddedLines("PharloomCore.Data.point_conditions.json")); PointScenes = PointConditionLoader.LoadSceneMapLines(ReadEmbeddedLines("PharloomCore.Data.point_conditions.json")); IEnumerable<string> lines = ReadEmbeddedLines("PharloomCore.Data.check_points.txt"); _placementFactory = (RoomGraph rg) => new PlacementSimulator(pharloomCore.Regions, lines, 0, conditions, rg); _roomGraph = (roomPrecision ? _roomGraphTemplate : null); Attach(); } private void Attach() { Placement = _placementFactory(_roomGraph); Detector = new DeadSeedDetector(Regions, _roomGraph); RoomGaps = ((_roomGraph != null) ? RoomGapSet.Compute(_roomGraph, Regions, Placement.BuildAllSlots()) : null); if (RoomGaps != null) { RoomGapReport.WarnOnce(RoomGaps); } } public void SetRoomPrecision(bool enabled) { RoomGraph roomGraph = (enabled ? _roomGraphTemplate : null); if (roomGraph != _roomGraph) { _roomGraph = roomGraph; Attach(); } } private static IEnumerable<string> ReadEmbeddedLines(string resourceName) { using Stream stream = typeof(PharloomCore).Assembly.GetManifestResourceStream(resourceName); if (stream == null) { throw new InvalidOperationException("缺少嵌入资源: " + resourceName); } using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd().Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.None); } public Gate FindPointGate(string key) { return Placement.FindPointGate(key); } public SeedVerdict TryGenerate(Random rng, int maxTries = 1000, bool fullRandomMode = false) { List<ItemSlot> slots = Placement.BuildAllSlots(); List<Item> pool = Placement.BuildItemPool(fullRandomMode); for (int i = 0; i < maxTries; i++) { if (Placement.TryPlaceActive(rng, slots, pool, out var assignment, fullRandomMode)) { SeedVerdict seedVerdict = Detector.Evaluate(assignment, fullRandomMode); if (!seedVerdict.IsDead) { return seedVerdict; } } } return new SeedVerdict { IsDead = true, Reason = "重试 " + maxTries + " 次仍未找到活种子" }; } public bool IsSeedLive(int seed, bool fullRandomMode = false) { List<ItemSlot> slots = Placement.BuildAllSlots(); List<Item> pool = Placement.BuildItemPool(fullRandomMode); if (!Placement.TryPlaceActive(new Random(seed), slots, pool, out var assignment, fullRandomMode)) { return false; } return !Detector.Evaluate(assignment, fullRandomMode).IsDead; } public int ScoreSeed(int seed, bool fullRandomMode = false) { List<ItemSlot> slots = Placement.BuildAllSlots(); List<Item> pool = Placement.BuildItemPool(fullRandomMode); Dictionary<ItemSlot, Item> assignment; bool flag = Placement.TryPlaceActive(new Random(seed), slots, pool, out assignment, fullRandomMode); SeedVerdict seedVerdict = Detector.Evaluate(assignment, fullRandomMode); if (!seedVerdict.IsDead && flag) { return 0; } int num = ((!flag) ? 1000000 : 0); if (seedVerdict.Reason != null && seedVerdict.Reason.StartsWith("固定点缺失")) { num += 1000000; } num += (seedVerdict.RoomMode ? seedVerdict.UnreachedRoomCount : seedVerdict.UnreachedRegions.Count) * 10000; return num + seedVerdict.BlockedSlotIds.Count * 100; } public int FindLiveSeed(Random rng, int maxTries = 1000, bool fullRandomMode = false) { for (int i = 0; i < maxTries; i++) { int num = rng.Next(1, int.MaxValue); if (IsSeedLive(num, fullRandomMode)) { return num; } } return -1; } public void ReplaceSceneConnections(IEnumerable<string> sceneConnectionLines) { SceneGraph.Build(sceneConnectionLines); } public void RestoreNativeSceneConnections() { SceneGraph.Build(_nativeConnLines); } public void MergeSceneConnections(IEnumerable<string> randomLines) { SceneGraph.Build(MergeConnectionLines(_nativeConnLines, randomLines)); } private static IEnumerable<string> MergeConnectionLines(IEnumerable<string> nativeLines, IEnumerable<string> randomLines) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); AddLines(dictionary, nativeLines); AddLines(dictionary, randomLines); return dictionary.Values; } private static void AddLines(Dictionary<string, string> map, IEnumerable<string> lines) { foreach (string line in lines) { string text = line.Trim(); if (text.Length != 0 && !text.StartsWith("#")) { string[] array = text.Split(new char[1] { '|' }); if (array.Length >= 4) { map[array[0].Trim() + "|" + array[1].Trim()] = text; } } } } } } namespace PharloomCore.Model { public enum AbilityCategory { Movement, Combat, Spell, Music } public enum AbilityId { NeedleThrow, Dash, DoubleJump, Brolly, SuperJump, Walljump, HarpoonDash, SilkCharge, ThreadSphere, SilkBomb, SilkBossNeedle, ChargeSlash, Parry, Needolin, EvaHeal, NeedolinMemory, Teleport, SilkDash, AttackUp, AttackLeft, AttackRight, Heal, Swim, ShamanCrest, ArchitectChargeSlash, MelodyConductor, MelodyLibrarian, MelodyArchitect, SilkHeart, Journal } public class Ability { public AbilityId Id { get; set; } public string Key { get; set; } public string DisplayName { get; set; } public AbilityCategory Category { get; set; } public override string ToString() { return DisplayName ?? Key; } } public static class MusicAbilityIds { public static readonly HashSet<AbilityId> All = new HashSet<AbilityId> { AbilityId.Needolin, AbilityId.EvaHeal, AbilityId.NeedolinMemory, AbilityId.Teleport, AbilityId.MelodyConductor, AbilityId.MelodyLibrarian, AbilityId.MelodyArchitect }; } public enum GateKind { Ability, Permission, AnyAbilityExcept, And, Or, Vertical, Horizontal, Cold, Item, Never } public class Gate { public GateKind Kind { get; set; } public AbilityId Ability { get; set; } public string PermissionId { get; set; } public PermissionSide PermissionSide { get; set; } public HashSet<AbilityId> ExcludedCategoriesOrIds { get; set; } public List<Gate> Children { get; set; } public int Level { get; set; } public string ItemName { get; set; } public static Gate AbilityGate(AbilityId id) { return new Gate { Kind = GateKind.Ability, Ability = id }; } public static Gate PermissionGate(string id, PermissionSide side) { return new Gate { Kind = GateKind.Permission, PermissionId = id + "_" + SideMapping.EngineSuffix(side) }; } public static Gate AnyAbilityExcept(params AbilityId[] excluded) { return new Gate { Kind = GateKind.AnyAbilityExcept, ExcludedCategoriesOrIds = new HashSet<AbilityId>(excluded) }; } public static Gate VerticalGate(int level) { return new Gate { Kind = GateKind.Vertical, Level = level }; } public static Gate HorizontalGate(int level, PermissionSide side) { return new Gate { Kind = GateKind.Horizontal, Level = level, PermissionSide = side }; } public static Gate ColdGate() { return new Gate { Kind = GateKind.Cold }; } public static Gate ItemGate(string itemName) { return new Gate { Kind = GateKind.Item, ItemName = itemName }; } public static Gate NeverGate() { return new Gate { Kind = GateKind.Never }; } public static Gate And(params Gate[] children) { return new Gate { Kind = GateKind.And, Children = new List<Gate>(children) }; } public static Gate Or(params Gate[] children) { return new Gate { Kind = GateKind.Or, Children = new List<Gate>(children) }; } } public enum PermissionSide { Left, Right } public static class SideMapping { public const bool InvertVisualToEngine = false; public static string EngineSuffix(PermissionSide visualSide) { if (visualSide != PermissionSide.Right) { return "L"; } return "R"; } public static PermissionSide FromEngineSuffix(string id) { if (!id.EndsWith("_R")) { return PermissionSide.Left; } return PermissionSide.Right; } } public class Permission { public string Id { get; set; } public AbilityId BoundAbility { get; set; } public PermissionSide Side { get; set; } public bool SidesSplit { get; set; } public override string ToString() { return Id; } } public static class PermissionIds { public const string Dash = "Dash"; public const string HarpoonDash = "HarpoonDash"; public const string Brolly = "Brolly"; public const string Walljump = "Walljump"; public const string SuperJump = "SuperJump"; } public class PlayerState { public HashSet<AbilityId> Abilities { get; } = new HashSet<AbilityId>(); public HashSet<string> Permissions { get; } = new HashSet<string>(); public HashSet<string> OwnedItems { get; } = new HashSet<string>(); public HashSet<Region> ReachableRegions { get; } = new HashSet<Region>(); public HashSet<string> ReachableRooms { get; set; } = new HashSet<string>(); public bool HasColdResistance { get; set; } public bool HasAbility(AbilityId id) { return Abilities.Contains(id); } public bool HasPermission(string id) { return Permissions.Contains(id); } public bool OwnsItem(string name) { return OwnedItems.Contains(name); } public static PlayerState WithStartingAbilities(bool fullRandomMode) { PlayerState playerState = new PlayerState(); if (fullRandomMode) { return playerState; } playerState.Abilities.Add(AbilityId.AttackUp); playerState.Abilities.Add(AbilityId.AttackLeft); playerState.Abilities.Add(AbilityId.AttackRight); playerState.Abilities.Add(AbilityId.Heal); return playerState; } } public class Region { public string Id { get; set; } public string DisplayName { get; set; } public List<string> ScenePrefixes { get; set; } public List<string> AdjacentRegionIds { get; set; } public Gate EntryGate { get; set; } public Dictionary<string, Gate> Exits { get; set; } public List<ItemSlot> Slots { get; set; } public bool IsStart { get; set; } public bool IsDream { get; set; } public Region() { ScenePrefixes = new List<string>(); AdjacentRegionIds = new List<string>(); Exits = new Dictionary<string, Gate>(); Slots = new List<ItemSlot>(); } public override string ToString() { return DisplayName ?? Id; } } public enum ItemKind { Ability, Permission, NamedItem, Cold, Virtual } public class ItemSlot { public string Id { get; set; } public string SourceKey { get; set; } public Region Region { get; set; } public string RoomId { get; set; } public bool IsFixed { get; set; } public Gate AccessGate { get; set; } public override bool Equals(object obj) { if (obj is ItemSlot itemSlot) { return string.Equals(Id, itemSlot.Id); } return false; } public override int GetHashCode() { if (Id == null) { return 0; } return Id.GetHashCode(); } public override string ToString() { return Id; } } public class Item { public ItemKind Kind { get; set; } public AbilityId AbilityId { get; set; } public string PermissionId { get; set; } public string ItemName { get; set; } public int Priority { get; set; } = 4; public override string ToString() { return Kind switch { ItemKind.Ability => AbilityId.ToString(), ItemKind.Permission => PermissionId, ItemKind.NamedItem => "Item:" + ItemName, ItemKind.Cold => "ColdResistance", ItemKind.Virtual => "Virt:" + ItemName, _ => "?", }; } } public class RoomComponent { public List<string> Rooms { get; } = new List<string>(); public bool IsMain { get; internal set; } public bool IsDreamSeeded { get; internal set; } public bool IsValid { get { if (!IsMain) { return IsDreamSeeded; } return true; } } public int Count => Rooms.Count; public bool Contains(string roomId) { if (roomId != null) { return Rooms.Contains(roomId); } return false; } } public class RoomGraph { public const string DefaultStartRoomId = "Tut_01"; private readonly HashSet<string> _alwaysReachableRooms = new HashSet<string>(StringComparer.Ordinal); private List<RoomComponent> _components; private Dictionary<string, RoomComponent> _componentOfRoom; private RoomComponent _mainComponent; private List<string> _orphanRooms; private HashSet<string> _orphanRoomSet; public string StartRoomId { get; set; } = "Tut_01"; public Dictionary<string, HashSet<string>> Adjacency { get; } = new Dictionary<string, HashSet<string>>(); public Dictionary<string, string> RoomToRegion { get; } = new Dictionary<string, string>(); public List<string> UnmappedScenes { get; } = new List<string>(); public int RoomCount => Adjacency.Count; public IReadOnlyList<RoomComponent> Components { get { EnsureComponents(); return _components; } } public RoomComponent MainComponent { get { EnsureComponents(); return _mainComponent; } } public IReadOnlyList<string> OrphanRoomIds { get { if (_orphanRooms == null) { BuildOrphans(); } return _orphanRooms; } } public IEnumerable<string> Neighbors(string roomId) { if (roomId != null && Adjacency.TryGetValue(roomId, out var value)) { return value; } return Array.Empty<string>(); } public void DeclareAlwaysReachableRooms(IEnumerable<string> roomIds) { _alwaysReachableRooms.Clear(); if (roomIds != null) { foreach (string roomId in roomIds) { if (!string.IsNullOrEmpty(roomId)) { _alwaysReachableRooms.Add(roomId); } } } InvalidateQueries(); } public RoomComponent ComponentOf(string roomId) { EnsureComponents(); if (roomId == null) { return null; } if (!_componentOfRoom.TryGetValue(roomId, out var value)) { return null; } return value; } public bool IsOrphanRoom(string roomId) { if (_orphanRoomSet == null) { BuildOrphans(); } if (roomId != null) { return _orphanRoomSet.Contains(roomId); } return false; } public static HashSet<string> DreamRegionRooms(Region[] regions, RoomGraph graph) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if (regions == null || graph == null) { return hashSet; } HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); foreach (Region region in regions) { if (region != null && region.IsDream) { hashSet2.Add(region.Id); } } if (hashSet2.Count == 0) { return hashSet; } foreach (KeyValuePair<string, string> item in graph.RoomToRegion) { if (hashSet2.Contains(item.Value)) { hashSet.Add(item.Key); } } return hashSet; } private void InvalidateQueries() { _components = null; _componentOfRoom = null; _mainComponent = null; _orphanRooms = null; _orphanRoomSet = null; } private void EnsureComponents() { if (_components != null) { return; } List<RoomComponent> list = new List<RoomComponent>(); Dictionary<string, RoomComponent> dictionary = new Dictionary<string, RoomComponent>(StringComparer.Ordinal); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); List<string> list2 = new List<string>(Adjacency.Keys); list2.Sort(StringComparer.Ordinal); foreach (string item in list2) { if (hashSet.Contains(item)) { continue; } RoomComponent roomComponent = new RoomComponent(); Queue<string> queue = new Queue<string>(); queue.Enqueue(item); hashSet.Add(item); while (queue.Count > 0) { string text = queue.Dequeue(); roomComponent.Rooms.Add(text); if (!Adjacency.TryGetValue(text, out var value)) { continue; } foreach (string item2 in value) { if (item2 != null && Adjacency.ContainsKey(item2) && hashSet.Add(item2)) { queue.Enqueue(item2); } } } roomComponent.Rooms.Sort(StringComparer.Ordinal); list.Add(roomComponent); foreach (string room in roomComponent.Rooms) { dictionary[room] = roomComponent; } } list.Sort((RoomComponent a, RoomComponent b) => (a.Count == b.Count) ? string.CompareOrdinal(a.Rooms[0], b.Rooms[0]) : b.Count.CompareTo(a.Count)); if (!string.IsNullOrEmpty(StartRoomId) && dictionary.TryGetValue(StartRoomId, out var value2)) { _mainComponent = value2; } else { _mainComponent = ((list.Count > 0) ? list[0] : null); } if (_mainComponent != null) { _mainComponent.IsMain = true; } foreach (RoomComponent item3 in list) { if (item3.IsMain) { continue; } foreach (string room2 in item3.Rooms) { if (_alwaysReachableRooms.Contains(room2)) { item3.IsDreamSeeded = true; break; } } } _components = list; _componentOfRoom = dictionary; } private void BuildOrphans() { EnsureComponents(); List<string> list = new List<string>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (RoomComponent component in _components) { if (component.IsValid) { continue; } foreach (string room in component.Rooms) { if (hashSet.Add(room)) { list.Add(room); } } } list.Sort(StringComparer.Ordinal); _orphanRooms = list; _orphanRoomSet = hashSet; } } } namespace PharloomCore.Logic { public class CheckpointSource { public const string ArboriumWalljumpId = "Arborium_Walljump"; public const string ArboriumWalljumpLeftId = "Arborium_Walljump_L"; public const string ArboriumWalljumpRightId = "Arborium_Walljump_R"; private readonly PrefixResolver _resolver; private readonly IReadOnlyDictionary<string, Gate> _conditionsByKey; public CheckpointSource(Region[] regions, IReadOnlyDictionary<string, Gate> conditionsByKey = null) { _resolver = new PrefixResolver(regions); _conditionsByKey = conditionsByKey; } public List<ItemSlot> BuildSlots(string checkpointsPath, bool includeLore = true) { return BuildSlots(File.ReadAllLines(checkpointsPath), includeLore); } public List<ItemSlot> BuildSlots(IEnumerable<string> lines, bool includeLore = true) { List<ItemSlot> list = new List<ItemSlot>(); int num = 0; foreach (string line in lines) { string text = line.Trim(); if (text.Length == 0) { continue; } string[] array = text.Split(new char[1] { '|' }); string text2 = array[0]; if (array.Length < 2 || (text2 != "Pickup" && (!includeLore || !(text2 == "Lore")))) { continue; } string text3 = array[1].Trim(); Region region = _resolver.Resolve(text3); if (region != null) { string text4 = ((array.Length > 5) ? array[5].Trim() : null); if (text2 == "Pickup" && array.Length > 7 && float.TryParse(array[6], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[7], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { text4 = text3 + "_" + result.ToString("F2", CultureInfo.InvariantCulture) + "_" + result2.ToString("F2", CultureInfo.InvariantCulture) + "_0.00"; } Gate accessGate = null; if (text4 != null && _conditionsByKey != null && _conditionsByKey.TryGetValue(text4, out var value)) { accessGate = value; } list.Add(new ItemSlot { Id = text2 + "_" + num + "_" + text3, SourceKey = text4, Region = region, RoomId = text3, AccessGate = accessGate }); num++; } } ClaimArboriumFixedSlots(list); return list; } private static void ClaimArboriumFixedSlots(List<ItemSlot> slots) { List<ItemSlot> list = new List<ItemSlot>(); foreach (ItemSlot slot in slots) { if (slot.Region.Id == "Arborium") { list.Add(slot); } } if (list.Count >= 3) { list[0].Id = "Arborium_Walljump"; list[0].IsFixed = true; list[1].Id = "Arborium_Walljump_L"; list[1].IsFixed = true; list[2].Id = "Arborium_Walljump_R"; list[2].IsFixed = true; } } } public class SeedVerdict { public bool IsDead { get; set; } public int ReachedCount { get; set; } public int TotalCount { get; set; } public List<string> UnreachedRegions { get; } = new List<string>(); public List<string> ReachedRegions { get; } = new List<string>(); public List<string> BlockedSlotIds { get; } = new List<string>(); public string Reason { get; set; } public List<string> UnreachedRooms { get; } = new List<string>(); public List<string> ReachedRooms { get; } = new List<string>(); public List<string> ExemptRooms { get; } = new List<string>(); public IReadOnlyList<string> GapRoomIds { get; set; } public bool HasGapExemption => ExemptRooms.Count > 0; public bool RoomMode { get; set; } public string ScopeLabel { get { if (!RoomMode) { return "区域"; } return "房间"; } } public int UnreachedRoomCount => UnreachedRooms.Count; private string ExemptNote { get { if (ExemptRooms.Count <= 0) { return string.Empty; } return "(另有 " + ExemptRooms.Count + " 个数据缺口房间豁免,不计死种)"; } } public override string ToString() { if (!IsDead) { return "活种子: 全部 " + ReachedCount + " " + ScopeLabel + "可达" + ExemptNote; } return "死种子: " + (string.IsNullOrEmpty(Reason) ? string.Join(", ", UnreachedRegions) : Reason); } } public class DeadSeedDetector { private readonly ReachabilityAnalyzer _analyzer; private readonly RoomGapSet _gaps; public bool RoomPrecision => _analyzer.RoomPrecision; public RoomGapSet Gaps => _gaps; public DeadSeedDetector(Region[] regions, RoomGraph roomGraph = null) { _analyzer = new ReachabilityAnalyzer(regions, roomGraph); _gaps = RoomGapSet.Compute(roomGraph, regions, null); } public SeedVerdict Evaluate(IReadOnlyDictionary<ItemSlot, Item> assignment, bool fullRandomMode = false) { SeedVerdict seedVerdict = new SeedVerdict { RoomMode = _analyzer.RoomPrecision }; if (assignment == null) { seedVerdict.IsDead = true; seedVerdict.Reason = "分配为空(放置失败)"; return seedVerdict; } ReachabilityResult reachabilityResult = _analyzer.Compute(assignment, fullRandomMode); seedVerdict.ReachedCount = (RoomPrecision ? reachabilityResult.ReachedRoomIds.Count : reachabilityResult.ReachedRegionIds.Count); seedVerdict.TotalCount = ((!RoomPrecision) ? _analyzer.Regions.Length : ((_analyzer.RoomGraph != null) ? _analyzer.RoomGraph.RoomCount : 0)); seedVerdict.ReachedRegions.AddRange(reachabilityResult.ReachedRegionIds); seedVerdict.UnreachedRegions.AddRange(reachabilityResult.UnreachedRegionIds); seedVerdict.ReachedRooms.AddRange(reachabilityResult.ReachedRoomIds); seedVerdict.BlockedSlotIds.AddRange(reachabilityResult.BlockedSlotIds); if (RoomPrecision) { seedVerdict.GapRoomIds = ((_gaps != null) ? _gaps.GapRoomIds : null); foreach (string unreachedRoomId in reachabilityResult.UnreachedRoomIds) { if (_gaps != null && _gaps.IsGapRoom(unreachedRoomId)) { seedVerdict.ExemptRooms.Add(unreachedRoomId); } else { seedVerdict.UnreachedRooms.Add(unreachedRoomId); } } } else { seedVerdict.UnreachedRooms.AddRange(reachabilityResult.UnreachedRoomIds); } string text = FindFixedViolation(assignment); if (text != null) { seedVerdict.IsDead = true; seedVerdict.Reason = "固定点缺失: " + text; return seedVerdict; } if (RoomPrecision ? (seedVerdict.UnreachedRooms.Count > 0) : (!reachabilityResult.AllReached)) { seedVerdict.IsDead = true; if (RoomPrecision) { seedVerdict.Reason = "房间不可达 (" + seedVerdict.UnreachedRooms.Count + "): " + string.Join(", ", seedVerdict.UnreachedRooms) + ExemptSuffix(seedVerdict); } else { seedVerdict.Reason = "区域不可达: " + string.Join(", ", reachabilityResult.UnreachedRegionIds); } return seedVerdict; } if (!reachabilityResult.AllPointsAccessible) { seedVerdict.IsDead = true; seedVerdict.Reason = "点位条件不可达 (" + reachabilityResult.BlockedSlotIds.Count + "): " + string.Join(", ", reachabilityResult.BlockedSlotIds); return seedVerdict; } seedVerdict.IsDead = false; return seedVerdict; } private static string ExemptSuffix(SeedVerdict verdict) { if (verdict.ExemptRooms.Count <= 0) { return string.Empty; } return ";另有 " + verdict.ExemptRooms.Count + " 个数据缺口房间豁免(不计死种): " + string.Join(", ", verdict.ExemptRooms); } private static string FindFixedViolation(IReadOnlyDictionary<ItemSlot, Item> assignment) { foreach (KeyValuePair<ItemSlot, Item> item in assignment) { if (item.Key.IsFixed && !MatchesFixed(item.Key, item.Value)) { return item.Key.Id + " 固定物品被篡改"; } } return null; } private static bool MatchesFixed(ItemSlot slot, Item item) { if (slot.Id == "Arborium_Walljump") { if (item.Kind == ItemKind.Ability) { return item.AbilityId == AbilityId.Walljump; } return false; } if (slot.Id == "Arborium_Walljump_L") { if (item.Kind == ItemKind.Permission && item.PermissionId == "Walljump_" + SideMapping.EngineSuffix(PermissionSide.Left)) { return item.AbilityId == AbilityId.Walljump; } return false; } if (slot.Id == "Arborium_Walljump_R") { if (item.Kind == ItemKind.Permission && item.PermissionId == "Walljump_" + SideMapping.EngineSuffix(PermissionSide.Right)) { return item.AbilityId == AbilityId.Walljump; } return false; } return false; } } public class FixedAssignments { public const string ArboriumWalljumpSlot = "Arborium_Walljump"; public const string ArboriumWalljumpLeftSlot = "Arborium_Walljump_L"; public const string ArboriumWalljumpRightSlot = "Arborium_Walljump_R"; public Dictionary<ItemSlot, Item> All { get; } public FixedAssignments(Region[] regions) { All = new Dictionary<ItemSlot, Item>(); Region region = FindRegion(regions, "Arborium"); if (region != null) { Add("Arborium_Walljump", region, new Item { Kind = ItemKind.Ability, AbilityId = AbilityId.Walljump }); Add("Arborium_Walljump_L", region, new Item { Kind = ItemKind.Permission, PermissionId = "Walljump_" + SideMapping.EngineSuffix(PermissionSide.Left), AbilityId = AbilityId.Walljump }); Add("Arborium_Walljump_R", region, new Item { Kind = ItemKind.Permission, PermissionId = "Walljump_" + SideMapping.EngineSuffix(PermissionSide.Right), AbilityId = AbilityId.Walljump }); } } private void Add(string id, Region region, Item item) { All[new ItemSlot { Id = id, Region = region, IsFixed = true }] = item; } private static Region FindRegion(Region[] regions, string id) { foreach (Region region in regions) { if (region.Id == id) { return region; } } return null; } } public static class GateEvaluator { public static bool Satisfied(Gate gate, PlayerState state) { switch (gate.Kind) { case GateKind.Ability: return state.HasAbility(gate.Ability); case GateKind.Permission: return state.HasPermission(gate.PermissionId); case GateKind.And: foreach (Gate child in gate.Children) { if (!Satisfied(child, state)) { return false; } } return true; case GateKind.Or: foreach (Gate child2 in gate.Children) { if (Satisfied(child2, state)) { return true; } } return false; case GateKind.AnyAbilityExcept: foreach (AbilityId ability in state.Abilities) { if (!gate.ExcludedCategoriesOrIds.Contains(ability)) { return true; } } return false; case GateKind.Vertical: return VerticalSatisfied(gate.Level, state); case GateKind.Horizontal: return HorizontalSatisfied(gate.Level, state); case GateKind.Cold: return state.HasColdResistance; case GateKind.Item: return state.OwnsItem(gate.ItemName); case GateKind.Never: return false; default: return false; } } public static bool VerticalSatisfied(int level, PlayerState state) { switch (level) { case 3: return state.HasAbility(AbilityId.SuperJump); case 2: if (!state.HasAbility(AbilityId.SuperJump)) { return state.HasAbility(AbilityId.Walljump); } return true; default: if (!state.HasAbility(AbilityId.SuperJump) && !state.HasAbility(AbilityId.Walljump)) { return state.HasAbility(AbilityId.DoubleJump); } return true; } } public static bool HorizontalSatisfied(int level, PlayerState state) { if (level >= 3) { if (!state.HasAbility(AbilityId.SuperJump)) { return state.HasAbility(AbilityId.HarpoonDash); } return true; } if (!state.HasAbility(AbilityId.SuperJump) && !state.HasAbility(AbilityId.HarpoonDash) && !state.HasAbility(AbilityId.Dash) && !state.HasAbility(AbilityId.Brolly)) { return state.HasAbility(AbilityId.SilkDash); } return true; } } public static class KeyItemAlignment { public class Row { public string SirId; public string Name; public int SirLimit; public string Engine; public int PoolCount; public bool Covered; public bool FixedOnly; public string Note; } private const string ColdKind = "@COLD"; private static readonly HashSet<string> DirectionSkills = new HashSet<string> { "hasDash", "hasHarpoonDash", "hasBrolly", "hasWalljump", "HasSeenEvaHeal" }; private static readonly (string id, string eng, string name, bool dirSkill)[] AllAbilities = new(string, string, string, bool)[24] { ("hasNeedleThrow", AbilityId.NeedleThrow.ToString(), "丝之矛", false), ("hasThreadSphere", AbilityId.ThreadSphere.ToString(), "灵丝风暴", false), ("hasSilkCharge", AbilityId.SilkCharge.ToString(), "丝刃标", false), ("hasSilkBomb", AbilityId.SilkBomb.ToString(), "符文之怒", false), ("hasSilkBossNeedle", AbilityId.SilkBossNeedle.ToString(), "苍白之爪", false), ("hasParry", AbilityId.Parry.ToString(), "格挡", false), ("hasHarpoonDash", AbilityId.HarpoonDash.ToString(), "飞针(方向技能)", true), ("hasNeedolin", AbilityId.Needolin.ToString(), "丝忆弦针", false), ("hasDash", AbilityId.Dash.ToString(), "疾风步(方向技能)", true), ("hasBrolly", AbilityId.Brolly.ToString(), "流浪者披风(方向技能)", true), ("hasDoubleJump", AbilityId.DoubleJump.ToString(), "雪绒披风(二段跳)", false), ("hasChargeSlash", AbilityId.ChargeSlash.ToString(), "蓄力斩", false), ("hasSuperJump", AbilityId.SuperJump.ToString(), "灵丝升腾", false), ("hasWalljump", AbilityId.Walljump.ToString(), "蛛攀术(方向技能)", true), ("HasSeenEvaHeal", AbilityId.EvaHeal.ToString(), "风铃摇·回血(方向技能)", true), ("hasNeedolinMemoryPowerup", AbilityId.NeedolinMemory.ToString(), "深邃挽歌", false), ("hasFastTravelTeleport", AbilityId.Teleport.ToString(), "幻兽歌", false), ("HasMelodyConductor", AbilityId.MelodyConductor.ToString(), "旋律·指挥", false), ("HasMelodyLibrarian", AbilityId.MelodyLibrarian.ToString(), "旋律·司书", false), ("HasMelodyArchitect", AbilityId.MelodyArchitect.ToString(), "旋律·建筑师", false), ("SilkHeart", AbilityId.SilkHeart.ToString(), "丝之心", false), ("Journal", AbilityId.Journal.ToString(), "猎人日志", false), ("ColdResist", "@COLD", "寒冷抗性", false), ("Swim", AbilityId.Swim.ToString(), "游泳", false) }; public static List<Row> Build(List<Item> pool, bool fullRandomMode) { List<Row> list = new List<Row>(); (string, string, string, bool)[] allAbilities = AllAbilities; for (int i = 0; i < allAbilities.Length; i++) { var (text, eng, name, _) = allAbilities[i]; if (!fullRandomMode || !DirectionSkills.Contains(text)) { bool flag = text == "hasWalljump"; int num = ((eng == "@COLD") ? pool.Count((Item item) => item.Kind == ItemKind.Cold) : pool.Count((Item item) => item.Kind == ItemKind.Ability && item.AbilityId.ToString() == eng)); list.Add(new Row { SirId = text, Name = name, SirLimit = ((text == "SilkHeart") ? 3 : 2), Engine = ((eng == "@COLD") ? "ItemKind.Cold" : ("能力 " + eng)), PoolCount = num, Covered = (flag || num > 0), FixedOnly = flag }); } } if (fullRandomMode) { AddDirectionPerms(list, pool); } list.Add(Named("virt:UnlockCrestSlot", "纹章槽位解锁器", 2, "CrestSocketUnlocker", pool)); list.Add(Named("Simple Key", "简单钥匙", 4, "SimpleKey", pool)); list.Add(Named("virt:SlabKeyA", "怠惰之钥", 1, "SlabKeyA", pool)); list.Add(Named("virt:SlabKeyB", "异端之钥", 1, "SlabKeyB", pool)); list.Add(Named("virt:SlabKeyC", "叛教之钥", 1, "SlabKeyC", pool)); return list; } private static void AddDirectionPerms(List<Row> rows, List<Item> pool) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (Item item8 in pool) { if (item8.Kind == ItemKind.Permission && PermissionsData.All.TryGetValue(item8.PermissionId, out var value)) { string key = value.BoundAbility.ToString() + "_" + value.Side; dictionary[key] = ((!dictionary.TryGetValue(key, out var value2)) ? 1 : (value2 + 1)); } } (string, string, AbilityId, PermissionSide, bool)[] array = new(string, string, AbilityId, PermissionSide, bool)[8] { ("perm:hasDash_L", "冲刺左", AbilityId.Dash, PermissionSide.Left, false), ("perm:hasDash_R", "冲刺右", AbilityId.Dash, PermissionSide.Right, false), ("perm:hasHarpoonDash_L", "飞针左", AbilityId.HarpoonDash, PermissionSide.Left, false), ("perm:hasHarpoonDash_R", "飞针右", AbilityId.HarpoonDash, PermissionSide.Right, false), ("perm:hasBrolly_L", "漂浮左", AbilityId.Brolly, PermissionSide.Left, false), ("perm:hasBrolly_R", "漂浮右", AbilityId.Brolly, PermissionSide.Right, false), ("perm:hasWalljump_L", "壁跳左", AbilityId.Walljump, PermissionSide.Left, true), ("perm:hasWalljump_R", "壁跳右", AbilityId.Walljump, PermissionSide.Right, true) }; for (int i = 0; i < array.Length; i++) { (string, string, AbilityId, PermissionSide, bool) tuple = array[i]; string item = tuple.Item1; string item2 = tuple.Item2; AbilityId item3 = tuple.Item3; PermissionSide item4 = tuple.Item4; bool item5 = tuple.Item5; string key2 = item3.ToString() + "_" + item4; int value3; int num = (dictionary.TryGetValue(key2, out value3) ? value3 : 0); rows.Add(new Row { SirId = item, Name = item2, SirLimit = 1, Engine = "权限 " + item3.ToString() + "_" + item4, PoolCount = num, Covered = (item5 || num > 0), FixedOnly = item5 }); } (string, string, AbilityId)[] array2 = new(string, string, AbilityId)[4] { ("perm:upward", "上劈权限", AbilityId.AttackUp), ("perm:left", "左劈权限", AbilityId.AttackLeft), ("perm:right", "右劈权限", AbilityId.AttackRight), ("perm:heal", "回血权限", AbilityId.Heal) }; for (int i = 0; i < array2.Length; i++) { (string, string, AbilityId) tuple2 = array2[i]; string item6 = tuple2.Item1; string item7 = tuple2.Item2; AbilityId ability = tuple2.Item3; int num2 = pool.Count((Item item8) => item8.Kind == ItemKind.Ability && item8.AbilityId == ability); rows.Add(new Row { SirId = item6, Name = item7, SirLimit = 2, Engine = "能力 " + ability, PoolCount = num2, Covered = (num2 > 0), Note = "无方向,引擎以能力建模" }); } } private static Row Named(string sirId, string name, int limit, string itemName, List<Item> pool) { return new Row { SirId = sirId, Name = name, SirLimit = limit, Engine = "NamedItem " + itemName, PoolCount = pool.Count((Item i) => i.Kind == ItemKind.NamedItem && i.ItemName == itemName), Covered = pool.Any((Item i) => i.Kind == ItemKind.NamedItem && i.ItemName == itemName) }; } } public class PlacementSimulator { private readonly Region[] _regions; private readonly string _checkpointsPath; private readonly IEnumerable<string> _checkpointLines; private readonly IReadOnlyDictionary<string, Gate> _conditionsByKey; private readonly int _randomSlotCount; private readonly RoomGraph _roomGraph; private List<ItemSlot> _cachedSlots; private List<Item> _cachedPool; private bool _cachedPoolFullRandom; private Dictionary<ItemSlot, Item> _cachedFixed; public bool RoomPrecision => _roomGraph != null; public PlacementSimulator(Region[] regions, string checkpointsPath, int randomSlotCount = 0, IReadOnlyDictionary<string, Gate> conditionsByKey = null, RoomGraph roomGraph = null) { _regions = regions; _checkpointsPath = checkpointsPath; _randomSlotCount = randomSlotCount; _conditionsByKey = conditionsByKey; _roomGraph = roomGraph; } public PlacementSimulator(Region[] regions, IEnumerable<string> checkpointLines, int randomSlotCount = 0, IReadOnlyDictionary<string, Gate> conditionsByKey = null, RoomGraph roomGraph = null) { _regions = regions; _checkpointLines = checkpointLines; _randomSlotCount = randomSlotCount; _conditionsByKey = conditionsByKey; _roomGraph = roomGraph; } public List<ItemSlot> BuildAllSlots() { if (_cachedSlots != null) { return _cachedSlots; } return _cachedSlots = ((_checkpointLines != null) ? new CheckpointSource(_regions, _conditionsByKey).BuildSlots(_checkpointLines) : ((_checkpointsPath != null) ? new CheckpointSource(_regions, _conditionsByKey).BuildSlots(_checkpointsPath) : BuildSyntheticSlots())); } public Gate FindPointGate(string key) { if (key == null || _conditionsByKey == null) { return null; } if (!_conditionsByKey.TryGetValue(key.Trim(), out var value)) { return null; } return value; } public Dictionary<ItemSlot, Item> BuildFixedAssignments() { if (_cachedFixed != null) { return new Dictionary<ItemSlot, Item>(_cachedFixed); } _cachedFixed = new FixedAssignments(_regions).All; return new Dictionary<ItemSlot, Item>(_cachedFixed); } public List<Item> BuildItemPool(bool fullRandomMode = false) { if (_cachedPool != null && _cachedPoolFullRandom == fullRandomMode) { return _cachedPool; } HashSet<AbilityId> hashSet = new HashSet<AbilityId> { AbilityId.Dash, AbilityId.HarpoonDash, AbilityId.Brolly, AbilityId.Walljump, AbilityId.EvaHeal }; HashSet<AbilityId> hashSet2 = new HashSet<AbilityId> { AbilityId.AttackUp, AbilityId.AttackLeft, AbilityId.AttackRight, AbilityId.Heal }; List<Item> list = new List<Item>(); foreach (Ability value in AbilitiesData.All.Values) { if (value.Id != AbilityId.Walljump && (!fullRandomMode || !hashSet.Contains(value.Id)) && (fullRandomMode || !hashSet2.Contains(value.Id))) { list.Add(new Item { Kind = ItemKind.Ability, AbilityId = value.Id, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Ability, AbilityId = value.Id }) }); list.Add(new Item { Kind = ItemKind.Ability, AbilityId = value.Id, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Ability, AbilityId = value.Id }) }); if (value.Id == AbilityId.SilkHeart) { list.Add(new Item { Kind = ItemKind.Ability, AbilityId = value.Id, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Ability, AbilityId = value.Id }) }); } } } list.Add(new Item { Kind = ItemKind.Cold, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Cold }) }); list.Add(new Item { Kind = ItemKind.Cold, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Cold }) }); if (fullRandomMode) { foreach (Permission value2 in PermissionsData.All.Values) { if (!(value2.Id == "Walljump_L") && !(value2.Id == "Walljump_R")) { list.Add(new Item { Kind = ItemKind.Permission, PermissionId = value2.Id, AbilityId = value2.BoundAbility, Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.Permission, PermissionId = value2.Id, AbilityId = value2.BoundAbility }) }); } } } list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyA", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyA" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyB", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyB" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyC", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SlabKeyC" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "CrestSocketUnlocker", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "CrestSocketUnlocker" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "CrestSocketUnlocker", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "CrestSocketUnlocker" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey" }) }); list.Add(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey", Priority = ItemTiers.Resolve(new Item { Kind = ItemKind.NamedItem, ItemName = "SimpleKey" }) }); _cachedPool = list; _cachedPoolFullRandom = fullRandomMode; return list; } public Dictionary<ItemSlot, Item> Randomize(Random rng, List<ItemSlot> slots, List<Item> pool) { Dictionary<ItemSlot, Item> dictionary = new Dictionary<ItemSlot, Item>(); foreach (KeyValuePair<ItemSlot, Item> item in BuildFixedAssignments()) { dictionary[MatchFixedSlot(slots, item.Key) ?? item.Key] = item.Value; } List<Item> list = new List<Item>(pool); Shuffle(rng, list); List<ItemSlot> list2 = new List<ItemSlot>(); foreach (ItemSlot slot in slots) { if (!slot.IsFixed) { list2.Add(slot); } } Shuffle(rng, list2); for (int i = 0; i < list.Count && i < list2.Count; i++) { dictionary[list2[i]] = list[i]; } return dictionary; } public bool TryPlaceActive(Random rng, List<ItemSlot> slots, List<Item> pool, out Dictionary<ItemSlot, Item> assignment, bool fullRandomMode = false) { return new SpherePlacement(_regions, _roomGraph).TryPlace(slots, pool, out assignment, fullRandomMode, rng); } public Dictionary<ItemSlot, Item> BuildAssignment(int seed, bool fullRandomMode = false) { if (!TryPlaceActive(new Random(seed), BuildAllSlots(), BuildItemPool(fullRandomMode), out var assignment, fullRandomMode)) { return null; } return assignment; } public Dictionary<ItemSlot, Item> TryPlaceLive(Random rng, List<ItemSlot> slots, List<Item> pool, int maxAttempts = 200, bool fullRandomMode = false) { DeadSeedDetector deadSeedDetector = new DeadSeedDetector(_regions, _roomGraph); for (int i = 0; i < maxAttempts; i++) { if (TryPlaceActive(rng, slots, pool, out var assignment, fullRandomMode) && !deadSeedDetector.Evaluate(assignment, fullRandomMode).IsDead) { return assignment; } } return null; } internal static ItemSlot MatchFixedSlot(List<ItemSlot> slots, ItemSlot fixedSlot) { foreach (ItemSlot slot in slots) { if (slot.IsFixed && string.Equals(slot.Id, fixedSlot.Id, StringComparison.Ordinal)) { return slot; } } return null; } private List<ItemSlot> BuildSyntheticSlots() { List<ItemSlot> list = new List<ItemSlot>(); Random random = new Random(1); for (int i = 0; i < _randomSlotCount; i++) { list.Add(new ItemSlot { Id = "Slot_" + i, Region = _regions[random.Next(_regions.Length)] }); } foreach (KeyValuePair<ItemSlot, Item> item in BuildFixedAssignments()) { list.Add(item.Key); } return list; } private static void Shuffle<T>(Random rng, IList<T> list) { for (int num = list.Count - 1; num > 0; num--) { int index = rng.Next(num + 1); T value = list[num]; list[num] = list[index]; list[index] = value; } } internal static List<T> Shuffled<T>(Random rng, IList<T> source) { List<T> list = new List<T>(source); Shuffle(rng, list); return list; } } public class PrefixResolver { private readonly Dictionary<string, Region> _byPrefix = new Dictionary<string, Region>(); private string[] _prefixesByLengthDesc; public PrefixResolver(Region[] regions) { foreach (Region region in regions) { foreach (string scenePrefix in region.ScenePrefixes) { _byPrefix[scenePrefix] = region; } } } public Region Resolve(string sceneName) { if (string.IsNullOrEmpty(sceneName)) { return null; } string text = sceneName.ToLowerInvariant(); string[] array = PrefixesByLengthDesc(); foreach (string text2 in array) { string text3 = text2.ToLowerInvariant(); if (text.StartsWith(text3 + "_") || text == text3) { return _byPrefix[text2]; } } return null; } private string[] PrefixesByLengthDesc() { if (_prefixesByLengthDesc != null) { return _prefixesByLengthDesc; } List<string> list = new List<string>(_byPrefix.Keys); list.Sort((string a, string b) => b.Length.CompareTo(a.Length)); _prefixesByLengthDesc = list.ToArray(); return _prefixesByLengthDesc; } } public class ReachabilityResult { public PlayerState State { get; set; } public List<string> ReachedRegionIds { get; } = new List<string>(); public List<string> UnreachedRegionIds { get; } = new List<string>(); public List<string> BlockedSlotIds { get; } = new List<string>(); public List<string> ReachedRoomIds { get; } = new List<string>(); public List<string> UnreachedRoomIds { get; } = new List<string>(); public bool RoomMode { get; set; } public bool AllReached { get { if (!RoomMode) { return UnreachedRegionIds.Count == 0; } return UnreachedRoomIds.Count == 0; } } public bool AllPointsAccessible => BlockedSlotIds.Count == 0; public int StepCount { get; set; } public int Steps { get { return StepCount; } set { StepCount = value; } } } public class ReachabilityAnalyzer { private readonly Region[] _regions; private readonly Dictionary<string, Region> _byId = new Dictionary<string, Region>(); private readonly RoomGraph _roomGraph; public Region[] Regions => _regions; public bool RoomPrecision => _roomGraph != null; public RoomGraph RoomGraph => _roomGraph; public List<ItemSlot> AllSlots { get; set; } public ReachabilityAnalyzer(Region[] regions, RoomGraph roomGraph = null) { _regions = regions; _roomGraph = roomGraph; foreach (Region region in regions) { _byId[region.Id] = region; } } public ReachabilityResult Compute(IReadOnlyDictionary<ItemSlot, Item> assignment, bool fullRandomMode = false, IReadOnlyList<Item> grants = null) { if (_roomGraph != null) { return RoomReachability.Compute(assignment, AllSlots, _roomGraph, _regions, fullRandomMode, grants); } return ComputeRegion(assignment, fullRandomMode, grants); } private ReachabilityResult ComputeRegion(IReadOnlyDictionary<ItemSlot, Item> assignment, bool fullRandomMode, IReadOnlyList<Item> grants = null) { PlayerState playerState = PlayerState.WithStartingAbilities(fullRandomMode); Region region = FindStart(); if (region == null) { return new ReachabilityResult { State = playerState }; } ReachabilityResult reachabilityResult = new ReachabilityResult { State = playerState }; playerState.ReachableRegions.Add(region); Region[] regions = _regions; foreach (Region region2 in regions) { if (region2.IsDream) { playerState.ReachableRegions.Add(region2); } } HashSet<Region> hashSet = new HashSet<Region>(); HashSet<ItemSlot> hashSet2 = new HashSet<ItemSlot>(); HashSet<Region> hashSet3 = new HashSet<Region>(); Queue<Region> queue = new Queue<Region>(); queue.Enqueue(region); regions = _regions; foreach (Region region3 in regions) { if (region3.IsDream) { queue.Enqueue(region3); } } AddFrontier(region, hashSet3, playerState); regions = _regions; foreach (Region region4 in regions) { if (region4.IsDream) { AddFrontier(region4, hashSet3, playerState); } } if (grants != null) { foreach (Item grant in grants) { ApplyItem(playerState, grant); } } int num = 0; do { bool flag = false; while (queue.Count > 0) { Region item = queue.Dequeue(); if (hashSet.Add(item)) { flag = true; } } foreach (KeyValuePair<ItemSlot, Item> item2 in assignment) { ItemSlot key = item2.Key; if (!hashSet2.Contains(key) && playerState.ReachableRegions.Contains(key.Region) && (key.AccessGate == null || GateEvaluator.Satisfied(key.AccessGate, playerState))) { hashSet2.Add(key); ApplyItem(playerState, item2.Value); flag = true; } } if (!flag) { break; } List<Region> list = new List<Region>(); foreach (Region item3 in hashSet3) { if (!playerState.ReachableRegions.Contains(item3) && (item3.EntryGate == null || GateEvaluator.Satisfied(item3.EntryGate, playerState))) { list.Add(item3); } } foreach (Region item4 in list) { playerState.ReachableRegions.Add(item4); hashSet3.Remove(item4); queue.Enqueue(item4); AddFrontier(item4, hashSet3, playerState); } if (list.Count == 0) { break; } num++; } while (num <= 1000); regions = _regions; foreach (Region region5 in regions) { if (playerState.ReachableRegions.Contains(region5)) { reachabilityResult.ReachedRegionIds.Add(region5.Id); } else { reachabilityResult.UnreachedRegionIds.Add(region5.Id); } } foreach (KeyValuePair<ItemSlot, Item> item5 in assignment) { ItemSlot key2 = item5.Key; if (key2.AccessGate != null && playerState.ReachableRegions.Contains(key2.Region) && !GateEvaluator.Satisfied(key2.AccessGate, playerState)) { reachabilityResult.BlockedSlotIds.Add(key2.Id ?? key2.SourceKey ?? "?"); } } reachabilityResult.StepCount = num; return reachabilityResult; } internal static void ApplyItem(PlayerState state, Item item) { switch (item.Kind) { case ItemKind.Ability: state.Abilities.Add(item.AbilityId); { foreach (Permission value in PermissionsData.All.Values) { if (value.BoundAbility == item.AbilityId) { state.Permissions.Add(value.Id); } } break; } case ItemKind.Permission: state.Permissions.Add(item.PermissionId); state.Abilities.Add(item.AbilityId); break; case ItemKind.NamedItem: if (!string.IsNullOrEmpty(item.ItemName)) { state.OwnedItems.Add(item.ItemName); } break; case ItemKind.Cold: state.HasColdResistance = true; break; case ItemKind.Virtual: if (!string.IsNullOrEmpty(item.ItemName)) { state.OwnedItems.Add(item.ItemName); } break; } } private void AddFrontier(Region region, HashSet<Region> frontier, PlayerState state) { foreach (string adjacentRegionId in region.AdjacentRegionIds) { Region item = _byId[adjacentRegionId]; if (!state.ReachableRegions.Contains(item)) { frontier.Add(item); } } } private Region FindStart() { Region[] regions = _regions; foreach (Region region in regions) { if (region.IsStart) { return region; } } return null; } } public class RoomGapComponent { public List<string> Rooms { get; } = new List<string>(); public List<string> RegionIds { get; } = new List<string>(); public int SlotCount { get; set; } public int Count => Rooms.Count; } public class RoomGapSet { private static readonly string[] EmptyRooms = new string[0]; public RoomGraph RoomGraph { get; } public IReadOnlyList<RoomGapComponent> OrphanComponents { get; } public IReadOnlyList<string> OrphanRoomIds { get; } public IReadOnlyList<string> OmittedRoomIds { get; } public IReadOnlyList<string> GapRoomIds { get; } public IReadOnlyDictionary<string, int> RoomSlotCounts { get; } public int OrphanRoomCount => OrphanRoomIds.Count; public int OmittedRoomCount => OmittedRoomIds.Count; public int ExemptRoomCount => GapRoomIds.Count; public int OrphanSlotCount { get; } public int OmittedSlotCount { get; } public int ExemptSlotCount { get; } public bool IsEmpty => GapRoomIds.Count == 0; private RoomGapSet(RoomGraph graph, IReadOnlyList<RoomGapComponent> orphanComponents, IReadOnlyList<string> orphanRooms, IReadOnlyList<string> omittedRooms, IReadOnlyDictionary<string, int> slotCounts, int orphanSlotCount, int omittedSlotCount) { RoomGraph = graph; OrphanComponents = orphanComponents; OrphanRoomIds = orphanRooms; OmittedRoomIds = omittedRooms; RoomSlotCounts = slotCounts; List<string> list = new List<string>(orphanRooms); HashSet<string> hashSet = new HashSet<string>(orphanRooms, StringComparer.Ordinal); foreach (string omittedRoom in omittedRooms) { if (hashSet.Add(omittedRoom)) { list.Add(omittedRoom); } } list.Sort(StringComparer.Ordinal); GapRoomIds = list; OrphanSlotCount = orphanSlotCount; OmittedSlotCount = omittedSlotCount; ExemptSlotCount = orphanSlotCount + omittedSlotCount; } public bool IsGapRoom(string roomId) { if (roomId == null || GapRoomIds.Count == 0) { return false; } int num = 0; int num2 = GapRoomIds.Count - 1; while (num <= num2) { int num3 = num + (num2 - num) / 2; int num4 = string.CompareOrdinal(roomId, GapRoomIds[num3]); if (num4 == 0) { return true; } if (num4 < 0) { num2 = num3 - 1; } else { num = num3 + 1; } } return false; } public int SlotCountOf(string roomId) { if (roomId == null || !RoomSlotCounts.TryGetValue(roomId, out var value)) { return 0; } return value; } public static RoomGapSet Compute(RoomGraph graph, Region[] regions, IReadOnlyCollection<ItemSlot> slots) { if (graph == null) { return null; } Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if (slots != null) { foreach (ItemSlot slot in slots) { if (slot != null && !string.IsNullOrEmpty(slot.RoomId)) { hashSet.Add(slot.RoomId); dictionary.TryGetValue(slot.RoomId, out var value); dictionary[slot.RoomId] = value + 1; } } } List<RoomGapComponent> list = new List<RoomGapComponent>(); int num = 0; IReadOnlyList<string> orphanRoomIds = graph.OrphanRoomIds; foreach (RoomComponent component in graph.Components) { if (component.IsValid) { continue; } RoomGapComponent roomGapComponent = new RoomGapComponent(); HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); foreach (string room in component.Rooms) { roomGapComponent.Rooms.Add(room); if (dictionary.TryGetValue(room, out var value2)) { roomGapComponent.SlotCount += value2; } if (graph.RoomToRegion.TryGetValue(room, out var value3)) { hashSet2.Add(value3); } } roomGapComponent.RegionIds.AddRange(hashSet2); roomGapComponent.RegionIds.Sort(StringComparer.Ordinal); num += roomGapComponent.SlotCount; list.Add(roomGapComponent); } List<string> list2 = new List<string>(); int num2 = 0; if (slots != null && hashSet.Count > 0) { HashSet<string> hashSet3 = new HashSet<string>(StringComparer.Ordinal); if (!string.IsNullOrEmpty(graph.StartRoomId)) { hashSet3.Add(graph.StartRoomId); } foreach (string item in RoomGraph.DreamRegionRooms(regions, graph)) { hashSet3.Add(item); } foreach (string item2 in hashSet) { if (!graph.Adjacency.ContainsKey(item2) && !hashSet3.Contains(item2)) { list2.Add(item2); if (dictionary.TryGetValue(item2, out var value4)) { num2 += value4; } } } list2.Sort(StringComparer.Ordinal); } HashSet<string> hashSet4 = new HashSet<string>(orphanRoomIds, StringComparer.Ordinal); foreach (string item3 in list2) { hashSet4.Add(item3); } Dictionary<string, int> dictionary2 = new Dictionary<string, int>(StringComparer.Ordinal); foreach (KeyValuePair<string, int> item4 in dictionary) { if (hashSet4.Contains(item4.Key)) { dictionary2[item4.Key] = item4.Value; } } IReadOnlyList<string> omittedRooms; if (list2.Count <= 0) { IReadOnlyList<string> emptyRooms = EmptyRooms; omittedRooms = emptyRooms; } else { IReadOnlyList<string> emptyRooms = list2; omittedRooms = emptyRooms; } return new RoomGapSet(graph, list, orphanRoomIds, omittedRooms, dictionary2, num, num2); } } public static class RoomGapReport { private static bool _warned; public static bool Warned => _warned; public static void Reset() { _warned = false; } public static void WarnOnce(RoomGapSet gaps) { if (gaps == null || _warned) { return; } _warned = true; if (gaps.IsEmpty) { Console.WriteLine("[RoomPrecision] 数据缺口核验:无缺口房间,房间精度按全房间严格判定。"); return; } Console.WriteLine("[RoomPrecision] 数据缺口豁免:孤儿分量 " + gaps.OrphanComponents.Count + " 组/共 " + gaps.OrphanRoomCount + " 房;缺节点 " + gaps.OmittedRoomCount + " 房/" + gaps.OmittedSlotCount + " 点位;合计豁免 " + gaps.ExemptRoomCount + " 房/" + gaps.ExemptSlotCount + " 点位"); for (int i = 0; i < gaps.OrphanComponents.Count; i++) { RoomGapComponent roomGapComponent = gaps.OrphanComponents[i]; Console.WriteLine("[RoomPrecision] 孤儿分量 #" + (i + 1) + ":" + roomGapComponent.Count + " 房/" + roomGapComponent.SlotCount + " 点位,区域=[" + string.Join(",", roomGapComponent.RegionIds) + "]"); Console.WriteLine("[RoomPrecision] 房间=" + Describe(gaps, roomGapComponent.Rooms)); } Console.WriteLine("[RoomPrecision] 缺节点房间=" + Describe(gaps, gaps.OmittedRoomIds)); Console.WriteLine("[RoomPrecision] 说明:以上房间在 场景连接.txt 中缺边/缺节点,房间精度下恒不可达;死种评定豁免(不计死种),但放置可达性不放宽——放置器照常不向这些房间的点位投放物品。"); } private static string Describe(RoomGapSet gaps, IReadOnlyList<string> rooms) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < rooms.Count; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(rooms[i]); int num = gaps.SlotCountOf(rooms[i]); if (num > 0) { stringBuilder.Append('(').Append(num).Append("点位)"); } } return stringBuilder.ToString(); } } public static class RoomGraphBuilder { private const string DynamicPlaceholder = "[dynamic]"; internal const string StartRegionId = "Tut"; public static RoomGraph Build(string[] lines, PrefixResolver resolver, Region[] regions = null) { return Build((IEnumerable<string>)lines, resolver, regions); } public static RoomGraph Build(IEnumerable<string> lines, PrefixResolver resolver, Region[] regions = null) { RoomGraph roomGraph = new RoomGraph(); if (lines == null) { return roomGraph; } HashSet<string> seen = new HashSet<string>(StringComparer.Ordinal); foreach (string line in lines) { if (line == null) { continue; } string text = line.Trim(); if (text.Length == 0 || text.StartsWith("#")) { continue; } string[] array = text.Split(new char[1] { '|' }); if (array.Length < 3) { continue; } string text2 = array[0].Trim(); string text3 = array[2].Trim(); if (text2.Length != 0 && text3.Length != 0) { Map(roomGraph, seen, text2, resolver); Map(roomGraph, seen, text3, resolver); if (!(text2 == "[dynamic]") && !(text3 == "[dynamic]") && !(text2 == text3)) { AddEdge(roomGraph, text2, text3); AddEdge(roomGraph, text3, text2); } } } ResolveStartRoom(roomGraph); roomGraph.DeclareAlwaysReachableRooms(RoomGraph.DreamRegionRooms(regions, roomGraph)); return roomGraph; } private static void Map(RoomGraph graph, HashSet<string> seen, string scene, PrefixResolver resolver) { if (!seen.Add(scene)) { return; } Region region = resolver?.Resolve(scene); if (region == null) { if (!graph.UnmappedScenes.Contains(scene)) { graph.UnmappedScenes.Add(scene); } } else { graph.RoomToRegion[scene] = region.Id; } } private static void AddEdge(RoomGraph graph, string a, string b) { if (!graph.Adjacency.TryGetValue(a, out var value)) { value = new HashSet<string>(StringComparer.Ordinal); graph.Adjacency[a] = value; } value.Add(b); } private static void ResolveStartRoom(RoomGraph graph) { if (!graph.Adjacency.ContainsKey(graph.StartRoomId)) { string text = FirstRoomOfRegion(graph, "Tut"); if (text == null) { Console.WriteLine("[RoomGraph] start-fallback failed: 图内无 Tut 区域房间,StartRoomId 保持 " + graph.StartRoomId); return; } Console.WriteLine("[RoomGraph] start-fallback: " + graph.StartRoomId + " 不在场景连接图中,回退到 Tut 区域房间 " + text); graph.StartRoomId = text; } } internal static string FirstRoomOfRegion(RoomGraph graph, string regionId) { string text = null; foreach (KeyValuePair<string, string> item in graph.RoomToRegion) { if (string.Equals(item.Value, regionId, StringComparison.Ordinal) && (text == null || string.CompareOrdinal(item.Key, text) < 0)) { text = item.Key; } } return text; } } public static class RoomReachability { private const int MaxSteps = 1000; private static readonly ConditionalWeakTable<RoomGraph, RoomTopology> Cache = new ConditionalWeakTable<RoomGraph, RoomTopology>(); public static ReachabilityResult Compute(IReadOnlyDictionary<ItemSlot, Item> assignment, List<ItemSlot> allSlots, RoomGraph roomGraph, Region[] regions, bool fullRandomMode, IReadOnlyList<Item> grants = null) { PlayerState playerState = PlayerState.WithStartingAbilities(fullRandomMode); ReachabilityResult reachabilityResult = new ReachabilityResult { State = playerState, RoomMode = true }; if (roomGraph == null) { return reachabilityResult; } if (assignment == null) { assignment = new Dictionary<ItemSlot, Item>(); } RoomTopology roomTopology = Topology(roomGraph, regions); playerState.ReachableRooms = roomTopology.ReachableRooms; playerState.ReachableRegions.UnionWith(roomTopology.ReachableRegionObjects); reachabilityResult.ReachedRoomIds.AddRange(roomTopology.ReachedRoomIds); reachabilityResult.UnreachedRoomIds.AddRange(roomTopology.UnreachedRoomIds); reachabilityResult.ReachedRegionIds.AddRange(roomTopology.ReachedRegionIds); reachabilityResult.UnreachedRegionIds.AddRange(roomTopology.UnreachedRegionIds); if (grants != null) { foreach (Item grant in grants) { ReachabilityAnalyzer.ApplyItem(playerState, grant); } } foreach (KeyValuePair<ItemSlot, Item> item in assignment) { ItemSlot key = item.Key; if (IsSlotReachable(key, roomGraph, roomTopology) && (key.AccessGate == null || GateEvaluator.Satisfied(key.AccessGate, playerState))) { ReachabilityAnalyzer.ApplyItem(playerState, item.Value); } } foreach (KeyValuePair<ItemSlot, Item> item2 in assignment) { ItemSlot key2 = item2.Key; if (key2.AccessGate != null && IsSlotReachable(key2, roomGraph, roomTopology) && !GateEvaluator.Satisfied(key2.AccessGate, playerState)) { reachabilityResult.BlockedSlotIds.Add(key2.Id ?? key2.SourceKey ?? "?"); } } reachabilityResult.StepCount = roomTopology.Steps; return reachabilityResult; } public static bool IsSlotReachable(ItemSlot slot, RoomGraph roomGraph, RoomTopology topo) { if (slot == null) { return false; } if (!string.IsNullOrEmpty(slot.RoomId)) { return topo.ReachableRooms.Contains(slot.RoomId); } if (slot.Region == null) { return false; } return topo.ReachableRegionIds.Contains(slot.Region.Id); } public static RoomTopology Topology(RoomGraph roomGraph, Region[] regions) { return Cache.GetValue(roomGraph, (RoomGraph g) => BuildTopology(g, regions)); } private static RoomTopology BuildTopology(RoomGraph roomGraph, Region[] regions) { HashSet<string> hashSet = SeedRooms(roomGraph, regions); List<string> list = new List<string>(hashSet); int num = 0; while (list.Count > 0 && num < 1000) { List<string> list2 = new List<string>(); foreach (string item in list) { if (!roomGraph.Adjacency.TryGetValue(item, out var value)) { continue; } foreach (string item2 in value) { if (hashSet.Add(item2)) { list2.Add(item2); } } } list = list2; num++; } RoomTopology roomTopology = new RoomTopology { Steps = num }; List<string> list3 = new List<string>(roomGraph.Adjacency.Keys); list3.Sort(StringComparer.Ordinal); foreach (string item3 in list3) { if (hashSet.Contains(item3)) { roomTopology.ReachedRoomIds.Add(item3); } else { roomTopology.UnreachedRoomIds.Add(item3); } } foreach (string item4 in hashSet) { if (roomGraph.Adjacency.ContainsKey(item4)) { roomTopology.ReachableRooms.Add(item4); } } HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); foreach (string reachedRoomId in roomTopology.ReachedRoomIds) { if (roomGraph.RoomToRegion.TryGetValue(reachedRoomId, out var value2)) { hashSet2.Add(value2); } } if (regions != null) { foreach (Region region in regions) { if (region != null) { if (hashSet2.Contains(region.Id)) { roomTopology.ReachedRegionIds.Add(region.Id); roomTopology.ReachableRegionObjects.Add(region); } else { roomTopology.UnreachedRegionIds.Add(region.Id); } } } } else { List<string> list4 = new List<string>(hashSet2); list4.Sort(StringComparer.Ordinal); foreach (string item5 in list4) { roomTopology.ReachedRegionIds.Add(item5); } } foreach (string item6 in hashSet2) { roomTopology.ReachableRegionIds.Add(item6); } return roomTopology; } private static HashSet<string> SeedRooms(RoomGraph roomGraph, Region[] regions) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if (!string.IsNullOrEmpty(roomGraph.StartRoomId)) { hashSet.Add(roomGraph.StartRoomId); } HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); if (regions != null) { foreach (Region region in regions) { if (region != null && region.IsDream) { hashSet2.Add(region.Id); } } } if (hashSet2.Count == 0) { return hashSet; } foreach (KeyValuePair<string, string> item in roomGraph.RoomToRegion) { if (hashSet2.Contains(item.Value)) { hashSet.Add(item.Key); } } return hashSet; } } public class RoomTopology { public int Steps { get; internal set; } public HashSet<string> ReachableRooms { get; } = new HashSet<string>(StringComparer.Ordinal); public HashSet<string> ReachableRegionIds { get; } = new HashSet<string>(StringComparer.Ordinal); public List<Region> ReachableRegionObjects { get; } = new List<Region>(); public List<string> ReachedRoomIds { get; } = new List<string>(); public List<string> UnreachedRoomIds { get; } = new List<string>(); public List<string> ReachedRegionIds { get; } = new List<string>(); public List<string> UnreachedRegionIds { get; } = new List<string>(); } public class SceneGraphBuilder { private readonly Region[] _regions; private readonly PrefixResolver _resolver; private readonly Dictionary<string, string> _unmappedScenes = new Dictionary<string, string>(); public IReadOnlyDictionary<string, string> UnmappedScenes => _unmappedScenes; public SceneGraphBuilder(Region[] regions) { _regions = regions; _resolver = new PrefixResolver(regions); } public void Build(string sceneConnectionPath) { Build(File.ReadAllLines(sceneConnectionPath)); } public void Build(IEnumerable<string> lines) { Region[] regions = _regions; for (int i = 0; i < regions.Length; i++) { regions[i].AdjacentRegionIds.Clear(); } foreach (string line in lines) { string text = line.Trim(); if (text.Length == 0 || text.StartsWith("#")) { continue; } string[] array = text.Split(new char[1] { '|' }); if (array.Length < 4) { continue; } string text2 = array[0].Trim(); string text3 = array[2].Trim(); if (!(text2 == "[dynamic]") && !(text3 == "[dynamic]")) { Region region = Resolve(text2); Region region2 = Resolve(text3); if (region != null && region2 != null && region != region2) { AddEdge(region, region2); AddEdge(region2, region); } } } } private Region Resolve(string sceneName) { Region region = _resolver.Resolve(sceneName); if (region != null) { return region; } string key = SceneKey(sceneName); if (!_unmappedScenes.ContainsKey(key)) { _unmappedScenes[key] = sceneName; } return null; } public static string SceneKey(string sceneName) { int num = sceneName.IndexOf('_'); if (num >= 0) { return sceneName.Substring(0, num); } return sceneName; } private static void AddEdge(Region a, Region b) { if (!a.AdjacentRegionIds.Contains(b.Id)) { a.AdjacentRegionIds.Add(b.Id); } } } public class SpherePlacement { private readonly Region[] _regions; private readonly ReachabilityAnalyzer _analyzer; public bool RoomPrecision => _analyzer.RoomPrecision; private string ScopeLabel { get { if (!RoomPrecision) { return "可达区域"; } return "可达房间"; } } private int ScopeTotal { get { if (!RoomPrecision) { return _regions.Length; } if (_analyzer.RoomGraph == null) { return 0; } return _analyzer.RoomGraph.RoomCount; } } public string LastFailureReason { get; private set; } public SpherePlacement(Region[] regions, RoomGraph roomGraph = null) { _regions = regions; _analyzer = new ReachabilityAnalyzer(regions, roomGraph); } public bool TryPlace(List<ItemSlot> slots, List<Item> pool, out Dictionary<ItemSlot, Item> assignment, bool fullRandomMode = false, Random rng = null) { LastFailureReason = null; if (slots == null || pool == null) { assignment = null; LastFailureReason = "槽位或物品池为空"; return false; } if (rng == null) { rng = new Random(); } _analyzer.AllSlots = slots; Dictionary<ItemSlot, Item> dictionary = new Dictionary<ItemSlot, Item>(); foreach (KeyValuePair<ItemSlot, Item> item in new FixedAssignments(_regions).All) { dictionary[PlacementSimulator.MatchFixedSlot(slots, item.Key) ?? item.Key] = item.Value; } List<ItemSlot> list = new List<ItemSlot>(); foreach (ItemSlot slot in slots) { if (!slot.IsFixed && !dictionary.ContainsKey(slot)) { list.Add(slot); } } List<Item> list2 = new List<Item>(pool); int num = slots.Count * 2 + 1; while (list2.Count > 0) { if (--num < 0) { assignment = dictionary; LastFailureReason = "轮数上限,剩余物品 " + list2.Count; return false; } PlayerState state = _analyzer.Compute(dictionary, fullRandomMode).State; List<ItemSlot> list3 = AvailableSlots(list, dictionary, state, RoomPrecision); if (list3.Count == 0) { assignment = dictionary; LastFailureReason = "无可取槽,剩余物品 " + list2.Count + "," + ScopeLabel + " " + ReachabilityCount(state) + "/" + ScopeTotal; return false; } List<Item> list4 = PriorityOrder(list2, rng); List<Item> list5 = new List<Item>(); bool flag = false; foreach (Item item2 in list4) { list5.Add(item2); if (GrantCount(list5, dictionary, list, fullRandomMode) > list3.Count) { flag = true; break; } } if (!flag) { if (list2.Count > list3.Count) { assignment = dictionary; LastFailureReason = "收尾槽位不足:剩余 " + list2.Count + " > 可取 " + list3.Count; return false; } foreach (Item item3 in list2) { ItemSlot itemSlot = TakeSlot(list3, rng); dictionary[itemSlot] = item3; list.Remove(itemSlot); } list2.Clear(); continue; } List<Item> list6 = new List<Item>(); for (int num2 = list5.Count - 1; num2 >= 0; num2--) { List<Item> list7 = new List<Item>(list5.Take(num2)); list7.AddRange(list6); if (GrantCount(list7, dictionary, list, fullRandomMode) < list3.Count + 1) { list6.Add(list5[num2]); } } list6.Reverse(); if (list6.Count == 0) { list6.Add(list5[list5.Count - 1]); } PlayerState state2 = _analyzer.Compute(dictionary, fullRandomMode, list6).State; List<ItemSlot> list8 = AvailableSlots(list, dictionary, state2, RoomPrecision); HashSet<ItemSlot> baseSet = new HashSet<ItemSlot>(list3); List<ItemSlot> list9 = list8.Where((ItemSlot s) => !baseSet.Contains(s)).ToList(); List<ItemSlot> list10 = ((list9.Count > 0) ? list9 : new List<ItemSlot>(list8)); foreach (ItemSlot item4 in list3) { if (!list10.Contains(item4)) { list10.Add(item4); } } Shuffle(rng, list6); foreach (Item item5 in list6) { List<Item> list11 = new List<Item>(); foreach (Item item6 in list6) { if (item6 != item5) { list11.Add(item6); } } PlayerState state3 = _analyzer.Compute(dictionary, fullRandomMode, list11).State; List<ItemSlot> list12 = AvailableSlots(list, dictionary, state3, RoomPrecision); List<ItemSlot> list13 = new List<ItemSlot>(); foreach (ItemSlot item7 in list10) { if (list12.Contains(item7)) { list13.Add(item7); } } if (list13.Count == 0) { assignment = dictionary; LastFailureReason = "自锁无可落点:" + item5?.ToString() + "(其候选槽均需自身授权)"; return false; } ItemSlot itemSlot2 = TakeSlot(list13, rng); dictionary[itemSlot2] = item5; list2.Remove(item5); list10.Remove(itemSlot2); } } assignment = dictionary; LastFailureReason = null; return true; } public static List<ItemSlot> AvailableSlots(List<ItemSlot> open, IReadOnlyDictionary<ItemSlot, Item> working, PlayerState state, bool roomPrecision = false) { List<ItemSlot> list = new List<ItemSlot>(); foreach (ItemSlot item in open) { if (working.ContainsKey(item)) { continue; } if (roomPrecision && !string.IsNullOrEmpty(item.RoomId)) { if (!state.ReachableRooms.Contains(item.RoomId)) { continue; } } else if (item.Region == null || !state.ReachableRegions.Contains(item.Region)) { continue; } if (item.AccessGate == null || GateEvaluator.Satisfied(item.AccessGate, state)) { list.Add(item); } } return list; } private int GrantCount(List<Item> grants, Dictionary<ItemSlot, Item> working, List<ItemSlot> open, bool fullRandomMode) { PlayerState state = _analyzer.Compute(working, fullRandomMode, grants).State; return AvailableSlots(open, working, state, RoomPrecision).Count; } private static List<Item> PriorityOrder(List<Item> unplaced, Random rng) { SortedList<int, List<Item>> sortedList = new SortedList<int, List<Item>>(); foreach (Item item in unplaced) { if (!sortedList.TryGetValue(item.Priority, out var value)) { value = new List<Item>(); sortedList[item.Priority] = value; } value.Add(item); } List<Item> list = new List<Item>(); foreach (KeyValuePair<int, List<Item>> item2 in sortedList) { list.AddRange(Shuffled(rng, item2.Value)); } return list; } private static int ReachabilityCount(PlayerState state) { if (state.ReachableRooms.Count <= 0) { return state.ReachableRegions.Count; } return state.ReachableRooms.Count; } private static ItemSlot TakeSlot(List<ItemSlot> list, Random rng) { int index = rng.Next(list.Count); ItemSlot result = list[index]; list.RemoveAt(index); return result; } internal static List<T> Shuffled<T>(Random rng, List<T> src) { List<T> list = new List<T>(src); for (int num = list.Count - 1; num > 0; num--) { int num2 = rng.Next(num + 1); List<T> list2 = list; int index = num; List<T> list3 = list; int index2 = num2; T value = list[num2]; T value2 = list[num]; list2[index] = value; list3[index2] = value2; } return list; } internal static void Shuffle<T>(Random rng, List<T> list) { for (int num = list.Count - 1; num > 0; num--) { int num2 = rng.Next(num + 1); int index = num; int index2 = num2; T value = list[num2]; T value2 = list[num]; list[index] = value; list[index2] = value2; } } } } namespace PharloomCore.Data { public static class AbilitiesData { public static readonly Dictionary<AbilityId, Ability> All = Build(); private static Dictionary<AbilityId, Ability> Build() { Dictionary<AbilityId, Ability> dictionary = new Dictionary<AbilityId, Ability>(); Add(dictionary, AbilityId.NeedleThrow, "hasNeedleThrow", "丝之矛", AbilityCategory.Combat); Add(dictionary, AbilityId.Dash, "hasDash", "疾风步", AbilityCategory.Movement); Add(dictionary, AbilityId.DoubleJump, "hasDoubleJump", "雪绒披风(二段跳)", AbilityCategory.Movement); Add(dictionary, AbilityId.Brolly, "hasBrolly", "流浪者披风(斗篷)", AbilityCategory.Movement); Add(dictionary, AbilityId.SuperJump, "hasSuperJump", "灵丝升腾(上冲)", AbilityCategory.Movement); Add(dictionary, AbilityId.Walljump, "hasWalljump", "蛛攀术(爬墙)", AbilityCategory.Movement); Add(dictionary, AbilityId.HarpoonDash, "hasHarpoonDash", "飞针", AbilityCategory.Movement); Add(dictionary, AbilityId.SilkCharge, "hasSilkCharge", "丝刃标", AbilityCategory.Spell); Add(dictionary, AbilityId.ThreadSphere, "hasThreadSphere", "灵丝风暴", AbilityCategory.Spell); Add(dictionary, AbilityId.SilkBomb, "hasSilkBomb", "符文之怒", AbilityCategory.Spell); Add(dictionary, AbilityId.SilkBossNeedle, "hasSilkBossNeedle", "苍白之爪", AbilityCategory.Spell); Add(dictionary, AbilityId.ChargeSlash, "hasChargeSlash", "蓄力斩", AbilityCategory.Spell); Add(dictionary, AbilityId.Parry, "hasParry", "格挡", AbilityCategory.Combat); Add(dictionary, AbilityId.Needolin, "hasNeedolin", "丝忆弦针", AbilityCategory.Music); Add(dictionary, AbilityId.EvaHeal, "HasSeenEvaHeal", "风铃摇", AbilityCategory.Music); Add(dictionary, AbilityId.NeedolinMemory, "hasNeedolinMemoryPowerup", "深邃挽歌", AbilityCategory.Music); Add(dictionary, AbilityId.Teleport, "hasFastTravelTeleport", "幻兽歌", AbilityCategory.Music); Add(dictionary, AbilityId.MelodyConductor, "HasMelodyConductor", "旋律·指挥", AbilityCategory.Music); Add(dictionary, AbilityId.MelodyLibrarian, "HasMelodyLibrarian", "旋律·司书", AbilityCategory.Music); Add(dictionary, AbilityId.MelodyArchitect, "HasMelodyArchitect", "旋律·建筑师", AbilityCategory.Music); Add(dictionary, AbilityId.SilkHeart, "SilkHeart", "丝之心", AbilityCategory.Music); Add(dictionary, AbilityId.Journal, "Journal", "猎人日志", AbilityCategory.Combat); Add(dictionary, AbilityId.SilkDash, "hasSilkDash", "丝冲", AbilityCategory.Movement); Add(dictionary, AbilityId.AttackUp, "perm:upward", "上劈权限", AbilityCategory.Combat); Add(dictionary, AbilityId.AttackLeft, "perm:left", "左劈权限", AbilityCategory.Combat); Add(dictionary, AbilityId.AttackRight, "perm:right", "右劈权限", AbilityCategory.Combat); Add(dictionary, AbilityId.Heal, "perm:heal", "回血权限", AbilityCategory.Combat); Add(dictionary, AbilityId.Swim, "Swim", "游泳", AbilityCategory.Movement); Add(dictionary, AbilityId.ShamanCrest, "chapelClosed_shaman", "萨满纹章", AbilityCategory.Movement); Add(dictionary, AbilityId.ArchitectChargeSlash, "hasChargeSlash", "建筑师蓄力斩", AbilityCategory.Combat); return dictionary; } private static void Add(Dictionary<AbilityId, Ability> d, AbilityId id, string key, string name, AbilityCategory cat) { d[id] = new Ability { Id = id, Key = key, DisplayName = name, Category = cat }; } } public static class AbilityAlias { private static readonly Dictionary<string, AbilityId> Map = new Dictionary<string, AbilityId>(StringComparer.OrdinalIgnoreCase) { { "二段跳", AbilityId.DoubleJump }, { "二段", AbilityId.DoubleJump }, { "爬墙", AbilityId.Walljump }, { "上冲", AbilityId.SuperJump }, { "上劈", AbilityId.SuperJump }, { "冲刺", AbilityId.Dash }, { "疾跑", AbilityId.Dash }, { "疾风步", AbilityId.Dash }, { "斗篷", AbilityId.Brolly }, { "披风", AbilityId.Brolly }, { "飞针", AbilityId.HarpoonDash }, { "丝冲", AbilityId.SilkDash }, { "丝蓄", AbilityId.SilkCharge }, { "蓄力丝冲", AbilityId.SilkCharge }, { "丝之矛", AbilityId.NeedleThrow }, { "灵丝风暴", AbilityId.ThreadSphere }, { "丝风暴", AbilityId.ThreadSphere }, { "符文之怒", AbilityId.SilkBomb }, { "苍白之爪", AbilityId.SilkBossNeedle }, { "蓄力斩", AbilityId.ChargeSlash }, { "格挡", AbilityId.Parry }, { "丝忆", AbilityId.Needolin }, { "丝忆弦针", AbilityId.Needolin }, { "琴弦乐", AbilityId.Needolin }, { "风铃摇", AbilityId.EvaHeal }, { "深邃挽歌", AbilityId.NeedolinMemory }, { "挽歌", AbilityId.NeedolinMemory }, { "幻兽歌", AbilityId.Teleport }, { "传送", AbilityId.Teleport }, { "游泳", AbilityId.Swim }, { "萨满纹章", AbilityId.ShamanCrest }, { "建筑师蓄力斩", AbilityId.ArchitectChargeSlash } }; public static bool TryResolve(string alias, out AbilityId id) { if (alias != null && Map.TryGetValue(alias.Trim(), out id)) { return true; } id = AbilityId.NeedleThrow; return false; } } public static class ItemTiers { private static readonly Dictionary<string, int> Tiers = new Dictionary<string, int> { { "kind:item_skill", 3 }, { "kind:item_relic", 4 }, { "kind:item_other", 4 }, { "kind:item_simplekey", 2 }, { "ability:hasNeedleThrow", 2 }, { "ability:hasThreadSphere", 3 }, { "ability:hasSilkCharge", 2 }, { "ability:hasSilkBomb", 3 }, { "ability:hasSilkBossNeedle", 3 }, { "ability:hasParry", 3 }, { "ability:hasHarpoonDash", 1 }, { "ability:hasNeedolin", 1 }, { "ability:hasDash", 1 }, { "ability:hasBrolly", 1 }, { "ability:hasDoubleJump", 1 }, { "ability:hasChargeSlash", 3 }, { "ability:hasSuperJump", 1 }, { "ability:hasWalljump", 1 }, { "ability:HasSeenEvaHeal", 3 }, { "ability:hasNeedolinMemoryPowerup", 2 }, { "ability:hasFastTravelTeleport", 4 }, { "ability:HasMelodyConductor", 2 }, { "ability:HasMelodyLibrarian", 2 }, { "ability:HasMelodyArchitect", 2 }, { "ability:SilkHeart", 2 }, { "ability:Journal", 3 }, { "ability:ColdResist", 1 }, { "ability:Swim", 1 }, { "perm:upward", 2 }, { "perm:left", 2 }, { "perm:right", 2 }, { "perm:heal", 1 }, { "perm:hasDash_L", 1 }, { "perm:hasDash_R", 1 }, { "perm:hasHarpoonDash_L", 1 }, { "perm:hasHarpoonDash_R", 1 }, { "perm:hasBrolly_L", 1 }, { "perm:hasBrolly_R", 1 }, { "perm:hasWalljump_L", 1 }, { "perm:hasWalljump_R", 1 }, { "virt:HeartPiece", 3 }, { "virt:SpoolPart", 3 }, { "virt:UnlockCrestSlot", 3 }, { "virt:ExtraYellowSlot", 2 }, { "virt:ExtraBlueSlot", 2 }, { "virt:SlabKeyA", 2 }, { "virt:SlabKeyB", 2 }, { "virt:SlabKeyC", 2 }, { "virt:Bellshrines", 3 }, { "kind:maps", 4 }, { "kind:stations", 1 }, { "virt:LoreLog", 4 }, { "flea:Rescue", 3 }, { "virt:Silk_3", 4 }, { "virt:Shards_300", 4 }, { "virt:BlueHealth_Random", 4 }, { "virt:RandomCoin", 4 }, { "virt:FallbackCoin", 0 } }; public static int Resolve(Item item) { string text = TierKey(item); if (text == null) { return 4; } if (!Tiers.TryGetValue(text, out var value)) { return 4; } return value; } private static string TierKey(Item item) { switch (item.Kind) { case ItemKind.Ability: { if (!AbilitiesData.All.TryGetValue(item.AbilityId, out var value)) { return null; } if (!value.Key.StartsWith("perm:")) { return "ability:" + value.Key; } return value.Key; } case ItemKind.Permission: return "perm:" + item.PermissionId; case ItemKind.Cold: return "ability:ColdResist"; case ItemKind.NamedItem: return item.ItemName switch { "SimpleKey" => "kind:item_simplekey", "CrestSocketUnlocker" => "virt:UnlockCrestSlot", "SlabKeyA" => "virt:SlabKeyA", "SlabKeyB" => "virt:SlabKeyB", "SlabKeyC" => "virt:SlabKeyC", _ => null, }; default: return null; } } } public static class PermissionsData { public const bool DefaultSidesSplit = true; public static readonly Dictionary<string, Permission> All = Build(); private static Dictionary<string, Permission> Build() { Dictionary<string, Permission> dictionary = new Dictionary<string, Permission>(); Add(dictionary, "Dash", AbilityId.Dash, PermissionSide.Left); Add(dictionary, "Dash", AbilityId.Dash, PermissionSide.Right); Add(dictionary, "HarpoonDash", AbilityId.HarpoonDash, PermissionSide.Left); Add(dictionary, "HarpoonDash", AbilityId.HarpoonDash, PermissionSide.Right); Add(dictionary, "Brolly", AbilityId.Brolly, PermissionSide.Left); Add(dictionary, "Brolly", AbilityId.Brolly, PermissionSide.Right); Add(dictionary, "Walljump", AbilityId.Walljump, PermissionSide.Left); Add(dictionary, "Walljump", AbilityId.Walljump, PermissionSide.Right); return dictionary; } private static void Add(Dictionary<string, Permission> d, string id, AbilityId ability, PermissionSide side) { d[id + "_" + SideMapping.EngineSuffix(side)] = new Permission { Id = id + "_" + SideMapping.EngineSuffix(side), BoundAbility = ability, Side = side, SidesSplit = true }; } private static string SideSuffix(PermissionSide side) { return SideMapping.EngineSuffix(side); } public static string FullId(string baseId) { return baseId + "_Full"; } public static bool IsFull(string id) { return id.EndsWith("_Full"); } public static string ParseSide(string id, out PermissionSide side) { side = SideMapping.FromEngineSuffix(id); return id.Substring(0, id.Length - 2); } } [DataContract] public class PointConditionFile { [DataMember(Name = "version")] public int Version { get; set; } [DataMember(Name = "points")] public PointConditionData[] Points { get; set; } } [DataContract] public class PointConditionData { [DataMember(Name = "Type")] public string Type { get; set; } [DataMember(Name = "Scene")] public string Scene { get; set; } [DataMember(Name = "Key")] public string Key { get; set; } [DataMember(Name = "Item")] public string Item { get; set; } [DataMember(Name = "Vertical")] public int Vertical { get; set; } [DataMember(Name = "HorizLeft")] public int HorizLeft { get; set; } [DataMember(Name = "HorizRight")] public int HorizRight { get; set; } [DataMember(Name = "Cold")] public bool Cold { get; set; } [DataMember(Name = "ItemRequirement")] public string ItemRequirement { get; set; } [DataMember(Name = "AbilityRequirement")] public string AbilityRequirement { get; set; } [DataMember(Name = "Solutions")] public List<PointSolutionData> Solutions { get; set; } } [DataContract] public class PointSolutionData { [DataMember(Name = "Abilities")] public List<string> Abilities { get; set; } } public static class PointConditionLoader { private static readonly Dictionary<string, string> DirectionPermissionIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "疾跑", "Dash" }, { "漂浮", "Brolly" }, { "飞针", "HarpoonDash" }, { "爬墙", "Walljump" } }; private static readonly Dictionary<string, AbilityId> DirectionAbilities = new Dictionary<string, AbilityId>(StringComparer.OrdinalIgnoreCase) { { "疾跑", AbilityId.Dash }, { "漂浮", AbilityId.Brolly }, { "飞针", AbilityId.HarpoonDash }, { "爬墙", AbilityId.Walljump } }; private static readonly HashSet<string> LegalItemRequirements = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "SlabKeyA", "SlabKeyB", "SlabKeyC" }; public static Dictionary<string, Gate> LoadFile(string path) { if (!File.Exists(path)) { return null; } return LoadJson(File.ReadAllText(path)); } public static Dictionary<string, Gate> LoadLines(IEnumerable<string> lines) { if (lines == null) { return null; } return LoadJson(string.Join("\n", lines)); } public static Dictionary<string, string> LoadSceneMapFile(string path) { if (!File.Exists(path)) { return null; } return LoadSceneMap(File.ReadAllText(path)); } public static Dictionary<string, string> LoadSceneMapLines(IEnumerable<string> lines) { if (lines == null) { return null; } return LoadSceneMap(string.Join("\n", lines)); } private static Dictionary<string, string> LoadSceneMap(string json) { if (string.IsNullOrWhiteSpace(json)) { return null; } PointConditionFile pointConditionFile; try { using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); pointConditionFile = (PointConditionFile)new DataContractJsonSerializer(typeof(PointConditionFile)).ReadObject(stream); } catch { return null; } if (pointConditionFile?.Points == null) { return null; } Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); PointConditionData[] points = pointConditionFile.Points; foreach (PointConditionData pointConditionData in points) { if (pointConditionData != null && !string.IsNullOrEmpty(pointConditionData.Key) && !string.IsNullOrEmpty(pointConditionData.Scene)) { dictionary[pointConditionData.Key.Trim()] = pointConditionData.Scene.Trim(); } } if (dictionary.Count <= 0) { return null; } return dictionary; } private static Dictionary<string, Gate> LoadJson(string json) { if (string.IsNullOrWhiteSpace(json)) { return null; } PointConditionFile pointConditionFile; try { using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); pointConditionFile = (PointConditionFile)new DataContractJsonSerializer(typeof(PointConditionFile)).ReadObject(stream); } catch { return null; } if (pointConditionFile?.Points == null) { return null; } Dictionary<string, Gate> dictionary = new Dictionary<string, Gate>(StringComparer.Ordinal); PointConditionData[] points = pointConditionFile.Points; foreach (PointConditionData pointConditionData in points) { if (pointConditionData != null && !string.IsNullOrEmpty(pointConditionData.Key)) { Gate gate = BuildGate(pointConditionData); if (gate != null) { dictionary[pointConditionData.Key.Trim()] = gate; } } } if (dictionary.Count <= 0) { return null; } return dictionary; } private static Gate BuildGate(PointConditionData p) { List<Gate> list = new List<Gate>(); if (p.Vertical > 0) { list.Add(Gate.VerticalGate(p.Vertical)); } if (p.HorizLeft > 0) { list.Add(Gate.HorizontalGate(p.HorizLeft, PermissionSide.Left)); } if (p.HorizRight > 0) { list.Add(Gate.HorizontalGate(p.HorizRight, PermissionSide.Right)); } if (p.Cold) { list.Add(Gate.ColdGate()); } if (!string.IsNullOrWhiteSpace(p.ItemRequirement) && LegalItemRequirements.Contains(p.ItemRequirement.Trim())) { list.Add(Gate.ItemGate(p.ItemRequirement.Trim())); } if (!string.IsNullOrWhiteSpace(p.AbilityRequirement)) { string text = p.AbilityRequirement.Trim(); AbilityId id; if (text == "抗寒") { list.Add(Gate.ColdGate()); } else if (AbilityAlias.TryResolve(text, out id)) { list.Add(Gate.AbilityGate(id)); } } if (p.Solutions != null && p.Solutions.Count > 0) { List<Gate> list2 = new List<Gate>(); foreach (PointSolutionData solution in p.Solutions) { if (solution == null || solution.Abilities == null || solution.Abilities.Count == 0) { continue; } List<Gate> list3 = new List<Gate>(); foreach (string ability in solution.Abilities) { list3.Add(ResolveSolutionWord(ability)); } list2.Add((list3.Count == 1) ? list3[0] : Gate.And(list3.ToArray())); } if (list2.Count > 0) { list.Add((list2.Count == 1) ? list2[0] : Gate.Or(list2.ToArray())); } } if (list.Count == 0) { return null; } if (list.Count == 1) { return list[0]; } return Gate.And(list.ToArray()); } private static Gate ResolveSolutionWord(string word) { if (string.IsNullOrWhiteSpace(word)) { return Gate.NeverGate(); } string text = word.Trim(); PermissionSide? permissionSide = null; int num = text.IndexOf('('); if (num > 0 && text.EndsWith(")", StringComparison.Ordinal)) { string text2 = text.Substring(num + 1, text.Length - num - 2).Trim(); text = text.Substring(0, num).Trim(); if (text2 == "左") { permissionSide = PermissionSide.Left; } else if (text2 == "右") { permissionSide = PermissionSide.Right; } } if (DirectionPermissionIds.TryGetValue(text, out var value)) { if (permissionSide.HasValue) { return Gate.PermissionGate(value, permissionSide.Value); } if (DirectionAbilities.TryGetValue(text, out var value2)) { return Gate.AbilityGate(value2); } } if (AbilityAlias.TryResolve(text, out var id)) { return Gate.AbilityGate(id); } return Gate.NeverGate(); } } public static class RegionsData { public static readonly Region[] All = Build(); private static Gate BrollyAny => Gate.Or(Perm("Brolly", PermissionSide.Left), Perm("Brolly", PermissionSide.Right)); private static Gate WallJumpBoth => Gate.And(Perm("Walljump", PermissionSide.Left), Perm("Walljump", PermissionSide.Right)); private static Gate HarpoonBoth => Gate.And(Perm("HarpoonDash", PermissionSide.Left), Perm("HarpoonDash", PermissionSide.Right)); private static Gate Ability(AbilityId id) { return Gate.AbilityGate(id); } private static Gate Perm(string baseId, PermissionSide side) { return Gate.PermissionGate(baseId, side); } private static Region[] Build() { List<Region> list = new List<Region>(); Region region = RegionsData.R("Tut", "苔藓洞穴(起点)", true, "Tut", "Mosstown"); list.Add(region); Region regi
BepInEx/plugins/SilksongItemRandomizer.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using AssetChainFixer; using Benchwarp.Components; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using GlobalSettings; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using PharloomCore; using PharloomCore.Data; using PharloomCore.Model; using QuestPlaymakerActions; using SilksongItemRandomizer; using StartingAbilityPicker; using TMProOld; using TeamCherry.Localization; using TeamCherry.SharedUtils; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; 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: AssemblyCompany("SilksongItemRandomizer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("SilksongItemRandomizer")] [assembly: AssemblyTitle("SilksongItemRandomizer")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourGitHubUsername/SilksongItemRandomizer")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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; } } } public class HotkeyHandler : MonoBehaviour { private GUIStyle _tipStyle; private GUIStyle _titleBoldStyle; private GUIStyle _nameBoldStyle; private GUIStyle _hintStyle; private GUIStyle _pickBtnStyle; private GUIStyle _skipBtnStyle; private GUIStyle _smallHintStyle; private GUIStyle _noteFieldStyle; private GUIStyle _noteBtnStyle; private static bool _isChineseCache; private List<(string cat, string name)> _currentCandidates = new List<(string, string)>(); private int _f4MsgCycleIndex; private int _f4ComboTier; private static readonly (string kind, string evt)[] F4GlowPopupItems = new(string, string)[9] { ("heart", "CORAL"), ("heart", "FLOWER"), ("heart", "HUNTER"), ("heart", "CLOVER"), ("melody", "CONDUCTOR"), ("melody", "LIBRARIAN"), ("melody", "ARCHITECT"), ("hcombo", "1"), ("hcombo", "2") }; private int _f4PopupIndex; private static bool _f4Toggle; private static int _crestPopupIndex; private static readonly string[] _testSkillFields = new string[17] { "hasDash", "hasWalljump", "hasHarpoonDash", "hasNeedolin", "hasSuperJump", "HasSeenEvaHeal", "hasNeedleThrow", "hasThreadSphere", "hasSilkCharge", "hasSilkBomb", "hasSilkBossNeedle", "hasParry", "hasBrolly", "hasDoubleJump", "hasChargeSlash", "hasNeedolinMemoryPowerup", "hasFastTravelTeleport" }; private static int _extraSlotTestIndex = 0; private static bool _slotDepsLoaded; private static int _splitTestIndex = 0; private static readonly (string label, string skillField, bool right, bool left)[] DirectionCalibList = new(string, string, bool, bool)[8] { ("冲刺左", "hasDash", false, true), ("冲刺右", "hasDash", true, false), ("飞针左", "hasHarpoonDash", false, true), ("飞针右", "hasHarpoonDash", true, false), ("漂浮左", "hasBrolly", false, true), ("漂浮右", "hasBrolly", true, false), ("壁跳左", "hasWalljump", false, true), ("壁跳右", "hasWalljump", true, false) }; private int _dirCalibIndex = 0; private static int _loreTestIndex = -1; private static int _f4SelfGiveIndex = 0; private static readonly (string label, string[] keys)[] SpriteSearchGroups = new(string, string[])[21] { ("prompt", new string[1] { "prompt" }), ("slash", new string[1] { "slash" }), ("needle", new string[1] { "needle" }), ("geo", new string[1] { "geo" }), ("rosary", new string[2] { "rosary", "bead" }), ("toll", new string[1] { "toll" }), ("map", new string[1] { "map" }), ("quest", new string[1] { "quest" }), ("station", new string[1] { "station" }), ("bench", new string[1] { "bench" }), ("bell", new string[1] { "bell" }), ("shrine", new string[2] { "shrine", "chapel" }), ("lock", new string[2] { "lock", "door" }), ("silk", new string[1] { "silk" }), ("shell", new string[2] { "shell", "shard" }), ("spool", new string[1] { "spool" }), ("crest", new string[1] { "crest" }), ("mask", new string[1] { "mask" }), ("heart", new string[1] { "heart" }), ("key", new string[1] { "key" }), ("memory", new string[2] { "memory", "orb" }) }; private static readonly (string cat, string name)[] SpritePickCandidates = new(string, string)[144] { ("prompt", "Cursed_item_prompt"), ("prompt", "Map_prompt"), ("prompt", "Tools_prompt"), ("prompt", "Crest_prompt"), ("prompt", "Journal_Prompt"), ("prompt", "Deep_Memory_Prompt"), ("prompt", "kings_brand_prompt"), ("prompt", "Wall_Jump_Prompt"), ("prompt", "Needolin_Prompt"), ("prompt", "dreamer_mask_prompt"), ("prompt", "Materium_Prompt"), ("prompt", "prompt_silkheart"), ("needle", "T_longneedle"), ("needle", "S_needle_throw"), ("needle", "cradle_needle"), ("needle", "Curse_dark_needle"), ("needle", "prompt_hornet_needle_throw"), ("rosary", "I_rosary_icon_clean"), ("rosary", "I_rosary_icon_big_clean"), ("rosary", "I_rosary_icon_mid_clean"), ("rosary", "I_rosary_icon_etched"), ("rosary", "tiny_icon_rosary"), ("rosary", "rosary_rock_type_base"), ("rosary", "T_rosary_magnet"), ("rosary", "tiny_tool_icon_rosary_cannon"), ("rosary", "rosary_cache_bell"), ("toll", "Toll_machine_silk_ration"), ("toll", "Toll_cap0003"), ("toll", "Toll_cog0006"), ("toll", "bellbench_toll_machine"), ("toll", "bellbench_toll_machine_map"), ("map", "I_map"), ("map", "I_map_type_02"), ("map", "I_quill_and_map"), ("map", "map_arrow"), ("map", "No_Map_symbol"), ("map", "quest_map_icon_round_style"), ("map", "Shop_map_icon__weavehome"), ("map", "gramaphone"), ("quest", "quest_dot_full"), ("quest", "quest_dot_empty"), ("quest", "Kill_quest_icon"), ("quest", "goop_quest_icon"), ("quest", "hunters_nest_quest_icon"), ("quest", "Steel_Servant_Quest_marker"), ("quest", "Mr_Mushroom_quest_notch"), ("quest", "quest_map_icon_round_style"), ("station", "pin_stag_station_shop_icon"), ("station", "pin_tube_station_shop_icon"), ("station", "pin_stag_station"), ("station", "pin_tube_station"), ("bench", "Bench_item_prompt"), ("bench", "pin_bench_shop_icon"), ("bench", "pin_bench"), ("bench", "pin_bench_bell"), ("bench", "town_bench_lit"), ("bell", "Hornet_icon_bell_clapper"), ("bell", "Bell_Hub_Icons0001"), ("bell", "Bell_Hub_Icons0006"), ("bell", "Hornet_bellway_token"), ("bell", "Hornet_bellway_token_duo"), ("bell", "QI_Main_bell_beast"), ("bell", "QI_Main_bellshrines"), ("bell", "bell_shrine_single_silk"), ("bell", "crawbell"), ("bell", "Music_box_bell0000"), ("bell", "bell_sub_sign"), ("shrine", "QI_Main_bellshrines"), ("shrine", "quest_map_icon_songshrines"), ("shrine", "Bellshrine"), ("shrine", "Belltown_Shrine"), ("shrine", "bell_shrine_single_silk"), ("lock", "UI_tool_slot_locked_fill"), ("lock", "Tool_slot_lock_ring"), ("lock", "trap_door_circle"), ("lock", "trapdoor_lever"), ("lock", "music_box_bell_lock0000"), ("silk", "silk_heart_inv_icon"), ("silk", "icon_silk_materium"), ("silk", "silk_heart_scene"), ("silk", "spell_core_slim_silk_heart_ss"), ("silk", "Silk_Grub_large_cocoon0000"), ("silk", "Silk_Grub_small_cocoon"), ("silk", "Toll_machine_silk_ration"), ("silk", "silk_bomb_prompt"), ("silk", "UI_halo_silk0000"), ("shell", "Shell_shard_icon"), ("shell", "I_shell_shard_icon_large"), ("shell", "Icon_Beast_Shard"), ("shell", "T_shell_satchel"), ("shell", "T_sting_shard"), ("shell", "tiny_tool_icon_sting_shard"), ("shell", "HUD_shard_shop"), ("shell", "glass_shards"), ("spool", "Hornet_Spool_Upgrade_Shop_Icon"), ("spool", "Hornet_Spool_Upgrade_Shop_Icon_full"), ("spool", "Hornet_Spool_Upgrade_Shop_Icon_Heart"), ("spool", "Inv_spool_backboard_ss"), ("spool", "T_focus_spool"), ("spool", "T_spool_bar_extender"), ("spool", "spool_upgrade_pickup"), ("spool", "Thread_Spool_spinner0000"), ("crest", "C_crest"), ("crest", "M_crest"), ("crest", "Tools_UI_Crest_Change"), ("crest", "crest_blank"), ("crest", "cursed_crest_animated0001"), ("crest", "Bell_Hub_Crest_Icon_Animated0000"), ("crest", "Crest_prompt"), ("mask", "Hornet_T_fractured_mask"), ("mask", "bestiary_icon_frame_mask"), ("mask", "dreamer_mask_prompt"), ("mask", "soft_masker"), ("mask", "sand_blown_mask"), ("mask", "Goomba_mask_chunk_01"), ("heart", "Heart_Piece_01"), ("heart", "Heart_Piece_02"), ("heart", "Heart_Piece_03"), ("heart", "silk_heart_inv_icon"), ("heart", "bone_heart_egg"), ("heart", "cog_heart_pieces"), ("heart", "heart_prompt_clover"), ("heart", "heart_prompt_flower"), ("heart", "heart_prompt_coral"), ("heart", "coral_king_heart_icon0000"), ("key", "dock_key"), ("key", "I_key_architect"), ("key", "I_key_whiteward"), ("key", "I_chute_key_whiteward"), ("key", "I_slab_key"), ("key", "I_slab_key_brass"), ("key", "I_slab_key_gold"), ("key", "I_slab_key_old"), ("key", "belltown_house_key"), ("key", "rusted_cage_key"), ("memory", "soul_orb"), ("memory", "soul_orb_generic"), ("memory", "black_soul_orb"), ("memory", "new_item_orb"), ("memory", "sc_grey_orb_single"), ("memory", "memory_large_flat"), ("memory", "memory_large_flat_outer"), ("memory", "red_memory_bottle"), ("memory", "UI_halo_orb_beams") }; private bool _pickerActive; private int _pickerIndex; private readonly List<string> _pickedNames = new List<string>(); private bool _annotateActive; private int _annotateIndex; private string _noteText = ""; private readonly List<(string name, string note)> _annotated = new List<(string, string)>(); private List<string> _annotateList = new List<string>(); private bool _isDumpingSprites; private bool _isDumpingTransitions; private static readonly string[] DumpSkipSubstrings = new string[9] { "Travel", "Caravan", "Diving_Bell", "Menu", "Boot", "Preloader", "Intro", "Cutscene", "Credits" }; private static readonly string[] SpecialNameKeywords = new string[8] { "silk spool", "heart piece", "mossberry", "aspid berry", "berry", "spool", "moss", "mask piece" }; private bool _isScanningSpecial; private static readonly string[] AspidBerryBoolNames = new string[3] { "mosstownAspidBerryCollected", "bonegraveAspidBerryCollected", "bonetownAspidBerryCollected" }; public static bool IsScanningChecks { get; private set; } private void Update() { SilksongItemRandomizerAPI.FlushLimitsRegenerate(); if (_pickerActive) { if (Input.GetKeyDown((KeyCode)13)) { PickCurrent(pick: true); } else if (Input.GetKeyDown((KeyCode)120)) { PickCurrent(pick: false); } } if (_annotateActive && Input.GetKeyDown((KeyCode)13)) { SaveCurrentNote(); } if (Input.GetKeyDown((KeyCode)287)) { WarpToLastBench(); } if (Input.GetKeyDown((KeyCode)289)) { ToggleRecentItemsUI(); } if (Input.GetKeyDown((KeyCode)27)) { Plugin.Instance?.RefreshBenchwarpUI(); } } private void StartFleaPicker() { if (!_isDumpingSprites) { ((MonoBehaviour)this).StartCoroutine(LoadAtlasesThenStartFleaPicker()); } } private void StartMapSpritePicker() { if (!_isDumpingSprites) { ((MonoBehaviour)this).StartCoroutine(LoadAtlasesThenStartMapPicker()); } } private void TestGrantDirectionPermissions() { try { DirectionPermissionReward directionPermissionReward = new DirectionPermissionReward(Locale.Get("上劈权限"), "upward", allowRight: false, allowLeft: false, isAttack: true); DirectionPermissionReward directionPermissionReward2 = new DirectionPermissionReward(Locale.Get("左劈权限"), "left", allowRight: false, allowLeft: false, isAttack: true); DirectionPermissionReward directionPermissionReward3 = new DirectionPermissionReward(Locale.Get("右劈权限"), "right", allowRight: false, allowLeft: false, isAttack: true); directionPermissionReward.Give(); RecentItemsUI.AddItem(directionPermissionReward); directionPermissionReward2.Give(); RecentItemsUI.AddItem(directionPermissionReward2); directionPermissionReward3.Give(); RecentItemsUI.AddItem(directionPermissionReward3); Plugin.ShowNotification("已发放 上/左/右劈 方向权限(验证持久化+弹窗+图标)", 4f); } catch (Exception arg) { Plugin.Log.LogError((object)$"[F4方向测试] 发放失败: {arg}"); } } private IEnumerator LoadAtlasesThenStartMapPicker() { if (_isDumpingSprites) { yield break; } _isDumpingSprites = true; string[] pendingKeys = new string[1] { "inv_nail" }; List<string> addrKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk)) { addrKeys.Add(sk); } } } } catch { } HashSet<string> atlasKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string k in addrKeys) { if (!IsLikelyAtlasKey(k)) { continue; } string[] array = pendingKeys; foreach (string kw in array) { if (k.IndexOf(kw, StringComparison.OrdinalIgnoreCase) >= 0) { atlasKeys.Add(k); break; } } } int loadedOk = 0; int loadedFail = 0; foreach (string k2 in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k2); } catch { loadedFail++; continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { loadedOk++; continue; } loadedFail++; try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); _currentCandidates.Clear(); Sprite[] allSprites = Resources.FindObjectsOfTypeAll<Sprite>(); Sprite[] array2 = allSprites; foreach (Sprite sp in array2) { if ((Object)(object)sp == (Object)null || string.IsNullOrEmpty(((Object)sp).name)) { continue; } string[] array3 = pendingKeys; foreach (string kw2 in array3) { if (((Object)sp).name.IndexOf(kw2, StringComparison.OrdinalIgnoreCase) >= 0) { _currentCandidates.Add(("map", ((Object)sp).name)); break; } } } if (_currentCandidates.Count == 0) { Plugin.Log.LogInfo((object)"[F4] 未找到剩余地图名的贴图。"); _isDumpingSprites = false; yield break; } _pickerActive = true; _pickerIndex = 0; _pickedNames.Clear(); Plugin.Log.LogInfo((object)$"[F4] 找到 {_currentCandidates.Count} 个剩余地图图标,开始筛选。"); _isDumpingSprites = false; } private void StartSwimIconPicker() { if (!_isDumpingSprites) { ((MonoBehaviour)this).StartCoroutine(LoadAtlasesThenStartSwimIconPicker()); } } private IEnumerator LoadAtlasesThenStartSwimIconPicker() { if (_isDumpingSprites) { yield break; } _isDumpingSprites = true; string[] pendingKeys = new string[5] { "clawline", "harpoon dash", "harpoondash", "harpoon", "dash" }; List<string> addrKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk)) { addrKeys.Add(sk); } } } } catch { } HashSet<string> atlasKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string k in addrKeys) { if (!IsLikelyAtlasKey(k)) { continue; } string[] array = pendingKeys; foreach (string kw in array) { if (k.IndexOf(kw, StringComparison.OrdinalIgnoreCase) >= 0) { atlasKeys.Add(k); break; } } } int loadedOk = 0; int loadedFail = 0; foreach (string k2 in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k2); } catch { loadedFail++; continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { loadedOk++; continue; } loadedFail++; try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); _currentCandidates.Clear(); Sprite[] allSprites = Resources.FindObjectsOfTypeAll<Sprite>(); Sprite[] array2 = allSprites; foreach (Sprite sp in array2) { if ((Object)(object)sp == (Object)null || string.IsNullOrEmpty(((Object)sp).name)) { continue; } string[] array3 = pendingKeys; foreach (string kw2 in array3) { if (((Object)sp).name.IndexOf(kw2, StringComparison.OrdinalIgnoreCase) >= 0) { _currentCandidates.Add(("swimicon", ((Object)sp).name)); break; } } } foreach (var c in _currentCandidates) { Plugin.Log.LogInfo((object)("[F4泳图标] " + c.name)); } if (_currentCandidates.Count == 0) { Plugin.Log.LogInfo((object)"[F4泳图标] 未找到关键词图标。"); _isDumpingSprites = false; yield break; } _pickerActive = true; _pickerIndex = 0; _pickedNames.Clear(); Plugin.Log.LogInfo((object)$"[F4泳图标] 找到 {_currentCandidates.Count} 个图标,开始筛选。"); _isDumpingSprites = false; } private void TestGlowPopupCycle() { try { var (text, text2) = F4GlowPopupItems[_f4PopupIndex++ % F4GlowPopupItems.Length]; Plugin.Log.LogInfo((object)("[F4发光弹窗] " + text + ":" + text2)); if (1 == 0) { } bool flag = text switch { "heart" => HeartMsgHelper.Show(text2), "melody" => MelodyMsgHelper.Show(text2), "hcombo" => OfficialMsgHelper.ShowHunterCombo(int.Parse(text2), (Action)null), _ => false, }; if (1 == 0) { } if (!flag) { Plugin.Log.LogWarning((object)("[F4发光弹窗] " + text + " " + text2 + " 弹出失败")); } ((MonoBehaviour)this).StartCoroutine(DumpGlowIconDelayed(text, text2)); } catch (Exception arg) { Plugin.Log.LogError((object)$"[F4发光弹窗] 异常: {arg}"); } } private IEnumerator DumpGlowIconDelayed(string kind, string evt) { for (int f = 0; f < 6; f++) { yield return null; } try { List<GameObject> clones = (from g in Object.FindObjectsOfType<GameObject>() where Object.op_Implicit((Object)(object)g) && ((Object)g).name.StartsWith("UI Msg Get Item", StringComparison.OrdinalIgnoreCase) select g).ToList(); Plugin.Log.LogInfo((object)$"[F4发光弹窗] {kind}:{evt}: 找到 {clones.Count} 个克隆体"); foreach (GameObject go in clones) { Transform iconT = go.transform.Find("Icon"); Transform glowT = go.transform.Find("Icon Glow"); SpriteRenderer sr = (Object.op_Implicit((Object)(object)iconT) ? ((Component)iconT).GetComponentInChildren<SpriteRenderer>(true) : null); SpriteRenderer srGlow = (Object.op_Implicit((Object)(object)glowT) ? ((Component)glowT).GetComponentInChildren<SpriteRenderer>(true) : null); ManualLogSource log = Plugin.Log; string[] obj = new string[12] { "[F4发光弹窗] ", kind, ":", evt, ": Icon='", null, null, null, null, null, null, null }; obj[5] = ((iconT != null) ? ((Object)iconT).name : null) ?? "NULL"; obj[6] = "' sprite="; obj[7] = ((Object.op_Implicit((Object)(object)sr) && Object.op_Implicit((Object)(object)sr.sprite)) ? ((Object)sr.sprite).name : "NULL"); obj[8] = " | Glow='"; obj[9] = ((glowT != null) ? ((Object)glowT).name : null) ?? "NULL"; obj[10] = "' sprite="; obj[11] = ((Object.op_Implicit((Object)(object)srGlow) && Object.op_Implicit((Object)(object)srGlow.sprite)) ? ((Object)srGlow.sprite).name : "NULL"); log.LogInfo((object)string.Concat(obj)); } } catch (Exception ex) { Exception ex2 = ex; Plugin.Log.LogError((object)("[F4发光弹窗] 反查图标异常: " + ex2.Message)); } } private void TestTriggerChapelDoorClose() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; Plugin.Log.LogInfo((object)("[教堂关门测试] 场景: " + name)); GameObject val = null; GameObject val2 = null; GameObject val3 = null; GameObject val4 = null; List<string> list = new List<string>(); PlayMakerFSM val5 = null; activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); foreach (GameObject val6 in rootGameObjects) { Transform[] componentsInChildren = val6.GetComponentsInChildren<Transform>(true); foreach (Transform val7 in componentsInChildren) { string name2 = ((Object)val7).name; if (name2.IndexOf("Door", StringComparison.OrdinalIgnoreCase) >= 0 || name2.IndexOf("door", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(name2); } if (name2 == "Door DoClose" && (Object)(object)val == (Object)null) { val = ((Component)val7).gameObject; } else if (name2 == "Door Closed" && (Object)(object)val2 == (Object)null) { val2 = ((Component)val7).gameObject; } else if (name2 == "Door Art" && (Object)(object)val4 == (Object)null) { val4 = ((Component)val7).gameObject; } } PlayMakerFSM[] componentsInChildren2 = val6.GetComponentsInChildren<PlayMakerFSM>(true); foreach (PlayMakerFSM val8 in componentsInChildren2) { if ((Object)(object)val5 == (Object)null && val8.FsmName == "chapel_door_control") { val5 = val8; } } } Plugin.Log.LogInfo((object)("[教堂关门测试] chapel_door_control FSM: " + (((Object)(object)val5 != (Object)null) ? ((Object)((Component)val5).gameObject).name : "未找到"))); Plugin.Log.LogInfo((object)("[教堂关门测试] Door DoClose: " + (((Object)(object)val != (Object)null) ? ((Object)val).name : "未找到") + " | Door Closed: " + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "未找到") + " | Door Art: " + (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "未找到"))); Plugin.Log.LogInfo((object)("[教堂关门测试] 场景内 door 相关对象: " + string.Join(", ", list.Distinct<string>(StringComparer.OrdinalIgnoreCase)))); if ((Object)(object)val5 == (Object)null) { Plugin.Log.LogWarning((object)"[教堂关门测试] 无 chapel_door_control FSM,退出"); return; } Plugin.Log.LogInfo((object)("[教堂关门测试] FSM 当前状态: " + val5.Fsm.ActiveStateName)); try { FsmVariables variables = val5.Fsm.Variables; FsmEnum fsmEnum = variables.GetFsmEnum("Crest Type"); FsmObject fsmObject = variables.GetFsmObject("Crest Object"); FsmString fsmString = variables.GetFsmString("Closed PD Bool"); ManualLogSource log = Plugin.Log; Enum arg = ((fsmEnum != null) ? fsmEnum.Value : null); object obj; if (fsmObject == null) { obj = null; } else { Object value = fsmObject.Value; obj = ((value != null) ? value.name : null); } if (obj == null) { obj = "空"; } log.LogInfo((object)string.Format("[教堂关门测试] Crest Type: {0} | Crest Object: {1} | Closed PD Bool: {2}", arg, obj, ((fsmString != null) ? fsmString.Value : null) ?? "空")); PlayerData instance = PlayerData.instance; if (instance != null) { Plugin.Log.LogInfo((object)$"[教堂关门测试] chapelClosed: reaper={instance.chapelClosed_reaper} wanderer={instance.chapelClosed_wanderer} beast={instance.chapelClosed_beast} witch={instance.chapelClosed_witch} toolmaster={instance.chapelClosed_toolmaster} shaman={instance.chapelClosed_shaman}"); } try { Plugin.Log.LogInfo((object)("[教堂关门测试] 平替标记: " + string.Join(", ", Plugin.SaveData.ChapelRandomizedCrests))); } catch { } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[教堂关门测试] 诊断输出异常: " + ex.Message)); } val5.Fsm.SetState("Do Close"); Plugin.Log.LogInfo((object)"[教堂关门测试] 已 SetState(\"Do Close\"),观察关门动画是否播放"); } catch (Exception arg2) { Plugin.Log.LogError((object)$"[教堂关门测试] 异常: {arg2}"); } } private void TestGiveRandomCrest() { try { List<ToolCrest> allCrests = ToolItemManager.GetAllCrests(); if (allCrests == null || allCrests.Count == 0) { Plugin.Log.LogError((object)"[F4纹章] ToolItemManager 无纹章清单"); return; } ToolCrest val = null; foreach (ToolCrest item in allCrests) { if ((Object)(object)item != (Object)null && !item.IsUnlocked) { val = item; break; } } if ((Object)(object)val == (Object)null) { val = allCrests[Random.Range(0, allCrests.Count)]; } if (!((Object)(object)val == (Object)null)) { Plugin.Log.LogInfo((object)("[F4纹章] 随机发放纹章: " + val.name)); SavedItemReward savedItemReward = new SavedItemReward((SavedItem)(object)val); savedItemReward.Give(); ItemRandomizer.AddGivenCount(savedItemReward.Id); ItemRandomizer.RecordMapping("test:F4crest", "reward:" + savedItemReward.Id); RecentItemsUI.AddItem(savedItemReward); } } catch (Exception arg) { Plugin.Log.LogError((object)$"[F4纹章] 异常: {arg}"); } } private static void LoadSlotDependencyBundles() { if (_slotDepsLoaded) { return; } _slotDepsLoaded = true; try { string text = Path.Combine(Application.streamingAssetsPath, "aa", "StandaloneWindows64"); if (!Directory.Exists(text)) { Plugin.Log.LogWarning((object)("[F4额外槽] Addressables 目录不存在: " + text)); return; } int num = 0; int num2 = 0; int num3 = 0; string[] files = Directory.GetFiles(text, "*.bundle"); foreach (string text2 in files) { try { AssetBundle val = AssetBundle.LoadFromFile(text2); if ((Object)(object)val == (Object)null) { num2++; } else if (val.isStreamedSceneAssetBundle) { val.Unload(false); num3++; } else { num++; } } catch { num2++; } } Plugin.Log.LogInfo((object)$"[F4额外槽] 依赖 bundle 全量加载: 成功{num} 场景跳过{num3} 失败{num2}"); } catch (Exception ex) { Plugin.Log.LogError((object)("[F4额外槽] 依赖 bundle 加载异常: " + ex.Message)); } } private void TestGiveExtraSlot() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) try { PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"[F4额外槽] PlayerData 不可用"); return; } int num = _extraSlotTestIndex % 2; _extraSlotTestIndex++; string text = ((num == 0) ? "UnlockedExtraYellowSlot" : "UnlockedExtraBlueSlot"); ManualLogSource log = Plugin.Log; object arg = _extraSlotTestIndex - 1; Scene activeScene = SceneManager.GetActiveScene(); log.LogInfo((object)$"[F4额外槽] 触发: slot#{arg} field={text} scene={((Scene)(ref activeScene)).name}"); FieldInfo field = typeof(PlayerData).GetField(text, BindingFlags.Instance | BindingFlags.Public); if (field == null || field.FieldType != typeof(bool)) { Plugin.Log.LogError((object)("[F4额外槽] 字段不存在: " + text)); return; } field.SetValue(instance, true); Plugin.Log.LogInfo((object)("[F4额外槽] 物品给予: " + text + " = true")); ToolItemType slotType = (ToolItemType)((num != 0) ? 1 : 2); ((MonoBehaviour)this).StartCoroutine(SpawnFullScreenSlotMsg(slotType)); } catch (Exception arg2) { Plugin.Log.LogError((object)$"[F4额外槽] 异常: {arg2}"); } } private IEnumerator SpawnFullScreenSlotMsg(ToolItemType slotType) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) GameObject evolvePrefab = ChainFixer.LoadPrefabFixed("prompts_assets_all.bundle", "Assets/Prefabs/UI/Messages/UI Msg Crest Evolve.prefab", "F4额外槽evolve"); if ((Object)(object)evolvePrefab == (Object)null) { string socketName = (((int)slotType == 2) ? "Socket 0" : "Socket 1"); Plugin.ShowNotification("解锁 " + socketName + "!"); yield break; } GameObject evo = Object.Instantiate<GameObject>(evolvePrefab); evo.SetActive(false); evo.transform.position = new Vector3(0f, 0f, 0f); PlayMakerFSM fsmComp = ((IEnumerable<PlayMakerFSM>)evo.GetComponentsInChildren<PlayMakerFSM>(true)).FirstOrDefault((Func<PlayMakerFSM, bool>)((PlayMakerFSM f) => f.FsmName == "Msg Control")); if ((Object)(object)fsmComp != (Object)null) { FsmString itemVar = fsmComp.FsmVariables.GetFsmString("Item"); if (itemVar != null) { string branch = (itemVar.Value = (((int)slotType == 2) ? "Socket 0" : "Socket 1")); Plugin.Log.LogInfo((object)("[F4额外槽] FSM '" + fsmComp.FsmName + "' 设 Item='" + branch + "',激活后 Init→StringSwitch→" + (((int)slotType == 2) ? "SOCKET 1" : "SOCKET 2") + " 分支")); } else { Plugin.Log.LogWarning((object)"[F4额外槽] FSM 无 Item 字符串变量"); } } else { Plugin.Log.LogWarning((object)"[F4额外槽] 未找到 Msg Control FSM"); } Plugin.Log.LogInfo((object)"[F4额外槽] 激活 evolve prefab,Msg Control FSM startState=Init 自动演出"); evo.SetActive(true); ((MonoBehaviour)this).StartCoroutine(DiagnoseBg(evo)); ((MonoBehaviour)this).StartCoroutine(HideEvolveVisualLater(evo, fsmComp)); } private IEnumerator DiagnoseBg(GameObject evo) { yield return (object)new WaitForSeconds(0.5f); if ((Object)(object)evo == (Object)null) { yield break; } Transform bg = evo.transform.Find("BG"); if ((Object)(object)bg == (Object)null) { Plugin.Log.LogWarning((object)"[F4额外槽] 未找到 BG 子物体"); yield break; } SpriteRenderer sr = ((Component)bg).GetComponent<SpriteRenderer>(); Animator anim = ((Component)bg).GetComponent<Animator>(); PlayMakerFSM fsm = ((Component)bg).GetComponent<PlayMakerFSM>(); ManualLogSource log = Plugin.Log; object[] obj = new object[5] { bg.position, ((Component)bg).gameObject.activeSelf, null, null, null }; object obj2; if (!((Object)(object)sr != (Object)null)) { obj2 = "NULL"; } else { object[] array = new object[5]; Sprite sprite = sr.sprite; array[0] = ((sprite != null) ? ((Object)sprite).name : null); array[1] = ((Renderer)sr).enabled; array[2] = sr.color; array[3] = ((Renderer)sr).sortingLayerName; array[4] = ((Renderer)sr).sortingOrder; obj2 = string.Format("sprite={0} enabled={1} color={2} sortingL={3} order={4}", array); } obj[2] = obj2; object obj3; if (!((Object)(object)anim != (Object)null)) { obj3 = "NULL"; } else { RuntimeAnimatorController runtimeAnimatorController = anim.runtimeAnimatorController; obj3 = $"ctrl={((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null)} enabled={((Behaviour)anim).enabled}"; } obj[3] = obj3; obj[4] = (((Object)(object)fsm != (Object)null) ? (fsm.FsmName + "/" + fsm.ActiveStateName) : "NULL"); log.LogInfo((object)string.Format("[F4额外槽] BG pos={0} active={1} sr={2} anim={3} fsm={4}", obj)); Component[] components = ((Component)bg).GetComponents<Component>(); foreach (Component c in components) { Plugin.Log.LogInfo((object)("[F4额外槽] BG 组件: " + ((object)c).GetType().Name)); } } private IEnumerator HideEvolveVisualLater(GameObject evo, PlayMakerFSM controlFsm) { yield return (object)new WaitForSeconds(7.5f); if ((Object)(object)evo == (Object)null) { yield break; } Plugin.Log.LogInfo((object)"[F4额外槽] 演出超时,发 PRESS 让 FSM 走完还原流程 (Detect→Down→Done)"); if ((Object)(object)controlFsm != (Object)null) { try { controlFsm.SendEvent("PRESS"); Plugin.Log.LogInfo((object)("[F4额外槽] 已发 PRESS,当前状态: " + controlFsm.Fsm.ActiveStateName)); } catch (Exception ex) { Exception ex2 = ex; Plugin.Log.LogWarning((object)("[F4额外槽] 发 PRESS 异常: " + ex2.Message)); } } float t = 0f; while (t < 3f && (Object)(object)evo != (Object)null) { t += Time.deltaTime; if ((Object)(object)controlFsm != (Object)null && controlFsm.Fsm.ActiveStateName == "Done") { Plugin.Log.LogInfo((object)"[F4额外槽] FSM 已到 Done(还原完成)"); break; } yield return null; } RestoreMsgInputState(); if ((Object)(object)evo != (Object)null) { evo.SetActive(false); Object.Destroy((Object)(object)evo); Plugin.Log.LogInfo((object)"[F4额外槽] evolve 视觉已回收"); } } private static void RestoreMsgInputState() { try { UIMsgProxy[] array = Object.FindObjectsOfType<UIMsgProxy>(true); UIMsgProxy[] array2 = array; foreach (UIMsgProxy val in array2) { val.SetIsInMsg(false); Plugin.Log.LogInfo((object)("[F4额外槽] 兜底还原 UIMsgProxy '" + ((Object)val).name + "' SetIsInMsg(false)")); } if (array.Length == 0) { Plugin.Log.LogInfo((object)"[F4额外槽] 未找到 UIMsgProxy,跳过兜底还原"); } try { PlayerData instance = PlayerData.instance; bool isInputBlocked = InventoryPaneInput.IsInputBlocked; bool isPickupPaused = CollectableItemPickup.IsPickupPaused; Plugin.Log.LogInfo((object)$"[F4额外槽] 还原后状态: disablePause={instance.disablePause} IsInputBlocked={isInputBlocked} IsPickupPaused={isPickupPaused}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[F4额外槽] 还原后状态读取异常: " + ex.Message)); } try { if (PlayerData.instance != null && PlayerData.instance.disablePause) { PlayerData.instance.disablePause = false; Plugin.Log.LogInfo((object)"[F4额外槽] 强制还原 disablePause=false(FSM 未走完 SetIsInMsg 还原链)"); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[F4额外槽] 强制还原 disablePause 异常: " + ex2.Message)); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[F4额外槽] 兜底还原异常: " + ex3.Message)); } } private IEnumerator TraceSlotFsm(GameObject go, PlayMakerFSM controlFsm) { if ((Object)(object)go == (Object)null) { yield break; } string outPath = Path.Combine(Paths.PluginPath, $"crest_evolve_trace_{DateTime.Now:HHmmssfff}.txt"); DumpGameObjectStructure(go, outPath); Transform icon = ((IEnumerable<Transform>)go.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "Icon")); Transform obj = go.transform.Find("Tool_Socket_Evolve_lvl1"); Animator targetAnim = ((obj != null) ? ((Component)obj).GetComponent<Animator>() : null); string lastState = null; for (int frame = 1; frame <= 90; frame++) { yield return null; if ((Object)(object)go == (Object)null) { Plugin.Log.LogInfo((object)"[F4额外槽] 弹窗已销毁"); break; } string state = (((Object)(object)controlFsm != (Object)null) ? (controlFsm.Fsm.ActiveStateName ?? "none") : "noCtrl"); string iconActive = (((Object)(object)icon != (Object)null) ? ((Component)icon).gameObject.activeInHierarchy.ToString() : "noIcon"); string animInfo = "noLvl1Anim"; if ((Object)(object)targetAnim != (Object)null) { AnimatorStateInfo st = targetAnim.GetCurrentAnimatorStateInfo(0); string iconSprite = "noIcon"; if ((Object)(object)icon != (Object)null) { SpriteRenderer sr = ((Component)icon).GetComponent<SpriteRenderer>(); iconSprite = (((Object)(object)sr == (Object)null) ? "noSR" : (((Object)(object)sr.sprite != (Object)null) ? ((Object)sr.sprite).name : "nullSprite")); } animInfo = $"animOn={((Behaviour)targetAnim).isActiveAndEnabled} normTime={((AnimatorStateInfo)(ref st)).normalizedTime:F2} stateHash={((AnimatorStateInfo)(ref st)).fullPathHash} clip={targetAnim.GetCurrentAnimatorClipInfo(0).Length} icon={iconSprite}"; } string line = "state=" + state + " icon=" + iconActive + " | " + animInfo; if (state != lastState || frame <= 3 || frame % 10 == 0) { Plugin.Log.LogInfo((object)$"[F4额外槽] 帧{frame}: {line}"); lastState = state; } if (state == "Done" || state == "Finished" || state == "Stop") { break; } } } private void TestDirectionSplitStep() { (string, bool)[] array = new(string, bool)[8] { ("hasDash", true), ("hasDash", false), ("hasHarpoonDash", true), ("hasHarpoonDash", false), ("hasBrolly", true), ("hasBrolly", false), ("hasWalljump", true), ("hasWalljump", false) }; int splitTestIndex = _splitTestIndex; _splitTestIndex = (_splitTestIndex + 1) % (array.Length + 1); if (splitTestIndex < array.Length) { (string, bool) tuple = array[splitTestIndex]; Plugin.Log.LogInfo((object)("[分裂弹窗测试] 弹出 " + tuple.Item1 + " " + (tuple.Item2 ? "LEFT" : "RIGHT"))); DirectionPopupHelper.ShowDirectionSplit(tuple.Item1, tuple.Item2, (Action)null); } else { Plugin.Log.LogInfo((object)"[分裂弹窗测试] 弹出 回血"); Sprite val = SpriteCache.Find("prompt_silkheart"); UiMsgCustomBannerHelper.Show("Brolly", val, "Vincular", "缚丝", "enable heal", false); } } private void DumpGameObjectStructure(GameObject root, string outputPath) { //IL_0086: 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) if ((Object)(object)root == (Object)null) { return; } try { using (StreamWriter streamWriter = new StreamWriter(outputPath, append: false, Encoding.UTF8)) { streamWriter.WriteLine("=== GameObject 结构导出: " + ((Object)root).name + " ==="); streamWriter.WriteLine($"时间: {DateTime.Now:HH:mm:ss.fff}"); streamWriter.WriteLine($"Active Self: {root.activeSelf} Active In Hierarchy: {root.activeInHierarchy}"); Scene scene = root.scene; streamWriter.WriteLine("场景: " + ((Scene)(ref scene)).name); streamWriter.WriteLine("层: " + LayerMask.LayerToName(root.layer)); streamWriter.WriteLine(); DumpTransformRecursive(root.transform, streamWriter, 0); } Plugin.Log.LogInfo((object)("[结构导出] 已保存到: " + outputPath)); } catch (Exception arg) { Plugin.Log.LogError((object)$"[结构导出] 失败: {arg}"); } } private void DumpTransformRecursive(Transform t, StreamWriter writer, int depth) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown string text = new string(' ', depth * 2); writer.WriteLine($"{text}[{depth}] ─ {((Object)t).name}"); writer.WriteLine($"{text} Position: {t.localPosition} Rotation: {t.localEulerAngles} Scale: {t.localScale}"); writer.WriteLine($"{text} Active Self: {((Component)t).gameObject.activeSelf} Active In Hierarchy: {((Component)t).gameObject.activeInHierarchy}"); writer.WriteLine(text + " Tag: " + ((Component)t).tag + " Layer: " + LayerMask.LayerToName(((Component)t).gameObject.layer)); Component[] components = ((Component)t).GetComponents<Component>(); writer.WriteLine($"{text} Components ({components.Length}):"); Component[] array = components; foreach (Component val in array) { if ((Object)(object)val == (Object)null) { writer.WriteLine(text + " - (missing)"); continue; } string fullName = ((object)val).GetType().FullName; writer.WriteLine(text + " - " + fullName); DumpComponentDetail(val, writer, text + " "); } foreach (Transform item in t) { Transform t2 = item; DumpTransformRecursive(t2, writer, depth + 1); } } private void DumpComponentDetail(Component comp, StreamWriter writer, string indent) { //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06cb: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) try { Animator val = (Animator)(object)((comp is Animator) ? comp : null); if (val != null) { writer.WriteLine(indent + "Animator:"); writer.WriteLine(indent + " Controller: " + (((Object)(object)val.runtimeAnimatorController != (Object)null) ? ((Object)val.runtimeAnimatorController).name : "NULL")); writer.WriteLine(indent + " Avatar: " + (((Object)(object)val.avatar != (Object)null) ? ((Object)val.avatar).name : "NULL")); writer.WriteLine($"{indent} Root Motion: {val.applyRootMotion}"); writer.WriteLine($"{indent} Update Mode: {val.updateMode}"); writer.WriteLine($"{indent} Enabled: {((Behaviour)val).enabled}"); if ((Object)(object)val.runtimeAnimatorController != (Object)null) { int layerCount = val.layerCount; writer.WriteLine($"{indent} Layers: {layerCount}"); for (int i = 0; i < layerCount; i++) { writer.WriteLine($"{indent} Layer[{i}]: {val.GetLayerName(i)} weight={val.GetLayerWeight(i)}"); } AnimatorControllerParameter[] parameters = val.parameters; writer.WriteLine($"{indent} Parameters: {parameters.Length}"); AnimatorControllerParameter[] array = parameters; foreach (AnimatorControllerParameter val2 in array) { writer.WriteLine($"{indent} {val2.name} ({val2.type}) = {GetAnimatorParamValue(val, val2)}"); } } return; } SpriteRenderer val3 = (SpriteRenderer)(object)((comp is SpriteRenderer) ? comp : null); if (val3 != null) { writer.WriteLine(indent + "SpriteRenderer:"); writer.WriteLine(indent + " Sprite: " + (((Object)(object)val3.sprite != (Object)null) ? ((Object)val3.sprite).name : "NULL")); writer.WriteLine($"{indent} Color: {val3.color}"); writer.WriteLine(indent + " Material: " + (((Object)(object)((Renderer)val3).sharedMaterial != (Object)null) ? ((Object)((Renderer)val3).sharedMaterial).name : "NULL")); writer.WriteLine($"{indent} Sorting Layer: {((Renderer)val3).sortingLayerName} Order: {((Renderer)val3).sortingOrder}"); writer.WriteLine($"{indent} Flip X: {val3.flipX} Flip Y: {val3.flipY}"); return; } PlayMakerFSM val4 = (PlayMakerFSM)(object)((comp is PlayMakerFSM) ? comp : null); if (val4 != null) { writer.WriteLine(indent + "PlayMakerFSM:"); writer.WriteLine(indent + " FSM Name: " + val4.FsmName); writer.WriteLine(indent + " Active State: " + val4.ActiveStateName); writer.WriteLine(indent + " Start State: " + ((val4.Fsm != null) ? val4.Fsm.StartState : "NULL")); writer.WriteLine($"{indent} Enabled: {((Behaviour)val4).enabled}"); writer.WriteLine(indent + " Variables:"); if (val4.Fsm == null || val4.Fsm.Variables == null) { return; } FsmVariables variables = val4.Fsm.Variables; FieldInfo[] fields = ((object)variables).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType.Name.StartsWith("Fsm")) { object value = fieldInfo.GetValue(variables); if (value != null) { string fsmVariableValue = GetFsmVariableValue(value); writer.WriteLine(indent + " " + fieldInfo.Name + " (" + fieldInfo.FieldType.Name + ") = " + fsmVariableValue); } } } return; } Canvas val5 = (Canvas)(object)((comp is Canvas) ? comp : null); if (val5 != null) { writer.WriteLine(indent + "Canvas:"); writer.WriteLine($"{indent} Render Mode: {val5.renderMode}"); writer.WriteLine(indent + " World Camera: " + (((Object)(object)val5.worldCamera != (Object)null) ? ((Object)val5.worldCamera).name : "NULL")); writer.WriteLine($"{indent} Pixel Perfect: {val5.pixelPerfect}"); writer.WriteLine($"{indent} Sort Order: {val5.sortingOrder}"); writer.WriteLine($"{indent} Scale Factor: {val5.scaleFactor}"); return; } AudioSource val6 = (AudioSource)(object)((comp is AudioSource) ? comp : null); if (val6 != null) { writer.WriteLine(indent + "AudioSource:"); writer.WriteLine(indent + " Clip: " + (((Object)(object)val6.clip != (Object)null) ? ((Object)val6.clip).name : "NULL")); writer.WriteLine($"{indent} Loop: {val6.loop} Mute: {val6.mute}"); writer.WriteLine($"{indent} Volume: {val6.volume} Pitch: {val6.pitch}"); return; } ParticleSystem val7 = (ParticleSystem)(object)((comp is ParticleSystem) ? comp : null); if (val7 != null) { writer.WriteLine(indent + "ParticleSystem:"); writer.WriteLine($"{indent} Enabled: {val7.isPlaying}"); MainModule main = val7.main; MinMaxCurve val8 = ((MainModule)(ref main)).startLifetime; object arg = ((MinMaxCurve)(ref val8)).constant; main = val7.main; val8 = ((MainModule)(ref main)).startSpeed; writer.WriteLine($"{indent} Main: startLifetime={arg} startSpeed={((MinMaxCurve)(ref val8)).constant}"); EmissionModule emission = val7.emission; val8 = ((EmissionModule)(ref emission)).rateOverTime; object arg2 = ((MinMaxCurve)(ref val8)).constant; emission = val7.emission; writer.WriteLine($"{indent} Emission: rate={arg2} enabled={((EmissionModule)(ref emission)).enabled}"); } } catch (Exception ex) { writer.WriteLine(indent + " [组件详情输出异常: " + ex.Message + "]"); } } private string GetAnimatorParamValue(Animator anim, AnimatorControllerParameter p) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0023: Expected I4, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 try { AnimatorControllerParameterType type = p.type; AnimatorControllerParameterType val = type; switch (val - 1) { default: if ((int)val != 9) { break; } return "Trigger"; case 0: return anim.GetFloat(p.nameHash).ToString("F3"); case 2: return anim.GetInteger(p.nameHash).ToString(); case 3: return anim.GetBool(p.nameHash).ToString(); case 1: break; } return "?"; } catch { return "获取失败"; } } private string GetFsmVariableValue(object v) { if (v == null) { return "null"; } try { PropertyInfo property = v.GetType().GetProperty("Value"); if (property != null) { object value = property.GetValue(v); return (value != null) ? value.ToString() : "null"; } FieldInfo field = v.GetType().GetField("Value"); if (field != null) { object value2 = field.GetValue(v); return (value2 != null) ? value2.ToString() : "null"; } return v.ToString(); } catch { return "??"; } } private void TestGiveSkillsInOrder() { try { PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"[F4弹窗测试] PlayerData 为空"); return; } List<string> list = new List<string>(); try { List<ToolCrest> allCrests = ToolItemManager.GetAllCrests(); if (allCrests != null) { foreach (ToolCrest item in allCrests) { if ((Object)(object)item != (Object)null && !string.IsNullOrEmpty(item.name)) { list.Add(item.name); } } } } catch { } int num = _testSkillFields.Length + list.Count; if (num == 0) { Plugin.Log.LogError((object)"[F4弹窗测试] 测试序列为空"); return; } int num2 = _f4SelfGiveIndex % num; _f4SelfGiveIndex++; if (num2 < _testSkillFields.Length) { string text = _testSkillFields[num2]; ResetPdBoolForTest(instance, text); if (text == "HasSeenEvaHeal") { ResetPdBoolForTest(instance, "HasBoundCrestUpgrader"); } Plugin.Log.LogInfo((object)$"[F4弹窗测试] 技能 #{_f4SelfGiveIndex}/{num}: {text}"); StartingAbilityPickerAPI.GiveSkill(text, true); } else { string text2 = list[num2 - _testSkillFields.Length]; Plugin.Log.LogInfo((object)$"[F4弹窗测试] 纹章 #{_f4SelfGiveIndex}/{num}: {text2}"); OfficialMsgHelper.ShowToolCrestByName(text2, (Action)null); } } catch (Exception arg) { Plugin.Log.LogError((object)$"[F4弹窗测试] 异常: {arg}"); } } private static void ResetPdBoolForTest(PlayerData pd, string field) { try { FieldInfo field2 = typeof(PlayerData).GetField(field, BindingFlags.Instance | BindingFlags.Public); if (field2 != null && field2.FieldType == typeof(bool)) { field2.SetValue(pd, false); } } catch { } } private void TestShowCrestPopup() { try { List<ToolCrest> allCrests = ToolItemManager.GetAllCrests(); if (allCrests == null || allCrests.Count == 0) { Plugin.Log.LogError((object)"[纹章弹窗] ToolItemManager 无纹章清单"); return; } ToolCrest val = allCrests[_crestPopupIndex % allCrests.Count]; _crestPopupIndex++; OfficialMsgHelper.ShowToolCrest(val, (Action)delegate { Plugin.Log.LogInfo((object)"[纹章弹窗] 弹窗结束"); }); } catch (Exception arg) { Plugin.Log.LogError((object)$"[纹章弹窗] 异常: {arg}"); } } private void TestGrantAllPermissions() { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown try { Plugin.Log.LogInfo((object)"[F4全部权限] ===== 授予前 GlobalConfig ====="); Plugin.Log.LogInfo((object)$"[F4全部权限] 攻击: Up={GlobalConfig.AttackUp.Value}, Left={GlobalConfig.AttackLeft.Value}, Right={GlobalConfig.AttackRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 冲刺: L={GlobalConfig.DashLeft.Value}, R={GlobalConfig.DashRight.Value} | 飞针: L={GlobalConfig.HarpoonLeft.Value}, R={GlobalConfig.HarpoonRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 漂浮: L={GlobalConfig.FloatLeft.Value}, R={GlobalConfig.FloatRight.Value} | 壁跳: L={GlobalConfig.WallJumpLeft.Value}, R={GlobalConfig.WallJumpRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 回血: Heal={GlobalConfig.Heal.Value}"); StartingAbilityPickerAPI.SetAttackPermissions(true, true, true); DirectionPermissions val = new DirectionPermissions(); val.DashLeft = true; val.DashRight = true; val.HarpoonLeft = true; val.HarpoonRight = true; val.FloatLeft = true; val.FloatRight = true; val.WallJumpLeft = true; val.WallJumpRight = true; val.AllowHeal = true; StartingAbilityPickerAPI.SetMovementPermissions(val); Plugin.Log.LogInfo((object)"[F4全部权限] ===== 授予后 GlobalConfig ====="); Plugin.Log.LogInfo((object)$"[F4全部权限] 攻击: Up={GlobalConfig.AttackUp.Value}, Left={GlobalConfig.AttackLeft.Value}, Right={GlobalConfig.AttackRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 冲刺: L={GlobalConfig.DashLeft.Value}, R={GlobalConfig.DashRight.Value} | 飞针: L={GlobalConfig.HarpoonLeft.Value}, R={GlobalConfig.HarpoonRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 漂浮: L={GlobalConfig.FloatLeft.Value}, R={GlobalConfig.FloatRight.Value} | 壁跳: L={GlobalConfig.WallJumpLeft.Value}, R={GlobalConfig.WallJumpRight.Value}"); Plugin.Log.LogInfo((object)$"[F4全部权限] 回血: Heal={GlobalConfig.Heal.Value}"); (bool, bool, bool) attackPermissions = StartingAbilityPickerAPI.GetAttackPermissions(); DirectionPermissions movementPermissions = StartingAbilityPickerAPI.GetMovementPermissions(); Plugin.Log.LogInfo((object)$"[F4全部权限] 运行时攻击: Up={attackPermissions.Item1}, Left={attackPermissions.Item2}, Right={attackPermissions.Item3}"); Plugin.Log.LogInfo((object)($"[F4全部权限] 运行时移动: 冲刺L={movementPermissions.DashLeft},R={movementPermissions.DashRight} 飞针L={movementPermissions.HarpoonLeft},R={movementPermissions.HarpoonRight} " + $"漂浮L={movementPermissions.FloatLeft},R={movementPermissions.FloatRight} 壁跳L={movementPermissions.WallJumpLeft},R={movementPermissions.WallJumpRight} 回血={movementPermissions.AllowHeal}")); Plugin.ShowNotification("已授予全部权限"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[F4全部权限] 异常: {arg}"); } } private void TestNextDirectionPermission() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown try { var (text, text2, flag, flag2) = DirectionCalibList[_dirCalibIndex % DirectionCalibList.Length]; _dirCalibIndex++; DirectionPermissions val = new DirectionPermissions(); switch (text2) { case "hasDash": val.DashLeft = flag2; val.DashRight = flag; break; case "hasHarpoonDash": val.HarpoonLeft = flag2; val.HarpoonRight = flag; break; case "hasBrolly": val.FloatLeft = flag2; val.FloatRight = flag; break; case "hasWalljump": val.WallJumpLeft = flag2; val.WallJumpRight = flag; break; } StartingAbilityPickerAPI.SetMovementPermissions(val); StartingAbilityPickerAPI.GiveSkill(text2, true); Plugin.ShowNotification(Locale.Get(text)); Plugin.Log.LogInfo((object)$"[F10方向校准] 已只开 {text}(skill={text2}, right={flag}, left={flag2}),请实测实际移动方向"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[F10方向校准] 异常: {arg}"); } } private void TestUnlockEvaHeal() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"PlayerData 不可用"); return; } instance.HasSeenEvaHeal = true; instance.HasBoundCrestUpgrader = true; instance.CrestUpgraderOfferedFinal = true; instance.CrestPreUpgradeTalked = true; instance.CrestTalkedPurpose = true; instance.CrestUpgraderTalkedSnare = true; instance.CrestTalkedPurpose = true; instance.CrestUpgraderTalkedSnare = true; instance.chapelClosed_reaper = true; instance.chapelClosed_wanderer = true; instance.chapelClosed_beast = true; instance.chapelClosed_witch = true; instance.chapelClosed_toolmaster = true; instance.chapelClosed_shaman = true; instance.completedMemory_reaper = true; instance.completedMemory_wanderer = true; instance.completedMemory_beast = true; instance.completedMemory_witch = true; instance.completedMemory_toolmaster = true; instance.completedMemory_shaman = true; string[] array = new string[3] { "EvaHeal", "Sylphsong", "Slythsong" }; string[] array2 = array; foreach (string text in array2) { try { Data data = ((SerializableNamedList<Data, NamedData>)(object)instance.Tools).GetData(text); data.IsUnlocked = true; data.AmountLeft = 1; ((SerializableNamedList<Data, NamedData>)(object)instance.Tools).SetData(text, data); } catch { } } try { Data data2 = ((SerializableNamedList<Data, NamedData>)(object)instance.Collectables).GetData("EvaHeal"); data2.Amount = 1; ((SerializableNamedList<Data, NamedData>)(object)instance.Collectables).SetData("EvaHeal", data2); } catch { } try { MethodInfo methodInfo = Type.GetType("AutoSaveManager, Assembly-CSharp")?.GetMethod("Save", new Type[1] { typeof(Enum) }); FieldInfo fieldInfo = Type.GetType("AutoSaveName, Assembly-CSharp")?.GetField("GAINED_SLYTHSONG"); if (methodInfo != null && fieldInfo != null) { methodInfo.Invoke(null, new object[1] { fieldInfo.GetValue(null) }); } } catch { } try { Type type = Type.GetType("InventoryCollectableItemSelectionHelper, Assembly-CSharp"); if (type != null) { PropertyInfo property = type.GetProperty("LastSelectionUpdate", BindingFlags.Static | BindingFlags.Public); if (property != null) { Type nestedType = type.GetNestedType("SelectionType"); if (nestedType != null) { object value = Enum.Parse(nestedType, "EvaHeal"); property.SetValue(null, value); } } } } catch { } try { HeroController instance2 = HeroController.instance; if ((Object)(object)instance2 != (Object)null) { instance2.AddSilk(1, true); } } catch { } } private void TestLoreDialogue() { LoreRandomizer.LoreEntry[] loreTable = LoreRandomizer.LoreTable; if (loreTable.Length != 0) { _loreTestIndex = (_loreTestIndex + 1) % loreTable.Length; LoreRandomizer.LoreEntry loreEntry = loreTable[_loreTestIndex]; LoreRandomizer.ShowLoreDialogue(loreEntry.Key, loreEntry.Sheet); } } private void PickCurrent(bool pick) { List<(string, string)> list = ((_currentCandidates.Count > 0) ? _currentCandidates : SpritePickCandidates.ToList()); if (_pickerIndex < list.Count) { if (pick) { _pickedNames.Add(list[_pickerIndex].Item2); } _pickerIndex++; if (_pickerIndex >= list.Count) { FinishPicker(); } } } private IEnumerator LoadAtlasesThenStartFleaPicker() { if (_isDumpingSprites) { yield break; } _isDumpingSprites = true; List<string> addrKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk)) { addrKeys.Add(sk); } } } } catch { } HashSet<string> atlasKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); (string label, string[] keys)[] spriteSearchGroups = SpriteSearchGroups; for (int i = 0; i < spriteSearchGroups.Length; i++) { (string label, string[] keys) group = spriteSearchGroups[i]; foreach (string k in addrKeys) { if (!IsLikelyAtlasKey(k)) { continue; } bool match = false; string[] item = group.keys; foreach (string kw in item) { if (k.IndexOf(kw, StringComparison.OrdinalIgnoreCase) >= 0) { match = true; break; } } if (match) { atlasKeys.Add(k); } } } int loadedOk = 0; int loadedFail = 0; foreach (string k2 in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k2); } catch { loadedFail++; continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { loadedOk++; continue; } loadedFail++; try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); _currentCandidates.Clear(); Sprite[] allSprites = Resources.FindObjectsOfTypeAll<Sprite>(); Sprite[] array = allSprites; foreach (Sprite sp in array) { if (!((Object)(object)sp == (Object)null)) { string name = ((Object)sp).name; if (!string.IsNullOrEmpty(name) && name.IndexOf("flea", StringComparison.OrdinalIgnoreCase) >= 0) { _currentCandidates.Add(("flea", name)); } } } if (_currentCandidates.Count == 0) { Plugin.Log.LogInfo((object)"[F4] 未找到任何包含 'flea' 的贴图。"); _isDumpingSprites = false; yield break; } _pickerActive = true; _pickerIndex = 0; _pickedNames.Clear(); Plugin.Log.LogInfo((object)$"[F4] 找到 {_currentCandidates.Count} 个 flea 图标,开始筛选。"); _isDumpingSprites = false; } private static string NormalizeSpriteName(string s) { if (string.IsNullOrEmpty(s)) { return s ?? ""; } StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { if (c != '-' && c != '_' && c != ' ') { stringBuilder.Append(char.ToLowerInvariant(c)); } } return stringBuilder.ToString(); } private IEnumerator LoadAtlasesThenStartPromptPicker() { if (_isDumpingSprites) { yield break; } _isDumpingSprites = true; List<string> addrKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk)) { addrKeys.Add(sk); } } } } catch { } HashSet<string> atlasKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string k in addrKeys) { if (IsLikelyAtlasKey(k)) { atlasKeys.Add(k); } } int loadedOk = 0; int loadedFail = 0; foreach (string k2 in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k2); } catch { loadedFail++; continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { loadedOk++; continue; } loadedFail++; try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); _currentCandidates.Clear(); Sprite[] allSprites = Resources.FindObjectsOfTypeAll<Sprite>(); List<string> flowerPrompt = new List<string>(); List<string> flowerAny = new List<string>(); List<string> farsightPrompt = new List<string>(); List<string> farsightAny = new List<string>(); List<string> completionPrompt = new List<string>(); List<string> completionAny = new List<string>(); Sprite[] array = allSprites; foreach (Sprite sp in array) { if ((Object)(object)sp == (Object)null) { continue; } string name = ((Object)sp).name; if (string.IsNullOrEmpty(name)) { continue; } string n = NormalizeSpriteName(name); if (n.Contains("flower")) { if (n.Contains("prompt")) { flowerPrompt.Add(name); } else { flowerAny.Add(name); } } if (n.Contains("far") && n.Contains("sight")) { if (n.Contains("prompt")) { farsightPrompt.Add(name); } else { farsightAny.Add(name); } } if (n.Contains("completion")) { if (n.Contains("prompt")) { completionPrompt.Add(name); } else { completionAny.Add(name); } } } foreach (string x in flowerPrompt) { _currentCandidates.Add(("花+prompt", x)); } if (flowerPrompt.Count == 0) { foreach (string x2 in flowerAny) { _currentCandidates.Add(("花", x2)); } } foreach (string x3 in farsightPrompt) { _currentCandidates.Add(("遥观仪+prompt", x3)); } if (farsightPrompt.Count == 0) { foreach (string x4 in farsightAny) { _currentCandidates.Add(("遥观仪", x4)); } } foreach (string x5 in completionPrompt) { _currentCandidates.Add(("completion+prompt", x5)); } if (completionPrompt.Count == 0) { foreach (string x6 in completionAny) { _currentCandidates.Add(("completion", x6)); } } Plugin.Log.LogInfo((object)($"[F4] 花: prompt命中{flowerPrompt.Count} / 回退{flowerAny.Count}," + $"遥观仪(far+sight): prompt命中{farsightPrompt.Count} / 回退{farsightAny.Count}," + $"completion: prompt命中{completionPrompt.Count} / 回退{completionAny.Count}")); if (_currentCandidates.Count == 0) { Plugin.Log.LogInfo((object)"[F4] 未找到任何含 whiteflower / farsight 的贴图。"); _isDumpingSprites = false; yield break; } _pickerActive = true; _pickerIndex = 0; _pickedNames.Clear(); Plugin.Log.LogInfo((object)$"[F4] 找到 {_currentCandidates.Count} 个目标图标,开始筛选。"); _isDumpingSprites = false; } private void FinishPicker() { _pickerActive = false; string path = Path.Combine(Paths.PluginPath, "sprite_picked.txt"); using (StreamWriter streamWriter = new StreamWriter(path, append: false)) { foreach (string pickedName in _pickedNames) { streamWriter.WriteLine(pickedName); } } StartAnnotate(_pickedNames); } private void StartAnnotate(List<string> names) { _annotateList = names.Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList(); if (_annotateList.Count != 0) { _annotated.Clear(); _annotateIndex = 0; _noteText = ""; _annotateActive = true; } } private void StartAnnotateFromFile() { string path = Path.Combine(Paths.PluginPath, "sprite_picked.txt"); if (File.Exists(path)) { List<string> names = (from l in File.ReadAllLines(path) select l.Trim() into l where l.Length > 0 select l).ToList(); StartAnnotate(names); } } private void SaveCurrentNote() { if (_annotateIndex < _annotateList.Count) { _annotated.Add((_annotateList[_annotateIndex], _noteText.Trim())); _annotateIndex++; _noteText = ""; if (_annotateIndex >= _annotateList.Count) { FinishAnnotate(); } } } private void FinishAnnotate() { _annotateActive = false; string path = Path.Combine(Paths.PluginPath, "sprite_annotated.txt"); using StreamWriter streamWriter = new StreamWriter(path, append: false); streamWriter.WriteLine("#sprite_name|用途备注"); foreach (var (text, text2) in _annotated) { streamWriter.WriteLine(text + "|" + text2); } } private IEnumerator DumpSpriteIconsCoroutine() { if (!_isDumpingSprites) { _isDumpingSprites = true; yield return ((MonoBehaviour)this).StartCoroutine(LoadAtlasesThenStartPicker()); _isDumpingSprites = false; } } private IEnumerator LoadAtlasesThenStartPicker() { List<string> addrKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk)) { addrKeys.Add(sk); } } } } catch { } HashSet<string> atlasKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); (string label, string[] keys)[] spriteSearchGroups = SpriteSearchGroups; for (int i = 0; i < spriteSearchGroups.Length; i++) { (string label, string[] keys) group = spriteSearchGroups[i]; foreach (string k in addrKeys) { if (!IsLikelyAtlasKey(k)) { continue; } bool match = false; string[] item = group.keys; foreach (string kw in item) { if (k.IndexOf(kw, StringComparison.OrdinalIgnoreCase) >= 0) { match = true; break; } } if (match) { atlasKeys.Add(k); } } } int loadedOk = 0; int loadedFail = 0; foreach (string k2 in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k2); } catch { loadedFail++; continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { loadedOk++; continue; } loadedFail++; try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); string pickPath = Path.Combine(Paths.PluginPath, "sprite_picked.txt"); if (File.Exists(pickPath)) { StartAnnotateFromFile(); yield break; } _pickerActive = true; _pickerIndex = 0; _pickedNames.Clear(); } private static bool IsLikelyAtlasKey(string key) { if (key.IndexOf(".spriteatlas", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (key.IndexOf(".bundle", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (key.IndexOf("sprites/", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return false; } private IEnumerator ExportSteelModeIconCoroutine() { _isDumpingSprites = true; try { SpriteCache.EnsureBuilt(); Sprite sprite = SpriteCache.Find("mode_select_Steel_Soul_HUD"); if ((Object)(object)sprite == (Object)null) { List<string> atlasKeys = new List<string>(); try { foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string sk = key as string; if (sk != null && !string.IsNullOrEmpty(sk) && IsLikelyAtlasKey(sk)) { string low = sk.ToLowerInvariant(); if (low.Contains("area_art") || low.Contains("mode_select") || low.Contains("steel")) { atlasKeys.Add(sk); } } } } } catch { } foreach (string k in atlasKeys) { AsyncOperationHandle<Object> handle; try { handle = Addressables.LoadAssetAsync<Object>((object)k); } catch { continue; } float deadline = Time.realtimeSinceStartup + 20f; while (!handle.IsDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (handle.IsDone && (int)handle.Status == 1) { continue; } try { if (handle.IsValid()) { Addressables.Release<Object>(handle); } } catch { } } SpriteCache.Reset(); SpriteCache.EnsureBuilt(); sprite = SpriteCache.Find("mode_select_Steel_Soul_HUD"); } if (!((Object)(object)sprite == (Object)null)) { string outPath = Path.Combine(Paths.PluginPath, "steel_mode_icon.png"); ExportSpriteToPng(sprite, outPath); } } finally { _isDumpingSprites = false; } } private static void ExportSpriteToPng(Sprite s, string outPath) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s == (Object)null) { return; } Texture2D texture = s.texture; if ((Object)(object)texture == (Object)null) { return; } Rect textureRect = s.textureRect; int num = Mathf.FloorToInt(((Rect)(ref textureRect)).x); int num2 = Mathf.FloorToInt(((Rect)(ref textureRect)).y); int num3 = Mathf.CeilToInt(((Rect)(ref textureRect)).width); int num4 = Mathf.CeilToInt(((Rect)(ref textureRect)).height); Texture2D val = null; RenderTexture val2 = null; RenderTexture val3 = null; try { val2 = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)texture, val2); val3 = RenderTexture.active; RenderTexture.active = val2; val = new Texture2D(num3, num4, (TextureFormat)4, false); val.ReadPixels(new Rect((float)num, (float)num2, (float)num3, (float)num4), 0, 0); val.Apply(); RenderTexture.active = val3; val3 = null; RenderTexture.ReleaseTemporary(val2); val2 = null; byte[] bytes = ImageConversion.EncodeToPNG(val); File.WriteAllBytes(outPath, bytes); } catch (Exception ex) { Plugin.Log.LogError((object)("[sprite搜索] 裁剪失败: " + ex.Message)); } finally { if ((Object)(object)RenderTexture.active != (Object)(object)val3 && (Object)(object)val3 != (Object)null) { RenderTexture.active = val3; } if ((Object)(object)val2 != (Object)null) { RenderTexture.ReleaseTemporary(val2); } if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } private static bool IsDumpSkipped(string sceneName) { string[] dumpSkipSubstrings = DumpSkipSubstrings; foreach (string value in dumpSkipSubstrings) { if (sceneName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private void DumpCheckPoints() { if (!IsScanningChecks && !_isDumpingTransitions) { ((MonoBehaviour)this).StartCoroutine(DumpCheckPointsCoroutine()); } } private IEnumerator DumpCheckPointsCoroutine() { IsScanningChecks = true; ThreadPriority oldLoadPriority = Application.backgroundLoadingPriority; Application.backgroundLoadingPriority = (ThreadPriority)4; FieldInfo suppressField = Type.GetType("HKSilksong_Randomizer.RandomSceneLoader, HKSilksong_SceneRandomizer")?.GetField("SuppressSceneEvents", BindingFlags.Static | BindingFlags.Public); suppressField?.SetValue(null, true); try { List<string> sceneNames = new List<string>(); try { int bsCount = SceneManager.sceneCountInBuildSettings; for (int i = 0; i < bsCount; i++) { string p = SceneUtility.GetScenePathByBuildIndex(i); if (!string.IsNullOrEmpty(p)) { sceneNames.Add(Path.GetFileNameWithoutExtension(p)); } } } catch { } if (sceneNames.Count < 10) { sceneNames.Clear(); try { HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string s = key as string; if (s != null && s.StartsWith("Scenes/", StringComparison.OrdinalIgnoreCase) && seen.Add(s)) { sceneNames.Add(s.Substring("Scenes/".Length)); } } } } catch { } } if (sceneNames.Count == 0) { Plugin.Log.LogError((object)"[扫描] 无法枚举场景清单(Build Settings 与 Addressables 均为空)"); yield break; } string outPath = Path.Combine(Paths.PluginPath, "check_points_scan.txt"); int sceneCount = 0; int pointCount = 0; int failed = 0; int excluded = 0; using StreamWriter writer = new StreamWriter(outPath, append: false); writer.WriteLine("#type|scene|path|name|detail|key|x|y"); writer.Flush(); foreach (string sceneName in sceneNames) { if (IsDumpSkipped(sceneName)) { excluded++; continue; } Scene scene = SceneManager.GetSceneByName(sceneName); bool weLoaded = false; bool viaAddr = false; AsyncOperationHandle<SceneInstance> addr = default(AsyncOperationHandle<SceneInstance>); if (!((Scene)(ref scene)).IsValid() || !((Scene)(ref scene)).isLoaded) { AsyncOperation op = null; try { op = SceneManager.LoadSceneAsync(sceneName, (LoadSceneMode)1); } catch { } if (op != null) { float deadline = Time.realtimeSinceStartup + 30f; while (!op.isDone && Time.realtimeSinceStartup <= deadline) { yield return null; } if (op.isDone) { scene = SceneManager.GetSceneByName(sceneName); if (((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded) { weLoaded = true; } } } if (!weLoaded) { bool started = false; try { addr = Addressables.LoadSceneAsync((object)("Scenes/" + sceneName), (LoadSceneMode)1, true, 100, (SceneReleaseMode)0); started = true; } catch { } if (started) { float deadline2 = Time.realtimeSinceStartup + 30f; while (!addr.IsDone && Time.realtimeSinceStartup <= deadline2) { yield return null; } if (addr.IsDone && (int)addr.Status == 1) { SceneInstance result = addr.Result; scene = ((SceneInstance)(ref result)).Scene; weLoaded = true; viaAddr = true; } else { try { if (addr.IsValid()) { Addressables.Release<SceneInstance>(addr); } } catch { } } } } if (!weLoaded) { failed++; yield return null; continue; } } ResetSpawnedShopSingleton(); try { int foundHere = ScanSceneCheckPoints(scene, sceneName, writer); pointCount += foundHere; sceneCount++; } catch { failed++; } if (weLoaded) { try { if (viaAddr) { Addressables.UnloadSceneAsync(addr, true); } else if (((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded) { SceneManager.UnloadSceneAsync(scene); } } catch { } } writer.Flush(); yield return null; } } finally { Application.backgroundLoadingPriority = oldLoadPriority; suppressField?.SetValue(null, false); IsScanningChecks = false; } } private static int ScanSceneCheckPoints(Scene scene, string sceneName, StreamWriter writer) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0269: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Invalid comparison between Unknown and I4 //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0697: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Unknown result type (might be due to invalid IL or missing references) //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_0781: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) int num = 0; string boolName; string text = (MapStationUnlockPatch.TryGetStationBoolForScene(sceneName, out boolName) ? ("station:" + boolName) : ""); GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { CollectableItemPickup[] componentsInChildren = val.GetComponentsInChildren<CollectableItemPickup>(true); foreach (CollectableItemPickup val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } string text2; try { text2 = PickupPatch.GetPickupKey(val2); } catch { text2 = sceneName + "_" + ((Object)((Component)val2).gameObject).name; } string text3 = ""; try { if ((Object)(object)val2.Item != (Object)null) { text3 = ((Object)val2.Item).name; } } catch { } Vector3 position = ((Component)val2).transform.position; writer.WriteLine($"Pickup|{sceneName}|{GetObjectPath(((Component)val2).transform)}|{((Object)((Component)val2).gameObject).name}|{text3}|{text2}|{position.x:F1}|{position.y:F1}"); num++; } NPCControlBase[] componentsInChildren2 = val.GetComponentsInChildren<NPCControlBase>(true); foreach (NPCControlBase val3 in componentsInChildren2) { if ((Object)(object)val3 == (Object)null) { continue; } string name = ((Object)((Component)val3).gameObject).name; Vector3 position2 = ((Component)val3).transform.position; if (LoreTriggerPatch.IsExcludedTollName(name)) { writer.WriteLine($"Toll|{sceneName}|{GetObjectPath(((Component)val3).transform)}|{name}|{text}||{position2.x:F1}|{position2.y:F1}"); num++; continue; } bool flag = false; try { flag = (int)((InteractableBase)val3).InteractLabel == 0; } catch { } if (flag) { string text4 = "loretrig:" + sceneName + ":" + name; writer.WriteLine($"Lore|{sceneName}|{GetObjectPath(((Component)val3).transform)}|{name}||{text4}|{position2.x:F1}|{position2.y:F1}"); num++; } } BellBench[] componentsInChildren3 = val.GetComponentsInChildren<BellBench>(true); foreach (BellBench val4 in componentsInChildren3) { if (!((Object)(object)val4 == (Object)null)) { Vector3 position3 = ((Component)val4).transform.position; writer.WriteLine($"BellBench|{sceneName}|{GetObjectPath(((Component)val4).transform)}|{((Object)((Component)val4).gameObject).name}|{text}||{position3.x:F1}|{position3.y:F1}"); num++; } } ShopOwner[] componentsInChildren4 = val.GetComponentsInChildren<ShopOwner>(true); foreach (ShopOwner val5 in componentsInChildren4) { if (!((Object)(object)val5 == (Object)null)) { for (int n = 0; n < 12; n++) { string text5 = $"shop:{sceneName}_{n}"; Vector3 position4 = ((Component)val5).transform.position; writer.WriteLine($"ShopSlot|{sceneName}|{GetObjectPath(((Component)val5).transform)}|ShopSlot_{n}|Slot {n}|{text5}|{position4.x:F1}|{position4.y:F1}"); num++; } } } SimpleShopMenuOwner[] componentsInChildren5 = val.GetComponentsInChildren<SimpleShopMenuOwner>(true); foreach (SimpleShopMenuOwner val6 in componentsInChildren5) { if (!((Object)(object)val6 == (Object)null)) { for (int num3 = 0; num3 < 12; num3++) { string text6 = $"shop:{sceneName}_{num3}"; Vector3 position5 = ((Component)val6).transform.position; writer.WriteLine($"ShopSlot|{sceneName}|{GetObjectPath(((Component)val6).transform)}|ShopSlot_{num3}|Slot {num3}|{text6}|{position5.x:F1}|{position5.y:F1}"); num++; } } } CaravanSpider[] componentsInChildren6 = val.GetComponentsInChildren<CaravanSpider>(true); foreach (CaravanSpider val7 in componentsInChildren6) { if (!((Object)(object)val7 == (Object)null)) { for (int num5 = 0; num5 < 12; num5++) { string text7 = $"shop:{sceneName}_{num5}"; Vector3 position6 = ((Component)val7).transform.position; writer.WriteLine($"ShopSlot|{sceneName}|{GetObjectPath(((Component)val7).transform)}|ShopSlot_{num5}|Slot {num5}|{text7}|{position6.x:F1}|{position6.y:F1}"); num++; } } } CaravanTroupeHunter[] componentsInChildren7 = val.GetComponentsInChildren<CaravanTroupeHunter>(true); foreach (CaravanTroupeHunter val8 in componentsInChildren7) { if (!((Object)(object)val8 == (Object)null)) { for (int num7 = 0; num7 < 12; num7++) { string text8 = $"shop:{sceneName}_{num7}"; Vector3 position7 = ((Component)val8).transform.position; writer.WriteLine($"ShopSlot|{sceneName}|{GetObjectPath(((Component)val8).transform)}|ShopSlot_{num7}|Slot {num7}|{text8}|{position7.x:F1}|{position7.y:F1}"); num++; } } } SimpleQuestsShopOwner[] componentsInChildren8 = val.GetComponentsInChildren<SimpleQuestsShopOwner>(true); foreach (SimpleQuestsShopOwner val9 in componentsInChildren8) { if (!((Object)(object)val9 == (Object)null)) { for (int num9 = 0; num9 < 12; num9++) { string text9 = $"shop:{sceneName}_{num9}"; Vector3 position8 = ((Component)val9).transform.position; writer.WriteLine($"ShopSlot|{sceneName}|{GetObjectPath(((Component)val9).transform)}|ShopSlot_{num9}|Slot {num9}|{text9}|{position8.x:F1}|{position8.y:F1}"); num++; } } } } return num; } private static void ResetSpawnedShopSingleton() { ShakraMerchantKeeper.ResetSpawnedShopSingleton(); } private static string GetObjectPath(Transform t) { StringBuilder stringBuilder = new StringBuilder(((Object)t).name); while ((Object)(object)t.parent != (Object)null) { t = t.parent; stringBuilder.Insert(0, ((Object)t).name + "/"); } return stringBuilder.ToString(); } private void DumpVanillaTransitions() { if (!_isDumpingTransitions) { ((MonoBehaviour)this).StartCoroutine(DumpVanillaTransitionsCoroutine()); } } private IEnumerator DumpVanillaTransitionsCoroutine() { _isDumpingTransitions = true; ThreadPriority oldLoadPriority = Application.backgroundLoadingPriority; Application.backgroundLoadingPriority = (ThreadPriority)4; FieldInfo suppressField = Type.GetType("HKSilksong_Randomizer.RandomSceneLoader, HKSilksong_SceneRandomizer")?.GetField("SuppressSceneEvents", BindingFlags.Static | BindingFlags.Public); suppressField?.SetValue(null, true); try { List<string> sceneNames = new List<string>(); string source = "Build Settings"; try { int bsCount = SceneManager.sceneCountInBuildSettings; for (int i = 0; i < bsCount; i++) { string p = SceneUtility.GetScenePathByBuildIndex(i); if (!string.IsNullOrEmpty(p)) { sceneNames.Add(Path.GetFileNameWithoutExtension(p)); } } } catch { } if (sceneNames.Count < 10) { sceneNames.Clear(); source = "Addressables"; try { HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (IResourceLocator locator in Addressables.ResourceLocators) { foreach (object key in locator.Keys) { string s = key as string; if (s != null && s.StartsWith("Scenes/", StringComparison.OrdinalIgnoreCase) && seen.Add(s)) { sceneNames.Add(s.Substring("Scenes/".Length)); } } } } catch { } } if (sceneNames.Count == 0) { Plugin.Log.LogError((object)"[Dump] 无法枚举场景清单(Build Settings 与 Addressables 均为空)"); yield break; } bool viaAddrList = source == "Addressables"; string outPath = Path.Combine(Paths.PluginPath, "vanilla_transitions.txt"); HashSet<string> seenPairs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); int sceneCount = 0; int pairCount = 0; int skipped = 0; int excluded = 0; using StreamWriter writer = new StreamWriter(outPath, append: false); writer.WriteLine("#sceneA|gateA|sceneB|gateB"); for (int batchStart = 0; batchStart < sceneNames.Count; batchStart += 10) { int batchLen = Math.Min(10, sceneNames.Count - batchStart); List<(string name, Scene scene, AsyncOperation op, AsyncOperationHandle<SceneInstance> addr, bool weLoaded, bool viaAddr)> items = new List<(string, Scene, AsyncOperation, AsyncOperationHandle<SceneInstance>, bool, bool)>(batchLen); for (int j = batchStart; j < batchStart + batchLen; j++) { string sceneName = sceneNames[j]; if (IsDumpSkipped(sceneName)) { excluded++; continue; } Scene scene = SceneManager.GetSceneByName(sceneName); if (((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded) { items.Add((sceneName, scene, null, default(AsyncOperationHandle<SceneInstance>), false, false)); continue; } AsyncOperation op = null; AsyncOperationHandle<SceneInstance> addr = default(AsyncOperationHandle<SceneInstance>); bool started = false; try { if (viaAddrList) { addr = Addressables.LoadSceneAsync((object)("Scenes/" + sceneName), (LoadSceneMode)1, true, 100, (SceneReleaseMode)0); } else { op = SceneManager.LoadSceneAsync(sceneName, (LoadSceneMode)1); } started = true; } catch { skipped++; } if (started && (op != null || viaAddrList)) { items.Add((sceneName, default(Scene), op, addr, true, viaAddrList)); } else if (started) { skipped++; } } float deadline = Time.realtimeSinceStartup + 60f; bool pending = true; while (pending && Time.realtimeSinceStartup <= deadline) { pending = false; foreach (var e in items) { if (e.weLoaded) { bool isDone; if (!e.viaAddr) { isDone = e.op.isDone; } else { AsyncOperationHandle<SceneInstance> item = e.addr; isDone = item.IsDone; } if (!isDone) { pending = true; break; } } } if (pending) { yield return null; } } foreach (var e2 in items) { Scene scene2; if (!e2.weLoaded) { scene2 = e2.scene; } else { int num; if (!e2.viaAddr) { num = (e2.op.isDone ? 1 : 0); } else { AsyncOperationHandle<SceneInstance> item = e2.addr; if (item.IsDone) { item = e2.addr; num = (((int)item.Status == 1) ? 1 : 0); } else { num = 0; } } if (num == 0) { skipped++; if (!e2.viaAddr) { continue; } try { AsyncOperationHandle<SceneInstance> item = e2.addr; if (item.IsValid()) { Addressables.Release<SceneInstance>(e2.addr); } } catch { } continue; } Scene val; if (!e2.viaAddr) { val = SceneManager.GetSceneByName(e2.name); } else { AsyncOperationHandle<SceneInstance> item = e2.addr; SceneInstance result = item.Result; val = ((SceneInstance)(ref result)).Scene; } scene2 = val; } try { if (((Scene)(ref scene2)).IsValid() && ((Scene)(ref scene2)).isLoaded) { int foundHere = 0; int totalHere = 0; GameObject[] rootGameObjects = ((Scene)(ref scene2)).GetRootGameObjects(); foreach (GameObject root in rootGameObjects) { TransitionPoint[] componentsInChildren = root.GetComponentsInChildren<TransitionPoint>(true); foreach (TransitionPoint tp in componentsInChildren) { if (!((Object)(object)tp == (Object)null) && !string.IsNullOrEmpty(tp.targetScene)) { totalHere++; string keyA = e2.name + "|" + ((Object)((Component)tp).gameObject).name; string keyB = tp.targetScene + "|" + tp.entryPoint; string pairKey = ((string.CompareOrdinal(keyA, keyB) <= 0) ? (keyA + "<->" + keyB) : (keyB + "<->" + keyA)); if (seenPairs.Add(pairKey)) { writer.WriteLine(keyA + "|" + tp.targetScene + "|" + tp.entryPoint); pairCount++; foundHere++; } } } } sceneCount++; } else { skipped++; } } catch { skipped++; } } foreach (var e3 in items) { if (!e3.weLoaded) { continue; } try { int num2; if (e3.viaAddr) { AsyncOperationHandle<SceneInstance> item = e3.addr; if (item.IsValid()) { item = e3.addr; if (item.IsDone) { item = e3.addr; num2 = (((int)item.Status == 1) ? 1 : 0); goto IL_0ba4; } } num2 = 0; goto IL_0ba4; } Scene s2 = SceneManager.GetSceneByName(e3.name); if (((Scene)(ref s2)).IsValid() && ((Scene)(ref s2)).isLoaded) { SceneManager.UnloadSceneAsync(s2); } goto end_IL_0b4b; IL_0ba4: if (num2 != 0) { Addressables.UnloadSceneAsync(e3.addr, true); } end_IL_0b4b:; } catch { } } writer.Flush(); yield return null; } } finally { Application.backgroundLoadingPriority = oldLoadPriority; suppressField?.SetValue(null, false); _isDumpingTransitions = false; } } private void WarpToLastBench() { try { PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"[HotkeyHandler] PlayerData 不可用"); return; } string respawnScene = instance.respawnScene; if (string.IsNullOrEmpty(respawnScene)) { Plugin.Log.LogWarning((object)"[HotkeyHandler] 重生点场景为空,请先坐一次椅子"); return; } Plugin.Log.LogInfo((object)("[HotkeyHandler] 传送至重生点: " + respawnScene + " / " + instance.respawnMarkerName)); GameManager gm = GameManager.instance; gm.SaveGame((Action<bool>)delegate(bool success) { if (!success) { Plugin.Log.LogError((object)"[HotkeyHandler] 保存游戏失败"); } else { gm.LoadGameFromUI(gm.profileID); } }); } catch (Exception ex) { Plugin.Log.LogError((object)("[HotkeyHandler] 传送异常: " + ex.Message)); } } private static void ToggleRecentItemsUI() { RecentItemsUI.Toggle(); Plugin.Log.LogInfo((object)("最近获得物品UI " + (RecentItemsUI.IsVisible ? "显示" : "隐藏"))); } private void DrawAnnotateWindow() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00f5: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_01b3: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_0208: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_025f: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Expected O, but got Unknown //IL_02bb: Expected O, but got Unknown //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Expected O, but got Unknown //IL_0318: Expected O, but got Unknown if (_annotateIndex >= _annotateList.Count) { FinishAnnotate(); return; } string text = _an
BepInEx/plugins/StartingAbilityPicker.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using GlobalSettings; using HKSilksong_Randomizer; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using SilksongItemRandomizer; using TMPro; using TeamCherry.Localization; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("StartingAbilityPicker")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("StartingAbilityPicker")] [assembly: AssemblyTitle("StartingAbilityPicker")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourGitHubUsername/StartingAbilityPicker")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 StartingAbilityPicker { public static class CrazyRandomizer { private static readonly Random GlobalRng = new Random(); public static void Apply() { Plugin.allowUpward = GlobalRng.Next(2) == 1; Plugin.allowLeft = GlobalRng.Next(2) == 1; Plugin.allowRight = GlobalRng.Next(2) == 1; Plugin.skillMode = true; Plugin.skillV = WeightedRandom(5, GlobalRng); Plugin.skillH = WeightedRandom(4, GlobalRng); Plugin.skillS = WeightedRandom(4, GlobalRng); Plugin.skillA = WeightedRandom(5, GlobalRng); if (Plugin.skillV == 0) { Plugin.skillV = 1; } if (Plugin.skillH == 0) { Plugin.skillH = 1; } Plugin.itemCount = WeightedRandom(10, GlobalRng); Plugin.seedInput = GlobalRng.Next(1, int.MaxValue).ToString(); } private static int WeightedRandom(int max, Random rng) { if (max <= 0) { return 0; } int num = 0; for (int i = 0; i <= max; i++) { int num2 = max - i + 1; num += num2 * num2; } int num3 = rng.Next(num); int num4 = 0; for (int j = 0; j <= max; j++) { int num5 = max - j + 1; num4 += num5 * num5; if (num3 < num4) { return j; } } return 0; } } public static class SharedRuntimeSettings { public static bool AttackUp = true; public static bool AttackLeft = true; public static bool AttackRight = true; public static bool UseTypeMode = false; public static int SkillTotal = 0; public static int SkillVertical = 0; public static int SkillHorizontal = 0; public static int SkillSpecial = 0; public static int SkillAttack = 0; public static int ItemCount = 0; public static int Seed = 0; public static bool ResetSeedWorld = false; public static bool FullRandomMode = false; public static bool CrestCurseEnabled = false; public static bool ForceCompletionDisplay = true; public static bool DashLeft = false; public static bool DashRight = false; public static bool HarpoonLeft = false; public static bool HarpoonRight = false; public static bool FloatLeft = false; public static bool FloatRight = false; public static bool WallJumpLeft = false; public static bool WallJumpRight = false; public static bool AllowHeal = false; public static bool HealGateEnabled = false; public static bool JumpGateEnabled = false; public static bool ColdResistGateEnabled = false; public static bool ColdResistOwned = false; public static bool DoubleJumpOwned = false; public static bool SwimOwned = false; public static bool SwimGateEnabled = false; public static bool ItemRandomEnabled = true; public static bool CrestRandomEnabled = false; public static bool SkillItemRandomEnabled = true; public static bool RelicRandomEnabled = true; public static bool TrapEnabled = false; public static bool TrapMovementEnabled = false; public static int TrapDifficulty = 0; public static int CurrencyFirstThreshold = 30; public static int CurrencySecondThreshold = 1000; public static int SilkSpearPityCount = 5; public static bool SilkRandomEnabled = false; public static bool SceneRandomEnabled = false; public static bool ShowSceneLabel = true; public static bool ShowSeedLabel = true; public static int RoomSeed = 0; public static int RoomRandomizerMode = 0; public static bool SkillTriggerEnabled = true; public static bool EnemyRandomEnabled = false; } public static class Locale { private static bool? _forceChinese; private static Dictionary<string, string> _externalTranslations; private static string _languageFolderPath; private static bool _isLoaded; private static bool? _cachedAutoDetect; private static readonly Dictionary<string, string> FallbackEnglish = new Dictionary<string, string> { { "开局选项 & 场景随机", "Startup Options & Scene Randomizer" }, { "当前存档开局设置:", "Current Save Startup Settings:" }, { "(此存档已设置过,只能查看)", "(This save has been configured, view only)" }, { "重置本存档设置", "Reset This Save's Settings" }, { "攻击方向选择:", "Attack Direction Selection:" }, { "下劈 (默认)", "Down Slash (Default)" }, { "上劈", "Up Slash" }, { "左劈", "Left Slash" }, { "右劈", "Right Slash" }, { "技能随机模式:", "Skill Random Mode:" }, { "总随机", "Total Mode" }, { "分类随机", "Type Mode" }, { "开局随机技能总数量:", "Total Random Skills:" }, { "分类随机数量:", "Category Random Count:" }, { "垂直技能", "Vertical Skills" }, { "水平技能", "Horizontal Skills" }, { "特殊技能", "Special Skills" }, { "攻击技能", "Attack Skills" }, { "开局随机物品数量:", "Starting Random Item Count:" }, { "种子", "Seed" }, { "重置种子世界(含技能触发器)", "Reset Seed World (incl. Skill Triggers)" }, { "警告:重置后当前种子世界将重新生成,所有拾取点会重生,技能触发器也会重置。", "Warning: This will regenerate the seed world, respawn all pickups, and reset skill triggers." }, { "确认", "Confirm" }, { "关闭", "Close" }, { "提示: 按 F7 呼出此窗口", "Tip: Press F7 to open this window" }, { "彻底疯狂", "Crazy Mode" }, { "纹章诅咒", "Crest Curse" }, { "启用纹章诅咒(每个纹章带有偏科效果)", "Enable Crest Curse (each crest has specialized effects)" }, { "丝之心、疾跑和上冲", "Silk Heart, Dash & Super Jump" }, { "[开]", "[ON]" }, { "[关]", "[OFF]" }, { "启用物品随机", "Enable Item Randomizer" }, { "场景随机未加载", "Scene Randomizer Not Loaded" }, { "场景随机设置", "Scene Randomizer" }, { "启用场景随机", "Enable Randomizer" }, { "启用陷阱随机", "Enable Trap Randomizer" }, { "陷阱、房间随机建议丝之心,疾跑和上冲", "Trap & Room Randomizer: Silk Heart, Dash & Super Jump recommended" }, { "陷阱难度:", "Trap Difficulty:" }, { "初猎", "Beginner" }, { "专注", "Focused" }, { "满溢", "Overflow" }, { "当前种子", "Current Seed" }, { "当前场景", "Current Scene" }, { "修改种子:", "Modify Seed:" }, { "应用种子", "Apply Seed" }, { "场景传送:", "Teleport:" }, { "传送", "Teleport" }, { "稍后传送至", "Teleporting to " }, { "场景连接已重新生成", "Regenerated" }, { "显示选项:", "Display:" }, { "显示当前场景名", "Show Scene Name" }, { "显示当前种子", "Show Seed" }, { "陷阱生命化", "Trap Life" }, { "完成度", "Completion" }, { "直接应用可随机", "Apply directly to randomize" }, { "启用怪物随机", "Enable Enemy Randomizer" }, { "面板背景", "Panel Background" }, { "全随机模式", "Full Random Mode" }, { "CN", "CN" }, { "EN", "EN" }, { "Auto", "Auto" }, { "Current Seed: ", "Current Seed: " }, { "Seed: ", "Seed: " }, { "Scene: ", "Scene: " }, { "正在传送到 ", "Teleporting to " }, { "纹章槽位已满,获得 100 念珠", "Crest slots full, gained 100 Geo" }, { "纹章槽位 {0} ({1}) 已解锁!", "Crest slot {0} ({1}) unlocked!" }, { "纹章槽位解锁器", "Crest Slot Unlocker" }, { "小生命", "Small Health" }, { "中灵丝", "Medium Silk" }, { "大念珠", "Large Geo" }, { "完全恢复", "Full Restore" }, { "面具碎片", "Mask Shard" }, { "丝轴碎片", "Spool Part" }, { "丝线恢复上限 +1", "Max Silk Regen +1" }, { "随机念珠", "Random Geo" }, { "随机蓝血", "Random Blue Health" }, { "丝之矛", "Silk Spear" }, { "灵丝风暴", "Thread Sphere" }, { "飞针", "Harpoon Dash" }, { "丝刃标", "Silk Charge" }, { "符文之怒", "Silk Bomb" }, { "苍白之爪", "Silk Boss Needle" }, { "丝忆弦针", "Needolin" }, { "疾风步", "Swift Step" }, { "流浪者披风", "Drifter's Cloak" }, { "雪绒披风", "Faydown Cloak" }, { "蓄力斩", "Charge Slash" }, { "灵丝升腾", "Silk Soar" }, { "蛛攀术", "Cling Grip" }, { "风铃摇", "EvaHeal" }, { "格挡", "Cross Stitch" }, { "深邃挽歌", "Deep Elegy" }, { "幻兽歌", "Beast Song" }, { "猎人日志", "Hunter's Journal" }, { "最近获得物品", "Recent Items" }, { "按 F6 可直接传送", "Press F6 to warp directly" }, { "攻击槽", "Attack Slot" }, { "工具槽", "Tool Slot" }, { "法术槽", "Spell Slot" }, { "未知", "Unknown" }, { "保底念珠", "Fallback Geo" }, { "灵丝", "Silk" }, { "蓝血", "Blue Health" }, { "念珠", "Geo" }, { "甲壳", "Shell" }, { "大灵丝碎片", "Large Silk Part" }, { "小念珠", "Small Geo" }, { "灵丝碎片", "Silk Fragment" }, { "生命", "Health" }, { "丝线恢复上限", "Max Silk Regen" } }; public static bool IsChinese { get { if (_forceChinese.HasValue) { return _forceChinese.Value; } if (_cachedAutoDetect.HasValue) { return _cachedAutoDetect.Value; } bool flag = DetectChinese(); _cachedAutoDetect = flag; return flag; } } public static void SetLanguageFolder(string path) { if (!string.IsNullOrEmpty(path) && Directory.Exists(path)) { _languageFolderPath = path; _isLoaded = false; } } public static void SetForceChinese(bool? force) { if (_forceChinese != force) { _forceChinese = force; _cachedAutoDetect = null; } } public static void Reload() { _isLoaded = false; _externalTranslations = null; _cachedAutoDetect = null; } public static string Get(string chineseText) { if (string.IsNullOrEmpty(chineseText)) { return chineseText; } EnsureLoaded(); if (_externalTranslations != null && _externalTranslations.TryGetValue(chineseText, out var value)) { return value; } if (IsChinese) { return chineseText; } if (FallbackEnglish.TryGetValue(chineseText, out var value2)) { return value2; } return chineseText; } private static void EnsureLoaded() { if (_isLoaded) { return; } _externalTranslations = null; _isLoaded = true; string text = _languageFolderPath; if (string.IsNullOrEmpty(text)) { text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "language"); } if (!Directory.Exists(text)) { Debug.LogWarning((object)("[Locale] Language folder not found: " + text)); return; } List<string> list = (from f in Directory.GetFiles(text, "*.json") orderby Path.GetFileName(f) select f).ToList(); if (list.Count == 0) { Debug.LogWarning((object)("[Locale] No JSON files found in " + text)); return; } Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in list) { try { Dictionary<string, string> dictionary2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(item)); if (dictionary2 == null) { continue; } foreach (KeyValuePair<string, string> item2 in dictionary2) { dictionary[item2.Key] = item2.Value; } Debug.Log((object)$"[Locale] Loaded {dictionary2.Count} entries from {Path.GetFileName(item)}"); } catch (Exception ex) { Debug.LogError((object)("[Locale] Failed to load " + item + ": " + ex.Message)); } } if (dictionary.Count > 0) { _externalTranslations = dictionary; Debug.Log((object)$"[Locale] Total external translations: {_externalTranslations.Count}"); } } private static bool DetectChinese() { try { Type type = Type.GetType("FontManager, Assembly-CSharp"); if (type != null) { FieldInfo field = type.GetField("_currentLanguage", BindingFlags.Static | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(null); if (value != null) { string text = value.ToString().ToUpper(); if (text == "ZH" || text == "ZH_TW") { return true; } } } } } catch { } try { GameSettings val = GameManager.instance?.gameSettings; if (val != null) { FieldInfo field2 = ((object)val).GetType().GetField("language", BindingFlags.Instance | BindingFlags.Public); if (field2 != null) { object value2 = field2.GetValue(val); if (value2 != null) { string text2 = value2.ToString().ToUpper(); if (text2 == "ZH" || text2 == "ZH_TW") { return true; } } } } } catch { } return false; } } public static class PanelRenderer { private static readonly Color BrightWhite = new Color(0.95f, 0.97f, 1f); private static GUIStyle _titleStyle; private static GUIStyle _statusStyle; private static GUIStyle _diffTitleStyle; private static GUIStyle _diffStatusStyle; private static GUIStyle _seedPlaceholderStyle; private static readonly Dictionary<int, GUIStyle> _titleStyleCache = new Dictionary<int, GUIStyle>(); private static readonly Dictionary<int, GUIStyle> _statusStyleCache = new Dictionary<int, GUIStyle>(); private static Vector2 _skillScrollPos; private static void EnsureStyles() { //IL_0014: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00e4: Expected O, but got Unknown if (_titleStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)1, fontSize = 14, fontStyle = (FontStyle)1 }; val.normal.textColor = BrightWhite; _titleStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)7, fontSize = 11 }; val2.normal.textColor = BrightWhite; _statusStyle = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)1, fontSize = 18, fontStyle = (FontStyle)1 }; val3.normal.textColor = BrightWhite; _diffTitleStyle = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)7, fontSize = 15 }; val4.normal.textColor = BrightWhite; _diffStatusStyle = val4; } } public static void DrawLeftPanel(Plugin p) { //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) //IL_0024: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) Color textColor = GUI.skin.label.normal.textColor; GUI.skin.label.normal.textColor = BrightWhite; GUI.skin.toggle.normal.textColor = BrightWhite; GUI.skin.button.normal.textColor = BrightWhite; GUI.skin.horizontalSlider.normal.textColor = BrightWhite; GUI.skin.textField.normal.textColor = BrightWhite; GUI.skin.label.fontSize = 20; GUI.skin.toggle.fontSize = 20; GUI.skin.button.fontSize = 24; GUI.skin.horizontalSlider.fontSize = 18; GUI.skin.textField.fontSize = 18; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(Locale.Get("当前存档开局设置:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); DrawBackgroundToggle(p); GUILayout.EndHorizontal(); GUILayout.Space(15f); bool flag = IsAlreadyChosen(p); if (flag) { GUILayout.Label(Locale.Get("(此存档已设置过,只能查看)"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUI.backgroundColor = new Color(0.8f, 0.5f, 0.2f); if (GUILayout.Button(Locale.Get("重置本存档设置"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(45f) })) { ResetProfile(p); GUI.backgroundColor = Color.white; GUI.skin.label.normal.textColor = textColor; GUI.skin.toggle.normal.textColor = textColor; GUI.skin.button.normal.textColor = textColor; GUI.skin.horizontalSlider.normal.textColor = textColor; GUI.skin.textField.normal.textColor = textColor; return; } GUI.backgroundColor = Color.white; } GUILayout.Space(20f); DrawAttackDirection(p, flag); GUILayout.Space(20f); DrawSkillModeButtons(p, flag); GUILayout.Space(10f); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(200f) }); _skillScrollPos = GUILayout.BeginScrollView(_skillScrollPos, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); if (!SharedRuntimeSettings.UseTypeMode) { DrawTotalSlider(p, flag); } else { DrawCategorySliders(p, flag); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.Space(15f); DrawItemSlider(p, flag); GUILayout.Space(25f); DrawSeedInput(p, flag); DrawConfirmAndClose(p, flag); GUILayout.Space(15f); int fontSize = GUI.skin.label.fontSize; GUI.skin.label.fontSize = 26; GUI.color = Color.yellow; GUILayout.Label(Locale.Get("提示: 按 F7 呼出此窗口"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUI.color = BrightWhite; GUI.skin.label.fontSize = fontSize; GUI.skin.label.normal.textColor = textColor; GUI.skin.toggle.normal.textColor = textColor; GUI.skin.button.normal.textColor = textColor; GUI.skin.horizontalSlider.normal.textColor = textColor; GUI.skin.textField.normal.textColor = textColor; } public static void DrawScenePanel(Plugin p) { //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) //IL_0024: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) Color textColor = GUI.skin.label.normal.textColor; GUI.skin.label.normal.textColor = BrightWhite; GUI.skin.button.normal.textColor = BrightWhite; GUI.skin.toggle.normal.textColor = BrightWhite; if (!p.SceneRandomAvailable) { GUILayout.Label(Locale.Get("场景随机未加载"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUI.skin.label.normal.textColor = textColor; return; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("CN", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(20f), GUILayout.Width(60f) })) { Locale.SetForceChinese(true); } if (GUILayout.Button("EN", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(20f), GUILayout.Width(60f) })) { Locale.SetForceChinese(false); } if (GUILayout.Button("Auto", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(20f), GUILayout.Width(60f) })) { Locale.SetForceChinese(null); } GUILayout.EndHorizontal(); GUILayout.Space(8f); GUILayout.Label(Locale.Get("场景随机设置"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(12f); DrawItemRandomToggle(p); DrawSceneToggle(p); DrawEnemyRandoAdjustToggle(p); DrawTrapToggle(p); DrawTrapDifficulty(p); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); DrawTrapMovementToggle(p); GUILayout.Space(12f); int currentRoomSeed = StartingAbilityPickerAPI.GetCurrentRoomSeed(); GUILayout.Label(string.Format("{0}: {1}", Locale.Get("当前种子"), currentRoomSeed), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(8f); string currentRoomScene = StartingAbilityPickerAPI.GetCurrentRoomScene(); GUILayout.Label(Locale.Get("当前场景") + ": " + currentRoomScene, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(18f); DrawSeedChanger(p); GUILayout.Space(20f); DrawTeleporter(p); GUILayout.Space(20f); DrawDisplayToggles(p); GUI.skin.label.normal.textColor = textColor; GUI.skin.button.normal.textColor = textColor; GUI.skin.toggle.normal.textColor = textColor; } private static bool IsAlreadyChosen(Plugin p) { int item = GameManager.instance?.profileID ?? (-1); if (Plugin.chosenProfileSet != null) { return Plugin.chosenProfileSet.Contains(item); } return false; } private static void ResetProfile(Plugin p) { int item = GameManager.instance?.profileID ?? (-1); Plugin.chosenProfileSet?.Remove(item); p.SaveChosenProfiles(); SharedRuntimeSettings.AttackUp = true; SharedRuntimeSettings.AttackLeft = true; SharedRuntimeSettings.AttackRight = true; SharedRuntimeSettings.UseTypeMode = false; SharedRuntimeSettings.SkillTotal = 0; SharedRuntimeSettings.SkillVertical = 0; SharedRuntimeSettings.SkillHorizontal = 0; SharedRuntimeSettings.SkillSpecial = 0; SharedRuntimeSettings.SkillAttack = 0; SharedRuntimeSettings.ItemCount = 0; SharedRuntimeSettings.ResetSeedWorld = false; SharedRuntimeSettings.FullRandomMode = false; SharedRuntimeSettings.CrestCurseEnabled = false; SharedRuntimeSettings.ForceCompletionDisplay = true; SharedRuntimeSettings.DashLeft = false; SharedRuntimeSettings.DashRight = false; SharedRuntimeSettings.HarpoonLeft = false; SharedRuntimeSettings.HarpoonRight = false; SharedRuntimeSettings.FloatLeft = false; SharedRuntimeSettings.FloatRight = false; SharedRuntimeSettings.WallJumpLeft = false; SharedRuntimeSettings.WallJumpRight = false; SharedRuntimeSettings.AllowHeal = false; SharedRuntimeSettings.ColdResistOwned = false; SharedRuntimeSettings.SwimOwned = false; SharedRuntimeSettings.DoubleJumpOwned = false; SharedRuntimeSettings.ColdResistGateEnabled = false; SharedRuntimeSettings.SwimGateEnabled = false; SharedRuntimeSettings.JumpGateEnabled = false; SharedRuntimeSettings.HealGateEnabled = false; StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); StartingAbilityPickerAPI.SetSkillRandomMode(SharedRuntimeSettings.UseTypeMode); StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); StartingAbilityPickerAPI.SetStartingItemCount(SharedRuntimeSettings.ItemCount); StartingAbilityPickerAPI.SetResetSeedWorld(SharedRuntimeSettings.ResetSeedWorld); StartingAbilityPickerAPI.SetFullRandomMode(SharedRuntimeSettings.FullRandomMode); StartingAbilityPickerAPI.SetCrestCurseEnabled(SharedRuntimeSettings.CrestCurseEnabled); StartingAbilityPickerAPI.SetForceCompletionDisplay(SharedRuntimeSettings.ForceCompletionDisplay); StartingAbilityPickerAPI.SetMovementPermissions(new DirectionPermissions { DashLeft = SharedRuntimeSettings.DashLeft, DashRight = SharedRuntimeSettings.DashRight, HarpoonLeft = SharedRuntimeSettings.HarpoonLeft, HarpoonRight = SharedRuntimeSettings.HarpoonRight, FloatLeft = SharedRuntimeSettings.FloatLeft, FloatRight = SharedRuntimeSettings.FloatRight, WallJumpLeft = SharedRuntimeSettings.WallJumpLeft, WallJumpRight = SharedRuntimeSettings.WallJumpRight, AllowHeal = SharedRuntimeSettings.AllowHeal }); RoomRandomMode.ResetPending(); try { GlobalConfig.FullRandomMode.Value = false; GlobalConfig.Heal.Value = false; GlobalConfig.Swim.Value = false; GlobalConfig.ColdResist.Value = false; GlobalConfig.Save(); Plugin.Log.LogInfo((object)"[ResetProfile] 已重置全部权限配置并写回 cfg(攻击开、移动/回血/游泳/抗寒关、全随机关)"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[ResetProfile] 重置写回 cfg 失败: {arg}"); } } private static void DrawAttackDirection(Plugin p, bool alreadyChosen) { GUILayout.Label(Locale.Get("攻击方向选择:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUILayout.Space(5f); GUI.enabled = false; DrawModeButton("下劈 (默认)", true, 18, GUILayout.Width(220f), GUILayout.Height(60f)); GUI.enabled = !alreadyChosen && !SharedRuntimeSettings.FullRandomMode; bool flag = DrawModeButton(Locale.Get("上劈"), SharedRuntimeSettings.AttackUp, 18, GUILayout.Width(220f), GUILayout.Height(60f)); if (flag != SharedRuntimeSettings.AttackUp && !alreadyChosen) { SharedRuntimeSettings.AttackUp = flag; StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); GlobalConfig.Save(); } bool flag2 = DrawModeButton(Locale.Get("左劈"), SharedRuntimeSettings.AttackLeft, 18, GUILayout.Width(220f), GUILayout.Height(60f)); if (flag2 != SharedRuntimeSettings.AttackLeft && !alreadyChosen) { SharedRuntimeSettings.AttackLeft = flag2; StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); GlobalConfig.Save(); } bool flag3 = DrawModeButton(Locale.Get("右劈"), SharedRuntimeSettings.AttackRight, 18, GUILayout.Width(220f), GUILayout.Height(60f)); if (flag3 != SharedRuntimeSettings.AttackRight && !alreadyChosen) { SharedRuntimeSettings.AttackRight = flag3; StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); GlobalConfig.Save(); } GUI.enabled = true; } private static void DrawSkillModeButtons(Plugin p, bool alreadyChosen) { //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(Locale.Get("技能随机模式:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); bool flag = !SharedRuntimeSettings.UseTypeMode; if (DrawModeButton(Locale.Get("总随机"), flag, 18, GUILayout.Width(130f), GUILayout.Height(60f)) != flag && !alreadyChosen) { SharedRuntimeSettings.UseTypeMode = false; StartingAbilityPickerAPI.SetSkillRandomMode(SharedRuntimeSettings.UseTypeMode); GlobalConfig.Save(); } bool useTypeMode = SharedRuntimeSettings.UseTypeMode; if (DrawModeButton(Locale.Get("分类随机"), useTypeMode, 18, GUILayout.Width(130f), GUILayout.Height(60f)) != useTypeMode && !alreadyChosen) { SharedRuntimeSettings.UseTypeMode = true; StartingAbilityPickerAPI.SetSkillRandomMode(SharedRuntimeSettings.UseTypeMode); GlobalConfig.Save(); } GUI.enabled = !alreadyChosen && !SharedRuntimeSettings.FullRandomMode; if (DrawModeButton(Locale.Get("彻底疯狂"), false, 18, GUILayout.Width(160f), GUILayout.Height(60f)) && !alreadyChosen) { CrazyRandomizer.Apply(); SharedRuntimeSettings.AttackUp = Plugin.allowUpward; SharedRuntimeSettings.AttackLeft = Plugin.allowLeft; SharedRuntimeSettings.AttackRight = Plugin.allowRight; SharedRuntimeSettings.UseTypeMode = Plugin.skillMode; SharedRuntimeSettings.SkillVertical = Plugin.skillV; SharedRuntimeSettings.SkillHorizontal = Plugin.skillH; SharedRuntimeSettings.SkillSpecial = Plugin.skillS; SharedRuntimeSettings.SkillAttack = Plugin.skillA; SharedRuntimeSettings.ItemCount = Plugin.itemCount; StartingAbilityPickerAPI.SetAttackPermissions(SharedRuntimeSettings.AttackUp, SharedRuntimeSettings.AttackLeft, SharedRuntimeSettings.AttackRight); StartingAbilityPickerAPI.SetSkillRandomMode(SharedRuntimeSettings.UseTypeMode); StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); StartingAbilityPickerAPI.SetStartingItemCount(SharedRuntimeSettings.ItemCount); GlobalConfig.Save(); } GUI.enabled = true; bool isPending = RoomRandomMode.IsPending; if (DrawModeButton(Locale.Get("丝之心、疾跑和上冲"), isPending, 14, GUILayout.Width(160f), GUILayout.Height(60f)) != isPending && !alreadyChosen) { RoomRandomMode.Toggle(); } GUILayout.EndHorizontal(); GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUI.enabled = !alreadyChosen; bool flag2 = DrawModeButton(Locale.Get("全随机模式"), SharedRuntimeSettings.FullRandomMode, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag2 != SharedRuntimeSettings.FullRandomMode && !alreadyChosen) { SharedRuntimeSettings.FullRandomMode = flag2; StartingAbilityPickerAPI.SetFullRandomMode(SharedRuntimeSettings.FullRandomMode); DirectionPermissions movementPermissions = StartingAbilityPickerAPI.GetMovementPermissions(); movementPermissions.AllowHeal = !flag2; StartingAbilityPickerAPI.SetMovementPermissions(movementPermissions); GlobalConfig.Save(); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.Space(10f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); bool flag3 = DrawModeButton(Locale.Get("纹章诅咒"), SharedRuntimeSettings.CrestCurseEnabled, 18, GUILayout.Width(160f), GUILayout.Height(60f)); if (flag3 != SharedRuntimeSettings.CrestCurseEnabled && !alreadyChosen) { SharedRuntimeSettings.CrestCurseEnabled = flag3; StartingAbilityPickerAPI.SetCrestCurseEnabled(SharedRuntimeSettings.CrestCurseEnabled); GlobalConfig.Save(); } bool flag4 = DrawModeButton(Locale.Get("完成度"), SharedRuntimeSettings.ForceCompletionDisplay, 18, GUILayout.Width(160f), GUILayout.Height(60f)); if (flag4 != SharedRuntimeSettings.ForceCompletionDisplay && !alreadyChosen) { SharedRuntimeSettings.ForceCompletionDisplay = flag4; StartingAbilityPickerAPI.SetForceCompletionDisplay(SharedRuntimeSettings.ForceCompletionDisplay); GlobalConfig.Save(); } GUI.enabled = true; GUILayout.EndHorizontal(); if (SharedRuntimeSettings.CrestCurseEnabled) { GUILayout.Space(5f); GUI.color = Color.yellow; GUILayout.Label(Locale.Get("启用纹章诅咒(每个纹章带有偏科效果)"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUI.color = BrightWhite; } } private static void DrawTotalSlider(Plugin p, bool alreadyChosen) { GUILayout.Label(Locale.Get("开局随机技能总数量:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(SharedRuntimeSettings.SkillTotal.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(35f), GUILayout.Height(40f) }); int num = (int)GUILayout.HorizontalSlider((float)SharedRuntimeSettings.SkillTotal, 0f, 13f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (num != SharedRuntimeSettings.SkillTotal && !alreadyChosen) { SharedRuntimeSettings.SkillTotal = num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); GlobalConfig.Save(); } GUILayout.EndHorizontal(); GUILayout.Space(10f); } private static void DrawCategorySliders(Plugin p, bool alreadyChosen) { GUILayout.Label(Locale.Get("分类随机数量:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); DrawOneSlider(Locale.Get("垂直技能"), ref SharedRuntimeSettings.SkillVertical, Plugin.MaxVerticalDynamic, alreadyChosen); DrawOneSlider(Locale.Get("水平技能"), ref SharedRuntimeSettings.SkillHorizontal, Plugin.MaxHorizontalDynamic, alreadyChosen); DrawOneSlider(Locale.Get("特殊技能"), ref SharedRuntimeSettings.SkillSpecial, Plugin.MaxSpecialDynamic, alreadyChosen); DrawOneSlider(Locale.Get("攻击技能"), ref SharedRuntimeSettings.SkillAttack, Plugin.MaxAttackDynamic, alreadyChosen); } private static void DrawOneSlider(string label, ref int value, int max, bool disabled) { GUILayout.Label($"{label} (0-{max})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(value.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(35f), GUILayout.Height(40f) }); int num = (int)GUILayout.HorizontalSlider((float)value, 0f, (float)max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (num != value && !disabled) { value = num; StartingAbilityPickerAPI.SetSkillCounts(SharedRuntimeSettings.SkillTotal, SharedRuntimeSettings.SkillVertical, SharedRuntimeSettings.SkillHorizontal, SharedRuntimeSettings.SkillSpecial, SharedRuntimeSettings.SkillAttack); GlobalConfig.Save(); } GUILayout.EndHorizontal(); } private static void DrawItemSlider(Plugin p, bool alreadyChosen) { GUILayout.Label(Locale.Get("开局随机物品数量:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(SharedRuntimeSettings.ItemCount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(35f), GUILayout.Height(40f) }); int num = (int)GUILayout.HorizontalSlider((float)SharedRuntimeSettings.ItemCount, 0f, 10f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (num != SharedRuntimeSettings.ItemCount && !alreadyChosen) { SharedRuntimeSettings.ItemCount = num; StartingAbilityPickerAPI.SetStartingItemCount(SharedRuntimeSettings.ItemCount); GlobalConfig.Save(); } GUILayout.EndHorizontal(); } private static void DrawSeedInput(Plugin p, bool alreadyChosen) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(Locale.Get("种子"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(60f), GUILayout.Height(40f) }); string text = SharedRuntimeSettings.Seed.ToString(); string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(160f), GUILayout.Height(40f) }); if (text2 != text && !alreadyChosen && int.TryParse(text2, out var result)) { SharedRuntimeSettings.Seed = result; StartingAbilityPickerAPI.SetSeed(SharedRuntimeSettings.Seed); GlobalConfig.Save(); } GUILayout.EndHorizontal(); GUILayout.Space(5f); bool resetSeedWorld = SharedRuntimeSettings.ResetSeedWorld; GUI.color = (resetSeedWorld ? Color.red : BrightWhite); bool flag = GUILayout.Toggle(resetSeedWorld, Locale.Get("重置种子世界(含技能触发器)"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); if (flag != resetSeedWorld && !alreadyChosen) { SharedRuntimeSettings.ResetSeedWorld = flag; StartingAbilityPickerAPI.SetResetSeedWorld(SharedRuntimeSettings.ResetSeedWorld); GlobalConfig.Save(); } GUI.color = BrightWhite; if (resetSeedWorld) { GUI.color = Color.yellow; GUILayout.Label(Locale.Get("警告:重置后当前种子世界将重新生成,所有拾取点会重生,技能触发器也会重置。"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(70f) }); GUI.color = BrightWhite; } GUILayout.Space(35f); } private static void DrawConfirmAndClose(Plugin p, bool alreadyChosen) { //IL_0009: 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_0069: 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) GUI.enabled = !alreadyChosen; GUI.backgroundColor = Color.green; if (GUILayout.Button(Locale.Get("确认"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(50f) }) && !alreadyChosen) { StartingAbilityPickerAPI.ApplyPending(); p.ApplySettings(); GlobalConfig.Save(); } GUI.backgroundColor = Color.white; GUI.enabled = true; GUI.backgroundColor = new Color(0.8f, 0.2f, 0.2f); if (GUILayout.Button(Locale.Get("关闭"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) })) { p.ShowUI = false; } GUI.backgroundColor = Color.white; } private static void DrawSceneToggle(Plugin p) { bool flag = StartingAbilityPickerAPI.IsRoomRandomizationEnabled(); bool flag2 = DrawModeButton(Locale.Get("启用场景随机"), flag, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag2 != flag) { StartingAbilityPickerAPI.SetRoomRandomizationEnabled(flag2); GlobalConfig.Save(); } } private static void DrawTrapToggle(Plugin p) { bool flag = SilksongItemRandomizerAPI.IsTrapEnabled(); bool flag2 = DrawModeButton(Locale.Get("启用陷阱随机"), flag, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag2 != flag) { SilksongItemRandomizerAPI.SetTrapEnabled(flag2); if (flag2) { SilksongItemRandomizerAPI.RegenerateTrapsNow(); } else { SilksongItemRandomizerAPI.SetTrapEnabled(false); } GlobalConfig.Save(); } } private static void DrawItemRandomToggle(Plugin p) { bool itemRandomEnabled = p.GetItemRandomEnabled(); bool flag = DrawModeButton(Locale.Get("启用物品随机"), itemRandomEnabled, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag != itemRandomEnabled) { p.SetItemRandomEnabled(flag); } } private static void DrawTrapDifficulty(Plugin p) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(Locale.Get("陷阱难度:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Sprite[] array = (Sprite[])(object)new Sprite[3] { Plugin.BeginnerIcon, Plugin.FocusedIcon, Plugin.OverflowIcon }; string[] array2 = new string[3] { "初猎", "专注", "满溢" }; float num = 50f; Rect rect; if ((Object)(object)Plugin.OverflowIcon != (Object)null && (Object)(object)Plugin.OverflowIcon.texture != (Object)null) { rect = Plugin.OverflowIcon.rect; float width = ((Rect)(ref rect)).width; rect = Plugin.OverflowIcon.rect; float height = ((Rect)(ref rect)).height; num = 90f * (height / width); } EnsureStyles(); Rect val2 = default(Rect); for (int i = 0; i < 3; i++) { bool flag = SilksongItemRandomizerAPI.GetTrapDifficulty() == i; Sprite val = array[i]; Rect rect2 = GUILayoutUtility.GetRect(90f, num, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(90f), GUILayout.Height(num) }); Color backgroundColor = (flag ? new Color(0.2f, 1f, 0.2f) : new Color(0.6f, 0.6f, 0.6f)); Color backgroundColor2 = GUI.backgroundColor; GUI.backgroundColor = backgroundColor; GUI.Box(rect2, ""); GUI.backgroundColor = backgroundColor2; if ((Object)(object)((val != null) ? val.texture : null) != (Object)null) { rect = val.rect; float width2 = ((Rect)(ref rect)).width; rect = val.rect; float height2 = ((Rect)(ref rect)).height; float num2; float num3; float num4; float num5; if (i == 0) { num2 = ((Rect)(ref rect2)).height; num3 = num2 * (width2 / height2); num4 = ((Rect)(ref rect2)).x + (((Rect)(ref rect2)).width - num3) / 2f; num5 = ((Rect)(ref rect2)).y; } else { num3 = 90f; num2 = num3 * (height2 / width2); num4 = ((Rect)(ref rect2)).x + (((Rect)(ref rect2)).width - num3) / 2f; num5 = ((Rect)(ref rect2)).y + (((Rect)(ref rect2)).height - num2) / 2f; } GUI.DrawTexture(new Rect(num4, num5, num3, num2), (Texture)(object)val.texture, (ScaleMode)0); } if (GUI.Button(rect2, "", GUIStyle.none)) { SilksongItemRandomizerAPI.SetTrapDifficulty(i); if (SilksongItemRandomizerAPI.IsTrapEnabled()) { SilksongItemRandomizerAPI.RegenerateTrapsNow(); } GlobalConfig.Save(); } ((Rect)(ref val2))..ctor(((Rect)(ref rect2)).x, ((Rect)(ref rect2)).y, ((Rect)(ref rect2)).width, ((Rect)(ref rect2)).height / 2f); Rect val3 = new Rect(((Rect)(ref rect2)).x, ((Rect)(ref rect2)).y + ((Rect)(ref rect2)).height / 2f, ((Rect)(ref rect2)).width, ((Rect)(ref rect2)).height / 2f); GUI.Label(val2, Locale.Get(array2[i]), _diffTitleStyle); GUI.Label(val3, flag ? Locale.Get("[开]") : Locale.Get("[关]"), _diffStatusStyle); } GUILayout.EndHorizontal(); GUILayout.Space(5f); } private static void DrawTrapMovementToggle(Plugin p) { bool flag = SilksongItemRandomizerAPI.IsTrapMovementEnabled(); bool flag2 = DrawModeButton(Locale.Get("陷阱生命化"), flag, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag2 != flag) { SilksongItemRandomizerAPI.SetTrapMovementEnabled(flag2); if (SilksongItemRandomizerAPI.IsTrapEnabled()) { SilksongItemRandomizerAPI.RegenerateTrapsNow(); } GlobalConfig.Save(); } } private static void DrawEnemyRandoAdjustToggle(Plugin p) { bool value = Plugin.EnemyRandoAdjustEnabled.Value; bool flag = DrawModeButton(Locale.Get("启用怪物随机"), value, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag != value) { p.SetEnemyRandoAdjustEnabled(flag); GlobalConfig.Save(); } } private static void DrawBackgroundToggle(Plugin p) { bool value = Plugin.PanelBackgroundEnabled.Value; bool flag = DrawModeButton(Locale.Get("面板背景"), value, 18, GUILayout.Width(260f), GUILayout.Height(60f)); if (flag != value) { p.SetPanelBackgroundEnabled(flag); GlobalConfig.Save(); } } private static void DrawSeedChanger(Plugin p) { //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown GUILayout.Label(Locale.Get("修改种子:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) }); string text = GUILayout.TextField(p.SceneSeedInput, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(260f), GUILayout.Height(30f) }); if (string.IsNullOrEmpty(text) && GUI.GetNameOfFocusedControl() != "SeedTextField") { Rect lastRect = GUILayoutUtility.GetLastRect(); GUI.SetNextControlName("SeedTextField"); Color color = GUI.color; GUI.color = Color.yellow; if (_seedPlaceholderStyle == null) { _seedPlaceholderStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14 }; } GUI.Label(lastRect, Locale.Get("直接应用可随机"), _seedPlaceholderStyle); GUI.color = color; } else { GUI.SetNextControlName("SeedTextField"); } p.SceneSeedInput = text; GUILayout.Space(4f); GUI.backgroundColor = Color.green; if (GUILayout.Button(Locale.Get("应用种子"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(32f), GUILayout.Width(260f) })) { string text2 = p.SceneSeedInput.Trim(); int result; if (string.IsNullOrEmpty(text2)) { result = new Random().Next(1, int.MaxValue); } else if (!int.TryParse(text2, out result)) { return; } try { object seedManager = p.SeedManager; object obj = seedManager.GetType().GetField("cfgNewSeed", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(seedManager); object obj2 = seedManager.GetType().GetField("cfgRegenerateTrigger", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(seedManager); obj.GetType().GetProperty("Value").SetValue(obj, result, null); obj2.GetType().GetProperty("Value").SetValue(obj2, true, null); Plugin.ShowNotification(Locale.Get("场景连接已重新生成")); if (SilksongItemRandomizerAPI.IsTrapEnabled()) { SilksongItemRandomizerAPI.SetSeed(result); SilksongItemRandomizerAPI.RegenerateTrapsNow(); } } catch (Exception arg) { Plugin.Log.LogError((object)$"场景种子更新失败: {arg}"); } } GUI.backgroundColor = Color.white; } private static void DrawTeleporter(Plugin p) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label(Locale.Get("场景传送:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) }); p.SceneTeleportInput = GUILayout.TextField(p.SceneTeleportInput, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(260f), GUILayout.Height(30f) }); GUILayout.Space(4f); GUI.backgroundColor = Color.green; if (GUILayout.Button(Locale.Get("传送"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(32f), GUILayout.Width(260f) }) && !string.IsNullOrWhiteSpace(p.SceneTeleportInput)) { p.PendingTeleport = true; p.PendingTeleportScene = p.SceneTeleportInput; p.ShowUI = false; Plugin.ShowNotification(Locale.Get("稍后传送至") + p.SceneTeleportInput + " ..."); } GUI.backgroundColor = Color.white; } private static void DrawDisplayToggles(Plugin p) { //IL_0044: 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_008b: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) bool showSceneLabel = p.GetShowSceneLabel(); bool showSeedLabel = p.GetShowSeedLabel(); GUILayout.Label(Locale.Get("显示选项:"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) }); GUILayout.Space(4f); GUI.color = (showSceneLabel ? Color.green : BrightWhite); if (GUILayout.Toggle(showSceneLabel, Locale.Get("显示当前场景名"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { if (!showSceneLabel) { p.SetShowSceneLabel(value: true); } } else if (showSceneLabel) { p.SetShowSceneLabel(value: false); } GUI.color = BrightWhite; GUILayout.Space(6f); GUI.color = (showSeedLabel ? Color.green : BrightWhite); if (GUILayout.Toggle(showSeedLabel, Locale.Get("显示当前种子"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { if (!showSeedLabel) { p.SetShowSceneLabel(value: true, isSeed: true); } } else if (showSeedLabel) { p.SetShowSceneLabel(value: false, isSeed: true); } GUI.color = BrightWhite; } private static bool DrawModeButton(string label, bool isOn, int titleFontSize = 18, params GUILayoutOption[] options) { //IL_0042: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0095: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c5: Expected O, but got Unknown string text = (isOn ? Locale.Get("[开]") : Locale.Get("[关]")); Color backgroundColor = (isOn ? new Color(0.2f, 1f, 0.2f) : new Color(0.6f, 0.6f, 0.6f)); Color backgroundColor2 = GUI.backgroundColor; GUI.backgroundColor = backgroundColor; bool num = GUILayout.Button("", options); Rect lastRect = GUILayoutUtility.GetLastRect(); EnsureStyles(); if (!_titleStyleCache.TryGetValue(titleFontSize, out var value)) { Dictionary<int, GUIStyle> titleStyleCache = _titleStyleCache; GUIStyle val = new GUIStyle(_titleStyle) { fontSize = titleFontSize }; value = val; titleStyleCache[titleFontSize] = val; } if (!_statusStyleCache.TryGetValue(titleFontSize, out var value2)) { Dictionary<int, GUIStyle> statusStyleCache = _statusStyleCache; GUIStyle val2 = new GUIStyle(_statusStyle) { fontSize = titleFontSize - 3 }; value2 = val2; statusStyleCache[titleFontSize] = val2; } GUI.Label(new Rect(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y, ((Rect)(ref lastRect)).width, ((Rect)(ref lastRect)).height / 2f), label, value); GUI.Label(new Rect(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y + ((Rect)(ref lastRect)).height / 2f, ((Rect)(ref lastRect)).width, ((Rect)(ref lastRect)).height / 2f), text, value2); GUI.backgroundColor = backgroundColor2; if (!num) { return isOn; } return !isOn; } } [BepInPlugin("HardItemRandomizer.StartingAbilityPicker", "Starting Ability Picker", "1.0.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; public static bool AllowLeftAttack = false; public static bool AllowRightAttack = false; public static bool AllowUpwardAttack = false; public static bool DirectionEnabled = true; public static bool AllowDashLeft = false; public static bool AllowDashRight = false; public static bool AllowHarpoonLeft = false; public static bool AllowHarpoonRight = false; public static bool AllowFloatLeft = false; public static bool AllowFloatRight = false; public static bool AllowWallJumpLeft = false; public static bool AllowWallJumpRight = false; public static bool AllowHeal = false; public static bool skillMode = false; public static int skillTotal = 0; public static int skillV = 0; public static int skillH = 0; public static int skillS = 0; public static int skillA = 0; public const int MaxVertical = 5; public const int MaxHorizontal = 4; public const int MaxSpecial = 4; public const int MaxAttack = 5; private bool _lastSceneWasMenu = true; private bool showUI; public static bool allowUpward = false; public static bool allowLeft = false; public static bool allowRight = false; public static int itemCount = 0; public static bool resetPickups = false; public static string seedInput = ""; internal static HashSet<int> chosenProfileSet = new HashSet<int>(); private static string _notificationMessage = null; private static float _notificationEndTime = 0f; private static GUIStyle _notificationStyle; private static Sprite _backgroundSprite; private static Sprite _beginnerIcon; private static Sprite _focusedIcon; private static Sprite _overflowIcon; private static bool _bgLoaded = false; private static Rect _windowRect; private static float _lastScreenHeight; public static bool crestCurseEnabled = false; public static ConfigEntry<bool> CfgAllowDashLeft; public static ConfigEntry<bool> CfgAllowDashRight; public static ConfigEntry<bool> CfgAllowHarpoonLeft; public static ConfigEntry<bool> CfgAllowHarpoonRight; public static ConfigEntry<bool> CfgAllowFloatLeft; public static ConfigEntry<bool> CfgAllowFloatRight; public static ConfigEntry<bool> CfgAllowWallJumpLeft; public static ConfigEntry<bool> CfgAllowWallJumpRight; public static ConfigEntry<bool> CfgAllowHeal; private static readonly WaitForSeconds HalfSecondWait = new WaitForSeconds(0.5f); public bool _pendingApply; public int _pendingSkillTotal; public int _pendingSkillV; public int _pendingSkillH; public int _pendingSkillS; public int _pendingSkillA; public bool _pendingSkillMode; public int _pendingItemCount; private bool _sceneRandomAvailable; private Type _sceneLoaderType; private Type _roomRandoType; private Type _seedManagerType; private object _sceneLoader; private object _roomRando; private object _seedManager; private FieldInfo _cfgShowSceneLabelField; private FieldInfo _currentSceneNameField; private MethodInfo _getSeedMethod; private string sceneSeedInput = ""; private string sceneTeleportInput = ""; private bool _pendingTeleport; private string _pendingTeleportScene = ""; private bool _apiInitialized; private static bool _hasLoadedFromSaveData = false; private static FieldInfo _currentSeedField; private static FieldInfo _enableRandomizationField; private static PropertyInfo _publicItemRandomProp; public static Plugin Instance { get; private set; } public static ConfigEntry<bool> UseNativeSkillGiving { get; private set; } public static ConfigEntry<string> ChosenProfiles { get; private set; } public static ConfigEntry<int> StartingSkillCount { get; private set; } public static ConfigEntry<int> StartingItemCount { get; private set; } public static ConfigEntry<int> RandomSeed { get; private set; } public static ConfigEntry<bool> CfgCrestCurseEnabled { get; private set; } public static ConfigEntry<bool> EnemyRandoAdjustEnabled { get; private set; } public static ConfigEntry<bool> PanelBackgroundEnabled { get; private set; } public static ConfigEntry<bool> CfgDirectionEnabled { get; private set; } public static ConfigEntry<bool> CfgFullRandomMode { get; private set; } public bool ShowUI { get { return showUI; } set { showUI = value; } } public string SceneSeedInput { get { return sceneSeedInput; } set { sceneSeedInput = value; } } public string SceneTeleportInput { get { return sceneTeleportInput; } set { sceneTeleportInput = value; } } public bool PendingTeleport { get { return _pendingTeleport; } set { _pendingTeleport = value; } } public string PendingTeleportScene { get { return _pendingTeleportScene; } set { _pendingTeleportScene = value; } } public object SeedManager => _seedManager; public bool SceneRandomAvailable => _sceneRandomAvailable; public static int MaxVerticalDynamic => 5; public static int MaxHorizontalDynamic => 4; public static int MaxSpecialDynamic => 4; public static int MaxAttackDynamic => 5; public static Sprite BeginnerIcon => _beginnerIcon; public static Sprite FocusedIcon => _focusedIcon; public static Sprite OverflowIcon => _overflowIcon; public static bool FullRandomModeEnabled { get { return DirectionPatch.FullRandomMode; } set { DirectionPatch.FullRandomMode = value; } } private int currentProfileID => PlayerData.instance?.profileID ?? (-1); public void SetPendingOpeningSettings(bool skillMode, int skillTotal, int skillV, int skillH, int skillS, int skillA, int itemCount) { _pendingSkillMode = skillMode; _pendingSkillTotal = skillTotal; _pendingSkillV = skillV; _pendingSkillH = skillH; _pendingSkillS = skillS; _pendingSkillA = skillA; _pendingItemCount = itemCount; _pendingApply = true; } public static void ShowNotification(string message, float duration = 3f) { _notificationMessage = message; _notificationEndTime = Time.time + duration; } private Texture2D MakeTexture(int width, int height, Color col) { //IL_000f: 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_0021: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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 bool GetCrestCurseEnabled() { return crestCurseEnabled; } public static void SetCrestCurseEnabled(bool value) { crestCurseEnabled = value; CfgCrestCurseEnabled.Value = value; try { Type.GetType("SilksongItemRandomizer.ToolEffectRandomizer, SilksongItemRandomizer")?.GetMethod("SetEnabled", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { value }); } catch { } Log.LogInfo((object)("纹章诅咒开关: " + (value ? "启用" : "禁用"))); } public static void SetFullRandomMode(bool enabled) { DirectionPatch.FullRandomMode = enabled; } public void SetForceCompletionDisplay(bool value) { int num = currentProfileID; if (num == -1 || GetForceCompletionDisplay() == value) { return; } Plugin.SaveData.ProfileCompletionDisplay[num] = value; Plugin.SaveGlobalData(); Log.LogInfo((object)string.Format("强制完成度显示开关 (存档 {0}): {1}", num, value ? "启用(显示)" : "禁用(隐藏)")); PlayerData instance = PlayerData.instance; if (instance != null) { if (value) { instance.ConstructedFarsight = true; RefreshCompletionUI(forceShow: true); } else { ClearFsmCompletionVariables(); } } GlobalConfig.Save(); } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"StartingAbilityPicker loaded! Press F7 to open starting options."); ChosenProfiles = GlobalConfig.ChosenProfiles; StartingSkillCount = GlobalConfig.StartingSkillCount; StartingItemCount = GlobalConfig.StartingItemCount; RandomSeed = GlobalConfig.RandomSeed; CfgCrestCurseEnabled = GlobalConfig.CrestCurseEnabled; crestCurseEnabled = CfgCrestCurseEnabled.Value; AllowUpwardAttack = GlobalConfig.AttackUp.Value; AllowLeftAttack = GlobalConfig.AttackLeft.Value; AllowRightAttack = GlobalConfig.AttackRight.Value; SharedRuntimeSettings.AttackUp = AllowUpwardAttack; SharedRuntimeSettings.AttackLeft = AllowLeftAttack; SharedRuntimeSettings.AttackRight = AllowRightAttack; _hasLoadedFromSaveData = true; Log.LogInfo((object)$"从 cfg 加载攻击方向: Up={AllowUpwardAttack}, Left={AllowLeftAttack}, Right={AllowRightAttack}"); try { Type.GetType("SilksongItemRandomizer.ToolEffectRandomizer, SilksongItemRandomizer")?.GetMethod("SetEnabled", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { crestCurseEnabled }); } catch { } EnemyRandoAdjustEnabled = GlobalConfig.EnemyRandoAdjustEnabled; try { Type type = Type.GetType("SilksongItemRandomizer.EnemyRandoAdjuster, SilksongItemRandomizer"); if (type != null) { PropertyInfo property = type.GetProperty("Enabled", BindingFlags.Static | BindingFlags.Public); if (property != null) { property.SetValue(null, EnemyRandoAdjustEnabled.Value); } } } catch (Exception arg) { Log.LogError((object)$"同步怪物调整开关失败: {arg}"); } PanelBackgroundEnabled = GlobalConfig.PanelBackgroundEnabled; UseNativeSkillGiving = GlobalConfig.UseNativeSkillGiving; SkillRandomizer.UseNativeItemGiving = UseNativeSkillGiving.Value; CfgDirectionEnabled = GlobalConfig.DirectionEnabled; DirectionEnabled = CfgDirectionEnabled.Value; CfgAllowDashLeft = GlobalConfig.DashLeft; CfgAllowDashRight = GlobalConfig.DashRight; CfgAllowHarpoonLeft = GlobalConfig.HarpoonLeft; CfgAllowHarpoonRight = GlobalConfig.HarpoonRight; CfgAllowFloatLeft = GlobalConfig.FloatLeft; CfgAllowFloatRight = GlobalConfig.FloatRight; CfgAllowWallJumpLeft = GlobalConfig.WallJumpLeft; CfgAllowWallJumpRight = GlobalConfig.WallJumpRight; CfgAllowHeal = GlobalConfig.Heal; AllowDashLeft = CfgAllowDashLeft.Value; AllowDashRight = CfgAllowDashRight.Value; AllowHarpoonLeft = CfgAllowHarpoonLeft.Value; AllowHarpoonRight = CfgAllowHarpoonRight.Value; AllowFloatLeft = CfgAllowFloatLeft.Value; AllowFloatRight = CfgAllowFloatRight.Value; AllowWallJumpLeft = CfgAllowWallJumpLeft.Value; AllowWallJumpRight = CfgAllowWallJumpRight.Value; AllowHeal = CfgAllowHeal.Value; CfgFullRandomMode = GlobalConfig.FullRandomMode; DirectionPatch.FullRandomMode = CfgFullRandomMode.Value; SharedRuntimeSettings.UseTypeMode = GlobalConfig.UseTypeMode.Value; SharedRuntimeSettings.SkillTotal = GlobalConfig.StartingSkillCount.Value; SharedRuntimeSettings.SkillVertical = GlobalConfig.SkillVertical.Value; SharedRuntimeSettings.SkillHorizontal = GlobalConfig.SkillHorizontal.Value; SharedRuntimeSettings.SkillSpecial = GlobalConfig.SkillSpecial.Value; SharedRuntimeSettings.SkillAttack = GlobalConfig.SkillAttack.Value; SharedRuntimeSettings.ItemCount = GlobalConfig.StartingItemCount.Value; SharedRuntimeSettings.ForceCompletionDisplay = GlobalConfig.ForceCompletionDisplay.Value; SharedRuntimeSettings.ResetSeedWorld = GlobalConfig.ResetSeedWorld.Value; LoadChosenProfiles(); EnsureRandomSeed(); SceneManager.sceneLoaded += OnSceneLoaded; Harmony.CreateAndPatchAll(typeof(DirectionPatch), (string)null); Harmony.CreateAndPatchAll(typeof(AbilityGatePatch), (string)null); Harmony.CreateAndPatchAll(typeof(DirectionPopupHelper), (string)null); Harmony.CreateAndPatchAll(typeof(SaveStats_GetCompletionPercentage_Patch), (string)null); Harmony.CreateAndPatchAll(typeof(SaveStats_UnlockedCompletionRate_Patch), (string)null); Harmony.CreateAndPatchAll(typeof(PlayerData_CountGameCompletion_Patch), (string)null); Harmony.CreateAndPatchAll(typeof(ConvertFloatToString_Patch), (string)null); Harmony.CreateAndPatchAll(typeof(BuildString_Patch), (string)null); ((MonoBehaviour)this).StartCoroutine(LoadAllImages()); InitSceneRandomRefs(); StartingAbilityPickerAPI.Initialize(new StartingAbilityPickerConfig { Seed = RandomSeed.Value, FullRandomMode = CfgFullRandomMode.Value, MovementPermissions = new DirectionPermissions { DashLeft = AllowDashLeft, DashRight = AllowDashRight, HarpoonLeft = AllowHarpoonLeft, HarpoonRight = AllowHarpoonRight, FloatLeft = AllowFloatLeft, FloatRight = AllowFloatRight, WallJumpLeft = AllowWallJumpLeft, WallJumpRight = AllowWallJumpRight, AllowHeal = AllowHeal }, CrestCurseEnabled = crestCurseEnabled, ForceCompletionDisplay = GetForceCompletionDisplay(), UseNativeSkillGiving = UseNativeSkillGiving.Value, PanelBackgroundEnabled = PanelBackgroundEnabled.Value, DefaultStartingItemCount = StartingItemCount.Value, DefaultSkillTotal = StartingSkillCount.Value, DefaultSkillV = 0, DefaultSkillH = 0, DefaultSkillS = 0, DefaultSkillA = 0, DefaultSkillTypeMode = false, DefaultResetPickups = false, DefaultAttackPermissions = (up: AllowUpwardAttack, left: AllowLeftAttack, right: AllowRightAttack), DisableBuiltinShortcut = false }); _apiInitialized = true; } private IEnumerator LoadAllImages() { string folder = Path.Combine(Paths.PluginPath, "elesanren-Hard_Item_Randomizer", "nandu"); string text = Path.Combine(folder, "4.png"); if (File.Exists(text)) { WWW www = new WWW("file://" + text); try { yield return www; if (string.IsNullOrEmpty(www.error) && (Object)(object)www.texture != (Object)null) { _backgroundSprite = Sprite.Create(www.texture, new Rect(0f, 0f, (float)((Texture)www.texture).width, (float)((Texture)www.texture).height), new Vector2(0.5f, 0.5f)); } } finally { ((IDisposable)www)?.Dispose(); } } string[] iconFiles = new string[3] { "1.png", "2.png", "3.png" }; for (int i = 0; i < 3; i++) { string text2 = Path.Combine(folder, iconFiles[i]); if (!File.Exists(text2)) { continue; } WWW www = new WWW("file://" + text2); try { yield return www; if (string.IsNullOrEmpty(www.error) && (Object)(object)www.texture != (Object)null) { Sprite val = Sprite.Create(www.texture, new Rect(0f, 0f, (float)((Texture)www.texture).width, (float)((Texture)www.texture).height), new Vector2(0.5f, 0.5f)); switch (i) { case 0: _beginnerIcon = val; break; case 1: _focusedIcon = val; break; case 2: _overflowIcon = val; break; } } } finally { ((IDisposable)www)?.Dispose(); } } _bgLoaded = true; } private void EnsureRandomSeed() { if (RandomSeed.Value == 0) { int num = (int)DateTime.UtcNow.Ticks ^ Environment.TickCount; if (num <= 0) { num = -num; } if (num <= 0) { num = 1; } RandomSeed.Value = num; GlobalConfig.Save(); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name != "Menu_Title" && ((Scene)(ref scene)).name != "Menu" && ((Scene)(ref scene)).name != "Loading" && (Object)(object)HeroController.instance != (Object)null) { AllowUpwardAttack = GlobalConfig.AttackUp.Value; AllowLeftAttack = GlobalConfig.AttackLeft.Value; AllowRightAttack = GlobalConfig.AttackRight.Value; SharedRuntimeSettings.AttackUp = AllowUpwardAttack; SharedRuntimeSettings.AttackLeft = AllowLeftAttack; SharedRuntimeSettings.AttackRight = AllowRightAttack; _hasLoadedFromSaveData = true; LoadPlayerDataSettings(); SharedRuntimeSettings.UseTypeMode = skillMode; SharedRuntimeSettings.SkillTotal = skillTotal; SharedRuntimeSettings.SkillVertical = skillV; SharedRuntimeSettings.SkillHorizontal = skillH; SharedRuntimeSettings.SkillSpecial = skillS; SharedRuntimeSettings.SkillAttack = skillA; SharedRuntimeSettings.ItemCount = StartingItemCount.Value; InitSceneRandomInstances(); if (GetForceCompletionDisplay()) { PlayerData instance = PlayerData.instance; if (instance != null && !instance.ConstructedFarsight) { instance.ConstructedFarsight = true; Log.LogInfo((object)$"已强制解锁完成度显示 (ConstructedFarsight) for profile {currentProfileID}"); } RefreshCompletionUI(forceShow: true); } Log.LogInfo((object)($"[OnSceneLoaded] 场景 '{((Scene)(ref scene)).name}' 加载完成, _pendingApply={_pendingApply}, " + $"total={_pendingSkillTotal}, V={_pendingSkillV}, H={_pendingSkillH}, S={_pendingSkillS}, A={_pendingSkillA}, items={_pendingItemCount}")); if (_pendingApply) { Log.LogInfo((object)"[OnSceneLoaded] _pendingApply=true, 启动 DelayedGiveAfterSceneLoad 协程"); ((MonoBehaviour)this).StartCoroutine(DelayedGiveAfterSceneLoad()); } else { Log.LogInfo((object)"[OnSceneLoaded] _pendingApply=false, 跳过给予流程"); } if (_apiInitialized) { StartingAbilityPickerAPI.MarkGameReady(); } } else if (((Scene)(ref scene)).name == "Menu_Title" || ((Scene)(ref scene)).name == "Menu") { _lastSceneWasMenu = true; } if (!GetForceCompletionDisplay()) { ClearFsmCompletionVariables(); } } private IEnumerator DelayedGiveAfterSceneLoad() { ManualLogSource log = Log; string[] obj = new string[5] { "[DelayedGiveAfterSceneLoad] 场景: ", null, null, null, null }; Scene activeScene = SceneManager.GetActiveScene(); obj[1] = ((Scene)(ref activeScene)).name; obj[2] = ", "; obj[3] = $"total={_pendingSkillTotal}, V={_pendingSkillV}, H={_pendingSkillH}, "; obj[4] = $"S={_pendingSkillS}, A={_pendingSkillA}, items={_pendingItemCount}"; log.LogInfo((object)string.Concat(obj)); float timeout = 15f; while (timeout > 0f && (PlayerData.instance == null || !((Object)(object)HeroController.instance != (Object)null) || !((Component)HeroController.instance).gameObject.activeInHierarchy)) { yield return null; timeout -= Time.deltaTime; } if (timeout <= 0f) { Log.LogWarning((object)"[DelayedGiveAfterSceneLoad] 等待超时,放弃给予"); _pendingApply = false; yield break; } yield return null; skillMode = _pendingSkillMode; skillTotal = _pendingSkillTotal; skillV = _pendingSkillV; skillH = _pendingSkillH; skillS = _pendingSkillS; skillA = _pendingSkillA; itemCount = _pendingItemCount; resetPickups = false; ApplySettings(); _pendingApply = false; } private void GivePendingSkillsAndItems() { Log.LogInfo((object)($"[GivePendingSkillsAndItems] 开始给予 — mode={_pendingSkillMode}, " + $"total={_pendingSkillTotal}, V={_pendingSkillV}, H={_pendingSkillH}, S={_pendingSkillS}, A={_pendingSkillA}, items={_pendingItemCount}")); if (!_pendingSkillMode) { for (int i = 0; i < _pendingSkillTotal; i++) { SkillRandomizer.GiveRandomSkill(); } } else { for (int j = 0; j < _pendingSkillV; j++) { SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.VerticalSkills); } for (int k = 0; k < _pendingSkillH; k++) { SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.HorizontalSkills); } for (int l = 0; l < _pendingSkillS; l++) { SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.SpecialSkills); } for (int m = 0; m < _pendingSkillA; m++) { SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.AttackSkills); } } for (int n = 0; n < _pendingItemCount; n++) { SavedItem randomItem = ItemRandomizer.GetRandomItem(); if ((Object)(object)randomItem != (Object)null) { randomItem.TryGet(false, true); } } RoomRandomMode.TryApply(); _pendingApply = false; showUI = false; Log.LogInfo((object)"技能和物品给予完成"); } private void LoadPlayerDataSettings() { try { PlayerData instance = PlayerData.instance; if (instance != null) { skillMode = instance.GetBool("SkillRandomMode"); skillTotal = instance.GetInt("SkillTotalCount"); skillV = instance.GetInt("SkillVerticalCount"); skillH = instance.GetInt("SkillHorizontalCount"); skillS = instance.GetInt("SkillSpecialCount"); skillA = instance.GetInt("SkillAttackCount"); if (!skillMode && skillTotal == 0) { skillTotal = StartingSkillCount.Value; } } } catch (Exception arg) { Log.LogError((object)$"加载技能随机设置失败: {arg}"); } } private void InitSceneRandomRefs() { _sceneRandomAvailable = false; try { _sceneLoaderType = Type.GetType("HKSilksong_Randomizer.RandomSceneLoader, HKSilksong_SceneRandomizer"); _roomRandoType = Type.GetType("HKSilksong_Randomizer.RoomRando, HKSilksong_SceneRandomizer"); _seedManagerType = Type.GetType("HKSilksong_Randomizer.SeedManager, HKSilksong_SceneRandomizer"); if (_sceneLoaderType == null || _roomRandoType == null || _seedManagerType == null) { Log.LogWarning((object)"场景随机模块类型未找到,右侧面板将不可用"); return; } _cfgShowSceneLabelField = _sceneLoaderType.GetField("cfgShowSceneLabel", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field = _sceneLoaderType.GetField("currentSceneName", BindingFlags.Instance | BindingFlags.NonPublic); _currentSceneNameField = field; MethodInfo method = _roomRandoType.GetMethod("GetGenerationSeed"); _getSeedMethod = method; _sceneRandomAvailable = true; Log.LogInfo((object)"场景随机模块可用(静态接口)"); } catch (Exception ex) { Log.LogWarning((object)("场景随机模块初始化失败: " + ex.Message)); } } private void InitSceneRandomInstances() { try { GameObject val = GameObject.Find("__RoomRando"); GameObject val2 = GameObject.Find("__SeedManager"); if ((Object)(object)val != (Object)null) { _roomRando = val.GetComponent(_roomRandoType); } if ((Object)(object)val2 != (Object)null) { _seedManager = val2.GetComponent(_seedManagerType); } if (_seedManager != null) { _sceneLoader = _seedManager.GetType().GetField("sceneLoader", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_seedManager); } } catch (Exception ex) { Log.LogWarning((object)("获取场景随机实例失败: " + ex.Message)); } } private void LoadChosenProfiles() { chosenProfileSet.Clear(); string[] array = ChosenProfiles.Value.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { if (int.TryParse(array[i].Trim(), out var result)) { chosenProfileSet.Add(result); } } } internal void SaveChosenProfiles() { ChosenProfiles.Value = string.Join(",", chosenProfileSet); GlobalConfig.Save(); } private void Update() { if (Input.GetKeyDown((KeyCode)288) && currentProfileID != -1) { showUI = !showUI; if (showUI) { allowUpward = AllowUpwardAttack; allowLeft = AllowLeftAttack; allowRight = AllowRightAttack; itemCount = StartingItemCount.Value; resetPickups = false; seedInput = RandomSeed.Value.ToString(); } } if (Input.GetKeyDown((KeyCode)9) && !GetForceCompletionDisplay()) { ClearFsmCompletionVariables(); } if (_pendingTeleport) { _pendingTeleport = false; ((MonoBehaviour)this).StartCoroutine(DelayedTeleport(_pendingTeleportScene)); } } private IEnumerator DelayedTeleport(string sceneName) { yield return HalfSecondWait; try { if (_sceneLoader != null) { object obj = _sceneLoader.GetType().GetField("cfgTeleportScene", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_sceneLoader); object obj2 = _sceneLoader.GetType().GetField("cfgTeleportConfirm", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_sceneLoader); obj?.GetType().GetProperty("Value")?.SetValue(obj, sceneName, null); obj2?.GetType().GetProperty("Value")?.SetValue(obj2, true, null); ShowNotification(Locale.Get("正在传送到 ") + sceneName + " ..."); } } catch (Exception arg) { Log.LogError((object)$"传送失败: {arg}"); } } private void OnGUI() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (_notificationMessage != null && Time.time <= _notificationEndTime) { if (_notificationStyle == null) { _notificationStyle = new GUIStyle(GUI.skin.box) { fontSize = 40, alignment = (TextAnchor)4 }; _notificationStyle.normal.textColor = Color.white; _notificationStyle.normal.background = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.7f)); } float num = 600f; float num2 = 120f; GUI.Box(new Rect(((float)Screen.width - num) / 2f, (float)(Screen.height / 2 - 100), num, num2), _notificationMessage, _notificationStyle); } else { _notificationMessage = null; } if (!showUI) { return; } if (((Rect)(ref _windowRect)).width == 0f || Mathf.Abs((float)Screen.height - _lastScreenHeight) > 1f) { float num3 = Screen.height; float num4 = 1080f; float num5 = 925f; float num6 = num3 / 8f; float num7 = num3 - num4 - num6; if (num7 < 0f) { num7 = 0f; } _windowRect = new Rect(20f, num7, num5, num4); _lastScreenHeight = num3; } _windowRect = GUILayout.Window(100, _windowRect, new WindowFunction(DrawUIWindow), Locale.Get("开局选项 & 场景随机"), Array.Empty<GUILayoutOption>()); } private void DrawUIWindow(int windowID) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (PanelBackgroundEnabled.Value && (Object)(object)_backgroundSprite != (Object)null && (Object)(object)_backgroundSprite.texture != (Object)null) { GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, ((Rect)(ref _windowRect)).height), (Texture)(object)_backgroundSprite.texture, (ScaleMode)0); } else { GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, ((Rect)(ref _windowRect)).height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.15f, 0.15f, 0.15f, 0.85f), 0f, 0f); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(558f) }); PanelRenderer.DrawLeftPanel(this); GUILayout.EndVertical(); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(270f) }); PanelRenderer.DrawScenePanel(this); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUI.DragWindow(); } internal void ApplySettings() { Log.LogInfo((object)"ApplySettings 开始执行"); StartingAbilityPickerAPI.SetAttackPermissions(allowUpward, allowLeft, allowRight); StartingAbilityPickerAPI.SetSkillRandomMode(skillMode); StartingAbilityPickerAPI.SetSkillCounts(skillTotal, skillV, skillH, skillS, skillA); StartingAbilityPickerAPI.SetStartingItemCount(itemCount); if (int.TryParse(seedInput, out var result)) { StartingAbilityPickerAPI.SetSeed(result); } StartingAbilityPickerAPI.SetResetSeedWorld(resetPickups); StartingAbilityPickerAPI.SetFullRandomMode(DirectionPatch.FullRandomMode); StartingAbilityPickerAPI.SetCrestCurseEnabled(crestCurseEnabled); StartingAbilityPickerAPI.SetForceCompletionDisplay(GetForceCompletionDisplay()); StartingAbilityPickerAPI.ApplyPending(); _pendingSkillMode = skillMode; _pendingSkillTotal = skillTotal; _pendingSkillV = skillV; _pendingSkillH = skillH; _pendingSkillS = skillS; _pendingSkillA = skillA; _pendingItemCount = itemCount; if (resetPickups) { _pendingApply = true; Log.LogInfo((object)"重置种子世界,将在场景加载完成后给予技能和物品"); ResetSeedWorld(); } else { GivePendingSkillsAndItems(); RoomRandomMode.TryApply(); showUI = false; } Log.LogInfo((object)"ApplySettings 执行完成"); StartingAbilityPickerAPI.SaveAllSettingsToConfig(); } private void ResetSeedWorld() { if (!int.TryParse(seedInput, out var result) || result == RandomSeed.Value) { result = new Random().Next(1, int.MaxValue); } seedInput = result.ToString(); RandomSeed.Value = result; GlobalConfig.Save(); TrySyncOtherMods(result); try { PlayerData instance = PlayerData.instance; if (instance == null) { return; } FieldInfo[] fields = typeof(PlayerData).GetFields(BindingFlags.Instance | BindingFlags.Public); int num = 0; FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (fieldInfo.Name.StartsWith("SkillTriggered_")) { fieldInfo.SetValue(instance, false); num++; } } Log.LogInfo((object)$"已重置 {num} 个技能触发器记录"); } catch (Exception arg) { Log.LogError((object)$"重置技能触发器失败: {arg}"); } } public static void ResetSeedWorldExternal(int newSeed) { seedInput = newSeed.ToString(); RandomSeed.Value = newSeed; GlobalConfig.Save(); Instance.TrySyncOtherMods(newSeed); try { PlayerData instance = PlayerData.instance; if (instance == null) { return; } FieldInfo[] fields = typeof(PlayerData).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.Name.StartsWith("SkillTriggered_")) { fieldInfo.SetValue(instance, false); } } } catch { } } private void TrySyncOtherMods(int newSeed) { try { Type type = Type.GetType("SilksongItemRandomizer.Plugin, SilksongItemRandomizer"); if (type != null) { PropertyInfo property = type.GetProperty("RandomSeed", BindingFlags.Static | BindingFlags.Public); if (property != null && property.GetValue(null) is ConfigEntry<int> val) { val.Value = newSeed; } type.GetMethod("ResetAllStaticData", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } } catch { } try { Type type2 = Type.GetType("SkillTriggerMod.Plugin, SkillTriggerMod"); if (type2 != null) { PropertyInfo property2 = type2.GetProperty("RandomSeed", BindingFlags.Static | BindingFlags.Public); if (property2 != null && property2.GetValue(null) is ConfigEntry<int> val2) { val2.Value = newSeed; } Type.GetType("SkillTriggerMod.SkillRandomizer, SkillTriggerMod")?.GetMethod("SetSeed", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { newSeed }); type2.GetMethod("ResetAllRecords", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } Plugin.SaveData.SkillTriggerRecords.Clear(); Plugin.SaveGlobalData(); } catch { } try { Type? type3 = Type.GetType("SilksongItemRandomizer.CrestRandomizer, SilksongItemRandomizer"); type3?.GetMethod("ResetMappings", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); type3?.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); Type.GetType("SilksongItemRandomizer.CrestRandomizePatch, SilksongItemRandomizer")?.GetMethod("ResetProcessedIds", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); Type.GetType("SilksongItemRandomizer.BenchRespawnPatch, SilksongItemRandomizer")?.GetMethod("ResetCooldown", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } catch { } } public int GetCurrentSeed() { if (_sceneLoaderType == null) { return 0; } try { if (_currentSeedField == null) { _currentSeedField = _sceneLoaderType.GetField("CurrentSeed", BindingFlags.Static | BindingFlags.Public); } FieldInfo currentSeedField = _currentSeedField; if (currentSeedField != null) { return (int)currentSeedField.GetValue(null); } } catch (Exception ex) { Log.LogWarning((object)("获取当前种子失败: " + ex.Message)); } return 0; } public string GetCurrentSceneName() { if (_sceneLoader == null) { return ""; } try { return (string)_currentSceneNameField?.GetValue(_sceneLoader); } catch { return ""; } } public bool GetSceneRandomEnabled() { if (_sceneLoaderType == null) { return false; } try { if (_enableRandomizationField == null) { _enableRandomizationField = _sceneLoaderType.GetField("EnableRandomization", BindingFlags.Static | BindingFlags.Public); } FieldInfo enableRandomizationField = _enableRandomizationField; if (enableRandomizationField != null) { return (bool)enableRandomizationField.GetValue(null); } } catch { } return false; } public void SetSceneRandomEnabled(bool enabled) { if (_sceneLoaderType == null) { return; } try { if (_enableRandomizationField == null) { _enableRandomizationField = _sceneLoaderType.GetField("EnableRandomization", BindingFlags.Static | BindingFlags.Public); } _enableRandomizationField?.SetValue(null, enabled); if (_sceneLoader != null) { FieldInfo field = _sceneLoaderType.GetField("cfgEnableRandomization", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(_sceneLoader); value?.GetType().GetProperty("Value")?.SetValue(value, enabled, null); } } } catch { } } public bool GetShowSceneLabel() { if (_cfgShowSceneLabelField != null && _sceneLoader != null) { try { object value = _cfgShowSceneLabelField.GetValue(_sceneLoader); object obj = value?.GetType().GetProperty("Value")?.GetValue(value); if (obj is bool) { return (bool)obj; } } catch { } } return true; } public void SetShowSceneLabel(bool value, bool isSeed = false) { try { if (!isSeed) { if (_cfgShowSceneLabelField != null && _sceneLoader != null) { object value2 = _cfgShowSceneLabelField.GetValue(_sceneLoader); value2?.GetType().GetProperty("Value")?.SetValue(value2, value, null); } } else if (_seedManager != null) { object obj = _seedManager.GetType().GetField("cfgShowSeedOnScreen", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_seedManager); obj?.GetType().GetProperty("Value")?.SetValue(obj, value, null); } } catch { } } public bool GetShowSeedLabel() { try { if (_seedManager != null) { object obj = _seedManager.GetType().GetField("cfgShowSeedOnScreen", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_seedManager); return (bool)(obj?.GetType().GetProperty("Value")?.GetValue(obj) ?? ((object)true)); } } catch { } return true; } public bool GetForceCompletionDisplay() { int num = currentProfileID; if (num == -1) { return true; } if (Plugin.SaveData.ProfileCompletionDisplay.TryGetValue(num, out var value)) { return value; } return true; } private void RefreshCompletionUI(bool forceShow = false) { if (!GetForceCompletionDisplay() && !forceShow) { ClearFsmCompletionVariables(); return; } PlayerData instance = PlayerData.instance; if (instance == null) { return; } string value = Mathf.RoundToInt(instance.completionPercentage) + "%"; string[] array = new string[4] { "Inv", "Tools", "Journal", "Quests" }; for (int i = 0; i < array.Length; i++) { GameObject val = GameObject.Find(array[i]); if ((Object)(object)val == (Object)null) { continue; } PlayMakerFSM component = val.GetComponent<PlayMakerFSM>(); if (!((Object)(object)component == (Object)null)) { FsmString val2 = component.FsmVariables.FindFsmString("Completion Percentage Str"); if (val2 != null) { val2.Value = value; } } } } private void ClearFsmCompletionVariables() { try { string[] array = new string[4] { "Inv", "Tools", "Journal", "Quests" }; for (int i = 0; i < array.Length; i++) { GameObject val = GameObject.Find(array[i]); if ((Object)(object)val == (Object)null) { continue; } PlayMakerFSM component = val.GetComponent<PlayMakerFSM>(); if ((Object)(object)component == (Object)null) { continue; } FsmString[] stringVariables = component.FsmVariables.StringVariables; foreach (FsmString val2 in stringVariables) { if (((NamedVariable)val2).Name.IndexOf("Completion", StringComparison.OrdinalIgnoreCase) >= 0) { val2.Value = ""; } } } } catch (Exception arg) { Log.LogWarning((object)$"清空完成度变量失败: {arg}"); } } public bool GetItemRandomEnabled() { try { if (_publicItemRandomProp == null) { _publicItemRandomProp = Type.GetType("SilksongItemRandomizer.Plugin, SilksongItemRandomizer")?.GetProperty("PublicItemRandomEnabled", BindingFlags.Static | BindingFlags.Public); } return _publicItemRandomProp != null && (bool)_publicItemRandomProp.GetValue(null); } catch { } return false; } public void ApplyStartingSettings() { GivePendingSkillsAndItems(); } public void SetItemRandomEnabled(bool value) { try { if (_publicItemRandomProp == null) { _publicItemRandomProp = Type.GetType("SilksongItemRandomizer.Plugin, SilksongItemRandomizer")?.GetProperty("PublicItemRandomEnabled", BindingFlags.Static | BindingFlags.Public); } _publicItemRandomProp?.SetValue(null, value); } catch { } } public void SetEnemyRandoAdjustEnabled(bool value) { EnemyRandoAdjustEnabled.Value = value; GlobalConfig.Save(); try { Type type = Type.GetType("SilksongItemRandomizer.EnemyRandoAdjuster, SilksongItemRandomizer"); if (type != null) { PropertyInfo property = type.GetProperty("Enabled", BindingFlags.Static | BindingFlags.Public); if (property != null) { property.SetValue(null, value); } } } catch (Exception arg) { Log.LogError((object)$"设置怪物调整开关失败: {arg}"); } } public void SetPanelBackgroundEnabled(bool value) { PanelBackgroundEnabled.Value = value; } } [HarmonyPatch(typeof(SaveStats), "GetCompletionPercentage")] public static class SaveStats_GetCompletionPercentage_Patch { [HarmonyPostfix] private static void Postfix(ref string __result) { if ((Object)(object)Plugin.Instance != (Object)null && !Plugin.Instance.GetForceCompletionDisplay()) { __result = ""; } } } [HarmonyPatch(typeof(SaveStats), "get_UnlockedCompletionRate")] public static class SaveStats_UnlockedCompletionRate_Patch { [HarmonyPostfix] private static void Postfix(ref bool __result) { if ((Object)(object)Plugin.Instance != (Object)null && !Plugin.Instance.GetForceCompletionDisplay()) { __result = false; } } } [HarmonyPatch(typeof(PlayerData), "CountGameCompletion")] public static class PlayerData_CountGameCompletion_Patch { [HarmonyPrefix] private static bool Prefix() { if ((Object)(object)Plugin.Instance != (Object)null) { return Plugin.Instance.GetForceCompletionDisplay(); } return true; } } [HarmonyPatch(typeof(ConvertFloatToString), "OnEnter")] public static class ConvertFloatToString_Patch { private static void Postfix(ConvertFloatToString __instance) { if ((Object)(object)Plugin.Instance != (Object)null && !Plugin.Instance.GetForceCompletionDisplay() && __instance.stringVariable != null && ((NamedVariable)__instance.stringVariable).Name == "Completion Percentage Str") { __instance.stringVariable.Value = ""; } } } [HarmonyPatch(typeof(BuildString), "OnEnter")] public static class BuildString_Patch { private static void Postfix(BuildString __instance) { if ((Object)(object)Plugin.Instance != (Object)null && !Plugin.Instance.GetForceCompletionDisplay() && __instance.storeResult != null && ((NamedVariable)__instanc