using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.pretty_kotik.peakchestfinder")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+4fbd562dad95c6f4dec78bfda224211b979a7b9c")]
[assembly: AssemblyProduct("com.pretty_kotik.peakchestfinder")]
[assembly: AssemblyTitle("Chest Finder")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace PeakChestFinder
{
internal sealed class ChestRadar : MonoBehaviour
{
private const float CompassHalfAngle = 90f;
private const string ChestAtlasResource = "PeakChestFinder.Assets.chest-atlas.png";
private readonly List<ChestTarget> _targets = new List<ChestTarget>();
private readonly HashSet<string> _reportedFallbackNames = new HashSet<string>(StringComparer.Ordinal);
private readonly PeakGameApi _game = new PeakGameApi();
private PluginConfig _settings;
private Texture2D _chestAtlas;
private Texture2D _upArrow;
private Texture2D _downArrow;
private GUIStyle? _distanceStyle;
private bool _gameFontApplied;
private bool _runtimeVisible = true;
private bool _apiReady;
private bool _apiFailureReported;
private bool _initialDebugStateReported;
private bool _hasFrameState;
private int _nearbyCount;
private float _nextApiAttempt;
private float _nextScan;
private Camera? _camera;
private Vector3 _playerPosition;
internal void Initialize(PluginConfig settings)
{
_settings = settings;
}
private void Awake()
{
_chestAtlas = LoadChestAtlas();
_upArrow = CreateArrowIcon(pointsUp: true);
_downArrow = CreateArrowIcon(pointsUp: false);
}
private void Update()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
if (_settings == null)
{
return;
}
KeyboardShortcut value = _settings.ToggleKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
HandleToggle();
}
if (!_settings.Enabled.Value || !_runtimeVisible)
{
_hasFrameState = false;
if (_settings.DebugMode.Value && !_initialDebugStateReported)
{
_initialDebugStateReported = true;
LogRadarState(enabled: false);
}
}
else if (EnsureApiReady() && Time.unscaledTime >= _nextScan)
{
RefreshTargets();
}
}
private void LateUpdate()
{
_hasFrameState = false;
if (!_apiReady || !_settings.Enabled.Value || !_runtimeVisible)
{
return;
}
try
{
if (_game.IsHudVisible() && _game.TryGetPlayerHead(out _playerPosition))
{
_camera = Camera.main;
_hasFrameState = (Object)(object)_camera != (Object)null;
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Radar presentation failed: " + ex.Message));
_apiReady = false;
_nextApiAttempt = Time.unscaledTime + 2f;
}
}
private void OnGUI()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Invalid comparison between Unknown and I4
//IL_008b: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: 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_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: 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_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0280: 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_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0304: Unknown result type (might be due to invalid IL or missing references)
//IL_030d: Unknown result type (might be due to invalid IL or missing references)
if (!_hasFrameState || (Object)(object)_camera == (Object)null || (int)Event.current.type != 7)
{
return;
}
EnsureGuiStyle();
float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 1.35f);
float num2 = Mathf.Min((float)Screen.width * 0.52f, 640f * num);
float num3 = 40f * num;
float num4 = ((float)Screen.width - num2) * 0.5f;
float num5 = 8f * num;
Rect val = default(Rect);
((Rect)(ref val))..ctor(num4, num5, num2, num3);
Color color = GUI.color;
GUI.color = new Color(0.035f, 0.03f, 0.022f, 0.48f);
GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
GUI.color = new Color(0.82f, 0.69f, 0.42f, 0.5f);
GUI.DrawTexture(new Rect(num4, num5 + num3 - 2f * num, num2, 2f * num), (Texture)(object)Texture2D.whiteTexture);
GUI.DrawTexture(new Rect((float)Screen.width * 0.5f - num, num5, 2f * num, 6f * num), (Texture)(object)Texture2D.whiteTexture);
GUI.color = color;
Vector3 forward = ((Component)_camera).transform.forward;
forward.y = 0f;
if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
{
return;
}
((Vector3)(ref forward)).Normalize();
float num6 = Mathf.Max(0f, _settings.MaxDistance.Value);
float verticalThreshold = Mathf.Max(0f, _settings.VerticalThreshold.Value);
float num7 = ((_targets.Count == 0) ? 0f : _targets[0].DistanceMeters);
float num8 = ((_targets.Count == 0) ? 0f : _targets[_targets.Count - 1].DistanceMeters);
for (int num9 = _targets.Count - 1; num9 >= 0; num9--)
{
ChestTarget chestTarget = _targets[num9];
Vector3 val2 = chestTarget.Position - _playerPosition;
float num10 = ((Vector3)(ref val2)).magnitude * _game.UnitsToMeters;
if (!(num10 > num6))
{
Vector3 val3 = val2;
val3.y = 0f;
if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
{
val3 = forward;
}
float num11 = Vector3.SignedAngle(forward, ((Vector3)(ref val3)).normalized, Vector3.up);
if (!(Mathf.Abs(num11) > 90f))
{
float centerX = num4 + num2 * (0.5f + num11 / 180f);
float distanceScale = ((num8 <= num7) ? 1f : Mathf.Lerp(1f, 0.5f, Mathf.InverseLerp(num7, num8, chestTarget.DistanceMeters)));
Color markerColor = _settings.GetChestType(chestTarget.Type).ResolveColor();
DrawMarker(centerX, num5, num5 + num3, num, distanceScale, markerColor, chestTarget.Type, val2.y * _game.UnitsToMeters, verticalThreshold, num10);
}
}
}
}
private void DrawMarker(float centerX, float compassY, float compassBottomY, float uiScale, float distanceScale, Color markerColor, ChestType chestType, float verticalDeltaMeters, float verticalThreshold, float distanceMeters)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: 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_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
float num = 28f * uiScale * distanceScale;
float num2 = 21f * uiScale * distanceScale;
float num3 = 11f * uiScale * distanceScale;
float num4 = 7f * uiScale * distanceScale;
float num5 = compassY + 25f * uiScale;
Rect val = default(Rect);
((Rect)(ref val))..ctor(centerX - num3 * 0.5f, num5 - num2 * 0.5f - num4 + uiScale * distanceScale, num3, num4);
Color color = GUI.color;
Texture2D val2 = null;
if (verticalDeltaMeters > verticalThreshold)
{
val2 = _upArrow;
}
else if (verticalDeltaMeters < 0f - verticalThreshold)
{
val2 = _downArrow;
}
if ((Object)(object)val2 != (Object)null)
{
float num6 = Mathf.Max(1f, 1.25f * uiScale * distanceScale);
Rect val3 = default(Rect);
((Rect)(ref val3))..ctor(((Rect)(ref val)).x - num6, ((Rect)(ref val)).y - num6, ((Rect)(ref val)).width + num6 * 2f, ((Rect)(ref val)).height + num6 * 2f);
GUI.color = new Color(0f, 0f, 0f, 0.9f);
GUI.DrawTexture(val3, (Texture)(object)val2);
GUI.color = markerColor;
GUI.DrawTexture(val, (Texture)(object)val2);
}
Rect val4 = default(Rect);
((Rect)(ref val4))..ctor(centerX - num * 0.5f, num5 - num2 * 0.5f, num, num2);
GUI.color = markerColor;
GUI.DrawTextureWithTexCoords(val4, (Texture)(object)_chestAtlas, GetAtlasUv(chestType, _chestAtlas), true);
_distanceStyle.fontSize = Mathf.RoundToInt(11f * uiScale);
GUI.color = Color.white;
Rect val5 = default(Rect);
((Rect)(ref val5))..ctor(centerX - 34f * uiScale, compassBottomY, 68f * uiScale, 16f * uiScale);
string text = $"{distanceMeters:0} m";
_distanceStyle.normal.textColor = new Color(0f, 0f, 0f, 0.9f);
GUI.Label(new Rect(((Rect)(ref val5)).x + uiScale, ((Rect)(ref val5)).y + uiScale, ((Rect)(ref val5)).width, ((Rect)(ref val5)).height), text, _distanceStyle);
_distanceStyle.normal.textColor = markerColor;
GUI.Label(val5, text, _distanceStyle);
GUI.color = color;
}
private void HandleToggle()
{
if (!_settings.Enabled.Value)
{
if (_settings.DebugMode.Value)
{
Plugin.Log.LogInfo((object)"Radar remains disabled by General.Enabled; 0 nearby chests are active.");
}
return;
}
_initialDebugStateReported = true;
if (_runtimeVisible)
{
if (EnsureApiReady())
{
RefreshTargets(reportInitialState: false);
}
LogRadarState(enabled: false);
_runtimeVisible = false;
_targets.Clear();
_nearbyCount = 0;
_hasFrameState = false;
}
else
{
_runtimeVisible = true;
if (EnsureApiReady())
{
RefreshTargets(reportInitialState: false);
}
LogRadarState(enabled: true);
}
}
private void RefreshTargets(bool reportInitialState = true)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
_nextScan = Time.unscaledTime + Mathf.Max(0.05f, _settings.ScanInterval.Value);
try
{
if (!_game.TryGetPlayerHead(out var position))
{
_targets.Clear();
_nearbyCount = 0;
return;
}
_game.FindChests(position, Mathf.Max(0f, _settings.MaxDistance.Value), _targets);
if (_settings.DebugMode.Value)
{
foreach (ChestTarget target in _targets)
{
if (target.UsedFallbackType && _reportedFallbackNames.Add(target.RawName))
{
Plugin.Log.LogInfo((object)("Unknown luggage name '" + target.RawName + "' is shown as Luggage."));
}
}
}
for (int num = _targets.Count - 1; num >= 0; num--)
{
if (!_settings.GetChestType(_targets[num].Type).Enabled.Value)
{
_targets.RemoveAt(num);
}
}
_nearbyCount = _targets.Count;
int num2 = Mathf.Max(0, _settings.MaxMarkers.Value);
if (_targets.Count > num2)
{
_targets.RemoveRange(num2, _targets.Count - num2);
}
if (reportInitialState && _settings.DebugMode.Value && !_initialDebugStateReported)
{
_initialDebugStateReported = true;
LogRadarState(enabled: true);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Chest scan failed: " + ex.Message));
_targets.Clear();
_nearbyCount = 0;
_apiReady = false;
_nextApiAttempt = Time.unscaledTime + 2f;
}
}
private bool EnsureApiReady()
{
if (_apiReady)
{
return true;
}
if (Time.unscaledTime < _nextApiAttempt)
{
return false;
}
_nextApiAttempt = Time.unscaledTime + 2f;
try
{
_apiReady = _game.TryInitialize();
if (_apiReady)
{
_apiFailureReported = false;
_nextScan = 0f;
Plugin.Log.LogInfo((object)"Chest radar connected to the PEAK game API.");
}
else if (!_apiFailureReported)
{
_apiFailureReported = true;
Plugin.Log.LogWarning((object)("Chest radar is waiting: " + _game.LastError));
}
}
catch (Exception ex)
{
if (!_apiFailureReported)
{
_apiFailureReported = true;
Plugin.Log.LogWarning((object)("Chest radar API probe failed: " + ex.Message));
}
}
return _apiReady;
}
private void LogRadarState(bool enabled)
{
if (_settings.DebugMode.Value)
{
Plugin.Log.LogInfo((object)string.Format("Radar {0}: {1} nearby chest(s) match the config; {2} marker(s) displayed.", enabled ? "enabled" : "disabled", _nearbyCount, _targets.Count));
}
}
private void EnsureGuiStyle()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
if (_distanceStyle == null)
{
GUIStyle val = new GUIStyle(GUI.skin.label)
{
alignment = (TextAnchor)4,
fontStyle = (FontStyle)1
};
val.normal.textColor = Color.white;
_distanceStyle = val;
}
if (!_gameFontApplied && _game.TryGetHudFont(out Font font))
{
_distanceStyle.font = font;
_gameFontApplied = true;
}
}
private static Texture2D LoadChestAtlas()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PeakChestFinder.Assets.chest-atlas.png");
if (stream == null)
{
throw new InvalidOperationException("Embedded chest atlas 'PeakChestFinder.Assets.chest-atlas.png' was not found.");
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
{
name = "PeakChestFinder Chest Atlas",
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1,
hideFlags = (HideFlags)61
};
if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true))
{
Object.Destroy((Object)(object)val);
throw new InvalidOperationException("Embedded chest atlas could not be decoded.");
}
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
return val;
}
private static Rect GetAtlasUv(ChestType type, Texture2D atlas)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
Rect val = (Rect)(type switch
{
ChestType.AncientLuggage => new Rect(0f, 2f / 3f, 0.5f, 1f / 3f),
ChestType.BigLuggage => new Rect(0f, 1f / 3f, 0.5f, 1f / 3f),
ChestType.ExplorersLuggage => new Rect(0.5f, 1f / 3f, 0.5f, 1f / 3f),
ChestType.ClownLuggage => new Rect(0f, 0f, 0.5f, 1f / 3f),
_ => new Rect(0.5f, 2f / 3f, 0.5f, 1f / 3f),
});
float num = 0.5f / (float)((Texture)atlas).width;
float num2 = 0.5f / (float)((Texture)atlas).height;
return new Rect(((Rect)(ref val)).x + num, ((Rect)(ref val)).y + num2, ((Rect)(ref val)).width - num * 2f, ((Rect)(ref val)).height - num2 * 2f);
}
private static Texture2D CreateArrowIcon(bool pointsUp)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = CreateTransparentTexture(24, 16, pointsUp ? "PeakChestFinder Up" : "PeakChestFinder Down");
for (int i = 2; i < 14; i++)
{
int num = (pointsUp ? (13 - i) : (i - 2));
int num2 = Mathf.Clamp(num, 1, 10);
FillRect(val, 12 - num2, i, num2 * 2 + 1, 1, Color.white);
}
val.Apply(false, true);
return val;
}
private static Texture2D CreateTransparentTexture(int width, int height, string name)
{
//IL_0004: 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_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
Texture2D val = new Texture2D(width, height, (TextureFormat)4, false)
{
name = name,
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1,
hideFlags = (HideFlags)61
};
val.SetPixels((Color[])(object)new Color[width * height]);
return val;
}
private static void FillRect(Texture2D texture, int x, int y, int width, int height, Color color)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
for (int i = y; i < y + height; i++)
{
for (int j = x; j < x + width; j++)
{
texture.SetPixel(j, i, color);
}
}
}
private void OnDestroy()
{
Object.Destroy((Object)(object)_chestAtlas);
Object.Destroy((Object)(object)_upArrow);
Object.Destroy((Object)(object)_downArrow);
}
}
internal enum ChestType
{
Luggage,
BigLuggage,
AncientLuggage,
ExplorersLuggage,
ClownLuggage
}
internal sealed class ChestTypeConfig
{
private readonly Color _defaultColor;
private string _cachedValue = string.Empty;
private string _warnedValue = string.Empty;
private Color _cachedColor;
internal ChestType Type { get; }
internal ConfigEntry<bool> Enabled { get; }
internal ConfigEntry<string> Color { get; }
internal ChestTypeConfig(ConfigFile config, ChestType type, bool enabledByDefault, string defaultColor)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
Type = type;
Enabled = config.Bind<bool>($"Chest.{type}", "Enabled", enabledByDefault, $"Show {type} chests on the radar.");
Color = config.Bind<string>($"Chest.{type}", "Color", defaultColor, "Marker color in #RRGGBB or #RRGGBBAA format.");
if (!ColorUtility.TryParseHtmlString(defaultColor, ref _defaultColor))
{
_defaultColor = Color.white;
}
_cachedColor = _defaultColor;
}
internal Color ResolveColor()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
string text = Color.Value?.Trim() ?? string.Empty;
if (text == _cachedValue)
{
return _cachedColor;
}
_cachedValue = text;
Color cachedColor = default(Color);
if (ColorUtility.TryParseHtmlString(text, ref cachedColor))
{
_cachedColor = cachedColor;
return _cachedColor;
}
_cachedColor = _defaultColor;
if (_warnedValue != text)
{
_warnedValue = text;
Plugin.Log.LogWarning((object)$"Invalid color '{text}' for {Type}; using its default color.");
}
return _cachedColor;
}
}
internal readonly struct ChestTarget
{
internal ChestType Type { get; }
internal Vector3 Position { get; }
internal float DistanceMeters { get; }
internal string RawName { get; }
internal bool UsedFallbackType { get; }
internal ChestTarget(ChestType type, Vector3 position, float distanceMeters, string rawName, bool usedFallbackType)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
Type = type;
Position = position;
DistanceMeters = distanceMeters;
RawName = rawName;
UsedFallbackType = usedFallbackType;
}
}
internal sealed class PeakGameApi
{
private const float DefaultUnitsToMeters = 1.6f;
private FieldInfo? _allLuggageField;
private PropertyInfo? _isOpenProperty;
private FieldInfo? _displayNameField;
private MethodInfo? _centerMethod;
private FieldInfo? _localCharacterField;
private PropertyInfo? _headProperty;
private FieldInfo? _guiInstanceField;
private FieldInfo? _hudCanvasField;
private FieldInfo? _interactNameTextField;
private PropertyInfo? _inPauseMenuProperty;
private PropertyInfo? _tmpFontProperty;
private PropertyInfo? _sourceFontFileProperty;
internal float UnitsToMeters { get; private set; } = 1.6f;
internal string LastError { get; private set; } = string.Empty;
internal bool TryInitialize()
{
Type type = FindGameType("Luggage");
Type type2 = FindGameType("Character");
if (type == null || type2 == null)
{
LastError = "Assembly-CSharp is not ready yet.";
return false;
}
_allLuggageField = type.GetField("ALL_LUGGAGE", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_isOpenProperty = type.GetProperty("IsOpen", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_displayNameField = type.GetField("displayName", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_centerMethod = type.GetMethod("Center", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
_localCharacterField = type2.GetField("localCharacter", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_headProperty = type2.GetProperty("Head", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (_allLuggageField == null || _isOpenProperty == null || _centerMethod == null || _localCharacterField == null || _headProperty == null)
{
LastError = "Required Character/Luggage members do not match this PEAK build.";
return false;
}
if ((FindGameType("CharacterStats")?.GetField("unitsToMeters", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null) is float num && num > 0f)
{
UnitsToMeters = num;
}
Type type3 = FindGameType("GUIManager");
_guiInstanceField = type3?.GetField("instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_hudCanvasField = type3?.GetField("hudCanvas", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_interactNameTextField = type3?.GetField("interactNameText", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_inPauseMenuProperty = type3?.GetProperty("InPauseMenu", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_tmpFontProperty = _interactNameTextField?.FieldType.GetProperty("font", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_sourceFontFileProperty = _tmpFontProperty?.PropertyType.GetProperty("sourceFontFile", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
LastError = string.Empty;
return true;
}
internal bool TryGetPlayerHead(out Vector3 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: 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_0049: 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)
position = default(Vector3);
object obj = _localCharacterField?.GetValue(null);
if (!(((obj == null) ? null : _headProperty?.GetValue(obj)) is Vector3 val))
{
return false;
}
position = val;
return true;
}
internal void FindChests(Vector3 playerPosition, float maxDistanceMeters, List<ChestTarget> results)
{
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: 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_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: 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)
results.Clear();
if (!(_allLuggageField?.GetValue(null) is IEnumerable enumerable))
{
return;
}
float num = maxDistanceMeters * maxDistanceMeters;
bool flag = default(bool);
foreach (object item in enumerable)
{
Component val = (Component)((item is Component) ? item : null);
if (val == null || (Object)(object)val == (Object)null || !val.gameObject.activeInHierarchy)
{
continue;
}
object obj = _isOpenProperty?.GetValue(item);
int num2;
if (obj is bool)
{
flag = (bool)obj;
num2 = 1;
}
else
{
num2 = 0;
}
if (num2 == 0 || flag || item.GetType().Name == "RespawnChest")
{
continue;
}
string text = (_displayNameField?.GetValue(item) as string) ?? string.Empty;
string text2 = ((Object)val.gameObject).name ?? string.Empty;
string rawName = (string.IsNullOrWhiteSpace(text) ? text2 : (text + " | " + text2));
bool isClown = val.gameObject.CompareTag("ClownLuggage");
bool usedFallbackType;
ChestType type = ClassifyChest(text, text2, isClown, out usedFallbackType);
if (_centerMethod?.Invoke(item, null) is Vector3 val2)
{
Vector3 val3 = val2 - playerPosition;
float num3 = ((Vector3)(ref val3)).sqrMagnitude * UnitsToMeters * UnitsToMeters;
if (!(num3 > num))
{
results.Add(new ChestTarget(type, val2, Mathf.Sqrt(num3), rawName, usedFallbackType));
}
}
}
results.Sort((ChestTarget left, ChestTarget right) => left.DistanceMeters.CompareTo(right.DistanceMeters));
}
private static ChestType ClassifyChest(string displayName, string objectName, bool isClown, out bool usedFallbackType)
{
string text = displayName + " " + objectName;
usedFallbackType = false;
if (isClown)
{
return ChestType.ClownLuggage;
}
if (text.IndexOf("ancient", StringComparison.OrdinalIgnoreCase) >= 0)
{
return ChestType.AncientLuggage;
}
if (text.IndexOf("explorer", StringComparison.OrdinalIgnoreCase) >= 0)
{
return ChestType.ExplorersLuggage;
}
if (text.IndexOf("big", StringComparison.OrdinalIgnoreCase) >= 0)
{
return ChestType.BigLuggage;
}
if (text.IndexOf("luggage", StringComparison.OrdinalIgnoreCase) < 0)
{
usedFallbackType = true;
}
return ChestType.Luggage;
}
internal bool TryGetHudFont(out Font font)
{
font = null;
try
{
object obj = _guiInstanceField?.GetValue(null);
object obj2 = ((obj == null) ? null : _interactNameTextField?.GetValue(obj));
object obj3 = ((obj2 == null) ? null : _tmpFontProperty?.GetValue(obj2));
if (obj3 != null)
{
object? obj4 = _sourceFontFileProperty?.GetValue(obj3);
Font val = (Font)((obj4 is Font) ? obj4 : null);
if (val != null)
{
font = val;
return true;
}
}
}
catch (Exception)
{
}
return false;
}
internal bool IsHudVisible()
{
if (_guiInstanceField == null || _hudCanvasField == null)
{
return true;
}
object value = _guiInstanceField.GetValue(null);
if (value == null)
{
return false;
}
object obj = _inPauseMenuProperty?.GetValue(null);
if (obj is bool && (bool)obj)
{
return false;
}
object? value2 = _hudCanvasField.GetValue(value);
Behaviour val = (Behaviour)((value2 is Behaviour) ? value2 : null);
if (val != null)
{
return val.isActiveAndEnabled;
}
return false;
}
private static Type? FindGameType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
if (assembly.GetName().Name == "Assembly-CSharp")
{
return assembly.GetType(fullName, throwOnError: false);
}
}
return null;
}
}
[BepInPlugin("com.pretty_kotik.peakchestfinder", "Chest Finder", "1.0.3")]
public class Plugin : BaseUnityPlugin
{
public const string Id = "com.pretty_kotik.peakchestfinder";
internal static ManualLogSource Log { get; private set; }
internal PluginConfig Settings { get; private set; }
public static string Name => "Chest Finder";
public static string Version => "1.0.3";
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
Settings = new PluginConfig(((BaseUnityPlugin)this).Config);
ChestRadar chestRadar = ((Component)this).gameObject.AddComponent<ChestRadar>();
chestRadar.Initialize(Settings);
Log.LogInfo((object)("Plugin " + Name + " is loaded."));
}
}
internal sealed class PluginConfig
{
internal ConfigEntry<bool> Enabled { get; }
internal ConfigEntry<KeyboardShortcut> ToggleKey { get; }
internal ConfigEntry<float> MaxDistance { get; }
internal ConfigEntry<float> ScanInterval { get; }
internal ConfigEntry<int> MaxMarkers { get; }
internal ConfigEntry<float> VerticalThreshold { get; }
internal ConfigEntry<bool> DebugMode { get; }
internal IReadOnlyDictionary<ChestType, ChestTypeConfig> ChestTypes { get; }
internal PluginConfig(ConfigFile config)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
Enabled = config.Bind<bool>("General", "Enabled", true, "Enable chest indicators.");
ToggleKey = config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Toggle chest indicators.");
MaxDistance = config.Bind<float>("Detection", "MaxDistance", 150f, "Maximum detection distance in PEAK metres.");
ScanInterval = config.Bind<float>("Detection", "ScanInterval", 0.25f, "Seconds between container scans.");
MaxMarkers = config.Bind<int>("Detection", "MaxMarkers", 10, "Maximum number of visible markers.");
VerticalThreshold = config.Bind<float>("Navigation", "VerticalThreshold", 2f, "Vertical arrow dead zone in PEAK metres.");
DebugMode = config.Bind<bool>("Debug", "Enabled", false, "Log radar state and nearby chest counts when toggled.");
ChestTypes = new Dictionary<ChestType, ChestTypeConfig>
{
[ChestType.Luggage] = new ChestTypeConfig(config, ChestType.Luggage, enabledByDefault: true, "#C8BBAA"),
[ChestType.BigLuggage] = new ChestTypeConfig(config, ChestType.BigLuggage, enabledByDefault: true, "#D6D9DE"),
[ChestType.AncientLuggage] = new ChestTypeConfig(config, ChestType.AncientLuggage, enabledByDefault: true, "#FF69B4"),
[ChestType.ExplorersLuggage] = new ChestTypeConfig(config, ChestType.ExplorersLuggage, enabledByDefault: true, "#FF8C32"),
[ChestType.ClownLuggage] = new ChestTypeConfig(config, ChestType.ClownLuggage, enabledByDefault: true, "#4DA3FF")
};
}
internal ChestTypeConfig GetChestType(ChestType type)
{
if (!ChestTypes.TryGetValue(type, out ChestTypeConfig value))
{
return ChestTypes[ChestType.Luggage];
}
return value;
}
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}