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

FREE BlueprintUnlockManager : 2.0.0 2.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;

namespace Oxide.Plugins
{
    [Info("BlueprintUnlockManager", "jerky", "2.0.0")]
    [Description("This plugin manages blueprint unlocks in Rust by limiting the number of learners per item and enforcing a queue system to rotate blueprint ownership.")]
    public class BlueprintUnlockManager : RustPlugin
    {
        private const string ConfigFileName = "BlueprintUnlockManager";
        private const string DataFileName = "BlueprintUnlockManagerQueue";
        private ConfigData config;
        private Dictionary<string, Queue<ulong>> itemQueues = new Dictionary<string, Queue<ulong>>();

        #region Config Classes
        public class ItemConfig
        {
            public string ShortName { get; set; }
            public int MaxLearners { get; set; }
        }

        public class ConfigData
        {
            public List<ItemConfig> Items { get; set; } = new List<ItemConfig>();
        }
        #endregion

        #region Oxide Hooks
        protected override void LoadDefaultConfig()
        {
            ConfigData defaultConfig = new ConfigData
            {
                Items = new List<ItemConfig>
                {
                    new ItemConfig { ShortName = "rifle.ak", MaxLearners = 2 },
                    new ItemConfig { ShortName = "smg.mp5", MaxLearners = 3 }
                }
            };
            Config.WriteObject(defaultConfig, true);
            PrintWarning("Default config generated.");
        }

        private void Init()
        {
            LoadConfigData();
            LoadQueueData();
            RegisterLang();

            // Check blueprint ownership for all online players at plugin initialization
            foreach (var player in BasePlayer.activePlayerList)
            {
                foreach (var item in config.Items)
                {
                    var shortName = item.ShortName;
                    var queue = GetQueue(shortName);

                    ItemDefinition def = ItemManager.FindItemDefinition(shortName);
                    if (def == null) continue;

                    if (HasPlayerBlueprint(player, def))
                    {
                        if (!queue.Contains(player.userID))
                        {
                            RemovePlayerBlueprint(player, def);
                            PrintToChatLang(player, "LostBlueprintQueueEnforcement", shortName);
                        }
                    }
                }
            }
        }

        private void RegisterLang()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["LostBlueprintQueueEnforcement"] = "You have lost the blueprint for {0} (queue enforcement).",
                ["LostBlueprintQueueRotation"] = "You have lost the blueprint for {0} (queue rotation).",
                ["AddedToBlueprintQueue"] = "You have been added to the blueprint queue for {0}.",
                ["RemovedFromBlueprintQueue"] = "You have been removed from the blueprint queue for {0}.",
                ["UsageLearnBP"] = "Usage: /learnbp <shortname>",
                ["UsageUnlearnBP"] = "Usage: /unlearnbp <shortname>"
            }, this, "en");

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["LostBlueprintQueueEnforcement"] = "{0} のBlueprintの所有資格を失いました。",
                ["LostBlueprintQueueRotation"] = "{0} のBlueprintの所有資格を失いました。",
                ["AddedToBlueprintQueue"] = "{0} のBlueprintの所有資格を得ました。",
                ["RemovedFromBlueprintQueue"] = "{0} のBlueprintキューから削除されました。",
                ["UsageLearnBP"] = "使い方: /learnbp <shortname>",
                ["UsageUnlearnBP"] = "使い方: /unlearnbp <shortname>"
            }, this, "ja");
        }

        private void PrintToChatLang(BasePlayer player, string key, params object[] args)
        {
            string message = string.Format(lang.GetMessage(key, this, player.UserIDString), args);
            PrintToChat(player, message);
        }

        private void OnServerSave()
        {
            SaveQueueData();
        }

        private void Unload()
        {
            SaveQueueData();
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            foreach (var item in config.Items)
            {
                var shortName = item.ShortName;
                var queue = GetQueue(shortName);

                ItemDefinition def = ItemManager.FindItemDefinition(shortName);
                if (def == null) continue;

                if (HasPlayerBlueprint(player, def))
                {
                    if (!queue.Contains(player.userID))
                    {
                        RemovePlayerBlueprint(player, def);
                        PrintToChatLang(player, "LostBlueprintQueueEnforcement", shortName);
                    }
                }
            }
        }
        #endregion

        #region Queue Management
        private Queue<ulong> GetQueue(string shortName)
        {
            if (!itemQueues.ContainsKey(shortName))
                itemQueues[shortName] = new Queue<ulong>();
            return itemQueues[shortName];
        }

        // Blueprintを習得した時に呼び出す(OnItemActionで使用)
        private void TryAddToQueue(BasePlayer player, string shortName)
        {
            var itemConfig = config.Items.FirstOrDefault(i => i.ShortName == shortName);
            if (itemConfig == null) return;

            var queue = GetQueue(shortName);

            if (queue.Contains(player.userID))
            {
                // 既にキューにいる場合は何もしない
                return;
            }

            if (queue.Count >= itemConfig.MaxLearners)
            {
                // キュー満員なら先頭のプレイヤーを追い出す
                ulong removedUserID = queue.Dequeue();
                var removedPlayer = BasePlayer.FindByID(removedUserID);
                ItemDefinition def = ItemManager.FindItemDefinition(shortName);
                if (removedPlayer != null && def != null && HasPlayerBlueprint(removedPlayer, def))
                {
                    RemovePlayerBlueprint(removedPlayer, def);
                    PrintToChatLang(removedPlayer, "LostBlueprintQueueRotation", shortName);
                }
            }

            // 新しいプレイヤーをキューに追加
            queue.Enqueue(player.userID);
            PrintToChatLang(player, "AddedToBlueprintQueue", shortName);
            SaveQueueData();
        }

        // Blueprintを失った時に呼び出す(コマンドやイベントで使用可能)
        private void RemoveFromQueue(BasePlayer player, string shortName)
        {
            var queue = GetQueue(shortName);
            if (queue.Contains(player.userID))
            {
                var newQueue = new Queue<ulong>(queue.Where(id => id != player.userID));
                itemQueues[shortName] = newQueue;
                PrintToChatLang(player, "RemovedFromBlueprintQueue", shortName);
            }
        }
        #endregion

        #region Blueprint Helper
        private bool HasPlayerBlueprint(BasePlayer player, ItemDefinition def)
        {
            return player.PersistantPlayerInfo.unlockedItems.Contains(def.itemid);
        }

        private void RemovePlayerBlueprint(BasePlayer player, ItemDefinition def)
        {
            var persistantPlayerInfo = player.PersistantPlayerInfo;
            if (persistantPlayerInfo.unlockedItems.Contains(def.itemid))
            {
                persistantPlayerInfo.unlockedItems.Remove(def.itemid);
                player.PersistantPlayerInfo = persistantPlayerInfo;
                player.SendNetworkUpdateImmediate();
            }
        }
        #endregion

        #region Config/Data Load/Save
        private void LoadConfigData()
        {
            try
            {
                config = Config.ReadObject<ConfigData>();
                if (config?.Items == null || config.Items.Count == 0)
                {
                    PrintWarning("Config is empty, generating default config.");
                    LoadDefaultConfig();
                    config = Config.ReadObject<ConfigData>();
                }
            }
            catch
            {
                PrintWarning("Config error, generating default config.");
                LoadDefaultConfig();
                config = Config.ReadObject<ConfigData>();
            }
        }

        private void LoadQueueData()
        {
            var data = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, List<ulong>>>(DataFileName);
            itemQueues.Clear();
            foreach (var kvp in data)
            {
                itemQueues[kvp.Key] = new Queue<ulong>(kvp.Value);
            }
        }

        private void SaveQueueData()
        {
            var data = itemQueues.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToList());
            Interface.Oxide.DataFileSystem.WriteObject(DataFileName, data);
        }
        #endregion

        #region ItemAction Hook
        object OnItemAction(Item item, string action, BasePlayer player)
        {
            if (action == "study" && item.IsBlueprint())
            {
                ItemDefinition blueprintTargetDef = item.blueprintTargetDef;
                string shortName = blueprintTargetDef.shortname;

                // 設定対象アイテムのみ処理
                var itemConfig = config.Items.FirstOrDefault(i => i.ShortName == shortName);
                if (itemConfig == null)
                    return null;

                TryAddToQueue(player, shortName);
            }

            return null;
        }
        #endregion

        #region Chat Command Example
        [ChatCommand("learnbp")]
        private void CmdLearnBP(BasePlayer player, string command, string[] args)
        {
            if (args.Length != 1)
            {
                PrintToChatLang(player, "UsageLearnBP");
                return;
            }
            var shortName = args[0];
            TryAddToQueue(player, shortName);
        }

        [ChatCommand("unlearnbp")]
        private void CmdUnlearnBP(BasePlayer player, string command, string[] args)
        {
            if (args.Length != 1)
            {
                PrintToChatLang(player, "UsageUnlearnBP");
                return;
            }
            var shortName = args[0];
            RemoveFromQueue(player, shortName);
        }
        #endregion
    }
}

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