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 TMPro;
using UnityEngine;
using UnityEngine.UI;
[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("GiveCorrectChange")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GiveCorrectChange")]
[assembly: AssemblyTitle("GiveCorrectChange")]
[assembly: AssemblyVersion("1.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 GiveCorrectChange
{
[BepInPlugin("com.acesgaminguk.givecorrectchange", "GiveCorrectChange", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static Harmony Harmony;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<ChangeMode> Mode;
internal static ConfigEntry<KeyboardShortcut> ManualHotkey;
internal static ConfigEntry<float> PanelX;
internal static ConfigEntry<float> PanelY;
internal static Data_Container? ActiveCashRegister;
internal static bool ManualChangePrepared;
internal static float ManualPreparedAt;
private Rect _panelRect;
private bool _panelPositionLoaded;
private GUIStyle? _windowStyle;
private GUIStyle? _titleStyle;
private GUIStyle? _smallStyle;
private GUIStyle? _buttonStyle;
private GUIStyle? _dangerButtonStyle;
private void Awake()
{
//IL_0062: 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_013d: 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_0194: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("# General #", "Enabled", true, "Enable Give Correct Change.");
Mode = ((BaseUnityPlugin)this).Config.Bind<ChangeMode>("# General #", "Mode", ChangeMode.ManualFill, "ManualFill shows a status panel and uses the hotkey. AutoFill prepares the exact change automatically. AutoComplete immediately completes cash transactions.");
ManualHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("# Controls #", "ManualHotkey", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "Hotkey used in ManualFill mode to prepare the correct change. Rebind this in the config or BepInEx ConfigurationManager.");
PanelX = ((BaseUnityPlugin)this).Config.Bind<float>("# UI #", "PanelX", -1f, "ManualFill panel X position. -1 uses default centered position.");
PanelY = ((BaseUnityPlugin)this).Config.Bind<float>("# UI #", "PanelY", -1f, "ManualFill panel Y position. -1 uses default lower-screen position.");
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)string.Format("{0} v{1} Initializing...", "Give Correct Change", ((BaseUnityPlugin)this).Info.Metadata.Version));
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)"Author: AcesGamingUK");
((BaseUnityPlugin)this).Logger.LogMessage((object)"GitHub: https://github.com/AcesGamingUK/Give-Correct-Change");
((BaseUnityPlugin)this).Logger.LogMessage((object)("ManualFill hotkey: " + ((object)ManualHotkey.Value/*cast due to .constrained prefix*/).ToString()));
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)"Give Correct Change Initialized successfully!");
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
Harmony = new Harmony("com.acesgaminguk.givecorrectchange");
Harmony.PatchAll();
}
private void Update()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (Enabled.Value && Mode.Value == ChangeMode.ManualFill && !((Object)(object)ActiveCashRegister == (Object)null))
{
KeyboardShortcut value = ManualHotkey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
CorrectChangeHelper.PrepareCorrectChange(ActiveCashRegister, hideManualPrompt: false);
}
}
}
private void OnGUI()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Invalid comparison between Unknown and I4
if (Enabled.Value && Mode.Value == ChangeMode.ManualFill && !((Object)(object)ActiveCashRegister == (Object)null))
{
EnsureStyles();
EnsurePanelPosition();
_panelRect = GUI.Window(920041, _panelRect, new WindowFunction(DrawManualPanel), GUIContent.none, _windowStyle);
if ((int)Event.current.type == 1)
{
SavePanelPosition();
}
}
}
private void DrawManualPanel(int windowId)
{
//IL_005b: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
float moneyToReturn = CorrectChangeHelper.GetMoneyToReturn(ActiveCashRegister);
string text = (Object.op_Implicit((Object)(object)ProductListing.Instance) ? ProductListing.Instance.ConvertFloatToTextPrice(moneyToReturn) : ("$" + moneyToReturn.ToString("0.00")));
GUI.Label(new Rect(16f, 10f, ((Rect)(ref _panelRect)).width - 32f, 24f), "Give Correct Change", _titleStyle);
GUI.Label(new Rect(16f, 42f, ((Rect)(ref _panelRect)).width - 32f, 24f), "Change due: " + text, _smallStyle);
string text2 = (ManualChangePrepared ? "✓ Change Prepared" : ("Press [" + ((object)ManualHotkey.Value/*cast due to .constrained prefix*/).ToString() + "] to prepare change"));
GUI.Label(new Rect(16f, 72f, ((Rect)(ref _panelRect)).width - 32f, 30f), text2, _buttonStyle);
GUI.Label(new Rect(16f, 113f, ((Rect)(ref _panelRect)).width - 32f, 22f), ManualChangePrepared ? "Click the cash pile on the counter" : "Cash checkout only", _smallStyle);
GUI.Label(new Rect(16f, 140f, ((Rect)(ref _panelRect)).width - 32f, 20f), "Mode: ManualFill", _smallStyle);
GUI.Label(new Rect(16f, 162f, ((Rect)(ref _panelRect)).width - 32f, 18f), "Hotkey active during checkout", _smallStyle);
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _panelRect)).width, 34f));
}
private void EnsurePanelPosition()
{
//IL_00b8: 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)
if (!_panelPositionLoaded)
{
float num = 300f;
float num2 = 186f;
float num3 = ((float)Screen.width - num) / 2f;
float num4 = (float)Screen.height - 245f;
float num5 = ((PanelX.Value < 0f) ? num3 : PanelX.Value);
float num6 = ((PanelY.Value < 0f) ? num4 : PanelY.Value);
num5 = Mathf.Clamp(num5, 0f, Mathf.Max(0f, (float)Screen.width - num));
num6 = Mathf.Clamp(num6, 0f, Mathf.Max(0f, (float)Screen.height - num2));
_panelRect = new Rect(num5, num6, num, num2);
_panelPositionLoaded = true;
}
}
private void SavePanelPosition()
{
if (_panelPositionLoaded)
{
float num = Mathf.Round(((Rect)(ref _panelRect)).x);
float num2 = Mathf.Round(((Rect)(ref _panelRect)).y);
if (Mathf.Abs(PanelX.Value - num) > 0.5f)
{
PanelX.Value = num;
}
if (Mathf.Abs(PanelY.Value - num2) > 0.5f)
{
PanelY.Value = num2;
}
}
}
private void EnsureStyles()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
//IL_00c4: 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_00d3: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Expected O, but got Unknown
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: 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_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Expected O, but got Unknown
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: 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_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Expected O, but got Unknown
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Unknown result type (might be due to invalid IL or missing references)
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_0260: Expected O, but got Unknown
if (_windowStyle == null)
{
Texture2D background = MakeTexture(new Color(0.04f, 0.04f, 0.04f, 0.92f));
Texture2D background2 = MakeTexture(new Color(0.13f, 0.38f, 0.2f, 0.95f));
Texture2D background3 = MakeTexture(new Color(0.18f, 0.5f, 0.28f, 0.95f));
Texture2D background4 = MakeTexture(new Color(0.22f, 0.16f, 0.1f, 0.95f));
Texture2D background5 = MakeTexture(new Color(0.34f, 0.24f, 0.14f, 0.95f));
GUIStyle val = new GUIStyle(GUI.skin.window)
{
padding = new RectOffset(0, 0, 0, 0),
border = new RectOffset(8, 8, 8, 8)
};
val.normal.background = background;
_windowStyle = val;
GUIStyle val2 = new GUIStyle(GUI.skin.label)
{
alignment = (TextAnchor)4,
fontSize = 17,
fontStyle = (FontStyle)1
};
val2.normal.textColor = new Color(1f, 0.72f, 0.22f, 1f);
_titleStyle = val2;
GUIStyle val3 = new GUIStyle(GUI.skin.label)
{
alignment = (TextAnchor)4,
fontSize = 13
};
val3.normal.textColor = Color.white;
_smallStyle = val3;
GUIStyle val4 = new GUIStyle(GUI.skin.button)
{
alignment = (TextAnchor)4,
fontSize = 14,
fontStyle = (FontStyle)1
};
val4.normal.background = background2;
val4.normal.textColor = Color.white;
val4.hover.background = background3;
val4.hover.textColor = Color.white;
val4.active.background = background3;
val4.active.textColor = Color.white;
_buttonStyle = val4;
GUIStyle val5 = new GUIStyle(GUI.skin.button)
{
alignment = (TextAnchor)4,
fontSize = 12
};
val5.normal.background = background4;
val5.normal.textColor = Color.white;
val5.hover.background = background5;
val5.hover.textColor = Color.white;
val5.active.background = background5;
val5.active.textColor = Color.white;
_dangerButtonStyle = val5;
}
}
private static Texture2D MakeTexture(Color color)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: 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: Expected O, but got Unknown
Texture2D val = new Texture2D(1, 1);
val.SetPixel(0, 0, color);
val.Apply();
return val;
}
private void OnDestroy()
{
Harmony harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
public enum ChangeMode
{
ManualFill,
AutoFill,
AutoComplete
}
internal static class CorrectChangeHelper
{
private static readonly FieldInfo MoneyToReturnField = AccessTools.Field(typeof(Data_Container), "moneyToReturn");
private static readonly FieldInfo CurrentAmountToReturnField = AccessTools.Field(typeof(Data_Container), "currentAmountToReturn");
private static readonly FieldInfo AllowMoneyReturnField = AccessTools.Field(typeof(Data_Container), "allowMoneyReturn");
internal static bool FieldsReady()
{
if (MoneyToReturnField != null && CurrentAmountToReturnField != null && AllowMoneyReturnField != null)
{
return true;
}
Plugin.Log.LogError((object)"Could not find one or more checkout fields. Game update may have changed Data_Container.");
return false;
}
internal static float GetMoneyToReturn(Data_Container container)
{
if (!FieldsReady())
{
return 0f;
}
return Mathf.Round((float)MoneyToReturnField.GetValue(container) * 100f) / 100f;
}
internal static void PrepareCorrectChange(Data_Container container, bool hideManualPrompt)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!Plugin.Enabled.Value || !FieldsReady())
{
return;
}
float moneyToReturn = GetMoneyToReturn(container);
if (moneyToReturn < 0f)
{
return;
}
CurrentAmountToReturnField.SetValue(container, moneyToReturn);
AllowMoneyReturnField.SetValue(container, true);
Transform val = ((Component)container).transform.Find("CashRegisterCanvas/Container/CurrentAmount");
if (Object.op_Implicit((Object)(object)val))
{
TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>();
if (Object.op_Implicit((Object)(object)component))
{
((TMP_Text)component).text = ProductListing.Instance.ConvertFloatToTextPrice(moneyToReturn);
((Graphic)component).color = Color.green;
}
}
Transform val2 = ((Component)container).transform.Find("CashRegister/MoneyGivenBack");
if (Object.op_Implicit((Object)(object)val2))
{
((Component)val2).gameObject.SetActive(true);
}
if ((Object)(object)Plugin.ActiveCashRegister == (Object)(object)container)
{
Plugin.ManualChangePrepared = true;
Plugin.ManualPreparedAt = Time.realtimeSinceStartup;
}
if (hideManualPrompt && (Object)(object)Plugin.ActiveCashRegister == (Object)(object)container)
{
Plugin.ActiveCashRegister = null;
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Failed to prepare correct change: " + ex));
}
}
}
[HarmonyPatch(typeof(Data_Container), "UserCode_RpcHidePaymentMethod__Int32__Int32")]
internal static class DataContainer_RpcHidePaymentMethod_Patch
{
private static void Postfix(Data_Container __instance, int index, int amountGiven)
{
if (!Plugin.Enabled.Value || index != 0)
{
return;
}
try
{
if (CorrectChangeHelper.FieldsReady() && !(CorrectChangeHelper.GetMoneyToReturn(__instance) < 0f))
{
if (Plugin.Mode.Value == ChangeMode.AutoComplete)
{
Plugin.ActiveCashRegister = null;
Plugin.ManualChangePrepared = false;
__instance.CmdReceivePayment(0f);
}
else if (Plugin.Mode.Value == ChangeMode.AutoFill)
{
Plugin.ActiveCashRegister = null;
Plugin.ManualChangePrepared = false;
CorrectChangeHelper.PrepareCorrectChange(__instance, hideManualPrompt: true);
}
else
{
Plugin.ManualChangePrepared = false;
Plugin.ManualPreparedAt = 0f;
Plugin.ActiveCashRegister = __instance;
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Failed to set up manual correct change: " + ex));
}
}
}
[HarmonyPatch(typeof(Data_Container), "UserCode_CmdReceivePayment__Single")]
internal static class DataContainer_CmdReceivePayment_Patch
{
private static void Prefix(Data_Container __instance, ref float returnDifference)
{
if (!Plugin.Enabled.Value)
{
return;
}
try
{
if (Plugin.Mode.Value == ChangeMode.AutoFill || Plugin.Mode.Value == ChangeMode.ManualFill)
{
float moneyToReturn = CorrectChangeHelper.GetMoneyToReturn(__instance);
if (Mathf.Abs(__instance.currentAmountToReturn - moneyToReturn) <= 0.011f)
{
returnDifference = 0f;
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Failed to normalize return difference: " + ex));
}
}
private static void Postfix(Data_Container __instance)
{
if ((Object)(object)Plugin.ActiveCashRegister == (Object)(object)__instance)
{
Plugin.ActiveCashRegister = null;
Plugin.ManualChangePrepared = false;
Plugin.ManualPreparedAt = 0f;
}
}
}
internal static class PluginInfo
{
public const string Guid = "com.acesgaminguk.givecorrectchange";
public const string Name = "GiveCorrectChange";
public const string DisplayName = "Give Correct Change";
public const string Version = "1.0.0";
public const string Author = "AcesGamingUK";
public const string Website = "https://github.com/AcesGamingUK/Give-Correct-Change";
}
}