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

FREE MBReward : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("MBReward", "Barry_Allenn", "1.0.0")]
    [Description("MBReward")] 
    public class MBReward : RustPlugin
    {
        [PluginReference] private Plugin ImageLibrary, MBMainMenu;

        private ImageUI imageUI = new ImageUI();

        private ConfigData configData;

        private class ConfigData
        {
            [JsonProperty("Команды")]
            public List<CommandEntry> Commands = new();

            [JsonProperty("Интервал в минутах для награды за онлайн")]
            public float OnlineRewardIntervalMinutes = 360f; // 6 часов


            [JsonProperty("Количество монет за онлайн")]
            public int OnlineRewardAmount = 1;

            [JsonProperty("Количество монет за первый вход")]
            public int FirstJoinRewardAmount = 5;

        }

        public class CommandEntry
        {
            public string Command;
            public string LangKey;
        }

        private Dictionary<ulong, double> onlineTimes = new();
        private Dictionary<ulong, double> lastCheckTimes = new();
        private const string DataFileName = "MBReward_OnlineData";

        private class OnlineData
        {
            public Dictionary<ulong, double> OnlineSeconds = new();
            public Dictionary<ulong, bool> FirstJoinGiven = new();

        }
        private OnlineData onlineData = new();

        protected override void LoadConfig()
{
    base.LoadConfig();
    configData = Config.ReadObject<ConfigData>();
}


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

        protected override void LoadDefaultConfig()
        {
            configData = new ConfigData
            {
                Commands = new List<CommandEntry>
                {
                    new CommandEntry { Command = "+1", LangKey = "Command_Home_Desc" },
                    new CommandEntry { Command = "+5", LangKey = "Command_Warp_Desc" }
                },
                OnlineRewardIntervalMinutes = 360f,
                OnlineRewardAmount = 1,
                FirstJoinRewardAmount = 5

            };

            SaveConfig();
        }


        void Init()
{
    LoadConfig();       // Чтение конфига
    LoadOnlineData();   // Чтение базы
}



        private void OnServerInitialized()
        {
            imageUI = new ImageUI();
            imageUI.DownloadImages();
            timer.Every(60f, TrackOnlineTime);
            // LoadOnlineData();
        }

        void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, "MBReward_UI");
            }

            imageUI?.UnloadImages();
            SaveOnlineData();
        }

        private void GiveCoins(BasePlayer player, int amount)
        {
            Server.Command($"mb.give {player.UserIDString} {amount}");
        }

        private float saveInterval = 300f; // Интервал сохранения в секундах (10 минут)
        private double lastSaveTime = 0;

        private void TrackOnlineTime()
        {
            double now = Interface.Oxide.Now;

            foreach (var player in BasePlayer.activePlayerList)
            {
                if (player == null || !player.IsConnected) continue;

                ulong userId = player.userID;

                if (!lastCheckTimes.ContainsKey(userId))
                    lastCheckTimes[userId] = now;

                double elapsed = now - lastCheckTimes[userId];
                lastCheckTimes[userId] = now;

                if (!onlineData.OnlineSeconds.ContainsKey(userId))
                    onlineData.OnlineSeconds[userId] = 0;

                onlineData.OnlineSeconds[userId] += elapsed;

                float minutesOnline = (float)(onlineData.OnlineSeconds[userId] / 60f);
                if (minutesOnline >= configData.OnlineRewardIntervalMinutes)
                {
                    GiveCoins(player, configData.OnlineRewardAmount);
                    onlineData.OnlineSeconds[userId] = 0;
                    player.ChatMessage($"Вы получили {configData.OnlineRewardAmount} монет за {configData.OnlineRewardIntervalMinutes} мин.онлайна!");
                }
            }

            // ⏳ Автосохранение раз в saveInterval секунд
            if (now - lastSaveTime >= saveInterval)
            {
                SaveOnlineData();
                lastSaveTime = now;
            }
        }


        private void SaveOnlineData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(DataFileName, onlineData);
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            ulong userId = player.userID;

            if (!onlineData.FirstJoinGiven.ContainsKey(userId))
            {
                int amount = configData.FirstJoinRewardAmount;
                if (amount > 0)
                {
                    GiveCoins(player, amount);
                    player.ChatMessage(Msg("MB_FirstJoinReward", player.UserIDString, amount));
                }

                onlineData.FirstJoinGiven[userId] = true;
                SaveOnlineData();
                Puts($"[MBReward] {player.displayName} получил награду за первый вход");
            }
        }

        private void LoadOnlineData()
        {
            onlineData = Interface.Oxide.DataFileSystem.ReadObject<OnlineData>(DataFileName) ?? new OnlineData();
        }

        // В классе MBReward добавьте этот метод
        [HookMethod("GetTimeToReward")]
        public object GetTimeToReward(BasePlayer player)
        {
            if (!onlineData.OnlineSeconds.ContainsKey(player.userID))
                return Msg("MB_Reward_Zero", player.UserIDString); // 0хв

            double secondsPlayed = onlineData.OnlineSeconds[player.userID];
            double secondsNeeded = configData.OnlineRewardIntervalMinutes * 60;
            double secondsRemaining = secondsNeeded - secondsPlayed;

            if (secondsRemaining <= 0)
                return Msg("MB_Reward_Ready", player.UserIDString); // готово

            TimeSpan timeLeft = TimeSpan.FromSeconds(secondsRemaining);

            if (timeLeft.Hours > 0)
                return Msg("MB_Reward_Format_HM", player.UserIDString, timeLeft.Hours, timeLeft.Minutes);
            else
                return Msg("MB_Reward_Format_M", player.UserIDString, timeLeft.Minutes);
        }

        private void ShowCoinsUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "MBReward_UI");

            var container = new CuiElementContainer();

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

            string backgroundPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0.7", Material = "assets/content/ui/uibackgroundblur.mat" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                CursorEnabled = true
            }, root);

            container.Add(new CuiButton
            {
                Button = { Color = "0 0 0 0", Close = "MBReward_UI" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "", FontSize = 0 }
            }, root);

            string imageId = imageUI?.GetImage("MBWelcome_Seven_Os");
            if (!string.IsNullOrEmpty(imageId))
            {
                container.Add(new CuiElement
                {
                    Name = CuiHelper.GetGuid(),
                    Parent = root,
                    Components =
                    {
                        new CuiRawImageComponent { Png = imageId },
                        new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-558 -314", OffsetMax = "558 315" }
                    }
                });
            }

            container.Add(new CuiButton
            {
                Button = { Color = "0 0 0 0", Close = "MBReward_UI" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "", FontSize = 0 }
            }, root);

            string centerPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0" },
                RectTransform = {
                    AnchorMin = "0.5 0.5",
                    AnchorMax = "0.5 0.5",
                    OffsetMin = "-438 -265", // ширина 800, высота 600
                    OffsetMax = "440 265"
                },
                CursorEnabled = true
            }, root);



            //     // Панель-фон
            // container.Add(new CuiPanel
            //     {
            //         Image = { Color = "0 0 0 0.9" }, // Темно-сірий прозорий фон
            //         RectTransform = { AnchorMin = "0.3 0.09", AnchorMax = "0.7 0.11" }
            //     }, root);

            //            // Панель-фон
            // container.Add(new CuiPanel
            //     {
            //         Image = { Color = "1 1 1 0.4" }, // Темно-сірий прозорий фон
            //         RectTransform = { AnchorMin = "0.2 -0.06", AnchorMax = "0.8 -0.02" }
            //     }, centerPanel);



            container.Add(new CuiLabel
            {
                RectTransform = { AnchorMin = "0.341 0.86", AnchorMax = "0.75 0.955" },
                Text = { Text = Msg("MB_Coins_Player", player.userID.ToString()), Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, FontSize = 30 }
            }, centerPanel);

            container.Add(new CuiLabel
            {
                RectTransform = { AnchorMin = "0.341 0.8", AnchorMax = "0.8 0.868" },
                Text = { Text = Msg("MB_Coins_Player_2", player.userID.ToString()), Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, FontSize = 21, Font = "permanentmarker.ttf" }
            }, centerPanel);

            container.Add(new CuiLabel
            {
                Text = { Text = Msg("MB_Close_Coins", player.userID.ToString()), FontSize = 13, Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter },
                RectTransform = { AnchorMin = "0.2 -0.06", AnchorMax = "0.8 -0.02" }
            }, centerPanel);

            container.Add(new CuiButton
            {
                Button = {
                    Command = "mbcoins.back",  // кастомная команда
                    Color = "0.2 0.5 0.8 0"
                },
                RectTransform = { AnchorMin = "0.865 0.04", AnchorMax = "0.947 0.12" },
                Text = {
                    Text = Msg("MB_Back", player.UserIDString),
                    FontSize = 15,
                    Align = TextAnchor.MiddleCenter,
                    Color = "1 1 1 1"
                }
            }, centerPanel);

            // 📐 Настройки ячеек
            float blockWidth = 175f;
            float blockHeight = 132f;
            float blockMargin = 8f;

            int totalCommands = configData.Commands.Count;
            int rows = 2;
            int columns = Mathf.CeilToInt(totalCommands / (float)rows);

            // 📏 Общая ширина контента
            float scrollContentWidth = columns * (blockWidth + blockMargin);
            scrollContentWidth = Mathf.Max(scrollContentWidth, 600f); // минимальная ширина

            // 🖼️ ScrollView (видимая область) с адаптивным якорем
            container.Add(new CuiElement
            {
                Name = "MBCoinsArea",
                Parent = centerPanel,
                Components =
    {
        new CuiScrollViewComponent
        {
            Horizontal = true,
            Vertical = false,
            Inertia = true,
            Elasticity = 0.2f,
            DecelerationRate = 0.2f,
            ScrollSensitivity = 30f,
            ContentTransform = new CuiRectTransform
            {
                AnchorMin = "0 0.015",
                AnchorMax = "0 1",
                OffsetMin = "0 0",
                OffsetMax = $"{scrollContentWidth} 0"
            },
            HorizontalScrollbar = new CuiScrollbar
            {
                Size = 5f,
                AutoHide = false,
                HandleColor = "0.3 0.6 0.9 0.7",
                TrackColor = "0.1 0.1 0.1 0.6"
            }
        },
        new CuiRectTransformComponent
        {
            AnchorMin = "0.34 0.235", AnchorMax = "0.74 0.75"
        },
        new CuiNeedsCursorComponent()
    }
            });

            // 🔲 Контейнер содержимого — это то, что листается
            container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0" },
                RectTransform = {
        AnchorMin = "0 0",
        AnchorMax = "0 1",
        OffsetMin = "0 0",
        OffsetMax = $"{scrollContentWidth} 0"
    }
            }, "MBCoinsArea", "MBCoinsContent");

            float startOffsetX = 3f; // 👈 отступ слева перед первым блоком


            // 🧩 Генерация ячеек
            for (int i = 0; i < totalCommands; i++)
            {
                int column = i / rows;
                int row = i % rows;

                float left = startOffsetX + column * (blockWidth + blockMargin);
                float right = left + blockWidth;

                float top = (row == 0) ? blockHeight + blockMargin : 0;
                float bottom = top + blockHeight;

                var entry = configData.Commands[i];
                string cmd = entry.Command;
                string desc = Msg(entry.LangKey, player.UserIDString);
                string backgroundImg = imageUI.GetImage("MBCoins_BG");
                string containerName = $"MBCoinsContent_{i}";

                // 📦 Контейнер блока
                container.Add(new CuiPanel
                {
                    Image = { Color = "0 0 0 0" },
                    RectTransform = {
            AnchorMin = "0 0",
            AnchorMax = "0 0",
            OffsetMin = $"{left} {top}",
            OffsetMax = $"{right} {bottom}"
        }
                }, "MBCoinsContent", containerName);

                // 🖼️ Фон
                if (!string.IsNullOrEmpty(backgroundImg))
                {
                    container.Add(new CuiElement
                    {
                        Name = $"MBCommandBG_{i}",
                        Parent = containerName,
                        Components =
            {
                new CuiRawImageComponent
                {
                    Png = backgroundImg,
                    Sprite = "assets/content/textures/generic/fulltransparent.tga",
                    Color = "1 1 1 1"
                },
                new CuiRectTransformComponent
                {
                    AnchorMin = "0 0",
                    AnchorMax = "1 1"
                }
            }
                    });
                }

                // 🏷️ Название команды
                container.Add(new CuiLabel
                {
                    Text = {
            Text = cmd,
            FontSize = 32,
            Align = TextAnchor.MiddleRight,
            Color = "1 1 1 0.8"
        },
                    RectTransform = {
            AnchorMin = "0.05 0.5", AnchorMax = "0.5 0.78"
        }
                }, containerName);

                // Панель-фон
                container.Add(new CuiPanel
                {
                    Image = { Color = "0.67 0.87 0.80 0" }, // Темно-сірий прозорий фон
                    RectTransform = { AnchorMin = "0.15 0.1", AnchorMax = "0.85 0.45" }
                }, containerName);

                // 📝 Описание команды
                container.Add(new CuiLabel
                {
                    Text = {
            Text = desc,
            FontSize = 10,
            Align = TextAnchor.UpperCenter,
            Color = "1 1 1 0.5"
        },
                    RectTransform = {
            AnchorMin = "0.15 0.1", AnchorMax = "0.85 0.45"
        }
                }, containerName);
            }

            CuiHelper.AddUi(player, container);
        }

        [ConsoleCommand("mbcoins.back")]
        private void CmdCoinsBack(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            CuiHelper.DestroyUi(player, "MBReward_UI");

            MBMainMenu?.Call("ShowMainMenu", player);
        }

        [ChatCommand("mb")]
        private void CmdMBReward(BasePlayer player, string command, string[] args)
        {
            ShowCoinsUI(player);
        }

        private class ImageUI
        {
            private const string PathFolder = "MBSystem/MBReward/Images/";
            private readonly Dictionary<string, ImageData> _images = new()
            {
                { "MBWelcome_Seven_Os", new ImageData() },
                { "MBCoins_BG", new ImageData() }
            };

            private enum ImageStatus { NotLoaded, Loaded, Failed }

            private class ImageData
            {
                public ImageStatus Status = ImageStatus.NotLoaded;
                public string Id { get; set; }
            }

            public string GetImage(string name)
            {
                if (_images.TryGetValue(name, out var image) && image.Status == ImageStatus.Loaded)
                    return image.Id;
                return null;
            }

            public void DownloadImages()
            {
                string fullPath = Interface.Oxide.DataDirectory + System.IO.Path.DirectorySeparatorChar + PathFolder;
                if (!System.IO.Directory.Exists(fullPath))
                {
                    System.IO.Directory.CreateDirectory(fullPath);
                    Interface.Oxide.LogInfo($"[MBReward] Создана папка: {fullPath}");
                }

                var nextImage = _images.FirstOrDefault(img => img.Value.Status == ImageStatus.NotLoaded);
                if (!string.IsNullOrEmpty(nextImage.Key))
                    ServerMgr.Instance.StartCoroutine(LoadImage(nextImage));
                else
                    Interface.Oxide.LogInfo("[MBReward] Все изображения загружены!");
            }

            private IEnumerator LoadImage(KeyValuePair<string, ImageData> image)
            {
                string filePath = "file://" + Interface.Oxide.DataDirectory + System.IO.Path.DirectorySeparatorChar + PathFolder + image.Key + ".png";
                using (var www = UnityEngine.Networking.UnityWebRequestTexture.GetTexture(filePath))
                {
                    yield return www.SendWebRequest();

                    if (www.result != UnityEngine.Networking.UnityWebRequest.Result.Success)
                    {
                        image.Value.Status = ImageStatus.Failed;
                        Interface.Oxide.LogWarning($"[MBReward] Ошибка загрузки {image.Key}");
                    }
                    else
                    {
                        Texture2D texture = UnityEngine.Networking.DownloadHandlerTexture.GetContent(www);
                        image.Value.Id = FileStorage.server.Store(texture.EncodeToPNG(), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
                        image.Value.Status = ImageStatus.Loaded;
                        UnityEngine.Object.DestroyImmediate(texture);
                    }

                    DownloadImages();
                }
            }

            public void UnloadImages()
            {
                foreach (var img in _images)
                {
                    if (img.Value.Status == ImageStatus.Loaded && img.Value.Id != null)
                        FileStorage.server.Remove(uint.Parse(img.Value.Id), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID);
                }
                _images.Clear();
            }
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["MB_Close_Coins"] = "Click on an empty space to close the menu",
                ["Command_OnlineReward_Desc"] = "Play for 6 hours and receive 1 MBCoin!",
                ["MB_Coins_Player"] = "FARM MBCOINS",
                ["MB_Coins_Player_2"] = "<color=#FFD700>Get rich</color> with every step!",
                ["MB_Reward_Time"] = "Time until reward: {0}",
                ["MB_Reward_Ready"] = "Reward is available!",
                ["MB_Reward_Zero"] = "0m",
                ["MB_Reward_Ready"] = "ready",
                ["MB_Reward_Format_HM"] = "{0}h {1}m",
                ["MB_Reward_Format_M"] = "{0}m",
                ["Command_Home_Desc"] = "6-hour session in the game",
                ["Command_Warp_Desc"] = "First time joining the server",
                ["MB_Back"] = "Back",
                ["MB_FirstJoinReward"] = "You received {0} coins for your first login on the server!"


            }, this);

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["MB_Close_Coins"] = "Натисніть на порожнє місце, щоб закрити меню",
                ["Command_OnlineReward_Desc"] = "6-ти годинний сеанс в грі",
                ["MB_Coins_Player"] = "ФАРМ MBCOINS",
                ["MB_Coins_Player_2"] = "<color=#FFD700>Збагачуйся</color> з кожним кроком!",
                ["MB_Reward_Time"] = "До нагороди: {0}",
                ["MB_Reward_Ready"] = "Нагорода доступна!",
                ["MB_Reward_Zero"] = "0хв",
                ["MB_Reward_Ready"] = "готово",
                ["MB_Reward_Format_HM"] = "{0}г {1}хв",
                ["MB_Reward_Format_M"] = "{0}хв",
                ["Command_Home_Desc"] = "6-ти годинний сеанс в грі",
                ["Command_Warp_Desc"] = "Вперше зайшов на сервер",
                ["MB_Back"] = "Назад",
                ["MB_FirstJoinReward"] = "Ви отримали {0} монет за перший вхід на сервер!"


            }, this, "uk");

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["MB_Close_Coins"] = "Нажмите на пустое место, чтобы закрыть меню",
                ["Command_OnlineReward_Desc"] = "6-часовой игровой сеанс",
                ["MB_Coins_Player"] = "ФАРМ MBCOINS",
                ["MB_Coins_Player_2"] = "<color=#FFD700>Обогащайся</color> с каждым шагом!",
                ["MB_Reward_Time"] = "До награды: {0}",
                ["MB_Reward_Ready"] = "Награда доступна!",
                ["MB_Reward_Zero"] = "0мин",
                ["MB_Reward_Ready"] = "готово",
                ["MB_Reward_Format_HM"] = "{0}ч {1}мин",
                ["MB_Reward_Format_M"] = "{0}мин",
                ["Command_Home_Desc"] = "6-часовой игровой сеанс",
                ["Command_Warp_Desc"] = "Первый вход на сервер",
                ["MB_Back"] = "Назад",
                ["MB_FirstJoinReward"] = "Вы получили {0} монет за первый вход на сервер!"
            }, this, "ru");
        }

        private string Msg(string key, string userid = null, params object[] obj)
        {
            return string.Format(lang.GetMessage(key, this, userid), obj);
        }
    }
}

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