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

FREE NWGConfigEditor : 2.0.0 2.0.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("NWGConfigEditor", "NWG Team", "2.0.0")]
    [Description("In-game deep config editor supporting nested objects and lists.")]
    public class NWGConfigEditor : RustPlugin {
        public static class UIConstants {
            public const string MainColor = "0.718 0.816 0.573 1";
            // Sage Green
            public const string SecondaryColor = "0.851 0.325 0.31 1";
            // Red/Rust
            public const string AccentColor = "1 0.647 0 1";
            // Orange
            public const string PanelColor = "0.15 0.15 0.15 0.98";
            // Dark Panel
            public const string HeaderColor = "0.1 0.1 0.1 1";
            public const string TextColor = "0.867 0.867 0.867 1";
            public const string Row1Color = "0.2 0.2 0.2 0.9";
            public const string Row2Color = "0.18 0.18 0.18 0.9";
        }
#region Constants
        private const string PermUse = "nwgconfigeditor.use";
        private const string PanelEditor = "NWGCfg_Editor";
        private const string PanelInput = "NWGCfg_Input";
        private const string PanelMain = "NWGCfg_Main";
#endregion
#region Session State
        private class EditorSession {
            public string PluginName;
            public JObject Config;
            public string NavigationPath = "";
            // e.g. "Categories.0.Items"
            public int Page = 1;
            public string EditingKey;
        }
        private readonly Dictionary<ulong, EditorSession> _sessions = new Dictionary<ulong, EditorSession>();
#endregion
#region Lifecycle
        private void Init() => permission.RegisterPermission(PermUse, this);
        private void Unload() {
            foreach (var p in BasePlayer.activePlayerList) CloseAll(p);
        }
#endregion
#region Commands
        [ChatCommand("config")]
        private void CmdConfig(BasePlayer player) {
            if (HasPerm(player)) ShowPluginList(player, 1);
        }
#endregion
#region UI: Plugin List
        private void ShowPluginList(BasePlayer player, int page) {
            CloseAll(player);
            var configs = Directory.GetFiles(Interface.Oxide.ConfigDirectory, "NWG*.json").Select(Path.GetFileNameWithoutExtension).ToList();
            var container = new CuiElementContainer();
            var root = container.Add(new CuiPanel {
                Image = {
                    Color = UIConstants.PanelColor
                }
                , RectTransform = {
                    AnchorMin = "0.2 0.1", AnchorMax = "0.8 0.9"
                }
                , CursorEnabled = true
            }
            , "Overlay", PanelMain);
            container.Add(new CuiLabel {
                Text = {
                    Text = GetMessage(Lang.TitleMain, player.UserIDString), FontSize = 20, Align = TextAnchor.MiddleCenter, Color = UIConstants.MainColor
                }
                , RectTransform = {
                    AnchorMin = "0 0.9", AnchorMax = "1 1"
                }
            }
            , root);
            for (int i = 0; i < configs.Count; i++) {
                float y = 0.85f - (i * 0.06f);
                var name = configs[i];
                container.Add(new CuiButton {
                    Button = {
                        Command = $"nwgcfg.open {name}", Color = "0.2 0.4 0.6 0.8"
                    }
                    , RectTransform = {
                        AnchorMin = $"0.05 {y-0.05f}", AnchorMax = $"0.95 {y}"
                    }
                    , Text = {
                        Text = name.Replace("NWG", "NWG "), Align = TextAnchor.MiddleLeft
                    }
                }
                , root);
            }
            CuiHelper.AddUi(player, container);
        }
#endregion
#region UI: Deep Editor
        private void ShowEditor(BasePlayer player) {
            var session = GetSession(player);
            if (session == null) return;
            CloseAll(player);
            var container = new CuiElementContainer();
            var root = container.Add(new CuiPanel {
                Image = {
                    Color = UIConstants.PanelColor
                }
                , RectTransform = {
                    AnchorMin = "0.1 0.05", AnchorMax = "0.9 0.95"
                }
                , CursorEnabled = true
            }
            , "Overlay", PanelEditor);
            // Header
            container.Add(new CuiPanel {
                Image = {
                    Color = UIConstants.HeaderColor
                }
                , RectTransform = {
                    AnchorMin = "0 0.93", AnchorMax = "1 1"
                }
            }
            , root);
            container.Add(new CuiLabel {
                Text = {
                    Text = GetMessage(Lang.TitleEditing, player.UserIDString, session.PluginName, session.NavigationPath), FontSize = 14, Color = UIConstants.MainColor
                }
                , RectTransform = {
                    AnchorMin = "0.1 0", AnchorMax = "0.7 1"
                }
            }
            , root);
            container.Add(new CuiButton {
                Button = {
                    Command = "nwgcfg.up", Color = "0.3 0.3 0.3 0.8"
                }
                , RectTransform = {
                    AnchorMin = "0.01 0.1", AnchorMax = "0.08 0.9"
                }
                , Text = {
                    Text = GetMessage(Lang.BtnUp, player.UserIDString)
                }
            }
            , root + "_Header");
            container.Add(new CuiButton {
                Button = {
                    Command = "nwgcfg.save", Color = "0.2 0.6 0.2 0.8"
                }
                , RectTransform = {
                    AnchorMin = "0.8 0.1", AnchorMax = "0.9 0.9"
                }
                , Text = {
                    Text = GetMessage(Lang.BtnSave, player.UserIDString)
                }
            }
            , root + "_Header");
            container.Add(new CuiButton {
                Button = {
                    Command = "nwgcfg.close", Color = UIConstants.SecondaryColor
                }
                , RectTransform = {
                    AnchorMin = "0.92 0.1", AnchorMax = "0.98 0.9"
                }
                , Text = {
                    Text = GetMessage(Lang.BtnClose, player.UserIDString)
                }
            }
            , root + "_Header");
            // Content
            var currentToken = GetPathToken(session.Config, session.NavigationPath);
            if (currentToken is JObject obj) {
                int i = 0;
                foreach (var prop in obj.Properties()) {
                    AddRow(container, root, prop.Name, prop.Value, i++);
                }
            }
            else if (currentToken is JArray arr) {
                for (int i = 0; i < arr.Count; i++) {
                    AddRow(container, root, $"[{i}]", arr[i], i);
                }
            }
            CuiHelper.AddUi(player, container);
        }
        private void AddRow(CuiElementContainer container, string parent, string key, JToken val, int index) {
            float yMax = 0.92f - (index * 0.055f);
            float yMin = yMax - 0.05f;
            var row = container.Add(new CuiPanel {
                Image = {
                    Color = index % 2 == 0 ? UIConstants.Row1Color : UIConstants.Row2Color
                }
                , RectTransform = {
                    AnchorMin = $"0.01 {yMin}", AnchorMax = $"0.99 {yMax}"
                }
            }
            , parent);
            container.Add(new CuiLabel {
                Text = {
                    Text = key, FontSize = 11, Align = TextAnchor.MiddleLeft
                }
                , RectTransform = {
                    AnchorMin = "0.02 0", AnchorMax = "0.4 1"
                }
            }
            , row);
            if (val is JObject || val is JArray) {
                container.Add(new CuiButton {
                    Button = {
                        Command = $"nwgcfg.nav {key}", Color = "0.3 0.4 0.5 0.8"
                    }
                    , RectTransform = {
                        AnchorMin = "0.85 0.1", AnchorMax = "0.98 0.9"
                    }
                    , Text = {
                        Text = GetMessage(Lang.BtnOpen, null)
                    }
                }
                , row);
            }
            else if (val.Type == JTokenType.Boolean) {
                bool b = val.Value<bool>();
                container.Add(new CuiButton {
                    Button = {
                        Command = $"nwgcfg.toggle {key}", Color = b ? "0.2 0.5 0.2 1" : "0.5 0.2 0.2 1"
                    }
                    , RectTransform = {
                        AnchorMin = "0.7 0.1", AnchorMax = "0.85 0.9"
                    }
                    , Text = {
                        Text = b.ToString().ToUpper()
                    }
                }
                , row);
            }
            else {
                container.Add(new CuiLabel {
                    Text = {
                        Text = val.ToString(), FontSize = 11, Align = TextAnchor.MiddleRight
                    }
                    , RectTransform = {
                        AnchorMin = "0.4 0", AnchorMax = "0.8 1"
                    }
                }
                , row);
                container.Add(new CuiButton {
                    Button = {
                        Command = $"nwgcfg.editfield {key}", Color = "0.2 0.3 0.4 0.8"
                    }
                    , RectTransform = {
                        AnchorMin = "0.85 0.1", AnchorMax = "0.98 0.9"
                    }
                    , Text = {
                        Text = GetMessage(Lang.BtnEdit, null)
                    }
                }
                , row);
            }
        }
#endregion
#region Actions
        [ConsoleCommand("nwgcfg.open")]
        private void CCOpen(ConsoleSystem.Arg a) {
            var p = a.Player();
            if (p == null || !HasPerm(p)) return;
            var name = a.GetString(0);
            var path = Path.Combine(Interface.Oxide.ConfigDirectory, name + ".json");
            if (!File.Exists(path)) return;
            _sessions[p.userID] = new EditorSession {
                PluginName = name, Config = JObject.Parse(File.ReadAllText(path))
            }
            ;
            ShowEditor(p);
        }
        [ConsoleCommand("nwgcfg.nav")]
        private void CCNav(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null) return;
            string key = a.GetString(0);
            s.NavigationPath = string.IsNullOrEmpty(s.NavigationPath) ? key : $"{s.NavigationPath}.{key}";
            ShowEditor(a.Player());
        }
        [ConsoleCommand("nwgcfg.up")]
        private void CCUp(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null) return;
            if (string.IsNullOrEmpty(s.NavigationPath)) {
                ShowPluginList(a.Player(), 1);
                return;
            }
            int lastDot = s.NavigationPath.LastIndexOf('.');
            s.NavigationPath = lastDot > 0 ? s.NavigationPath.Substring(0, lastDot) : "";
            ShowEditor(a.Player());
        }
        [ConsoleCommand("nwgcfg.save")]
        private void CCSave(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null) return;
            string configPath = Path.Combine(Interface.Oxide.ConfigDirectory, s.PluginName + ".json");
            // Backup before save
            string backupPath = Path.Combine(Interface.Oxide.ConfigDirectory, s.PluginName + ".json.bak");
            if (File.Exists(configPath)) File.Copy(configPath, backupPath, true);
            File.WriteAllText(configPath, s.Config.ToString(Formatting.Indented));
            Server.Command($"oxide.reload {s.PluginName}");
            a.Player().ChatMessage(GetMessage(Lang.SavedMessage, a.Player().UserIDString, s.PluginName));
        }
        [ConsoleCommand("nwgcfg.close")]
        private void CCClose(ConsoleSystem.Arg a) {
            CloseAll(a.Player());
            _sessions.Remove(a.Player().userID);
        }
        [ConsoleCommand("nwgcfg.toggle")]
        private void CCToggle(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null) return;
            string key = a.GetString(0);
            var fullPath = string.IsNullOrEmpty(s.NavigationPath) ? key : $"{s.NavigationPath}.{key}";
            var token = s.Config.SelectToken(fullPath);
            if (token != null && token.Type == JTokenType.Boolean) {
                SetToken(s.Config, fullPath, !token.Value<bool>());
                ShowEditor(a.Player());
            }
        }
        [ConsoleCommand("nwgcfg.editfield")]
        private void CCEditField(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null) return;
            s.EditingKey = a.GetString(0);
            ShowInput(a.Player());
        }
        [ConsoleCommand("nwgcfg.setvalue")]
        private void CCSetValue(ConsoleSystem.Arg a) {
            var s = GetSession(a.Player());
            if (s == null || s.EditingKey == null) return;
            var fullPath = string.IsNullOrEmpty(s.NavigationPath) ? s.EditingKey : $"{s.NavigationPath}.{s.EditingKey}";
            var current = s.Config.SelectToken(fullPath);
            if (current == null) return;
            string val = a.GetString(0);
            JToken newToken = current.Type == JTokenType.Integer ? (JToken)long.Parse(val) : (current.Type == JTokenType.Float ? (JToken)float.Parse(val) : (JToken)val);
            SetToken(s.Config, fullPath, newToken);
            CuiHelper.DestroyUi(a.Player(), PanelInput);
            ShowEditor(a.Player());
        }
#endregion
#region Helpers
        private bool HasPerm(BasePlayer p) => p.IsAdmin || permission.UserHasPermission(p.UserIDString, PermUse);
        private void CloseAll(BasePlayer p) {
            CuiHelper.DestroyUi(p, PanelMain);
            CuiHelper.DestroyUi(p, PanelEditor);
            CuiHelper.DestroyUi(p, PanelInput);
        }
        private EditorSession GetSession(BasePlayer p) => p != null && _sessions.TryGetValue(p.userID, out var s) ? s : null;
        private JToken GetPathToken(JObject root, string path) => string.IsNullOrEmpty(path) ? root : root.SelectToken(path);
        private void SetToken(JObject root, string path, JToken val) {
            var token = root.SelectToken(path);
            if (token != null) token.Replace(val);
        }
        private void ShowInput(BasePlayer p) {
            var container = new CuiElementContainer();
            var root = container.Add(new CuiPanel {
                Image = {
                    Color = "0 0 0 0.8"
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1"
                }
                , CursorEnabled = true
            }
            , "Overlay", PanelInput);
            container.Add(new CuiPanel {
                Image = {
                    Color = UIConstants.PanelColor
                }
                , RectTransform = {
                    AnchorMin = "0.3 0.4", AnchorMax = "0.7 0.6"
                }
            }
            , root);
            container.Add(new CuiLabel {
                Text = {
                    Text = GetMessage(Lang.InputPrompt, p.UserIDString), Align = TextAnchor.MiddleCenter
                }
                , RectTransform = {
                    AnchorMin = "0.3 0.55", AnchorMax = "0.7 0.6"
                }
            }
            , root);
            container.Add(new CuiElement {
                Parent = root, Components = {
                    new CuiInputFieldComponent {
                        Command = "nwgcfg.setvalue", Align = TextAnchor.MiddleCenter
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.35 0.45", AnchorMax = "0.65 0.52"
                    }
                }
            }
            );
            CuiHelper.AddUi(p, container);
        }
#endregion
#region Localization
        private class Lang {
            public const string NoPermission = "NoPermission";
            public const string TitleMain = "TitleMain";
            public const string TitleEditing = "TitleEditing";
            public const string BtnUp = "BtnUp";
            public const string BtnSave = "BtnSave";
            public const string BtnClose = "BtnClose";
            public const string BtnOpen = "BtnOpen";
            public const string BtnEdit = "BtnEdit";
            public const string SavedMessage = "SavedMessage";
            public const string InputPrompt = "InputPrompt";
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                [Lang.NoPermission]
                = "No permission.", [Lang.TitleMain] = "NWG CONFIG FILES", [Lang.TitleEditing] = "EDITING: {0} > {1}", [Lang.BtnUp] = "UP", [Lang.BtnSave] = "SAVE", [Lang.BtnClose] = "✕", [Lang.BtnOpen] = "OPEN >", [Lang.BtnEdit] = "EDIT", [Lang.SavedMessage] = "Saved and reloaded {0} (Backup created)", [Lang.InputPrompt] = "ENTER NEW VALUE:"
            }
            , this);
        }
        private string GetMessage(string key, string userId, params object[] args) => string.Format(lang.GetMessage(key, this, userId), args);
#endregion
    }
}

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