using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Peak;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace BelltowerFinder;
[BepInPlugin("com.dsh.belltowerfinder", "Bell Tower Finder", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
private ConfigEntry<float> _scanInterval;
private ConfigEntry<KeyboardShortcut> _toggleKey;
private ConfigEntry<KeyboardShortcut> _rescanKey;
private ConfigEntry<KeyboardShortcut> _panelKey;
private ConfigEntry<bool> _showBeacons;
private ConfigEntry<string> _beaconColorHex;
private ConfigEntry<float> _beaconHeight;
private ConfigEntry<bool> _gloomOnly;
private ConfigEntry<string> _nameFilter;
private ConfigEntry<float> _clusterRadius;
private ConfigEntry<bool> _includeJesterBells;
private ConfigEntry<bool> _logAll;
private bool _showPanel = true;
private float _nextScanTime;
private string _status = "";
private readonly List<Vector3> _towers = new List<Vector3>();
private readonly List<string> _towerNames = new List<string>();
private GameObject _root;
private BeaconRenderer _beacons;
private void Awake()
{
//IL_0042: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: Expected O, but got Unknown
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0225: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: 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_0288: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
_scanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScanInterval", 2f, "扫描间隔(秒)");
_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)291, (KeyCode[])(object)new KeyCode[0]), "开关光柱(F6 被其他 mod 占用,默认 F10)");
_rescanKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "RescanKey", new KeyboardShortcut((KeyCode)292, (KeyCode[])(object)new KeyCode[0]), "立即重新扫描");
_panelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "PanelKey", new KeyboardShortcut((KeyCode)277, (KeyCode[])(object)new KeyCode[0]), "开关左上角信息面板");
_showBeacons = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowBeacons", true, "是否显示黄色光柱");
_beaconColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Visual", "BeaconColorHex", "#FFCC00FF", "光柱颜色(HEX RRGGBBAA)");
_beaconHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "BeaconHeight", 150f, "光柱高度");
_gloomOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "GloomOnly", true, "只显示雾沼(Gloom/Swamp)段里的钟塔");
_nameFilter = ((BaseUnityPlugin)this).Config.Bind<string>("Scan", "NameFilter", "bell,tower,belfry", "按名字匹配钟塔的关键词,逗号分隔");
_clusterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "ClusterRadius", 50f, "同一座钟塔的零件归类半径");
_includeJesterBells = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "IncludeJesterBells", true, "把雾沼段里的 JesterBells 也算作钟(游戏里钟塔上的钟)");
_logAll = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogAllMatches", false, "把每次扫描命中的物体都打到日志(找名字用)");
_root = new GameObject("BelltowerFinderBeacons");
Object.DontDestroyOnLoad((Object)(object)_root);
_beacons = _root.AddComponent<BeaconRenderer>();
_beacons.color = ParseHexColor(_beaconColorHex.Value, new Color(1f, 0.8f, 0f, 1f));
_beacons.height = Mathf.Max(10f, _beaconHeight.Value);
((Behaviour)_beacons).enabled = _showBeacons.Value;
ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
object[] array = new object[7] { "[BelltowerFinder] loaded. ", null, null, null, null, null, null };
KeyboardShortcut value = _toggleKey.Value;
array[1] = ((KeyboardShortcut)(ref value)).MainKey;
array[2] = "=toggle beacons, ";
value = _rescanKey.Value;
array[3] = ((KeyboardShortcut)(ref value)).MainKey;
array[4] = "=rescan, ";
value = _panelKey.Value;
array[5] = ((KeyboardShortcut)(ref value)).MainKey;
array[6] = "=panel";
logger.LogInfo((object)string.Concat(array));
}
private void Update()
{
//IL_0008: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
try
{
KeyboardShortcut value = _toggleKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
_showBeacons.Value = !_showBeacons.Value;
if ((Object)(object)_beacons != (Object)null)
{
((Behaviour)_beacons).enabled = _showBeacons.Value;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("[BelltowerFinder] 光柱:" + (_showBeacons.Value ? "开" : "关") + ",当前 " + _towers.Count + " 座钟塔"));
}
value = _rescanKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
ScanNow();
}
value = _panelKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
_showPanel = !_showPanel;
}
if (Time.time >= _nextScanTime)
{
_nextScanTime = Time.time + Mathf.Max(0.5f, _scanInterval.Value);
ScanNow();
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[BelltowerFinder] Update error: " + ex));
}
}
private void ScanNow()
{
//IL_0605: Unknown result type (might be due to invalid IL or missing references)
//IL_060a: Unknown result type (might be due to invalid IL or missing references)
//IL_060e: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Invalid comparison between Unknown and I4
//IL_040c: Unknown result type (might be due to invalid IL or missing references)
//IL_0411: Unknown result type (might be due to invalid IL or missing references)
//IL_057c: Unknown result type (might be due to invalid IL or missing references)
//IL_0581: Unknown result type (might be due to invalid IL or missing references)
//IL_058e: Unknown result type (might be due to invalid IL or missing references)
//IL_06d2: Unknown result type (might be due to invalid IL or missing references)
//IL_0454: Unknown result type (might be due to invalid IL or missing references)
//IL_045b: 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_04a3: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
//IL_034d: 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)
try
{
MapHandler val = Object.FindObjectOfType<MapHandler>();
if (!((Object)(object)val != (Object)null) || !MapHandler.Exists || !MapHandler.ExistsAndInitialized)
{
SetStatus("未进入地图(请先进入每日远征)");
ClearBeacons();
return;
}
GameObject val2 = null;
try
{
MapSegment[] segments = val.segments;
if (segments != null)
{
foreach (MapSegment val3 in segments)
{
if (val3 == null)
{
continue;
}
try
{
if ((int)val3.biome == 8)
{
val2 = val3.segmentParent;
break;
}
}
catch
{
}
}
}
}
catch
{
}
List<string> list = SplitList(_nameFilter.Value);
List<Transform> list2 = new List<Transform>();
Transform val4 = ((_gloomOnly.Value && (Object)(object)val2 != (Object)null) ? val2.transform : null);
Transform[] array = ((!((Object)(object)val4 != (Object)null)) ? Object.FindObjectsOfType<Transform>() : ((Component)val4).GetComponentsInChildren<Transform>(true));
Transform[] array2 = array;
foreach (Transform val5 in array2)
{
if ((Object)(object)val5 == (Object)null || (Object)(object)val5.root == (Object)(object)_root.transform)
{
continue;
}
string text = ((Object)val5).name.ToLowerInvariant();
bool flag = false;
for (int i = 0; i < list.Count; i++)
{
if (list[i].Length > 0 && text.Contains(list[i]))
{
flag = true;
break;
}
}
if (flag)
{
list2.Add(val5);
}
}
if (_logAll.Value && list2.Count > 0)
{
foreach (Transform item in list2)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[BelltowerFinder][match] '" + ((Object)item).name + "' at " + FmtVec(item.position)));
}
}
List<Vector3> list3 = new List<Vector3>();
List<string> list4 = new List<string>();
foreach (Transform item2 in list2)
{
bool flag2 = false;
for (int i = 0; i < list3.Count; i++)
{
if (Vector3.Distance(list3[i], item2.position) <= _clusterRadius.Value)
{
if (item2.position.y > list3[i].y)
{
list3[i] = item2.position;
list4[i] = ((Object)item2).name;
}
flag2 = true;
break;
}
}
if (!flag2)
{
list3.Add(item2.position);
list4.Add(((Object)item2).name);
}
}
if (_includeJesterBells.Value)
{
try
{
JesterBells[] array3 = Resources.FindObjectsOfTypeAll<JesterBells>();
if (array3 != null)
{
JesterBells[] array4 = array3;
foreach (JesterBells val6 in array4)
{
if ((Object)(object)val6 == (Object)null)
{
continue;
}
try
{
Transform transform = ((Component)val6).transform;
if ((Object)(object)transform == (Object)null)
{
continue;
}
Scene scene = ((Component)transform).gameObject.scene;
if (!((Scene)(ref scene)).IsValid() || ((Object)(object)val2 != (Object)null && !IsDescendant(transform, val2.transform)))
{
continue;
}
bool flag3 = false;
for (int i = 0; i < list3.Count; i++)
{
if (Vector3.Distance(list3[i], transform.position) <= _clusterRadius.Value)
{
flag3 = true;
break;
}
}
if (!flag3)
{
list3.Add(transform.position);
list4.Add("JesterBells");
}
}
catch
{
}
}
}
}
catch
{
}
}
bool flag4 = !SameList(_towers, list3);
_towers.Clear();
_towers.AddRange(list3);
_towerNames.Clear();
_towerNames.AddRange(list4);
if ((Object)(object)_beacons != (Object)null)
{
_beacons.targets.Clear();
if (_showBeacons.Value)
{
foreach (Vector3 tower in _towers)
{
_beacons.targets.Add(tower);
}
}
}
if (_towers.Count > 0)
{
object[] array5 = new object[5] { "雾沼钟塔:", _towers.Count, " 座 (", null, null };
object[] array6 = array5;
KeyboardShortcut value = _toggleKey.Value;
array6[3] = ((KeyboardShortcut)(ref value)).MainKey;
array5[4] = " 开关光柱)";
SetStatus(string.Concat(array5));
}
else if ((Object)(object)val2 == (Object)null && _gloomOnly.Value)
{
SetStatus("未找到雾沼段(今天的每日地图可能没有雾沼)");
}
else
{
SetStatus("雾沼段内没扫到钟塔:开 LogAll 看日志,或调 NameFilter");
}
if (flag4)
{
for (int i = 0; i < _towers.Count; i++)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[BelltowerFinder] 钟塔 #" + (i + 1) + " '" + _towerNames[i] + "' " + FmtVec(_towers[i])));
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[BelltowerFinder] Scan error: " + ex));
}
}
private void ClearBeacons()
{
if ((Object)(object)_beacons != (Object)null)
{
_beacons.targets.Clear();
}
}
private void SetStatus(string s)
{
if (_status != s)
{
_status = s;
((BaseUnityPlugin)this).Logger.LogInfo((object)("[BelltowerFinder] " + s));
}
}
private void OnGUI()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_024d: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: 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_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
if (!_showPanel)
{
return;
}
try
{
GUILayout.BeginArea(new Rect(10f, 10f, 420f, 260f));
GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Label("<b>Bell Tower Finder(雾沼钟塔)</b>", (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Label(_status, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Space(4f);
if (_towers.Count == 0)
{
GUILayout.Label("(no bell towers found)", (GUILayoutOption[])(object)new GUILayoutOption[0]);
}
else
{
Camera main = Camera.main;
Rect val2 = default(Rect);
for (int i = 0; i < _towers.Count; i++)
{
string text = "钟塔 #" + (i + 1) + " " + FmtVec(_towers[i]);
if (i < _towerNames.Count && _towerNames[i].Length > 0)
{
text = text + " (" + _towerNames[i] + ")";
}
GUILayout.Label("<color=#FFCC00>" + text + "</color>", (GUILayoutOption[])(object)new GUILayoutOption[0]);
if (!((Object)(object)main != (Object)null))
{
continue;
}
try
{
Vector3 val = main.WorldToScreenPoint(_towers[i]);
if (val.z > 0f)
{
((Rect)(ref val2))..ctor(val.x - 30f, (float)Screen.height - val.y - 12f, 90f, 20f);
GUI.color = new Color(1f, 0.8f, 0f, 1f);
GUI.Label(val2, "钟塔");
GUI.color = Color.white;
}
}
catch
{
}
}
}
GUILayout.Space(4f);
object[] array = new object[6];
object[] array2 = array;
KeyboardShortcut value = _toggleKey.Value;
array2[0] = ((KeyboardShortcut)(ref value)).MainKey;
array[1] = " 开关光柱 | ";
object[] array3 = array;
value = _rescanKey.Value;
array3[2] = ((KeyboardShortcut)(ref value)).MainKey;
array[3] = " 重扫 | ";
object[] array4 = array;
value = _panelKey.Value;
array4[4] = ((KeyboardShortcut)(ref value)).MainKey;
array[5] = " 面板";
GUILayout.Label(string.Concat(array), (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.EndVertical();
GUILayout.EndArea();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[BelltowerFinder] OnGUI error: " + ex));
}
}
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 SameList(List<Vector3> a, List<Vector3> b)
{
//IL_001d: 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)
if (a.Count != b.Count)
{
return false;
}
for (int i = 0; i < a.Count; i++)
{
if (Vector3.Distance(a[i], b[i]) > 1f)
{
return false;
}
}
return true;
}
private static List<string> SplitList(string s)
{
List<string> list = new List<string>();
if (string.IsNullOrEmpty(s))
{
return list;
}
string[] array = s.Split(new char[1] { ',' });
string[] array2 = array;
foreach (string text in array2)
{
string text2 = text.Trim().ToLowerInvariant();
if (text2.Length > 0)
{
list.Add(text2);
}
}
return list;
}
private static string FmtVec(Vector3 v)
{
return "(" + v.x.ToString("F0") + ", " + v.y.ToString("F0") + ", " + v.z.ToString("F0") + ")";
}
private static Color ParseHexColor(string hex, Color fallback)
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: 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_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_0042: 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_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 (string.IsNullOrEmpty(hex))
{
return fallback;
}
string text = hex.TrimStart(new char[1] { '#' });
if (text.Length < 6)
{
return fallback;
}
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;
}
}
}
public class BeaconRenderer : MonoBehaviour
{
public List<Vector3> targets = new List<Vector3>();
public Color color = new Color(1f, 0.8f, 0f, 1f);
public float height = 150f;
private Material _mat;
private void EnsureMat()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
if ((Object)(object)_mat != (Object)null)
{
return;
}
try
{
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;
}
}
catch
{
}
}
private void OnRenderObject()
{
//IL_0062: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_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_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: 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_0111: 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_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
if (targets == null || targets.Count == 0)
{
return;
}
try
{
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)
{
GL.Vertex(target);
GL.Vertex(target + new Vector3(0f, num, 0f));
GL.Vertex(target + new Vector3(0f, num, 0f) + new Vector3(-3f, 0f, 0f));
GL.Vertex(target + new Vector3(0f, num, 0f) + new Vector3(3f, 0f, 0f));
GL.Vertex(target + new Vector3(0f, num, 0f) + new Vector3(0f, 0f, -3f));
GL.Vertex(target + new Vector3(0f, num, 0f) + new Vector3(0f, 0f, 3f));
}
GL.End();
GL.PopMatrix();
}
catch
{
}
}
}