Иконка ресурса

FREE Backpacks : 3.15.5 3.15.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 // #define DEBUG_DROP_ON_DEATH
// #define DEBUG_POOLING
// #define DEBUG_BACKPACK_LIFECYCLE
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Facepunch;
using Network;
using Newtonsoft.Json.Converters;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Rust;
using UnityEngine;
using UnityEngine.UI;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
    [Info("Backpacks", "WhiteThunder", "3.15.5")]
    [Description("Allows players to have a Backpack which provides them extra inventory space.")]
    internal class Backpacks : CovalencePlugin {
#region Fields
        private static int _maxCapacityPerPage = 48;
        private const int MinRows = 1;
        private const int MaxRows = 8;
        private const int MinContainerCapacity = 1;
        private const int MaxContainerCapacity = 48;
        private const int SlotsPerRow = 6;
        private const float StandardLootDelay = 0.1f;
        private const Item.Flag SearchableItemFlag = (Item.Flag)(1 << 24);
        private const Item.Flag UnsearchableItemFlag = (Item.Flag)(1 << 25);
        private const ItemDefinition.Flag SearchableItemDefinitionFlag = (ItemDefinition.Flag)(1 << 24);
        private const string UsagePermission = "backpacks.use";
        private const string SizePermission = "backpacks.size";
        private const string GUIPermission = "backpacks.gui";
        private const string FetchPermission = "backpacks.fetch";
        private const string GatherPermission = "backpacks.gather";
        private const string RetrievePermission = "backpacks.retrieve";
        private const string AdminPermission = "backpacks.admin";
        private const string AdminProtectedPermission = "backpacks.admin.protected";
        private const string CapacityProfilePermission = "backpacks.size.profile";
        private const string KeepOnDeathPermission = "backpacks.keepondeath";
        private const string NoFoodSpoilingPermission = "backpacks.nofoodspoiling";
        private const string LegacyKeepOnWipePermission = "backpacks.keeponwipe";
        private const string LegacyNoBlacklistPermission = "backpacks.noblacklist";
        private const string CoffinPrefab = "assets/prefabs/misc/halloween/coffin/coffinstorage.prefab";
        private const string DroppedBackpackPrefab = "assets/prefabs/misc/item drop/item_drop_backpack.prefab";
        private const string ResizableLootPanelName = "generic_resizable";
        private const int SaddleBagItemId = 1400460850;
        private readonly CapacityManager _capacityManager;
        private readonly BackpackManager _backpackManager;
        private readonly SubscriberManager _subscriberManager = new();
        private ProtectionProperties _immortalProtection;
        private Effect _reusableEffect = new();
        private string _cachedButtonUi;
        private readonly ApiInstance _api;
        private Configuration _config;
        private PreferencesData _preferencesData;
        private CapacityData _capacityData;
        private readonly HashSet<ulong> _uiViewers = new();
        private Coroutine _saveRoutine;
        [PluginReference]
        private readonly Plugin Arena, BackpackButton, EventManager, ItemRetriever;
        public Backpacks() {
            _backpackManager = new BackpackManager(this);
            _capacityManager = new CapacityManager(this, _backpackManager);
            _api = new ApiInstance(this);
        }
#endregion
#region Hooks
        private void Init() {
            permission.RegisterPermission(UsagePermission, this);
            permission.RegisterPermission(GUIPermission, this);
            permission.RegisterPermission(FetchPermission, this);
            permission.RegisterPermission(GatherPermission, this);
            permission.RegisterPermission(RetrievePermission, this);
            permission.RegisterPermission(AdminPermission, this);
            permission.RegisterPermission(AdminProtectedPermission, this);
            permission.RegisterPermission(KeepOnDeathPermission, this);
            permission.RegisterPermission(NoFoodSpoilingPermission, this);
            _config.Init(this);
            _maxCapacityPerPage = Mathf.Clamp(_config.BackpackSize.MaxCapacityPerPage, MinContainerCapacity, MaxContainerCapacity);
            PoolUtils.ResizePools();
            _preferencesData = PreferencesData.Load();
            _capacityData = CapacityData.Exists() ? CapacityData.Load() : new CapacityData();
            _capacityManager.Init(_config, _capacityData);
            Unsubscribe(nameof(OnPlayerSleep));
            Unsubscribe(nameof(OnPlayerSleepEnded));
            if (_config.GUI.Enabled) {
                AddCovalenceCommand("backpackgui", nameof(ToggleBackpackGUICommand));
            }
            else {
                Unsubscribe(nameof(OnPlayerConnected));
                Unsubscribe(nameof(OnNpcConversationStart));
                Unsubscribe(nameof(OnNpcConversationEnded));
            }
        }
        private void OnServerInitialized() {
            _immortalProtection = ScriptableObject.CreateInstance<ProtectionProperties>();
            _immortalProtection.name = "BackpacksProtection";
            _immortalProtection.Add(1);
            CheckBackpackButtonPlugin();
            RegisterAsItemSupplier();
            if (_config.GUI.Enabled) {
                Subscribe(nameof(OnPlayerSleep));
                Subscribe(nameof(OnPlayerSleepEnded));
                Subscribe(nameof(OnPlayerConnected));
                Subscribe(nameof(OnNpcConversationStart));
                Subscribe(nameof(OnNpcConversationEnded));
                foreach (var player in BasePlayer.activePlayerList) {
                    MaybeCreateButtonUi(player);
                }
            }
        }
        private void Unload() {
            UnityEngine.Object.Destroy(_immortalProtection);
            RestartSaveRoutine(async : false, keepInUseBackpacks : false);
            BackpackNetworkController.ResetNetworkGroupId();
            foreach (var player in BasePlayer.activePlayerList) {
                DestroyButtonUi(player);
            }
            PoolUtils.ResizePools(empty : true);
        }
        private void OnNewSave(string filename) {
            if (_config.BackpackSize.DynamicSize is {
                Enabled : true, CapacityResetOptions.Enabled : true
            }
            ) {
                _capacityData.Clear();
                if (_capacityData.SaveIfChanged()) {
                    LogWarning("Dynamic size data has been reset.");
                }
            }
            if (_config.ClearOnWipe.Enabled) {
                _backpackManager.ClearCache();
                IEnumerable<string> backpackFileNameList;
                try {
                    backpackFileNameList = Interface.Oxide.DataFileSystem.GetFiles(Name).Select(fn => fn.Split(Path.DirectorySeparatorChar).Last().Replace(".json", string.Empty));
                }
                catch (DirectoryNotFoundException) {
                    // No backpacks to clear.return;
                }
                var retainedDueToContents = 0;
                var retainedDueToPreferences = 0;
                var deletedBackpackFiles = 0;
                foreach (var backpackFileName in backpackFileNameList) {
                    if (!ulong.TryParse(backpackFileName, out var userId)) continue;
                    var backpack = _backpackManager.GetBackpackIfExists(userId);
                    if (backpack == null) continue;
                    backpack.EraseContents(_config.ClearOnWipe.GetForPlayer(backpackFileName));
                    // Only delete the backpack data file if it's empty and has no saved preferences.if (backpack.HasItems || backpack.HasPreferences)
                    {
                        backpack.SaveIfChanged();
                        if (backpack.HasItems) {
                            retainedDueToContents++;
                        }
                        else if (backpack.HasPreferences) {
                            retainedDueToPreferences++;
                        }
                    }
                    else {
                        _backpackManager.DeleteBackpackFile(userId);
                        deletedBackpackFiles++;
                    }
                }
                _backpackManager.ClearCache();
                var logMessage = "New save created.Backpacks were wiped according to the config and player permissions.";
                if (deletedBackpackFiles > 0) {
                    logMessage += $"\n- {deletedBackpackFiles} file(s) were deleted because those backpacks are now empty.";
                }
                if (retainedDueToContents > 0) {
                    logMessage += $"\n- {retainedDueToContents} file(s) were retained because those backpacks were not empty after applying the player's wipe ruleset.";
                }
                if (retainedDueToPreferences > 0) {
                    logMessage += $"\n- {retainedDueToPreferences} file(s) were retained even though those backpacks are empty because they contain player gather/retrieve preferences.";
                }
                LogWarning(logMessage);
            }
        }
        private void OnServerSave() {
            RestartSaveRoutine(async : true, keepInUseBackpacks : true);
        }
        private void OnPluginLoaded(Plugin plugin) {
            switch (plugin.Name) {
                case nameof(BackpackButton) : CheckBackpackButtonPlugin();
                break;
                case nameof(ItemRetriever) : RegisterAsItemSupplier();
                break;
            }
        }
        private void OnPluginUnloaded(Plugin plugin) {
            _subscriberManager.RemoveSubscriber(plugin);
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            _capacityManager.ForgetCachedCapacity(player.userID);
            _backpackManager.GetBackpackIfCached(player.userID)?.NetworkController?.Unsubscribe(player);
        }
        // Handle player death by normal means.private void OnEntityDeath(BasePlayer player, HitInfo info) =>
        OnEntityKill(player);
        // Handle player death while sleeping in a safe zone.private void OnEntityKill(BasePlayer player)
        {
            if (player.IsNpc) return;
            DestroyButtonUi(player);
            if (!_backpackManager.HasBackpack(player.userID)) return;
            if (permission.UserHasPermission(player.UserIDString, KeepOnDeathPermission)) {
#if DEBUG_DROP_ON_DEATH
                LogWarning($"[DEBUG_DROP_ON_DEATH] [Player {player.UserIDString}] Backpack not dropped because the player has the {KeepOnDeathPermission} permission.");
#endif
                return;
            }
            if (_config.EraseOnDeath) {
                _backpackManager.TryEraseForPlayer(player.userID);
            }
            else if (_config.DropOnDeath) {
                _backpackManager.Drop(player.userID, player.transform.position);
            }
            else {
#if DEBUG_DROP_ON_DEATH
                LogWarning($"[DEBUG_DROP_ON_DEATH] [Player {player.UserIDString}] Backpack not dropped because \"Drop on Death (true/false)\" is set to false in the config.");
#endif
            }
        }
        private void OnGroupPermissionGranted(string groupName, string perm) {
            if (!perm.StartsWith("backpacks")) return;
            if (perm.StartsWith(SizePermission) || perm.StartsWith(UsagePermission) || perm.StartsWith(CapacityProfilePermission)) {
                _backpackManager.HandleCapacityPermissionChangedForGroup(groupName);
            }
            else if (perm.StartsWith(RestrictionRuleset.FullPermissionPrefix) || perm.Equals(LegacyNoBlacklistPermission)) {
                _backpackManager.HandleRestrictionPermissionChangedForGroup(groupName);
            }
            else if (perm.Equals(GatherPermission)) {
                _backpackManager.HandleGatherPermissionChangedForGroup(groupName);
            }
            else if (perm.Equals(RetrievePermission)) {
                _backpackManager.HandleRetrievePermissionChangedForGroup(groupName);
            }
            else if (perm.Equals(NoFoodSpoilingPermission)) {
                _backpackManager.HandleFoodSpoilingPermissionChangedForGroup(groupName);
            }
            else if (_config.GUI.Enabled && perm.Equals(GUIPermission)) {
                var groupName2 = groupName;
                foreach (var player in BasePlayer.activePlayerList.Where(p => permission.UserHasGroup(p.UserIDString, groupName2))) {
                    CreateOrDestroyButtonUi(player);
                }
            }
        }
        private void OnGroupPermissionRevoked(string groupName, string perm) {
            OnGroupPermissionGranted(groupName, perm);
        }
        private void OnUserPermissionGranted(string userId, string perm) {
            if (!perm.StartsWith("backpacks")) return;
            if (perm.StartsWith(SizePermission) || perm.StartsWith(UsagePermission) || perm.StartsWith(CapacityProfilePermission)) {
                _backpackManager.HandleCapacityPermissionChangedForUser(userId);
            }
            else if (perm.StartsWith(RestrictionRuleset.FullPermissionPrefix) || perm.Equals(LegacyNoBlacklistPermission)) {
                _backpackManager.HandleRestrictionPermissionChangedForUser(userId);
            }
            else if (perm.Equals(GatherPermission)) {
                _backpackManager.HandleGatherPermissionChangedForUser(userId);
            }
            else if (perm.Equals(RetrievePermission)) {
                _backpackManager.HandleRetrievePermissionChangedForUser(userId);
            }
            else if (perm.Equals(NoFoodSpoilingPermission)) {
                _backpackManager.HandleFoodSpoilingPermissionChangedForUser(userId);
            }
            else if (_config.GUI.Enabled && perm.Equals(GUIPermission)) {
                var player = BasePlayer.Find(userId);
                if (player != null) {
                    CreateOrDestroyButtonUi(player);
                }
            }
        }
        private void OnUserPermissionRevoked(string userId, string perm) {
            OnUserPermissionGranted(userId, perm);
        }
        private void OnUserGroupAdded(string userId, string groupName) {
            _backpackManager.HandleGroupChangeForUser(userId);
        }
        private void OnUserGroupRemoved(string userId, string groupName) {
            _backpackManager.HandleGroupChangeForUser(userId);
        }
        // Only subscribed while the GUI button is enabled.private void OnPlayerConnected(BasePlayer player) => MaybeCreateButtonUi(player);
        private void OnPlayerRespawned(BasePlayer player) {
            // People reported NRE on Carbon framework, meaning the player is somehow null, unknown root cause.if (player == null)
            return;
            MaybeCreateButtonUi(player);
            _backpackManager.GetBackpackIfCached(player.userID)?.PauseGatherMode(1f);
        }
        // Only subscribed while the GUI button is enabled.private void OnPlayerSleepEnded(BasePlayer player) => OnPlayerRespawned(player);
        // Only subscribed while the GUI button is enabled.private void OnPlayerSleep(BasePlayer player) => DestroyButtonUi(player);
        // Only subscribed while the GUI button is enabled.private void OnNpcConversationStart(NPCTalking npcTalking, BasePlayer player, ConversationData conversationData)
        {
            // This delay can be removed in the future if an OnNpcConversationStarted hook is created.NextTick(() =>
            {
                // Verify the conversation started, since another plugin may have blocked it.if (!npcTalking.conversingPlayers.Contains(player))
                return;
                DestroyButtonUi(player);
            }
            );
        }
        // Only subscribed while the GUI button is enabled.private void OnNpcConversationEnded(NPCTalking npcTalking, BasePlayer player) => MaybeCreateButtonUi(player);
        private void OnNetworkSubscriptionsUpdate(Networkable networkable, List<Network.Visibility.Group> groupsToAdd, List<Network.Visibility.Group> groupsToRemove) {
            if (groupsToRemove == null) return;
            for (var i = groupsToRemove.Count - 1; i >= 0; i--) {
                var group = groupsToRemove[i];
                if (BackpackNetworkController.IsBackpackNetworkGroup(group)) {
                    // Prevent automatically unsubscribing from backpack network groups.// This allows the subscriptions to persist while players move around.groupsToRemove.Remove(group);
                }
            }
        }
#endregion
#region API
        private class ApiInstance {
            public readonly Dictionary<string, object> ApiWrapper;
            private readonly Backpacks _plugin;
            private BackpackManager _backpackManager => _plugin._backpackManager;
            public ApiInstance(Backpacks plugin) {
                _plugin = plugin;
                ApiWrapper = new Dictionary<string, object> {
                    [nameof(AddSubscriber)]
                    = new Action<Plugin, Dictionary<string, object>>(AddSubscriber), [nameof(RemoveSubscriber)] = new Action<Plugin>(RemoveSubscriber), [nameof(GetExistingBackpacks)] = new Func<Dictionary<ulong, ItemContainer>>(GetExistingBackpacks), [nameof(EraseBackpack)] = new Action<ulong>(EraseBackpack), [nameof(DropBackpack)] = new Func<BasePlayer, List<DroppedItemContainer>, DroppedItemContainer>(DropBackpack), [nameof(GetBackpackOwnerId)] = new Func<ItemContainer, ulong>(GetBackpackOwnerId), [nameof(IsBackpackLoaded)] = new Func<BasePlayer, bool>(IsBackpackLoaded), [nameof(IsDynamicCapacityEnabled)] = new Func<bool>(IsDynamicCapacityEnabled), [nameof(GetBackpackCapacity)] = new Func<BasePlayer, int>(GetBackpackCapacity), [nameof(GetBackpackCapacityById)] = new Func<ulong, string, int>(GetBackpackCapacityById), [nameof(GetBackpackInitialCapacity)] = new Func<BasePlayer, int>(GetBackpackInitialCapacity), [nameof(GetBackpackMaxCapacity)] = new Func<BasePlayer, int>(GetBackpackMaxCapacity), [nameof(AddBackpackCapacity)] = new Func<BasePlayer, int, int>(AddBackpackCapacity), [nameof(SetBackpackCapacity)] = new Func<BasePlayer, int, int>(SetBackpackCapacity), [nameof(IsBackpackGathering)] = new Func<BasePlayer, bool>(IsBackpackGathering), [nameof(IsBackpackRetrieving)] = new Func<BasePlayer, bool>(IsBackpackRetrieving), [nameof(GetBackpackContainer)] = new Func<ulong, ItemContainer>(GetBackpackContainer), [nameof(GetBackpackItemAmount)] = new Func<ulong, int, ulong, int>(GetBackpackItemAmount), [nameof(TryOpenBackpack)] = new Func<BasePlayer, ulong, bool>(TryOpenBackpack), [nameof(TryOpenBackpackContainer)] = new Func<BasePlayer, ulong, ItemContainer, bool>(TryOpenBackpackContainer), [nameof(TryOpenBackpackPage)] = new Func<BasePlayer, ulong, int, bool>(TryOpenBackpackPage), [nameof(SumBackpackItems)] = new Func<ulong, Dictionary<string, object>, int>(SumBackpackItems), [nameof(CountBackpackItems)] = new Func<ulong, Dictionary<string, object>, int>(CountBackpackItems), [nameof(TakeBackpackItems)] = new Func<ulong, Dictionary<string, object>, int, List<Item>, int>(TakeBackpackItems), [nameof(MutateBackpackItems)] = new Func<ulong, Dictionary<string, object>, Dictionary<string, object>, int>(MutateBackpackItems), [nameof(TryDepositBackpackItem)] = new Func<ulong, Item, bool>(TryDepositBackpackItem), [nameof(WriteBackpackContentsFromJson)] = new Action<ulong, string>(WriteBackpackContentsFromJson), [nameof(ReadBackpackContentsAsJson)] = new Func<ulong, string>(ReadBackpackContentsAsJson),
                }
                ;
            }
            public void AddSubscriber(Plugin plugin, Dictionary<string, object> spec) {
                if (plugin == null) throw new ArgumentNullException(nameof(plugin));
                if (spec == null) throw new ArgumentNullException(nameof(spec));
                _plugin._subscriberManager.AddSubscriber(plugin, spec);
            }
            public void RemoveSubscriber(Plugin plugin) {
                if (plugin == null) throw new ArgumentNullException(nameof(plugin));
                _plugin._subscriberManager.RemoveSubscriber(plugin);
            }
            public Dictionary<ulong, ItemContainer> GetExistingBackpacks() {
                return _backpackManager.GetAllCachedContainers();
            }
            public void EraseBackpack(ulong userId) {
                _backpackManager.TryEraseForPlayer(userId);
            }
            public DroppedItemContainer DropBackpack(BasePlayer player, List<DroppedItemContainer> collect) {
                var backpack = _backpackManager.GetBackpackIfExists(player.userID);
                if (backpack == null) return null;
                return _backpackManager.Drop(player.userID, player.transform.position, collect);
            }
            public ulong GetBackpackOwnerId(ItemContainer container) {
                return _backpackManager.GetCachedBackpackForContainer(container)?.OwnerId ?? 0;
            }
            public bool IsBackpackLoaded(BasePlayer player) {
                return _backpackManager.GetBackpackIfCached(player.userID) != null;
            }
            public bool IsDynamicCapacityEnabled() {
                return _plugin._config.BackpackSize.DynamicSize.Enabled;
            }
            public int GetBackpackCapacity(BasePlayer player) {
                return _plugin._capacityManager.GetCapacity(player.userID, player.UserIDString);
            }
            public int GetBackpackCapacityById(ulong playerID, string playerIDString) {
                return _plugin._capacityManager.GetCapacity(playerID, playerIDString);
            }
            public int GetBackpackInitialCapacity(BasePlayer player) {
                return _plugin._capacityManager.GetInitialCapacity(player.userID, player.UserIDString);
            }
            public int GetBackpackMaxCapacity(BasePlayer player) {
                return _plugin._capacityManager.GetMaxCapacity(player.userID, player.UserIDString);
            }
            public int AddBackpackCapacity(BasePlayer player, int amount) {
                return _plugin._capacityManager.AddCapacity(player, amount);
            }
            public int SetBackpackCapacity(BasePlayer player, int capacity) {
                return _plugin._capacityManager.SetCapacity(player, capacity);
            }
            public bool IsBackpackGathering(BasePlayer player) {
                return _backpackManager.GetBackpackIfCached(player.userID)?.IsGathering ?? false;
            }
            public bool IsBackpackRetrieving(BasePlayer player) {
                return _backpackManager.GetBackpackIfCached(player.userID)?.IsRetrieving ?? false;
            }
            public ItemContainer GetBackpackContainer(ulong ownerId) {
                return _backpackManager.GetBackpackIfExists(ownerId)?.GetContainer(ensureContainer : true);
            }
            public int GetBackpackItemAmount(ulong ownerId, int itemId, ulong skinId) {
                var itemQuery = new ItemQuery {
                    ItemId = itemId, SkinId = skinId
                }
                ;
                return _backpackManager.GetBackpackIfExists(ownerId)?.SumItems(ref itemQuery) ?? 0;
            }
            public bool TryOpenBackpack(BasePlayer player, ulong ownerId) {
                return _backpackManager.TryOpenBackpack(player, ownerId);
            }
            public bool TryOpenBackpackContainer(BasePlayer player, ulong ownerId, ItemContainer container) {
                return _backpackManager.TryOpenBackpackContainer(player, ownerId, container);
            }
            public bool TryOpenBackpackPage(BasePlayer player, ulong ownerId, int page) {
                return _backpackManager.TryOpenBackpackPage(player, ownerId, page);
            }
            public int SumBackpackItems(ulong ownerId, Dictionary<string, object> dict) {
                var itemQuery = ItemQuery.Parse(dict);
                return _backpackManager.GetBackpackIfExists(ownerId)?.SumItems(ref itemQuery) ?? 0;
            }
            public int CountBackpackItems(ulong ownerId, Dictionary<string, object> dict) {
                var backpack = _backpackManager.GetBackpackIfExists(ownerId);
                if (backpack == null) return 0;
                if (dict == null) return backpack.ItemCount;
                var itemQuery = ItemQuery.Parse(dict);
                return backpack.CountItems(ref itemQuery);
            }
            public int TakeBackpackItems(ulong ownerId, Dictionary<string, object> dict, int amount, List<Item> collect) {
                var itemQuery = ItemQuery.Parse(dict);
                return _backpackManager.GetBackpackIfExists(ownerId)?.TakeItems(ref itemQuery, amount, collect) ?? 0;
            }
            public int MutateBackpackItems(ulong ownerId, Dictionary<string, object> itemQueryDict, Dictionary<string, object> mutationRequestDict) {
                var itemQuery = ItemQuery.Parse(itemQueryDict);
                var mutationRequest = MutationRequest.Parse(mutationRequestDict);
                return _backpackManager.GetBackpackIfExists(ownerId)?.MutateItems(ref itemQuery, ref mutationRequest) ?? 0;
            }
            public bool TryDepositBackpackItem(ulong ownerId, Item item) {
                return _backpackManager.GetBackpack(ownerId).TryDepositItem(item);
            }
            public void WriteBackpackContentsFromJson(ulong ownerId, string json) {
                _backpackManager.GetBackpack(ownerId).WriteContentsFromJson(json);
            }
            public string ReadBackpackContentsAsJson(ulong ownerId) {
                return _backpackManager.GetBackpackIfExists(ownerId)?.SerializeContentsAsJson();
            }
        }
        [HookMethod(nameof(API_GetApi))]
        public Dictionary<string, object> API_GetApi() {
            return _api.ApiWrapper;
        }
        [HookMethod(nameof(API_AddSubscriber))]
        public void API_AddSubscriber(Plugin plugin, Dictionary<string, object> spec) {
            _api.AddSubscriber(plugin, spec);
        }
        [HookMethod(nameof(API_RemoveSubscriber))]
        public void API_RemoveSubscriber(Plugin plugin) {
            _api.RemoveSubscriber(plugin);
        }
        // Deprecated, only returns container for first page.Use higher level APIs instead.[HookMethod(nameof(API_GetExistingBackpacks))]
        public Dictionary<ulong, ItemContainer> API_GetExistingBackpacks() {
            return _api.GetExistingBackpacks();
        }
        [HookMethod(nameof(API_EraseBackpack))]
        public void API_EraseBackpack(ulong userId) {
            _api.EraseBackpack(userId);
        }
        [HookMethod(nameof(API_EraseBackpack))]
        public void API_EraseBackpack(EncryptedValue<ulong> userId) {
            _api.EraseBackpack(userId);
        }
        [HookMethod(nameof(API_DropBackpack))]
        public DroppedItemContainer API_DropBackpack(BasePlayer player, List<DroppedItemContainer> collect = null) {
            return _api.DropBackpack(player, collect);
        }
        [HookMethod(nameof(API_GetBackpackOwnerId))]
        public object API_GetBackpackOwnerId(ItemContainer container) {
            return ObjectCache.Get(_api.GetBackpackOwnerId(container));
        }
        [HookMethod(nameof(API_IsBackpackLoaded))]
        public object API_IsBackpackLoaded(BasePlayer player) {
            return ObjectCache.Get(_api.IsBackpackLoaded(player));
        }
        [HookMethod(nameof(API_IsDynamicCapacityEnabled))]
        public object API_IsDynamicCapacityEnabled(BasePlayer player) {
            return ObjectCache.Get(_api.IsDynamicCapacityEnabled());
        }
        [HookMethod(nameof(API_GetBackpackCapacity))]
        public object API_GetBackpackCapacity(BasePlayer player) {
            return ObjectCache.Get(_api.GetBackpackCapacity(player));
        }
        [HookMethod(nameof(API_GetBackpackCapacityById))]
        public object API_GetBackpackCapacityById(ulong playerID, string playerIDString) {
            return ObjectCache.Get(_api.GetBackpackCapacityById(playerID, playerIDString));
        }
        [HookMethod(nameof(API_GetBackpackCapacityById))]
        public object API_GetBackpackCapacityById(EncryptedValue<ulong> playerID, string playerIDString) {
            return ObjectCache.Get(_api.GetBackpackCapacityById(playerID, playerIDString));
        }
        [HookMethod(nameof(API_GetBackpackInitialCapacity))]
        public object API_GetBackpackInitialCapacity(BasePlayer player) {
            return ObjectCache.Get(_api.GetBackpackInitialCapacity(player));
        }
        [HookMethod(nameof(API_GetBackpackMaxCapacity))]
        public object API_GetBackpackMaxCapacity(BasePlayer player) {
            return ObjectCache.Get(_api.GetBackpackMaxCapacity(player));
        }
        [HookMethod(nameof(API_AddBackpackCapacity))]
        public object API_AddBackpackCapacity(BasePlayer player, int amount) {
            return ObjectCache.Get(_api.AddBackpackCapacity(player, amount));
        }
        [HookMethod(nameof(API_SetBackpackCapacity))]
        public object API_SetBackpackCapacity(BasePlayer player, int capacity) {
            return ObjectCache.Get(_api.SetBackpackCapacity(player, capacity));
        }
        [HookMethod(nameof(API_IsBackpackGathering))]
        public object API_IsBackpackGathering(BasePlayer player) {
            return ObjectCache.Get(_api.IsBackpackGathering(player));
        }
        [HookMethod(nameof(API_IsBackpackRetrieving))]
        public object API_IsBackpackRetrieving(BasePlayer player) {
            return ObjectCache.Get(_api.IsBackpackRetrieving(player));
        }
        // Deprecated, only returns container for first page.Use higher level APIs instead.[HookMethod(nameof(API_GetBackpackContainer))]
        public ItemContainer API_GetBackpackContainer(ulong ownerId) {
            return _api.GetBackpackContainer(ownerId);
        }
        [HookMethod(nameof(API_GetBackpackContainer))]
        public ItemContainer API_GetBackpackContainer(EncryptedValue<ulong> ownerId) {
            return _api.GetBackpackContainer(ownerId);
        }
        [HookMethod(nameof(API_GetBackpackItemAmount))]
        public int API_GetBackpackItemAmount(ulong ownerId, int itemId, ulong skinId = 0) {
            return _api.GetBackpackItemAmount(ownerId, itemId, skinId);
        }
        [HookMethod(nameof(API_GetBackpackItemAmount))]
        public int API_GetBackpackItemAmount(EncryptedValue<ulong> ownerId, int itemId, ulong skinId = 0) {
            return _api.GetBackpackItemAmount(ownerId, itemId, skinId);
        }
        [HookMethod(nameof(API_TryOpenBackpack))]
        public object API_TryOpenBackpack(BasePlayer player, ulong ownerId = 0) {
            return ObjectCache.Get(_api.TryOpenBackpack(player, ownerId));
        }
        [HookMethod(nameof(API_TryOpenBackpack))]
        public object API_TryOpenBackpack(BasePlayer player, EncryptedValue<ulong> ownerId = default) {
            return ObjectCache.Get(_api.TryOpenBackpack(player, ownerId));
        }
        [HookMethod(nameof(API_TryOpenBackpackContainer))]
        public object API_TryOpenBackpackContainer(BasePlayer player, ulong ownerId, ItemContainer container) {
            return ObjectCache.Get(_api.TryOpenBackpackContainer(player, ownerId, container));
        }
        [HookMethod(nameof(API_TryOpenBackpackContainer))]
        public object API_TryOpenBackpackContainer(BasePlayer player, EncryptedValue<ulong> ownerId, ItemContainer container) {
            return ObjectCache.Get(_api.TryOpenBackpackContainer(player, ownerId, container));
        }
        [HookMethod(nameof(API_TryOpenBackpackPage))]
        public object API_TryOpenBackpackPage(BasePlayer player, ulong ownerId = 0, int page = 0) {
            return ObjectCache.Get(_api.TryOpenBackpackPage(player, ownerId, page));
        }
        [HookMethod(nameof(API_TryOpenBackpackPage))]
        public object API_TryOpenBackpackPage(BasePlayer player, EncryptedValue<ulong> ownerId = default, int page = 0) {
            return ObjectCache.Get(_api.TryOpenBackpackPage(player, ownerId, page));
        }
        [HookMethod(nameof(API_SumBackpackItems))]
        public object API_SumBackpackItems(ulong ownerId, Dictionary<string, object> dict) {
            return ObjectCache.Get(_api.SumBackpackItems(ownerId, dict));
        }
        [HookMethod(nameof(API_SumBackpackItems))]
        public object API_SumBackpackItems(EncryptedValue<ulong> ownerId, Dictionary<string, object> dict) {
            return ObjectCache.Get(_api.SumBackpackItems(ownerId, dict));
        }
        [HookMethod(nameof(API_CountBackpackItems))]
        public object API_CountBackpackItems(ulong ownerId, Dictionary<string, object> dict) {
            return ObjectCache.Get(_api.CountBackpackItems(ownerId, dict));
        }
        [HookMethod(nameof(API_CountBackpackItems))]
        public object API_CountBackpackItems(EncryptedValue<ulong> ownerId, Dictionary<string, object> dict) {
            return ObjectCache.Get(_api.CountBackpackItems(ownerId, dict));
        }
        [HookMethod(nameof(API_TakeBackpackItems))]
        public object API_TakeBackpackItems(ulong ownerId, Dictionary<string, object> dict, int amount, List<Item> collect) {
            return ObjectCache.Get(_api.TakeBackpackItems(ownerId, dict, amount, collect));
        }
        [HookMethod(nameof(API_TakeBackpackItems))]
        public object API_TakeBackpackItems(EncryptedValue<ulong> ownerId, Dictionary<string, object> dict, int amount, List<Item> collect) {
            return ObjectCache.Get(_api.TakeBackpackItems(ownerId, dict, amount, collect));
        }
        [HookMethod(nameof(API_MutateBackpackItems))]
        public object API_MutateBackpackItems(ulong ownerId, Dictionary<string, object> itemQueryDict, Dictionary<string, object> mutationRequestDict) {
            return ObjectCache.Get(_api.MutateBackpackItems(ownerId, itemQueryDict, mutationRequestDict));
        }
        [HookMethod(nameof(API_MutateBackpackItems))]
        public object API_MutateBackpackItems(EncryptedValue<ulong> ownerId, Dictionary<string, object> itemQueryDict, Dictionary<string, object> mutationRequestDict) {
            return ObjectCache.Get(_api.MutateBackpackItems(ownerId, itemQueryDict, mutationRequestDict));
        }
        [HookMethod(nameof(API_TryDepositBackpackItem))]
        public object API_TryDepositBackpackItem(ulong ownerId, Item item) {
            return ObjectCache.Get(_api.TryDepositBackpackItem(ownerId, item));
        }
        [HookMethod(nameof(API_TryDepositBackpackItem))]
        public object API_TryDepositBackpackItem(EncryptedValue<ulong> ownerId, Item item) {
            return ObjectCache.Get(_api.TryDepositBackpackItem(ownerId, item));
        }
        [HookMethod(nameof(API_WriteBackpackContentsFromJson))]
        public void API_WriteBackpackContentsFromJson(ulong ownerId, string json) {
            _api.WriteBackpackContentsFromJson(ownerId, json);
        }
        [HookMethod(nameof(API_WriteBackpackContentsFromJson))]
        public void API_WriteBackpackContentsFromJson(EncryptedValue<ulong> ownerId, string json) {
            _api.WriteBackpackContentsFromJson(ownerId, json);
        }
        [HookMethod(nameof(API_ReadBackpackContentsAsJson))]
        public object API_ReadBackpackContentsAsJson(ulong ownerId) {
            return _api.ReadBackpackContentsAsJson(ownerId);
        }
        [HookMethod(nameof(API_ReadBackpackContentsAsJson))]
        public object API_ReadBackpackContentsAsJson(EncryptedValue<ulong> ownerId) {
            return _api.ReadBackpackContentsAsJson(ownerId);
        }
#endregion
#region Exposed Hooks
        private static class ExposedHooks {
            public static object CanOpenBackpack(BasePlayer looter, ulong ownerId) {
                return Interface.CallHook("CanOpenBackpack", looter, ObjectCache.Get(ownerId));
            }
            public static void OnBackpackClosed(BasePlayer looter, ulong ownerId, ItemContainer container) {
                Interface.CallHook("OnBackpackClosed", looter, ObjectCache.Get(ownerId), container);
            }
            public static void OnBackpackOpened(BasePlayer looter, ulong ownerId, ItemContainer container) {
                Interface.CallHook("OnBackpackOpened", looter, ObjectCache.Get(ownerId), container);
            }
            public static object CanDropBackpack(ulong ownerId, Vector3 position) {
                return Interface.CallHook("CanDropBackpack", ObjectCache.Get(ownerId), position);
            }
            public static void OnBackpackDropped(ulong ownerId, List<DroppedItemContainer> droppedBackpackList) {
                Interface.CallHook("OnBackpackDropped", ownerId, droppedBackpackList);
            }
            public static object CanEraseBackpack(ulong ownerId) {
                return Interface.CallHook("CanEraseBackpack", ObjectCache.Get(ownerId));
            }
            public static object CanBackpackAcceptItem(ulong ownerId, ItemContainer container, Item item) {
                return Interface.CallHook("CanBackpackAcceptItem", ObjectCache.Get(ownerId), container, item);
            }
        }
#endregion
#region Commands
        [Command("backpack", "backpack.open")]
        private void BackpackOpenCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, UsagePermission)) return;
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()), ParsePageArg(args.FirstOrDefault()), wrapAround : false );
        }
        [Command("backpack.next")]
        private void BackpackNextCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, UsagePermission)) return;
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()) );
        }
        [Command("backpack.previous", "backpack.prev")]
        private void BackpackPreviousCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, UsagePermission)) return;
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()), forward : false );
        }
        [Command("backpack.fetch")]
        private void BackpackFetchCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, FetchPermission)) return;
            if (args.Length < 2) {
                ReplyToPlayer(player, LangEntry.BackpackFetchSyntax);
                return;
            }
            if (!VerifyCanOpenBackpack(basePlayer, basePlayer.userID)) return;
            if (!VerifyValidItem(player, args[0], out var itemDefinition)) return;
            if (!int.TryParse(args[1], out var desiredAmount) || desiredAmount < 1) {
                ReplyToPlayer(player, LangEntry.InvalidItemAmount);
                return;
            }
            var itemLocalizedName = itemDefinition.displayName.translated;
            var backpack = _backpackManager.GetBackpack(basePlayer.userID);
            var itemQuery = new ItemQuery {
                ItemDefinition = itemDefinition
            }
            ;
            var quantityInBackpack = backpack.SumItems(ref itemQuery);
            if (quantityInBackpack == 0) {
                ReplyToPlayer(player, LangEntry.ItemNotInBackpack, itemLocalizedName);
                return;
            }
            if (desiredAmount > quantityInBackpack) {
                desiredAmount = quantityInBackpack;
            }
            var amountTransferred = backpack.FetchItems(basePlayer, ref itemQuery, desiredAmount);
            if (amountTransferred <= 0) {
                ReplyToPlayer(player, LangEntry.FetchFailed, itemLocalizedName);
                return;
            }
            ReplyToPlayer(player, LangEntry.ItemsFetched, amountTransferred, itemLocalizedName);
        }
        [Command("backpack.erase")]
        private void EraseBackpackCommand(IPlayer player, string cmd, string[] args) {
            if (!player.IsServer) return;
            if (args.Length < 1 || !ulong.TryParse(args[0], out var userId)) {
                player.Reply($"Syntax: {cmd} <id>");
                return;
            }
            if (!_backpackManager.TryEraseForPlayer(userId)) {
                LogWarning($"Player {userId.ToString()} has no backpack to erase.");
                return;
            }
            LogWarning($"Erased backpack for player {userId.ToString()}.");
        }
        [Command("viewbackpack")]
        private void ViewBackpackCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, AdminPermission)) return;
            if (args.Length < 1) {
                ReplyToPlayer(player, LangEntry.ViewBackpackSyntax);
                return;
            }
            if (!VerifyTargetPlayer(player, args[0], out var targetPlayerId, out var targetPlayerIdString)) return;
            if (permission.UserHasPermission(targetPlayerIdString, AdminProtectedPermission)) {
                ReplyToPlayer(player, LangEntry.ViewBackpackProtected);
                return;
            }
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()), ParsePageArg(args.ElementAtOrDefault(1)), desiredOwnerId : targetPlayerId );
        }
        // Alias for older versions of Player Administration (which should ideally not be calling this method directly).private void ViewBackpack(BasePlayer player, string cmd, string[] args) =>
        ViewBackpackCommand(player.IPlayer, cmd, args);
        [Command("backpack.addsize")]
        private void AddBackpackCapacityCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyHasPermission(player, AdminPermission)) return;
            if (args.Length < 2 || !int.TryParse(args[1], out var amount)) {
                ReplyToPlayer(player, LangEntry.BackpackCapacitySyntax, cmd);
                return;
            }
            if (!VerifyTargetPlayer(player, args[0], out var targetPlayerId, out var targetPlayerIdString) || !VerifyDynamicCapacityEnabled(player)) return;
            var newCapacity = _capacityManager.AddCapacity(targetPlayerId, targetPlayerIdString, amount);
            ReplyToPlayer(player, LangEntry.ChangeCapacitySuccess, targetPlayerId, newCapacity);
        }
        [Command("backpack.setsize")]
        private void SetBackpackCapacityCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyHasPermission(player, AdminPermission)) return;
            if (args.Length < 2 || !int.TryParse(args[1], out var amount)) {
                ReplyToPlayer(player, LangEntry.BackpackCapacitySyntax, cmd);
                return;
            }
            if (!VerifyTargetPlayer(player, args[0], out var targetPlayerId, out var targetPlayerIdString) || !VerifyDynamicCapacityEnabled(player)) return;
            var newCapacity = _capacityManager.SetCapacity(targetPlayerId, targetPlayerIdString, amount);
            ReplyToPlayer(player, LangEntry.ChangeCapacitySuccess, targetPlayerId, newCapacity);
        }
        private void ToggleBackpackGUICommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyPlayer(player, out var basePlayer) || !VerifyHasPermission(player, GUIPermission)) return;
            var enabledNow = _preferencesData.ToggleGuiButtonPreference(basePlayer.userID, _config.GUI.EnabledByDefault);
            if (enabledNow) {
                MaybeCreateButtonUi(basePlayer);
            }
            else {
                DestroyButtonUi(basePlayer);
            }
            ReplyToPlayer(player, LangEntry.ToggledBackpackGUI);
        }
        [Command("backpack.setgathermode")]
        private void SetGatherCommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyCanInteract(player, out var basePlayer) || !VerifyHasPermission(player, UsagePermission) || !VerifyHasPermission(player, GatherPermission)) return;
            var backpack = _backpackManager.GetBackpack(basePlayer.userID);
            if (!backpack.CanGather) return;
            if (args.Length < 1 || !TryParseGatherMode(basePlayer, args[0], out var gatherMode)) {
                ReplyToPlayer(player, LangEntry.SetGatherSyntax, cmd, GetGatherModeDisplayOptions(basePlayer));
                return;
            }
            var oneBasedPageIndex = 1;
            if (args.Length >= 2 && !IsKeyBindArg(args[1]) && !int.TryParse(args[1], out oneBasedPageIndex)) {
                ReplyToPlayer(player, LangEntry.SetGatherSyntax, cmd, GetGatherModeDisplayOptions(basePlayer));
                return;
            }
            if (oneBasedPageIndex < 1 || oneBasedPageIndex > backpack.PageCount) {
                ReplyToPlayer(player, LangEntry.PageOutOfRange, backpack.PageCount);
                return;
            }
            var pageIndex = oneBasedPageIndex - 1;
            if (backpack.GetGatherModeForPage(pageIndex) == gatherMode) return;
            backpack.SetGatherModeForPage(basePlayer, pageIndex, gatherMode);
            ReplyToPlayer(player, LangEntry.SetGatherModeSuccess, oneBasedPageIndex, GetGatherModeDisplayString(basePlayer, gatherMode));
        }
        [Command("backpack.ui.togglegather")]
        private void ToggleGatherUICommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyPlayer(player, out var basePlayer)) return;
            var lootingContainer = basePlayer.inventory.loot.containers.FirstOrDefault();
            if (lootingContainer == null) return;
            if (!_backpackManager.IsBackpack(lootingContainer, out var backpack, out var pageIndex) || backpack.OwnerId != basePlayer.userID || !backpack.CanGather) return;
            backpack.ToggleGatherMode(basePlayer, pageIndex);
        }
        [Command("backpack.ui.toggleretrieve")]
        private void ToggleRetrieveUICommand(IPlayer player, string cmd, string[] args) {
            if (!VerifyPlayer(player, out var basePlayer)) return;
            var lootingContainer = basePlayer.inventory.loot.containers.FirstOrDefault();
            if (lootingContainer == null) return;
            if (!_backpackManager.IsBackpack(lootingContainer, out var backpack, out var pageIndex) || pageIndex > 31 || backpack.OwnerId != basePlayer.userID || !backpack.CanRetrieve) return;
            backpack.ToggleRetrieve(basePlayer, pageIndex);
        }
        // Note: The outputs of this command are not localized as they are intended only for
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху