using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using Peak;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[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;
}
}
}
public class BeaconRenderer : MonoBehaviour
{
public List<Vector3> targets = new List<Vector3>();
public Color color = new Color(0f, 1f, 0f, 1f);
public float height = 150f;
private Material _mat;
private void OnDestroy()
{
if ((Object)(object)_mat != (Object)null)
{
Object.Destroy((Object)(object)_mat);
_mat = null;
}
}
private void EnsureMat()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
if (!((Object)(object)_mat != (Object)null))
{
Shader val = Shader.Find("Hidden/Internal-Colored");
if (!((Object)(object)val == (Object)null))
{
_mat = new Material(val);
((Object)_mat).hideFlags = (HideFlags)61;
_mat.SetInt("_ZWrite", 0);
_mat.SetInt("_SrcBlend", 5);
_mat.SetInt("_DstBlend", 10);
_mat.renderQueue = 5000;
}
}
}
private void OnRenderObject()
{
//IL_0044: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: 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_0084: 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_0090: Unknown result type (might be due to invalid IL or missing references)
//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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: 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)
//IL_00fc: 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)
if (targets == null || targets.Count == 0)
{
return;
}
EnsureMat();
if ((Object)(object)_mat == (Object)null)
{
return;
}
_mat.SetPass(0);
GL.PushMatrix();
GL.Begin(1);
GL.Color(color);
float num = height;
foreach (Vector3 target in targets)
{
Vector3 val = target + new Vector3(0f, num, 0f);
GL.Vertex(target);
GL.Vertex(val);
GL.Vertex(val + new Vector3(-3f, 0f, 0f));
GL.Vertex(val + new Vector3(3f, 0f, 0f));
GL.Vertex(val + new Vector3(0f, 0f, -3f));
GL.Vertex(val + new Vector3(0f, 0f, 3f));
}
GL.End();
GL.PopMatrix();
}
}
[BepInPlugin("com.mandrake.bugfinder", "PEAK Finder", "3.2.1")]
public class Plugin : BaseUnityPlugin
{
private class Category
{
public int Index;
public string ConfigName;
public string DisplayName;
public string WorldLabel;
public ConfigEntry<bool> Show;
public ConfigEntry<KeyboardShortcut> ToggleKeyEntry;
public BeaconRenderer Live;
public readonly List<Vector3> LivePos = new List<Vector3>();
public readonly List<string> LiveNames = new List<string>();
public List<string> Keywords;
public Type MarkerType;
public bool ItemScan;
}
private class LuggageHit
{
public Vector3 Pos;
public int SegIdx = -1;
public string SegLabel = "";
public bool Open;
}
private class TodaySeg
{
public int Index = -1;
public string Canon = "";
public int Biome = -1;
public string VariantEn = "";
public string VariantCn = "";
public bool Done;
}
private List<string> _capyExcludeKeys = new List<string>();
private Type _mirageType;
private FieldInfo _mirageHideField;
private MapHandler _capyLogMap;
private int _mirageLogged = -1;
private readonly List<Transform> _mirageHidden = new List<Transform>();
private readonly List<Transform> _mirageComps = new List<Transform>();
private ConfigEntry<float> _scanInterval;
private ConfigEntry<bool> _autoScan;
private ConfigEntry<KeyboardShortcut> _toggleKey;
private ConfigEntry<KeyboardShortcut> _rescanKey;
private ConfigEntry<KeyboardShortcut> _panelKey;
private ConfigEntry<float> _beaconHeight;
private ConfigEntry<bool> _swampOnly;
private ConfigEntry<bool> _gloomOnly;
private ConfigEntry<bool> _includeJesterBells;
private ConfigEntry<float> _clusterRadius;
private bool _showPanel;
private float _nextScanTime;
private string _status = "";
private string _mapName = "";
private readonly List<Category> _categories = new List<Category>();
private Category _mandrake;
private Category _bug;
private Category _beehive;
private Category _capybara;
private Category _belltower;
private Category _luggage;
private MapHandler _cachedMap;
private readonly List<GameObject> _roots = new List<GameObject>();
private readonly List<Transform> _tmpTransforms = new List<Transform>();
private readonly List<Transform> _excludeChars = new List<Transform>();
private GameObject _root;
private MapHandler _bellScanMap;
private bool _bellCacheValid;
private bool _bellNoGloomLogged;
private readonly List<Vector3> _bellCachePos = new List<Vector3>();
private readonly List<string> _bellCacheNames = new List<string>();
private ConfigEntry<bool> _luggageExport;
private readonly List<LuggageHit> _clownHits = new List<LuggageHit>();
private string _luggageSummary = "";
private int _luggageOpenedCount;
private string _luggageSig = "";
private string _luggageLogSig = "";
private string _mapSortingCn = "";
private string _mapSortingEn = "";
private int _mapSegCount;
private MountainProgressHandler _mph;
private MapHandler _mphMap;
private readonly List<string> _climbNames = new List<string>();
private bool _climbLoaded;
private bool _climbOrderAligned;
private bool _climbAlignWarned;
private readonly List<TodaySeg> _today = new List<TodaySeg>();
private bool _todayAligned;
private string _todayMapSig = "";
private string _todayDetailCn = "";
private string _todayExportSig = "";
private ConfigEntry<bool> _todayExport;
private bool _manualRescan;
private static readonly HashSet<string> MesaKnownVariants = new HashSet<string> { "ScorpionsHell", "CactusHell", "CactusForest", "DynamiteHell", "TornadoHell", "TumblerHell" };
private static readonly HashSet<string> RootsKnownVariants = new HashSet<string> { "CaveMania", "DeepWater", "BombBeetle", "DeepWoods", "Clearcut" };
private static readonly HashSet<string> RootsStructuralNames = new HashSet<string> { "Redwoods", "Redwood", "Variant" };
private static readonly Dictionary<int, Dictionary<string, string>> VariantCnMap = new Dictionary<int, Dictionary<string, string>>
{
[0] = new Dictionary<string, string>
{
["Default"] = "默认",
["SnakeBeach"] = "蛇岩",
["RedBeach"] = "赤沙",
["BlueBeach"] = "蓝沙",
["JellyHell"] = "水母地狱",
["BlackSand"] = "黑沙"
},
[1] = new Dictionary<string, string>
{
["Default"] = "默认",
["Lava"] = "熔岩管",
["Pillars"] = "巨柱",
["Thorny"] = "巨棘藤",
["Bombs"] = "爆菇",
["Ivy"] = "紫毒藤",
["SkyJungle"] = "浮岛"
},
[2] = new Dictionary<string, string>
{
["Default"] = "默认",
["Lava"] = "熔岩管",
["Spiky"] = "冰刺",
["GeyserHell"] = "间歇泉地狱"
},
[6] = new Dictionary<string, string>
{
["Default"] = "默认",
["ScorpionsHell"] = "毒蝎地狱",
["CactusHell"] = "峭壁仙人掌地狱",
["CactusForest"] = "高原仙人掌林",
["DynamiteHell"] = "炸药地狱",
["TornadoHell"] = "龙卷风地狱",
["TumblerHell"] = "风滚草地狱"
},
[7] = new Dictionary<string, string>
{
["Default"] = "默认",
["CaveMania"] = "洞窟丛生",
["DeepWater"] = "赤水孢泽",
["BombBeetle"] = "爆菇甲虫",
["DeepWoods"] = "幽深密林",
["Clearcut"] = "皆伐菌原"
}
};
internal string _mapSortingDetailCn => _todayDetailCn;
internal void BindCapybaraConfig()
{
_capyExcludeKeys = SplitList(((BaseUnityPlugin)this).Config.Bind<string>("Scan", "CapybaraExcludeFilter", "mirage", "卡皮巴拉地标排除关键词(方山的假绿洲带 Mirage),逗号分隔").Value);
try
{
_mirageType = Type.GetType("Mirage, Assembly-CSharp");
}
catch
{
_mirageType = null;
}
try
{
_mirageHideField = ((_mirageType != null) ? _mirageType.GetField("objectsToHide") : null);
}
catch
{
_mirageHideField = null;
}
}
private void ScanCapybara(Category cat, MapHandler map)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected I4, but got Unknown
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0435: Unknown result type (might be due to invalid IL or missing references)
//IL_032f: Unknown result type (might be due to invalid IL or missing references)
List<Vector3> list = new List<Vector3>();
List<string> list2 = new List<string>();
List<Transform> list3 = new List<Transform>();
List<Tuple<Transform, Vector3, string>> list4 = new List<Tuple<Transform, Vector3, string>>();
List<GameObject> list5 = new List<GameObject>();
if (map.segments != null)
{
MapSegment[] segments = map.segments;
foreach (MapSegment val in segments)
{
if (val != null && !((Object)(object)val.segmentParent == (Object)null))
{
bool flag = false;
try
{
int num = (int)val.biome;
flag = num == 2 || num == 6;
}
catch
{
}
if (flag)
{
list5.Add(val.segmentParent);
}
}
}
}
CollectMirageData();
int num2 = 0;
try
{
Object[] array = Resources.FindObjectsOfTypeAll(typeof(Capybara));
if (array != null)
{
Object[] array2 = array;
foreach (Object obj2 in array2)
{
Component val2 = (Component)(object)((obj2 is Component) ? obj2 : null);
if ((Object)(object)val2 == (Object)null || (Object)(object)val2.gameObject == (Object)null)
{
continue;
}
Scene scene = val2.gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
if (!val2.gameObject.activeInHierarchy)
{
num2++;
}
else if (!IsExcluded(val2.transform) && !IsMirageFake(val2.transform))
{
list.Add(val2.transform.position);
list2.Add("Capybara (" + ((Object)val2.gameObject).name + ")");
list3.Add(val2.transform);
}
}
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 卡皮巴拉组件扫描失败: " + ex.Message));
}
List<string> list6 = new List<string>();
foreach (GameObject item in list5)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
_tmpTransforms.Clear();
item.GetComponentsInChildren<Transform>(true, _tmpTransforms);
foreach (Transform tmpTransform in _tmpTransforms)
{
if ((Object)(object)tmpTransform == (Object)null || (Object)(object)((Component)tmpTransform).gameObject == (Object)null || ((Object)(object)_root != (Object)null && (Object)(object)tmpTransform.root == (Object)(object)_root.transform))
{
continue;
}
string text = ((Object)tmpTransform).name.ToLowerInvariant();
if (!MatchKeys(text, cat.Keywords))
{
continue;
}
string text2 = null;
if (text.Contains("capybara"))
{
text2 = "capybara锚点";
}
else if (text.Contains("spawner") || text.Contains("spawn"))
{
text2 = "生成锚点";
}
else if (text.Contains("autolod") || text.Contains("_lod"))
{
text2 = "LOD代理";
}
else if (!((Component)tmpTransform).gameObject.activeInHierarchy)
{
text2 = "禁用";
}
if (text2 == null && IsMirageFake(tmpTransform))
{
text2 = "Mirage幻影";
}
if (text2 != null)
{
if (list6.Count < 12)
{
list6.Add(((Object)tmpTransform).name + "(" + text2 + ")");
}
}
else
{
list4.Add(Tuple.Create<Transform, Vector3, string>(tmpTransform, tmpTransform.position, "地标 (" + ((Object)tmpTransform).name + ")"));
}
}
}
int num3 = 0;
if (list4.Count > 0)
{
HashSet<GameObject> hashSet = new HashSet<GameObject>();
if (list3.Count > 0)
{
foreach (Transform item2 in list3)
{
GameObject val3 = FindSegmentRoot(item2, list5);
if ((Object)(object)val3 != (Object)null)
{
hashSet.Add(val3);
}
}
}
foreach (Tuple<Transform, Vector3, string> item3 in list4)
{
GameObject val4 = FindSegmentRoot(item3.Item1, list5);
if ((Object)(object)val4 != (Object)null && hashSet.Contains(val4))
{
num3++;
continue;
}
list.Add(item3.Item2);
list2.Add(item3.Item3);
}
}
Cluster(list, list2, cat.LivePos, cat.LiveNames, _clusterRadius.Value);
if ((Object)(object)_capyLogMap != (Object)(object)map)
{
_capyLogMap = map;
_mirageLogged = -1;
}
if (_mirageLogged != _mirageComps.Count)
{
_mirageLogged = _mirageComps.Count;
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 卡皮巴拉:Alpine/Mesa 段根 " + list5.Count + " 个,Mirage " + _mirageComps.Count + " 个(引用假道具 " + _mirageHidden.Count + " 个),跳过禁用组件实例 " + num2 + ((num3 > 0) ? (";地标压制 " + num3 + " 个(段内有真卡皮巴拉)") : "") + ((list6.Count > 0) ? (";地标排除: " + string.Join(", ", list6.ToArray())) : ";无地标排除")));
}
}
private void CollectMirageData()
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
_mirageHidden.Clear();
_mirageComps.Clear();
if (_mirageType == null)
{
return;
}
try
{
Object[] array = Resources.FindObjectsOfTypeAll(_mirageType);
foreach (Object obj in array)
{
Component val = (Component)(object)((obj is Component) ? obj : null);
if ((Object)(object)val == (Object)null || (Object)(object)val.gameObject == (Object)null)
{
continue;
}
Scene scene = val.gameObject.scene;
if (!((Scene)(ref scene)).IsValid())
{
continue;
}
_mirageComps.Add(val.transform);
if (_mirageHideField == null || !(_mirageHideField.GetValue(val) is GameObject[] array2))
{
continue;
}
GameObject[] array3 = array2;
foreach (GameObject val2 in array3)
{
if ((Object)(object)val2 != (Object)null)
{
_mirageHidden.Add(val2.transform);
}
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] Mirage 收集失败: " + ex.Message));
}
}
private bool IsMirageFake(Transform t)
{
Transform val = t;
int num = 0;
while ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && num < 20)
{
if (MatchKeys(((Object)val).name.ToLowerInvariant(), _capyExcludeKeys))
{
return true;
}
if (_mirageType != null && HasComp(((Component)val).gameObject, _mirageType))
{
return true;
}
val = val.parent;
num++;
}
if (_mirageType == null)
{
return false;
}
if ((Object)(object)t != (Object)null && (Object)(object)((Component)t).gameObject != (Object)null && HasCompInChildren(((Component)t).gameObject, _mirageType))
{
return true;
}
foreach (Transform item in _mirageHidden)
{
if (!((Object)(object)item == (Object)null) && ((Object)(object)t == (Object)(object)item || IsDescendant(t, item) || IsDescendant(item, t)))
{
return true;
}
}
return false;
}
private static bool HasComp(GameObject go, Type type)
{
try
{
return (Object)(object)go.GetComponent(type) != (Object)null;
}
catch
{
return false;
}
}
private static GameObject FindSegmentRoot(Transform t, List<GameObject> roots)
{
if ((Object)(object)t == (Object)null || roots == null)
{
return null;
}
Transform val = t;
while ((Object)(object)val != (Object)null)
{
foreach (GameObject root in roots)
{
if ((Object)(object)root != (Object)null && (Object)(object)val == (Object)(object)root.transform)
{
return root;
}
}
val = val.parent;
}
return null;
}
private static bool HasCompInChildren(GameObject go, Type type)
{
try
{
Component[] componentsInChildren = go.GetComponentsInChildren(type, true);
return componentsInChildren != null && componentsInChildren.Length != 0;
}
catch
{
return false;
}
}
private void Awake()
{
//IL_0061: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Expected O, but got Unknown
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
//IL_0309: Unknown result type (might be due to invalid IL or missing references)
//IL_034b: Unknown result type (might be due to invalid IL or missing references)
_scanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScanInterval", 5f, "扫描间隔(秒)");
_autoScan = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoScan", true, "是否自动定时扫描(关掉后只用手动重扫)");
_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "开关全部光柱");
_rescanKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "RescanKey", new KeyboardShortcut((KeyCode)282, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "立即重新扫描");
_panelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "PanelKey", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "开关左上角信息面板(关闭后停止自动扫描,再次打开立即扫描)");
_beaconHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "BeaconHeight", 150f, "实刷光柱高度");
_swampOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "SwampOnly", false, "道具类层级兜底只扫描雾沼(Swamp)段(生物群系 8)");
_gloomOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "GloomOnly", true, "钟塔只扫描雾沼(Gloom/Swamp)段(找不到雾沼段时回退全图)");
_includeJesterBells = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "IncludeJesterBells", true, "把雾沼段里的 JesterBells 也算作钟");
_clusterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "ClusterRadius", 50f, "同一目标的归类半径");
BindLuggageConfig();
BindCapybaraConfig();
BindTodayConfig();
_root = new GameObject("PEAKFinderBeacons");
Object.DontDestroyOnLoad((Object)(object)_root);
_mandrake = AddCategory(1, "Mandrake", "曼德拉草", "曼德拉", showDefault: true, "#00FF00FF", new Color(0f, 1f, 0f), "MandrakeNameFilter", "mandrake", typeof(Mandrake), itemScan: true);
_bug = AddCategory(2, "Bug", "雾沼虫", "雾沼虫", showDefault: true, "#00A0FFFF", new Color(0f, 0.63f, 1f), "BugNameFilter", "earlyworm,worm", typeof(EarlyWorm), itemScan: true);
_beehive = AddCategory(3, "Beehive", "蜂巢·蜂蜜", "蜂巢", showDefault: true, "#B026FFFF", new Color(0.69f, 0.15f, 1f), "BeehiveNameFilter", "beehive,honey,honeycomb", typeof(Beehive), itemScan: true);
_capybara = AddCategory(4, "Capybara", "卡皮巴拉", "卡皮巴拉", showDefault: true, "#FF8C00FF", new Color(1f, 0.55f, 0f), "CapybaraNameFilter", "oasis,hotspring,spring", typeof(Capybara), itemScan: false);
_belltower = AddCategory(5, "Belltower", "钟塔", "钟塔", showDefault: true, "#FFCC00FF", new Color(1f, 0.8f, 0f), "BelltowerNameFilter", "bell,tower,belfry", null, itemScan: false);
_luggage = AddCategory(6, "Luggage", "小丑行李", "小丑行李", showDefault: true, "#FF0033FF", new Color(1f, 0f, 0.2f), "LuggageNameFilter", "clown", null, itemScan: false);
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] v3.2.1 loaded. " + KeyText(_toggleKey) + "=全开/关, " + KeyText(_rescanKey) + "=重扫, " + KeyText(_panelKey) + "=面板, 面板开启时数字 5-0 切分类(5曼德拉 6雾沼虫 7蜂巢 8卡皮巴拉 9钟塔 0小丑行李)"));
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if ((int)mode != 0)
{
return;
}
foreach (Category category in _categories)
{
category.LivePos.Clear();
category.LiveNames.Clear();
}
ClearRenderers();
}
private Category AddCategory(int index, string configName, string display, string worldLabel, bool showDefault, string colorHexDefault, Color fallbackColor, string filterKey, string filterDefault, Type markerType, bool itemScan)
{
//IL_00e6: 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_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: 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)
Category category = new Category
{
Index = index,
ConfigName = configName,
DisplayName = display,
WorldLabel = worldLabel,
MarkerType = markerType,
ItemScan = itemScan
};
category.Show = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "Show" + configName + "Beacons", showDefault, "是否显示" + display + "光柱");
ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("Visual", configName + "ColorHex", colorHexDefault, display + "光柱颜色(HEX RRGGBBAA)");
category.Keywords = SplitList(((BaseUnityPlugin)this).Config.Bind<string>("Scan", filterKey, filterDefault, "按名字匹配" + display + "的关键词,逗号分隔").Value);
category.ToggleKeyEntry = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "CategoryKey" + index, new KeyboardShortcut(DefaultCategoryKey(index), Array.Empty<KeyCode>()), "面板开启时:切换" + display + "显示");
category.Live = _root.AddComponent<BeaconRenderer>();
category.Live.color = ParseHexColor(val.Value, fallbackColor);
category.Live.height = Mathf.Max(10f, _beaconHeight.Value);
((Behaviour)category.Live).enabled = category.Show.Value;
_categories.Add(category);
return category;
}
private void Update()
{
//IL_0006: 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_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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
try
{
KeyboardShortcut value = _toggleKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
ToggleAllCategories();
}
value = _rescanKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
_manualRescan = true;
ScanNow();
}
value = _panelKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
_showPanel = !_showPanel;
if (_showPanel)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PEAKFinder] 面板开启,开始扫描");
ScanNow();
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PEAKFinder] 面板关闭,停止自动扫描");
}
}
if (_showPanel)
{
foreach (Category category in _categories)
{
value = category.ToggleKeyEntry.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
SetCategoryShow(category, !category.Show.Value);
}
}
}
if (_showPanel && _autoScan.Value && Time.time >= _nextScanTime)
{
_nextScanTime = Time.time + Mathf.Max(0.5f, _scanInterval.Value);
ScanNow();
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[PEAKFinder] Update error: " + ex));
}
}
private void SetCategoryShow(Category cat, bool on)
{
cat.Show.Value = on;
if ((Object)(object)cat.Live != (Object)null)
{
((Behaviour)cat.Live).enabled = on;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] " + cat.DisplayName + ":" + (on ? "开" : "关")));
}
private void ToggleAllCategories()
{
bool flag = _categories.Any((Category c) => c.Show.Value);
foreach (Category category in _categories)
{
SetCategoryShow(category, !flag);
}
}
private void ScanNow()
{
//IL_009d: 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)
try
{
MapHandler val = Object.FindObjectOfType<MapHandler>();
if ((Object)(object)val == (Object)null || !MapHandler.Exists || !MapHandler.ExistsAndInitialized)
{
_status = "未进入地图(请先进入每日远征)";
_mapName = "";
ResetLuggageSession();
RefreshTodayDetail(null, forceExport: false);
_manualRescan = false;
foreach (Category category in _categories)
{
category.LivePos.Clear();
category.LiveNames.Clear();
}
ClearRenderers();
return;
}
Scene scene = ((Component)val).gameObject.scene;
_mapName = ((Scene)(ref scene)).name;
RefreshMapSorting(val);
EnsureRoots(val);
BuildExcludeChars();
RefreshTodayDetail(val, _manualRescan);
_manualRescan = false;
foreach (Category category2 in _categories)
{
category2.LivePos.Clear();
category2.LiveNames.Clear();
if (category2 == _luggage)
{
ScanLuggage(category2, val);
}
else if (category2.Show.Value)
{
if (category2 == _belltower)
{
ScanBelltower(category2, val);
}
else if (category2 == _capybara)
{
ScanCapybara(category2, val);
}
else
{
ScanItemCategory(category2);
}
}
}
AssignRenderers();
UpdateStatus();
LogMatches();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[PEAKFinder] Scan error: " + ex));
}
}
private void EnsureRoots(MapHandler map)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Invalid comparison between Unknown and I4
if ((Object)(object)_cachedMap == (Object)(object)map && _roots.Count > 0)
{
return;
}
_cachedMap = map;
_roots.Clear();
if (map.segments == null)
{
return;
}
MapSegment[] segments = map.segments;
foreach (MapSegment val in segments)
{
if (val != null && (!_swampOnly.Value || (int)val.biome == 8) && (Object)(object)val.segmentParent != (Object)null && !_roots.Contains(val.segmentParent))
{
_roots.Add(val.segmentParent);
}
}
}
private void BuildExcludeChars()
{
_excludeChars.Clear();
Character[] array = Resources.FindObjectsOfTypeAll<Character>();
if (array == null)
{
return;
}
Character[] array2 = array;
foreach (Character val in array2)
{
if ((Object)(object)val != (Object)null)
{
_excludeChars.Add(((Component)val).transform);
}
}
}
private void ScanItemCategory(Category cat)
{
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
List<Vector3> list = new List<Vector3>();
List<string> list2 = new List<string>();
if (cat.MarkerType != null)
{
AddComponentTargets(cat, list, list2);
}
if (cat.ItemScan)
{
AddItemTargets(cat, list, list2);
}
foreach (GameObject root in _roots)
{
if ((Object)(object)root == (Object)null)
{
continue;
}
_tmpTransforms.Clear();
root.GetComponentsInChildren<Transform>(true, _tmpTransforms);
foreach (Transform tmpTransform in _tmpTransforms)
{
if (!((Object)(object)tmpTransform == (Object)null) && (!((Object)(object)_root != (Object)null) || !((Object)(object)tmpTransform.root == (Object)(object)_root.transform)))
{
string text = ((Object)tmpTransform).name.ToLowerInvariant();
if (MatchKeys(text, cat.Keywords) && !text.Contains("spawner") && !text.Contains("spawn"))
{
list.Add(tmpTransform.position);
list2.Add(((Object)tmpTransform).name);
}
}
}
}
Cluster(list, list2, cat.LivePos, cat.LiveNames, _clusterRadius.Value);
}
private void ScanBelltower(Category cat, MapHandler map)
{
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_0342: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0394: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_bellScanMap != (Object)(object)map)
{
_bellScanMap = map;
_bellCacheValid = false;
_bellNoGloomLogged = false;
_bellCachePos.Clear();
_bellCacheNames.Clear();
}
GameObject val = FindGloomSegmentRoot(map);
if ((Object)(object)val == (Object)null && _gloomOnly.Value)
{
if (!_bellNoGloomLogged)
{
_bellNoGloomLogged = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PEAKFinder] 钟塔:本图无雾沼段,跳过扫描(数量应为 0)");
}
cat.LivePos.Clear();
cat.LiveNames.Clear();
return;
}
Scene scene;
if (_bellCacheValid)
{
cat.LivePos.Clear();
cat.LiveNames.Clear();
cat.LivePos.AddRange(_bellCachePos);
cat.LiveNames.AddRange(_bellCacheNames);
}
else
{
List<Vector3> list = new List<Vector3>();
List<string> list2 = new List<string>();
if ((Object)(object)val != (Object)null && _gloomOnly.Value)
{
_tmpTransforms.Clear();
val.GetComponentsInChildren<Transform>(true, _tmpTransforms);
foreach (Transform tmpTransform in _tmpTransforms)
{
if (!((Object)(object)tmpTransform == (Object)null) && MatchKeys(((Object)tmpTransform).name.ToLowerInvariant(), cat.Keywords))
{
list.Add(tmpTransform.position);
list2.Add(((Object)tmpTransform).name);
}
}
}
else if (!_gloomOnly.Value)
{
Transform[] array = Object.FindObjectsOfType<Transform>();
foreach (Transform val2 in array)
{
if (!((Object)(object)val2 == (Object)null))
{
scene = ((Component)val2).gameObject.scene;
if (((Scene)(ref scene)).IsValid() && (!((Object)(object)_root != (Object)null) || !((Object)(object)val2.root == (Object)(object)_root.transform)) && MatchKeys(((Object)val2).name.ToLowerInvariant(), cat.Keywords))
{
list.Add(val2.position);
list2.Add(((Object)val2).name);
}
}
}
}
Cluster(list, list2, cat.LivePos, cat.LiveNames, _clusterRadius.Value);
if (cat.LivePos.Count > 0)
{
_bellCachePos.Clear();
_bellCachePos.AddRange(cat.LivePos);
_bellCacheNames.Clear();
_bellCacheNames.AddRange(cat.LiveNames);
_bellCacheValid = true;
}
}
if (!_includeJesterBells.Value)
{
return;
}
JesterBells[] array2 = Resources.FindObjectsOfTypeAll<JesterBells>();
foreach (JesterBells val3 in array2)
{
if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).gameObject == (Object)null)
{
continue;
}
GameObject gameObject = ((Component)val3).gameObject;
scene = gameObject.scene;
if (!((Scene)(ref scene)).IsValid() || !gameObject.activeInHierarchy || ((Object)(object)val != (Object)null && !IsDescendant(gameObject.transform, val.transform)))
{
continue;
}
bool flag = false;
foreach (Vector3 livePo in cat.LivePos)
{
if (Vector3.Distance(livePo, gameObject.transform.position) <= _clusterRadius.Value)
{
flag = true;
break;
}
}
if (!flag)
{
cat.LivePos.Add(gameObject.transform.position);
cat.LiveNames.Add("JesterBells");
}
}
}
private GameObject FindGloomSegmentRoot(MapHandler map)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
if (map.segments == null)
{
return null;
}
MapSegment[] segments = map.segments;
foreach (MapSegment val in segments)
{
if (val != null && (int)val.biome == 8)
{
return val.segmentParent;
}
}
return null;
}
private void AssignRenderers()
{
foreach (Category category in _categories)
{
if ((Object)(object)category.Live != (Object)null)
{
category.Live.targets.Clear();
if (category.Show.Value)
{
category.Live.targets.AddRange(category.LivePos);
}
((Behaviour)category.Live).enabled = category.Show.Value;
}
}
}
private void ClearRenderers()
{
foreach (Category category in _categories)
{
if ((Object)(object)category.Live != (Object)null)
{
category.Live.targets.Clear();
}
}
}
private void UpdateStatus()
{
bool flag = _categories.Any((Category c) => c.LivePos.Count > 0);
_status = (flag ? "已扫描" : "没扫到目标:看日志或调 NameFilter 关键词");
}
private void LogMatches()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
foreach (Category category in _categories)
{
if (category != _luggage)
{
for (int i = 0; i < category.LivePos.Count; i++)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] " + category.DisplayName + " #" + (i + 1) + " '" + category.LiveNames[i] + "' " + FmtVec(category.LivePos[i])));
}
}
}
}
private void OnGUI()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
if (!_showPanel)
{
return;
}
try
{
GUILayout.BeginArea(new Rect(10f, 10f, 440f, 280f));
GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
GUILayout.Label("<b>PEAK Finder</b>", Array.Empty<GUILayoutOption>());
GUILayout.Label("地图: " + (string.IsNullOrEmpty(_mapName) ? "-" : _mapName) + " " + _status, Array.Empty<GUILayoutOption>());
string text = ((_mapSortingDetailCn.Length > 0) ? _mapSortingDetailCn : _mapSortingCn);
if (text.Length > 0)
{
GUILayout.Label("今日: " + text + "(" + _mapSegCount + "段)", Array.Empty<GUILayoutOption>());
}
foreach (Category category in _categories)
{
string text2 = (category.Show.Value ? "<color=#7CFC00>开</color>" : "<color=#A0A0A0>关</color>");
string text3 = "共 " + category.LivePos.Count;
if (category == _luggage && category.LivePos.Count > 0)
{
text3 = text3 + ":" + _luggageSummary;
if (_luggageOpenedCount > 0)
{
text3 = text3 + ",已开" + _luggageOpenedCount;
}
}
GUILayout.Label("[" + KeyShortLabel(category.ToggleKeyEntry.Value) + "] " + category.DisplayName + " " + text2 + " " + text3, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(4f);
GUILayout.Label(KeyText(_toggleKey) + " 全开/关 | " + KeyText(_rescanKey) + " 重扫 | " + KeyText(_panelKey) + " 面板", Array.Empty<GUILayoutOption>());
GUILayout.Label("面板开启时: 数字 5-0 切分类", Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
GUILayout.EndArea();
Camera main = Camera.main;
foreach (Category category2 in _categories)
{
if (category2.Show.Value && !((Object)(object)category2.Live == (Object)null))
{
for (int i = 0; i < category2.LivePos.Count; i++)
{
DrawWorldLabel(main, category2.LivePos[i], category2.WorldLabel, category2.Live.color);
}
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[PEAKFinder] OnGUI error: " + ex));
}
}
private static void DrawWorldLabel(Camera cam, Vector3 worldPos, string text, Color col)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_0012: 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_0032: 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)
//IL_004e: 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)
if (!((Object)(object)cam == (Object)null))
{
Vector3 val = cam.WorldToScreenPoint(worldPos);
if (!(val.z <= 0f))
{
Rect val2 = new Rect(val.x - 30f, (float)Screen.height - val.y - 12f, 90f, 20f);
GUI.color = col;
GUI.Label(val2, text);
GUI.color = Color.white;
}
}
}
private void AddComponentTargets(Category cat, List<Vector3> pos, List<string> names)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
Object[] array = Resources.FindObjectsOfTypeAll(cat.MarkerType);
if (array == null)
{
return;
}
Object[] array2 = array;
foreach (Object obj in array2)
{
Component val = (Component)(object)((obj is Component) ? obj : null);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.gameObject == (Object)null))
{
GameObject gameObject = val.gameObject;
Scene scene = gameObject.scene;
if (((Scene)(ref scene)).IsValid() && !IsExcluded(gameObject.transform))
{
pos.Add(gameObject.transform.position);
names.Add(cat.ConfigName + " (" + ((Object)gameObject).name + ")");
}
}
}
}
private void AddItemTargets(Category cat, List<Vector3> pos, List<string> names)
{
//IL_0030: 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_006d: Unknown result type (might be due to invalid IL or missing references)
Item[] array = Resources.FindObjectsOfTypeAll<Item>();
foreach (Item val in array)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null))
{
GameObject gameObject = ((Component)val).gameObject;
Scene scene = gameObject.scene;
if (((Scene)(ref scene)).IsValid() && !IsExcluded(gameObject.transform) && MatchKeys(((Object)gameObject).name.ToLowerInvariant(), cat.Keywords))
{
pos.Add(gameObject.transform.position);
names.Add("Item (" + ((Object)gameObject).name + ")");
}
}
}
}
private bool IsExcluded(Transform t)
{
if ((Object)(object)t == (Object)null)
{
return true;
}
if ((Object)(object)_root != (Object)null && (Object)(object)t.root == (Object)(object)_root.transform)
{
return true;
}
foreach (Transform excludeChar in _excludeChars)
{
if ((Object)(object)excludeChar != (Object)null && IsDescendant(t, excludeChar))
{
return true;
}
}
return false;
}
private static bool IsDescendant(Transform t, Transform root)
{
Transform val = t;
while ((Object)(object)val != (Object)null)
{
if ((Object)(object)val == (Object)(object)root)
{
return true;
}
val = val.parent;
}
return false;
}
private static bool MatchKeys(string lowerName, List<string> keys)
{
foreach (string key in keys)
{
if (key.Length > 0 && lowerName.Contains(key))
{
return true;
}
}
return false;
}
private static void Cluster(List<Vector3> srcPos, List<string> srcNames, List<Vector3> outPos, List<string> outNames, float radius)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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_0080: 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)
outPos.Clear();
outNames.Clear();
if (srcPos.Count == 0)
{
return;
}
List<int> list = new List<int>(8);
for (int i = 0; i < srcPos.Count; i++)
{
Vector3 val = srcPos[i];
bool flag = false;
for (int j = 0; j < outPos.Count; j++)
{
if (Vector3.Distance(outPos[j], val) <= radius)
{
if (val.y > outPos[j].y)
{
outPos[j] = val;
list[j] = i;
}
flag = true;
break;
}
}
if (!flag)
{
outPos.Add(val);
list.Add(i);
}
}
foreach (int item in list)
{
outNames.Add(srcNames[item]);
}
}
private static List<string> SplitList(string s)
{
List<string> list = new List<string>();
if (string.IsNullOrEmpty(s))
{
return list;
}
string[] array = s.Split(',');
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim().ToLowerInvariant();
if (text.Length > 0)
{
list.Add(text);
}
}
return list;
}
private static string FmtVec(Vector3 v)
{
return "(" + v.x.ToString("F0") + ", " + v.y.ToString("F0") + ", " + v.z.ToString("F0") + ")";
}
private unsafe static string KeyText(ConfigEntry<KeyboardShortcut> entry)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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_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)
KeyboardShortcut value = entry.Value;
KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
if ((int)mainKey != 0)
{
return ((object)(*(KeyCode*)(&mainKey))/*cast due to .constrained prefix*/).ToString();
}
return "(无)";
}
private unsafe static string KeyShortLabel(KeyboardShortcut ks)
{
//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_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_001f: 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_0010: Invalid comparison between Unknown and I4
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected I4, but got Unknown
KeyCode mainKey = ((KeyboardShortcut)(ref ks)).MainKey;
if ((int)mainKey >= 48 && (int)mainKey <= 57)
{
return (mainKey - 48).ToString();
}
if ((int)mainKey != 0)
{
return ((object)(*(KeyCode*)(&mainKey))/*cast due to .constrained prefix*/).ToString();
}
return "-";
}
private static Color ParseHexColor(string hex, Color fallback)
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: 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_009c: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(hex))
{
return fallback;
}
string text = hex.TrimStart('#');
if (text.Length < 6)
{
return fallback;
}
try
{
float num = (float)Convert.ToInt32(text.Substring(0, 2), 16) / 255f;
float num2 = (float)Convert.ToInt32(text.Substring(2, 2), 16) / 255f;
float num3 = (float)Convert.ToInt32(text.Substring(4, 2), 16) / 255f;
float num4 = ((text.Length >= 8) ? ((float)Convert.ToInt32(text.Substring(6, 2), 16) / 255f) : 1f);
return new Color(num, num2, num3, num4);
}
catch
{
return fallback;
}
}
private void EnsureClimb(MapHandler map)
{
if (_climbLoaded && (Object)(object)_mphMap == (Object)(object)map)
{
return;
}
_mphMap = map;
if ((Object)(object)map == (Object)null)
{
_climbLoaded = false;
_climbNames.Clear();
return;
}
try
{
_climbNames.Clear();
_mph = Object.FindObjectOfType<MountainProgressHandler>();
if ((Object)(object)_mph == (Object)null)
{
return;
}
ProgressPoint[] progressPoints = _mph.progressPoints;
if (progressPoints == null || progressPoints.Length == 0)
{
return;
}
ProgressPoint[] array = progressPoints;
foreach (ProgressPoint val in array)
{
if (val == null)
{
continue;
}
string text = "";
try
{
text = val.title ?? "";
}
catch
{
}
if (text.Length == 0)
{
try
{
text = val.localizedTitle ?? "";
}
catch
{
}
}
string text2 = BiomeEn(text);
if (text2.Length != 0)
{
_climbNames.Add(text2);
}
}
_climbLoaded = _climbNames.Count > 0;
}
catch (Exception ex)
{
_climbLoaded = false;
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 读取今日爬升序列失败(下次扫描重试): " + ex.Message));
}
}
private static bool IsKnownCanon(string canon)
{
switch (NormalizeKey(canon))
{
case "shore":
case "beach":
case "roots":
case "gloom":
case "swamp":
case "ocean":
case "nadir":
case "tropics":
case "citadel":
case "caldera":
case "volcano":
case "thekiln":
case "thepeak":
case "jungle":
case "forest":
case "alpine":
case "desert":
case "temple":
case "heaven":
case "snow":
case "mesa":
case "kiln":
case "peak":
case "hell":
case "mars":
case "void":
case "grasslands":
case "thecitadel":
case "skyblock":
case "wisconsin":
return true;
default:
return false;
}
}
private static string CanonicalOfSegment(MapSegment seg)
{
try
{
GameObject segmentParent = seg.segmentParent;
if ((Object)(object)segmentParent != (Object)null)
{
string text = CleanRootName(((Object)segmentParent).name);
if (text.Length > 0 && IsKnownCanon(text))
{
return BiomeEn(text);
}
}
}
catch
{
}
string text2 = BiomeName(seg);
if (text2.Length == 0)
{
return "";
}
string text3 = BiomeEn(text2);
if (!IsKnownCanon(text3))
{
return "";
}
return text3;
}
private string SegmentCnAt(List<MapSegment> order, int i)
{
if (_climbOrderAligned && i < _climbNames.Count)
{
return BiomeCn(_climbNames[i]);
}
string text = CanonicalOfSegment(order[i]);
if (text.Length > 0)
{
return BiomeCn(text);
}
return BiomeCn(BiomeName(order[i]));
}
private static string SegDebugInfo(MapSegment seg)
{
if (seg == null)
{
return "?";
}
try
{
GameObject segmentParent = seg.segmentParent;
return "容器:" + (((Object)(object)segmentParent != (Object)null) ? ((Object)segmentParent).name : "(无)") + ", biome:" + BiomeName(seg);
}
catch
{
return "?";
}
}
private static KeyCode DefaultCategoryKey(int index)
{
return (KeyCode)(index switch
{
1 => 53,
2 => 54,
3 => 55,
4 => 56,
5 => 57,
6 => 48,
_ => 290,
});
}
private void BindLuggageConfig()
{
_luggageExport = ((BaseUnityPlugin)this).Config.Bind<bool>("Export", "ExportEnabled", true, "小丑行李结果变化时自动导出每日报告(txt/json/latest.json → plugins/ClownLuggageFinder/reports,无坐标)");
}
private void ResetLuggageSession()
{
RefreshMapSorting(null);
_luggageSig = "";
_luggageLogSig = "";
_luggageSummary = "";
_luggageOpenedCount = 0;
_clownHits.Clear();
_climbOrderAligned = false;
_climbAlignWarned = false;
}
private void RefreshMapSorting(MapHandler map)
{
_mapSortingCn = "";
_mapSortingEn = "";
_mapSegCount = 0;
if ((Object)(object)map == (Object)null)
{
return;
}
EnsureClimb(map);
if (_climbNames.Count >= 2)
{
StringBuilder stringBuilder = new StringBuilder();
StringBuilder stringBuilder2 = new StringBuilder();
foreach (string climbName in _climbNames)
{
string value = BiomeCn(climbName);
if (stringBuilder.Length > 0)
{
stringBuilder.Append(",");
}
stringBuilder.Append(value);
if (stringBuilder2.Length > 0)
{
stringBuilder2.Append(">");
}
stringBuilder2.Append(climbName);
_mapSegCount++;
}
_mapSortingCn = stringBuilder.ToString();
_mapSortingEn = stringBuilder2.ToString();
}
else
{
if (map.segments == null)
{
return;
}
StringBuilder stringBuilder3 = new StringBuilder();
StringBuilder stringBuilder4 = new StringBuilder();
MapSegment[] segments = map.segments;
foreach (MapSegment val in segments)
{
if (val == null)
{
continue;
}
string text = BiomeName(val);
if (text.Length != 0)
{
string value2 = BiomeCn(text);
string value3 = BiomeEn(text);
if (stringBuilder3.Length > 0)
{
stringBuilder3.Append(",");
}
stringBuilder3.Append(value2);
if (stringBuilder4.Length > 0)
{
stringBuilder4.Append(">");
}
stringBuilder4.Append(value3);
_mapSegCount++;
}
}
_mapSortingCn = stringBuilder3.ToString();
_mapSortingEn = stringBuilder4.ToString();
}
}
private void ScanLuggage(Category cat, MapHandler map)
{
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: 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_0155: 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_047a: Unknown result type (might be due to invalid IL or missing references)
cat.LivePos.Clear();
cat.LiveNames.Clear();
_clownHits.Clear();
_luggageSummary = "";
_luggageOpenedCount = 0;
if ((Object)(object)map == (Object)null)
{
return;
}
EnsureClimb(map);
List<MapSegment> list = OrderedSegments(map);
if (list.Count == 0)
{
return;
}
_climbOrderAligned = _climbNames.Count == list.Count;
if (!_climbOrderAligned && !_climbAlignWarned && _climbNames.Count > 0)
{
_climbAlignWarned = true;
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 爬升点数(" + _climbNames.Count + ")与段数(" + list.Count + ")不一致,行李段名回退 biome 解析(变体段可能标错)"));
}
Luggage[] array = null;
try
{
array = Resources.FindObjectsOfTypeAll<Luggage>();
}
catch
{
}
if (array == null || array.Length == 0)
{
try
{
array = Object.FindObjectsOfType<Luggage>();
}
catch
{
}
}
if (array == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"[PEAKFinder] 小丑行李扫描失败:Luggage 查询抛出异常");
return;
}
int num = 0;
Luggage[] array2 = array;
foreach (Luggage val in array2)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
if ((Object)(object)((Component)val).gameObject == (Object)null)
{
continue;
}
Scene scene = ((Component)val).gameObject.scene;
if (!((Scene)(ref scene)).IsValid())
{
continue;
}
string text = "";
try
{
text += val.displayName;
}
catch
{
}
try
{
text = text + " " + ((Object)((Component)val).gameObject).name;
}
catch
{
}
try
{
text = text + " " + val.GetName();
}
catch
{
}
if (!text.ToLowerInvariant().Contains("clown"))
{
continue;
}
LuggageHit luggageHit = new LuggageHit();
try
{
Transform transform = val.GetTransform();
luggageHit.Pos = (((Object)(object)transform != (Object)null) ? transform.position : ((Component)val).gameObject.transform.position);
}
catch
{
num++;
goto end_IL_013f;
}
try
{
luggageHit.Open = val.IsOpen;
}
catch
{
}
bool active = false;
try
{
active = ((Component)val).gameObject.activeInHierarchy;
}
catch
{
}
int num2 = LocateSegmentIndex(list, val, active);
if (num2 < 0)
{
continue;
}
luggageHit.SegIdx = num2;
int num3 = num2;
if (!_climbOrderAligned)
{
string text2 = CanonicalOfSegment(list[num2]);
int num4 = ((text2.Length > 0) ? _climbNames.IndexOf(text2) : (-1));
if (num4 >= 0)
{
num3 = num4;
}
}
luggageHit.SegLabel = "第" + (num3 + 1) + "段·" + SegmentCnAt(list, num2) + TodayVariantSuffix(num2);
_clownHits.Add(luggageHit);
end_IL_013f:;
}
catch
{
num++;
}
}
if (num > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 小丑行李扫描有 " + num + " 个对象处理异常(已跳过)"));
}
_clownHits.Sort(CompareBySeg);
StringBuilder stringBuilder = new StringBuilder();
int num5 = 0;
for (int j = 0; j < _clownHits.Count; j++)
{
LuggageHit luggageHit2 = _clownHits[j];
if (luggageHit2.Open)
{
num5++;
}
int num6 = 1;
for (; j + 1 < _clownHits.Count && _clownHits[j + 1].SegIdx == luggageHit2.SegIdx; j++)
{
if (_clownHits[j + 1].Open)
{
num5++;
}
num6++;
}
if (stringBuilder.Length > 0)
{
stringBuilder.Append("、");
}
stringBuilder.Append(luggageHit2.SegLabel);
if (num6 > 1)
{
stringBuilder.Append("×" + num6);
}
}
_luggageSummary = stringBuilder.ToString();
_luggageOpenedCount = num5;
foreach (LuggageHit clownHit in _clownHits)
{
cat.LivePos.Add(clownHit.Pos);
cat.LiveNames.Add(clownHit.SegLabel + (clownHit.Open ? "(已开)" : "(未开)"));
}
string text3 = "";
foreach (LuggageHit clownHit2 in _clownHits)
{
text3 = text3 + clownHit2.SegIdx + ":" + (clownHit2.Open ? "1" : "0") + ";";
}
if (text3 != _luggageSig)
{
_luggageSig = text3;
if (_luggageExport.Value)
{
TryExportLuggageReport(map, list);
}
}
if (!(text3 != _luggageLogSig))
{
return;
}
_luggageLogSig = text3;
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 小丑行李 " + ((_clownHits.Count > 0) ? ("共 " + _clownHits.Count + ":" + _luggageSummary) : "本图未发现")));
if (_clownHits.Count <= 0)
{
return;
}
StringBuilder stringBuilder2 = new StringBuilder();
foreach (LuggageHit clownHit3 in _clownHits)
{
MapSegment seg = ((clownHit3.SegIdx >= 0 && clownHit3.SegIdx < list.Count) ? list[clownHit3.SegIdx] : null);
if (stringBuilder2.Length > 0)
{
stringBuilder2.Append(" | ");
}
stringBuilder2.Append(clownHit3.SegLabel).Append(" <- ").Append(SegDebugInfo(seg));
}
stringBuilder2.Append(";爬升序列 ").Append(_climbNames.Count).Append(" 项 / 段列表 ")
.Append(list.Count)
.Append(" 项")
.Append(_climbOrderAligned ? "(对齐)" : "(未对齐)");
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 段位解析: " + stringBuilder2.ToString()));
}
private static int CompareBySeg(LuggageHit a, LuggageHit b)
{
return a.SegIdx.CompareTo(b.SegIdx);
}
private static List<MapSegment> OrderedSegments(MapHandler map)
{
List<MapSegment> list = new List<MapSegment>();
if ((Object)(object)map == (Object)null || map.segments == null)
{
return list;
}
MapSegment[] segments = map.segments;
foreach (MapSegment val in segments)
{
if (val != null && BiomeName(val).Length != 0)
{
list.Add(val);
}
}
return list;
}
private static int LocateSegmentIndex(List<MapSegment> order, Luggage l, bool active)
{
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
//IL_022c: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Unknown result type (might be due to invalid IL or missing references)
try
{
Transform transform = l.GetTransform();
if ((Object)(object)transform == (Object)null)
{
transform = ((Component)l).gameObject.transform;
}
Transform val = transform;
while ((Object)(object)val != (Object)null)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null))
{
for (int i = 0; i < order.Count; i++)
{
if (GameObjectEquals(order[i].segmentParent, ((Component)val).gameObject) || GameObjectEquals(order[i].segmentCampfire, ((Component)val).gameObject))
{
return i;
}
}
}
val = val.parent;
}
}
catch
{
}
try
{
Transform transform2 = l.GetTransform();
if ((Object)(object)transform2 == (Object)null)
{
transform2 = ((Component)l).gameObject.transform;
}
Transform val2 = transform2;
while ((Object)(object)val2 != (Object)null)
{
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).gameObject == (Object)null))
{
string text = CleanRootName(((Object)((Component)val2).gameObject).name);
if (text.Length != 0)
{
int result = -1;
int num = 0;
for (int j = 0; j < order.Count; j++)
{
if (NormalizeKey(text) == NormalizeKey(BiomeName(order[j])))
{
num++;
result = j;
}
}
if (num == 1)
{
return result;
}
}
}
val2 = val2.parent;
}
}
catch
{
}
if (active)
{
try
{
MapSegment currentMapSegment = MapHandler.CurrentMapSegment;
if (currentMapSegment != null)
{
for (int k = 0; k < order.Count; k++)
{
if (GameObjectEquals(order[k].segmentParent, currentMapSegment.segmentParent) || GameObjectEquals(order[k].segmentCampfire, currentMapSegment.segmentCampfire))
{
return k;
}
}
}
}
catch
{
}
}
try
{
Transform transform3 = l.GetTransform();
if ((Object)(object)transform3 == (Object)null)
{
transform3 = ((Component)l).gameObject.transform;
}
if ((Object)(object)transform3 != (Object)null)
{
int result2 = -1;
float num2 = float.MaxValue;
for (int m = 0; m < order.Count; m++)
{
GameObject segmentParent = order[m].segmentParent;
if (!((Object)(object)segmentParent == (Object)null))
{
Vector3 val3 = segmentParent.transform.position - transform3.position;
float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
if (sqrMagnitude < num2)
{
num2 = sqrMagnitude;
result2 = m;
}
}
}
return result2;
}
}
catch
{
}
return -1;
}
private static bool GameObjectEquals(GameObject a, GameObject b)
{
if ((Object)(object)a != (Object)null && (Object)(object)b != (Object)null)
{
return (Object)(object)a == (Object)(object)b;
}
return false;
}
private void TryExportLuggageReport(MapHandler map, List<MapSegment> order)
{
try
{
if (!_luggageExport.Value || (Object)(object)map == (Object)null || !MapHandler.Exists || !MapHandler.ExistsAndInitialized)
{
return;
}
if (_clownHits.Count == 0)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PEAKFinder] 小丑行李报告:当前地图未发现,跳过导出");
return;
}
string text = Path.Combine(Paths.PluginPath, "ClownLuggageFinder", "reports");
try
{
Directory.CreateDirectory(text);
}
catch
{
}
string text2 = DateTime.Now.ToString("yyyy-MM-dd");
string text3 = Path.Combine(text, "clown_luggage_" + text2);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("=== PEAK 小丑行李每日报告(不含坐标) ===");
stringBuilder.AppendLine("日期: " + text2);
stringBuilder.AppendLine("生成时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
stringBuilder.AppendLine("山峰排序(中文): " + _mapSortingCn);
if (_mapSortingDetailCn.Length > 0)
{
stringBuilder.AppendLine("山峰排序(含变体): " + _mapSortingDetailCn);
}
stringBuilder.AppendLine("山峰排序(英文): " + _mapSortingEn);
stringBuilder.AppendLine("小丑行李数量: " + _clownHits.Count);
stringBuilder.AppendLine("");
int num = 1;
foreach (LuggageHit clownHit in _clownHits)
{
stringBuilder.AppendLine("小丑行李 #" + num + ":");
stringBuilder.AppendLine(" 位置: " + clownHit.SegLabel);
stringBuilder.AppendLine(" 状态: " + (clownHit.Open ? "已打开" : "未打开"));
stringBuilder.AppendLine("");
num++;
}
File.WriteAllText(text3 + ".txt", stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
StringBuilder stringBuilder2 = new StringBuilder();
stringBuilder2.Append("{\"date\":\"" + DateTime.Now.ToString("M月d日") + "\",");
stringBuilder2.Append("\"map\":\"" + JsonEsc(_mapSortingEn) + "\",");
stringBuilder2.Append("\"MapSorting\":\"" + JsonEsc(_mapSortingCn) + "\",");
if (_mapSortingDetailCn.Length > 0)
{
stringBuilder2.Append("\"MapSortingDetail\":\"" + JsonEsc(_mapSortingDetailCn) + "\",");
}
stringBuilder2.Append("\"num\":" + _clownHits.Count + ",");
StringBuilder stringBuilder3 = new StringBuilder();
bool flag = true;
for (int i = 0; i < order.Count; i++)
{
int num2 = 0;
foreach (LuggageHit clownHit2 in _clownHits)
{
if (clownHit2.SegIdx == i)
{
num2++;
}
}
if (num2 != 0)
{
if (!flag)
{
stringBuilder3.Append(",");
}
flag = false;
stringBuilder3.Append("\"" + JsonEsc(SegmentCnAt(order, i) + TodayVariantSuffix(i)) + "\":" + num2);
}
}
stringBuilder2.Append("\"segments\":{" + stringBuilder3.ToString() + "},");
stringBuilder2.Append("\"location\":[");
bool flag2 = true;
foreach (LuggageHit clownHit3 in _clownHits)
{
if (!flag2)
{
stringBuilder2.Append(",");
}
flag2 = false;
stringBuilder2.Append("{\"segment\":\"" + JsonEsc(clownHit3.SegLabel) + "\",\"open\":" + (clownHit3.Open ? "true" : "false") + "}");
}
stringBuilder2.Append("],");
stringBuilder2.Append("\"totalnum\":" + _clownHits.Count);
stringBuilder2.Append("}");
string contents = stringBuilder2.ToString();
File.WriteAllText(text3 + ".json", contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
File.WriteAllText(Path.Combine(text, "latest.json"), contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 小丑行李报告已导出: " + text3 + ".txt"));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[PEAKFinder] 小丑行李报告导出失败: " + ex));
}
}
private static string BiomeName(MapSegment seg)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
try
{
string text = ((object)seg.biome/*cast due to .constrained prefix*/).ToString();
if (!string.IsNullOrEmpty(text) && text != "0")
{
return text;
}
}
catch
{
}
try
{
GameObject segmentParent = seg.segmentParent;
if ((Object)(object)segmentParent != (Object)null)
{
string text2 = CleanRootName(((Object)segmentParent).name);
if (text2.Length > 0)
{
return text2;
}
}
}
catch
{
}
return "";
}
private static string BiomeCn(string en)
{
switch (NormalizeKey(en))
{
case "shore":
case "beach":
return "海岸";
case "tropics":
case "jungle":
return "雨林";
case "roots":
case "forest":
return "森林";
case "alpine":
case "snow":
return "雪山";
case "desert":
case "mesa":
return "方山";
case "gloom":
case "swamp":
return "雾沼";
case "citadel":
case "temple":
case "thecitadel":
return "城塞";
case "caldera":
case "volcano":
return "火山";
case "thekiln":
case "kiln":
return "熔炉";
case "thepeak":
case "peak":
return "顶峰";
case "grasslands":
return "草原";
case "ocean":
return "海洋";
case "skyblock":
return "浮岛";
case "hell":
return "地狱";
case "heaven":
return "天堂";
case "mars":
return "火星";
case "wisconsin":
return "威斯康星";
case "void":
return "虚空";
case "nadir":
return "深渊";
default:
if (en != null)
{
return en.Trim();
}
return "";
}
}
private static string BiomeEn(string en)
{
switch (NormalizeKey(en))
{
case "shore":
case "beach":
return "Shore";
case "tropics":
case "jungle":
return "Tropics";
case "roots":
case "forest":
return "Roots";
case "alpine":
case "snow":
return "Alpine";
case "desert":
case "mesa":
return "Mesa";
case "gloom":
case "swamp":
return "Gloom";
case "citadel":
case "temple":
case "thecitadel":
return "The Citadel";
case "caldera":
case "volcano":
return "Caldera";
case "thekiln":
case "kiln":
return "The Kiln";
case "thepeak":
case "peak":
return "The Peak";
case "grasslands":
return "Grasslands";
case "ocean":
return "Ocean";
case "skyblock":
return "Skyblock";
case "hell":
return "Hell";
case "heaven":
return "Heaven";
case "mars":
return "Mars";
case "wisconsin":
return "Wisconsin";
case "void":
return "Void";
case "nadir":
return "Nadir";
default:
if (en != null)
{
return en.Trim();
}
return "";
}
}
private static string NormalizeKey(string en)
{
if (en == null)
{
return "";
}
StringBuilder stringBuilder = new StringBuilder();
string text = en.ToLowerInvariant();
foreach (char c in text)
{
if (c != '_' && c != '-' && c != ' ' && c != '.')
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString();
}
private static string CleanRootName(string n)
{
if (n == null)
{
return "";
}
return n.Replace("_Segment", "").Replace("Segment", "").Replace("_Campfire", "")
.Replace("Campfire", "")
.Trim()
.Trim('_', '-', ' ', '.');
}
private static string JsonEsc(string s)
{
if (s == null)
{
return "";
}
return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
}
internal void BindTodayConfig()
{
_todayExport = ((BaseUnityPlugin)this).Config.Bind<bool>("Export", "ExportTodayMapDetail", true, "今日地图详情变化时自动导出 json(plugins/ClownLuggageFinder/reports/today_map_*.json,无坐标);Ctrl+F1 重扫也会导出");
}
internal static bool BiomeHasVariant(int biome)
{
if (biome != 0 && biome != 1 && biome != 2 && biome != 6)
{
return biome == 7;
}
return true;
}
private void RebuildToday(MapHandler map)
{
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected I4, but got Unknown
_today.Clear();
_todayDetailCn = "";
if ((Object)(object)map == (Object)null)
{
return;
}
List<MapSegment> list = OrderedSegments(map);
if (_climbNames.Count == 0 || list.Count == 0)
{
return;
}
bool flag = _climbNames.Count == list.Count;
int num = (flag ? _climbNames.Count : list.Count);
for (int i = 0; i < num; i++)
{
TodaySeg todaySeg = new TodaySeg
{
Index = i
};
todaySeg.Canon = (flag ? _climbNames[i] : BiomeEn(BiomeName(list[i])));
try
{
todaySeg.Biome = (int)list[i].biome;
}
catch
{
todaySeg.Biome = -1;
}
_today.Add(todaySeg);
}
_todayAligned = flag;
}
private void RefreshTodayDetail(MapHandler map, bool forceExport)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)map == (Object)null)
{
_todayMapSig = "";
_todayExportSig = "";
_today.Clear();
_todayDetailCn = "";
return;
}
Scene scene = ((Component)map).gameObject.scene;
string text = ((Scene)(ref scene)).name + "|" + string.Join(">", _climbNames.ToArray());
if (text != _todayMapSig || _today.Count == 0)
{
_todayMapSig = text;
RebuildToday(map);
}
if (_today.Count == 0)
{
return;
}
List<MapSegment> order = OrderedSegments(map);
bool flag = false;
for (int i = 0; i < _today.Count; i++)
{
TodaySeg todaySeg = _today[i];
if (todaySeg.Done || !BiomeHasVariant(todaySeg.Biome))
{
continue;
}
bool parentActive;
string text2 = ResolveSegmentVariant(order, i, todaySeg.Biome, out parentActive);
if (text2 != null)
{
todaySeg.Done = text2.Length > 0 || parentActive;
if (text2.Length > 0 && text2 != todaySeg.VariantEn)
{
todaySeg.VariantEn = text2;
todaySeg.VariantCn = LocalizeVariant(todaySeg.Biome, text2);
flag = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 今日变体: 段" + (i + 1) + "·" + todaySeg.Canon + " = " + text2 + ((todaySeg.VariantCn.Length > 0) ? ("(" + todaySeg.VariantCn + ")") : "")));
}
}
}
if (flag)
{
RefreshDetailString();
}
if (forceExport || flag)
{
string text3 = _todayMapSig + "|" + BuildDetailCanons();
if (forceExport || text3 != _todayExportSig)
{
_todayExportSig = text3;
TryExportTodayDetail(map);
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 今日变体解析失败: " + ex.Message));
}
}
private string ResolveSegmentVariant(List<MapSegment> order, int i, int biome, out bool parentActive)
{
parentActive = false;
try
{
if (i >= order.Count)
{
return null;
}
GameObject segmentParent = order[i].segmentParent;
if ((Object)(object)segmentParent == (Object)null)
{
return null;
}
parentActive = segmentParent.activeInHierarchy;
string text = CollectChosenVariantName(segmentParent, biome, parentActive);
if (text != null)
{
return text;
}
Transform parent = segmentParent.transform.parent;
if ((Object)(object)parent != (Object)null && (Object)(object)((Component)parent).gameObject != (Object)null && (Object)(object)((Component)parent).gameObject != (Object)(object)segmentParent)
{
string text2 = CollectChosenVariantName(((Component)parent).gameObject, biome, ((Component)parent).gameObject.activeInHierarchy);
if (text2 != null)
{
parentActive = true;
return text2;
}
}
return parentActive ? "" : null;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[PEAKFinder] 段变体读取异常: " + ex.Message));
return parentActive ? "" : null;
}
}
private string CollectChosenVariantName(GameObject root, int biome, bool rootActive)
{
if ((Object)(object)root == (Object)null)
{
return null;
}
if (biome == 6 || biome == 7)
{
List<string> list = new List<string>();
VariantObject[] componentsInChildren = root.GetComponentsInChildren<VariantObject>(true);
if (componentsInChildren == null)
{
return null;
}
VariantObject[] array = componentsInChildren;
foreach (VariantObject val in array)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null))
{
GameObject gameObject = ((Component)val).gameObject;
if (rootActive ? gameObject.activeInHierarchy : gameObject.activeSelf)
{
list.Add(((Object)gameObject).name);
}
}
}
HashSet<string> hashSet = ((biome == 6) ? MesaKnownVariants : RootsKnownVariants);
foreach (string item in list)
{
if (hashSet.Contains(item))
{
return CleanVariant(biome, item);
}
}
foreach (string item2 in list)
{
if (item2.Equals("Default", StringComparison.Ordinal))
{
return CleanVariant(biome, item2);
}
}
if (list.Count == 0)
{
return null;
}
return CleanVariant(biome, list[0]);
}
List<string> list2 = new List<string>();
BiomeVariant[] componentsInChildren2 = root.GetComponentsInChildren<BiomeVariant>(true);
if (componentsInChildren2 == null)
{
return null;
}
BiomeVariant[] array2 = componentsInChildren2;
foreach (BiomeVariant val2 in array2)
{
if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null)
{
continue;
}
GameObject gameObject2 = ((Component)val2).gameObject;
if (rootActive ? gameObject2.activeInHierarchy : gameObject2.activeSelf)
{
string name = ((Object)gameObject2).name;
if (!string.IsNullOrWhiteSpace(name) && !list2.Contains(name))
{
list2.Add(name.Trim());
}
}
}
if (list2.Count == 0)
{
return null;
}
return CleanVariant(biome, list2[0]);
}
private static string CleanVariant(int biome, string variant)
{
switch (biome)
{
case 6:
if (variant.Equals("NoVariant", StringComparison.Ordinal))
{
return "Default";
}
if (variant.Equals("CacusHell", StringComparison.Ordinal))
{
return "CactusHell";
}
return variant;
default:
return variant;
case 7:
{
string[] array = variant.Split(' ', '-');
if (array.Length <= 1)
{
return variant;
}
for (int i = 0; i < array.Length; i++)
{
string text = array[i];
if (text.Length > 0)
{
text = char.ToUpperInvariant(text[0]) + text.Substring(1).ToLowerInvariant();
}
if (RootsStructuralNames.Contains(text))
{
text = "";
}
array[i] = text;
}
return string.Join("", array);
}
}
}
private static string LocalizeVariant(int biome, string variant)
{
if (VariantCnMap.TryGetValue(biome, out var value) && value.TryGetValue(variant, out var value2))
{
return value2;
}
return variant;
}
private void RefreshDetailString()
{
_todayDetailCn = "";
if (!_todayAligned || _today.Count == 0)
{
return;
}
StringBuilder stringBuilder = new StringBuilder();
foreach (TodaySeg item in _today)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append(",");
}
stringBuilder.Append(BiomeCn(item.Canon));
if (item.VariantCn.Length > 0)
{
stringBuilder.Append('(').Append(item.VariantCn).Append(')');
}
}
_todayDetailCn = stringBuilder.ToString();
}
private string BuildDetailCanons()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (TodaySeg item in _today)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append('>');
}
stringBuilder.Append(item.Canon);
if (item.VariantEn.Length > 0)
{
stringBuilder.Append('(').Append(item.VariantEn).Append(')');
}
}
return stringBuilder.ToString();
}
private string TodayVariantSuffix(int segIdx)
{
if (!_todayAligned || segIdx < 0 || segIdx >= _today.Count)
{
return "";
}
TodaySeg todaySeg = _today[segIdx];
if (todaySeg.VariantCn.Length <= 0)
{
return "";
}
return "(" + todaySeg.VariantCn + ")";
}
private static string SafeFileName(string n)
{
if (string.IsNullOrEmpty(n))
{
return "level";
}
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
StringBuilder stringBuilder = new StringBuilder();
foreach (char c in n)
{
bool flag = false;
char[] array = invalidFileNameChars;
foreach (char c2 in array)
{
if (c == c2)
{
flag = true;
break;
}
}
stringBuilder.Append(flag ? '_' : c);
}
return stringBuilder.ToString();
}
private void TryExportTodayDetail(MapHandler map)
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!_todayExport.Value || (Object)(object)map == (Object)null || _today.Count == 0 || !MapHandler.Exists || !MapHandler.ExistsAndInitialized)
{
return;
}
string text = Path.Combine(Paths.PluginPath, "ClownLuggageFinder", "reports");
try
{
Directory.CreateDirectory(text);
}
catch
{
}
string text2 = DateTime.Now.ToString("yyyy-MM-dd");
string text3 = Path.Combine(text, "today_map_" + text2);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("{\"date\":\"" + DateTime.Now.ToString("M月d日") + "\",");
Scene scene = ((Component)map).gameObject.scene;
stringBuilder.Append("\"level\":\"" + JsonEsc(SafeFileName(((Scene)(ref scene)).name)) + "\",");
stringBuilder.Append("\"map\":\"" + JsonEsc(BuildDetailCanons()) + "\",");
stringBuilder.Append("\"MapSorting\":\"" + JsonEsc((_mapSortingDetailCn.Length > 0) ? _mapSortingDetailCn : _mapSortingCn) + "\",");
stringBuilder.Append("\"num\":" + _today.Count + ",");
stringBuilder.Append("\"segments\":[");
bool flag = true;
foreach (TodaySeg item in _today)
{
if (!flag)
{
stringBuilder.Append(",");
}
flag = false;
string text4 = BiomeCn(item.Canon);
stringBuilder.Append("{\"index\":" + item.Index + ",");
stringBuilder.Append("\"label\":\"" + JsonEsc("第" + (item.Index + 1) + "段·" + text4 + TodayVariantSuffix(item.Index)) + "\",");
stringBuilder.Append("\"biome\":\"" + JsonEsc(item.Canon) + "\",");
stringBuilder.Append("\"biome_cn\":\"" + JsonEsc(text4) + "\",");
stringBuilder.Append("\"variant\":\"" + JsonEsc(item.VariantEn) + "\",");
stringBuilder.Append("\"variant_cn\":\"" + JsonEsc(item.VariantCn) + "\"}");
}
stringBuilder.Append("]}");
string contents = stringBuilder.ToString();
File.WriteAllText(text3 + ".json", contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
File.WriteAllText(Path.Combine(text, "today_map_latest.json"), contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PEAKFinder] 今日地图详情已导出: " + text3 + ".json" + ((_mapSortingDetailCn.Length > 0) ? ("(" + _mapSortingDetailCn + ")") : "")));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[PEAKFinder] 今日地图详情导出失败: " + ex));
}
}
}