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

FREE SyncPipes : 0.9.32 0.9.32

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Rust;
using System;
using Oxide.Core;
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System.Collections;
using System.Diagnostics;
using Oxide.Game.Rust.Cui;
using Random = System.Random;
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
using System.Runtime.CompilerServices;
namespace Oxide.Plugins {
    [Info("Sync Pipes", "Joe 90", "0.9.32")]
    [Description("Allows players to transfer items between containers.All pipes from a container are used synchronously to enable advanced sorting and splitting.")]
    partial class SyncPipes : RustPlugin {
#region Initialization
        /// <summary>
        /// The instance of syncPipes on the server to allow child classes to access it
        /// </summary>
        private static SyncPipes Instance;
        private const string ToolCupboardPrefab = "cupboard.tool.deployed";
#pragma warning disable CS0649
        // Reference to the Furnace Splitter plugin https://umod.org/plugins/furnace-splitter
        // Disabled as 01/09/2022 rust update causes items to vanish
        Plugin FurnaceSplitter = null;
        // Refernce to the Quick Smelt plugin https://umod.org/plugins/quick-smelt
        [PluginReference]
        Plugin QuickSmelt;
#pragma warning restore CS0649
        /// <summary>
        /// Hook: Initializes syncPipes when the server starts to load it
        /// </summary>
        void Init() {
            Instance = this;
            _config = SyncPipesConfig.Load();
            Commands.InitializeChat();
            permission.RegisterPermission($"{Name}.user", this);
            permission.RegisterPermission($"{Name}.admin", this);
            InstanceConfig.RegisterPermissions();
#region static data declarations
            _chatCommands = new Dictionary<Enum, bool> {
                {
                    Oxide.Plugins.SyncPipes.Chat.Commands, true
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CancelPipeCreationFromChat, true
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CancelCopy, true
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CancelRemove, true
                }
                , {
                    Oxide.Plugins.SyncPipes.PipeMenu.HelpLabel.FlowBar, true
                }
                ,
            }
            ;
            _bindingCommands = new Dictionary<Enum, bool> {
                {
                    Oxide.Plugins.SyncPipes.Chat.PlacingBindingHint, true
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CancelPipeCreationFromBind, true
                }
                ,
            }
            ;
            _messageTypes = new Dictionary<Enum, MessageType> {
                {
                    Oxide.Plugins.SyncPipes.Overlay.AlreadyConnected, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.TooFar, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.TooFarTC, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.TooClose, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.NoPrivilegeToCreate, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.MonumentDenied, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CantConnectTwoToolcuboards, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.BlacklistedContainer, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.NoPrivilegeToEdit, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.PipeLimitReached, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.UpgradeLimitReached, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitFirstContainer, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitSecondContainer, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitToName, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitToClearName, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitToGetBuildingId, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.HitToSetBuildingId, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CannotNameContainer, MessageType.Warning
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CopyFromPipe, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.CopyToPipe, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Overlay.RemovePipe, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Pipe.Status.Pending, MessageType.Info
                }
                , {
                    Oxide.Plugins.SyncPipes.Pipe.Status.Success, MessageType.Success
                }
                , {
                    Oxide.Plugins.SyncPipes.Pipe.Status.SourceError, MessageType.Error
                }
                , {
                    Oxide.Plugins.SyncPipes.Pipe.Status.DestinationError, MessageType.Error
                }
                , {
                    Oxide.Plugins.SyncPipes.Pipe.Status.IdGenerationFailed, MessageType.Error
                }
                ,
            }
            ;
            _storageDetails = new Dictionary<Storage, StorageData> {
                {
                    Storage.Default, new StorageData("unknown.container", "https://i.imgur.com/cayN7SQ.png", new Vector3(0f, 0f, 0f), false)
                }
                , {
                    Storage.PumpJackCrudeOutput, new StorageData("crudeoutput", "c/c9/Pump_Jack_icon.png", new Vector3(0f, 0f, -0.5f), true)
                }
                , {
                    Storage.Fireplace, new StorageData("fireplace.deployed", "https://static.wikia.nocookie.net/rust_gamepedia/images/c/c2/Stone_Fireplace.png/revision/latest/scale-to-width-down/{0}", new Vector3(0f, -1.3f, 0f), false)
                }
                , {
                    Storage.ResearchTable, new StorageData("researchtable_deployed", "2/21/Research_Table_icon.png", new Vector3(0.8f, -0.5f, -0.3f), true)
                }
                , {
                    Storage.VendingMachine, new StorageData("vendingmachine.deployed", "5/5c/Vending_Machine_icon.png", new Vector3(0f, -0.5f, 0f), true)
                }
                , {
                    Storage.QuarryFuelInput, new StorageData("fuelstorage", "b/b8/Mining_Quarry_icon.png", new Vector3(-0.5f, 0f, -0.4f), true)
                }
                , {
                    Storage.SmallPlanterBox, new StorageData("planter.small.deployed", "a/a7/Small_Planter_Box_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.JackOLanternHappy, new StorageData("jackolantern.happy", "9/92/Jack_O_Lantern_Happy_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.DropBox, new StorageData("dropbox.deployed", "4/46/Drop_Box_icon.png", new Vector3(0f, 0.4f, 0.3f), true)
                }
                , {
                    Storage.MiningQuarry, new StorageData("mining_quarry", "b/b8/Mining_Quarry_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.SuperStocking, new StorageData("stocking_large_deployed", "6/6a/SUPER_Stocking_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.QuarryHopperOutput, new StorageData("hopperoutput", "b/b8/Mining_Quarry_icon.png", new Vector3(0f, -0.6f, -0.3f), true)
                }
                , {
                    Storage.SmallOilRefinery, new StorageData("refinery_small_deployed", "a/ac/Small_Oil_Refinery_icon.png", new Vector3(-0.3f, -0.2f, -0.1f), true)
                }
                , {
                    Storage.LargePlanterBox, new StorageData("planter.large.deployed", "3/35/Large_Planter_Box_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.ShotgunTrap, new StorageData("guntrap.deployed", "6/6c/Shotgun_Trap_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.LargeFurnace, new StorageData("furnace.large", "e/ee/Large_Furnace_icon.png", new Vector3(0f, -1.5f, 0f), true)
                }
                , {
                    Storage.WoodStorageBox, new StorageData("woodbox_deployed", "f/ff/Wood_Storage_Box_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.PumpJack, new StorageData("mining.pumpjack", "c/c9/Pump_Jack_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.Recycler, new StorageData("recycler_static", "e/ef/Recycler_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.Fridge, new StorageData("fridge.deployed", "8/88/Fridge_icon.png", new Vector3(0f, -0.5f, 0f), true)
                }
                , {
                    Storage.JackOLanternAngry, new StorageData("jackolantern.angry", "9/96/Jack_O_Lantern_Angry_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.SkullFirePit, new StorageData("skull_fire_pit", "3/32/Skull_Fire_Pit_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.Composter, new StorageData("composter", "https://i.imgur.com/qpA7I8P.png", new Vector3(0f, 0f, 0f), false)
                }
                , {
                    Storage.CampFire, new StorageData("campfire", "3/35/Camp_Fire_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.LargeWoodBox, new StorageData("box.wooden.large", "b/b2/Large_Wood_Box_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.Barbeque, new StorageData("bbq.deployed", "f/f8/Barbeque_icon.png", new Vector3(-0.2f, -0.2f, 0f), true)
                }
                , {
                    Storage.ToolCupboard, new StorageData("cupboard.tool.deployed", "5/57/Tool_Cupboard_icon.png", new Vector3(0f, -0.5f, 0f), true)
                }
                , {
                    Storage.SmallStash, new StorageData("small_stash_deployed", "5/53/Small_Stash_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.Mailbox, new StorageData("mailbox.deployed", "1/17/Mail_Box_icon.png", new Vector3(0f, 0f, -0.15f), true)
                }
                , {
                    Storage.Furnace, new StorageData("furnace", "e/e3/Furnace_icon.png", new Vector3(0f, -0.5f, 0f), true)
                }
                , {
                    Storage.SurvivalFishTrap, new StorageData("survivalfishtrap.deployed", "9/9d/Survival_Fish_Trap_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.SmallStocking, new StorageData("stocking_small_deployed", "9/97/Small_Stocking_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.AutoTurret, new StorageData("autoturret_deployed", "f/f9/Auto_Turret_icon.png", new Vector3(0f, -0.58f, 0f), true)
                }
                , {
                    Storage.RepairBench, new StorageData("repairbench_deployed", "3/3b/Repair_Bench_icon.png", new Vector3(0f, 0f, 0f), true)
                }
                , {
                    Storage.FlameTurret, new StorageData("flameturret.deployed", "f/f9/Flame_Turret_icon.png", new Vector3(0f, -0.3f, 0.1f), true)
                }
                , {
                    Storage.PumpJackFuelInput, new StorageData("fuelstorage", "c/c9/Pump_Jack_icon.png", new Vector3(-0.5f, 0.1f, -0.3f), true)
                }
                ,
            }
            ;
#endregion
        }
        /// <summary>
        /// Hook: Cleans up syncPipes when the server unloads it
        /// </summary>
        void Unload() {
            Instance.Puts("SyncPipes is unloading...");
            DataStore.OnePointOne.Save(false);
            Puts("Unloading All Pipes");
            Pipe.Cleanup();
            ContainerManager.Cleanup();
            PlayerHelper.Cleanup();
            ExperimentalUnload();
            Instance.Puts("SyncPipes unloaded");
        }
        partial void ExperimentalUnload();
#endregion
#region Commands
        /// <summary>
        /// Contains all the commands used by syncPipes
        /// Various stubs are included in the main SyncPipes class as this is needed by oxide
        /// </summary>
        static class Commands {
            /// <summary>
            /// Adds all the chat commands to Oxide
            /// </summary>
            public static void InitializeChat() {
                Add("", nameof(CommandArgs));
                Add("help", nameof(CommandHelp));
                Add("copy", nameof(CommandCopy));
                Add("remove", nameof(CommandRemove));
                Add("stats", nameof(CommandStats));
                Add("name", nameof(CommandName));
            }
            /// <summary>
            /// Helper to simplify adding the commands to Oxide./// Adds the standard command prefix characters (from the config) to each command
            /// </summary>
            /// <param name="commandSuffix">The name of the command to be suffixed to the chat command charactes</param>
            /// <param name="callback">The name of the method to be called by this command</param>
            private static void Add(string commandSuffix, string callback) => Instance.AddCovalenceCommand($"{InstanceConfig.CommandPrefix}{commandSuffix}", callback);
            /// <summary>
            /// Default args based command
            /// </summary>
            /// <param name="playerHelper">Player helper for the player calling this command</param>
            /// <param name="args">The arguments given with the command</param>
            public static void Args(PlayerHelper playerHelper, string[] args) {
                if (playerHelper == null) return;
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                switch (args.Length > 0 ? args[0] : null) {
                    case null : case "p" : playerHelper.TogglePlacingPipe(false);
                    break;
                    case "h" : case "help" : case "?" : Help(playerHelper);
                    break;
                    case "c" : case "copy" : Copy(playerHelper);
                    break;
                    case "r" : case "remove" : Remove(playerHelper);
                    break;
                    case "s" : case "stats" : Stats(playerHelper);
                    break;
                    case "n" : var name = string.Join(" ", args.Length > 1 ? args[1] : null);
                    Name(playerHelper, name);
                    break;
                    case "tc" : if (!playerHelper.IsAdmin) return;
                    if(playerHelper.State == PlayerHelper.UserState.ToolCupboard) playerHelper.StopToolCupboardBuildingId();
                    else playerHelper.StartToolCupboardBuildingId();
                    break;
                }
            }
            /// <summary>
            /// Start or stop placing a pipe
            /// </summary>
            /// <param name="playerHelper">The player calling the command</param>
            public static void PlacePipe(PlayerHelper playerHelper) {
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                playerHelper?.TogglePlacingPipe(true);
            }
            /// <summary>
            /// Displays help information in the player chat bar./// </summary>
            /// <param name="playerHelper">Player requesting for help</param>
            public static void Help(PlayerHelper playerHelper) {
                if (playerHelper == null) return;
                playerHelper.PrintToChatWithTitle(@"by Joe 90<size=5>

</size>
Based on <color=#80c5ff>j</color>Pipes by TheGreatJ");
                playerHelper.PrintToChat(Chat.Commands);
                playerHelper.PrintToChat(Chat.PipeMenuInstructions);
                playerHelper.PrintToChat(Chat.UpgradePipes);
            }
            /// <summary>
            /// Start or stop copying a pipe
            /// </summary>
            /// <param name="playerHelper">Player wanting to copy a pipe</param>
            public static void Copy(PlayerHelper playerHelper) => playerHelper?.ToggleCopyingPipe();
            /// <summary>
            /// Switch into or out of remove pipe mode
            /// </summary>
            /// <param name="playerHelper">Player wanting to remove pipes</param>
            public static void Remove(PlayerHelper playerHelper) {
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                playerHelper?.ToggleRemovingPipe();
            }
            /// <summary>
            /// Show player stats about how many pipes they have, their pipe limit (if applicable) and the state of those pipes./// </summary>
            /// <param name="playerHelper">Player requesting their stats</param>
            public static void Stats(PlayerHelper playerHelper) {
                if (playerHelper == null) return;
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                var total = playerHelper.Pipes.Count;
                var running = 0;
                foreach (var pipe in playerHelper.Pipes) {
                    if (pipe.Value.IsEnabled) running++;
                }
                var disabled = total - running;
                playerHelper.PrintToChatWithTitle(playerHelper.PipeLimit != -1 ? Chat.StatsUnlimited : Chat.StatsLimited, total, playerHelper.PipeLimit, running, disabled );
            }
            /// <summary>
            /// Open a pipe menu
            /// </summary>
            /// <param name="arg">Used to get the player and the pipe id</param>
            public static void OpenMenu(ConsoleSystem.Arg arg) {
                var playerHelper = PlayerHelper.Get(arg.Player());
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                GetPipe(arg)?.OpenMenu(playerHelper);
            }
            /// <summary>
            /// Close a pipe menu
            /// </summary>
            /// <param name="arg">Used to get the player and the pipe id</param>
            public static void CloseMenu(ConsoleSystem.Arg arg) => GetPipe(arg)?.CloseMenu(PlayerHelper.Get(arg.Player()));
            /// <summary>
            /// Start or stop naming a pipe or container
            /// </summary>
            /// <param name="playerHelper">Player wanting to name a pipe or container</param>
            /// <param name="name">The name to be applied</param>
            public static void Name(PlayerHelper playerHelper, string name) {
                if (!playerHelper.IsUser) {
                    playerHelper.ShowOverlay(Overlay.NotAuthorisedOnSyncPipes);
                    OverlayText.Hide(playerHelper.Player, 2f);
                    return;
                }
                playerHelper.StartNaming(name);
            }
            /// <summary>
            /// Close the player's menus.This is normally done when something affects the pipes they are looking at./// </summary>
            /// <param name="playerHelper">The player to close the menus for</param>
            public static void ForceCloseMenu(PlayerHelper playerHelper) => playerHelper?.CloseMenu();
            /// <summary>
            /// Adjust the priority of the pipe
            /// </summary>
            /// <param name="arg">Used to get the player, the pipe id (arg.Args[0]) and the amount to change the priority by (arg.Args[1])</param>
            public static void ChangePriority(ConsoleSystem.Arg arg) {
                var pipe = GetPipe(arg);
                var change = GetInt(arg);
                if(change.HasValue) pipe?.ChangePriority(change.Value);
            }
            /// <summary>
            /// Refresh a menu for a player.Normally called when a pipe is changed./// </summary>
            /// <param name="arg">Used to get the player and the pipe id</param>
            public static void RefreshMenu(ConsoleSystem.Arg arg) => GetPipe(arg)?.OpenMenu(PlayerHelper.Get(arg.Player()));
            /// <summary>
            /// Helper to get the pipe from a given command arg
            /// </summary>
            /// <param name="arg">Used the get the pipe id from arg.Args</param>
            /// <param name="index">Override the default index for the pipe id to be in the arg.Args</param>
            /// <returns>The pipe with the given pipe id
            /// If it is missing or not pipe is found then it will return null</returns>
            private static Pipe GetPipe(ConsoleSystem.Arg arg, int index = 0) {
                if (arg.Args.Length < index + 1) return null;
                ulong pipeId;
                return ulong.TryParse(arg.Args[index], out pipeId) ? Pipe.Get(pipeId) : null;
            }
            /// <summary>
            /// Helper to get a boolean value from a given command arg
            /// </summary>
            /// <param name="arg">Used to get the value to be parsed as bool</param>
            /// <param name="index">Set the index in the arg.Arg of the value to be parsed.</param>
            /// <returns>The boolean value of the input./// If it's missing or invalid it will return false</returns>
            private static bool GetBool(ConsoleSystem.Arg arg, int index = 1) {
                if (arg.Args.Length < index + 1) return false;
                return arg.Args[index]?.Equals(true.ToString()) ?? false;
            }
            /// <summary>
            /// Helper to get a nullable integer value from a give command arg
            /// </summary>
            /// <param name="arg">Used to get the value to be parsed as int</param>
            /// <param name="index">Set the index in the arg.Arg of the value to be parsed.</param>
            /// <returns>The integer value of the input
            /// If it's missing or invalid it will return null</returns>
            private static int? GetInt(ConsoleSystem.Arg arg, int index = 1) {
                if (arg.Args.Length < index + 1) return null;
                int parseInt;
                return int.TryParse(arg.Args[index], out parseInt) ? parseInt : default(int?);
            }
            /// <summary>
            /// Turn the pipe on or off
            /// </summary>
            /// <param name="arg">Used to get the pipe id and requested pipe state</param>
            public static void SetPipeState(ConsoleSystem.Arg arg) => GetPipe(arg)?.SetEnabled(GetBool(arg));
            /// <summary>
            /// Turn the pipe's auto start on or off
            /// </summary>
            /// <param name="arg">Used to get the pipe id and requested auto start state</param>
            public static void SetPipeAutoStart(ConsoleSystem.Arg arg) => GetPipe(arg)?.SetAutoStart(GetBool(arg));
            /// <summary>
            /// Reverse the direction of the pipe
            /// </summary>
            /// <param name="arg">Used to get the pipe id</param>
            public static void SwapPipeDirection(ConsoleSystem.Arg arg) => GetPipe(arg)?.SwapDirection();
            /// <summary>
            /// Set the pipe to single or multi stack
            /// </summary>
            /// <param name="arg">Used to get the pipe id and the requested stack mode
            /// true : set to multi-stack mode
            /// false: set to single-stack mode</param>
            public static void SetPipeMultiStack(ConsoleSystem.Arg arg) => GetPipe(arg)?.SetMultiStack(GetBool(arg));
            /// <summary>
            /// Turns on or off the pipe's Furnace Splitter options
            /// </summary>
            /// <param name="arg">Used to get the pipe id and the request Furnace Splitter state</param>
            public static void SetPipeFurnaceStackEnabled(ConsoleSystem.Arg arg) => GetPipe(arg)?.SetFurnaceStackEnabled(GetBool(arg));
            /// <summary>
            /// Sets the number of stacks in the pipe's Furnace Stack Splitter options
            /// </summary>
            /// <param name="arg">Used to get the pipe id and the requested Furnace Splitter stack count</param>
            public static void SetPipeFurnaceStackCount(ConsoleSystem.Arg arg) {
                var stackCount = GetInt(arg);
                if (stackCount == null) return;
                GetPipe(arg)?.SetFurnaceStackCount(stackCount.Value);
            }
            /// <summary>
            /// Opens a loot container that allows players to control the items a pipe filters by
            /// </summary>
            /// <param name="arg">Used to get the pipe id and the player</param>
            public static void OpenPipeFilter(ConsoleSystem.Arg arg) => GetPipe(arg)?.OpenFilter(PlayerHelper.Get(arg.Player()));
            /// <summary>
            /// Shows or hides help labels in pipe menu
            /// </summary>
            /// <param name="arg">Used to get the pipe id and the player</param>
            public static void MenuHelp(ConsoleSystem.Arg arg) => PlayerHelper.Get(arg.Player())?.Menu.ToggleHelp();
            // Flush the permissions of this player helper by forcing it to be recreated
            public static void FlushPlayerPermissions(ConsoleSystem.Arg arg) => PlayerHelper.Remove(arg.Player());
        }
#region Command Stubs
        // These stubs are included as Oxide.Plugin needs all command and chat functions in the main class.void CommandArgs(IPlayer player, string command, string[] args) => Commands.Args(PlayerHelper.Get(player), args);
        void CommandHelp(IPlayer player, string command, string[] args) => Commands.Help(PlayerHelper.Get(player));
        void CommandCopy(IPlayer player, string command, string[] args) => Commands.Copy(PlayerHelper.Get(player));
        void CommandRemove(IPlayer player, string command, string[] args) => Commands.Remove(PlayerHelper.Get(player));
        void CommandStats(IPlayer player, string command, string[] args) => Commands.Stats(PlayerHelper.Get(player));
        void CommandName(IPlayer player, string command, string[] args) => Commands.Name(PlayerHelper.Get(player), string.Join(" ", args));
        [SyncPipesConsoleCommand("create")]
        void StartPipe(ConsoleSystem.Arg arg) => Commands.PlacePipe(PlayerHelper.Get(arg.Player()));
        [SyncPipesConsoleCommand("openmenu")]
        void OpenMenu(ConsoleSystem.Arg arg) => Commands.OpenMenu(arg);
        [SyncPipesConsoleCommand("closemenu")]
        void CloseMenu(ConsoleSystem.Arg arg) => Commands.CloseMenu(arg);
        [SyncPipesConsoleCommand("forceclosemenu")]
        void ForceCloseMenu(ConsoleSystem.Arg arg) => Commands.ForceCloseMenu(PlayerHelper.Get(arg.Player()));
        [SyncPipesConsoleCommand("refreshmenu")]
        void RefreshMenu(ConsoleSystem.Arg arg) => Commands.RefreshMenu(arg);
        [SyncPipesConsoleCommand("changepriority")]
        void ChangePriority(ConsoleSystem.Arg arg) => Commands.ChangePriority(arg);
        [SyncPipesConsoleCommand("setpipestate")]
        void SetPipeState(ConsoleSystem.Arg arg) => Commands.SetPipeState(arg);
        [SyncPipesConsoleCommand("setpipeautostart")]
        void SetPipeAutoStart(ConsoleSystem.Arg arg) => Commands.SetPipeAutoStart(arg);
        [SyncPipesConsoleCommand("swappipedirection")]
        void SwapPipeDirection(ConsoleSystem.Arg arg) => Commands.SwapPipeDirection(arg);
        [SyncPipesConsoleCommand("setpipemultistack")]
        void SetPipeMultiStack(ConsoleSystem.Arg arg) => Commands.SetPipeMultiStack(arg);
        [SyncPipesConsoleCommand("setpipefurnacestackenabled")]
        void SetPipeFurnaceStackEnabled(ConsoleSystem.Arg arg) => Commands.SetPipeFurnaceStackEnabled(arg);
        [SyncPipesConsoleCommand("setpipefurnacestackcount")]
        void SetPipeFurnaceStackCount(ConsoleSystem.Arg arg) => Commands.SetPipeFurnaceStackCount(arg);
        [SyncPipesConsoleCommand("openpipefilter")]
        void OpenPipeFilter(ConsoleSystem.Arg arg) => Commands.OpenPipeFilter(arg);
        [SyncPipesConsoleCommand("menuhelp")]
        void MenuHelp(ConsoleSystem.Arg arg) => Commands.MenuHelp(arg);
        [SyncPipesConsoleCommand("flushperms")]
        void FlushPlayerPermissions(ConsoleSystem.Arg arg) => Commands.FlushPlayerPermissions(arg);
#endregion
        /// <summary>
        /// Helper to add the plugin commandPrefix to the start of each command./// </summary>
        public class SyncPipesConsoleCommandAttribute : ConsoleCommandAttribute {
            public SyncPipesConsoleCommandAttribute(string command) : base($"{nameof(SyncPipes).ToLower()}.{command}") {
            }
        }
#endregion
#region Config
        class SyncPipesConfig {
            private static readonly SyncPipesConfig Default = New();
            public static SyncPipesConfig New() {
                return new SyncPipesConfig {
                    FilterSizes = new List<int> {
                        0, 6, 18, 30, 42
                    }
                    , FlowRates = new List<int> {
                        1, 5, 10, 30, 50
                    }
                    , MaximumPipeDistance = 64f, MinimumPipeDistance = 2f, NoDecay = true, CommandPrefix = "p", HotKey = "p", UpdateRate = 2, AttachXmasLights = false, DestroyWithSalvage = false, PermissionLevels = new Dictionary<string, PermissionLevel> {
                        {
                            "sticks", new PermissionLevel {
                                MaximumGrade = 0, MaximumPipes = 15
                            }
                        }
                        , {
                            "wood", new PermissionLevel {
                                MaximumGrade = 1, MaximumPipes = 25
                            }
                        }
                        , {
                            "stone", new PermissionLevel {
                                MaximumGrade = 2, MaximumPipes = 35
                            }
                        }
                        , {
                            "metal", new PermissionLevel {
                                MaximumGrade = 3, MaximumPipes = 45
                            }
                        }
                        , {
                            "hqm", new PermissionLevel {
                                MaximumGrade = -1, MaximumPipes = -1
                            }
                        }
                    }
                }
                ;
            }
            [JsonProperty("LogLevel")]
            public int LogLevel {
                get;
                set;
            }
            = (int)LogLevels.Error;
            [JsonProperty("filterSizes")]
            public List<int> FilterSizes {
                get;
                set;
            }
            [JsonProperty("flowRates")]
            public List<int> FlowRates {
                get;
                set;
            }
            [JsonProperty("maxPipeDist")]
            public float MaximumPipeDistance {
                get;
                set;
            }
            [JsonProperty("minPipeDist")]
            public float MinimumPipeDistance {
                get;
                set;
            }
            [JsonProperty("noDecay")]
            public bool NoDecay {
                get;
                set;
            }
            [JsonProperty("commandPrefix")]
            public string CommandPrefix {
                get;
                set;
            }
            [JsonProperty("hotKey")]
            public string HotKey {
                get;
                set;
            }
            [JsonProperty("updateRate")]
            public int UpdateRate {
                get;
                set;
            }
            [JsonProperty("xmasLights")]
            public bool AttachXmasLights {
                get;
                set;
            }
            [JsonProperty("permLevels", DefaultValueHandling = DefaultValueHandling.Ignore)]
            public Dictionary<string, PermissionLevel> PermissionLevels {
                get;
                set;
            }
            [JsonProperty("salvageDestroy")]
            public bool DestroyWithSalvage {
                get;
                set;
            }
            = false;
            [JsonProperty("experimental", DefaultValueHandling = DefaultValueHandling.Ignore)]
            public ExperimentalConfig Experimental {
                get;
                set;
            }
            = new ExperimentalConfig();
            [JsonProperty("blacklistTC")]
            public bool BlacklistTC {
                get;
                set;
            }
            = false;
            [JsonProperty("useQuickSmelt")]
            public bool UseQuickSmelt {
                get;
                set;
            }
            = true;
            public class PermissionLevel {
                [JsonProperty("upgradeLimit")]
                public int MaximumGrade {
                    get;
                    set;
                }
                = (int)BuildingGrade.Enum.TopTier;
                [JsonProperty("pipeLimit")]
                public int MaximumPipes {
                    get;
                    set;
                }
                = -1;
                public static readonly PermissionLevel Default = new PermissionLevel() {
                    MaximumGrade = (int)BuildingGrade.Enum.Twigs, MaximumPipes = 0
                }
                ;
            }
            private string[] Validate() {
                var errors = new List<string>();
                var filterSizeError = FilterSizes.Count != 5;
                if (!filterSizeError) {
                    for (var i = 0; i < FilterSizes.Count; i++) {
                        if (FilterSizes[i] < 0 || FilterSizes[i] > 42) {
                            filterSizeError = true;
                            break;
                        }
                    }
                }
                if (filterSizeError) {
                    errors.Add("filterSizes must have 5 values between 0 and 42");
                    FilterSizes = new List<int>(Default.FilterSizes);
                }
                var flowRateError = FlowRates.Count != 5;
                if (!flowRateError) {
                    for (var i = 0; i < FlowRates.Count; i++) {
                        if (FlowRates[i] <= 0) {
                            flowRateError = true;
                            break;
                        }
                    }
                }
                if (flowRateError) {
                    errors.Add("flowRates must have 5 values greater than 0");
                    FlowRates = new List<int>(Default.FlowRates);
                }
                if (UpdateRate <= 0) {
                    errors.Add("updateRage must be greater than 0");
                    UpdateRate = Default.UpdateRate;
                }
                return errors.ToArray();
            }
            public static SyncPipesConfig Load() {
                try {
                    Instance.Puts("Loading Config");
                    var config = Instance.Config.ReadObject<SyncPipesConfig>();
                    if (config?.FilterSizes == null) {
                        Instance.Puts("Setting Defaults");
                        config = New();
                        Instance.Config.WriteObject(config);
                    }
                    var errors = config.Validate();
                    for (var i = 0; i < errors.Length; i++) Instance.PrintWarning(errors[i]);
                    if (errors.Length > 0) {
                        Instance.PrintError("Invalid config file.Using default configs.");
                        return Default;
                    }
                    return config;
                }
                catch (Exception e) {
                    Logger.Runtime.LogException(e, "Config.Load");
                    Instance.PrintError("Invalid config file.Using default configs.");
                    return Default;
                }
            }
            /// <summary>
            /// Register the level permission keys to Oxide
            /// </summary>
            public void RegisterPermissions() {
                if (PermissionLevels != null) {
                    foreach (var permissionKey in PermissionLevels.Keys) {
                        Instance.permission.RegisterPermission($"{Instance.Name}.level.{permissionKey}", Instance);
                    }
                }
            }
        }
        class ExperimentalConfig {
            [JsonProperty("barrelPipe")]
            public bool BarrelPipe {
                get;
                set;
            }
            [JsonProperty("permEntity")]
            public bool PermanentEntities {
                get;
                set;
            }
        }
        /// <summary>
        /// Oxide hook for loading default config settings
        /// </summary>
        protected override void LoadDefaultConfig() {
            Config?.Clear();
            _config = SyncPipesConfig.New();
            Config?.WriteObject(_config);
            SaveConfig();
        }
        /// <summary>
        /// Config for this plugin instance./// </summary>
        static SyncPipesConfig InstanceConfig => Instance._config;
        private SyncPipesConfig _config;
        // the config store for this plugin instance
        /// <summary>
        /// New Hook: Exposes the No Decay config to external plugins
        /// </summary>
        private bool IsNoDecayEnabled => InstanceConfig.NoDecay;
#endregion
#region ContainerHelper
        public const string FUEL_STORAGE_PREFAB = "fuelstorage";
        public const string QUARRY_OUTPUT_PREFAB = "hopperoutput";
        public const string PUMPJACK_OUTPUT_PREFAB = "crudeoutput";
        /// <summary>
        /// This helps find containers and the required information needed to attach pipes
        /// </summary>
        static class ContainerHelper {
            /// <summary>
            /// Lists all the container types that pipes cannot connect to
            /// </summary>
            /// <param name="container">The container to check</param>
            /// <returns>True if the container type is blacklisted</returns>
            public static bool IsBlacklisted(BaseEntity container) {
                return (InstanceConfig.BlacklistTC && container.ShortPrefabName == ToolCupboardPrefab) || container is BaseFuelLightSource || container is Locker || container is ShopFront || container is RepairBench || container is LootContainer;
            }
            /// <summary>
            /// Get a storage container from its Id
            /// </summary>
            /// <param name="id">The Id to search for</param>
            /// <returns>The container that matches the id</returns>
            public static StorageContainer Find(uint id) {
                return Find((BaseEntity)BaseNetworkable.serverEntities.Find(id));
            }
            /// <summary>
            /// Get the container id and the startable type from a container
            /// </summary>
            /// <param name="container">The container to get the data for</param>
            public static ContainerType GetEntityType(BaseEntity container) {
                if (container is BaseOven) return ContainerType.Oven;
                if (container is Recycler) return ContainerType.Recycler;
                if (container is ResourceExtractorFuelStorage) {
                    switch (container.ShortPrefabName) {
                        case FUEL_STORAGE_PREFAB : return ContainerType.FuelStorage;
                        case QUARRY_OUTPUT_PREFAB : return ContainerType.QuarryOutput;
                        case PUMPJACK_OUTPUT_PREFAB : return ContainerType.PumpJackOutput;
                    }
                }
                return ContainerType.General;
            }
            public static bool InMonument(BaseEntity entity) {
                switch (GetEntityType(entity)) {
                    case ContainerType.PumpJackOutput : case ContainerType.QuarryOutput : case ContainerType.FuelStorage : case ContainerType.Recycler : for (int i = 0; i < TerrainMeta.Path.Monuments.Count; i++) {
                        var monument = TerrainMeta.Path.Monuments[i];
                        if (monument.IsInBounds(entity.transform.position)) return false;
                    }
                    break;
                }
                return true;
            }
            private static void LogFindError(uint parentId, BaseEntity entity, ContainerType containerType, List<BaseEntity> children = null) {
                Logger.FindErrors.Log("------------------- {0} -------------------", parentId);
                if (entity == null) Logger.FindErrors.Log("Entity not found");
                else Logger.FindErrors.Log("Entity: {0} ({1})", entity.ShortPrefabName, entity);
                Logger.FindErrors.Log("Type: {0}", containerType);
                for (int i = 0; i < children?.Count; i++) Logger.FindErrors.Log("Child {0}: {1} ({2})", i, children[i].ShortPrefabName, children[i]);
                Logger.FindErrors.Log("");
            }
            public static BaseEntity Find(uint parentId, ContainerType containerType) {
                var entity = (BaseEntity) BaseNetworkable.serverEntities.Find(parentId);
                return Find(entity, containerType);
            }
            public static BaseEntity Find(BaseEntity entity, ContainerType containerType) {
                if (entity == null) {
                    LogFindError(entity.net.ID, null, containerType);
                    return null;
                }
                if (!IsComplexStorage(containerType)) return entity;
                BaseResourceExtractor resourceExtractor = null;
                if (entity?.TryGetComponent<BaseResourceExtractor>(out resourceExtractor) ?? false) {
                    var children = resourceExtractor.children;
                    var prefabName = GetShortPrefabName(containerType);
                    for (var i = 0; i < children?.Count; i++) {
                        if (children[i].ShortPrefabName == prefabName) return children[i] as ResourceExtractorFuelStorage;
                    }
                    LogFindError(entity.net.ID, entity, containerType, children);
                }
                else {
                    LogFindError(entity.net.ID, entity, containerType);
                }
                return null;
            }
            public static StorageContainer Find(BaseEntity parent) {
                StorageContainer container = null;
                return parent?.TryGetComponent<StorageContainer>(out container) ?? false ? container : null;
            }
            public static string GetShortPrefabName(ContainerType containerType) {
                switch (containerType) {
                    case ContainerType.FuelStorage : return FUEL_STORAGE_PREFAB;
                    case ContainerType.QuarryOutput : return QUARRY_OUTPUT_PREFAB;
                    case ContainerType.PumpJackOutput : return PUMPJACK_OUTPUT_PREFAB;
                }
                return "";
            }
            public static bool IsComplexStorage(ContainerType containerType) {
                switch (containerType) {
                    case ContainerType.FuelStorage : case ContainerType.PumpJackOutput : case ContainerType.QuarryOutput : return true;
                    default : return false;
                }
            }
            public static bool CanAutoStart(ContainerType containerType) {
                switch (containerType) {
                    case ContainerType.FuelStorage : case ContainerType.Oven : case ContainerType.Recycler : return true;
                    default : return false;
                }
            }
        }
        /// <summary>
        /// Entity Types
        /// </summary>
        public enum ContainerType {
            General, Oven, Recycler, FuelStorage, QuarryOutput, PumpJackOutput, ResourceExtractor
        }
#endregion
#region ContainerManager
        /// <summary>
        ///     This is attached to a Storage Container to act as the controller for moving items through pipes.///     This then allows for items to move through pipes in a more synchronous manner.///     Items can be split evenly between all pipes of the same priority./// </summary>
        public class ContainerManager : MonoBehaviour {
            ///// <summary>
            ///// Get the save data for all container managers
            ///// </summary>
            ///// <returns>data for all container managers</returns>
            //public static IEnumerable<DataStore> Save()
            //{
            //    using (var enumerator = ManagedContainerLookup.GetEnumerator())
            //    {
            //        while (enumerator.MoveNext())
            //        {
            //            if (enumerator.Current.Value.
// ... [Code preview truncated due to length. Full source in attached file] ...

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