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

FREE Backpacks : 3.11.6 3.11.6

Нет прав для скачивания
C#:
// #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 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.11.6")]
    [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 MinCapacity = 1;
        private const int MaxCapacity = 48;
        private const int SlotsPerRow = 6;
        private const int ReclaimEntryMaxSize = 40;
        private const float StandardLootDelay = 0.1f;
        private const Item.Flag UnsearchableItemFlag = (Item.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 KeepOnDeathPermission = "backpacks.keepondeath";
        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 BackpackCapacityManager _backpackCapacityManager;
        private readonly BackpackManager _backpackManager;
        private readonly SubscriberManager _subscriberManager = new SubscriberManager();
        private ProtectionProperties _immortalProtection;
        private Effect _reusableEffect = new Effect();
        private string _cachedButtonUi;
        private readonly ApiInstance _api;
        private Configuration _config;
        private StoredData _storedData;
        private readonly HashSet<ulong> _uiViewers = new HashSet<ulong>();
        private Coroutine _saveRoutine;
        [PluginReference]
        private readonly Plugin Arena, BagOfHolding, BackpackButton, EventManager, ItemRetriever;
        public Backpacks() {
            _backpackCapacityManager = new BackpackCapacityManager(this);
            _backpackManager = new BackpackManager(this);
            _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(KeepOnDeathPermission, this);
            _config.Init(this);
            _maxCapacityPerPage = Mathf.Clamp(_config.BackpackSize.MaxCapacityPerPage, MinCapacity, MaxCapacity);
            _backpackCapacityManager.Init(_config);
            PoolUtils.ResizePools();
            _storedData = StoredData.Load();
            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.ClearOnWipe.Enabled) return;
            _backpackManager.ClearCache();
            IEnumerable<string> fileNames;
            try {
                fileNames = Interface.Oxide.DataFileSystem.GetFiles(Name).Select(fn => {
                    return fn.Split(Path.DirectorySeparatorChar).Last().Replace(".json", string.Empty);
                }
                );
            }
            catch (DirectoryNotFoundException) {
                // No backpacks to clear.return;
            }
            var skippedBackpackCount = 0;
            foreach (var fileName in fileNames) {
                ulong userId;
                if (!ulong.TryParse(fileName, out userId)) continue;
                var ruleset = _config.ClearOnWipe.GetForPlayer(fileName);
                if (ruleset == null || ruleset.DisallowsAll) {
                    _backpackManager.ClearBackpackFile(userId);
                    continue;
                }
                if (ruleset.AllowsAll) continue;
                var backpack = _backpackManager.GetBackpackIfExists(userId);
                if (backpack == null) continue;
                backpack.EraseContents(ruleset);
                backpack.SaveIfChanged();
            }
            _backpackManager.ClearCache();
            LogWarning($"New save created.Backpacks were wiped according to the config and player permissions.");
        }
        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;
                case nameof(BagOfHolding) : {
                    NextTick(() => {
                        if (!plugin.IsLoaded) return;
                        _backpackManager.DiscoverBags(plugin);
                    }
                    );
                    break;
                }
            }
        }
        private void OnPluginUnloaded(Plugin plugin) {
            _subscriberManager.RemoveSubscriber(plugin);
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            _backpackCapacityManager.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.HasBackpackFile(player.userID) || permission.UserHasPermission(player.UserIDString, KeepOnDeathPermission)) return;
            if (_config.EraseOnDeath) {
                _backpackManager.TryEraseForPlayer(player.userID);
            }
            else if (_config.DropOnDeath) {
                _backpackManager.Drop(player.userID, player.transform.position);
            }
        }
        private void OnGroupPermissionGranted(string groupName, string perm) {
            if (!perm.StartsWith("backpacks")) return;
            if (perm.StartsWith(SizePermission) || perm.StartsWith(UsagePermission)) {
                _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 (_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)) {
                _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 (_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) {
            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(Network.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(GetBackpackCapacity)] = new Func<BasePlayer, int>(GetBackpackCapacity), [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(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 int GetBackpackCapacity(BasePlayer player) {
                return _plugin._backpackCapacityManager.GetCapacity(player.userID, player.UserIDString);
            }
            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 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);
        }
        [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_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_GetBackpackCapacity))]
        public object API_GetBackpackCapacity(BasePlayer player) {
            return ObjectCache.Get(_api.GetBackpackCapacity(player));
        }
        [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));
        }
        [HookMethod(nameof(API_GetBackpackContainer))]
        public ItemContainer API_GetBackpackContainer(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_TryOpenBackpack))]
        public object API_TryOpenBackpack(BasePlayer player, ulong ownerId = 0) {
            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_TryOpenBackpackPage))]
        public object API_TryOpenBackpackPage(BasePlayer player, ulong ownerId = 0, 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_CountBackpackItems))]
        public object API_CountBackpackItems(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_TryDepositBackpackItem))]
        public object API_TryDepositBackpackItem(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_ReadBackpackContentsAsJson))]
        public object API_ReadBackpackContentsAsJson(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 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) {
            BasePlayer basePlayer;
            if (!VerifyCanInteract(player, out 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) {
            BasePlayer basePlayer;
            if (!VerifyCanInteract(player, out basePlayer) || !VerifyHasPermission(player, UsagePermission)) return;
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()) );
        }
        [Command("backpack.previous", "backpack.prev")]
        private void BackpackPreviousCommand(IPlayer player, string cmd, string[] args) {
            BasePlayer basePlayer;
            if (!VerifyCanInteract(player, out basePlayer) || !VerifyHasPermission(player, UsagePermission)) return;
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()), forward : false );
        }
        [Command("backpack.fetch")]
        private void BackpackFetchCommand(IPlayer player, string cmd, string[] args) {
            BasePlayer basePlayer;
            if (!VerifyCanInteract(player, out basePlayer) || !VerifyHasPermission(player, FetchPermission)) return;
            if (args.Length < 2) {
                player.Reply(GetMessage(player, "Backpack Fetch Syntax"));
                return;
            }
            if (!VerifyCanOpenBackpack(basePlayer, basePlayer.userID)) return;
            ItemDefinition itemDefinition;
            if (!VerifyValidItem(player, args[0], out itemDefinition)) return;
            int desiredAmount;
            if (!int.TryParse(args[1], out desiredAmount) || desiredAmount < 1) {
                player.Reply(GetMessage(player, "Invalid Item Amount"));
                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) {
                player.Reply(string.Format(GetMessage(player, "Item Not In Backpack"), itemLocalizedName));
                return;
            }
            if (desiredAmount > quantityInBackpack) {
                desiredAmount = quantityInBackpack;
            }
            var amountTransferred = backpack.FetchItems(basePlayer, ref itemQuery, desiredAmount);
            if (amountTransferred <= 0) {
                player.Reply(string.Format(GetMessage(player, "Fetch Failed"), itemLocalizedName));
                return;
            }
            player.Reply(string.Format(GetMessage(player, "Items Fetched"), amountTransferred.ToString(), itemLocalizedName));
        }
        [Command("backpack.erase")]
        private void EraseBackpackCommand(IPlayer player, string cmd, string[] args) {
            if (!player.IsServer) return;
            ulong userId;
            if (args.Length < 1 || !ulong.TryParse(args[0], out 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) {
            BasePlayer basePlayer;
            if (!VerifyCanInteract(player, out basePlayer) || !VerifyHasPermission(player, AdminPermission)) return;
            if (args.Length < 1) {
                player.Reply(GetMessage(player, "View Backpack Syntax"));
                return;
            }
            string failureMessage;
            var targetPlayer = FindPlayer(player, args[0], out failureMessage);
            if (targetPlayer == null) {
                player.Reply(failureMessage);
                return;
            }
            var targetBasePlayer = targetPlayer.Object as BasePlayer;
            var desiredOwnerId = targetBasePlayer?.userID ?? ulong.Parse(targetPlayer.Id);
            OpenBackpack(basePlayer, IsKeyBindArg(args.LastOrDefault()), ParsePageArg(args.ElementAtOrDefault(1)), desiredOwnerId : desiredOwnerId );
        }
        // 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);
        private void ToggleBackpackGUICommand(IPlayer player, string cmd, string[] args) {
            BasePlayer basePlayer;
            if (!VerifyPlayer(player, out basePlayer) || !VerifyHasPermission(player, GUIPermission)) return;
            var enabledNow = _storedData.ToggleGuiButtonPreference(basePlayer.userID, _config.GUI.EnabledByDefault);
            if (enabledNow) {
                MaybeCreateButtonUi(basePlayer);
            }
            else {
                DestroyButtonUi(basePlayer);
            }
            player.Reply(GetMessage(player, "Toggled Backpack GUI"));
        }
        [Command("backpack.togglegather")]
        private void ToggleGatherCommand(IPlayer player, string cmd, string[] args) {
            BasePlayer basePlayer;
            if (!VerifyPlayer(player, out basePlayer)) return;
            var lootingContainer = basePlayer.inventory.loot.containers.FirstOrDefault();
            if (lootingContainer == null) return;
            Backpack backpack;
            int pageIndex;
            if (!_backpackManager.IsBackpack(lootingContainer, out backpack, out pageIndex) || backpack.OwnerId != basePlayer.userID || !backpack.CanGather) return;
            backpack.ToggleGatherMode(basePlayer, pageIndex);
        }
        [Command("backpack.toggleretrieve")]
        private void ToggleRetrieveCommand(IPlayer player, string cmd, string[] args) {
            BasePlayer basePlayer;
            if (!VerifyPlayer(player, out basePlayer)) return;
            var lootingContainer = basePlayer.inventory.loot.containers.FirstOrDefault();
            if (lootingContainer == null) return;
            Backpack backpack;
            int pageIndex;
            if (!_backpackManager.IsBackpack(lootingContainer, out backpack, out pageIndex) || pageIndex > 31 || backpack.OwnerId != basePlayer.userID || !backpack.CanRetrieve) return;
            backpack.ToggleRetrieve(basePlayer, pageIndex);
        }
#endregion
#region Helper Methods
        public static void LogDebug(string message) => Interface.Oxide.LogDebug($"[Backpacks] {message}");
        public static void LogInfo(string message) => Interface.Oxide.LogInfo($"[Backpacks] {message}");
        public static void LogWarning(string message) => Interface.Oxide.LogWarning($"[Backpacks] {message}");
        public static void LogError(string message) => Interface.Oxide.LogError($"[Backpacks] {message}");
        private static T[] ParseEnumList<T>(string[] list, string errorFormat) where T : struct {
            var valueList = new List<T>(list?.Length ?? 0);
            if (list != null) {
                foreach (var itemName in list) {
                    T result;
                    if (Enum.TryParse(itemName, ignoreCase : true, result : out result)) {
                        valueList.Add(result);
                    }
                    else {
                        LogError(string.Format(errorFormat, itemName));
                    }
                }
            }
            return valueList.ToArray();
        }
        private static bool IsKeyBindArg(string arg) {
            return arg == "True";
        }
        private static int ParsePageArg(string arg) {
            if (arg == null) return -1;
            int pageIndex;
            return int.TryParse(arg, out pageIndex) ? Math.Max(0, pageIndex - 1) : -1;
        }
        private static string DetermineLootPanelName(ItemContainer container) {
            return (container.entityOwner as StorageContainer)?.panelName ?? (container.entityOwner as ContainerIOEntity)?.lootPanelName ?? (container.entityOwner as LootableCorpse)?.lootPanelName ?? (container.entityOwner as DroppedItemContainer)?.lootPanelName ?? (container.entityOwner as BaseRidableAnimal)?.lootPanelName ?? ResizableLootPanelName;
        }
        private static void ClosePlayerInventory(BasePlayer player) {
            player.ClientRPCPlayer(null, player, "OnRespawnInformation");
        }
        private static float CalculateOpenDelay(ItemContainer currentContainer, int nextContainerCapacity, bool isKeyBind = false) {
            if (currentContainer != null) {
                // Can instantly switch to a smaller container.if (nextContainerCapacity <= currentContainer.capacity)
                return 0;
                // Can instantly switch to a generic resizable loot panel from a different loot panel.if (DetermineLootPanelName(currentContainer) != ResizableLootPanelName)
                return 0;
                // Need a short delay so the generic_resizable loot panel can be redrawn properly.return StandardLootDelay;
            }
            // Can open instantly since not looting and chat is assumed to be closed.if (isKeyBind)
            return 0;
            // Not opening via key bind, so the chat window may be open.// Must delay in case the chat is still closing or else the loot panel may close instantly.return StandardLootDelay;
        }
        private static void StartLooting(BasePlayer player, ItemContainer container, StorageContainer entitySource) {
            if (player.CanInteract() && Interface.CallHook("CanLootEntity", player, entitySource) == null && player.inventory.loot.StartLootingEntity(entitySource, doPositionChecks : false)) {
                player.inventory.loot.AddContainer(container);
                player.inventory.loot.SendImmediate();
                player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", entitySource.panelName);
            }
        }
        private static ItemContainer CreateItemContainer(int capacity, StorageContainer entityOwner) {
            var container = new ItemContainer();
            container.ServerInitialize(null, capacity);
            container.GiveUID();
            container.entityOwner = entityOwner;
            return container;
        }
        private static ItemContainer GetRootContainer(Item item) {
            var container = item.parent;
            if (container == null) return null;
            while (container.parent?.parent != null && container.parent != item) {
                container = container.parent.parent;
            }
            return container;
        }
        private void SendEffect(BasePlayer player, string effectPrefab) {
            if (string.IsNullOrWhiteSpace(effectPrefab)) return;
            _reusableEffect.Init(Effect.Type.Generic, player, 0, Vector3.zero, Vector3.forward);
            _reusableEffect.pooledString = effectPrefab;
            EffectNetwork.Send(_reusableEffect, player.net.connection);
        }
        private void CheckBackpackButtonPlugin() {
            if (BackpackButton == null || _config.UsingDefaults || !_config.GUI.Enabled) return;
            foreach (var player in BasePlayer.activePlayerList) {
                DestroyButtonUi(player);
            }
            _config.GUI.Enabled = false;
            SaveConfig();
            LogWarning($"Disabled GUI button in the config because the {nameof(BackpackButton)} plugin was detected.");
        }
        private void RegisterAsItemSupplier() {
            ItemRetriever?.Call("API_AddSupplier", this, new Dictionary<string, object> {
                ["FindPlayerItems"]
                = new Action<BasePlayer, Dictionary<string, object>, List<Item>>((player, rawItemQuery, collect) => {
                    var backpack = _backpackManager.GetBackpackIfCached(player.userID);
                    if (backpack == null || !backpack.CanRetrieve || !backpack.CanAccess) return;
                    var itemQuery = ItemQuery.Parse(rawItemQuery);
                    backpack.FindItems(ref itemQuery, collect, forItemRetriever : true);
                }
                ), ["FindPlayerAmmo"] = new Action<BasePlayer, AmmoTypes, List<Item>>((player, ammoType, collect) => {
                    var backpack = _backpackManager.GetBackpackIfCached(player.userID);
                    if (backpack == null || !backpack.CanRetrieve || !backpack.CanAccess) return;
                    backpack.FindAmmo(ammoType, collect, forItemRetriever : true);
                }
                ), ["SumPlayerItems"] = new Func<BasePlayer, Dictionary<string, object>, int>((player, rawItemQuery) => {
                    var backpack = _backpackManager.GetBackpackIfCached(player.userID);
                    if (backpack == null || !backpack.CanRetrieve || !backpack.CanAccess) return 0;
                    var itemQuery = ItemQuery.Parse(rawItemQuery);
                    return backpack.SumItems(ref itemQuery, forItemRetriever : true);
                }
                ), ["TakePlayerItems"] = new Func<BasePlayer, Dictionary<string, object>, int, List<Item>, int>((player, rawItemQuery, amount, collect) => {
                    var backpack = _backpackManager.GetBackpackIfCached(player.userID);
                    if (backpack == null || !backpack.CanRetrieve || !backpack.CanAccess) return 0;
                    var itemQuery = ItemQuery.Parse(rawItemQuery);
                    return backpack.TakeItems(ref itemQuery, amount, collect, forItemRetriever : true);
                }
                ), ["SerializeForNetwork"] = new Action<BasePlayer, List<ProtoBuf.Item>>((player, saveList) => {
                    var backpack = _backpackManager.GetBackpackIfCached(player.userID);
                    // Don't check CanAccess here to save on performance.This may result in minor issues like the
                    // player attempting an action they can't perform.if (backpack == null || !backpack.CanRetrieve)
                    return;
                    backpack.SerializeForNetwork(saveList, forItemRetriever : true);
                }
                ),
            }
            );
        }
        private IEnumerator SaveRoutine(bool async, bool keepInUseBackpacks) {
            if (_storedData.SaveIfChanged() && async) yield return null;
            yield return _backpackManager.SaveAllAndKill(async, keepInUseBackpacks);
        }
        private void RestartSaveRoutine(bool async, bool keepInUseBackpacks) {
            if (_saveRoutine != null) {
                ServerMgr.Instance.StopCoroutine(_saveRoutine);
            }
            ServerMgr.Instance?.StartCoroutine(SaveRoutine(async, keepInUseBackpacks));
        }
        private void OpenBackpackMaybeDelayed(BasePlayer looter, ItemContainer currentContainer, Backpack backpack, int pageIndex, bool isKeyBind) {
            var pageCapacity = backpack.GetAllowedPageCapacityForLooter(looter.userID, pageIndex);
            var delaySeconds = CalculateOpenDelay(currentContainer, pageCapacity, isKeyBind);
            if (delaySeconds > 0) {
                if (currentContainer != null) {
                    looter.EndLooting();
                    looter.inventory.loot.SendImmediate();
                }
                var ownerId2 = backpack.OwnerId;
                var looter2 = looter;
                var pageIndex2 = pageIndex;
                timer.Once(delaySeconds, () => _backpackManager.TryOpenBackpackPage(looter2, ownerId2, pageIndex2));
                return;
            }
            _backpackManager.TryOpenBackpackPage(looter, backpack.OwnerId, pageIndex);
        }
        private void OpenBackpack(BasePlayer looter, bool isKeyBind, int desiredPageIndex = -1, bool forward = true, bool wrapAround = true, ulong desiredOwnerId = 0) {
            var playerLoot = looter.inventory.loot;
            var lootingContainer = playerLoot.containers.FirstOrDefault();
            if (lootingContainer != null) {
                Backpack currentBackpack;
                int currentPageIndex;
                if (_backpackManager.IsBackpack(lootingContainer, out currentBackpack, out currentPageIndex) && (currentBackpack.OwnerId == desiredOwnerId || desiredOwnerId == 0)) {
                    var nextPageIndex = currentBackpack.DetermineNextPageIndexForLooter(looter.userID, currentPageIndex, desiredPageIndex, forward, wrapAround, requireContents : false);
                    if (nextPageIndex == currentPageIndex) {
                        if (!wrapAround) {
                            // Close the backpack.looter.EndLooting();
                            ClosePlayerInventory(looter);
                        }
                        return;
                    }
                    var nextPageCapacity = currentBackpack.GetAllowedPageCapacityForLooter(looter.userID, nextPageIndex);
                    if (nextPageCapacity > lootingContainer.capacity) {
                        playerLoot.Clear();
                        playerLoot.SendImmediate();
                        {
                            var backpack2 = currentBackpack;
                            var looter2 = looter;
                            var pageIndex2 = desiredPageIndex;
                            timer.Once(StandardLootDelay, () => backpack2.TryOpen(looter2, pageIndex2));
                        }
                        return;
                    }
                    currentBackpack.SwitchToPage(looter, nextPageIndex);
                    return;
                }
                var parent = lootingContainer.parent?.parent;
                if (parent != null && _backpackManager.IsBackpack(parent, out currentBackpack, out currentPageIndex) && (currentBackpack.OwnerId == desiredOwnerId || desiredOwnerId == 0)) {
                    // Player is looting a child container of the target backpack, so open the current page.OpenBackpackMaybeDelayed(looter, lootingContainer, currentBackpack, currentPageIndex, isKeyBind);
                    return;
                }
            }
            // At this point, player is not looting, looting a different backpack, or looting a different container.if (desiredOwnerId == 0)
            {
                desiredOwnerId = looter.userID;
            }
            var backpack = _backpackManager.GetBackpack(desiredOwnerId);
            desiredPageIndex = backpack.DetermineInitialPageForLooter(looter.userID, desiredPageIndex, forward);
            OpenBackpackMaybeDelayed(looter, lootingContainer, backpack, desiredPageIndex, isKeyBind);
        }
        private bool ShouldDisplayGuiButton(BasePlayer player) {
            return _storedData.GetGuiButtonPreference(player.userID) ?? _config.GUI.EnabledByDefault;
        }
        private IPlayer FindPlayer(IPlayer requester, string nameOrID, out string failureMessage) {
            failureMessage = string.Empty;
            ulong userId;
            if (nameOrID.StartsWith("7656119") && nameOrID.Length == 17 && ulong.TryParse(nameOrID, out userId)) {
                IPlayer player = covalence.Players.All.FirstOrDefault(p => p.Id == nameOrID);
                if (player == null) {
                    failureMessage = string.Format(GetMessage(requester, "User ID not Found"), nameOrID);
                }
                return player;
            }
            var foundPlayers = new List<IPlayer>();
            foreach (var player in covalence.Players.All) {
                if (player.Name.Equals(nameOrID, StringComparison.InvariantCultureIgnoreCase)) return player;
                if (player.Name.ToLower().Contains(nameOrID.ToLower())) {
                    foundPlayers.Add(player);
                }
            }
            switch (foundPlayers.Count) {
     
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху