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

FREE BaseGuardian : 1.1.1 1.1.1

Нет прав для скачивания
C#:
/* 
 * Copyright (C) 2025 NexCore/CrypticRedHat - All Rights Reserved
 * Unauthorized copying of this file, via any medium, is strictly prohibited.
 * This file is proprietary and confidential, created and maintained by NexCore (CrypticRedHat).
 *
 * Plugin Name: BaseGuardian
 * Version: 1.1.1
 * Last Updated: April 2025
 * Contact: zaneful@proton.me
 *
 * Description:
 * This software is provided as part of a Rust server mod/plugin. By using this file,
 * you agree to the following terms. You may not, without explicit written permission
 * from the Developer:
 *   - Copy, distribute, or disclose any part of this software in any medium.
 *   - Alter, merge, publish, sublicense, or sell copies of this software, in whole or in part.
 *
 * Warranty and Liability:
 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH
 * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * Any breach of these terms will be pursued to the fullest extent of applicable laws.
 */

using System.Collections.Generic;
using UnityEngine;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries;
using Oxide.Plugins;
using System;

namespace Oxide.Plugins
{
    [Info("BaseGuardian", "NexCore", "1.1.1")]
    [Description("Closes doors and tops up TCs, with crash detection and network drop checks.")]
    public class BaseGuardian : RustPlugin
    {
        private class BaseGuardianConfig
        {
            public bool EnableCrashCheck { get; set; } = true;
            public bool CloseDoorsOnCrash { get; set; } = true;
            public bool TopUpTCOnCrash { get; set; } = false;

            public bool EnableNetworkDropCheck { get; set; } = false;
            public string NetworkCheckHost { get; set; } = "https://www.google.com";
            public int PingFrequencySeconds { get; set; } = 600;
            public int MaxPingFailures { get; set; } = 3;
            public bool CloseDoorsOnNetDrop { get; set; } = true;
            public bool TopUpTCOnNetDrop { get; set; } = false;

            public float TCUpkeepHoursToTopup { get; set; } = 12f;
        }

        private class BaseGuardianData
        {
            public bool GracefulShutdown = true;
        }

        private BaseGuardianConfig config;
        private BaseGuardianData data;

        private const string PermDoors = "baseguardian.doors";
        private const string PermTC = "baseguardian.tc";

        private int consecutiveFailures;
        private Timer netCheckTimer;

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating a new configuration file...");
            config = new BaseGuardianConfig();
            SaveConfig();
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            config = Config.ReadObject<BaseGuardianConfig>();
            if (config == null)
            {
                PrintWarning("Configuration file is invalid; creating a new one.");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(config, true);
        }

        private void LoadData()
        {
            data = Interface.Oxide.DataFileSystem.ReadObject<BaseGuardianData>(Name);
            if (data == null) data = new BaseGuardianData();
        }

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, data);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoPermission"] = "You do not have permission to use this command.",
                ["ClosedDoors"] = "Closed {0} doors on the server.",
                ["ToppedCupboards"] = "Topped up {0} tool cupboards to 12 hours of upkeep.",
                ["NoCupboardsFound"] = "No valid tool cupboards were found to top up."
            }, this, "en");
        }

        private string Msg(string key, string userId = null) => lang.GetMessage(key, this, userId);

        private void Init()
        {
            permission.RegisterPermission(PermDoors, this);
            permission.RegisterPermission(PermTC, this);
            LoadData();
        }

        private void Unload()
        {
            data.GracefulShutdown = true;
            SaveData();
        }

        private void OnServerInitialized()
        {
            LoadData();
            if (config.EnableCrashCheck && !data.GracefulShutdown)
            {
                if (config.CloseDoorsOnCrash) CloseAllDoors();
                if (config.TopUpTCOnCrash) TopUpAllTCs();
            }
            data.GracefulShutdown = false;
            SaveData();

            if (config.EnableNetworkDropCheck)
            {
                StartNetworkMonitor();
            }
        }

        [ChatCommand("bg.doors")]
        [ConsoleCommand("bg.doors")]
        private void CmdCloseDoors(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, PermDoors))
            {
                SendReply(player, Msg("NoPermission", player.UserIDString));
                return;
            }
            CloseAllDoors(player);
        }

        private void CloseAllDoors(BasePlayer player = null)
        {
            int closedDoors = 0;
            foreach (var net in BaseNetworkable.serverEntities)
            {
                var entity = net as BaseEntity;
                if (entity == null) continue;
                string shortName = entity.ShortPrefabName?.ToLower() ?? "";
                if (shortName.Contains("door") || shortName.Contains("gate") || shortName.Contains("shutter") || shortName.Contains("hatch"))
                {
                    if (entity.HasFlag(BaseEntity.Flags.Open))
                    {
                        entity.SetFlag(BaseEntity.Flags.Open, false);
                        entity.SendNetworkUpdateImmediate();
                        closedDoors++;
                    }
                }
            }
            if (player != null) SendReply(player, string.Format(Msg("ClosedDoors", player.UserIDString), closedDoors));
            else Puts(string.Format(Msg("ClosedDoors"), closedDoors));
        }

        [ChatCommand("bg.tc")]
        [ConsoleCommand("bg.tc")]
        private void CmdTopUpTC(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, PermTC))
            {
                SendReply(player, Msg("NoPermission", player.UserIDString));
                return;
            }
            TopUpAllTCs(player);
        }

        private void TopUpAllTCs(BasePlayer player = null)
        {
            int cupboardsTopped = 0;
            foreach (var net in BaseNetworkable.serverEntities)
            {
                var tc = net as BuildingPrivlidge;
                if (tc == null) continue;

                float currentMinutes = tc.GetProtectedMinutes();
                if (currentMinutes <= 0f) continue;

                float currentHours = currentMinutes / 60f;
                float targetHours = config.TCUpkeepHoursToTopup;
                if (currentHours >= targetHours) continue;

                float neededHours = targetHours - currentHours;
                float neededSeconds = neededHours * 3600f;

                var dailyCosts = new List<ItemAmount>();
                tc.CalculateUpkeepCostAmounts(dailyCosts);

                float fraction = neededHours / 24f;
                foreach (var itemAmt in dailyCosts) itemAmt.amount *= fraction;
                GiveCostsToTCInventory(tc, dailyCosts);

                tc.PurchaseUpkeepTime(neededSeconds);

                float newCoverage = tc.GetProtectedMinutes() / 60f;
                if (newCoverage >= config.TCUpkeepHoursToTopup) cupboardsTopped++;
            }

            if (cupboardsTopped > 0)
            {
                if (player != null)
                    SendReply(player, string.Format(Msg("ToppedCupboards", player.UserIDString), cupboardsTopped));
                else
                    Puts(string.Format(Msg("ToppedCupboards"), cupboardsTopped));
            }
            else
            {
                if (player != null)
                    SendReply(player, Msg("NoCupboardsFound", player.UserIDString));
                else
                    Puts(Msg("NoCupboardsFound"));
            }
        }

        private void GiveCostsToTCInventory(BuildingPrivlidge tc, List<ItemAmount> costs)
        {
            if (tc.inventory == null) return;
            foreach (var itemAmt in costs)
            {
                if (itemAmt?.itemDef == null) continue;
                int quantity = Mathf.CeilToInt(itemAmt.amount);
                if (quantity <= 0) continue;

                var item = ItemManager.CreateByItemID(itemAmt.itemDef.itemid, quantity);
                if (item != null) tc.inventory.GiveItem(item);
            }
        }

        private void StartNetworkMonitor()
        {
            if (netCheckTimer != null && !netCheckTimer.Destroyed) netCheckTimer.Destroy();
            netCheckTimer = timer.Repeat(config.PingFrequencySeconds, 0, () => CheckNetwork());
        }

        private void CheckNetwork()
        {
            webrequest.EnqueueGet(
                config.NetworkCheckHost,
                (code, response) =>
                {
                    if (code == 200)
                    {
                        consecutiveFailures = 0;
                    }
                    else
                    {
                        consecutiveFailures++;
                        if (consecutiveFailures >= config.MaxPingFailures)
                        {
                            Puts($"Network drop detected after {consecutiveFailures} consecutive failures. Host {config.NetworkCheckHost}");

                            netCheckTimer?.Destroy();

                            if (config.CloseDoorsOnNetDrop) CloseAllDoors();
                            if (config.TopUpTCOnNetDrop) TopUpAllTCs();
                        }
                    }
                },
                this,
                null,
                10f
            );
        }
    }
}

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