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

FREE ExcavatorLock : 0.4.37 0.4.37

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#define _DEBUGusing Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries.Covalence;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using UnityEngine.Networking;
using Facepunch;
// rev 0.4.25
//    some correction to the lang file
namespace Oxide.Plugins {
    [Info("Excavator Lock", "Lorenzo", "0.4.37")]
    [Description("Lock excavator to a player/team/clan when it run")]
    class ExcavatorLock : CovalencePlugin {
        [PluginReference]
        private Plugin Clans;
        [PluginReference]
        private Plugin Notify;
#region Variables
        private static ExcavatorLock _instance;
        private static DiscordComponent _discord = null;
        private const string PermissionAdmin = "excavatorlock.admin";
        private const ulong supplyDropSkinID = 234501;
        private const string PREFAB_ITEM_DROP = "assets/prefabs/misc/item drop/item_drop.prefab";
        string TraceFile = "Trace";
        // file name in log directory
#if CARBON
        const char Platform = 'C';
#else
        const char Platform = 'O';
#endif
#endregion
#region Configuration
        private static Configuration _config;
        private class Configuration {
            [JsonProperty(PropertyName = "Use permission")]
            public bool UsePermission = false;
            // use permission or grant access to players
            [JsonProperty(PropertyName = "Permission")]
            public string Permission = "excavatorlock.use";
            // name of permission
            [JsonProperty(PropertyName = "Allow access to excavator without permission (will not lock)")]
            public bool UseExcavatorWithoutPermission = false;
            [JsonProperty(PropertyName = "Multiplier permission")]
            public bool MultiplierPermission = false;
            // use permission or grant access to every players
            [JsonProperty(PropertyName = "Permission For Multiplier")]
            public string PermissionMult = "excavatorlock.multiplier";
            // name of permission for multiplier
            [JsonProperty(PropertyName = "CoolDown before releasing excavator")]
            public float CoolDown = 5;
            // 5 minute cooldown after excavator finish and anybody can loot
            [JsonProperty(PropertyName = "Send Excavator available Message to All")]
            public bool MessageAll = true;
            [JsonProperty(PropertyName = "Enable engine loot after it is started to add diesel")]
            public bool engineloot = true;
            // In case clans pluginis installed but you dont want to use it with this plugin
            [JsonProperty(PropertyName = "Use Teams")]
            public bool UseTeams = true;
            // In case clans pluginis installed but you dont want to use it with this plugin
            [JsonProperty(PropertyName = "Use Clans plugin")]
            public bool UseClans = false;
            [JsonProperty(PropertyName = "Use clan table")]
            public bool UseClanTable = false;
            [JsonProperty(PropertyName = "CoolDown before a player or team can restart the excavator (0 is disabled)")]
            public float PlayerCoolDown = 30;
            // 60 minute cooldown after excavator finish and anybody can loot
            [JsonIgnore]
            public float _PlayerCoolDown = 30;
            // internal value
            [JsonProperty(PropertyName = "Apply cooldown to all excavators")]
            public bool CoolDownGlobal = true;
            // 60 minute cooldown after excavator finish and anybody can loot
            [JsonProperty(PropertyName = "Enable fuel modifier")]
            public bool enablefuelModifier = true;
            [JsonProperty(PropertyName = "Maximum stack size for diesel engine (-1 to disable function)")]
            public int DieselFuelMaxStackSize = -1;
            [JsonProperty(PropertyName = "Enable signal Computer lock")]
            public bool enableComputeLock = true;
            [JsonProperty(PropertyName = "Enable signal Computer message")]
            public bool enableComputeMesssage = true;
            [JsonProperty(PropertyName = "Running time per fuel units (time in seconds)")]
            public float runningTimePerFuelUnit = 120f;
            [JsonProperty(PropertyName = "Sulfur production multiplier ")]
            public float SulfurMult = 1f;
            [JsonProperty(PropertyName = "HQM production multiplier")]
            public float HQMMult = 1f;
            [JsonProperty(PropertyName = "Metal production multiplier")]
            public float MetalMult = 1f;
            [JsonProperty(PropertyName = "Stone production multiplier")]
            public float StoneMult = 1f;
            [JsonProperty(PropertyName = "Excavator chat command")]
            public string excavatorquerry = "excavator";
            [JsonProperty(PropertyName = "Excavator clear status")]
            public string excavatorclearstatus = "excavatorclear";
            [JsonProperty(PropertyName = "Excavator stop command")]
            public string excavatorStop = "excavatorstop";
            [JsonProperty(PropertyName = "Empty the output piles when excavator start")]
            public bool FlushOutputPiles = false;
            [JsonProperty(PropertyName = "Charge needed for supply drop (0 to use default of 600sec)")]
            public long chargeNeededForSupplies = 0;
            [JsonProperty(PropertyName = "Clear excavator lock after all player from team/clan disconnect ")]
            public bool ClearExcavatorLockOnAllTeamDisconnect = false;
            [JsonProperty(PropertyName = "Clear excavator lock after player owner disconnect")]
            public bool ClearExcavatorLockOnPlayerOwnerDisconnect = false;
            [JsonProperty(PropertyName = "Time after all player disconnect before excavator clear (minutes)")]
            public long CooldownExcavatorLockOnDisconnect = 10;
            // default 10 minutes
            [JsonProperty(PropertyName = "Items in report list", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public string[] ReportItems = {
                "stones", "metal.ore", "metal.fragments", "hq.metal.ore", "metal.refined", "sulfur.ore", "sulfur", "lowgradefuel", "crude.oil"
            }
            ;
            [JsonProperty("Use Discord hook")]
            public bool Discordena = false;
            [JsonProperty("Use Discord timestamp")]
            public bool UseDiscordTimestamp = true;
            [JsonProperty("Discord hook url")]
            public string DiscordHookUrl = "";
            [JsonProperty(PropertyName = "Use Notify plugin")]
            public bool useNotify = false;
            [JsonProperty(PropertyName = "Debug")]
            public bool Debug = false;
            [JsonProperty(PropertyName = "Log to file")]
            public bool LogToFile = false;
        }
        ;
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
            }
            catch {
                PrintError("Your configuration file contains an error.Using default configuration values.");
                LoadDefaultConfig();
            }
            _config.SulfurMult = Mathf.Clamp(_config.SulfurMult, 0f, 100000f);
            _config.HQMMult = Mathf.Clamp(_config.HQMMult, 0f, 100000f);
            _config.MetalMult = Mathf.Clamp(_config.MetalMult, 0f, 100000f);
            _config.StoneMult = Mathf.Clamp(_config.StoneMult, 0f, 100000f);
            _config._PlayerCoolDown = Math.Max(_config.PlayerCoolDown, _config.CoolDown);
            if (_config.ClearExcavatorLockOnAllTeamDisconnect == true && _config.ClearExcavatorLockOnPlayerOwnerDisconnect == true) {
                PrintError("Both ClearExcavatorLockOnAllTeamDisconnect and ClearExcavatorLockOnPlayerOwnerDisconnect are true.Using team mode by default");
                _config.ClearExcavatorLockOnPlayerOwnerDisconnect = false;
            }
            SaveConfig();
        }
        protected override void LoadDefaultConfig() => _config = new Configuration();
        protected override void SaveConfig() => Config.WriteObject(_config);
#endregion Configuration
        // ############################################################################################
#region UserInfo
        private Dictionary<ulong, ExcavatorInfo> Excavators = new Dictionary<ulong, ExcavatorInfo>();
        // dict to link all the diff component entity to the right excavator
        private Dictionary<ulong, ulong> Associate = new Dictionary<ulong, ulong>();
        private class ExcavatorInfo {
            public ulong playerid;
            public string displayName;
            [JsonIgnore]
            public double FuelTimeRemaining;
            [JsonIgnore]
            public bool state;
            // is the excavator running
            public DateTime fueltime;
            public DateTime stoptime;
            public string Name;
            public Dictionary<ulong, CooldownTime> PlayerCooldown;
            [JsonIgnore]
            public DateTime PlayerDisconnectTime;
            [JsonIgnore]
            public int CountTick;
            [JsonIgnore]
            public ExcavatorArm Arm;
            [JsonIgnore]
            public Timer timerStopped = null;
            [JsonIgnore]
            public float[] extraMineralProduced = {
                0f, 0f, 0f, 0f
            }
            ;
            [JsonIgnore]
            public int pileIndex = 0;
            public ExcavatorInfo() {
                playerid = 0;
                displayName = string.Empty;
                FuelTimeRemaining = 0f;
                state = false;
                PlayerDisconnectTime = DateTime.MaxValue;
                fueltime = DateTime.MinValue;
                stoptime = DateTime.MinValue;
                Name = "nobody";
                PlayerCooldown = new Dictionary<ulong, CooldownTime>();
                CountTick = 10;
                Arm = null;
            }
        }
        public class CooldownTime {
            public bool IsOnline;
            public bool IgnoreOnline;
            public DateTime Time;
            public CooldownTime() {
                IsOnline = true;
                Time = DateTime.MinValue;
                IgnoreOnline = false;
            }
        }
        private void LoadData() {
            try {
                Excavators = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, ExcavatorInfo>>(Name);
                if (Excavators == null) throw new Exception();
            }
            catch {
                Excavators = new Dictionary<ulong, ExcavatorInfo>();
                PrintWarning($"Data file corrupted or incompatible.Reinitialising data file ");
                SaveData();
            }
        }
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject(Name, Excavators);
        }
#endregion UserInfo
        // ############################################################################################
#region Localization
        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        private new void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["ExcavatorOff"]
                = "<color=#FF1500>- Excavator just turn off !</color>", ["ExcavatorCoolDown"] = "<color=#FF1500>- You have {0} minutes to get the ore, before it unlock to all</color>", ["ExcavatorInUse"] = "<color=#FFA500>Excavator currently in use by {0}</color>", ["ExcavatorStartEngine"] = "Excavator started for {0,2:F0} minutes", ["ExcavatorStartEngineHM"] = "Excavator started for {0,2:F0} hour, {1,2:F0} minutes", ["ExcavatorStarted_"] = "Excavator {0}, started by {1}.loot is protected", ["ExcavatorStoped_"] = "Excavator {0}, stopped and is available to all", ["ExcavatorFuel"] = "<color=#FFA500>Excavator currently running with {0} fuel in storage</color>", ["ExcavatorPlCooldown"] = "Excavator Player cooldown will expire in {0} minutes", ["ExcavatorAvailableIn1"] = "Excavator {0}, used by {2}, will be available in {1,2:F0} minutes", ["ExcavatorClearStatus"] = "Clearing the excavator status", ["ExcavatorPermission"] = "Player does not have permission to use excavator", ["ExcavatorSupplySignal"] = "Airdrop was activated at excavator {0} by player {1}, please do not steal", ["ExcavatorClearOffline"] = "Excavator {0}, cleared because team/clan player are offline", ["NoExcavatorFoundNear"] = "No excavator found near to apply command", ["MoveFuelToOutput"] = "Stop excavator, moving fuel to output pile",
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["ExcavatorOff"]
                = "<color=#FF1500>- l'excavateur viens de s'arrêter !</color>", ["ExcavatorCoolDown"] = "<color=#FF1500>- Vous avez {0} minutes pour récuperer le butin avant qu'il ne soit accessible pour tous !</color>", ["ExcavatorInUse"] = "<color=#FFA500>l'excavateur est utilisé par {0}.</color>", ["ExcavatorStartEngine"] = "L'excavateur est démarré pour {0,2:F0} minutes.", ["ExcavatorStartEngineHM"] = "L'excavateur est démarré pour {0,2:F0} heure(s), {1,2:F0} minutes.", ["ExcavatorStarted_"] = "L'excavateur {0} a été démarré par {1}.Le butin est protégé !", ["ExcavatorStoped_"] = "Arret de l'excavateur {0}.Le butin est disponible pour tous !", ["ExcavatorFuel"] = "<color=#FFA500>L'excavateur a été démarré avec {0} diesel(s) dans le reservoir.</color>", ["ExcavatorPlCooldown"] = "Le délai d'utilisation de l'Excavateur expire dans {0} minutes.", ["ExcavatorAvailableIn1"] = "L'excavateur {0}, utilisé par {2}, sera disponible dans {1,2:F0} minutes.", ["ExcavatorClearStatus"] = "Efface le status de l'excavateur.", ["ExcavatorPermission"] = "Le joueur n'a pas la permission d'utiliser l'excavateur.", ["ExcavatorSupplySignal"] = "Largage aérien activé a l'excavator {0} par le joueur {1}, s.v.p.ne pas voler.", ["ExcavatorClearOffline"] = "L'excavateur {0}, est libre, le l'equipe/clan s'est deconnecté !", ["NoExcavatorFoundNear"] = "Aucun excavateur trouvé, deplacez vous plus pres dèun excavateur", ["MoveFuelToOutput"] = "Arret de l'excavateur, transfert du diesel vers pile de sortie",
            }
            , this, "fr");
        }
#endregion Localization
#region Hooks Targets
        private void Unload() {
            SaveData();
            if (_config.chargeNeededForSupplies > 2) ExcavatorSignalComputer.chargeNeededForSupplies = 600f;
            // reset to default
            foreach (var KVP in Excavators) {
                if (KVP.Value.timerStopped != null) {
                    timer.Destroy(ref KVP.Value.timerStopped);
                }
            }
            _instance = null;
            _discord = null;
            _config = null;
        }
        private void Init() {
            _instance = this;
            permission.RegisterPermission(_config.Permission, this);
            permission.RegisterPermission(_config.PermissionMult, this);
            permission.RegisterPermission(PermissionAdmin, this);
            LoadData();
            if (!_config.ClearExcavatorLockOnAllTeamDisconnect && !_config.ClearExcavatorLockOnPlayerOwnerDisconnect) {
                Unsubscribe(nameof(OnPlayerConnected));
                Unsubscribe(nameof(OnPlayerDisconnected));
            }
            AddCovalenceCommand(_config.excavatorquerry, nameof(Excavator_info));
            AddCovalenceCommand(_config.excavatorclearstatus, nameof(Excavator_clearstatus));
            AddCovalenceCommand(_config.excavatorStop, nameof(Excavator_stopcommand));
        }
        private void OnServerInitialized(bool initial) {
            if (_config.Discordena && !string.IsNullOrEmpty(_config.DiscordHookUrl)) {
                var loader = new GameObject("WebObject");
                _discord = loader.AddComponent<DiscordComponent>().Configure(_config.DiscordHookUrl);
                PrintToLog($"Plugin Excavator Lock restarted");
            }
            // limit the range between 10 sec and 10 minutes per barrel
            if (_config.runningTimePerFuelUnit < 10f) {
                PrintWarning("Warning, config.runningTimePerFuelUnit modifier is disabled.(runningTimePerFuelUnit < 10)");
                _config.runningTimePerFuelUnit = 10f;
            }
            if (_config.runningTimePerFuelUnit > 6000f) {
                PrintWarning("Warning, config.runningTimePerFuelUnit set to maximum at 6000 sec.(runningTimePerFuelUnit > 6000)");
                _config.runningTimePerFuelUnit = 6000f;
            }
            // this is just in case user think its in second and put a large value
            if (_config.PlayerCoolDown > 120) {
                PrintWarning($"Configuration cooldown period {_config.PlayerCoolDown} minutes");
            }
            List<DieselEngine> engines = Pool.Get<List<DieselEngine>>();
            List<ExcavatorSignalComputer> Computes = Pool.Get<List<ExcavatorSignalComputer>>();
            engines.Clear();
            Computes.Clear();
            // count the excavator engine on the map
            foreach (var entarm in BaseNetworkable.serverEntities) {
                var arm = entarm as ExcavatorArm;
                if (arm != null) {
                    Vis.Entities<DieselEngine>(arm.transform.position, 20f, engines, -1);
                    Vis.Entities<ExcavatorSignalComputer>(arm.transform.position, 20f, Computes, -1);
                    ExcavatorInfo excavatorinfo;
                    if (!Excavators.TryGetValue(arm.net.ID.Value, out excavatorinfo)) {
                        excavatorinfo = new ExcavatorInfo();
                        Excavators.Add(arm.net.ID.Value, excavatorinfo);
                    }
                    excavatorinfo.Name = PositionToString(arm.transform.position);
                    excavatorinfo.Arm = arm;
                    // Associate engines to excavator in dictionary
                    foreach (var engine in engines) {
                        // experiemntal max stack size
                        if (_config.DieselFuelMaxStackSize >= 0) engine.inventory.maxStackSize = _config.DieselFuelMaxStackSize;
                        excavatorinfo.state = engine.IsOn();
                        Associate.Add(engine.net.ID.Value, arm.net.ID.Value);
                        if (_config.enablefuelModifier) engine.runningTimePerFuelUnit = _config.runningTimePerFuelUnit;
                        if (excavatorinfo.state) excavatorinfo.FuelTimeRemaining = CalcFuelTime(engine);
                        else excavatorinfo.FuelTimeRemaining = 0;
                        excavatorinfo.fueltime = DateTime.Now.AddMinutes(excavatorinfo.FuelTimeRemaining);
                        break;
                        // only one engine per excavator, ignore duplicates
                    }
                    // Associate outputpiles to excavator in dictionary
                    foreach (var outputpile in arm.outputPiles) {
                        Associate.Add(outputpile.net.ID.Value, arm.net.ID.Value);
                    }
                    if (_config.chargeNeededForSupplies > 2) ExcavatorSignalComputer.chargeNeededForSupplies = (float)_config.chargeNeededForSupplies;
                    // Associate engines to excavator in dictionary
                    foreach (var compute in Computes) {
                        Associate.Add(compute.net.ID.Value, arm.net.ID.Value);
                        break;
                        // only one compute, ignore duplicates
                    }
                }
                engines.Clear();
                Computes.Clear();
            }
            Pool.FreeUnmanaged(ref engines);
            Pool.FreeUnmanaged(ref Computes);
            NextTick(() => {
                // Check if the excavator entry exist
                // If not remove it.This append when server wipe
                List<ulong> removals = new List<ulong>();
                foreach (KeyValuePair<ulong, ExcavatorInfo> kvp in Excavators) {
                    if (kvp.Value.Arm == null) {
                        PrintWarning($"Removing excavator info for {kvp.Key} ");
                        removals.Add(kvp.Key);
                    }
                }
                // cleanup dict entry of unused info
                foreach (ulong removeid in removals) {
                    Excavators.Remove(removeid);
                }
                if (_config.UseClans && !IspluginLoaded(Clans)) {
                    PrintWarning("Optional Clans plugin not found.Clans disabled");
                }
                if (_config.useNotify && !IspluginLoaded(Notify)) {
                    PrintWarning("Optional Notify plugin not found.Notify disabled");
                }
            }
            );
        }
        object OnDieselEngineToggle(DieselEngine engine, BasePlayer player) {
            if (engine.skinID != 0UL) return null;
            ulong armID;
            ExcavatorInfo excavatorinfo = null;
            if (!Associate.TryGetValue(engine.net.ID.Value, out armID)) return null;
            // allow if engine not associated with excavator
            if (!Excavators.TryGetValue(armID, out excavatorinfo)) return true;
            //
            bool perm = CanPlayerUse((ulong)player.userID);
            if (!perm && !_config.UseExcavatorWithoutPermission) {
                SendChatMessage(player, "ExcavatorPermission");
                return true;
            }
            // check if engine is off.if (!engine.IsOn())
            {
                var checkcooldown = CheckPlayerCooldown((ulong)player.userID, excavatorinfo);
                // if Player cooldown is active, dont allow excavator restart
                if (checkcooldown) {
                    SendChatMessage(player, "ExcavatorPlCooldown", PlayerCooldownTime((ulong)player.userID, excavatorinfo));
                    return true;
                }
                // If excavator is captured, dont allow it to restart
                if (!IsExcavatorAvailable(excavatorinfo)) {
                    SendChatMessage(player, "ExcavatorInUse", excavatorinfo.displayName);
                    return true;
                    // do not start excavator
                }
                if (perm) {
                    excavatorinfo.playerid = (ulong)player.userID;
                    excavatorinfo.displayName = player.displayName;
                    excavatorinfo.PlayerDisconnectTime = DateTime.MaxValue;
                }
                else {
                    excavatorinfo.playerid = 0;
                    excavatorinfo.displayName = "nobody";
                    excavatorinfo.PlayerDisconnectTime = DateTime.MaxValue;
                }
                PrintToLog($"Excavator engine {excavatorinfo.Name} started at : {DateTime.Now.ToString("hh : mm tt")}");
                return null;
            }
            return null;
        }
        double CalcFuelTime(DieselEngine engine) => (engine.cachedFuelTime + engine.runningTimePerFuelUnit * (float)engine.GetFuelAmount()) / 60f;
        // The engine was toggled.void OnDieselEngineToggled(DieselEngine engine)
        {
            if (engine.skinID != 0UL) return;
            ulong armID;
            ExcavatorInfo excavatorinfo = null;
            if (!Associate.TryGetValue(engine.net.ID.Value, out armID)) return;
            //
            if (!Excavators.TryGetValue(armID, out excavatorinfo)) return;
            //
            excavatorinfo.state = engine.IsOn();
            if (excavatorinfo.state) {
                if (excavatorinfo.playerid != 0) {
                    // Excavator state is On
                    excavatorinfo.FuelTimeRemaining = CalcFuelTime(engine);
                    excavatorinfo.fueltime = DateTime.Now.AddMinutes(excavatorinfo.FuelTimeRemaining);
                    excavatorinfo.PlayerDisconnectTime = DateTime.MaxValue;
                    BasePlayer player = BasePlayer.FindByID(excavatorinfo.playerid);
                    if (player != null) {
                        if (excavatorinfo.FuelTimeRemaining < 60) SendChatMessage(player, "ExcavatorStartEngine", Math.Ceiling(excavatorinfo.FuelTimeRemaining));
                        else SendChatMessage(player, "ExcavatorStartEngineHM", excavatorinfo.FuelTimeRemaining / 60, excavatorinfo.FuelTimeRemaining % 60);
                        if (_config.MessageAll) {
                            BroadcastMessage("ExcavatorStarted_", excavatorinfo.Name, player.displayName);
                        }
                    }
                    // Start
                    AddPlayerCooldown(excavatorinfo.playerid, excavatorinfo.FuelTimeRemaining, excavatorinfo);
                    if (_config.FlushOutputPiles) {
                        var arm = excavatorinfo.Arm;
                        if (arm != null) {
                            int cnt = 1;
                            foreach (var piles in arm.outputPiles) {
                                var storage = piles.GetComponent<StorageContainer>();
                                PrintToLog($"Flush {cnt}/2 {ReportInventory(storage)} items from loot pile");
                                DropItemContainer(storage.inventory, piles.transform.position, Quaternion.identity);
                                cnt++;
                            }
                        }
                    }
                    if (excavatorinfo.timerStopped != null) {
                        timer.Destroy(ref excavatorinfo.timerStopped);
                    }
                }
            }
            else {
                // Excavator state is Off
                if (excavatorinfo.playerid != 0) {
                    excavatorinfo.stoptime = DateTime.Now;
                    // Update cooldown info when the excavator stop
                    AddPlayerCooldown(excavatorinfo.playerid, 0f, excavatorinfo);
                    // player will be null when disconnected and wont receive message
                    var player = BasePlayer.FindByID(excavatorinfo.playerid);
                    if (player != null) {
                        SendChatMessage(player, "ExcavatorOff");
                        SendChatMessage(player, "ExcavatorCoolDown", _config.CoolDown);
                    }
                    PrintToLog($"Excavator {excavatorinfo.Name} stopped at : {DateTime.Now.ToString("hh : mm tt")}");
                    if (excavatorinfo.timerStopped != null) {
                        timer.Destroy(ref excavatorinfo.timerStopped);
                    }
                    excavatorinfo.timerStopped = timer.Once(_config.CoolDown * 60f, () => {
                        // In case excavator is resarted after cooldown
                        if (excavatorinfo!=null && !excavatorinfo.state) {
                            if (_config.MessageAll) BroadcastMessage("ExcavatorStoped_", excavatorinfo.Name);
                            excavatorinfo.playerid = 0;
                            excavatorinfo.displayName = "nobody";
                            excavatorinfo.PlayerDisconnectTime = DateTime.MaxValue;
                            excavatorinfo.timerStopped = null;
                        }
                    }
                    );
                }
            }
            SaveData();
        }
        object CanLootEntity(BasePlayer player, StorageContainer container) {
            if (container.skinID != 0UL) return null;
            // ID excavator_output_pile
            // ID engine
            if (container.prefabID == 673116596) return LootExcavatorOutputPile(player, container);
            // "excavator_output_pile"
            else if (container.prefabID == 2982299738) return LootDieselEngine(player, container);
            // "engine"
            else if (container.prefabID == 3632568684) return LootAirdrop(player, container);
            // Airdrop
            return null;
        }
        void OnLootEntityEnd(BasePlayer player, StorageContainer container) {
            if (container.skinID != 0UL) return;
            if (container.prefabID == 2982299738) LootDieselEngineEnd(player, container);
            // "engine"
        }
        void LootDieselEngineEnd(BasePlayer player, StorageContainer container) {
            if (container.skinID != 0UL) return;
            ulong armID;
            ExcavatorInfo excavatorinfo = null;
            var engine = container as DieselEngine;
            if (engine == null) return;
            if (!Associate.TryGetValue(engine.net.ID.Value, out armID)) return;
            if (!Excavators.TryGetValue(armID, out excavatorinfo)) return;
            if (excavatorinfo.state == true) {
                excavatorinfo.FuelTimeRemaining = CalcFuelTime(engine);
                excavatorinfo.fueltime = DateTime.Now.AddMinutes(excavatorinfo.FuelTimeRemaining);
                AddPlayerCooldown(excavatorinfo.playerid, excavatorinfo.FuelTimeRemaining, excavatorinfo);
            }
        }
        object LootExcavatorOutputPile(BasePlayer player, StorageContainer container) {
            ulong armID;
            ExcavatorInfo excavatorinfo = null;
            if (!Associate.TryGetValue(container.net.ID.Value, out armID)) return true;
            //
            if (!Excavators.TryGetValue(armID, out excavatorinfo)) return true;
            //
            if (IsAdmin((ulong)player.userID) || excavatorinfo.playerid == 0 || IsExcavatorAvailable(excavatorinfo)) {
                PrintToLog($"Player {player.displayName}/{(ulong)player.userID} looting pile not locked    loc:{excavatorinfo.Name}, {ReportInventory(container)} items in pile");
                return null;
            }
            if (((ulong)player.userID == excavatorinfo.playerid) || (SameTeam((ulong)player.userID, excavatorinfo.playerid)) || (SameClan((ulong)player.userID, excavatorinfo.playerid))) {
                PrintToLog($"Player {player.displayName}/{(ulong)player.userID} looting pile owned by:{excavatorinfo.displayName}/{excavatorinfo.playerid}  loc:{excavatorinfo.Name}, {ReportInventory(container)} item in pile");
                return null;
            }
            SendChatMessage(player, "ExcavatorInUse", excavatorinfo.displayName);
            return true;
        }
        object LootDieselEngine(BasePlayer player, StorageContainer container) {
            if (container.skinID != 0UL) return null;
            ulong armID;
            ExcavatorInfo excavatorinfo = null;
            if (!Associate.TryGetValue(container.net.ID.Value, out armID)) return null;
            // ignore engine not associated
            if (!Excavators.TryGetValue(armID, out excavatorinfo)) return true;
            //
            if (IsAdmin((ulong)player.userID) || excavatorinfo.playerid == 0 || (IsExcavatorAvailable(excavatorinfo) && !CheckPlayerCooldown((ulong)player.userID, excavatorinfo))) {
                PrintToLog($"Player {player.displayName}/{(ulong)player.userID} Looting engine, not locked  pos:{excavatorinfo.Name}");
                return null;
            }
            if (((ulong)player.userID == excavatorinfo.playerid) || (SameTeam((ulong)player.userID, excavatorinfo.playerid)) || (SameClan((ulong)player.userID, excavatorinfo.playerid))) {
                if (!_config.engineloot)  // cannot loot diesel engine if current user
                {
                    var amount = (container.inventory.itemList.Count != 0) ? container.inventory.itemList[0].amount + 1 : 1;
                    if (excavatorinfo.state) SendChatMessage(player, "ExcavatorFuel", amount.ToString());
                    else {
                        SendChatMessage(player, "ExcavatorAvailableIn1", excavatorinfo.Name, PlayerCooldownTime((ulong)player.userID, excavatorinfo), excavatorinfo.displayName);
                    }
                    return true;
                    // disable engine loot
                }
                PrintToLog($"Player {player.displayName}/{(ulong)player.userID} Looting engine, locked to {excavatorinfo.displayName}/{excavatorinfo.playerid}  pos:{excavatorinfo.Name}");
                return null;
            }
            SendChatMessage(player, "ExcavatorInUse", excavatorinfo.displayName);
            return true;
        }
        object LootAirdrop(BasePlayer player, StorageContainer container) {
            ulong armID;
            ExcavatorInfo excavatorinfo;
            List<ExcavatorSignalComputer> Computes = Pool.Get<List<ExcavatorSignalComputer>>();
            Computes.Clear();
            Vis.Entities<ExcavatorSignalComputer>(container.transform.position, 90f, Computes, -1);
            if (Computes.Count != 0) {
                if (Associate.TryGetValue(Computes[0].net.ID.Value, out armID)) {
                    if (Excavators.TryGetValue(armID, out excavatorinfo)) {
                        PrintToLog($"Player {player.displayName}/{(ulong)player.userID} Looting supply drop near excavator, locked to {excavatorinfo.displayName}/{excavatorinfo.playerid}  pos:{excavatorinfo.Name}  dist:{Vector3.Distance(Computes[0].transform.position, container.transform.position).ToString("F1")}");
                    }
                }
            }
            Pool.FreeUnmanaged(ref Computes);
            return null;
        }
        object OnExcavatorResourceSet(ExcavatorArm arm, string resourceName, BasePlayer player) {
            ExcavatorInfo excavatorinfo;
            if (!Excavators.TryGetValue(arm.net.ID.Value, out excavatorinfo)) return true;
            if (IsAdmin((ulong)player.userID) || excavatorinfo.playerid == 0 || IsExcavatorAvailable(excavatorinfo)) {
                PrintToLog($"Excavator {excavatorinfo.Name} started at : {DateTime.Now.ToString("hh : mm tt")} for {excavatorinfo.FuelTimeRemaining} minutes, not locked to player {excavatorinfo.displayName}/{excavatorinfo.playerid}.Mining {resourceName}");
                return null;
            }
            // check if a different player/team/clan is trying to use excavator
            if (!(((ulong)player.userID == excavatorinfo.playerid) || (SameTeam((ulong)player.userID, excavatorinfo.playerid)) || (SameClan((ulong)player.userID, excavatorinfo.playerid)))) {
                SendChatMessage(player, "ExcavatorInUse", excavatorinfo.displayName);
                return true;
            }
            PrintToLog($"Excavator {excavatorinfo.Name} started at : {DateTime.Now.ToString("hh : mm tt")} for {excavatorinfo.FuelTimeRemaining} minutes, by player {excavatorinfo.displayName}/{excavatorinfo.playerid}.Mining {resourceName}");
            return null;
        }
        object OnExcavatorGather(ExcavatorArm arm, Item item) {
            float multiplier = 1f;
            ExcavatorInfo excavatorinfo;
            if (!Excavators.TryGetValue(arm.net.ID.Value, out excavatorinfo)) return null;
            if (excavatorinfo.pileIndex == 0) excavatorinfo.pileIndex = excavatorinfo.Arm.outputPiles.Count - 1;
            else excavatorinfo.pileIndex--;
            if (excavatorinfo.playerid!=0 && IsMultiplierActive(excavatorinfo.playerid)) {
                if (item.info.shortname == "sulfur.ore" && _config.SulfurMult != 0f) multiplier = _config.SulfurMult;
                else if (item.info.shortname == "hq.metal.ore" && _config.HQMMult != 0f) multiplier = _config.HQMMult;
                else if (item.info.shortname == "metal.fragments" && _config.MetalMult != 0f) multiplier = _config.MetalMult;
                else if (item.info.shortname == "stones" && _config.StoneMult != 0f) multiplier = _config.StoneMult;
            }
            float tmp = excavatorinfo.extraMineralProduced[excavatorinfo.pileIndex] + ((float)item.amount * (multiplier -1f));
            float tmp2 = Mathf.Floor(tmp);
            item.amount = Math.Max(0, item.amount + (int)tmp2);
            excavatorinfo.extraMineralProduced[excavatorinfo.pileIndex] = tmp - tmp2;
            // Evaluate every ~10 sec.if ((_config.ClearExcavatorLockOnAllTeamDisconnect || _config.ClearExcavatorLockOnPlayerOwnerDisconnect) && --excavatorinfo.CountTick == 0)
            {
                excavatorinfo.CountTick = 10;
                if (excavatorinfo.PlayerDisconnectTime != DateTime.MaxValue) {
                    if (excavatorinfo.PlayerDisconnectTime.AddMinutes(_config.CooldownExcavatorLockOnDisconnect) <= DateTime.Now) {
                        // Clear quarry lock
                        if (_config.ClearExcavatorLockOnPlayerOwnerDisconnect) {
                            PrintToLog($"Excavator unlocked because player owner disconnected for {_config.CooldownExcavatorLockOnDisconnect} minutes {excavatorinfo.displayName}/{excavatorinfo.playerid} ");
                        }
                        if (_config.ClearExcavatorLockOnAllTeamDisconnect) {
                            PrintToLog($"Excavator unlocked because all team/clan disconnected for {_config.CooldownExcavatorLockOnDisconnect} minutes {excavatorinfo.displayName}/{excavatorinfo.playerid} ");
                        }
                        if (_config.MessageAll) BroadcastMessage("ExcavatorClearOffline", excavatorinfo.Name);
                        excavatorinfo.PlayerDisconnectTime = DateTime.MaxValue;
                        ClearExcavator(excavatorinfo, false);
                    }
                }
            }
            return null;
        }
        void OnPlayerConnected(BasePlayer player) {
            if (player == null) return;
            foreach (KeyValuePair<ulong, ExcavatorInfo> excav in Excavators) {
                foreach (var kvp in excav.Value.PlayerCooldown) {
                    if (_config.ClearExcavatorLockOnPlayerOwnerDisconnect) {
                        if ((ulong)player.userID == kvp.Key && (ulong)player.userID == excav.Value.playerid) {
                            kvp.Value.IsOnline = true;
                            excav.Value.PlayerDisconnectTime = DateTime.MaxValue;
                            PrintToLog($"Player connected {player.displayName}/{(ulong)player.userID} at {DateTime.Now}   isconnected:{BasePlayer.FindAwakeOrSleeping(player.UserIDString)?.IsConnected ?? false}");
                        }
                    }
                    if (_config.ClearExcavatorLockOnAllTeamDisconnect) {
                        if ((ulong)player.userID == kvp.Key) {
                            kvp.Value.IsOnline = true;
                            excav.Value.PlayerDisconnectTime = DateTime.MaxValue;
                            PrintToLog($"Player connected {player.displayName}/{(ulong)player.userID} at {DateTime.Now}   isconnected:{BasePlayer.FindAwakeOrSleeping(player.UserIDString)?.IsConnected ?? false}");
                        }
                    }
                }
            }
        }
        void OnPlayerDisconnected(BasePlayer player, string strReason) {
            int PlayerCount;
            if (player == null) return;
            foreach (KeyValuePair<ulong, ExcavatorInfo> excav in Excavators) {
                if (_config.ClearExcavatorLockOnPlayerOwnerDisconnect) PlayerCount = 1;
                else PlayerCount = excav.Value.PlayerCooldown.Count;
                foreach (var kvp in excav.Value.PlayerCooldown) {
                    if (_config.ClearExcavatorLockOnPlayerOwnerDisconnect) {
                        if ((ulong)player.userID == kvp.Key && (ulong)player.userID == excav.Value.playerid) {
                            kvp.Value.IsOnline = false;
                            PlayerCount--;
                            PrintToLog($"Player disconnected {player.displayName}/{(ulong)player.userID} at {DateTime.Now}   isconnected:{BasePlayer.FindAwakeOrSleeping(player.UserIDString)?.IsConnected ?? false}");
                        }
                    }
                    if (_config.ClearExcavatorLockOnAllTeamDisconnect) {
                        if (kvp.Key == (ulong)player.userID) {
                            kvp.Value.IsOnline = false;
                            PrintToLog($"Player disconnected {player.displayName}/{(ulong)player.userID} at {DateTime.Now}   isconnected:{BasePlayer.FindAwakeOrSleeping(player.UserIDString)?.IsConnected ?? false}");
                        }
                        if (!kvp.Value.IsOnline || kvp.Value.IgnoreOnline) PlayerCount--;
                    }
                }
                if (PlayerCount == 0) {
                    excav.Value.PlayerDisconnectTime = DateTime.Now;
                    PrintToLog($"Activate disconnect countdown {player.displayName}/{(ulong)player.userID} at {DateTime.Now}  {excav.Value.Name} by {excav.Value.displayName}/{excav.Value.playerid} ");
                }
            }
        }
        bool CheckPlayerCooldown(ulong playerID, ExcavatorInfo excavatorinfo) {
            List<ulong> removals = new List<ulong>();
            DateTime now = DateTime.Now;
            bool result = false;
            if (_config.CoolDownGlobal) {
                foreach (KeyValuePair<ulong, ExcavatorInfo> excav in Excavators) {
                    foreach (KeyValuePair<ulong, CooldownTime> kvp in excav.Value.PlayerCooldown) {
                        if (now >= kvp.Value.Time) removals.Add(kvp.Key);
                        if (kvp.Key == playerID && now < kvp.Value.Time) result=true;
                    }
                    // cleanup dict entry of older time info
                    foreach (ulong removeid in removals) {
                        excav.Value.PlayerCooldown.Remove(removeid);
                    }
                    removals.Clear();
                }
            }
            else {
                foreach (KeyValuePair<ulong, CooldownTime> kvp in excavatorinfo.PlayerCooldown) {
                    if (now >= kvp.Value.Time) removals.Add(kvp.Key);
                    if (kvp.Key == playerID && now < kvp.Value.Time) result=true;
                }
                // cleanup dict entry of older time info
                foreach (ulong removeid in removals) {
                    excavatorinfo.PlayerCooldown.Remove(removeid);
                }
            }
            return result;
        }
        int PlayerCooldownTime(ulong playerID, ExcavatorInfo excavatorinfo) {
            DateTime now = DateTime.Now;
            CooldownTime cooldown;
            if (_config.CoolDownGlobal) {
                foreach (KeyValuePair<ulong, ExcavatorInfo> excav in Excavators) {
                    if (excav.Value.PlayerCooldown.TryGetValue(playerID, out cooldown) && now < cooldown.Time) {
                        var diff = cooldown.Time.Subtract(now);
                        return (int)Math.Ceiling(diff.TotalMinutes);
                    }
                }
            }
            else {
                if (excavatorinfo.PlayerCooldown.TryGetValue(playerID, out cooldown) && now < cooldown.Time) {
                    var diff = cooldown.Time.Subtract(now);
                    return (int)Math.Ceiling(diff.TotalMinutes);
                }
            }
            return 0;
        }
        void AddPlayerCooldown(ulong playerID, double extra, ExcavatorInfo excavatorinfo) {
            var teammanager = RelationshipManager.ServerInstance;
            foreach (KeyValuePair<ulong, CooldownTime> kvp in excavatorinfo.PlayerCooldown) {
                kvp.Value.IgnoreOnline = true;
            }
            //player.IsConnected
            CooldownTime CoolDown = new CooldownTime();
            CoolDown.IsOnline = BasePlayer.FindAwakeOrSleeping(playerID.ToString())?.IsConnected ?? false;
            CoolDown.Time = DateTime.Now.AddMinutes(_config._PlayerCoolDown + extra);
            AddSinglePlayerCooldown(playerID, excavatorinfo, CoolDown);
            if (CoolDown.IsOnline == false) {
                PrintWarning($"Player {playerID} just activated quarry, but is flagged Offline.Something is wrong ");
                PrintToLog($"Player {playerID} just activated quarry, but is flagged Offline.Something is wrong ");
            }
            // If enable, Process all team members
            if (_config.UseTeams && teammanager != null) {
                var team = teammanager.FindPlayersTeam(playerID);
                if (team != null) {
                    foreach (var ent in team.members) {
                        CoolDown = new CooldownTime();
                        CoolDown.IsOnline = BasePlayer.FindAwakeOrSleeping(ent.ToString())?.IsConnected ?? false;
                        CoolDown.IgnoreOnline = false;
                        CoolDown.Time = DateTime.Now.AddMinutes(_config._PlayerCoolDown + extra);
                        AddSinglePlayerCooldown(ent, excavatorinfo, CoolDown);
                    }
                }
            }
            // if enable, process the clan member
            if (_config.UseClans && IspluginLoaded(Clans)) {
                BasePlayer friend;
                var member = Clans.Call("GetClanMembers", playerID.ToString());
                if (member!=null) {
                    List<string> memberlist = member as List<string>;
                    foreach (var ent in memberlist) {
                        friend = BasePlayer.FindAwakeOrSleeping(ent);
                        if (friend != null) {
                            CoolDown = new CooldownTime();
                            CoolDown.IsOnline = friend.IsConnected;
                            CoolDown.IgnoreOnline = false;
                            CoolDown.Time = DateTime.Now.AddMinutes(_config._PlayerCoolDown + extra);
                            AddSinglePlayerCooldown(ulong.Parse(ent), excavatorinfo, CoolDown);
                        }
                    }
                }
            }
            // if enable, process the clan member from clantable
            if (_config.UseClanTable) {
                BasePlayer friend;
                long clanId = BasePlayer.FindAwakeOrSleeping(playerID.ToString())?.clanId ?? 0;
                if (clanId != 0) {
                    IClan clan = null;
                    if (ClanManager.ServerInstance.Backend?.TryGet(clanId, out clan) ?? false) {
                        foreach (ClanMember member in clan.Members) {
                            friend = BasePlayer.FindAwakeOrSleeping(member.SteamId.ToString());
                            if (friend != null) {
                                CoolDown = new CooldownTime();
                                CoolDown.IsOnline = friend.IsConnected;
                                CoolDown.IgnoreOnline = false;
                                CoolDown.Time = DateTime.Now.AddMinutes(_config._PlayerCoolDown + extra);
                                AddSinglePlayerCooldown(member.SteamId, excavatorinfo, CoolDown);
                            }
                        }
                    }
                }
            }
        }
        void AddSinglePlayerCooldown(ulong playerID, ExcavatorInfo excavatorinfo, CooldownTime Cooldown) {

// ... [Code preview truncated due to length. Full source in attached file] ...

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