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

FREE FurnaceNoOreStop : 1.3.0 1.3.0

Нет прав для скачивания
C#:
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

//Bunch of optimizations and some minor changes for version 1.1.1
//Bunch more optimzation for 1.2.1
//1.2.2 Checks for ores and furnaces now use HashSet for faster lookups
//Might add more configurable settings in the future. Potentially the list of BaseOvens affected and the cookable types.

namespace Oxide.Plugins
{
    [Info("Furnace No Ore Stop", "Tacman", "1.3.0")]
    [Description("Stops furnaces when there are no more ores, now stops when owner goes offline if permission 'onoff' granted")]
    public class FurnaceNoOreStop : RustPlugin
    {
        private string usePerm = "furnacenoorestop.use";
        private Dictionary<ulong, List<BaseOven>> cookers = new(); //This is to keep track of player ovens, if config setting for on and off are enabled. It also keeps track for turning off when no more ores or crude.
        /*private static readonly HashSet<string> checkOvens = new() //to keep track of all valid furnace and refinery prefab names
        {
            "furnace",
            "furnace.small",
            "furnace.large",
            "legacy_furnace",
            "electricfurnace.deployed",
            "refinery_small_deployed",
            "refinery"
        };*/
        private static readonly HashSet<string> checkOres = new()
        {
            "metal.ore",
            "hq.metal.ore",
            "sulfur.ore",
            "crude.oil"
        };
        private static readonly HashSet<uint> prefabID = new()
        {
            3808299817, //electric furnace deployed
            2931042549, //regular furnace deployed
            2013224025, //legacy furnace deployed
            1374462671, //large furnace deployed
            1057236622 //oil refinery deployed
        };
        #region Config
        static Configuration config;
        public class Configuration
        {
            [JsonProperty("Turn off furnaces when players disconnect?")]
            public bool disconnectOff;
            [JsonProperty("Turn on players furnaces when they connect?")]
            public bool connectOn;
            [JsonProperty("Debugging when player connect and disconnects?")]
            public bool debug;

            public static Configuration DefaultConfig()
            {
                return new Configuration
                {
                    disconnectOff = false,
                    connectOn = false,
                    debug = false
                };
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                SaveConfig();
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
                PrintWarning("Creating new configuration file.");
                LoadDefaultConfig();
            }
        }

        protected override void LoadDefaultConfig() => config = Configuration.DefaultConfig();
        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region Setup

        void Init()
        {
            permission.RegisterPermission(usePerm, this);
        }

        #endregion

        #region Hooks
        void OnServerInitialized()
        {
            cookers.Clear();

            foreach (BaseOven oven in BaseNetworkable.serverEntities.OfType<BaseOven>()) //Only doing this once at server start to populate the dictionary, i prefer this over saving data, it is much more accurate this way.
            {
                if (oven.OwnerID == 0) continue;
                if (!prefabID.Contains(oven.prefabID)) continue; //only care about furnaces and refineries, checks prefab id now

                if (!cookers.TryGetValue(oven.OwnerID, out var list))
                    cookers[oven.OwnerID] = list = new List<BaseOven>();

                if (!list.Contains(oven))
                    list.Add(oven);
            }
        }

        void OnEntitySpawned(BaseOven oven) //decided to use BaseOven here instead of BaseNetworkable for optimization
        {
            if (oven == null) return;
            if (oven.OwnerID == 0) return;
            if (!prefabID.Contains(oven.prefabID)) return;

            if (!cookers.TryGetValue(oven.OwnerID, out var list))
                cookers[oven.OwnerID] = list = new List<BaseOven>();

            if (!list.Contains(oven))
                list.Add(oven);
            if (config.debug)
                Puts($"Added {oven.ShortPrefabName} for owner {BasePlayer.FindByID(oven.OwnerID)?.displayName}");
        }

        void OnEntityKill(BaseOven oven) //same again with BaseOven instead of BaseNetworkable
        {
            if (oven == null) return;
            if (!cookers.TryGetValue(oven.OwnerID, out var list)) return;

            list.Remove(oven);
            if (list.Count == 0)
                cookers.Remove(oven.OwnerID);
        }
        //hashset lookups should be more performant
        private void OnOvenCooked(BaseOven oven)
        {
            if (oven == null || oven.inventory == null) return;

            if (!prefabID.Contains(oven.prefabID)) return;

            if (!permission.UserHasPermission(oven.OwnerID.ToString(), usePerm)) return;

            bool hasOres = false;
            foreach (var i in oven.inventory.itemList)
            {
                if (checkOres.Contains(i.info.shortname))
                {
                    hasOres = true;
                    break;
                }
            }

            if (hasOres)
            {
                if (!oven.IsOn())
                {
                    oven.StartCooking();
                    if (config.debug)
                        Puts($"Furnace owned by {BasePlayer.FindByID(oven.OwnerID)?.displayName} has been turned on as ore/crude was added.");
                }
            }
            else
            {
                oven.StopCooking();
                if (config.debug)
                    Puts($"Furnace owned by {BasePlayer.FindByID(oven.OwnerID)?.displayName} has been turned off as it has no more ores/crude inside.");
            }
        }

        /*in here, it does not actually automatically turn on when the furnace already has existing items, so I use OnLootEntityEnd() to accomplish this.
         I have enabled this again so that industrial automation works properly as long as there are no ores or crude inside already.*/
        private void OnItemAddedToContainer(ItemContainer container, Item item)
        {
            if (container == null || item == null)
                return;

            BaseOven oven = container.entityOwner as BaseOven;
            if (oven == null) return;
            if (!checkOres.Contains(item.info.shortname)) return;
            if (!prefabID.Contains(oven.prefabID)) return;
            if (!permission.UserHasPermission(oven.OwnerID.ToString(), usePerm)) return;

            if (!oven.IsOn())
            {
                oven.StartCooking();
                if (config.debug)
                    Puts($"Furnace owned by {BasePlayer.FindByID(oven.OwnerID)?.displayName} has been turned on as ore/crude was added.");
            }
        }

        private void OnLootEntityEnd(BasePlayer player, BaseOven oven)
        {
            if (oven == null) return;
            if (!prefabID.Contains(oven.prefabID)) return;
            if (!permission.UserHasPermission(oven.OwnerID.ToString(), usePerm)) return;

            if (!oven.IsOn())
            {
                oven.StartCooking();
                if (config.debug)
                    Puts($"Furnace owned by {BasePlayer.FindByID(oven.OwnerID)?.displayName} has been turned on as it has ores/crude inside.");
            }
            if(config.debug)
                Puts($"{player.displayName} looted furnace with prefab id {oven.prefabID}");
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (config.connectOn)
                ToggleOvens(player, true);
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            if (config.disconnectOff)
                ToggleOvens(player, false);
        }
        #endregion

        #region Helper
        //removed the LINQ check here to increase performance when players log in and out. Now uses a direct dictionary lookup.
        private void ToggleOvens(BasePlayer player, bool online)
        {
            if (player == null) return;
            if (!cookers.TryGetValue(player.userID, out var ovens)) return;

            foreach (BaseOven oven in ovens)
            {
                if (oven == null) continue;

                if (online && !oven.IsOn())
                {
                    oven.StartCooking();
                    if (config.debug)
                        Puts($"{oven.ShortPrefabName} owned by {player.displayName} turned on.");
                }
                else if (!online && oven.IsOn())
                {
                    oven.StopCooking();
                    if (config.debug)
                        Puts($"{oven.ShortPrefabName} owned by {player.displayName} turned off.");
                }
            }
        }

        #endregion
    }
}

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