using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Mirror;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[HarmonyPatch(typeof(WarehouseButton), "CmdRequestPress", new Type[] { typeof(NetworkConnectionToClient) })]
public static class WarehouseButton_CmdRequestPress_Patch
{
public static bool BypassConfirmation;
[HarmonyPrefix]
public static bool Prefix(WarehouseButton __instance, NetworkConnectionToClient conn)
{
if (BypassConfirmation)
{
return true;
}
ButtonRerollShop component = ((Component)__instance).GetComponent<ButtonRerollShop>();
if ((Object)(object)component == (Object)null)
{
return true;
}
if (!NetworkClient.active)
{
return true;
}
if (SafeShopPlugin.EnableCooldown.Value && SafeShopUI.IsOnCooldown(component))
{
return false;
}
if (SafeShopPlugin.EnableConfirmation.Value)
{
SafeShopUI.RequestConfirmation(component);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ButtonRerollShop), "OnUpdatePresentation")]
public static class ButtonRerollShop_OnUpdatePresentation_Patch
{
private static FieldInfo _costTextField;
private static PropertyInfo _textProp;
[HarmonyPostfix]
public static void Postfix(ButtonRerollShop __instance)
{
if (!SafeShopPlugin.EnableCooldown.Value || !SafeShopPlugin.ShowCountdown.Value)
{
return;
}
float cooldownRemaining = SafeShopUI.GetCooldownRemaining(__instance);
if (cooldownRemaining <= 0f)
{
return;
}
FloaterUI floaterUI = SafeShopUI.GetFloaterUI(__instance);
if ((Object)(object)floaterUI == (Object)null)
{
return;
}
if (_costTextField == null)
{
_costTextField = AccessTools.Field(typeof(ShopInfoFloaterUI), "costText");
}
if (_costTextField == null)
{
return;
}
object component = ((Component)floaterUI).GetComponent(typeof(ShopInfoFloaterUI));
if (component == null)
{
return;
}
object value = _costTextField.GetValue(component);
if (value != null)
{
if (_textProp == null)
{
_textProp = value.GetType().GetProperty("text");
}
if (!(_textProp == null))
{
int num = Mathf.CeilToInt(cooldownRemaining);
_textProp.SetValue(value, "Available in\n" + num + "s", null);
}
}
}
}
[BepInPlugin("strazer.safeshop", "Strazer's SafeShop", "1.0.0")]
public class SafeShopPlugin : BaseUnityPlugin
{
public const string GUID = "strazer.safeshop";
public const string NAME = "Strazer's SafeShop";
public const string VERSION = "1.0.0";
public static ConfigEntry<bool> EnableConfirmation;
public static ConfigEntry<bool> EnableCooldown;
public static ConfigEntry<int> CooldownSeconds;
public static ConfigEntry<bool> ShowCountdown;
public static ConfigEntry<string> PopupTitle;
public static ConfigEntry<string> PopupMessage;
public static SafeShopPlugin Instance { get; private set; }
private void Awake()
{
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Expected O, but got Unknown
Instance = this;
EnableConfirmation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableConfirmation", true, "Show a confirmation popup before rerolling the shop.");
EnableCooldown = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableCooldown", false, "Apply a cooldown after each reroll.");
CooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("General", "CooldownSeconds", 30, "Cooldown duration in seconds.");
ShowCountdown = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCountdown", true, "Show the countdown on the in-world button floater.");
PopupTitle = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PopupTitle", "Reroll Shop?", "Title text for the confirmation popup.");
PopupMessage = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PopupMessage", "Spend {0} to reroll the shop?", "Message text for the confirmation popup. {0} is replaced with the cost.");
SafeShopUI.Initialize();
Harmony val = new Harmony("strazer.safeshop");
val.PatchAll();
GameObject val2 = new GameObject("SafeShop_UI");
Object.DontDestroyOnLoad((Object)(object)val2);
((Object)val2).hideFlags = (HideFlags)61;
val2.AddComponent<SafeShopUI>();
Debug.Log((object)"[SafeShop] Loaded");
}
}
public class SafeShopUI : MonoBehaviour, IInputController
{
private const float WindowWidth = 420f;
private const float WindowHeight = 240f;
private const float ButtonHeight = 44f;
private const float ButtonWidth = 140f;
private const float ButtonSpacing = 24f;
private const float OverlayAlpha = 0.4f;
private const float AnimDuration = 0.18f;
private const int PopupWindowId = 1396786757;
private static readonly Dictionary<ButtonRerollShop, float> Cooldowns = new Dictionary<ButtonRerollShop, float>();
private static ButtonRerollShop _pendingButton;
private static bool _popupVisible;
private static SafeShopUI _instance;
private static FieldInfo _floaterUIField;
private static FieldInfo _costForRerollField;
private static FieldInfo _syncTimesRerolledField;
private static FieldInfo _rerollCostIncrementField;
private static FieldInfo _costTextField;
private static FieldInfo _pressedField;
private static FieldInfo _receivedResponseField;
private static MethodInfo _cmdRequestPressMethod;
private Rect _windowRect;
private int _cost;
private float _openTime;
private bool _savedCursorVisible;
private CursorLockMode _savedCursorLockMode;
private bool _cursorSaved;
private bool _controllerRegistered;
private GUIStyle _windowStyle;
private GUIStyle _titleStyle;
private GUIStyle _messageStyle;
private GUIStyle _costLabelStyle;
private GUIStyle _costValueStyle;
private GUIStyle _confirmButtonStyle;
private GUIStyle _cancelButtonStyle;
private GUIStyle _separatorStyle;
private bool _stylesReady;
public static void Initialize()
{
_floaterUIField = AccessTools.Field(typeof(ButtonRerollShop), "_floaterUI");
_costForRerollField = AccessTools.Field(typeof(ButtonRerollShop), "costForReroll");
_syncTimesRerolledField = AccessTools.Field(typeof(ButtonRerollShop), "_syncTimesRerolled");
_rerollCostIncrementField = AccessTools.Field(typeof(ButtonRerollShop), "rerollCostIncrement");
_costTextField = AccessTools.Field(typeof(ShopInfoFloaterUI), "costText");
_pressedField = AccessTools.Field(typeof(WarehouseButton), "_pressed");
_receivedResponseField = AccessTools.Field(typeof(WarehouseButton), "_receivedResponse");
_cmdRequestPressMethod = AccessTools.Method(typeof(WarehouseButton), "CmdRequestPress", new Type[1] { typeof(NetworkConnectionToClient) }, (Type[])null);
}
public static FloaterUI GetFloaterUI(ButtonRerollShop button)
{
if (_floaterUIField == null)
{
return null;
}
object? value = _floaterUIField.GetValue(button);
return (FloaterUI)((value is FloaterUI) ? value : null);
}
private static int GetRerollCost(ButtonRerollShop button)
{
int num = 0;
int num2 = 0;
int num3 = 0;
if (_costForRerollField != null)
{
num = (int)_costForRerollField.GetValue(button);
}
if (_syncTimesRerolledField != null)
{
num2 = (int)_syncTimesRerolledField.GetValue(button);
}
if (_rerollCostIncrementField != null)
{
num3 = (int)_rerollCostIncrementField.GetValue(button);
}
return num + num2 * num3;
}
private void Awake()
{
_instance = this;
}
private void Update()
{
TickCooldowns();
if (_popupVisible)
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
}
private void TickCooldowns()
{
if (Cooldowns.Count == 0)
{
return;
}
float unscaledTime = Time.unscaledTime;
List<ButtonRerollShop> list = null;
foreach (KeyValuePair<ButtonRerollShop, float> cooldown in Cooldowns)
{
if (unscaledTime >= cooldown.Value)
{
if (list == null)
{
list = new List<ButtonRerollShop>();
}
list.Add(cooldown.Key);
}
}
if (list == null)
{
return;
}
foreach (ButtonRerollShop item in list)
{
RestoreButton(item);
Cooldowns.Remove(item);
}
Debug.Log((object)"[SafeShop] Cooldown ended");
}
private void OnGUI()
{
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
if (_popupVisible)
{
EnsureStyles();
HandleKeyboardInput();
HandleControllerInput();
float num = Mathf.Clamp01((Time.unscaledTime - _openTime) / 0.18f);
float progress = 1f - (1f - num) * (1f - num);
DrawOverlay(progress);
_windowRect = new Rect(((float)Screen.width - 420f) * 0.5f, ((float)Screen.height - 240f) * 0.5f, 420f, 240f);
GUI.backgroundColor = Color.clear;
_windowRect = GUI.Window(1396786757, _windowRect, new WindowFunction(DrawWindowContents), SafeShopPlugin.PopupTitle.Value, _windowStyle);
}
}
private void DrawOverlay(float progress)
{
//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_001d: 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_004e: Unknown result type (might be due to invalid IL or missing references)
Color color = GUI.color;
GUI.color = new Color(0f, 0f, 0f, 0.4f * progress);
GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
GUI.color = color;
}
private void DrawWindowContents(int id)
{
GUILayout.Space(4f);
GUILayout.Label(SafeShopPlugin.PopupTitle.Value, _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Space(6f);
string text = string.Format(SafeShopPlugin.PopupMessage.Value, "$" + _cost);
GUILayout.Label(text, _messageStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Space(10f);
GUILayout.Label("", _separatorStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.ExpandWidth(true),
GUILayout.Height(1f)
});
GUILayout.Space(8f);
GUILayout.Label("Cost", _costLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Label("$" + _cost, _costValueStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Space(4f);
GUILayout.Label("", _separatorStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.ExpandWidth(true),
GUILayout.Height(1f)
});
GUILayout.Space(8f);
DrawButtons();
}
private void DrawButtons()
{
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.FlexibleSpace();
if (GUILayout.Button("Confirm", _confirmButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(140f),
GUILayout.Height(44f)
}))
{
ConfirmReroll();
}
GUILayout.Space(24f);
if (GUILayout.Button("Cancel", _cancelButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(140f),
GUILayout.Height(44f)
}))
{
CancelReroll();
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
private void HandleKeyboardInput()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Invalid comparison between Unknown and I4
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Invalid comparison between Unknown and I4
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Invalid comparison between Unknown and I4
Event current = Event.current;
if ((int)current.type == 4)
{
if ((int)current.keyCode == 27)
{
CancelReroll();
current.Use();
}
else if ((int)current.keyCode == 13 || (int)current.keyCode == 271 || (int)current.keyCode == 32)
{
ConfirmReroll();
current.Use();
}
}
}
private void HandleControllerInput()
{
if (Input.GetKeyDown((KeyCode)330) || Input.GetKeyDown((KeyCode)350) || Input.GetKeyDown((KeyCode)370) || Input.GetKeyDown((KeyCode)390))
{
ConfirmReroll();
}
if (Input.GetKeyDown((KeyCode)331) || Input.GetKeyDown((KeyCode)351) || Input.GetKeyDown((KeyCode)371) || Input.GetKeyDown((KeyCode)391))
{
CancelReroll();
}
}
public void OnInputControlGained()
{
}
public void OnInputControlLost()
{
}
private void EnsureStyles()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Expected O, but got Unknown
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
//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_00f3: Expected O, but got Unknown
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Expected O, but got Unknown
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Expected O, but got Unknown
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Expected O, but got Unknown
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0229: Expected O, but got Unknown
//IL_025a: Unknown result type (might be due to invalid IL or missing references)
//IL_0264: Expected O, but got Unknown
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Expected O, but got Unknown
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
if (!_stylesReady)
{
_stylesReady = true;
_windowStyle = new GUIStyle(GUI.skin.window);
Texture2D val = new Texture2D(1, 1);
val.SetPixel(0, 0, new Color(0.12f, 0.12f, 0.14f, 0.97f));
val.Apply();
_windowStyle.normal.background = val;
_windowStyle.padding = new RectOffset(16, 16, 8, 16);
_windowStyle.border = new RectOffset(8, 8, 8, 8);
GUIStyle val2 = new GUIStyle(GUI.skin.label);
val2.fontSize = 22;
val2.fontStyle = (FontStyle)1;
val2.alignment = (TextAnchor)1;
val2.normal.textColor = Color.white;
_titleStyle = val2;
GUIStyle val3 = new GUIStyle(GUI.skin.label);
val3.fontSize = 16;
val3.alignment = (TextAnchor)1;
val3.normal.textColor = new Color(0.85f, 0.85f, 0.85f);
val3.wordWrap = true;
_messageStyle = val3;
GUIStyle val4 = new GUIStyle(GUI.skin.label);
val4.fontSize = 14;
val4.alignment = (TextAnchor)1;
val4.normal.textColor = new Color(0.7f, 0.7f, 0.7f);
_costLabelStyle = val4;
GUIStyle val5 = new GUIStyle(GUI.skin.label);
val5.fontSize = 22;
val5.fontStyle = (FontStyle)1;
val5.alignment = (TextAnchor)1;
val5.normal.textColor = new Color(0.3f, 0.95f, 0.35f);
_costValueStyle = val5;
GUIStyle val6 = new GUIStyle(GUI.skin.button);
val6.fontSize = 16;
val6.fontStyle = (FontStyle)1;
val6.alignment = (TextAnchor)4;
val6.fixedHeight = 44f;
_confirmButtonStyle = val6;
GUIStyle val7 = new GUIStyle(GUI.skin.button);
val7.fontSize = 16;
val7.fontStyle = (FontStyle)1;
val7.alignment = (TextAnchor)4;
val7.fixedHeight = 44f;
_cancelButtonStyle = val7;
_separatorStyle = new GUIStyle();
Texture2D val8 = new Texture2D(1, 1);
val8.SetPixel(0, 0, new Color(0.35f, 0.35f, 0.4f, 0.8f));
val8.Apply();
_separatorStyle.normal.background = val8;
}
}
public static void RequestConfirmation(ButtonRerollShop button)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (_popupVisible || (Object)(object)_pendingButton != (Object)null)
{
return;
}
_pendingButton = button;
if (!((Object)(object)_instance == (Object)null))
{
_instance._cost = GetRerollCost(button);
_instance._openTime = Time.unscaledTime;
_instance._savedCursorVisible = Cursor.visible;
_instance._savedCursorLockMode = Cursor.lockState;
_instance._cursorSaved = true;
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
_popupVisible = true;
if (!_instance._controllerRegistered)
{
AggroInputManager.PushController((IInputController)(object)_instance);
_instance._controllerRegistered = true;
}
Debug.Log((object)"[SafeShop] Popup opened");
}
}
private void ConfirmReroll()
{
ClosePopup();
ButtonRerollShop pendingButton = _pendingButton;
_pendingButton = null;
if (!((Object)(object)pendingButton == (Object)null) && !(_cmdRequestPressMethod == null))
{
Debug.Log((object)"[SafeShop] Player confirmed");
WarehouseButton_CmdRequestPress_Patch.BypassConfirmation = true;
WarehouseButton component = ((Component)pendingButton).GetComponent<WarehouseButton>();
if ((Object)(object)component != (Object)null)
{
MethodInfo cmdRequestPressMethod = _cmdRequestPressMethod;
object[] parameters = new object[1];
cmdRequestPressMethod.Invoke(component, parameters);
}
WarehouseButton_CmdRequestPress_Patch.BypassConfirmation = false;
if (SafeShopPlugin.EnableCooldown.Value)
{
StartCooldown(pendingButton);
}
}
}
private void CancelReroll()
{
if ((Object)(object)_pendingButton != (Object)null)
{
ResetButtonState(_pendingButton);
}
ClosePopup();
_pendingButton = null;
Debug.Log((object)"[SafeShop] Player cancelled");
}
private void ClosePopup()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
_popupVisible = false;
if (_controllerRegistered)
{
AggroInputManager.RemoveController((IInputController)(object)this);
_controllerRegistered = false;
}
if (_cursorSaved)
{
Cursor.visible = _savedCursorVisible;
Cursor.lockState = _savedCursorLockMode;
_cursorSaved = false;
}
}
private static void ResetButtonState(ButtonRerollShop button)
{
WarehouseButton component = ((Component)button).GetComponent<WarehouseButton>();
if (!((Object)(object)component == (Object)null))
{
if (_pressedField != null)
{
_pressedField.SetValue(component, false);
}
if (_receivedResponseField != null)
{
_receivedResponseField.SetValue(component, true);
}
}
}
private void OnDisable()
{
ForceClose();
}
private void OnDestroy()
{
ForceClose();
}
private void ForceClose()
{
if (_popupVisible)
{
if ((Object)(object)_pendingButton != (Object)null)
{
ResetButtonState(_pendingButton);
}
ClosePopup();
_pendingButton = null;
}
}
public static bool IsOnCooldown(ButtonRerollShop button)
{
if (!Cooldowns.TryGetValue(button, out var value))
{
return false;
}
return Time.unscaledTime < value;
}
public static float GetCooldownRemaining(ButtonRerollShop button)
{
if (!Cooldowns.TryGetValue(button, out var value))
{
return -1f;
}
return value - Time.unscaledTime;
}
private static void StartCooldown(ButtonRerollShop button)
{
float value = Time.unscaledTime + (float)SafeShopPlugin.CooldownSeconds.Value;
Cooldowns[button] = value;
Debug.Log((object)"[SafeShop] Cooldown started");
}
private static void RestoreButton(ButtonRerollShop button)
{
FloaterUI floaterUI = GetFloaterUI(button);
if ((Object)(object)floaterUI == (Object)null || _costTextField == null)
{
return;
}
object component = ((Component)floaterUI).GetComponent(typeof(ShopInfoFloaterUI));
if (component == null)
{
return;
}
object value = _costTextField.GetValue(component);
if (value != null)
{
PropertyInfo property = value.GetType().GetProperty("text");
if (property != null)
{
property.SetValue(value, "", null);
}
}
}
}