using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.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.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 SailwindReceiptAlert
{
[BepInPlugin("skeptic043.sailwind.receiptalert", "Sailwind Receipt Alert", "1.1.0")]
public sealed class ReceiptAlertPlugin : BaseUnityPlugin
{
public const string PluginId = "skeptic043.sailwind.receiptalert";
public const string PluginName = "Sailwind Receipt Alert";
public const string PluginVersion = "1.1.0";
internal const string WarningText = "Don't forget your trade receipt!";
internal const string CollectedText = "Trade receipt collected!";
private const float ParchmentWidthMultiplier = 1.2f;
internal static readonly Vector3 ZoneSize = new Vector3(12f, 4f, 12f);
internal static readonly Vector3 ZoneOffset = new Vector3(0f, 0.5f, 0f);
private static ReceiptAlertPlugin? _instance;
private static readonly FieldInfo? NotificationUiField = AccessTools.Field(typeof(NotificationUi), "UI");
private static bool _issuingReceiptNotification;
private static bool _parchmentSetupFailureLogged;
private static bool _parchmentSetupLogged;
private static bool _receiptStorageFailureLogged;
private static Transform? _widenedParchment;
private static Vector3 _originalParchmentScale;
private static ReceiptAlertParchmentReset? _parchmentReset;
private ConfigEntry<bool>? _enabled;
private ConfigEntry<bool>? _autoCollectReceipt;
private Harmony? _harmony;
private void Awake()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
_instance = this;
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Handle uncollected trade receipts when leaving a port desk area.");
_autoCollectReceipt = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoCollectReceipt", false, "Automatically collect an available trade receipt on exit instead of showing a reminder.");
_harmony = new Harmony("skeptic043.sailwind.receiptalert");
_harmony.PatchAll(typeof(PortDudeAwakePatch));
_harmony.PatchAll(typeof(NotificationUiShowNotificationPatch));
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded; PortDude zone size {2} m.", "Sailwind Receipt Alert", "1.1.0", ZoneSize));
}
private void OnDestroy()
{
RestoreParchmentWidth();
if (Object.op_Implicit((Object)(object)_parchmentReset))
{
Object.Destroy((Object)(object)_parchmentReset);
}
_parchmentReset = null;
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
if (_instance == this)
{
_instance = null;
}
}
internal static void LogSetup(string message)
{
ReceiptAlertPlugin? instance = _instance;
if (instance != null)
{
((BaseUnityPlugin)instance).Logger.LogDebug((object)message);
}
}
internal static void LogSetupFailure(string message, Exception? error = null)
{
ReceiptAlertPlugin? instance = _instance;
ManualLogSource val = ((instance != null) ? ((BaseUnityPlugin)instance).Logger : null);
if (val != null)
{
if (error == null)
{
val.LogWarning((object)message);
}
else
{
val.LogWarning((object)$"{message}: {error}");
}
}
}
internal static bool HandleReceiptOnExit()
{
ReceiptAlertPlugin instance = _instance;
if (!((Object)(object)instance == (Object)null))
{
ConfigEntry<bool>? enabled = instance._enabled;
if (enabled != null && enabled.Value)
{
EconomyUIReceiptScribe instance2 = EconomyUIReceiptScribe.instance;
if (!Object.op_Implicit((Object)(object)instance2) || !instance2.ReceiptAvailable())
{
return false;
}
NotificationUi instance3 = NotificationUi.instance;
if (!Object.op_Implicit((Object)(object)instance3))
{
return false;
}
ConfigEntry<bool>? autoCollectReceipt = instance._autoCollectReceipt;
if (autoCollectReceipt != null && autoCollectReceipt.Value)
{
if (!Object.op_Implicit((Object)(object)TradeReceiptsUI.instance))
{
if (!_receiptStorageFailureLogged)
{
_receiptStorageFailureLogged = true;
LogSetupFailure("Trade receipt storage is unavailable; falling back to the reminder.");
}
return ShowReceiptNotification(instance3, "Don't forget your trade receipt!");
}
if (!instance2.RequestCurrentReceipt())
{
return false;
}
return ShowReceiptNotification(instance3, "Trade receipt collected!");
}
return ShowReceiptNotification(instance3, "Don't forget your trade receipt!");
}
}
return false;
}
private static bool ShowReceiptNotification(NotificationUi notification, string message)
{
_issuingReceiptNotification = true;
try
{
notification.ShowNotification(message);
}
catch
{
RestoreParchmentWidth();
throw;
}
finally
{
_issuingReceiptNotification = false;
}
return true;
}
internal static void OnNotificationShown(NotificationUi notification, string message)
{
if (!_issuingReceiptNotification || (!string.Equals(message, "Don't forget your trade receipt!", StringComparison.Ordinal) && !string.Equals(message, "Trade receipt collected!", StringComparison.Ordinal)))
{
RestoreParchmentWidth();
return;
}
try
{
WidenParchment(notification);
}
catch (Exception arg)
{
RestoreParchmentWidth();
LogParchmentSetupFailure($"Could not widen receipt notification parchment: {arg}");
}
}
private static void WidenParchment(NotificationUi notification)
{
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)_widenedParchment))
{
object? obj = NotificationUiField?.GetValue(notification);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if ((Object)(object)val != (Object)null && Object.op_Implicit((Object)(object)val) && (Object)(object)_widenedParchment != (Object)null && _widenedParchment.IsChildOf(val.transform))
{
return;
}
RestoreParchmentWidth();
}
object? obj2 = NotificationUiField?.GetValue(notification);
GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
if ((Object)(object)val2 == (Object)null || !Object.op_Implicit((Object)(object)val2))
{
LogParchmentSetupFailure("Could not find Sailwind's notification UI; receipt notification will use its normal size.");
return;
}
Transform val3 = val2.transform.Find("notification UI");
Transform val4 = (Object.op_Implicit((Object)(object)val3) ? val3.Find("notification_UI") : null);
if ((Object)(object)val3 == (Object)null || !Object.op_Implicit((Object)(object)val3) || (Object)(object)val4 == (Object)null || !Object.op_Implicit((Object)(object)val4) || !Object.op_Implicit((Object)(object)((Component)val4).GetComponent<SkinnedMeshRenderer>()))
{
LogParchmentSetupFailure("Could not find Sailwind's notification parchment; receipt notification will use its normal size.");
return;
}
ReceiptAlertParchmentReset receiptAlertParchmentReset = val2.GetComponent<ReceiptAlertParchmentReset>();
if (!Object.op_Implicit((Object)(object)receiptAlertParchmentReset))
{
receiptAlertParchmentReset = val2.AddComponent<ReceiptAlertParchmentReset>();
}
_parchmentReset = receiptAlertParchmentReset;
_widenedParchment = val3;
_originalParchmentScale = val3.localScale;
val3.localScale = new Vector3(_originalParchmentScale.x * 1.2f, _originalParchmentScale.y, _originalParchmentScale.z);
if (!_parchmentSetupLogged)
{
_parchmentSetupLogged = true;
LogSetup($"Receipt notification parchment width set to {1.2f:0.0}x while the message is visible.");
}
}
internal static void RestoreParchmentWidth(ReceiptAlertParchmentReset? reset = null)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)reset != (Object)null) || _parchmentReset == reset)
{
if ((Object)(object)_widenedParchment != (Object)null && Object.op_Implicit((Object)(object)_widenedParchment))
{
_widenedParchment.localScale = _originalParchmentScale;
}
_widenedParchment = null;
}
}
internal static void OnParchmentResetDestroyed(ReceiptAlertParchmentReset reset)
{
RestoreParchmentWidth(reset);
if (_parchmentReset == reset)
{
_parchmentReset = null;
}
}
private static void LogParchmentSetupFailure(string message)
{
if (!_parchmentSetupFailureLogged)
{
_parchmentSetupFailureLogged = true;
LogSetupFailure(message);
}
}
internal static void LogPlayerEvent(string phase, Collider collider, string area, bool? notificationCalled)
{
ReceiptAlertPlugin instance = _instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
try
{
EconomyUIReceiptScribe instance2 = EconomyUIReceiptScribe.instance;
string arg = "unknown";
if (Object.op_Implicit((Object)(object)instance2))
{
try
{
arg = (instance2.ReceiptAvailable() ? "available" : "unavailable");
}
catch (Exception ex)
{
arg = "check-failed:" + ex.GetType().Name;
}
}
((BaseUnityPlugin)instance).Logger.LogDebug((object)("Player-tagged collider " + phase + " receipt zone at " + area + ": " + $"collider={((Object)collider).name} ({((object)collider).GetType().Name}, id={((Object)collider).GetInstanceID()}), " + $"scribe={Object.op_Implicit((Object)(object)instance2)}, receipt={arg}, notification={Object.op_Implicit((Object)(object)NotificationUi.instance)}, " + $"enabled={instance._enabled?.Value ?? false}, autoCollect={instance._autoCollectReceipt?.Value ?? false}, " + "notificationCalled=" + (notificationCalled?.ToString() ?? "n/a") + "."));
}
catch (Exception ex2)
{
((BaseUnityPlugin)instance).Logger.LogDebug((object)("Could not log receipt zone " + phase + " event at " + area + ": " + ex2.GetType().Name + "."));
}
}
}
[HarmonyPatch(typeof(NotificationUi), "ShowNotification", new Type[]
{
typeof(string),
typeof(float)
})]
internal static class NotificationUiShowNotificationPatch
{
[HarmonyPostfix]
private static void Postfix(NotificationUi __instance, string __0)
{
ReceiptAlertPlugin.OnNotificationShown(__instance, __0);
}
}
public sealed class ReceiptAlertParchmentReset : MonoBehaviour
{
private void OnDisable()
{
ReceiptAlertPlugin.RestoreParchmentWidth(this);
}
private void OnDestroy()
{
ReceiptAlertPlugin.OnParchmentResetDestroyed(this);
}
}
[HarmonyPatch(typeof(PortDude), "Awake")]
internal static class PortDudeAwakePatch
{
[HarmonyPostfix]
private static void Postfix(PortDude __instance)
{
//IL_003e: 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)
//IL_0093: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: 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_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)__instance))
{
ReceiptAlertPlugin.LogSetupFailure("Skipped receipt zone: PortDude is missing.");
return;
}
GameObject val = null;
try
{
Transform transform = ((Component)__instance).transform;
if (Object.op_Implicit((Object)(object)((Component)transform).GetComponent<ReceiptAlertSkippedMarker>()))
{
return;
}
foreach (Transform item in transform)
{
if (Object.op_Implicit((Object)(object)((Component)item).GetComponent<ReceiptAlertZone>()))
{
ReceiptAlertPlugin.LogSetup("Receipt zone already exists for " + ((Object)__instance).name + "; skipped duplicate.");
return;
}
}
Vector3 lossyScale = transform.lossyScale;
if (!ValidScale(lossyScale.x) || !ValidScale(lossyScale.y) || !ValidScale(lossyScale.z))
{
((Component)transform).gameObject.AddComponent<ReceiptAlertSkippedMarker>();
ReceiptAlertPlugin.LogSetupFailure($"Skipped receipt zone for {((Object)__instance).name}: invalid world scale {lossyScale}.");
return;
}
val = new GameObject("Receipt Alert Zone");
val.SetActive(false);
val.transform.SetParent(transform, false);
val.transform.localPosition = new Vector3(ReceiptAlertPlugin.ZoneOffset.x / lossyScale.x, ReceiptAlertPlugin.ZoneOffset.y / lossyScale.y, ReceiptAlertPlugin.ZoneOffset.z / lossyScale.z);
val.transform.localRotation = Quaternion.identity;
val.transform.localScale = new Vector3(1f / lossyScale.x, 1f / lossyScale.y, 1f / lossyScale.z);
Rigidbody obj = val.AddComponent<Rigidbody>();
obj.isKinematic = true;
obj.useGravity = false;
BoxCollider obj2 = val.AddComponent<BoxCollider>();
((Collider)obj2).isTrigger = true;
obj2.size = ReceiptAlertPlugin.ZoneSize;
val.AddComponent<ReceiptAlertZone>();
val.SetActive(true);
ReceiptAlertPlugin.LogSetup("Created receipt zone for " + ((Object)__instance).name + ".");
}
catch (Exception error)
{
if (Object.op_Implicit((Object)(object)val))
{
Object.Destroy((Object)(object)val);
}
ReceiptAlertPlugin.LogSetupFailure("Could not create receipt zone for " + ((Object)__instance).name, error);
}
}
private static bool ValidScale(float value)
{
if (value > 0.0001f && !float.IsNaN(value))
{
return !float.IsInfinity(value);
}
return false;
}
}
public sealed class ReceiptAlertSkippedMarker : MonoBehaviour
{
}
public sealed class ReceiptAlertZone : MonoBehaviour
{
private const int MaxPlayerEventLogs = 12;
private bool _callbackFailureLogged;
private int _playerEventLogs;
private void OnTriggerEnter(Collider other)
{
if (Object.op_Implicit((Object)(object)other) && ((Component)other).CompareTag("Player"))
{
LogPlayerEvent("entered", other, null);
}
}
private void OnTriggerExit(Collider other)
{
if (!Object.op_Implicit((Object)(object)other) || !((Component)other).CompareTag("Player"))
{
return;
}
bool value = false;
try
{
value = ReceiptAlertPlugin.HandleReceiptOnExit();
}
catch (Exception error)
{
if (!_callbackFailureLogged)
{
_callbackFailureLogged = true;
Transform parent = ((Component)this).transform.parent;
ReceiptAlertPlugin.LogSetupFailure("Receipt handling failed at " + ((parent != null) ? ((Object)parent).name : null), error);
}
}
LogPlayerEvent("exited", other, value);
}
private void LogPlayerEvent(string phase, Collider other, bool? notificationCalled)
{
if (_playerEventLogs < 12)
{
_playerEventLogs++;
Transform parent = ((Component)this).transform.parent;
ReceiptAlertPlugin.LogPlayerEvent(phase, other, ((parent != null) ? ((Object)parent).name : null) ?? ((Object)this).name, notificationCalled);
if (_playerEventLogs == 12)
{
Transform parent2 = ((Component)this).transform.parent;
ReceiptAlertPlugin.LogSetup("Receipt zone at " + (((parent2 != null) ? ((Object)parent2).name : null) ?? ((Object)this).name) + " reached its player-event debug log limit.");
}
}
}
}
}