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

FREE SQFrozen : 2.3.1 2.3.1

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

namespace Oxide.Plugins
{
    [Info("SQFrozen", "BLOOD KRAKEN", "2.3.1")]
    [Description("Freeze your VIP/Premium/Elite groups to save time - Timer Pause Edition")]
    class SQFrozen : RustPlugin
    {
        #region References
        [PluginReference]
        Plugin ImageLibrary, IQPermissions, IQEconomic;
        #endregion

        #region Config
        private Configuration config;
        
        public class Configuration
        {
            [JsonProperty("URL images")]
            public ImagesConfig Images = new ImagesConfig();
            
            [JsonProperty("Groups")]
            public Dictionary<string, GroupConfig> Groups = new Dictionary<string, GroupConfig>
            {
                ["vip"] = new GroupConfig 
                { 
                    DisplayName = "VIP", 
                    ImageUrl = "https://i.yapx.ru/c6DS6.png",
                    FrozenImageUrl = "https://i.yapx.ru/c6DUc.png",
                    Aliases = new List<string> { "vip" }
                },
                ["premium"] = new GroupConfig 
                { 
                    DisplayName = "PREMIUM", 
                    ImageUrl = "https://i.yapx.ru/c6C5n.png",
                    FrozenImageUrl = "https://i.yapx.ru/c6DUc.png",
                    Aliases = new List<string> { "premium" }
                },
                ["elita"] = new GroupConfig 
                { 
                    DisplayName = "ELITE", 
                    ImageUrl = "https://i.yapx.ru/c6CvG.png",
                    FrozenImageUrl = "https://i.yapx.ru/c6DUc.png",
                    Aliases = new List<string> { "elita", "elite" }
                }
            };
            
            [JsonProperty("Days per snowflake")]
            public int DaysPerSnowflake = 7;
            
            [JsonProperty("Snowflake price")]
            public int SnowflakePrice = 100;
            
            [JsonProperty("Max snowflakes")]
            public int MaxSnowflakes = 6;
            
            [JsonProperty("UI Scale (0.1 - 1.0)")]
            public float UIScale = 0.65f;
            
            [JsonProperty("Debug mode (console logs)")]
            public bool DebugMode = true;
            
            [JsonProperty("Snowflake item shortname")]
            public string SnowflakeItem = "bleach";
            
            [JsonProperty("Snowflake skin ID")]
            public ulong SnowflakeSkin = 3665432012;
            
            [JsonProperty("Настройка физической валюты (Тип 1 - предмет в инвентаре)")]
            public CurrencyConfig PhysicalCurrency = new CurrencyConfig
            {
                Enabled = true,
                Shortname = "sticks",
                SkinID = 3629342280,
                DisplayName = "BLKR"
            };
            
            [JsonProperty("Настройка электронной валюты (Тип 2 - IQEconomic)")]
            public ElectronicCurrencyConfig ElectronicCurrency = new ElectronicCurrencyConfig
            {
                Enabled = false,
                PluginName = "IQEconomic"
            };
            
            [JsonProperty("Return snowflakes on early unfreeze")]
            public bool ReturnSnowflakesOnEarlyUnfreeze = true;
        }
        
        public class ImagesConfig
        {
            public string Background = "https://i.yapx.ru/c593r.png";
            public string CloseButton = "https://i.yapx.ru/c6CrX.png";
            public string FreezeButton = "https://i.yapx.ru/c6CNM.png";
            public string UnfreezeButton = "https://i.yapx.ru/c6CSX.png";
            public string BuyButton = "https://i.yapx.ru/c6C4z.png";
            public string CheckboxActive = "https://i.yapx.ru/c6Cnr.png";
            public string SnowflakeActive = "https://i.yapx.ru/c6C7G.png";
            public string SnowflakeInactive = "https://i.yapx.ru/c6DBR.png";
            public string SnowflakeSelected = "https://i.yapx.ru/c6DHE.png";
            public string CanFreezeIcon = "https://i.yapx.ru/c6DYE.png";
            public string FrozenIcon = "https://i.yapx.ru/c6DUc.png";
        }
        
        public class GroupConfig
        {
            public string DisplayName;
            public string ImageUrl;
            public string FrozenImageUrl;
            public List<string> Aliases = new List<string>();
        }
        
        public class CurrencyConfig
        {
            [JsonProperty("Включить физическую валюту")]
            public bool Enabled = true;
            
            [JsonProperty("Shortname")]
            public string Shortname = "sticks";
            
            [JsonProperty("SkinID")]
            public ulong SkinID = 3629342280;
            
            [JsonProperty("Отображаемое имя")]
            public string DisplayName = "BLKR";
        }
        
        public class ElectronicCurrencyConfig
        {
            [JsonProperty("Включить электронную валюту")]
            public bool Enabled = false;
            
            [JsonProperty("Название плагина (IQEconomic/Economics/ServerRewards)")]
            public string PluginName = "IQEconomic";
        }
        
        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Creating default config");
                config = new Configuration();
                SaveConfig();
            }
        }
        
        protected override void SaveConfig() => Config.WriteObject(config);
        protected override void LoadDefaultConfig() => config = new Configuration();
        #endregion

        #region Data
        private FrozenData frozenData;
        private Dictionary<ulong, Dictionary<string, DateTime>> playerGroupExpiry = new Dictionary<ulong, Dictionary<string, DateTime>>();
        private Dictionary<ulong, int> playerSelectedSnowflakes = new Dictionary<ulong, int>();
        private Dictionary<ulong, string> playerSelectedGroup = new Dictionary<ulong, string>();
        private const string DataPath = "SQFrozen/players/FrozenPermissions";
        private const string ExpiryDataPath = "SQFrozen/players/GroupExpiry";
        
        private string IQPermissionsDataPath => Path.Combine(Interface.Oxide.DataDirectory, "IQSystem", "IQPermissions", "Permissions.json");
        
        public class FrozenData : Dictionary<ulong, Dictionary<string, FrozenGroupInfo>> {}
        
        public class FrozenGroupInfo
        {
            public DateTime FrozenAt;
            public DateTime OriginalExpiry;
            public int SnowflakesUsed;
            public TimeSpan RemainingTime;
            public string TimeFormat;
            public DateTime UnfreezeDate;
        }
        
        private void LoadData()
        {
            frozenData = Interface.Oxide.DataFileSystem.ReadObject<FrozenData>(DataPath) ?? new FrozenData();
            playerGroupExpiry = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, Dictionary<string, DateTime>>>(ExpiryDataPath) ?? new Dictionary<ulong, Dictionary<string, DateTime>>();
        }
        
        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(DataPath, frozenData);
            Interface.Oxide.DataFileSystem.WriteObject(ExpiryDataPath, playerGroupExpiry);
        }
        #endregion

        #region Group Mapping Helpers
        
        private string FindConfigGroupKey(string iqGroupName)
        {
            if (string.IsNullOrEmpty(iqGroupName)) return null;
            
            string searchName = iqGroupName.ToLower();
            
            foreach (var kvp in config.Groups)
            {
                string configKey = kvp.Key.ToLower();
                var groupConfig = kvp.Value;
                
                if (configKey == searchName)
                    return kvp.Key;
                
                if (groupConfig.DisplayName?.ToLower() == searchName)
                    return kvp.Key;
                
                if (groupConfig.Aliases != null)
                {
                    foreach (var alias in groupConfig.Aliases)
                    {
                        if (alias?.ToLower() == searchName)
                            return kvp.Key;
                    }
                }
            }
            
            return null;
        }
        
        private bool IsKnownGroup(string iqGroupName)
        {
            return FindConfigGroupKey(iqGroupName) != null;
        }
        
        private string GetNormalizedGroupKey(string groupName)
        {
            var configKey = FindConfigGroupKey(groupName);
            return configKey ?? groupName.ToLower();
        }
        
        #endregion

        #region Hooks
        private void OnServerInitialized()
        {
            LoadData();
            RegisterImages();
            permission.RegisterPermission("sqfrozen.admin", this);
            permission.RegisterPermission("sqfrozen.use", this);
            
            timer.Every(3600f, CheckExpiredFrozenGroups);
            
            if (IQPermissions == null)
            {
                PrintWarning("IQPermissions not found!");
            }
            else
            {
                PrintWarning("IQPermissions found.");
            }
            
            if (config.PhysicalCurrency.Enabled)
            {
                PrintWarning($"Using PHYSICAL currency: {config.PhysicalCurrency.Shortname} (Skin: {config.PhysicalCurrency.SkinID})");
            }
            else if (config.ElectronicCurrency.Enabled)
            {
                PrintWarning($"Using ELECTRONIC currency: {config.ElectronicCurrency.PluginName}");
            }
        }
        
        private void OnPlayerDisconnected(BasePlayer player)
        {
            playerSelectedSnowflakes.Remove(player.userID);
            playerSelectedGroup.Remove(player.userID);
        }
        
        private void Unload()
        {
            SaveData();
            foreach (var player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, "SQFrozen_Main");
            }
        }
        
        private void CheckExpiredFrozenGroups()
        {
            bool changed = false;
            var now = DateTime.Now;
            
            foreach (var playerData in frozenData.ToList())
            {
                foreach (var groupData in playerData.Value.ToList())
                {
                    var info = groupData.Value;
                    
                    if (now > info.UnfreezeDate)
                    {
                        ReturnGroup(playerData.Key, groupData.Key, info);
                        playerData.Value.Remove(groupData.Key);
                        changed = true;
                    }
                }
                
                if (playerData.Value.Count == 0)
                    frozenData.Remove(playerData.Key);
            }
            
            if (changed)
                SaveData();
        }
        #endregion

        #region ImageLibrary
        private void RegisterImages()
        {
            if (ImageLibrary == null) 
            {
                PrintError("ImageLibrary not found!");
                return;
            }
            
            ImageLibrary.Call("AddImage", config.Images.Background, "SQFrozen_BG", 0UL);
            ImageLibrary.Call("AddImage", config.Images.CloseButton, "SQFrozen_Close", 0UL);
            ImageLibrary.Call("AddImage", config.Images.FreezeButton, "SQFrozen_Freeze", 0UL);
            ImageLibrary.Call("AddImage", config.Images.UnfreezeButton, "SQFrozen_Unfreeze", 0UL);
            ImageLibrary.Call("AddImage", config.Images.BuyButton, "SQFrozen_Buy", 0UL);
            ImageLibrary.Call("AddImage", config.Images.CheckboxActive, "SQFrozen_CheckOn", 0UL);
            ImageLibrary.Call("AddImage", config.Images.SnowflakeActive, "SQFrozen_SnowOn", 0UL);
            ImageLibrary.Call("AddImage", config.Images.SnowflakeInactive, "SQFrozen_SnowOff", 0UL);
            ImageLibrary.Call("AddImage", config.Images.SnowflakeSelected, "SQFrozen_SnowSel", 0UL);
            ImageLibrary.Call("AddImage", config.Images.CanFreezeIcon, "SQFrozen_CanFreeze", 0UL);
            ImageLibrary.Call("AddImage", config.Images.FrozenIcon, "SQFrozen_FrozenStatus", 0UL);
            
            foreach (var group in config.Groups)
            {
                ImageLibrary.Call("AddImage", group.Value.ImageUrl, $"SQFrozen_Group_{group.Key}", 0UL);
                ImageLibrary.Call("AddImage", group.Value.FrozenImageUrl, $"SQFrozen_Group_{group.Key}_Frozen", 0UL);
            }
        }
        
        private string GetImage(string name)
        {
            if (ImageLibrary == null) return "";
            return ImageLibrary.Call<string>("GetImage", name) ?? "";
        }
        #endregion

        #region Commands
        [ChatCommand("frozen")]
        private void cmdFrozen(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "sqfrozen.use"))
            {
                player.ChatMessage("<color=red>No permission!</color>");
                return;
            }
            
            if (!playerSelectedSnowflakes.ContainsKey(player.userID))
                playerSelectedSnowflakes[player.userID] = 1;
            
            RefreshPlayerGroupData(player);
            
            if (config.DebugMode)
            {
                DebugPlayerGroups(player);
            }
                
            OpenMainUI(player);
        }
        
        [ChatCommand("givesnow")]
        private void cmdGiveSnow(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "sqfrozen.admin"))
            {
                player.ChatMessage("<color=red>Нет доступа!</color>");
                return;
            }
            
            int amount = 1;
            if (args.Length > 0 && int.TryParse(args[0], out int parsedAmount))
            {
                amount = parsedAmount;
            }
            
            GiveSnowflakes(player, amount);
            player.ChatMessage($"<color=green>Вы выдали себе {amount} снежинок!</color>");
        }
        
        [ChatCommand("setgrouptime")]
        private void cmdSetGroupTime(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "sqfrozen.admin"))
            {
                player.ChatMessage("<color=red>Нет доступа!</color>");
                return;
            }
            
            if (args.Length < 2)
            {
                player.ChatMessage("<color=yellow>Использование: /setgrouptime <группа> <дни></color>");
                return;
            }
            
            string group = args[0].ToLower();
            if (!int.TryParse(args[1], out int days))
            {
                player.ChatMessage("<color=red>Укажите количество дней числом!</color>");
                return;
            }
            
            if (!config.Groups.ContainsKey(group))
            {
                player.ChatMessage($"<color=red>Группа {group} не найдена в конфиге!</color>");
                return;
            }
            
            if (!playerGroupExpiry.ContainsKey(player.userID))
                playerGroupExpiry[player.userID] = new Dictionary<string, DateTime>();
            
            playerGroupExpiry[player.userID][group] = DateTime.Now.AddDays(days);
            SaveData();
            
            player.ChatMessage($"<color=green>Группе {config.Groups[group].DisplayName} установлено время: {days} дней!</color>");
        }
        
        [ConsoleCommand("sqfrozen.select")]
        private void ccmdSelect(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || arg.Args == null || arg.Args.Length < 1) return;
            
            string group = arg.Args[0].ToLower();
            if (!config.Groups.ContainsKey(group)) return;
            
            playerSelectedGroup[player.userID] = group;
            if (!playerSelectedSnowflakes.ContainsKey(player.userID))
                playerSelectedSnowflakes[player.userID] = 1;
                
            OpenMainUI(player, group);
        }
        
        [ConsoleCommand("sqfrozen.snowflake")]
        private void ccmdSnowflake(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || arg.Args == null || arg.Args.Length < 2) return;
            
            string group = arg.Args[0].ToLower();
            if (!int.TryParse(arg.Args[1], out int count)) return;
            
            int playerSnowflakes = CountSnowflakes(player);
            count = Mathf.Clamp(count, 1, Mathf.Min(config.MaxSnowflakes, playerSnowflakes));
            
            playerSelectedSnowflakes[player.userID] = count;
            
            OpenMainUI(player, group);
        }
        
        [ConsoleCommand("sqfrozen.freeze")]
        private void ccmdFreeze(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || arg.Args == null || arg.Args.Length < 1) return;
            
            string group = arg.Args[0].ToLower();
            int snowflakes = playerSelectedSnowflakes.GetValueOrDefault(player.userID, 1);
            
            int playerSnowflakes = CountSnowflakes(player);
            if (playerSnowflakes < snowflakes)
            {
                player.ChatMessage($"<color=red>Недостаточно снежинок! Нужно: {snowflakes}, есть: {playerSnowflakes}</color>");
                return;
            }
            
            FreezeGroup(player, group, snowflakes);
        }
        
        [ConsoleCommand("sqfrozen.unfreeze")]
        private void ccmdUnfreeze(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || arg.Args == null || arg.Args.Length < 1) return;
            
            string group = arg.Args[0].ToLower();
            UnfreezeGroup(player, group);
        }
        
        [ConsoleCommand("sqfrozen.buy")]
        private void ccmdBuy(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            
            BuySnowflake(player);
        }
        
        [ConsoleCommand("sqfrozen.close")]
        private void ccmdClose(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            
            CuiHelper.DestroyUi(player, "SQFrozen_Main");
            playerSelectedSnowflakes.Remove(player.userID);
            playerSelectedGroup.Remove(player.userID);
        }
        
        [ConsoleCommand("givefrozen")]
        private void ccmdGiveFrozen(ConsoleSystem.Arg arg)
        {
            if (arg.Player() != null && !permission.UserHasPermission(arg.Player().UserIDString, "sqfrozen.admin"))
            {
                arg.ReplyWith("No permission");
                return;
            }
            
            if (arg.Args == null || arg.Args.Length < 2)
            {
                arg.ReplyWith("Usage: givefrozen <steamid> <amount>");
                return;
            }
            
            if (!ulong.TryParse(arg.Args[0], out ulong steamId) || !int.TryParse(arg.Args[1], out int amount))
            {
                arg.ReplyWith("Invalid arguments");
                return;
            }
            
            var target = BasePlayer.FindByID(steamId);
            if (target != null)
            {
                GiveSnowflakes(target, amount);
                arg.ReplyWith($"Gave {amount} snowflakes to {steamId}");
                if (target.IsConnected)
                    target.ChatMessage($"<color=cyan>[SQFrozen]</color> You got <color=yellow>{amount}</color> snowflakes!");
            }
            else
            {
                arg.ReplyWith("Player not found");
            }
        }
        
        [ConsoleCommand("sqfrozen.debug")]
        private void ccmdDebug(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            
            if (!permission.UserHasPermission(player.UserIDString, "sqfrozen.admin"))
            {
                player.ChatMessage("<color=red>No permission!</color>");
                return;
            }
            
            DebugPlayerGroups(player);
            player.ChatMessage("<color=green>Debug info printed to console!</color>");
        }
        
        [ConsoleCommand("sqfrozen.refresh")]
        private void ccmdRefresh(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;
            
            RefreshPlayerGroupData(player);
            player.ChatMessage("<color=green>Данные групп обновлены!</color>");
            OpenMainUI(player);
        }
        #endregion

        #region Debug
        private void DebugPlayerGroups(BasePlayer player)
        {
            Puts($"=== SQFrozen Debug for {player.displayName} ({player.userID}) ===");
            
            var iqData = GetIQPermissionsGroupData(player.userID);
            Puts($"IQPermissions groups found: {iqData.Count}");
            foreach (var kvp in iqData)
            {
                string mappedKey = FindConfigGroupKey(kvp.Key);
                Puts($"  IQ: '{kvp.Key}' -> Config: '{mappedKey ?? "NOT MAPPED"}', Expiry: {kvp.Value:O}");
            }
            
            Puts($"Oxide groups: {string.Join(", ", permission.GetUserGroups(player.UserIDString))}");
            
            var allGroups = GetAllPlayerGroups(player);
            Puts($"All groups found: {string.Join(", ", allGroups)}");
            
            if (playerGroupExpiry.ContainsKey(player.userID))
            {
                Puts("Stored expiry times:");
                foreach (var kvp in playerGroupExpiry[player.userID])
                {
                    Puts($"  {kvp.Key}: {kvp.Value:dd.MM.yyyy HH:mm}");
                }
            }
            
            if (frozenData.ContainsKey(player.userID))
            {
                Puts("Frozen groups:");
                foreach (var kvp in frozenData[player.userID])
                {
                    var info = kvp.Value;
                    int daysLeft = (info.UnfreezeDate - DateTime.Now).Days;
                    Puts($"  {kvp.Key}: FrozenAt={info.FrozenAt}, UnfreezeDate={info.UnfreezeDate}, RemainingTime={info.RemainingTime.Days}d {info.RemainingTime.Hours}h, DaysLeft={daysLeft}");
                }
            }
            
            Puts($"Snowflakes in inventory: {CountSnowflakes(player)} (item: {config.SnowflakeItem}, skin: {config.SnowflakeSkin})");
            Puts($"Currency balance: {GetCurrencyBalance(player)} {GetCurrencyName()}");
            Puts("=== End Debug ===");
        }
        #endregion

        #region IQPermissions Integration
        
        private void RefreshPlayerGroupData(BasePlayer player)
        {
            if (player == null) return;
            
            try
            {
                var iqGroups = GetIQPermissionsGroupData(player.userID);
                
                if (!playerGroupExpiry.ContainsKey(player.userID))
                    playerGroupExpiry[player.userID] = new Dictionary<string, DateTime>();
                
                foreach (var kvp in iqGroups)
                {
                    string iqGroupName = kvp.Key;
                    DateTime expiry = kvp.Value;
                    
                    string configKey = FindConfigGroupKey(iqGroupName);
                    
                    if (configKey == null)
                    {
                        if (config.DebugMode)
                        {
                            Puts($"[Refresh] Unknown group '{iqGroupName}' - skipping or using raw name");
                        }
                        configKey = iqGroupName.ToLower();
                    }
                    
                    if (expiry > DateTime.Now)
                    {
                        playerGroupExpiry[player.userID][configKey] = expiry;
                        
                        if (config.DebugMode)
                        {
                            Puts($"[Refresh] Updated {player.displayName} - IQ: '{iqGroupName}' -> Config: '{configKey}', Expiry: {expiry:dd.MM.yyyy HH:mm}");
                        }
                    }
                }
                
                var groupsToRemove = new List<string>();
                foreach (var groupKey in playerGroupExpiry[player.userID].Keys.ToList())
                {
                    bool foundInIQ = false;
                    foreach (var iqKvp in iqGroups)
                    {
                        if (GetNormalizedGroupKey(iqKvp.Key) == groupKey)
                        {
                            foundInIQ = true;
                            break;
                        }
                    }
                    
                    if (!foundInIQ)
                    {
                        bool isFrozen = frozenData.ContainsKey(player.userID) && 
                                       frozenData[player.userID].ContainsKey(groupKey);
                        
                        if (!isFrozen)
                        {
                            groupsToRemove.Add(groupKey);
                        }
                    }
                }
                
                foreach (var groupKey in groupsToRemove)
                {
                    playerGroupExpiry[player.userID].Remove(groupKey);
                    if (config.DebugMode)
                    {
                        Puts($"[Refresh] Removed expired group {groupKey} for {player.displayName}");
                    }
                }
                
                if (playerGroupExpiry[player.userID].Count == 0)
                    playerGroupExpiry.Remove(player.userID);
                
                SaveData();
                
                if (config.DebugMode)
                {
                    Puts($"[Refresh] Completed for {player.displayName}. Active groups: {iqGroups.Count}");
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error refreshing player data: {ex.Message}");
            }
        }
        
        private Dictionary<string, DateTime> GetIQPermissionsGroupData(ulong userID)
        {
            var result = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
            
            try
            {
                if (!File.Exists(IQPermissionsDataPath))
                    return result;
                
                string json = File.ReadAllText(IQPermissionsDataPath);
                var data = JObject.Parse(json);
                
                var groupsData = data["Информация о группах игрока"] as JObject;
                if (groupsData == null) return result;
                
                string userIdStr = userID.ToString();
                
                foreach (var group in groupsData.Properties())
                {
                    var players = group.Value as JObject;
                    if (players == null) continue;
                    
                    if (players[userIdStr] != null)
                    {
                        string dateStr = players[userIdStr].ToString();
                        if (DateTime.TryParse(dateStr, out DateTime expiry))
                        {
                            result[group.Name] = expiry;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Puts($"Error reading IQPermissions data: {ex.Message}");
            }
            
            return result;
        }
        
        private string FormatTimeForIQPermissions(TimeSpan time)
        {
            var parts = new List<string>();
            
            if (time.Days > 0)
                parts.Add($"{time.Days}d");
            
            if (time.Hours > 0)
                parts.Add($"{time.Hours}h");
            
            if (time.Minutes > 0)
                parts.Add($"{time.Minutes}m");
            
            if (time.Seconds > 0 && time.Days == 0)
                parts.Add($"{time.Seconds}s");
            
            return string.Join(" ", parts);
        }
        
        #endregion

        #region Currency System
        
        private int GetCurrencyBalance(BasePlayer player)
        {
            if (config.PhysicalCurrency.Enabled)
            {
                return CountPhysicalCurrency(player);
            }
            else if (config.ElectronicCurrency.Enabled)
            {
                return GetElectronicBalance(player);
            }
            return 0;
        }
        
        private bool RemoveCurrency(BasePlayer player, int amount)
        {
            if (config.PhysicalCurrency.Enabled)
            {
                return RemovePhysicalCurrency(player, amount);
            }
            else if (config.ElectronicCurrency.Enabled)
            {
                return RemoveElectronicBalance(player, amount);
            }
            return false;
        }
        
        private string GetCurrencyName()
        {
            if (config.PhysicalCurrency.Enabled)
            {
                return config.PhysicalCurrency.DisplayName;
            }
            else if (config.ElectronicCurrency.Enabled)
            {
                return config.ElectronicCurrency.PluginName;
            }
            return "UNKNOWN";
        }
        
        #region Physical Currency
        
        private int CountPhysicalCurrency(BasePlayer player)
        {
            int count = 0;
            var containerList = new List<ItemContainer>
            {
                player.inventory.containerMain,
                player.inventory.containerBelt,
                player.inventory.containerWear
            };
            
            foreach (var container in containerList)
            {
                if (container == null) continue;
                foreach (var item in container.itemList)
                {
                    if (item.info.shortname == config.PhysicalCurrency.Shortname && 
                        item.skin == config.PhysicalCurrency.SkinID)
                        count += item.amount;
                }
            }
            return count;
        }
        
        private bool RemovePhysicalCurrency(BasePlayer player, int amount)
        {
            int toRemove = amount;
            var containerList = new List<ItemContainer>
            {
                player.inventory.containerMain,
                player.inventory.containerBelt,
                player.inventory.containerWear
            };
            
            foreach (var container in containerList)
            {
                if (container == null) continue;
                foreach (var item in container.itemList.ToList())
                {
                    if (item.info.shortname == config.PhysicalCurrency.Shortname && 
                        item.skin == config.PhysicalCurrency.SkinID)
                    {
                        if (item.amount <= toRemove)
                        {
                            toRemove -= item.amount;
                            item.Remove();
                        }
                        else
                        {
                            item.amount -= toRemove;
                            item.MarkDirty();
                            toRemove = 0;
                        }
                        if (toRemove <= 0) return true;
                    }
                }
            }
            return toRemove <= 0;
        }
        
        #endregion
        
        #region Electronic Currency
        
        private int GetElectronicBalance(BasePlayer player)
        {
            string pluginName = config.ElectronicCurrency.PluginName.ToLower();
            
            try
            {
                switch (pluginName)
                {
                    case "iqeconomic":
                        if (IQEconomic == null) return 0;
                        object iqBalance = IQEconomic.Call("API_GET_BALANCE", player.userID);
                        return iqBalance != null ? Convert.ToInt32(iqBalance) : 0;
                        
                    case "economics":
                        Plugin economics = plugins.Find("Economics");
                        if (economics == null) return 0;
                        object ecoBalance = economics.Call("Balance", player.UserIDString);
                        return ecoBalance != null ? Convert.ToInt32(ecoBalance) : 0;
                        
                    case "serverrewards":
                        Plugin serverRewards = plugins.Find("ServerRewards");
                        if (serverRewards == null) return 0;
                        object srBalance = serverRewards.Call("CheckPoints", player.userID);
                        return srBalance != null ? Convert.ToInt32(srBalance) : 0;
                        
                    default:
                        PrintError($"Unknown electronic currency plugin: {pluginName}");
                        return 0;
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error getting electronic balance: {ex.Message}");
                return 0;
            }
        }
        
        private bool RemoveElectronicBalance(BasePlayer player, int amount)
        {
            string pluginName = config.ElectronicCurrency.PluginName.ToLower();
            
            try
            {
                switch (pluginName)
                {
                    case "iqeconomic":
                        if (IQEconomic == null) return false;
                        IQEconomic.Call("API_REMOVE_BALANCE", player.userID, amount);
                        return true;
                        
                    case "economics":
                        Plugin economics = plugins.Find("Economics");
                        if (economics == null) return false;
                        economics.Call("Withdraw", player.UserIDString, (double)amount);
                        return true;
                        
                    case "serverrewards":
                        Plugin serverRewards = plugins.Find("ServerRewards");
                        if (serverRewards == null) return false;
                        object result = serverRewards.Call("TakePoints", player.userID, amount);
                        return result != null && (bool)result;
                        
                    default:
                        PrintError($"Unknown electronic currency plugin: {pluginName}");
                        return false;
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error removing electronic balance: {ex.Message}");
                return false;
            }
        }
        
        #endregion
        
        #endregion

        #region Group Management
        
        private bool RemoveGroupFromPlayer(ulong userID, string group)
        {
            bool removed = false;
            
            string originalIQGroupName = group;
            var configGroup = config.Groups.ContainsKey(group) ? config.Groups[group] : null;
            if (configGroup != null && configGroup.Aliases != null && configGroup.Aliases.Count > 0)
            {
                var iqData = GetIQPermissionsGroupData(userID);
                foreach (var alias in configGroup.Aliases)
                {
                    if (iqData.ContainsKey(alias))
                    {
                        originalIQGroupName = alias;
                        break;
                    }
                }
            }
            
            try
            {
                string command = $"revokegroup {userID} {originalIQGroupName}";
                Puts($"Executing console: {command}");
                ConsoleSystem.Run(ConsoleSystem.Option.Server, command);
                removed = true;
            }
            catch (Exception ex)
            {
                Puts($"Console revokegroup error: {ex.Message}");
            }
            
            try
            {
                if (File.Exists(IQPermissionsDataPath))
                {
                    string json = File.ReadAllText(IQPermissionsDataPath);
                    var data = JObject.Parse(json);
                    
                    var groupsData = data["Информация о группах игрока"] as JObject;
                    if (groupsData != null)
                    {
                        string userIdStr = userID.ToString();
                        
                        var possibleNames = new List<string> { group, originalIQGroupName };
                        if (configGroup?.Aliases != null)
                            possibleNames.AddRange(configGroup.Aliases);
                        
                        foreach (var searchName in possibleNames.Distinct(StringComparer.OrdinalIgnoreCase))
                        {
                            var groupProperty = groupsData.Properties()
                                .FirstOrDefault(p => p.Name.Equals(searchName, StringComparison.OrdinalIgnoreCase));
                            
                            if (groupProperty != null)
                            {
                                var players = groupProperty.Value as JObject;
                                if (players != null && players[userIdStr] != null)
                                {
                                    players.Remove(userIdStr);
                                    Puts($"Removed {userIdStr} from group {groupProperty.Name} in JSON");
                                    
                                    File.WriteAllText(IQPermissionsDataPath, data.ToString(Formatting.Indented));
                                    Puts($"Saved IQPermissions JSON");
                                    removed = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Puts($"JSON edit error: {ex.Message}");
            }
            
            try
            {
                string steamId = userID.ToString();
                if (permission.UserHasGroup(steamId, group))
                {
                    permission.RemoveUserGroup(steamId, group);
                    Puts($"Also removed from Oxide groups");
                }
            }
            catch { }
            
            return removed;
        }
        
        private bool AddGroupToPlayer(ulong userID, string group, string timeFormat)
        {
            bool added = false;
            DateTime expiry = DateTime.Now;
            
            try
            {
                var regex = new Regex(@"(\d+)([dhms])");
                var matches = regex.Matches(timeFormat.ToLower());
                
                foreach (Match match in matches)
                {
                    int value = int.Parse(match.Groups[1].Value);
                    string unit = match.Groups[2].Value;
                    
                    switch (unit)
                    {
                        case "d": expiry = expiry.AddDays(value); break;
                        case "h": expiry = expiry.AddHours(value); break;
                        case "m": expiry = expiry.AddMinutes(value); break;
                        case "s": expiry = expiry.AddSeconds(value); break;
                    }
                }
            }
            catch
            {
                expiry = DateTime.Now.AddDays(1);
            }
            
            string iqGroupName = group;
            var configGroup = config.Groups.ContainsKey(group) ? config.Groups[group] : null;
            if (configGroup != null)
            {
                iqGroupName = configGroup.Aliases?.FirstOrDefault() ?? configGroup.DisplayName ?? group;
            }
            
            try
            {
                string command = $"addgroup {userID} {iqGroupName} {timeFormat}";
                Puts($"Executing console: {command}");
                ConsoleSystem.Run(ConsoleSystem.Option.Server, command);
                added = true;
            }
            catch (Exception ex)
            {
                Puts($"Console addgroup error: {ex.Message}");
            }
            
            try
            {
                JObject data;
                
                if (File.Exists(IQPermissionsDataPath))
                {
                    string json = File.ReadAllText(IQPermissionsDataPath);
                    data = JObject.Parse(json);
                }
                else
                {
                    data = new JObject
                    {
                        ["Информация о привилегиях игрока"] = new JObject(),
                        ["Информация о группах игрока"] = new JObject()
                    };
                }
                
                var groupsData = data["Информация о группах игрока"] as JObject;
                if (groupsData == null)
                {
                    groupsData = new JObject();
                    data["Информация о группах игрока"] = groupsData;
                }
                
                var possibleNames = new List<string> { iqGroupName };
                if (configGroup?.Aliases != null)
                    possibleNames.AddRange(configGroup.Aliases);
                possibleNames.Add(group);
                
                JObject players = null;
                string actualGroupName = iqGroupName;
                
                foreach (var searchName in possibleNames.Distinct(StringComparer.OrdinalIgnoreCase))
                {
                    var groupProperty = groupsData.Properties()
                        .FirstOrDefault(p => p.Name.Equals(searchName, StringComparison.OrdinalIgnoreCase));
                    
                    if (groupProperty != null)
                    {
                        actualGroupName = groupProperty.Name;
                        players = groupProperty.Value as JObject;
                        break;
                    }
                }
                
                if (players == null)
                {
                    players = new JObject();
                    groupsData[iqGroupName] = players;
                    actualGroupName = iqGroupName;
                }
                
                players[userID.ToString()] = expiry.ToString("O");
                Puts($"Added to JSON: {userID} -> {actualGroupName}, expires: {expiry}");
                
                File.WriteAllText(IQPermissionsDataPath, data.ToString(Formatting.Indented));
                Puts($"Saved IQPermissions JSON");
                added = true;
            }
            catch (Exception ex)
            {
                Puts($"JSON edit error: {ex.Message}");
            }
            
            try
            {
                permission.AddUserGroup(userID.ToString(), group);
                Puts($"Also added to Oxide groups");
            }
            catch { }
            
            return added;
        }
        
        private void ReturnGroup(ulong userID, string group, FrozenGroupInfo info)
        {
            string timeFormat = info.TimeFormat;
            
            if (string.IsNullOrEmpty(timeFormat))
            {
                timeFormat = FormatTimeForIQPermissions(info.RemainingTime);
                Puts($"[ReturnGroup] Warning: TimeFormat was empty, using calculated: {timeFormat}");
            }
            
            Puts($"[ReturnGroup] Returning group {group} to {userID} with saved time: {timeFormat} (Remaining: {info.RemainingTime.Days}d {info.RemainingTime.Hours}h)");
            
            bool success = AddGroupToPlayer(userID, group, timeFormat);
            
            var player = BasePlayer.FindByID(userID);
            if (player != null && player.IsConnected)
            {
                if (success)
                {
                    player.ChatMessage($"<color=cyan>[SQFrozen]</color> Your <color=yellow>{config.Groups[group].DisplayName}</color> group has been restored! Time: {timeFormat}");
                }
                else
                {
                    player.ChatMessage($"<color=red>[SQFrozen] Error restoring group! Contact admin.</color>");
                }
            }
        }
        
        #endregion

        #region Logic
        
        // ИСПРАВЛЕНО v2.3.1: Убрана проверка на количество дней заморозки
        private void FreezeGroup(BasePlayer player, string groupName, int snowflakes)
        {
            if (!config.Groups.ContainsKey(groupName))
            {
                player.ChatMessage("<color=red>Invalid group!</color>");
                return;
            }
            
            RefreshPlayerGroupData(player);
            
            string actualGroupName = groupName;
            if (!HasGroup(player, groupName))
            {
                var allGroups = GetAllPlayerGroups(player);
                var similarGroup = allGroups.FirstOrDefault(g => g.Equals(groupName, StringComparison.OrdinalIgnoreCase));
                
                if (similarGroup != null)
                {
                    actualGroupName = similarGroup;
                }
                else
                {
                    player.ChatMessage($"<color=red>You don't have this group!</color>");
                    return;
                }
            }
            
            string groupKey = actualGroupName.ToLower();
            
            if (frozenData.ContainsKey(player.userID) && f
// ... [Code preview truncated due to length. Full source in attached file] ...

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