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

FREE TPMenu : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("TPMenu", "SARO", "1.0.0")]
    public class TPMenu : RustPlugin
    {
        private readonly PluginConfig config;
        private const string MainLayer = "tpmenu";
        private const float CACHE_TIMEOUT = 5f;
        private const float BUTTON_HEIGHT = 0.04f;
        private const float BUTTON_SPACING = 0.005f;
        private const float BUTTON_WIDTH = 0.075f;
        private const float PANEL_BG_COLOR = 0.12f;
        private const float BUTTON_BG_COLOR = 0.19f;
        private const float OUTLINE_COLOR = 0.30f;
        private const float TEXT_COLOR = 0.8f;
        private const int FONT_SIZE = 12;
        private const string FONT_NAME = "robotocondensed-regular.ttf";
        private const string BOLD_FONT_NAME = "robotocondensed-bold.ttf";
        private const float BASE_FONT_SIZE = 12f;
        private const float MIN_INTERFACE_SCALE = 0.6f;
        private const float MAX_INTERFACE_SCALE = 1.0f;
        private const float MAX_FONT_SIZE = 24f;

        private const int BUTTONS_PER_PAGE = 5;
        private const float SCROLL_UP_Y = 0.715f;
        private const float SCROLL_DOWN_Y = 0.515f;

        private const int TITLE_FONT_SIZE = 20;
        private const int SMALL_FONT_SIZE = 10;

        [PluginReference]
        private readonly Plugin? ImageLibrary;

        [PluginReference]
        private readonly Plugin? Friends;

        [PluginReference]
        private readonly Plugin? MutualPermission;

        [PluginReference]
        private readonly Plugin? NTeleportation;

        [PluginReference]
        private readonly Plugin? Teleport;

        [PluginReference]
        private readonly Plugin? Teleportation;

        [PluginReference]
        private readonly Plugin? HomesGUI;

        [PluginReference]
        private readonly Plugin? Home;

        [PluginReference]
        private readonly Plugin? IQTeleportation;

        private readonly Dictionary<string, string> imageCache;
        private readonly Dictionary<ulong, Dictionary<string, Vector3>> homesCache;
        private readonly Dictionary<ulong, List<ulong>> friendsCache;
        private readonly Dictionary<ulong, DateTime> lastHomesUpdate;
        private readonly Dictionary<ulong, DateTime> lastFriendsUpdate;
        private readonly Dictionary<ulong, bool> PlayersList;
        private readonly Dictionary<ulong, int> menuPageByUser;
        private readonly Dictionary<ulong, bool> actionsInProgress;

        private const float LEFT_PANEL_X = 0.377f;
        private const float CENTER_PANEL_X = 0.453f;
        private const float RIGHT_PANEL_X = 0.547f;
        private const float PANEL_WIDTH = 0.075f;
        private const float TOP_PANEL_Y = 0.915f;
        private const float PANEL_HEIGHT = 0.15f;

        private const float BASE_BUTTON_HEIGHT = 0.04f;
        private const float BASE_BUTTON_SPACING = 0.005f;
        private const float BASE_BUTTON_WIDTH = 0.075f;

        public TPMenu()
        {
            config = new PluginConfig();
            imageCache = new Dictionary<string, string>();
            homesCache = new Dictionary<ulong, Dictionary<string, Vector3>>();
            friendsCache = new Dictionary<ulong, List<ulong>>();
            lastHomesUpdate = new Dictionary<ulong, DateTime>();
            lastFriendsUpdate = new Dictionary<ulong, DateTime>();
            PlayersList = new Dictionary<ulong, bool>();
            menuPageByUser = new Dictionary<ulong, int>();
            actionsInProgress = new Dictionary<ulong, bool>();

            ImageLibrary = plugins.Find("ImageLibrary");
            Friends = plugins.Find("Friends");
            MutualPermission = plugins.Find("MutualPermission");
            NTeleportation = plugins.Find("NTeleportation");
            Teleport = plugins.Find("Teleport");
            Teleportation = plugins.Find("Teleportation");
            HomesGUI = plugins.Find("HomesGUI");
            Home = plugins.Find("Home");
            IQTeleportation = plugins.Find("IQTeleportation");
        }

        private void Loaded()
        {
            LoadData();
            permission.RegisterPermission("tpmenu.use", this);
            LoadConfig();

            cmd.RemoveConsoleCommand("tpmenu", this);
            cmd.AddConsoleCommand("tpmenu", this, nameof(cmdOpentpmenuConsole));

            if (config?.MainSettings?.Commands != null)
            {
                foreach (string command in config.MainSettings.Commands)
                {
                    cmd.AddChatCommand(command, this, nameof(cmdOpentpmenu));
                }
            }
        }

        [HookMethod("OnPluginLoaded")]
        private void OnPluginLoaded(Plugin plugin)
        {
            // Method intentionally left empty.}

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Создание новой конфигурации по умолчанию...");

            if (config == null)
            {
                return;
            }

            config.MainSettings = new MainSettings
            {
                Commands = new List<string> { "menu", "tpmenu" }.Distinct().ToList(),
                ShowOnConnect = false,
                ShowOnlyFirstConnect = false,
            };

            config.Homes = new ButtonConfig
            {
                Title = "ДОМА",
                ButtonColor = "0.19 0.19 0.21 0.75",
                TextColor = "1 1 1 1",
                ButtonText = new Dictionary<string, string> { { "ru", "ДОМА" } },
            };

            config.Friends = new ButtonConfig
            {
                Title = "ДРУЗЬЯ",
                ButtonColor = "0.19 0.19 0.21 0.75",
                TextColor = "1 1 1 1",
                ButtonText = new Dictionary<string, string> { { "ru", "ДРУЗЬЯ" } },
            };

            config.Home = new HomeSettings();
            config.FriendsSettings = new FriendSettings();
        }

        private void LoadConfig()
        {
            try
            {
                PluginConfig loadedConfig = null;
                if (Config.Exists())
                {
                    loadedConfig = Config.ReadObject<PluginConfig>();
                }

                if (loadedConfig != null)
                {
                    if (loadedConfig.MainSettings != null)
                    {
                        config.MainSettings = loadedConfig.MainSettings;
                        if (config.MainSettings.Commands != null)
                        {
                            config.MainSettings.Commands = config.MainSettings.Commands.Distinct().ToList();
                        }
                        if (config.MainSettings.ButtonSettings?.Buttons != null)
                        {
                            config.MainSettings.ButtonSettings.Buttons = config.MainSettings.ButtonSettings.Buttons.GroupBy(b => new
                                {
                                    b.Command,
                                    b.Text,
                                }).Select(g => g.First()).ToList();
                        }
                    }
                    if (loadedConfig.Homes != null)
                    {
                        config.Homes = loadedConfig.Homes;
                    }
                    if (loadedConfig.Friends != null)
                    {
                        config.Friends = loadedConfig.Friends;
                    }
                    if (loadedConfig.Home != null)
                    {
                        config.Home = loadedConfig.Home;
                    }
                    if (loadedConfig.FriendsSettings != null)
                    {
                        config.FriendsSettings = loadedConfig.FriendsSettings;
                    }
                    if (loadedConfig.ConfigVersion != default)
                    {
                        config.ConfigVersion = loadedConfig.ConfigVersion;
                    }
                }
                else
                {
                    LoadDefaultConfig();
                    SaveConfig();
                }

                config.MainSettings ??= new MainSettings();
                config.MainSettings.ButtonSettings ??= new ButtonSettings();

                if (config.MainSettings.Commands == null || config.MainSettings.Commands.Count == 0)
                {
                    config.MainSettings.Commands = new List<string> { "menu", "tpmenu" };
                }
                else
                {
                    config.MainSettings.Commands = config.MainSettings.Commands.Distinct().ToList();
                }

                if (
                    config.MainSettings.ButtonSettings.Buttons == null
                    || config.MainSettings.ButtonSettings.Buttons.Count == 0
                )
                {
                    config.MainSettings.ButtonSettings.Buttons = new List<MenuButton>
                    {
                        new() { Command = "chat.say /block", Text = "БЛОКИРОВКА" },
                        new() { Command = "chat.say /help", Text = "ПОМОЩЬ" },
                    };
                }
                else
                {
                    config.MainSettings.ButtonSettings.Buttons = config.MainSettings.ButtonSettings.Buttons.GroupBy(b => new { b.Command, b.Text }).Select(g => g.First()).ToList();
                }

                SaveConfig();
            }
            catch (Exception ex)
            {
                PrintError($"Error in LoadConfig: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private void UpdateConfigValues()
        {
            if (config.ConfigVersion < PluginConfig.DefaultConfig().ConfigVersion)
            {
                PrintWarning("Updating old config version...");
                PluginConfig baseConfig = PluginConfig.DefaultConfig();
                config.ConfigVersion = baseConfig.ConfigVersion;
                SaveConfig();
            }
        }

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

        private void LoadData()
        {
            try
            {
                PlayersList.Clear();
                Dictionary<ulong, bool> data = Interface.Oxide.DataFileSystem.ReadObject<
                    Dictionary<ulong, bool>
                >("tpmenu_Players");
                if (data != null)
                {
                    foreach (KeyValuePair<ulong, bool> kvp in data)
                    {
                        PlayersList[kvp.Key] = kvp.Value;
                    }
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error loading data: {ex.Message}");
                PlayersList.Clear();
            }
        }

        private void SaveData()
        {
            try
            {
                Interface.Oxide.DataFileSystem.WriteObject("tpmenu_Players", PlayersList);
            }
            catch (Exception ex)
            {
                PrintError($"Error saving data: {ex.Message}");
            }
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (!config.MainSettings.ShowOnConnect)
            {
                return;
            }

            if (config.MainSettings.ShowOnlyFirstConnect)
            {
                if (!PlayersList.ContainsKey(player.userID))
                {
                    PlayersList[player.userID] = true;
                    SaveData();
                    _ = timer.Once(2f, () => CreateMenu(player));
                }
            }
            else
            {
                _ = timer.Once(2f, () => CreateMenu(player));
            }
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            _ = homesCache.Remove(player.userID);
            _ = friendsCache.Remove(player.userID);
            _ = lastHomesUpdate.Remove(player.userID);
            _ = lastFriendsUpdate.Remove(player.userID);
            _ = actionsInProgress.Remove(player.userID);
        }

        private Dictionary<string, Vector3> GetHomes(ulong playerid)
        {
            try
            {
                if (
                    homesCache.TryGetValue(playerid, out Dictionary<string, Vector3>? cachedHomes)
                    && lastHomesUpdate.TryGetValue(playerid, out DateTime lastUpdate)
                    && (DateTime.Now - lastUpdate).TotalSeconds < CACHE_TIMEOUT
                )
                {
                    return cachedHomes;
                }

                BasePlayer player = BasePlayer.FindByID(playerid);
                if (player == null)
                {
                    return new Dictionary<string, Vector3>();
                }

                Dictionary<string, Vector3> homes = new();

                Plugin IQTeleportation = plugins.Find("IQTeleportation");
                if (IQTeleportation != null)
                {
                    try
                    {
                        object homeResult = IQTeleportation.Call("GetHomes", playerid);
                        if (homeResult is Dictionary<string, Vector3> iqHomes)
                        {
                            foreach (KeyValuePair<string, Vector3> home in iqHomes)
                            {
                                homes[home.Key] = home.Value;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        PrintError($"Ошибка при получении домов из IQTeleportation: {ex.Message}");
                    }
                }

                if (NTeleportation != null)
                {
                    if (
                        NTeleportation?.Call("API_GetHomes", player)
                        is Dictionary<string, Vector3> ntHomes
                    )
                    {
                        foreach (KeyValuePair<string, Vector3> home in ntHomes)
                        {
                            homes[home.Key] = home.Value;
                        }
                    }
                }

                if (Teleport != null)
                {
                    if (
                        Teleport?.Call("ApiGetHomes", playerid)
                        is Dictionary<string, Vector3> tpHomes
                    )
                    {
                        foreach (KeyValuePair<string, Vector3> home in tpHomes)
                        {
                            homes[home.Key] = home.Value;
                        }
                    }
                }

                if (Teleportation != null)
                {
                    if (
                        Teleportation?.Call("GetHomes", playerid)
                        is Dictionary<string, Vector3> telHomes
                    )
                    {
                        foreach (KeyValuePair<string, Vector3> home in telHomes)
                        {
                            homes[home.Key] = home.Value;
                        }
                    }
                }

                if (HomesGUI != null)
                {
                    if (
                        HomesGUI?.Call("GetPlayerHomes", playerid.ToString())
                        is Dictionary<string, Vector3> guiHomes
                    )
                    {
                        foreach (KeyValuePair<string, Vector3> home in guiHomes)
                        {
                            homes[home.Key] = home.Value;
                        }
                    }
                }

                homesCache[playerid] = homes;
                lastHomesUpdate[playerid] = DateTime.Now;
                return homes;
            }
            catch (Exception ex)
            {
                PrintError($"Error in GetHomes: {ex.Message}");
                return new Dictionary<string, Vector3>();
            }
        }

        private List<ulong> GetFriends(ulong playerid)
        {
            try
            {
                if (
                    friendsCache.TryGetValue(playerid, out List<ulong>? cachedFriends)
                    && lastFriendsUpdate.TryGetValue(playerid, out DateTime lastUpdate)
                    && (DateTime.Now - lastUpdate).TotalSeconds < CACHE_TIMEOUT
                )
                {
                    return cachedFriends;
                }

                List<ulong> result = new();

                if (Friends != null && Friends?.Call("GetFriends", playerid) is ulong[] friends)
                {
                    result.AddRange(friends);
                }

                friendsCache[playerid] = result;
                lastFriendsUpdate[playerid] = DateTime.Now;
                return result;
            }
            catch (Exception ex)
            {
                PrintError($"Error in GetFriends: {ex.Message}");
                return new List<ulong>();
            }
        }

        private bool IsPlayerOnline(ulong friendId)
        {
            BasePlayer player = BasePlayer.FindByID(friendId);
            return player?.IsConnected == true;
        }

        private string GetFriendName(ulong friendId)
        {
            try
            {
                BasePlayer player = BasePlayer.FindByID(friendId);
                if (player != null)
                {
                    return player.displayName.Length > 10
                        ? player.displayName.Substring(0, 7) + "*"
                        : player.displayName;
                }

                IPlayer offlinePlayer = covalence.Players.FindPlayerById(friendId.ToString());
                if (offlinePlayer != null)
                {
                    string name = offlinePlayer.Name;
                    return name.Length > 10 ? name.Substring(0, 7) + "*" : name;
                }

                if (Friends != null)
                {
                    if (
                        Friends?.Call("GetFriendData", friendId)
                            is Dictionary<string, object> friendData
                        && friendData.TryGetValue("name", out object? value)
                    )
                    {
                        string name = value.ToString();
                        return name.Length > 10 ? name.Substring(0, 7) + "*" : name;
                    }
                }

                return friendId.ToString();
            }
            catch (Exception ex)
            {
                PrintError($"Error in GetFriendName: {ex.Message}");
                return friendId.ToString();
            }
        }

        private bool IsTeamLeader(BasePlayer player)
        {
            RelationshipManager.PlayerTeam team =
                RelationshipManager.ServerInstance.FindPlayersTeam(player.userID);
            return team?.teamLeader == player.userID;
        }

        private string GetGridString(Vector3 position)
        {
            Vector2 adjPosition = new((World.Size / 2) + position.x, (World.Size / 2) - position.z);
            return $"{NumberToString((int)(adjPosition.x / 150))}{(int)(adjPosition.y / 150)}";
        }

        private string NumberToString(int number)
        {
            bool a = number > 26;
            char c = (char)(65 + (a ? number - 26 : number));
            return a ? "A" + c : c.ToString();
        }

        private int GetFreeHomesCount(BasePlayer player)
        {
            try
            {
                const int defaultMaxHomes = 5;

                if (config?.Home != null)
                {
                    int count = config.Home.MaxHomes;
                    if (count <= 0)
                    {
                        count = defaultMaxHomes;
                    }

                    if (config.Home.PermissionsHomes?.Count > 0)
                    {
                        foreach (KeyValuePair<string, int> perm in config.Home.PermissionsHomes)
                        {
                            if (permission.UserHasPermission(player.UserIDString, perm.Key))
                            {
                                count = perm.Value;
                                break;
                            }
                        }
                    }

                    return count;
                }
                else if (config?.Homes != null)
                {
                    int count = config.Homes.MaxHomes;
                    if (count <= 0)
                    {
                        count = defaultMaxHomes;
                    }

                    if (config.Homes.PermissionsHomes?.Count > 0)
                    {
                        foreach (KeyValuePair<string, int> perm in config.Homes.PermissionsHomes)
                        {
                            if (permission.UserHasPermission(player.UserIDString, perm.Key))
                            {
                                count = perm.Value;
                                break;
                            }
                        }
                    }

                    return count;
                }

                PrintWarning(
                    "Не удалось найти настройки для домов в конфигурации, используем значение по умолчанию"
                );
                return defaultMaxHomes;
            }
            catch (Exception ex)
            {
                PrintError($"Error in GetFreeHomesCount: {ex.Message}");
                return 5;
            }
        }

        private int GetCurrentPage(BasePlayer player)
        {
            List<KeyValuePair<string, Vector3>> homes = GetHomes(player.userID).ToList();
            return (int)Math.Ceiling(homes.Count / 5.0f);
        }

        private string GetImage(string url)
        {
            if (ImageLibrary == null || string.IsNullOrEmpty(url))
            {
                return string.Empty;
            }

            return imageCache.TryGetValue(url, out string cachedImage)
                ? cachedImage
                : (imageCache[url] = (string)ImageLibrary.Call("GetImage", url) ?? string.Empty);
        }

        private void cmdOpentpmenu(BasePlayer player, string command, string[] args)
        {
            try
            {
                if (!permission.UserHasPermission(player.UserIDString, "tpmenu.use"))
                {
                    player.ChatMessage("У вас нет разрешения на использование этой команды");
                    return;
                }

                DestroyUI(player);
                CreateMenu(player);
            }
            catch (Exception ex)
            {
                PrintError($"Error in cmdOpentpmenu: {ex.Message}\n{ex.StackTrace}");
            }
        }

        [ConsoleCommand("tpmenu")]
        private void cmdOpentpmenuConsole(ConsoleSystem.Arg arg)
        {
            try
            {
                BasePlayer player = arg.Player();
                if (player == null)
                {
                    return;
                }

                if (!permission.UserHasPermission(player.UserIDString, "tpmenu.use"))
                {
                    player.ChatMessage("У вас нет разрешения на использование этой команды");
                    return;
                }

                DestroyUI(player);
                CreateMenu(player);
            }
            catch (Exception ex)
            {
                PrintError($"Error in cmdOpentpmenuConsole: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private void DestroyAllButtons(BasePlayer player)
        {
            for (int i = 0; i < 600; i++)
            {
                _ = CuiHelper.DestroyUi(player, $"{MainLayer}.ButtonOutline.{i}");
            }

            for (int i = 0; i < 10; i++)
            {
                _ = CuiHelper.DestroyUi(player, $"HomeRemove_{i}");
            }

            _ = CuiHelper.DestroyUi(player, "PrevPageButton");
            _ = CuiHelper.DestroyUi(player, "PageIndicator");
            _ = CuiHelper.DestroyUi(player, "NextPageButton");
        }

        [ConsoleCommand("tpmenu_UI")]
        private void cmdtpmenuCommands(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            if (player == null)
            {
                return;
            }

            switch (args.GetString(0).ToLower(System.Globalization.CultureInfo.CurrentCulture))
            {
                case "close":
                    DestroyUI(player);
                    break;
                case "home":
                    if (args.Args.Length > 1)
                    {
                        string homeName = args.GetString(1);
                        player.Command("chat.say", $"/home {homeName}");
                        _ = timer.Once(0.1f, () => CreateMenu(player));
                    }
                    break;
                case "removehome":
                    if (args.Args.Length > 1)
                    {
                        if (IsActionInProgress(player.userID))
                        {
                            player.ChatMessage("Дождитесь завершения предыдущего действия");
                            return;
                        }

                        SetActionInProgress(player.userID, true);
                        string homeName = args.GetString(1);
                        player.Command("chat.say", $"/removehome {homeName}");

                        _ = homesCache.Remove(player.userID);
                        _ = lastHomesUpdate.Remove(player.userID);

                        _ = timer.Once(
                            0.1f,
                            () =>
                            {
                                CreateMenu(player);
                                SetActionInProgress(player.userID, false);
                            }
                        );
                    }
                    break;
                case "switchpage":
                    if (args.Args.Length > 1 && int.TryParse(args.GetString(1), out int page))
                    {
                        if (IsActionInProgress(player.userID))
                        {
                            return;
                        }

                        SetActionInProgress(player.userID, true);

                        try
                        {
                            Dictionary<string, Vector3> homes = GetHomes(player.userID);
                            int totalPages = (int)Math.Ceiling(homes.Count / 5.0f);
                            if (totalPages == 0)
                            {
                                totalPages = 1;
                            }

                            if (page < 1)
                            {
                                page = 1;
                            }

                            if (page > totalPages)
                            {
                                page = totalPages;
                            }

                            DestroyUI(player);
                            CreateMenu(player, page);
                        }
                        finally
                        {
                            SetActionInProgress(player.userID, false);
                        }
                    }
                    break;
                case "scroll":
                    if (args.Args.Length > 1)
                    {
                        DestroyUI(player);
                        CreateMenu(player);
                    }
                    break;
                case "sethome":
                    if (args.Args.Length > 1)
                    {
                        if (IsActionInProgress(player.userID))
                        {
                            player.ChatMessage("Дождитесь завершения предыдущего действия");
                            return;
                        }

                        SetActionInProgress(player.userID, true);
                        string gridPos = args.GetString(1);
                        string homeName = gridPos.Length > 7 ? gridPos.Substring(0, 7) : gridPos;

                        player.Command("chat.say", $"/sethome {homeName}");

                        _ = homesCache.Remove(player.userID);
                        _ = lastHomesUpdate.Remove(player.userID);

                        _ = timer.Once(
                            0.1f,
                            () =>
                            {
                                CreateMenu(player);
                                SetActionInProgress(player.userID, false);
                            }
                        );
                    }
                    break;
                case "friend":
                    if (
                        args.Args.Length > 1
                        && ulong.TryParse(args.GetString(1), out ulong friendId)
                    )
                    {
                        DestroyUI(player);
                        player.Command("chat.say", $"/tpr {friendId}");
                    }
                    break;
                case "addfriend":
                    DestroyUI(player);
                    if (Friends != null)
                    {
                        _ = Friends.Call("ShowFriends", player);

                        ResetCache(player.userID);
                    }
                    else
                    {
                        player.ChatMessage("Плагин Friends не найден!");
                    }
                    break;
                case "removefriend":
                    if (
                        args.Player() != null
                        && ulong.TryParse(args.GetString(1), out ulong friendToRemove)
                    )
                    {
                        _ = Friends.Call("fremove", friendToRemove);
                        ResetCache(args.Player().userID);
                        ResetCache(friendToRemove);
                        UpdateFriendsPanel(args.Player());
                    }
                    break;
            }
        }

        private void UpdateHomePanel(BasePlayer player, int page)
        {
            try
            {
                if (config.Home == null)
                {
                    PrintError("Home settings are null! Initializing default settings.");
                    config.Home = new HomeSettings();
                    SaveConfig();
                }

                CuiElementContainer container = new();

                const string homePanel = MainLayer + ".Home";

                _ = container.Add(
                    new CuiLabel
                    {
                        RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                        Text =
                        {
                            Text = $"<color=#ff8c08>{config.Home.Title}</color>",
                            FontSize = 20,
                            Align = TextAnchor.MiddleCenter,
                            Font = BOLD_FONT_NAME,
                        },
                    },
                    homePanel + ".Title"
                );

                List<KeyValuePair<string, Vector3>> homes = GetHomes(player.userID).ToList();
                int maxHomes = GetFreeHomesCount(player);

                int totalPages = (int)Math.Ceiling(homes.Count / 5.0f);
                if (totalPages == 0)
                {
                    totalPages = 1;
                }

                if (page > totalPages)
                {
                    page = totalPages;
                }

                List<KeyValuePair<string, Vector3>> pageHomes = homes.Skip((page - 1) * 5).Take(5).ToList();

                const float startButtonY = 0.635f;
                const float homeButtonX = 0.377f;

                for (int i = 0; i < Math.Min(pageHomes.Count, 5); i++)
                {
                    KeyValuePair<string, Vector3> home = pageHomes[i];
                    float buttonY = startButtonY - (i * (BUTTON_HEIGHT + BUTTON_SPACING));

                    ButtonConfig buttonConfig = new()
                    {
                        Command = $"tpmenu_UI home {home.Key}",
                        ButtonColor = "0.19 0.19 0.21 0.75",
                        TextColor = "1 1 1 1",
                        ButtonText = new Dictionary<string, string>
                        {
                            { "ru", $"<color=#ff8c08>{home.Key}</color>" },
                        },
                    };

                    CreateButton(container, buttonConfig, homeButtonX, buttonY, 100 + i, player);

                    string removeButtonId = $"HomeRemove_{i}";
                    _ = container.Add(
                        new CuiButton
                        {
                            RectTransform =
                            {
                                AnchorMin =
                                    $"{homeButtonX + BUTTON_WIDTH - 0.015f} {buttonY + 0.005f}",
                                AnchorMax =
                                    $"{homeButtonX + BUTTON_WIDTH - 0.002f} {buttonY + BUTTON_HEIGHT - 0.005f}",
                            },
                            Button =
                            {
                                Color = "0.8 0 0 0.7",
                                Command = $"tpmenu_UI removehome {home.Key}",
                            },
                            Text =
                            {
                                Text = "×",
                                FontSize = FONT_SIZE + 4,
                                Align = TextAnchor.MiddleCenter,
                                Color = "1 1 1 1",
                                Font = BOLD_FONT_NAME,
                            },
                        },
                        MainLayer,
                        removeButtonId
                    );
                }

                int buttonCount = Math.Min(pageHomes.Count, 5);

                bool showNavigationButtons = homes.Count > 5;

                if (page == 1 && homes.Count > 5)
                {
                    const float buttonY = startButtonY - (5 * (BUTTON_HEIGHT + BUTTON_SPACING));
                    const float smallButtonWidth = BUTTON_WIDTH / 4;

                    const float textWidth = BUTTON_WIDTH - (2 * smallButtonWidth);
                    const float textX = homeButtonX + smallButtonWidth;
                    _ = container.Add(
                        new CuiLabel
                        {
                            RectTransform =
                            {
                                AnchorMin = $"{textX} {buttonY}",
                                AnchorMax = $"{textX + textWidth} {buttonY + BUTTON_HEIGHT}",
                            },
                            Text =
                            {
                                Text = "<color=#FFFFFF>1/2</color>",
                                FontSize = FONT_SIZE,
                                Align = TextAnchor.MiddleCenter,
                                Font = BOLD_FONT_NAME,
                            },
                        },
                        MainLayer,
                        "PageIndicator"
                    );

                    const float rightButtonX = textX + textWidth;
                    _ = container.Add(
                        new CuiButton
                        {
                            RectTransform =
                            {
                                AnchorMin = $"{rightButtonX} {buttonY}",
                                AnchorMax =
                                    $"{rightButtonX + smallButtonWidth} {buttonY + BUTTON_HEIGHT}",
                            },
                            Button =
                            {
                                Color = "0.19 0.19 0.21 0.75",
                                Command = "tpmenu_UI switchpage 2",
                            },
                            Text =
                            {
                                Text = "►",
                                FontSize = FONT_SIZE,
                                Align = TextAnchor.MiddleCenter,
                                Color = "1 1 1 0.8",
                                Font = BOLD_FONT_NAME,
                            },
                        },
                        MainLayer,
                        "NextPageButton"
                    );
                }
                else if (page > 1)
                {
                    const float buttonY = startButtonY - (5 * (BUTTON_HEIGHT + BUTTON_SPACING));
                    const float smallButtonWidth = BUTTON_WIDTH / 4;

                    _ = container.Add(
                        new CuiButton
                        {
                            RectTransform =
                            {
                                AnchorMin = $"{homeButtonX} {buttonY}",
                                AnchorMax =
                                    $"{homeButtonX + smallButtonWidth} {buttonY + BUTTON_HEIGHT}",
                            },
                            Button =
                            {
                                Color = "0.19 0.19 0.21 0.75",
                                Command = "tpmenu_UI switchpage 1",
                            },
                            Text =
                            {
                                Text = "◄",
                                FontSize = FONT_SIZE,
                                Align = TextAnchor.MiddleCenter,
                                Color = "1 1 1 0.8",
                                Font = BOLD_FONT_NAME,
                            },
                        },
                        MainLayer,
                        "PrevPageButton"
                    );

                    const float textWidth = BUTTON_WIDTH - (2 * smallButtonWidth);
                    const float textX = homeButtonX + smallButtonWidth;
                    _ = container.Add(
                        new CuiLabel
                        {
                            RectTransform =
                            {
                                AnchorMin = $"{textX} {buttonY}",
                                AnchorMax = $"{textX + textWidth} {buttonY + BUTTON_HEIGHT}",
                            },
                            Text =
                            {
                                Text = "<color=#FFFFFF>2/2</color>",
                                FontSize = FONT_SIZE,
                                Align = TextAnchor.MiddleCenter,
                                Font = BOLD_FONT_NAME,
                            },
                        },
                        MainLayer,
                        "PageIndicator"
                    );
                }

                if (homes.Count < maxHomes)
                {
                    if (page == 1 && homes.Count <= 5)
                    {
                        float buttonY =
                            startButtonY - (buttonCount * (BUTTON_HEIGHT + BUTTON_SPACING));

                        ButtonConfig addButtonConfig = new()
                        {
                            Command =
                                $"tpmenu_UI sethome {GetGridString(player.transform.position)}",
                            ButtonColor = "0.19 0.19 0.21 0.75",
                            TextColor = "1 1 1 1",
                            ButtonText = new Dictionary<string, string>
                            {
                                { "ru", "<color=#00FF00>ДОБАВИТЬ</color>" },
                            },
                        };

                        CreateButton(container, addButtonConfig, homeButtonX, buttonY, 200, player);
                    }
                    else if (page > 1 && pageHomes.Count < 5)
                    {
                        float buttonY =
                            startButtonY - (pageHomes.Count * (BUTTON_HEIGHT + BUTTON_SPACING));

                        ButtonConfig addButtonConfig = new()
                        {
                            Command =
                                $"tpmenu_UI sethome {GetGridString(player.transform.position)}",
                            ButtonColor = "0.19 0.19 0.21 1",
                            TextColor = "1 1 1 1",
                            ButtonText = new Dictionary<string, string>
                            {
                                { "ru", "<color=#00FF00>ДОБАВИТЬ</color>" },
                            },
                        };

                        CreateButton(container, addButtonConfig, homeButtonX, buttonY, 200, player);
                    }
                }

                _ = container.Add(
                    new CuiLabel
                    {
                        RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 0.35" },
                        Text =
                        {
                            Text = "<color=#FFFFFF>АВТОЗАКРЫТИЕ</color>",
                            FontSize = 16,
                            Align = TextAnchor.MiddleCenter,
                            Font = BOLD_FONT_NAME,
                        },
                    },
                    homePanel
                );

                const float autodoorButtonY =
                    startButtonY - (6 * (BUTTON_HEIGHT + BUTTON_SPACING)) - 0.02f;

                ButtonConfig autodoorButtonConfig = new()
                {
                    Command = "chat.say /ad",
                    ButtonColor = "0.19 0.19 0.21 0.75",
                    TextColor = "1 1 1 1",
                    ButtonText = new Dictionary<string, string>
                    {
                        { "ru", "<color=#FFFFFF>АВТОЗАКРЫТИЕ</color>" },
                    },
                };

                CreateButton(
                    container,
                    autodoorButtonConfig,
                    homeButtonX,
                    autodoorButtonY,
                    250,
                    player
                );

                _ = CuiHelper.AddUi(player, container);
            }
            catch (Exception ex)
            {
                PrintError($"Error in UpdateHomePanel: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private void UpdateFriendsPanel(BasePlayer player)
        {
            try
            {
                _ = CuiHelper.DestroyUi(player, "FriendsPanel");

                DestroyAllButtons(player);

                CuiElementContainer container = new();
                CreateFriendsPanel(container, player);
                _ = CuiHelper.AddUi(player, container);
            }
            catch (Exception ex)
            {
                PrintError($"Error in UpdateFriendsPanel: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private void DestroyUI(BasePlayer player)
        {
            try
            {
                _ = CuiHelper.DestroyUi(player, MainLayer);
            }
            catch (Exception ex)
            {
                PrintError($"Error in DestroyUI: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private void Unload()
        {
            foreach (BasePlayer? player in BasePlayer.activePlayerList)
            {
                DestroyUI(player);
            }
        }

        private void CreateMenu(BasePlayer player, int page = 1)
        {
            try
            {
                DestroyUI(player);
                CuiElementContainer container = new();

                _ = container.Add(
                    new CuiPanel
                    {
                        CursorEnabled = true,
                        RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                        Image = { Color = "0 0 0 0" },
                    },
                    "Overlay",
                    MainLayer
                );

                _ = container.Add(
                    new CuiButton
                    {
                        RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                        Button = { Color = "0 0 0 0", Command = "tpmenu_UI close" },
                        Text = { Text = "" },
                    },
                    MainLayer,
                    MainLayer + ".Background"
                );

                CreatePanels(container, player, TITLE_FONT_SIZE);

                CreateButtons(container, player, page);

                _ = CuiHelper.AddUi(player, container);
            }
            catch (Exception ex)
            {
                PrintError($"Error in CreateMenu: {ex.Message}");
            }
        }

        private void CreatePanels(
            CuiElementContainer container,
            BasePlayer player,
            int titleFontSize
        )
        {
            CreatePanel(
                container,
                "TeleportPanel",
                $"{LEFT_PANEL_X} {TOP_PANEL_Y - PANEL_HEIGHT}",
                $"{LEFT_PANEL_X + PANEL_WIDTH} {TOP_PANEL_Y}",
                "<color=#ff8c08>ТЕЛЕПОРТ</color>",
                titleFontSize
            );

            CreatePanel(
                container,
                "MenuPanel",
                $"{CENTER_PANEL_X} {TOP_PANEL_Y - PANEL_HEIGHT}",
                $"{CENTER_PANEL_X + PANEL_WIDTH} {TOP_PANEL_Y}",
                "",
                titleFontSize
            );

            _ = container.Add(
                new CuiPanel
                {
                    RectTransform =
                    {
                        AnchorMin = $"{CENTER_PANEL_X} {TOP_PANEL_Y - PANEL_HEIGHT}",
                        AnchorMax = $"{RIGHT_PANEL_X} {TOP_PANEL_Y}",
                    },
                    Image = { Color = "0 0 0 0" },
                },
                MainLayer,
                "MenuTitlePanel"
            );

            _ = container.Add(
                new CuiLabel
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                    Text =
                    {
                        Text = "<color=#ff8c08>МЕНЮ</color>",
                        FontSize = titleFontSize,
                        Align = TextAnchor.MiddleCenter,
                        Font = BOLD_FONT_NAME,
                    },
                },
                "MenuTitlePanel"
            );

            CreatePanel(
                container,
                "TradePanel",
                $"{RIGHT_PANEL_X} {TOP_PANEL_Y - PANEL_HEIGHT}",
                $"{RIGHT_PANEL_X + PANEL_WIDTH} {TOP_PANEL_Y}",
                "<color=#ff8c08>ОБМЕН</color>",
                titleFontSize
            );

            CreateTeleportButtons(container, player);
            CreateTradeButtons(container, player);

            _ = container.Add(
                new CuiLabel
                {
                    RectTransform =
                    {
                        AnchorMin = $"{CENTER_PANEL_X - 0.02} 0.37",
                        AnchorMax = $"{RIGHT_PANEL_X + 0.02} 0.41",
                    },
                    Text =
                    {
                        Text = "<color=#ff8c08>Frenetic</color> Rust",
                        FontSize = titleFontSize,
                        Align = TextAnchor.MiddleCenter,
                        Font = BOLD_FONT_NAME,
                    },
                },
                MainLayer
            );

            _ = container.Add(
                new CuiLabel
        
// ... [Code preview truncated due to length. Full source in attached file] ...

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