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

FREE BlueprintOnly : 0.6.1 0.6.1

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

namespace Oxide.Plugins
{
    /// <summary>
    /// Blueprint Only Plugin
    /// Compatible with both Oxide and Carbon
    /// 
    /// Features:
    /// - Blueprint learning notifications (Multi-language support)
    /// - Research table usage restrictions
    /// - Workbench tech tree unlock restrictions
    /// 
    /// Permissions:
    /// - blueprintonly.notify.bypass: Bypass notifications
    /// - blueprintonly.research.use: Allow research table usage
    /// - blueprintonly.workbench.use: Allow workbench tech tree usage
    /// </summary>
    [Info("Blueprint Only", "MiaygawaYuu", "0.6.1")]
    [Description("Blueprint Only Plugin - Compatible with Oxide and Carbon")]
    public class BlueprintOnly : RustPlugin
    {
        #region Fields
        
        private readonly Dictionary<string, Dictionary<string, string>> _translations = new Dictionary<string, Dictionary<string, string>>();
        private readonly Dictionary<ulong, float> _lastWorkbenchBlockNotice = new Dictionary<ulong, float>();
        private bool _translationsLoaded = false;
        
        #endregion
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["BP Notify"] = "{0} learned {1}.",
                ["Workbench Block Notify"] = "The tech tree cannot be opened at the workbench.",
                ["ResearchTable Block Notify"] = "Research tables are not available."
            }, this);

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["BP Notify"] = "{0} さんが {1} をおぼえました。",
                ["Workbench Block Notify"] = "ワークベンチでのテックツリーのカイホウはできません。",
                ["ResearchTable Block Notify"] = "リサーチテーブルはつかえません。"
            }, this, "ja");
        }

        private void Init()
        {
            // Register permissions
            permission.RegisterPermission("blueprintonly.notify.bypass", this);
            permission.RegisterPermission("blueprintonly.research.use", this);
            permission.RegisterPermission("blueprintonly.workbench.use", this);
        }

        private void OnServerInitialized()
        {
            LoadTranslations();
        }

        #region Translation System

        /// <summary>
        /// Load translation data from Rust asset bundles
        /// </summary>
        private void LoadTranslations()
        {
            try
            {
                AssetBundleBackend assets = (AssetBundleBackend)FileSystem.Backend;
                Dictionary<string, AssetBundle> files = assets.files;

                foreach (var kvp in files)
                {
                    string path = kvp.Key;
                    AssetBundle bundle = kvp.Value;

                    if (!path.EndsWith(".json") || !path.StartsWith("assets/localization/"))
                        continue;

                    TextAsset textAsset = bundle.LoadAsset(path) as TextAsset;
                    if (textAsset == null)
                        continue;

                    int lastIndex = path.LastIndexOf('/');
                    int secondLastIndex = path.LastIndexOf('/', lastIndex - 1) + 1;
                    string language = path.Substring(secondLastIndex, lastIndex - secondLastIndex);

                    if (language.Equals("editor", System.StringComparison.OrdinalIgnoreCase))
                        continue;

                    if (!_translations.ContainsKey(language))
                    {
                        _translations[language] = new Dictionary<string, string>();
                    }

                    Dictionary<string, string> tokens = JsonConvert.DeserializeObject<Dictionary<string, string>>(textAsset.text);
                    if (tokens != null)
                    {
                        foreach (var token in tokens)
                        {
                            _translations[language][token.Key] = token.Value;
                        }
                    }
                }

                _translationsLoaded = true;
                Puts($"Translation system initialized: {_translations.Count} languages loaded");
            }
            catch (System.Exception ex)
            {
                PrintError($"Failed to load translations: {ex.Message}");
                _translationsLoaded = false;
            }
        }

        /// <summary>
        /// Get player's language setting
        /// </summary>
        private string GetPlayerLanguage(BasePlayer player)
        {
            return player?.net?.connection?.info?.GetString("global.language", "en") ?? "en";
        }

        /// <summary>
        /// Get translation for specified language and token
        /// </summary>
        private string GetTranslation(string language, string token)
        {
            if (!_translationsLoaded || string.IsNullOrEmpty(token))
                return null;

            if (_translations.TryGetValue(language, out Dictionary<string, string> tokens))
            {
                if (tokens.TryGetValue(token, out string translation))
                {
                    return translation;
                }
            }

            return null;
        }

        /// <summary>
        /// Get translated item name
        /// </summary>
        private string GetItemTranslation(BasePlayer player, Item item)
        {
            if (item?.blueprintTargetDef?.displayName == null)
                return "Unknown Item";

            string language = GetPlayerLanguage(player);
            string token = item.blueprintTargetDef.displayName.token;
            
            // Get translation in player's language
            string translation = GetTranslation(language, token);
            
            // Fallback to English name if translation not found
            return translation ?? item.blueprintTargetDef.displayName.english;
        }

        #endregion

        // Hook: Block research table usage
        object CanResearchItem(BasePlayer player, Item targetItem)
        {
            if (!permission.UserHasPermission(player.UserIDString, "blueprintonly.research.use"))
            {
                string _message = lang.GetMessage("ResearchTable Block Notify", this, player.UserIDString);
                PrintToChat(player,_message);
                return false;
            }else{
                return null;
            }
        }

        private bool CanUseWorkbenchTechTree(BasePlayer player)
        {
            if (player == null || permission.UserHasPermission(player.UserIDString, "blueprintonly.workbench.use"))
            {
                return true;
            }

            float now = Time.realtimeSinceStartup;
            if (!_lastWorkbenchBlockNotice.TryGetValue(player.userID, out float lastNotice) || now - lastNotice > 1f)
            {
                _lastWorkbenchBlockNotice[player.userID] = now;

                string _message = lang.GetMessage("Workbench Block Notify", this, player.UserIDString);
                PrintToChat(player,_message);
            }

            return false;
        }

        // Hook: Block workbench tech tree availability checks
        object CanUnlockTechTreeNode(BasePlayer player, TechTreeData.NodeInstance node, TechTreeData techTree)
        {
            return CanUseWorkbenchTechTree(player) ? null : (object)false;
        }

        // Hook: Block the actual workbench tech tree unlock RPC
        object OnTechTreeNodeUnlock(Workbench workbench, TechTreeData.NodeInstance node, BasePlayer player)
        {
            return CanUseWorkbenchTechTree(player) ? null : (object)true;
        }

        // Hook: Blueprint learning notification
        object OnItemAction(Item item, string action, BasePlayer player)
        {
            if (action == "study")
            {                
                if (!player.PersistantPlayerInfo.unlockedItems.Contains(item.blueprintTargetDef.itemid))
                {
                    if (!permission.UserHasPermission(player.UserIDString, "blueprintonly.notify.bypass"))
                    {
                        // Send translated message to each online player
                        foreach (BasePlayer onlinePlayer in BasePlayer.activePlayerList)
                        {
                            string _message = lang.GetMessage("BP Notify", this, onlinePlayer.UserIDString);
                            string itemName = GetItemTranslation(onlinePlayer, item);
                            string message = string.Format(_message, player.displayName, itemName);
                            PrintToChat(onlinePlayer, message);
                        }
                    }
                }
            }
            return null;
        }
    }
}

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