using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterResourceChest.Configuration;
using BetterResourceChest.Localization;
using BetterResourceChest.Utils;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace BetterResourceChest
{
[BepInPlugin("IceBoxStudio.BetterResourceChest", "BetterResourceChest", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class BetterResourceChest : BaseUnityPlugin
{
private static BetterResourceChest _instance;
private Harmony _harmony;
private bool _patched;
public static BetterResourceChest Instance => _instance;
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
_instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"=============================================");
Logger.LogInfo((object)("BetterResourceChest " + LocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
ApplyPatches();
RegisterModConfig();
Logger.LogInfo((object)("BetterResourceChest " + LocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
Logger.LogInfo((object)"=============================================");
}
private void ApplyPatches()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
if (_patched)
{
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
return;
}
_harmony = new Harmony("IceBoxStudio.BetterResourceChest");
_harmony.PatchAll();
_patched = true;
}
private static void RegisterModConfig()
{
try
{
Type type = Type.GetType("ModConfigManager.Api.ModConfigManagerApi, ModConfigManager");
if (!(type == null))
{
type.GetMethod("RegisterHotkeyCompatibleByGuid")?.Invoke(null, new object[1] { "IceBoxStudio.BetterResourceChest" });
type.GetMethod("RegisterModDisplayName")?.Invoke(null, new object[2] { "BetterResourceChest", "更好的材料箱" });
}
}
catch
{
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IceBoxStudio.BetterResourceChest";
public const string PLUGIN_NAME = "BetterResourceChest";
public const string PLUGIN_VERSION = "1.0.1";
}
}
namespace BetterResourceChest.Utils
{
public static class InputActionBindingHelper
{
public static InputAction CreateButtonAction(string actionName, string hotkey, Action onPerformed)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
string text = BuildBindingPath(hotkey);
if (string.IsNullOrWhiteSpace(text))
{
return null;
}
InputAction val = new InputAction(actionName, (InputActionType)1, text, (string)null, (string)null, (string)null);
if (onPerformed != null)
{
val.performed += delegate
{
onPerformed();
};
}
val.Enable();
return val;
}
public static InputAction CreateValueAction(string actionName, string hotkey)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
string text = BuildBindingPath(hotkey);
if (string.IsNullOrWhiteSpace(text))
{
return null;
}
InputAction val = new InputAction(actionName, (InputActionType)0, text, (string)null, (string)null, (string)null);
val.Enable();
return val;
}
public static string BuildBindingPath(string hotkey)
{
if (string.IsNullOrWhiteSpace(hotkey))
{
return null;
}
string text = hotkey.Trim();
if (text.Contains("<") && text.Contains(">"))
{
return text;
}
string text2 = text.ToLowerInvariant();
switch (text2)
{
case "mousewheel":
case "mousescroll":
return "<Mouse>/scroll";
case "leftbutton":
return "<Mouse>/leftButton";
case "rightbutton":
return "<Mouse>/rightButton";
case "middlebutton":
return "<Mouse>/middleButton";
case "backbutton":
return "<Mouse>/backButton";
case "forwardbutton":
return "<Mouse>/forwardButton";
default:
return text2 switch
{
"buttonsouth" => "<Gamepad>/buttonSouth",
"buttoneast" => "<Gamepad>/buttonEast",
"buttonwest" => "<Gamepad>/buttonWest",
"buttonnorth" => "<Gamepad>/buttonNorth",
"leftshoulder" => "<Gamepad>/leftShoulder",
"rightshoulder" => "<Gamepad>/rightShoulder",
"lefttrigger" => "<Gamepad>/leftTrigger",
"righttrigger" => "<Gamepad>/rightTrigger",
"dpadup" => "<Gamepad>/dpad/up",
"dpaddown" => "<Gamepad>/dpad/down",
"dpadleft" => "<Gamepad>/dpad/left",
"dpadright" => "<Gamepad>/dpad/right",
"startbutton" => "<Gamepad>/start",
"selectbutton" => "<Gamepad>/select",
"leftstickpress" => "<Gamepad>/leftStickPress",
"rightstickpress" => "<Gamepad>/rightStickPress",
_ => "<Keyboard>/" + text2,
};
}
}
public static string FormatHotkeyForDisplay(string s)
{
if (string.IsNullOrWhiteSpace(s))
{
return string.Empty;
}
s = s.Trim();
if (s.Length == 1)
{
return s.ToUpperInvariant();
}
if (s[0] == 'f' || s[0] == 'F')
{
bool flag = true;
for (int i = 1; i < s.Length; i++)
{
if (!char.IsDigit(s[i]))
{
flag = false;
break;
}
}
if (flag)
{
return ("F" + s.Substring(1)).ToUpperInvariant();
}
}
string text = s.ToLowerInvariant();
switch (text)
{
case "mousewheel":
case "mousescroll":
return "Mouse Wheel";
case "leftbutton":
return "Mouse Left";
case "rightbutton":
return "Mouse Right";
case "middlebutton":
return "Mouse Middle";
case "backbutton":
return "Mouse Back";
case "forwardbutton":
return "Mouse Forward";
default:
switch (text)
{
case "buttonsouth":
return "Gamepad A";
case "buttoneast":
return "Gamepad B";
case "buttonwest":
return "Gamepad X";
case "buttonnorth":
return "Gamepad Y";
case "leftshoulder":
return "Gamepad LB";
case "rightshoulder":
return "Gamepad RB";
case "lefttrigger":
return "Gamepad LT";
case "righttrigger":
return "Gamepad RT";
case "dpadup":
return "D-Pad Up";
case "dpaddown":
return "D-Pad Down";
case "dpadleft":
return "D-Pad Left";
case "dpadright":
return "D-Pad Right";
case "startbutton":
return "Gamepad Start";
case "selectbutton":
return "Gamepad Select";
case "leftstickpress":
return "Left Stick Press";
case "rightstickpress":
return "Right Stick Press";
default:
switch (text.Length)
{
case 5:
switch (text[0])
{
case 's':
if (!(text == "slash"))
{
break;
}
return "/";
case 'm':
if (!(text == "minus"))
{
break;
}
return "-";
case 'c':
if (!(text == "comma"))
{
break;
}
return ",";
case 'q':
if (!(text == "quote"))
{
break;
}
return "'";
}
break;
case 9:
switch (text[4])
{
case 's':
if (!(text == "backslash"))
{
break;
}
return "\\";
case 'c':
if (!(text == "semicolon"))
{
break;
}
return ";";
case 'q':
if (!(text == "backquote"))
{
break;
}
return "`";
}
break;
case 6:
switch (text[0])
{
case 'e':
if (!(text == "equals"))
{
break;
}
return "=";
case 'p':
if (!(text == "period"))
{
break;
}
return ".";
}
break;
case 4:
if (!(text == "plus"))
{
break;
}
return "+";
case 11:
if (!(text == "leftbracket"))
{
break;
}
return "[";
case 12:
if (!(text == "rightbracket"))
{
break;
}
return "]";
}
break;
case null:
break;
}
switch (text)
{
case "alt":
case "ctrl":
case "shift":
case "enter":
case "space":
case "escape":
case "esc":
case "tab":
case "backspace":
case "capslock":
return char.ToUpper(s[0]) + s.Substring(1).ToLowerInvariant();
case "leftalt":
return "LeftAlt";
case "rightalt":
return "RightAlt";
case "leftctrl":
return "LeftCtrl";
case "rightctrl":
return "RightCtrl";
case "leftshift":
return "LeftShift";
case "rightshift":
return "RightShift";
default:
return char.ToUpper(s[0]) + s.Substring(1).ToLowerInvariant();
}
}
}
}
}
namespace BetterResourceChest.Patches
{
[HarmonyPatch(typeof(BlockChest))]
public static class CheckoutPatch
{
[HarmonyPatch("Interact")]
[HarmonyPrefix]
public static bool Interact_Prefix(BlockChest __instance)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (!ChestTools.IsEnabled("BulkDeposit"))
{
return true;
}
if (!((Interactable)__instance).CanInteract())
{
return true;
}
PlayerInventory localInventory = ChestTools.GetLocalInventory(__instance);
if ((Object)(object)localInventory == (Object)null)
{
return true;
}
if (localInventory.GetCurrentInventorySlot().itemId == -1)
{
return true;
}
ItemSO currentItemSO = localInventory.GetCurrentItemSO();
ItemSO storedItemSO = __instance.GetStoredItemSO();
if ((Object)(object)currentItemSO == (Object)null)
{
return true;
}
if ((Object)(object)storedItemSO != (Object)null && storedItemSO.id != currentItemSO.id)
{
return true;
}
int maxAmount = __instance.maxCapacity - __instance.GetStoredItemAmountVariable();
if (GetTotalItemCount(localInventory, currentItemSO, maxAmount) <= 1)
{
return true;
}
__instance.PlaceItemServerRpc(default(ServerRpcParams));
return false;
}
[HarmonyPatch("PlaceItemServerRpc")]
[HarmonyPrefix]
public static bool PlaceItemServerRpc_Prefix(BlockChest __instance, ServerRpcParams serverRpcParams = default(ServerRpcParams))
{
//IL_0032: 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_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
if (!ChestTools.IsEnabled("BulkDeposit"))
{
return true;
}
if (!ChestTools.IsExecuteStage((NetworkBehaviour)(object)__instance) || (!((NetworkBehaviour)__instance).NetworkManager.IsServer && !((NetworkBehaviour)__instance).NetworkManager.IsHost))
{
return true;
}
ulong senderClientId = serverRpcParams.Receive.SenderClientId;
PlayerInventory component = ((Component)NetworkManager.Singleton.ConnectedClients[senderClientId].PlayerObject).GetComponent<PlayerInventory>();
InventorySlot currentInventorySlot = component.GetCurrentInventorySlot();
if (currentInventorySlot.itemId == -1)
{
return true;
}
ItemSO currentItemSO = component.GetCurrentItemSO();
if ((Object)(object)currentItemSO == (Object)null)
{
return true;
}
NetworkVariable<long> storedItemId = ChestTools.GetStoredItemId(__instance);
NetworkVariable<int> storedItemAmount = ChestTools.GetStoredItemAmount(__instance);
if (storedItemId == null || storedItemAmount == null)
{
return true;
}
if (storedItemId.Value == -1)
{
if (!__instance.allowedItems.Contains(currentItemSO))
{
return true;
}
}
else if (storedItemId.Value != currentItemSO.id)
{
return true;
}
int maxAmount = __instance.maxCapacity - storedItemAmount.Value;
int totalItemCount = GetTotalItemCount(component, currentItemSO, maxAmount);
if (totalItemCount <= 1)
{
return true;
}
if (storedItemId.Value == -1)
{
storedItemId.Value = currentInventorySlot.itemId;
}
storedItemAmount.Value += totalItemCount;
component.RemoveItem(currentItemSO, totalItemCount);
return false;
}
private static int GetTotalItemCount(PlayerInventory inventory, ItemSO item, int maxAmount)
{
if ((Object)(object)inventory == (Object)null || (Object)(object)item == (Object)null || maxAmount <= 0)
{
return 0;
}
return Mathf.Min(inventory.GetItemCount(item), maxAmount);
}
}
[HarmonyPatch(typeof(ChestPickup))]
public static class ChestPickupPatch
{
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
public static void GetDescription_Postfix(ref string __result)
{
if (!string.IsNullOrEmpty(__result))
{
__result = __result + "\n" + ChestTools.GetTakeAmountHint();
}
}
[HarmonyPatch("Interact")]
[HarmonyPrefix]
public static bool Interact_Prefix(ChestPickup __instance)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance.blockChest == (Object)null || !((Interactable)__instance).CanInteract())
{
return true;
}
ItemSO storedItemSO = __instance.blockChest.GetStoredItemSO();
if ((Object)(object)storedItemSO == (Object)null)
{
return true;
}
PlayerInventory localInventory = ChestTools.GetLocalInventory(__instance.blockChest);
if ((Object)(object)localInventory == (Object)null)
{
return true;
}
int freeSpace = ChestTools.GetFreeSpace(localInventory, storedItemSO);
int num = Mathf.Min(ChestTools.GetTakeAmount(), Mathf.Min(freeSpace, __instance.blockChest.GetStoredItemAmountVariable()));
if (num <= 1)
{
return true;
}
for (int i = 0; i < num; i++)
{
__instance.blockChest.TakeItemServerRpc(default(ServerRpcParams));
}
return false;
}
}
[HarmonyPatch(typeof(PlayerInteraction))]
public static class PlayerInteractionPatch
{
private static readonly FieldInfo MainCameraField = AccessTools.Field(typeof(PlayerInteraction), "mainCamera");
[HarmonyPatch("InteractionRay")]
[HarmonyPostfix]
public static void InteractionRay_Postfix(PlayerInteraction __instance)
{
if (TryGetChestPickup(__instance, out var pickup) && ChestTools.UpdateTakeAmountInput())
{
((TMP_Text)__instance.textPrimaryInteraction).text = ((Interactable)pickup).GetDescription();
}
}
internal static bool TryGetChestPickup(PlayerInteraction interaction, out ChestPickup pickup)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
pickup = null;
object? value = MainCameraField.GetValue(interaction);
Camera val = (Camera)((value is Camera) ? value : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
RaycastHit val2 = default(RaycastHit);
if (!Physics.Raycast(val.ViewportPointToRay(Vector3.one / 2f), ref val2, interaction.interactionDistance, LayerMask.op_Implicit(interaction.layerMask), (QueryTriggerInteraction)1))
{
return false;
}
pickup = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<ChestPickup>();
return (Object)(object)pickup != (Object)null;
}
}
internal static class ChestTools
{
private static readonly FieldInfo CurrentSlotField = AccessTools.Field(typeof(PlayerInventory), "currentSlot");
private static readonly FieldInfo ActiveSlotsField = AccessTools.Field(typeof(PlayerInventory), "activeSlots");
private static readonly FieldInfo LocalPlayerInventoryField = AccessTools.Field(typeof(BlockChest), "localPlayerInventory");
private static readonly FieldInfo StoredItemIdField = AccessTools.Field(typeof(BlockChest), "storedItemID");
private static readonly FieldInfo StoredItemAmountField = AccessTools.Field(typeof(BlockChest), "storedItemAmount");
private static readonly FieldInfo RpcExecStageField = AccessTools.Field(typeof(NetworkBehaviour), "__rpc_exec_stage");
private static int _takeAmount = -1;
private static InputAction _takeAmountWheelAction;
private static InputAction _takeAmountUpAction;
private static InputAction _takeAmountDownAction;
private static string _takeAmountUpBinding = "";
private static string _takeAmountDownBinding = "";
private static InputAction _quickStackAction;
private static string _quickStackBinding;
public static int GetCapacity()
{
if (ConfigManager.Instance == null)
{
return 250;
}
return Mathf.Max(1, ConfigManager.Instance.GetInt("Capacity", 250));
}
public static int GetTakeAmount()
{
if (_takeAmount < 1)
{
if (ConfigManager.Instance == null)
{
_takeAmount = 5;
}
else
{
_takeAmount = Mathf.Max(1, ConfigManager.Instance.GetInt("DefaultTakeAmount", 5));
}
}
return _takeAmount;
}
public static void ChangeTakeAmount(int delta)
{
_takeAmount = Mathf.Clamp(GetTakeAmount() + delta, 1, 999);
}
private static string GetUpInput()
{
if (ConfigManager.Instance == null)
{
return "";
}
return ConfigManager.Instance.GetString("TakeAmountUp");
}
private static string GetDownInput()
{
if (ConfigManager.Instance == null)
{
return "";
}
return ConfigManager.Instance.GetString("TakeAmountDown");
}
public static bool UpdateTakeAmountInput()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
EnsureWheel();
EnsureTakeAmountButtons();
if (_takeAmountWheelAction != null)
{
Vector2 val = _takeAmountWheelAction.ReadValue<Vector2>();
if (val.y > 0.01f)
{
ChangeTakeAmount(1);
return true;
}
if (val.y < -0.01f)
{
ChangeTakeAmount(-1);
return true;
}
}
if (_takeAmountUpAction != null && _takeAmountUpAction.WasPerformedThisFrame())
{
ChangeTakeAmount(1);
return true;
}
if (_takeAmountDownAction != null && _takeAmountDownAction.WasPerformedThisFrame())
{
ChangeTakeAmount(-1);
return true;
}
return false;
}
public static string GetTakeAmountHint()
{
string upInput = GetUpInput();
string downInput = GetDownInput();
string text = ((string.IsNullOrEmpty(upInput) || string.IsNullOrEmpty(downInput)) ? InputActionBindingHelper.FormatHotkeyForDisplay("MouseWheel") : (InputActionBindingHelper.FormatHotkeyForDisplay(upInput) + "/" + InputActionBindingHelper.FormatHotkeyForDisplay(downInput)));
return LocalizationManager.Instance.GetLocalizedText("hint.take_amount", GetTakeAmount(), text);
}
public static bool IsEnabled(string key)
{
if (ConfigManager.Instance != null)
{
return ConfigManager.Instance.IsPatchEnabled(key);
}
return false;
}
public static PlayerInventory GetLocalInventory(BlockChest chest)
{
object? value = LocalPlayerInventoryField.GetValue(chest);
PlayerInventory val = (PlayerInventory)((value is PlayerInventory) ? value : null);
if ((Object)(object)val == (Object)null && (Object)(object)((NetworkBehaviour)chest).NetworkManager != (Object)null && ((NetworkBehaviour)chest).NetworkManager.LocalClient != null && (Object)(object)((NetworkBehaviour)chest).NetworkManager.LocalClient.PlayerObject != (Object)null)
{
val = ((Component)((NetworkBehaviour)chest).NetworkManager.LocalClient.PlayerObject).GetComponent<PlayerInventory>();
LocalPlayerInventoryField.SetValue(chest, val);
}
return val;
}
public static int GetCurrentSlotIndex(PlayerInventory inventory)
{
if (!(CurrentSlotField.GetValue(inventory) is NetworkVariable<int> val))
{
return 0;
}
return val.Value;
}
public static int GetActiveSlotCount(PlayerInventory inventory)
{
object value = ActiveSlotsField.GetValue(inventory);
if (value is int)
{
return (int)value;
}
return 0;
}
public static void RemoveCurrentItem(PlayerInventory inventory, int amount)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_0058: 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)
if ((Object)(object)inventory == (Object)null || amount <= 0)
{
return;
}
InventorySlot currentInventorySlot = inventory.GetCurrentInventorySlot();
if (currentInventorySlot.itemId != -1)
{
int num = currentInventorySlot.amount - amount;
if (num > 0)
{
inventory.slots[GetCurrentSlotIndex(inventory)] = new InventorySlot
{
itemId = currentInventorySlot.itemId,
amount = num,
cost = currentInventorySlot.cost,
dayCounter = 0
};
}
else
{
inventory.UseItem();
}
}
}
public static int GetFreeSpace(PlayerInventory inventory, ItemSO item)
{
//IL_0040: 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_0046: 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_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)inventory == (Object)null || (Object)(object)item == (Object)null || inventory.slots == null)
{
return 0;
}
int num = Mathf.Min(GetActiveSlotCount(inventory), inventory.slots.Count);
int num2 = 0;
for (int i = 0; i < num; i++)
{
InventorySlot val = inventory.slots[i];
if (val.itemId == -1)
{
num2 += item.stackSize;
}
else if (val.itemId == item.id && val.amount < item.stackSize)
{
num2 += item.stackSize - val.amount;
}
}
return num2;
}
public static NetworkVariable<long> GetStoredItemId(BlockChest chest)
{
return StoredItemIdField.GetValue(chest) as NetworkVariable<long>;
}
public static NetworkVariable<int> GetStoredItemAmount(BlockChest chest)
{
return StoredItemAmountField.GetValue(chest) as NetworkVariable<int>;
}
public static bool IsExecuteStage(NetworkBehaviour behaviour)
{
object value = RpcExecStageField.GetValue(behaviour);
if (value != null)
{
return value.ToString() == "Execute";
}
return false;
}
public static bool UsesMouseWheel()
{
return true;
}
private static void EnsureWheel()
{
if (_takeAmountWheelAction == null)
{
_takeAmountWheelAction = InputActionBindingHelper.CreateValueAction("TakeAmountWheel", "MouseWheel");
}
}
private static void EnsureTakeAmountButtons()
{
string upInput = GetUpInput();
string downInput = GetDownInput();
bool flag = _takeAmountUpBinding != upInput;
bool flag2 = _takeAmountDownBinding != downInput;
if (!flag && !flag2)
{
return;
}
if (flag)
{
InputAction takeAmountUpAction = _takeAmountUpAction;
if (takeAmountUpAction != null)
{
takeAmountUpAction.Disable();
}
InputAction takeAmountUpAction2 = _takeAmountUpAction;
if (takeAmountUpAction2 != null)
{
takeAmountUpAction2.Dispose();
}
_takeAmountUpAction = null;
_takeAmountUpBinding = null;
}
if (flag2)
{
InputAction takeAmountDownAction = _takeAmountDownAction;
if (takeAmountDownAction != null)
{
takeAmountDownAction.Disable();
}
InputAction takeAmountDownAction2 = _takeAmountDownAction;
if (takeAmountDownAction2 != null)
{
takeAmountDownAction2.Dispose();
}
_takeAmountDownAction = null;
_takeAmountDownBinding = null;
}
if (!string.IsNullOrEmpty(upInput))
{
_takeAmountUpBinding = upInput;
_takeAmountUpAction = InputActionBindingHelper.CreateButtonAction("TakeAmountUp", upInput, delegate
{
});
if (_takeAmountUpAction != null)
{
_takeAmountUpAction.Enable();
}
}
if (!string.IsNullOrEmpty(downInput))
{
_takeAmountDownBinding = downInput;
_takeAmountDownAction = InputActionBindingHelper.CreateButtonAction("TakeAmountDown", downInput, delegate
{
});
if (_takeAmountDownAction != null)
{
_takeAmountDownAction.Enable();
}
}
}
public static void SetupQuickStack()
{
bool flag = ConfigManager.Instance?.IsPatchEnabled("QuickStackEnabled") ?? true;
string text = ConfigManager.Instance?.GetString("QuickStackKey", "T") ?? "T";
if (_quickStackAction == null || !(_quickStackBinding == text))
{
InputAction quickStackAction = _quickStackAction;
if (quickStackAction != null)
{
quickStackAction.Disable();
}
InputAction quickStackAction2 = _quickStackAction;
if (quickStackAction2 != null)
{
quickStackAction2.Dispose();
}
_quickStackAction = null;
_quickStackBinding = null;
if (flag)
{
_quickStackBinding = text;
_quickStackAction = InputActionBindingHelper.CreateButtonAction("QuickStack", text, QuickStack);
}
}
}
private static void QuickStack()
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: 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_01af: 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)
NetworkManager singleton = NetworkManager.Singleton;
if ((Object)(object)singleton == (Object)null || singleton.LocalClient == null || (Object)(object)singleton.LocalClient.PlayerObject == (Object)null)
{
return;
}
PlayerInventory component = ((Component)singleton.LocalClient.PlayerObject).GetComponent<PlayerInventory>();
if ((Object)(object)component == (Object)null || component.slots == null)
{
return;
}
Vector3 position = ((Component)singleton.LocalClient.PlayerObject).transform.position;
int num = Mathf.Min(GetActiveSlotCount(component), component.slots.Count);
float num2 = ConfigManager.Instance?.GetFloat("QuickStackRange", 5f) ?? 5f;
int num3 = 0;
BlockChest[] array = Object.FindObjectsOfType<BlockChest>();
foreach (BlockChest val in array)
{
if ((Object)(object)val == (Object)null || Vector3.Distance(((Component)val).transform.position, position) > num2)
{
continue;
}
NetworkVariable<long> storedItemId = GetStoredItemId(val);
if (storedItemId == null || storedItemId.Value <= 0)
{
continue;
}
int num4 = -1;
int num5 = 0;
for (int j = 0; j < num; j++)
{
if (component.slots[j].itemId == storedItemId.Value)
{
if (num4 < 0)
{
num4 = j;
}
num5 += component.slots[j].amount;
}
}
if (num4 < 0 || num5 <= 0)
{
continue;
}
int num6 = GetStoredItemAmount(val)?.Value ?? 0;
int num7 = val.maxCapacity - num6;
if (num7 > 0)
{
int num8 = Mathf.Min(num5, num7);
num3 += num8;
if (CurrentSlotField.GetValue(component) is NetworkVariable<int> val2)
{
val2.Value = num4;
}
val.PlaceItemServerRpc(default(ServerRpcParams));
}
}
if (num3 > 0 && (Object)(object)UIManager.Instance != (Object)null)
{
string localizedText = LocalizationManager.Instance.GetLocalizedText("hint.quick_stack_result", num3);
UIManager.Instance.ShowNotification(localizedText, false, 3f, false);
}
}
}
[HarmonyPatch(typeof(BlockChest))]
public static class GameManagerPatch
{
[HarmonyPatch("OnNetworkSpawn")]
[HarmonyPostfix]
public static void OnNetworkSpawn_Postfix(BlockChest __instance)
{
__instance.maxCapacity = ChestTools.GetCapacity();
}
}
[HarmonyPatch(typeof(PlayerInventory))]
public static class PlayerInventoryPatch
{
[HarmonyPatch("HandleScroll")]
[HarmonyPrefix]
public static bool HandleScroll_Prefix(PlayerInventory __instance)
{
if (!ChestTools.UsesMouseWheel())
{
return true;
}
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.playerInteraction == (Object)null)
{
return true;
}
ChestPickup pickup;
return !PlayerInteractionPatch.TryGetChestPickup(__instance.playerInteraction, out pickup);
}
}
[HarmonyPatch(typeof(UIManager))]
internal static class UIManagerHotkeyPatch
{
private static bool _init;
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void Awake_Postfix()
{
if (!_init)
{
_init = true;
ChestTools.SetupQuickStack();
}
}
}
}
namespace BetterResourceChest.Localization
{
public static class LocalizationHelper
{
public static Dictionary<string, string> GetDefaultTranslations(string language)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
switch (language)
{
case "zh":
dictionary.Add("plugin.initializing", "开始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
dictionary.Add("config.section.resource_chest", "材料箱");
dictionary.Add("config.bulk_deposit", "一次性放置背包内相同物品");
dictionary.Add("config.default_take_amount", "默认取出数量\n默认:5");
dictionary.Add("config.take_amount_up", "增加取出数量的快捷键\n留空使用鼠标滚轮\n默认:无");
dictionary.Add("config.take_amount_down", "减少取出数量的快捷键\n留空使用鼠标滚轮\n默认:无");
dictionary.Add("config.capacity", "材料箱容量\n默认:250");
dictionary.Add("config.quick_stack_enabled", "启用快速堆叠");
dictionary.Add("config.quick_stack_key", "快速堆叠快捷键\n默认:T");
dictionary.Add("config.quick_stack_range", "快速堆叠范围(米)\n默认:5");
dictionary.Add("hint.take_amount", "当前取出: {0} | 使用 {1} 调整取出数量");
dictionary.Add("hint.quick_stack_result", "已将 {0} 件物品存入附近的材料箱。");
break;
case "zh-Hant":
dictionary.Add("plugin.initializing", "開始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
dictionary.Add("config.section.resource_chest", "材料箱");
dictionary.Add("config.bulk_deposit", "一次性放置背包內相同物品");
dictionary.Add("config.default_take_amount", "預設取出數量\n預設:5");
dictionary.Add("config.take_amount_up", "增加取出數量的快捷鍵\n留空使用滑鼠滾輪\n預設:無");
dictionary.Add("config.take_amount_down", "減少取出數量的快捷鍵\n留空使用滑鼠滾輪\n預設:無");
dictionary.Add("config.capacity", "材料箱容量\n預設:250");
dictionary.Add("config.quick_stack_enabled", "啟用快速堆疊");
dictionary.Add("config.quick_stack_key", "快速堆疊快捷鍵\n預設:T");
dictionary.Add("config.quick_stack_range", "快速堆疊範圍(公尺)\n預設:5");
dictionary.Add("hint.take_amount", "目前取出: {0} | 使用 {1} 調整取出數量");
dictionary.Add("hint.quick_stack_result", "已將 {0} 件物品存入附近的材料箱。");
break;
case "en":
dictionary.Add("plugin.initializing", "Initializing...");
dictionary.Add("plugin.author_prefix", "Author: ");
dictionary.Add("plugin.initialized", "Initialized");
dictionary.Add("plugin.patches_skipped", "Patches already applied");
dictionary.Add("config.section.resource_chest", "Resource chest");
dictionary.Add("config.bulk_deposit", "Deposit all matching items at once");
dictionary.Add("config.default_take_amount", "Default take amount\nDefault: 5");
dictionary.Add("config.take_amount_up", "Increase take amount hotkey\nLeave empty to use mouse wheel\nDefault: None");
dictionary.Add("config.take_amount_down", "Decrease take amount hotkey\nLeave empty to use mouse wheel\nDefault: None");
dictionary.Add("config.capacity", "Resource chest capacity\nDefault: 250");
dictionary.Add("config.quick_stack_enabled", "Enable quick stack");
dictionary.Add("config.quick_stack_key", "Quick stack hotkey\nDefault: T");
dictionary.Add("config.quick_stack_range", "Quick stack range (m)\nDefault: 5");
dictionary.Add("hint.take_amount", "Take amount: {0} | Use {1} to adjust");
dictionary.Add("hint.quick_stack_result", "Deposited {0} items to nearby chests.");
break;
case "ja":
dictionary.Add("plugin.initializing", "初期化中...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初期化に成功しました!");
dictionary.Add("plugin.patches_skipped", "パッチは既に適用されています。スキップします...");
dictionary.Add("config.section.resource_chest", "資源箱");
dictionary.Add("config.bulk_deposit", "同じアイテムを一度に預ける");
dictionary.Add("config.default_take_amount", "デフォルト取出数\nデフォルト:5");
dictionary.Add("config.take_amount_up", "取出数を増やすホットキー\n空の場合はマウスホイール\nデフォルト:なし");
dictionary.Add("config.take_amount_down", "取出数を減らすホットキー\n空の場合はマウスホイール\nデフォルト:なし");
dictionary.Add("config.capacity", "資源箱の容量\nデフォルト:250");
dictionary.Add("config.quick_stack_enabled", "クイックスタックを有効にする");
dictionary.Add("config.quick_stack_key", "クイックスタックホットキー\nデフォルト:T");
dictionary.Add("config.quick_stack_range", "クイックスタック範囲(m)\nデフォルト:5");
dictionary.Add("hint.take_amount", "取出数: {0} | {1}で調整");
dictionary.Add("hint.quick_stack_result", "{0}個のアイテムを近くの資源箱に預けました。");
break;
}
return dictionary;
}
}
public class LocalizationManager
{
private static LocalizationManager _instance;
private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();
private string _currentLocale = "zh";
public static readonly string[] SupportedLanguages = new string[12]
{
"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
"tr", "uk"
};
public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());
private LocalizationManager()
{
Initialize();
}
public void Initialize()
{
//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)
if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
{
LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
}
string[] supportedLanguages = SupportedLanguages;
foreach (string text in supportedLanguages)
{
Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
if (defaultTranslations != null && defaultTranslations.Count > 0)
{
_localizations[text] = defaultTranslations;
}
}
LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
}
private void OnGameLanguageChanged(Locale locale)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)locale != (Object)null)
{
LocaleIdentifier identifier = locale.Identifier;
string code = ((LocaleIdentifier)(ref identifier)).Code;
if (_localizations.ContainsKey(code))
{
_currentLocale = code;
}
else
{
_currentLocale = "en";
}
}
}
public string GetLocalizedText(string key, params object[] args)
{
if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
{
_currentLocale = "en";
}
if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
{
if (args.Length == 0)
{
return value;
}
return string.Format(value, args);
}
if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
{
if (args.Length == 0)
{
return value2;
}
return string.Format(value2, args);
}
if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
{
if (args.Length == 0)
{
return value3;
}
return string.Format(value3, args);
}
return key;
}
}
}
namespace BetterResourceChest.Configuration
{
public class ConfigManager
{
private static ConfigManager _instance;
private readonly ConfigFile _configFile;
private readonly Dictionary<string, ConfigEntry<bool>> _boolConfigs;
private readonly Dictionary<string, ConfigEntry<string>> _stringConfigs;
private readonly Dictionary<string, ConfigEntry<int>> _intConfigs;
private readonly Dictionary<string, ConfigEntry<float>> _floatConfigs;
public static ConfigManager Instance => _instance;
private ConfigManager(ConfigFile configFile)
{
_configFile = configFile;
_boolConfigs = new Dictionary<string, ConfigEntry<bool>>();
_stringConfigs = new Dictionary<string, ConfigEntry<string>>();
_intConfigs = new Dictionary<string, ConfigEntry<int>>();
_floatConfigs = new Dictionary<string, ConfigEntry<float>>();
InitializeDefaultConfigs();
}
public static void Initialize(ConfigFile configFile)
{
if (_instance == null)
{
_instance = new ConfigManager(configFile);
}
}
private void InitializeDefaultConfigs()
{
string section = Text("config.section.resource_chest");
RegisterBool(section, "BulkDeposit", Text("config.bulk_deposit"), defaultValue: true);
RegisterInt(section, "DefaultTakeAmount", Text("config.default_take_amount"), 5);
RegisterString(section, "TakeAmountUp", Text("config.take_amount_up"), "");
RegisterString(section, "TakeAmountDown", Text("config.take_amount_down"), "");
RegisterInt(section, "Capacity", Text("config.capacity"), 300);
RegisterBool(section, "QuickStackEnabled", Text("config.quick_stack_enabled"), defaultValue: true);
RegisterString(section, "QuickStackKey", Text("config.quick_stack_key"), "T");
RegisterFloat(section, "QuickStackRange", Text("config.quick_stack_range"), 5f);
}
private string Text(string key)
{
return LocalizationManager.Instance?.GetLocalizedText(key);
}
public ConfigEntry<bool> RegisterBool(string section, string key, string description, bool defaultValue)
{
ConfigEntry<bool> val = _configFile.Bind<bool>(section, key, defaultValue, description);
_boolConfigs[key] = val;
return val;
}
public ConfigEntry<string> RegisterString(string section, string key, string description, string defaultValue)
{
ConfigEntry<string> val = _configFile.Bind<string>(section, key, defaultValue, description);
_stringConfigs[key] = val;
return val;
}
public ConfigEntry<int> RegisterInt(string section, string key, string description, int defaultValue)
{
ConfigEntry<int> val = _configFile.Bind<int>(section, key, defaultValue, description);
_intConfigs[key] = val;
return val;
}
public ConfigEntry<float> RegisterFloat(string section, string key, string description, float defaultValue)
{
ConfigEntry<float> val = _configFile.Bind<float>(section, key, defaultValue, description);
_floatConfigs[key] = val;
return val;
}
public bool IsPatchEnabled(string key)
{
if (_boolConfigs.TryGetValue(key, out var value))
{
return value.Value;
}
return false;
}
public float GetFloat(string key, float defaultValue = 0f)
{
if (_floatConfigs.TryGetValue(key, out var value))
{
return value.Value;
}
return defaultValue;
}
public int GetInt(string key, int defaultValue = 0)
{
if (_intConfigs.TryGetValue(key, out var value))
{
return value.Value;
}
return defaultValue;
}
public string GetString(string key, string defaultValue = "")
{
if (_stringConfigs.TryGetValue(key, out var value))
{
return value.Value;
}
return defaultValue;
}
}
}