• Хостинг игровых серверов

    Максимальная производительность для ваших игровых серверов!

    Заказать сейчас

GPT-4 Turbo грядки

Нейросеть GPT-4 Turbo доступна только «Prime» пользователям.
Если в вашем плагине для игры Rust не отображается список доступных перков при открытии /pmenu, это может быть связано с несколькими причинами. Давайте рассмотрим основные шаги, которые помогут вам диагностировать и исправить эту проблему:

### 1. Проверка конфигурации
Убедитесь, что ваш плагин правильно загружает конфигурацию и что в ней есть доступные перки. Если конфигурация не загружается или загружается некорректно, перки не будут отображаться.

### 2. Проверка кода, отвечающего за отображение меню
Убедитесь, что код, отвечающий за отображение меню с перками, исправен и корректно работает с загруженным списком перков. Возможно, в логике отображения меню есть ошибка, из-за которой перки не показываются.

### 3. Проверка логов на наличие ошибок
Проверьте логи сервера на наличие ошибок, связанных с вашим плагином. Ошибки в коде или проблемы с загрузкой ресурсов могут быть зарегистрированы в логах, что поможет вам найти причину проблемы.

### 4. Обратите внимание на версию игры и API плагинов
Удостоверьтесь, что ваш плагин совместим с текущей версией игры и используемыми библиотеками или API. Иногда обновления игры требуют обновления плагинов.

### 5. Проверка прав доступа
Убедитесь, что у игроков, пытающихся открыть меню перков, есть необходимые права доступа. Если у игрока нет прав для просмотра перков, меню может не отображаться.

### Пример кода для отладки
Добавьте в код плагина логи для отладки, чтобы убедиться, что конфигурация загружается, и список перков не пустой. Например, вы можете добавить что-то вроде:

C#:
Puts("Загрузка конфигурации перков…");
if (config.Perks == null || config.Perks.Count == 0)
{
    Puts("Список перков пуст или не загружен!");
}
else
{
    Puts($"Загружено перков: {config.Perks.Count}");
    foreach (var perk in config.Perks)
    {
        Puts($"Перк: {perk.Name}");
    }
}

Где config - это ваш объект конфигурации, содержащий список перков. Этот код поможет вам понять, правильно ли загружаются данные и не пуст ли список перков при запуске плагина.

Если проблема продолжает возникать даже после выполнения всех вышеупомянутых шагов, возможно, вам придется более тщательно изучить логику отображения пользовательского интерфейса вашего плагина и удостовериться, что все обработчики событий и команды корректно реализованы и зарегистрированы.
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
// Для простоты примера привилегии будем хранить в списке
private List<string> purchasedPerks = new List<string>();

// Инициализация
void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

// Обработка команды /pmenu
void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

// Показать меню привилегий
private void ShowPerksMenu(BasePlayer player)
{
// Удаляем предыдущее меню, если оно есть
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

// Пример добавления кнопки привилегии
// Следует добавить проверку на уже купленные привилегии
if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

CuiHelper.AddUi(player, elements);
}

// Обработчик покупки привилегии
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

// Здесь должна быть логика проверки и списания средств с баланса игрока
// Например, проверить достаточно ли у игрока монет и списать их

purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
}
}
Добавь сюда кнопку закрытия меню и свяжи плагин с экономикой что бы при покупки привелегии использовался баланс из плагина экономики
 
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
// Для простоты примера привилегии будем хранить в списке
private List<string> purchasedPerks = new List<string>();

// Инициализация
void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

// Обработка команды /pmenu
void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

// Показать меню привилегий
private void ShowPerksMenu(BasePlayer player)
{
// Удаляем предыдущее меню, если оно есть
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

// Пример добавления кнопки привилегии
// Следует добавить проверку на уже купленные привилегии
if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

CuiHelper.AddUi(player, elements);
}

// Обработчик покупки привилегии
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

// Здесь должна быть логика проверки и списания средств с баланса игрока
// Например, проверить достаточно ли у игрока монет и списать их

purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
}
}
Добавь сюда кнопку закрытия меню и свяжи плагин с экономикой что бы при покупки привелегии использовался баланс из плагина экономики
В вашем коде для добавления кнопки закрытия меню и интеграции с плагином экономики необходимо выполнить несколько шагов. Давайте начнем с добавления кнопки закрытия меню.

### Добавление кнопки закрытия

Чтобы добавить кнопку закрытия, вам нужно расширить ваш CuiElementContainer в методе ShowPerksMenu(BasePlayer player):

C#:
// Кнопка закрытия меню
elements.Add(new CuiButton
{
    Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
    RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
    Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

Не забудьте добавить соответствующую обработку команды UI_Destroy для закрытия UI:

C#:
[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
    var player = arg.Player();
    if (player != null)
    {
        CuiHelper.DestroyUi(player, "PerksMenu");
    }
}

### Интеграция с экономикой

Чтобы интегрировать покупку привилегий с плагином экономики, вам нужно будет добавить проверку и списание средств с баланса игрока. Предполагая, что плагин экономики имеет API для работы с балансом, код может выглядеть примерно так:

1. В начале файла добавьте ссылку на плагин экономики:

C#:
[PluginReference]
Plugin Economics;

2. Модифицируйте метод BuyPerk для интеграции с экономикой:

C#:
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
    if (args.Length == 0) return;

    string perkName = args[0];
    if (purchasedPerks.Contains(perkName))
    {
        SendReply(player, "You already have this perk.");
        return;
    }

    // Примерная стоимость привилегии
    int perkCost = 100; // Задайте стоимость

    // Проверяем, достаточно ли средств у игрока
    var balance = Economics.CallHook("Balance", player.userID);
    if (balance is double && (double)balance >= perkCost)
    {
        // Списание средств
        Economics.CallHook("Withdraw", player.userID, (double)perkCost);
        purchasedPerks.Add(perkName);
        SendReply(player, $"You have purchased the {perkName} perk.");
    }
    else
    {
        SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
    }
}

Учтите, что код предполагает наличие методов Balance и Withdraw в API плагина экономики, которые возвращают текущий баланс игрока и списывают средства соответственно. Проверьте документацию вашего плагина экономики на наличие этих или аналогичных методов и их правильное использование.

Эти изменения позволят вам добавить кнопку закрытия в пользовательский интерфейс и интегрировать покупку привилегий с системой экономики вашего сервера Rust.
 
В вашем коде для добавления кнопки закрытия меню и интеграции с плагином экономики необходимо выполнить несколько шагов. Давайте начнем с добавления кнопки закрытия меню.

### Добавление кнопки закрытия

Чтобы добавить кнопку закрытия, вам нужно расширить ваш CuiElementContainer в методе ShowPerksMenu(BasePlayer player):

C#:
// Кнопка закрытия меню
elements.Add(new CuiButton
{
    Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
    RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
    Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

Не забудьте добавить соответствующую обработку команды UI_Destroy для закрытия UI:

C#:
[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
    var player = arg.Player();
    if (player != null)
    {
        CuiHelper.DestroyUi(player, "PerksMenu");
    }
}

### Интеграция с экономикой

Чтобы интегрировать покупку привилегий с плагином экономики, вам нужно будет добавить проверку и списание средств с баланса игрока. Предполагая, что плагин экономики имеет API для работы с балансом, код может выглядеть примерно так:

1. В начале файла добавьте ссылку на плагин экономики:

C#:
[PluginReference]
Plugin Economics;

2. Модифицируйте метод BuyPerk для интеграции с экономикой:

C#:
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
    if (args.Length == 0) return;

    string perkName = args[0];
    if (purchasedPerks.Contains(perkName))
    {
        SendReply(player, "You already have this perk.");
        return;
    }

    // Примерная стоимость привилегии
    int perkCost = 100; // Задайте стоимость

    // Проверяем, достаточно ли средств у игрока
    var balance = Economics.CallHook("Balance", player.userID);
    if (balance is double && (double)balance >= perkCost)
    {
        // Списание средств
        Economics.CallHook("Withdraw", player.userID, (double)perkCost);
        purchasedPerks.Add(perkName);
        SendReply(player, $"You have purchased the {perkName} perk.");
    }
    else
    {
        SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
    }
}

Учтите, что код предполагает наличие методов Balance и Withdraw в API плагина экономики, которые возвращают текущий баланс игрока и списывают средства соответственно. Проверьте документацию вашего плагина экономики на наличие этих или аналогичных методов и их правильное использование.

Эти изменения позволят вам добавить кнопку закрытия в пользовательский интерфейс и интегрировать покупку привилегий с системой экономики вашего сервера Rust.
объедене это все
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
// Для простоты примера привилегии будем хранить в списке
private List<string> purchasedPerks = new List<string>();

// Инициализация
void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

// Обработка команды /pmenu
void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

// Показать меню привилегий
private void ShowPerksMenu(BasePlayer player)
{
// Удаляем предыдущее меню, если оно есть
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

// Пример добавления кнопки привилегии
// Следует добавить проверку на уже купленные привилегии
if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

CuiHelper.AddUi(player, elements);
}

// Обработчик покупки привилегии
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

// Здесь должна быть логика проверки и списания средств с баланса игрока
// Например, проверить достаточно ли у игрока монет и списать их

purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
}
}
 
объедене это все
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
// Для простоты примера привилегии будем хранить в списке
private List<string> purchasedPerks = new List<string>();

// Инициализация
void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

// Обработка команды /pmenu
void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

// Показать меню привилегий
private void ShowPerksMenu(BasePlayer player)
{
// Удаляем предыдущее меню, если оно есть
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

// Пример добавления кнопки привилегии
// Следует добавить проверку на уже купленные привилегии
if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

CuiHelper.AddUi(player, elements);
}

// Обработчик покупки привилегии
[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

// Здесь должна быть логика проверки и списания средств с баланса игрока
// Например, проверить достаточно ли у игрока монет и списать их

purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
}
}
Чтобы объединить предложенные изменения, необходимо внедрить логику проверки и списания средств с баланса игрока при покупке привилегии, а также добавить кнопку закрытия меню. Вот ваш код с необходимыми изменениями:

C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("PerksMenu", "YourName", "0.1")]
    public class PerksMenu : RustPlugin
    {
        [PluginReference]
        Plugin Economics; // Ссылка на плагин экономики

        private List<string> purchasedPerks = new List<string>();

        void Init()
        {
            cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
        }

        void CmdPerksMenu(BasePlayer player, string command, string[] args)
        {
            ShowPerksMenu(player);
        }

        private void ShowPerksMenu(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "PerksMenu");

            var elements = new CuiElementContainer();
            var mainPanel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.7" },
                RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
                CursorEnabled = true
            }, "Overlay", "PerksMenu");

            if (!purchasedPerks.Contains("DoubleJump"))
            {
                elements.Add(new CuiButton
                {
                    Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
                    RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
                    Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
                }, mainPanel);
            }

            // Кнопка закрытия меню
            elements.Add(new CuiButton
            {
                Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
                RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
                Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
            }, mainPanel);

            CuiHelper.AddUi(player, elements);
        }

        [ConsoleCommand("UI_Destroy")]
        void CmdUIDestroy(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null)
            {
                CuiHelper.DestroyUi(player, "PerksMenu");
            }
        }

        [ChatCommand("buy.perk")]
        void BuyPerk(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0) return;

            string perkName = args[0];
            if (purchasedPerks.Contains(perkName))
            {
                SendReply(player, "You already have this perk.");
                return;
            }

            int perkCost = 100; // Задать стоимость
            var balance = Economics.CallHook("Balance", player.userID);
            if (balance is double && (double)balance >= perkCost)
            {
                Economics.CallHook("Withdraw", player.userID, (double)perkCost);
                purchasedPerks.Add(perkName);
                SendReply(player, $"You have purchased the {perkName} perk.");
            }
            else
            {
                SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
            }
        }
    }
}

В этом коде:

1. Используется ссылка на плагин экономики для работы с балансом игрока.
2. При покупке привилегии проверяется достаточность средств, и в случае успеха средства списываются с баланса.
3. Добавлена кнопка закрытия пользовательского интерфейса с обработчиком команды UI_Destroy для её функционирования.

Убедитесь, что плагин экономики, на который вы ссылаетесь, установлен и корректно работает на вашем сервере Rust, и что его API поддерживает вызовы Balance и Withdraw с передачей идентификатора пользователя и суммы транзакции.
 
Чтобы объединить предложенные изменения, необходимо внедрить логику проверки и списания средств с баланса игрока при покупке привилегии, а также добавить кнопку закрытия меню. Вот ваш код с необходимыми изменениями:

C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("PerksMenu", "YourName", "0.1")]
    public class PerksMenu : RustPlugin
    {
        [PluginReference]
        Plugin Economics; // Ссылка на плагин экономики

        private List<string> purchasedPerks = new List<string>();

        void Init()
        {
            cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
        }

        void CmdPerksMenu(BasePlayer player, string command, string[] args)
        {
            ShowPerksMenu(player);
        }

        private void ShowPerksMenu(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "PerksMenu");

            var elements = new CuiElementContainer();
            var mainPanel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.7" },
                RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
                CursorEnabled = true
            }, "Overlay", "PerksMenu");

            if (!purchasedPerks.Contains("DoubleJump"))
            {
                elements.Add(new CuiButton
                {
                    Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
                    RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
                    Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
                }, mainPanel);
            }

            // Кнопка закрытия меню
            elements.Add(new CuiButton
            {
                Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
                RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
                Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
            }, mainPanel);

            CuiHelper.AddUi(player, elements);
        }

        [ConsoleCommand("UI_Destroy")]
        void CmdUIDestroy(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null)
            {
                CuiHelper.DestroyUi(player, "PerksMenu");
            }
        }

        [ChatCommand("buy.perk")]
        void BuyPerk(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0) return;

            string perkName = args[0];
            if (purchasedPerks.Contains(perkName))
            {
                SendReply(player, "You already have this perk.");
                return;
            }

            int perkCost = 100; // Задать стоимость
            var balance = Economics.CallHook("Balance", player.userID);
            if (balance is double && (double)balance >= perkCost)
            {
                Economics.CallHook("Withdraw", player.userID, (double)perkCost);
                purchasedPerks.Add(perkName);
                SendReply(player, $"You have purchased the {perkName} perk.");
            }
            else
            {
                SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
            }
        }
    }
}

В этом коде:

1. Используется ссылка на плагин экономики для работы с балансом игрока.
2. При покупке привилегии проверяется достаточность средств, и в случае успеха средства списываются с баланса.
3. Добавлена кнопка закрытия пользовательского интерфейса с обработчиком команды UI_Destroy для её функционирования.

Убедитесь, что плагин экономики, на который вы ссылаетесь, установлен и корректно работает на вашем сервере Rust, и что его API поддерживает вызовы Balance и Withdraw с передачей идентификатора пользователя и суммы транзакции.
дополни плагин теперь нужно что бы все перки добавлялись в json файле и изменения происходили после перезапуска плагина и настройка всех плагинов выглядела так
"jetpack": {
"description": "",
"iconName": null,
"commands": [
"grantperm $player.name jetpack.use 29d"
],
"displayName": "jetpack /givejetpack",
"cost": 30000,
"cooldown": 2592000
 
дополни плагин теперь нужно что бы все перки добавлялись в json файле и изменения происходили после перезапуска плагина и настройка всех плагинов выглядела так
"jetpack": {
"description": "",
"iconName": null,
"commands": [
"grantperm $player.name jetpack.use 29d"
],
"displayName": "jetpack /givejetpack",
"cost": 30000,
"cooldown": 2592000
Для того чтобы модифицировать указанный плагин так, чтобы он загружал информацию о перках из JSON файла и позволял осуществлять настройку перков через этот файл, вам понадобится выполнить следующие шаги:

1. Создать класс для хранения настроек перка.
2. Загрузить настройки из JSON файла при инициализации плагина.
3. Изменить логику отображения и покупки перков, основываясь на загруженных настройках.

### Шаг 1. Создание класса для хранения настроек перка

C#:
private class Perk
{
    public string Description { get; set; }
    public string IconName { get; set; }
    public List<string> Commands { get; set; }
    public string DisplayName { get; set; }
    public int Cost { get; set; }
    public int Cooldown { get; set; }
}

### Шаг 2. Загрузка настроек из JSON файла

Для управления настройками через файл, Oxide предоставляет механизм конфигурационных файлов. Вам нужно создать или модифицировать метод LoadDefaultConfig, чтобы загрузить настройки перков из файла.

C#:
private Dictionary<string, Perk> perks;

protected override void LoadDefaultConfig()
{
    // Загрузка настроек перков из JSON файла
    // Пример загрузки, фактическая реализация зависит от структуры вашего JSON файла
    perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
    SaveConfig();
}

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

### Шаг 3. Изменение логики отображения и покупки перков

Теперь, когда у вас есть загруженные настройки перков, вам нужно использовать эту информацию для отображения доступных перков и обработки их покупки.

#### Отображение перков

Вы должны изменить метод ShowPerksMenu, чтобы он динамически добавлял кнопки на основе загруженных настроек:

C#:
private void ShowPerksMenu(BasePlayer player)
{
    // Существующая начальная часть метода
    
    foreach (var perk in perks)
    {
        // Добавление кнопок для каждого перка
        // Используйте информацию из perk.Value для установки описания, стоимости и т.д.
    }
    
    // Оставшаяся часть метода
}

#### Обработка покупки

Метод BuyPerk должен быть обновлен, чтобы корректно обрабатывать запросы на покупку, используя информацию о стоимости и командах активации из настроек:

C#:
void BuyPerk(BasePlayer player, string command, string[] args)
{
    if (args.Length == 0) return;

    string perkName = args[0];
    if (!perks.ContainsKey(perkName))
    {
        SendReply(player, "This perk does not exist.");
        return;
    }

    Perk perk = perks[perkName];
    // Теперь используйте информацию из perk для проверки баланса, списания денег и активации перка
}

Убедитесь, что у вас есть корректный JSON файл с настройками перков, который соответствует структуре, ожидаемой вашим кодом. Этот файл должен быть расположен в папке oxide/config и называться так же, как и ваш плагин (например, PerksMenu.json).

Эти шаги позволят вам управлять настройками перков через JSON файл, облегчая их настройку и модификацию без необходимости переписывания кода плагина.
 
Для того чтобы модифицировать указанный плагин так, чтобы он загружал информацию о перках из JSON файла и позволял осуществлять настройку перков через этот файл, вам понадобится выполнить следующие шаги:

1. Создать класс для хранения настроек перка.
2. Загрузить настройки из JSON файла при инициализации плагина.
3. Изменить логику отображения и покупки перков, основываясь на загруженных настройках.

### Шаг 1. Создание класса для хранения настроек перка

C#:
private class Perk
{
    public string Description { get; set; }
    public string IconName { get; set; }
    public List<string> Commands { get; set; }
    public string DisplayName { get; set; }
    public int Cost { get; set; }
    public int Cooldown { get; set; }
}

### Шаг 2. Загрузка настроек из JSON файла

Для управления настройками через файл, Oxide предоставляет механизм конфигурационных файлов. Вам нужно создать или модифицировать метод LoadDefaultConfig, чтобы загрузить настройки перков из файла.

C#:
private Dictionary<string, Perk> perks;

protected override void LoadDefaultConfig()
{
    // Загрузка настроек перков из JSON файла
    // Пример загрузки, фактическая реализация зависит от структуры вашего JSON файла
    perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
    SaveConfig();
}

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

### Шаг 3. Изменение логики отображения и покупки перков

Теперь, когда у вас есть загруженные настройки перков, вам нужно использовать эту информацию для отображения доступных перков и обработки их покупки.

#### Отображение перков

Вы должны изменить метод ShowPerksMenu, чтобы он динамически добавлял кнопки на основе загруженных настроек:

C#:
private void ShowPerksMenu(BasePlayer player)
{
    // Существующая начальная часть метода
   
    foreach (var perk in perks)
    {
        // Добавление кнопок для каждого перка
        // Используйте информацию из perk.Value для установки описания, стоимости и т.д.
    }
   
    // Оставшаяся часть метода
}

#### Обработка покупки

Метод BuyPerk должен быть обновлен, чтобы корректно обрабатывать запросы на покупку, используя информацию о стоимости и командах активации из настроек:

C#:
void BuyPerk(BasePlayer player, string command, string[] args)
{
    if (args.Length == 0) return;

    string perkName = args[0];
    if (!perks.ContainsKey(perkName))
    {
        SendReply(player, "This perk does not exist.");
        return;
    }

    Perk perk = perks[perkName];
    // Теперь используйте информацию из perk для проверки баланса, списания денег и активации перка
}

Убедитесь, что у вас есть корректный JSON файл с настройками перков, который соответствует структуре, ожидаемой вашим кодом. Этот файл должен быть расположен в папке oxide/config и называться так же, как и ваш плагин (например, PerksMenu.json).

Эти шаги позволят вам управлять настройками перков через JSON файл, облегчая их настройку и модификацию без необходимости переписывания кода плагина.
объедяни с
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private List<string> purchasedPerks = new List<string>();

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

int perkCost = 100; // Задать стоимость
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
 
объедяни с
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private List<string> purchasedPerks = new List<string>();

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

if (!purchasedPerks.Contains("DoubleJump"))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk DoubleJump", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = "Double Jump - 100 Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

int perkCost = 100; // Задать стоимость
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
Объединив предложенный вами код и предыдущие шаги по модификации плагина для загрузки настроек перков из JSON файла, получаем следующее:

C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("PerksMenu", "YourName", "0.1")]
    public class PerksMenu : RustPlugin
    {
        [PluginReference]
        Plugin Economics; // Ссылка на плагин экономики

        private Dictionary<string, Perk> perks;
        
        private List<string> purchasedPerks = new List<string>();

        private class Perk
        {
            public string Description { get; set; }
            public string IconName { get; set; }
            public List<string> Commands { get; set; }
            public string DisplayName { get; set; }
            public int Cost { get; set; }
            public int Cooldown { get; set; }
        }

        void Init()
        {
            cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
            LoadPerkConfig();
        }

        void LoadPerkConfig()
        {
            // Загрузка настроек перков из конфигурационного файла
            perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
        }

        void CmdPerksMenu(BasePlayer player, string command, string[] args)
        {
            ShowPerksMenu(player);
        }

        private void ShowPerksMenu(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "PerksMenu");

            var elements = new CuiElementContainer();
            var mainPanel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.7" },
                RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
                CursorEnabled = true
            }, "Overlay", "PerksMenu");

            foreach (var perk in perks)
            {
                if (!purchasedPerks.Contains(perk.Key))
                {
                    elements.Add(new CuiButton
                    {
                        Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
                        RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
                        Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
                    }, mainPanel);
                }
            }

            // Кнопка закрытия меню
            elements.Add(new CuiButton
            {
                Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
                RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
                Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
            }, mainPanel);

            CuiHelper.AddUi(player, elements);
        }

        [ConsoleCommand("UI_Destroy")]
        void CmdUIDestroy(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null)
            {
                CuiHelper.DestroyUi(player, "PerksMenu");
            }
        }

        [ChatCommand("buy.perk")]
        void BuyPerk(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0) return;

            string perkName = args[0];
            if (purchasedPerks.Contains(perkName))
            {
                SendReply(player, "You already have this perk.");
                return;
            }

            if (!perks.ContainsKey(perkName))
            {
                SendReply(player, "This perk does not exist.");
                return;
            }

            Perk perk = perks[perkName];
            int perkCost = perk.Cost; // Получаем стоимость из конфигурации
            var balance = Economics.CallHook("Balance", player.userID);
            if (balance is double && (double)balance >= perkCost)
            {
                Economics.CallHook("Withdraw", player.userID, (double)perkCost);
                purchasedPerks.Add(perkName);
                SendReply(player, $"You have purchased the {perkName} perk.");
            }
            else
            {
                SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
            }
        }
    }
}

Этот код интегрирует ваш исходный код с динамической загрузкой настроек перков из JSON-файла. Не забудьте реализовать логику сохранения и загрузки списка купленных перков (purchasedPerks), если это необходимо для вашего плагина.
 
Объединив предложенный вами код и предыдущие шаги по модификации плагина для загрузки настроек перков из JSON файла, получаем следующее:

C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("PerksMenu", "YourName", "0.1")]
    public class PerksMenu : RustPlugin
    {
        [PluginReference]
        Plugin Economics; // Ссылка на плагин экономики

        private Dictionary<string, Perk> perks;
       
        private List<string> purchasedPerks = new List<string>();

        private class Perk
        {
            public string Description { get; set; }
            public string IconName { get; set; }
            public List<string> Commands { get; set; }
            public string DisplayName { get; set; }
            public int Cost { get; set; }
            public int Cooldown { get; set; }
        }

        void Init()
        {
            cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
            LoadPerkConfig();
        }

        void LoadPerkConfig()
        {
            // Загрузка настроек перков из конфигурационного файла
            perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
        }

        void CmdPerksMenu(BasePlayer player, string command, string[] args)
        {
            ShowPerksMenu(player);
        }

        private void ShowPerksMenu(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "PerksMenu");

            var elements = new CuiElementContainer();
            var mainPanel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.7" },
                RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
                CursorEnabled = true
            }, "Overlay", "PerksMenu");

            foreach (var perk in perks)
            {
                if (!purchasedPerks.Contains(perk.Key))
                {
                    elements.Add(new CuiButton
                    {
                        Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
                        RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
                        Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
                    }, mainPanel);
                }
            }

            // Кнопка закрытия меню
            elements.Add(new CuiButton
            {
                Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
                RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
                Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
            }, mainPanel);

            CuiHelper.AddUi(player, elements);
        }

        [ConsoleCommand("UI_Destroy")]
        void CmdUIDestroy(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null)
            {
                CuiHelper.DestroyUi(player, "PerksMenu");
            }
        }

        [ChatCommand("buy.perk")]
        void BuyPerk(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0) return;

            string perkName = args[0];
            if (purchasedPerks.Contains(perkName))
            {
                SendReply(player, "You already have this perk.");
                return;
            }

            if (!perks.ContainsKey(perkName))
            {
                SendReply(player, "This perk does not exist.");
                return;
            }

            Perk perk = perks[perkName];
            int perkCost = perk.Cost; // Получаем стоимость из конфигурации
            var balance = Economics.CallHook("Balance", player.userID);
            if (balance is double && (double)balance >= perkCost)
            {
                Economics.CallHook("Withdraw", player.userID, (double)perkCost);
                purchasedPerks.Add(perkName);
                SendReply(player, $"You have purchased the {perkName} perk.");
            }
            else
            {
                SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
            }
        }
    }
}

Этот код интегрирует ваш исходный код с динамической загрузкой настроек перков из JSON-файла. Не забудьте реализовать логику сохранения и загрузки списка купленных перков (purchasedPerks), если это необходимо для вашего плагина.
после загрузки плагина не появился файл json с настройкой по примеру
"jetpack": {
"description": "",
"iconName": null,
"commands": [
"grantperm $player.name jetpack.use 29d"
],
"displayName": "jetpack /givejetpack",
"cost": 30000,
"cooldown": 2592000
 
после загрузки плагина не появился файл json с настройкой по примеру
"jetpack": {
"description": "",
"iconName": null,
"commands": [
"grantperm $player.name jetpack.use 29d"
],
"displayName": "jetpack /givejetpack",
"cost": 30000,
"cooldown": 2592000
Если после загрузки плагина не появился JSON файл с настройками, это может быть связано с отсутствием кода для создания и сохранения стандартных настроек в случае, если файл конфигурации не существует. Для корректной работы плагина и автоматического создания файла настроек при его отсутствии, вам нужно добавить соответствующий код.

Также, в предоставленном коде отсутствует метод LoadDefaultConfig(), который вызывается Oxide, если файл конфигурации не найден или пуст. В этом методе вы можете задать и сохранить стандартные настройки, которые вы хотели бы использовать.

Ниже приведен пример того, как можно добавить метод LoadDefaultConfig() и сохранить в нём стандартные настройки в JSON формате:

C#:
protected override void LoadDefaultConfig()
{
    // Создаем стандартные настройки
    var defaultPerks = new Dictionary<string, Perk>
    {
        {
            "jetpack", new Perk
            {
                Description = "",
                IconName = null,
                Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
                DisplayName = "jetpack /givejetpack",
                Cost = 30000,
                Cooldown = 2592000
            }
        }
    };

    // Сохраняем стандартные настройки в файл конфигурации
    Config.WriteObject(new { Perks = defaultPerks }, true);
}

Не забудьте, что данный метод LoadDefaultConfig() автоматически вызывается только если файл конфигурации отсутствует или не может быть прочитан. После первого создания файла конфигурации или его ручного редактирования, плагин будет использовать существующие настройки.

Также убедитесь, что метод Init() или другой подходящий метод вызывает LoadDefaultConfig() явно, если это необходимо для вашей логики инициализации, или если вы хотите перезаписать конфигурацию каждый раз при загрузке плагина.

C#:
void Init()
{
    // Загружаем или создаем настройки по умолчанию
    LoadDefaultConfig();
    LoadPerkConfig();
}

Это гарантирует, что ваш плагин всегда будет иметь доступ к файлу конфигурации с необходимыми настройками.
 
Если после загрузки плагина не появился JSON файл с настройками, это может быть связано с отсутствием кода для создания и сохранения стандартных настроек в случае, если файл конфигурации не существует. Для корректной работы плагина и автоматического создания файла настроек при его отсутствии, вам нужно добавить соответствующий код.

Также, в предоставленном коде отсутствует метод LoadDefaultConfig(), который вызывается Oxide, если файл конфигурации не найден или пуст. В этом методе вы можете задать и сохранить стандартные настройки, которые вы хотели бы использовать.

Ниже приведен пример того, как можно добавить метод LoadDefaultConfig() и сохранить в нём стандартные настройки в JSON формате:

C#:
protected override void LoadDefaultConfig()
{
    // Создаем стандартные настройки
    var defaultPerks = new Dictionary<string, Perk>
    {
        {
            "jetpack", new Perk
            {
                Description = "",
                IconName = null,
                Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
                DisplayName = "jetpack /givejetpack",
                Cost = 30000,
                Cooldown = 2592000
            }
        }
    };

    // Сохраняем стандартные настройки в файл конфигурации
    Config.WriteObject(new { Perks = defaultPerks }, true);
}

Не забудьте, что данный метод LoadDefaultConfig() автоматически вызывается только если файл конфигурации отсутствует или не может быть прочитан. После первого создания файла конфигурации или его ручного редактирования, плагин будет использовать существующие настройки.

Также убедитесь, что метод Init() или другой подходящий метод вызывает LoadDefaultConfig() явно, если это необходимо для вашей логики инициализации, или если вы хотите перезаписать конфигурацию каждый раз при загрузке плагина.

C#:
void Init()
{
    // Загружаем или создаем настройки по умолчанию
    LoadDefaultConfig();
    LoadPerkConfig();
}

Это гарантирует, что ваш плагин всегда будет иметь доступ к файлу конфигурации с необходимыми настройками.
объедяни это с
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private Dictionary<string, Perk> perks;

private List<string> purchasedPerks = new List<string>();

private class Perk
{
public string Description { get; set; }
public string IconName { get; set; }
public List<string> Commands { get; set; }
public string DisplayName { get; set; }
public int Cost { get; set; }
public int Cooldown { get; set; }
}

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
LoadPerkConfig();
}

void LoadPerkConfig()
{
// Загрузка настроек перков из конфигурационного файла
perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

foreach (var perk in perks)
{
if (!purchasedPerks.Contains(perk.Key))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

if (!perks.ContainsKey(perkName))
{
SendReply(player, "This perk does not exist.");
return;
}

Perk perk = perks[perkName];
int perkCost = perk.Cost; // Получаем стоимость из конфигурации
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
 
Если после загрузки плагина не появился JSON файл с настройками, это может быть связано с отсутствием кода для создания и сохранения стандартных настроек в случае, если файл конфигурации не существует. Для корректной работы плагина и автоматического создания файла настроек при его отсутствии, вам нужно добавить соответствующий код.

Также, в предоставленном коде отсутствует метод LoadDefaultConfig(), который вызывается Oxide, если файл конфигурации не найден или пуст. В этом методе вы можете задать и сохранить стандартные настройки, которые вы хотели бы использовать.

Ниже приведен пример того, как можно добавить метод LoadDefaultConfig() и сохранить в нём стандартные настройки в JSON формате:

C#:
protected override void LoadDefaultConfig()
{
    // Создаем стандартные настройки
    var defaultPerks = new Dictionary<string, Perk>
    {
        {
            "jetpack", new Perk
            {
                Description = "",
                IconName = null,
                Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
                DisplayName = "jetpack /givejetpack",
                Cost = 30000,
                Cooldown = 2592000
            }
        }
    };

    // Сохраняем стандартные настройки в файл конфигурации
    Config.WriteObject(new { Perks = defaultPerks }, true);
}

Не забудьте, что данный метод LoadDefaultConfig() автоматически вызывается только если файл конфигурации отсутствует или не может быть прочитан. После первого создания файла конфигурации или его ручного редактирования, плагин будет использовать существующие настройки.

Также убедитесь, что метод Init() или другой подходящий метод вызывает LoadDefaultConfig() явно, если это необходимо для вашей логики инициализации, или если вы хотите перезаписать конфигурацию каждый раз при загрузке плагина.

C#:
void Init()
{
    // Загружаем или создаем настройки по умолчанию
    LoadDefaultConfig();
    LoadPerkConfig();
}

Это гарантирует, что ваш плагин всегда будет иметь доступ к файлу конфигурации с необходимыми настройками.
объедяни это с
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private Dictionary<string, Perk> perks;

private List<string> purchasedPerks = new List<string>();

private class Perk
{
public string Description { get; set; }
public string IconName { get; set; }
public List<string> Commands { get; set; }
public string DisplayName { get; set; }
public int Cost { get; set; }
public int Cooldown { get; set; }
}

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
LoadPerkConfig();
}

void LoadPerkConfig()
{
// Загрузка настроек перков из конфигурационного файла
perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

foreach (var perk in perks)
{
if (!purchasedPerks.Contains(perk.Key))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

if (!perks.ContainsKey(perkName))
{
SendReply(player, "This perk does not exist.");
return;
}

Perk perk = perks[perkName];
int perkCost = perk.Cost; // Получаем стоимость из конфигурации
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
 
Если после загрузки плагина не появился JSON файл с настройками, это может быть связано с отсутствием кода для создания и сохранения стандартных настроек в случае, если файл конфигурации не существует. Для корректной работы плагина и автоматического создания файла настроек при его отсутствии, вам нужно добавить соответствующий код.

Также, в предоставленном коде отсутствует метод LoadDefaultConfig(), который вызывается Oxide, если файл конфигурации не найден или пуст. В этом методе вы можете задать и сохранить стандартные настройки, которые вы хотели бы использовать.

Ниже приведен пример того, как можно добавить метод LoadDefaultConfig() и сохранить в нём стандартные настройки в JSON формате:

C#:
protected override void LoadDefaultConfig()
{
    // Создаем стандартные настройки
    var defaultPerks = new Dictionary<string, Perk>
    {
        {
            "jetpack", new Perk
            {
                Description = "",
                IconName = null,
                Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
                DisplayName = "jetpack /givejetpack",
                Cost = 30000,
                Cooldown = 2592000
            }
        }
    };

    // Сохраняем стандартные настройки в файл конфигурации
    Config.WriteObject(new { Perks = defaultPerks }, true);
}

Не забудьте, что данный метод LoadDefaultConfig() автоматически вызывается только если файл конфигурации отсутствует или не может быть прочитан. После первого создания файла конфигурации или его ручного редактирования, плагин будет использовать существующие настройки.

Также убедитесь, что метод Init() или другой подходящий метод вызывает LoadDefaultConfig() явно, если это необходимо для вашей логики инициализации, или если вы хотите перезаписать конфигурацию каждый раз при загрузке плагина.

C#:
void Init()
{
    // Загружаем или создаем настройки по умолчанию
    LoadDefaultConfig();
    LoadPerkConfig();
}

Это гарантирует, что ваш плагин всегда будет иметь доступ к файлу конфигурации с необходимыми настройками.
объедяни это с

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

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private Dictionary<string, Perk> perks;

private List<string> purchasedPerks = new List<string>();

private class Perk
{
public string Description { get; set; }
public string IconName { get; set; }
public List<string> Commands { get; set; }
public string DisplayName { get; set; }
public int Cost { get; set; }
public int Cooldown { get; set; }
}

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
LoadPerkConfig();
}

void LoadPerkConfig()
{
// Загрузка настроек перков из конфигурационного файла
perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

foreach (var perk in perks)
{
if (!purchasedPerks.Contains(perk.Key))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

if (!perks.ContainsKey(perkName))
{
SendReply(player, "This perk does not exist.");
return;
}

Perk perk = perks[perkName];
int perkCost = perk.Cost; // Получаем стоимость из конфигурации
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
 
Если после загрузки плагина не появился JSON файл с настройками, это может быть связано с отсутствием кода для создания и сохранения стандартных настроек в случае, если файл конфигурации не существует. Для корректной работы плагина и автоматического создания файла настроек при его отсутствии, вам нужно добавить соответствующий код.

Также, в предоставленном коде отсутствует метод LoadDefaultConfig(), который вызывается Oxide, если файл конфигурации не найден или пуст. В этом методе вы можете задать и сохранить стандартные настройки, которые вы хотели бы использовать.

Ниже приведен пример того, как можно добавить метод LoadDefaultConfig() и сохранить в нём стандартные настройки в JSON формате:

C#:
protected override void LoadDefaultConfig()
{
    // Создаем стандартные настройки
    var defaultPerks = new Dictionary<string, Perk>
    {
        {
            "jetpack", new Perk
            {
                Description = "",
                IconName = null,
                Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
                DisplayName = "jetpack /givejetpack",
                Cost = 30000,
                Cooldown = 2592000
            }
        }
    };

    // Сохраняем стандартные настройки в файл конфигурации
    Config.WriteObject(new { Perks = defaultPerks }, true);
}

Не забудьте, что данный метод LoadDefaultConfig() автоматически вызывается только если файл конфигурации отсутствует или не может быть прочитан. После первого создания файла конфигурации или его ручного редактирования, плагин будет использовать существующие настройки.

Также убедитесь, что метод Init() или другой подходящий метод вызывает LoadDefaultConfig() явно, если это необходимо для вашей логики инициализации, или если вы хотите перезаписать конфигурацию каждый раз при загрузке плагина.

C#:
void Init()
{
    // Загружаем или создаем настройки по умолчанию
    LoadDefaultConfig();
    LoadPerkConfig();
}

Это гарантирует, что ваш плагин всегда будет иметь доступ к файлу конфигурации с необходимыми настройками.
теперь сделай так что бы все покупки привелегий брались из json например
{
"Perks": {
"jetpack": {
"Commands": [
"grantperm $player.name jetpack.use 29d"
],
"Cooldown": 2592000,
"Cost": 30000,
"Description": "",
"DisplayName": "jetpack /givejetpack",
"IconName": null
}
}
}
в файле json и мне нужно что бы именно отсюда активировались привелегии
 
теперь сделай так что бы все покупки привелегий брались из json например
{
"Perks": {
"jetpack": {
"Commands": [
"grantperm $player.name jetpack.use 29d"
],
"Cooldown": 2592000,
"Cost": 30000,
"Description": "",
"DisplayName": "jetpack /givejetpack",
"IconName": null
}
}
}
в файле json и мне нужно что бы именно отсюда активировались привелегии
Чтобы считывать настройки привилегий из JSON файла и активировать их основываясь на этой конфигурации, вам потребуется два основных шага: сначала загрузить и распарсить настройки из файла, а затем использовать эти настройки для активации привилегий при соответствующих условиях.

Допустим, у вас уже есть JSON файл с настройками, как вы показали. Вот как вы можете реализовать эти шаги в вашем плагине:

### Шаг 1: Загрузка и парсинг настроек

1. Создайте классы для представления настроек:
Сначала нужно определить C# классы, которые соответствуют структуре вашего JSON файла. Это позволит легко десериализовать JSON в объекты.

Код:
csharp
   class PerkConfig
   {
       public Dictionary<string, Perk> Perks { get; set; }
   }

   class Perk
   {
       public List<string> Commands { get; set; }
       public int Cooldown { get; set; }
       public int Cost { get; set; }
       public string Description { get; set; }
       public string DisplayName { get; set; }
       public string IconName { get; set; }
   }

2. Загрузите и десериализуйте JSON файл:
Вам нужно написать код, который загрузит JSON файл и преобразует его в объекты ваших классов.

Код:
csharp
   PerkConfig perkConfig;

   protected override void LoadConfig()
   {
       base.LoadConfig();
       
       try
       {
           perkConfig = Config.ReadObject<PerkConfig>();
       }
       catch
       {
           PrintWarning("Не удалось загрузить конфигурацию. Восстанавливаю стандартные настройки...");
           LoadDefaultConfig();
       }
   }

   protected override void LoadDefaultConfig()
   {
       perkConfig = new PerkConfig
       {
           // Здесь добавьте стандартные настройки
       };
   }

### Шаг 2: Использование настроек для активации привилегий

1. Активация привилегий:
Используйте загруженные настройки для активации привилегий. Например, если пользователь покупает привилегию, вы можете выполнять соответствующие команды из конфигурации.

Код:
csharp
   void ActivatePerk(string perkName, BasePlayer player)
   {
       if (!perkConfig.Perks.TryGetValue(perkName, out Perk perk))
       {
           PrintWarning($"Привилегия {perkName} не найдена.");
           return;
       }

       foreach (var command in perk.Commands)
       {
           // Замените $player.name на имя игрока
           var cmd = command.Replace("$player.name", player.UserIDString);
           // Выполните команду
           consoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), cmd);
       }

       // Здесь можно добавить логику для списания стоимости и применения кулдауна
   }

Убедитесь, что команды выполняются с правильными правами, например, некоторые команды могут требовать серверных прав для их выполнения.

2. Привязка к событию покупки:
Привяжите функцию активации привилегий к логике покупки в вашем плагине, чтобы активировать привилегии после успешной покупки.

Этот подход позволяет легко управлять привилегиями через JSON файл, делая систему гибкой и удобной для масштабирования и изменений.
 
Чтобы считывать настройки привилегий из JSON файла и активировать их основываясь на этой конфигурации, вам потребуется два основных шага: сначала загрузить и распарсить настройки из файла, а затем использовать эти настройки для активации привилегий при соответствующих условиях.

Допустим, у вас уже есть JSON файл с настройками, как вы показали. Вот как вы можете реализовать эти шаги в вашем плагине:

### Шаг 1: Загрузка и парсинг настроек

1. Создайте классы для представления настроек:
Сначала нужно определить C# классы, которые соответствуют структуре вашего JSON файла. Это позволит легко десериализовать JSON в объекты.

Код:
csharp
   class PerkConfig
   {
       public Dictionary<string, Perk> Perks { get; set; }
   }

   class Perk
   {
       public List<string> Commands { get; set; }
       public int Cooldown { get; set; }
       public int Cost { get; set; }
       public string Description { get; set; }
       public string DisplayName { get; set; }
       public string IconName { get; set; }
   }

2. Загрузите и десериализуйте JSON файл:
Вам нужно написать код, который загрузит JSON файл и преобразует его в объекты ваших классов.

Код:
csharp
   PerkConfig perkConfig;

   protected override void LoadConfig()
   {
       base.LoadConfig();
      
       try
       {
           perkConfig = Config.ReadObject<PerkConfig>();
       }
       catch
       {
           PrintWarning("Не удалось загрузить конфигурацию. Восстанавливаю стандартные настройки...");
           LoadDefaultConfig();
       }
   }

   protected override void LoadDefaultConfig()
   {
       perkConfig = new PerkConfig
       {
           // Здесь добавьте стандартные настройки
       };
   }

### Шаг 2: Использование настроек для активации привилегий

1. Активация привилегий:
Используйте загруженные настройки для активации привилегий. Например, если пользователь покупает привилегию, вы можете выполнять соответствующие команды из конфигурации.

Код:
csharp
   void ActivatePerk(string perkName, BasePlayer player)
   {
       if (!perkConfig.Perks.TryGetValue(perkName, out Perk perk))
       {
           PrintWarning($"Привилегия {perkName} не найдена.");
           return;
       }

       foreach (var command in perk.Commands)
       {
           // Замените $player.name на имя игрока
           var cmd = command.Replace("$player.name", player.UserIDString);
           // Выполните команду
           consoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), cmd);
       }

       // Здесь можно добавить логику для списания стоимости и применения кулдауна
   }

Убедитесь, что команды выполняются с правильными правами, например, некоторые команды могут требовать серверных прав для их выполнения.

2. Привязка к событию покупки:
Привяжите функцию активации привилегий к логике покупки в вашем плагине, чтобы активировать привилегии после успешной покупки.

Этот подход позволяет легко управлять привилегиями через JSON файл, делая систему гибкой и удобной для масштабирования и изменений.
теперь объедени это все с
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private Dictionary<string, Perk> perks;

private List<string> purchasedPerks = new List<string>();

private class Perk
{
public string Description { get; set; }
public string IconName { get; set; }
public List<string> Commands { get; set; }
public string DisplayName { get; set; }
public int Cost { get; set; }
public int Cooldown { get; set; }
}

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
LoadPerkConfig();
}

void LoadPerkConfig()
{
// Загрузка настроек перков из конфигурационного файла
perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

foreach (var perk in perks)
{
if (!purchasedPerks.Contains(perk.Key))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

protected override void LoadDefaultConfig()
{
// Создаем стандартные настройки
var defaultPerks = new Dictionary<string, Perk>
{
{
"jetpack", new Perk
{
Description = "",
IconName = null,
Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
DisplayName = "jetpack /givejetpack",
Cost = 30000,
Cooldown = 2592000
}
}
};

// Сохраняем стандартные настройки в файл конфигурации
Config.WriteObject(new { Perks = defaultPerks }, true);
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

if (!perks.ContainsKey(perkName))
{
SendReply(player, "This perk does not exist.");
return;
}

Perk perk = perks[perkName];
int perkCost = perk.Cost; // Получаем стоимость из конфигурации
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}
 
Чтобы считывать настройки привилегий из JSON файла и активировать их основываясь на этой конфигурации, вам потребуется два основных шага: сначала загрузить и распарсить настройки из файла, а затем использовать эти настройки для активации привилегий при соответствующих условиях.

Допустим, у вас уже есть JSON файл с настройками, как вы показали. Вот как вы можете реализовать эти шаги в вашем плагине:

### Шаг 1: Загрузка и парсинг настроек

1. Создайте классы для представления настроек:
Сначала нужно определить C# классы, которые соответствуют структуре вашего JSON файла. Это позволит легко десериализовать JSON в объекты.

Код:
csharp
   class PerkConfig
   {
       public Dictionary<string, Perk> Perks { get; set; }
   }

   class Perk
   {
       public List<string> Commands { get; set; }
       public int Cooldown { get; set; }
       public int Cost { get; set; }
       public string Description { get; set; }
       public string DisplayName { get; set; }
       public string IconName { get; set; }
   }

2. Загрузите и десериализуйте JSON файл:
Вам нужно написать код, который загрузит JSON файл и преобразует его в объекты ваших классов.

Код:
csharp
   PerkConfig perkConfig;

   protected override void LoadConfig()
   {
       base.LoadConfig();
      
       try
       {
           perkConfig = Config.ReadObject<PerkConfig>();
       }
       catch
       {
           PrintWarning("Не удалось загрузить конфигурацию. Восстанавливаю стандартные настройки...");
           LoadDefaultConfig();
       }
   }

   protected override void LoadDefaultConfig()
   {
       perkConfig = new PerkConfig
       {
           // Здесь добавьте стандартные настройки
       };
   }

### Шаг 2: Использование настроек для активации привилегий

1. Активация привилегий:
Используйте загруженные настройки для активации привилегий. Например, если пользователь покупает привилегию, вы можете выполнять соответствующие команды из конфигурации.

Код:
csharp
   void ActivatePerk(string perkName, BasePlayer player)
   {
       if (!perkConfig.Perks.TryGetValue(perkName, out Perk perk))
       {
           PrintWarning($"Привилегия {perkName} не найдена.");
           return;
       }

       foreach (var command in perk.Commands)
       {
           // Замените $player.name на имя игрока
           var cmd = command.Replace("$player.name", player.UserIDString);
           // Выполните команду
           consoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), cmd);
       }

       // Здесь можно добавить логику для списания стоимости и применения кулдауна
   }

Убедитесь, что команды выполняются с правильными правами, например, некоторые команды могут требовать серверных прав для их выполнения.

2. Привязка к событию покупки:
Привяжите функцию активации привилегий к логике покупки в вашем плагине, чтобы активировать привилегии после успешной покупки.

Этот подход позволяет легко управлять привилегиями через JSON файл, делая систему гибкой и удобной для масштабирования и изменений.
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
[Info("PerksMenu", "YourName", "0.1")]
public class PerksMenu : RustPlugin
{
[PluginReference]
Plugin Economics; // Ссылка на плагин экономики

private Dictionary<string, Perk> perks;

private List<string> purchasedPerks = new List<string>();

private class Perk
{
public string Description { get; set; }
public string IconName { get; set; }
public List<string> Commands { get; set; }
public string DisplayName { get; set; }
public int Cost { get; set; }
public int Cooldown { get; set; }
}

void Init()
{
cmd.AddChatCommand("pmenu", this, "CmdPerksMenu");
LoadPerkConfig();
}

void LoadPerkConfig()
{
// Загрузка настроек перков из конфигурационного файла
perks = Config.ReadObject<Dictionary<string, Perk>>("Perks");
}

void CmdPerksMenu(BasePlayer player, string command, string[] args)
{
ShowPerksMenu(player);
}

private void ShowPerksMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "PerksMenu");

var elements = new CuiElementContainer();
var mainPanel = elements.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.7" },
RectTransform = { AnchorMin = "0.3 0.3", AnchorMax = "0.7 0.7" },
CursorEnabled = true
}, "Overlay", "PerksMenu");

foreach (var perk in perks)
{
if (!purchasedPerks.Contains(perk.Key))
{
elements.Add(new CuiButton
{
Button = { Command = $"buy.perk {perk.Key}", Color = "0.2 0.9 0.2 0.7" },
RectTransform = { AnchorMin = "0.1 0.8", AnchorMax = "0.9 0.9" },
Text = { Text = $"{perk.Value.DisplayName} - {perk.Value.Cost} Coins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, mainPanel);
}
}

// Кнопка закрытия меню
elements.Add(new CuiButton
{
Button = { Command = "UI_Destroy", Color = "0.8 0.2 0.2 0.7" },
RectTransform = { AnchorMin = "0.9 0.9", AnchorMax = "1 1" },
Text = { Text = "X", FontSize = 20, Align = TextAnchor.MiddleCenter }
}, mainPanel);

CuiHelper.AddUi(player, elements);
}

[ConsoleCommand("UI_Destroy")]
void CmdUIDestroy(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null)
{
CuiHelper.DestroyUi(player, "PerksMenu");
}
}

protected override void LoadDefaultConfig()
{
// Создаем стандартные настройки
var defaultPerks = new Dictionary<string, Perk>
{
{
"jetpack", new Perk
{
Description = "",
IconName = null,
Commands = new List<string> { "grantperm $player.name jetpack.use 29d" },
DisplayName = "jetpack /givejetpack",
Cost = 30000,
Cooldown = 2592000
}
}
};

// Сохраняем стандартные настройки в файл конфигурации
Config.WriteObject(new { Perks = defaultPerks }, true);
}

[ChatCommand("buy.perk")]
void BuyPerk(BasePlayer player, string command, string[] args)
{
if (args.Length == 0) return;

string perkName = args[0];
if (purchasedPerks.Contains(perkName))
{
SendReply(player, "You already have this perk.");
return;
}

if (!perks.ContainsKey(perkName))
{
SendReply(player, "This perk does not exist.");
return;
}

Perk perk = perks[perkName];
int perkCost = perk.Cost; // Получаем стоимость из конфигурации
var balance = Economics.CallHook("Balance", player.userID);
if (balance is double && (double)balance >= perkCost)
{
Economics.CallHook("Withdraw", player.userID, (double)perkCost);
purchasedPerks.Add(perkName);
SendReply(player, $"You have purchased the {perkName} perk.");
}
else
{
SendReply(player, $"Not enough coins. You need {perkCost} coins to purchase this perk.");
}
}
}
}

теперь нужно это все объедянить в 1 плагин
 
Чтобы считывать настройки привилегий из JSON файла и активировать их основываясь на этой конфигурации, вам потребуется два основных шага: сначала загрузить и распарсить настройки из файла, а затем использовать эти настройки для активации привилегий при соответствующих условиях.

Допустим, у вас уже есть JSON файл с настройками, как вы показали. Вот как вы можете реализовать эти шаги в вашем плагине:

### Шаг 1: Загрузка и парсинг настроек

1. Создайте классы для представления настроек:
Сначала нужно определить C# классы, которые соответствуют структуре вашего JSON файла. Это позволит легко десериализовать JSON в объекты.

Код:
csharp
   class PerkConfig
   {
       public Dictionary<string, Perk> Perks { get; set; }
   }

   class Perk
   {
       public List<string> Commands { get; set; }
       public int Cooldown { get; set; }
       public int Cost { get; set; }
       public string Description { get; set; }
       public string DisplayName { get; set; }
       public string IconName { get; set; }
   }

2. Загрузите и десериализуйте JSON файл:
Вам нужно написать код, который загрузит JSON файл и преобразует его в объекты ваших классов.

Код:
csharp
   PerkConfig perkConfig;

   protected override void LoadConfig()
   {
       base.LoadConfig();
      
       try
       {
           perkConfig = Config.ReadObject<PerkConfig>();
       }
       catch
       {
           PrintWarning("Не удалось загрузить конфигурацию. Восстанавливаю стандартные настройки...");
           LoadDefaultConfig();
       }
   }

   protected override void LoadDefaultConfig()
   {
       perkConfig = new PerkConfig
       {
           // Здесь добавьте стандартные настройки
       };
   }

### Шаг 2: Использование настроек для активации привилегий

1. Активация привилегий:
Используйте загруженные настройки для активации привилегий. Например, если пользователь покупает привилегию, вы можете выполнять соответствующие команды из конфигурации.

Код:
csharp
   void ActivatePerk(string perkName, BasePlayer player)
   {
       if (!perkConfig.Perks.TryGetValue(perkName, out Perk perk))
       {
           PrintWarning($"Привилегия {perkName} не найдена.");
           return;
       }

       foreach (var command in perk.Commands)
       {
           // Замените $player.name на имя игрока
           var cmd = command.Replace("$player.name", player.UserIDString);
           // Выполните команду
           consoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), cmd);
       }

       // Здесь можно добавить логику для списания стоимости и применения кулдауна
   }

Убедитесь, что команды выполняются с правильными правами, например, некоторые команды могут требовать серверных прав для их выполнения.

2. Привязка к событию покупки:
Привяжите функцию активации привилегий к логике покупки в вашем плагине, чтобы активировать привилегии после успешной покупки.

Этот подход позволяет легко управлять привилегиями через JSON файл, делая систему гибкой и удобной для масштабирования и изменений.
При покупки перка пишет you don't not have permission to use the command grantperm,нужно покупка из примера
{
"Perks": {
"jetpack": {
"Commands": [
"grantperm $player.name jetpack.use 29d"
],
"Cooldown": 2592000,
"Cost": 30000,
"Description": "",
"DisplayName": "jetpack /givejetpack",
"IconName": null
}
}
}

использовалась команда grantperm $player.name
 
Активность
Пока никто не печатает сообщение