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

FREE IQEconomic : 2.20.23 2.20.23

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Oxide.Core;
using System.Text;
using ConVar;
using Object = System.Object;
using Oxide.Core.Plugins;
using Rust.Ai.Gen2;
using System.Linq;
using System.Collections;
using Pool = Facepunch.Pool;
using System;
using UnityEngine.Networking;
using Oxide.Core.Database;
using System.Collections.Generic;
namespace Oxide.Plugins {
    [Info("IQEconomic", "Mercury", "2.20.23")]
    [Description("Экономика на ваш сервер")]
    public class IQEconomic : RustPlugin {
        void OnItemCraftCancelled(ItemCraftTask task, ItemCrafter crafter) {
            BasePlayer player = crafter.owner;
            if (!player) return;
            player.ResetInputIdleTime();
        }
        private Boolean isUsedStores = false;
        private void TransferToPlayer(BasePlayer player, String nameOrID, String amountString) {
            if (String.IsNullOrWhiteSpace(nameOrID)) {
                SendChat(GetLang("CHAT_ALERT_TRANSFER_NO_NAME", player.UserIDString), player);
                return;
            }
            if (String.IsNullOrWhiteSpace(amountString) || !Int32.TryParse(amountString, out Int32 amount)) {
                SendChat(GetLang("CHAT_ALERT_TRANSFER_INCORRECT_AMOUNT", player.UserIDString), player);
                return;
            }
            (BasePlayer, String) targetPlayer = FindPlayerNameOrID(player, nameOrID);
            if (!targetPlayer.Item1) {
                if (targetPlayer.Item2 != null && !String.IsNullOrWhiteSpace(targetPlayer.Item2)) {
                    SendChat(targetPlayer.Item2, player);
                    return;
                }
                SendChat(GetLang("CHAT_ALERT_TRANSFER_PLAYER_OFFLINE", player.UserIDString), player);
                return;
            }
            if (!IsValidTransfer(player, targetPlayer.Item1, amount)) return;
            ExecuteTransfer(player, targetPlayer.Item1, amount);
        }
        private void RemoveBalance(String userID, Int32 amount, TypeLog typeLog) {
            if (config.generalSetting.typeCoins == TypeCoins.Physics) {
                PrintWarning(LanguageEn ? $"You cannot take currency from player {userID} while they are offline" : $"Нельзя забрать валюту у игрока {userID} пока он оффлайн");
                return;
            }
            if (isUsedSQL) GetAndFunctionalBalancePlayerSQL(userID, false, amount);
            else {
                PlayerInfo pInfo = PlayerInfo.GetOffline(userID);
                if (pInfo == null) return;
                if (!DoesHaveEnoughBalance(pInfo.Balance)) {
                    pInfo.Balance = 0;
                    LogAction(userID, pInfo.Balance, typeLog, false);
                }
                else {
                    pInfo.Balance -= amount;
                    LogAction(userID, amount, typeLog, false);
                }
                PlayerInfo.SaveOffline(userID, pInfo);
                Interface.Oxide.CallHook("OnRemovedBalance", UInt64.Parse(userID), amount, null, pInfo.Balance);
                Interface.Oxide.CallHook("OnUpdatedBalance", UInt64.Parse(userID), null, pInfo.Balance);
            }
        }
        private Item OnItemSplited(Item item, Int32 amount)  //Other plugin hook
        {
            switch (item.skin) {
                case 47328465 : case 57854932 : case 23156768 : case 31213265 : return null;
            }
            Item x = config.generalSetting.physicsItem.CreatePhysicMoney(amount);
            item.amount -= amount;
            item.MarkDirty();
            return x;
        }
        private void OnPlayerDeath(BasePlayer target, HitInfo hitInfo) {
            if(!target) return;
            Boolean isRealPlayerTarget = IsRealPlayer(target);
            Configuration.EarningCoins.PresetEarning earningPlayer = config.earningCoins.killedPlayer;
            Configuration.EarningCoins.PresetEarning earningNpc = config.earningCoins.killedNpcs;
            if (isRealPlayerTarget) {
                if (isUsedUI) InterfaceBuilder.DestroyPlayerUI(target);
                if (config.generalSetting.physicsItem.useSaveDeath && config.generalSetting.typeCoins == TypeCoins.Physics) {
                    Int32 balance = GetBalancePlayer(target);
                    RemoveBalance(target, balance, TypeLog.SaveAfterDeath);
                    saveAfterDeath[target] = balance;
                }
            }
            if (!earningPlayer.useEarning && !earningNpc.useEarning) return;
            if (hitInfo == null) return;
            BasePlayer attacker = hitInfo.InitiatorPlayer;
            if (!attacker) return;
            if (!IsRealPlayer(attacker)) return;
            if (attacker == target) return;
            if (isRealPlayerTarget) {
                if (IsBlockedEarningKillPlayer(attacker, target)) return;
                if (!IsOnlyTakeEarning(attacker, earningPlayer)) return;
                AddBalance(attacker, earningPlayer.countMoney, TypeLog.Action, earningPlayer.useChatAlert ? "CHAT_ALERT_EARNING_KILLED_PLAYER" : default, earningNpc.useNoteAlert);
                return;
            }
            if (!IsOnlyTakeEarning(attacker, earningNpc)) return;
            AddBalance(attacker, earningNpc.countMoney, TypeLog.Action, earningNpc.useChatAlert ? "CHAT_ALERT_EARNING_KILLED_NPC" : default, earningNpc.useNoteAlert);
        }
        private void Unload() {
            if (_ == null) return;
            if (coroutineMigrate != null) {
                ServerMgr.Instance.StopCoroutine(coroutineMigrate);
                coroutineMigrate = null;
            }
            else {
                foreach (BasePlayer player in BasePlayer.activePlayerList) DisconnectedPlayer(player);
            }
            if (!String.IsNullOrWhiteSpace(config.commandExchanger) && config.exchangerSetting.useExchanger) WriteData();
            if (saveAfterDeath != null) {
                saveAfterDeath.Clear();
                saveAfterDeath = null;
            }
            if (heliKilleds != null) {
                heliKilleds.Clear();
                heliKilleds = null;
            }
            if (timerTrackerTimes is {
                Destroyed : false
            }
            ) {
                timerTrackerTimes.Destroy();
                timerTrackerTimes = null;
            }
            if (timerWaitSQL is {
                Destroyed : false
            }
            ) {
                timerWaitSQL.Destroy();
                timerWaitSQL = null;
            }
            if (timerUpdateCourse is {
                Destroyed : false
            }
            ) {
                timerUpdateCourse.Destroy();
                timerUpdateCourse = null;
            }
            if (sqlConnection != null && sqlLibrary != null) {
                sqlLibrary.CloseDb(sqlConnection);
                sqlConnection = null;
            }
            InterfaceBuilder.DestroyAll();
            if (_imageUI != null) {
                _imageUI.UnloadImages();
                _imageUI = null;
            }
            if (cachedUI != null) {
                cachedUI.Clear();
                cachedUI = null;
            }
            if (exchangerDataPlayer != null) {
                exchangerDataPlayer.Clear();
                exchangerDataPlayer = null;
            }
            lootedEntity.Clear();
            _ = null;
        }
        private (BasePlayer, String) FindPlayerNameOrID(BasePlayer finder, String nameOrID) {
            List<BasePlayer> players = Pool.Get<List<BasePlayer>>();
            players.AddRange(BasePlayer.activePlayerList);
            if (nameOrID.IsSteamId() && ulong.TryParse(nameOrID, out UInt64 userID)) {
                BasePlayer player = BasePlayer.FindByID(userID);
                Pool.FreeUnmanaged(ref players);
                return (player, null);
            }
            List<BasePlayer> matchingPlayers = Pool.Get<List<BasePlayer>>();
            try {
                matchingPlayers.AddRange(players.Where(player => player.displayName != null && player.displayName.IndexOf(nameOrID, StringComparison.OrdinalIgnoreCase) >= 0));
                switch (matchingPlayers.Count) {
                    case 1 : {
                        BasePlayer foundPlayer = matchingPlayers[0];
                        return (foundPlayer, null);
                    }
                    case > 1 : {
                        String nicknameList = String.Join(", ", matchingPlayers.Take(3).Select(p => p.displayName));
                        return (null, GetLang("CHAT_ALERT_TRANSFER_MATCHES_PLAYERS", finder.UserIDString, nameOrID, nicknameList));
                    }
                    default : return (null, null);
                }
            }
            finally {
                Pool.FreeUnmanaged(ref players);
                Pool.FreeUnmanaged(ref matchingPlayers);
            }
        }
        private void UpdateExchangedUI(BasePlayer player, Int32 balancePlayer, Int32 limitExchanged) {
            if (!exchangerDataPlayer.ContainsKey(player)) return;
            DrawUI_UpdateExchangeBalance_Menu(player, balancePlayer);
            DrawUI_UpdateExchangeOne_Menu(player, balancePlayer, limitExchanged, exchangerDataPlayer[player]);
            DrawUI_UpdateExchangeFull_Menu(player, balancePlayer, limitExchanged);
            if (limitExchanged >= 0) DrawUI_UpdateExchangeLimite_Menu(player, limitExchanged);
        }
        private abstract class DataManager<T> where T : DataManager<T>, new() {
            private const String baseFolder = "IQSystem/IQEconomic/";
            public static Dictionary<String, T> _players = new();
            protected static void ImportPlayer(String userId, T data) => _players[userId] = data;
            protected static void SavePlayer(String userId) {
                if (!_players.TryGetValue(userId, out T data)) return;
                Interface.Oxide.DataFileSystem.WriteObject(baseFolder + userId, data);
            }
            protected static void SaveOfflinePlayer(String userId, T data) => Interface.Oxide.DataFileSystem.WriteObject(baseFolder + userId, data);
            protected static void RemovePlayer(String userId) {
                if (!_players.ContainsKey(userId)) return;
                _players.Remove(userId);
            }
            protected static void DeletePlayer(String userId) {
                RemovePlayer(userId);
                Interface.Oxide.DataFileSystem.DeleteDataFile(baseFolder + userId);
            }
            protected static T GetPlayer(String userId) => _players.GetValueOrDefault(userId);
            protected static T GetOfflinePlayer(String userId) {
                T data = null;
                try {
                    data = Interface.Oxide.DataFileSystem.ReadObject<T>(baseFolder + userId);
                }
                catch (Exception e) {
                    Interface.Oxide.LogError(e.ToString());
                }
                return data;
            }
            protected static T LoadPlayer(String userId) {
                T data = null;
                try {
                    data = Interface.Oxide.DataFileSystem.ReadObject<T>(baseFolder + userId);
                }
                catch (Exception e) {
                    Interface.Oxide.LogError(e.ToString());
                }
                return _players[userId] = data;
            }
            protected static String[] GetFilesPlayers() {
                try {
                    Int32 json = ".json".Length;
                    String[] paths = Interface.Oxide.DataFileSystem.GetFiles(baseFolder, "*.json");
                    for (Int32 i = 0; i < paths.Length; i++) {
                        String path = paths[i];
                        Int32 separatorIndex = path.LastIndexOf("/", StringComparison.Ordinal);
                        paths[i] = path.Substring(separatorIndex + 1, path.Length - separatorIndex - 1 - json);
                    }
                    return paths;
                }
                catch {
                    return Array.Empty<String>();
                }
            }
        }
        void API_SET_BALANCE(BasePlayer player, Int32 balance, ItemContainer itemContainer = null) => AddBalance(player, balance, TypeLog.API);
        private void SendChat(String Message, BasePlayer player, Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            Configuration.OtherPlugins.IQChatSetting chatContoller = config.otherPlugins.settingIQChat;
            if (IQChat) {
                if (chatContoller.useUiAlert) IQChat.Call("API_ALERT_PLAYER_UI", player, Message);
                else IQChat.Call("API_ALERT_PLAYER", player, Message, chatContoller.customPrefix, chatContoller.customAvatar);
            }
            else player.SendConsoleCommand("chat.add", channel, 0, Message);
        }
        private Boolean isUsedSQL = false;
        private void OnEntityEnter(TriggerWorkbench trigger, BasePlayer player) {
            if (!player || player.IsNpc) return;
            InterfaceBuilder.DestroyPlayerUI(player);
        }
        private void OnNewSave(String filename) => CleanerDataFiles();
        private void OnServerInitialized() {
            RegisteredPermission();
            if (isUsedSQL) SQL_OpenConnection();
            if (config.earningCoins.timeTracked.timeTrackerPreset.useEarning) timerTrackerTimes = timer.Every(timeTracker, TrackedPlayers);
            if (config.generalSetting.interfaceSetting.useUI) {
                _imageUI = new ImageUI();
                _imageUI.DownloadImage();
            }
            else {
                if (!_.isUsedSQL) foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
            }
            cmd.AddChatCommand(config.commandBalance, this, nameof(ChatCommandBalance));
            cmd.AddConsoleCommand(config.commandBalance, this, nameof(ConsoleCommandBalance));
            if (isUsedExchanger) {
                orderedListExchanged = config.exchangerSetting.GetOrderedList();
                UpdateExchangerCourse();
                timerUpdateCourse = timer.Every(timeUpdateCourse, UpdateExchangerCourse);
                cmd.AddChatCommand(config.commandExchanger, this, nameof(ChatCommandExchanger));
                cmd.AddConsoleCommand(config.commandExchanger, this, nameof(ConsoleCommandExchanger));
            }
            else if (config.exchangerSetting.useTransferP2P) {
                cmd.AddChatCommand(config.commandExchanger, this, nameof(ChatCommandExchanger));
                cmd.AddConsoleCommand(config.commandExchanger, this, nameof(ConsoleCommandExchanger));
            }
        }
        void API_SET_BALANCE(String userID, Int32 balance, ItemContainer itemContainer = null) {
            if (!UInt64.TryParse(userID, out UInt64 id)) return;
            BasePlayer player = BasePlayer.FindByID(id);
            if(!player) AddBalance(userID, balance, TypeLog.API);
            else AddBalance(player, balance, TypeLog.API);
        }
        private const String actionLogRemoved = (LanguageEn ? "written off" : "списано");
        private Boolean IsTakeEarning(BasePlayer player, Configuration.EarningCoins.PresetEarning earning) => IsRealPlayer(player) && earning.IsEarning(player);
        private Item OnItemSplit(Item item, Int32 amount) {
            if (item.skin != config.generalSetting.physicsItem.skinID) return null;
            Item x = config.generalSetting.physicsItem.CreatePhysicMoney(amount);
            item.amount -= amount;
            item.MarkDirty();
            return x;
        }
        // TODO: Множитель получения валюты по разрешению [Под вопросом]
        /// <summary>
        /// - Изменана конфигурация по настройке выпадаемой валюты с ящиков
        /// - Добавлена возможность начисление валюты за лутание ящиков для типа - Виртуальная
        /// - Добавлена возможность включить отображенеи получения валюты в уведомлении Rust'a над метаболизмом
        /// - Добавлена поддержка новых животных Gen2
        /// - Добавлена поддержка новых NPC Gen2
        /// - Корректировка в ответе API DoesHaveEnoughBalance при снятии нулевого баланса
        /// - Исправлено, когда награда за вертолет могла не начислиться
        /// </summary>
        [PluginReference]
        Plugin IQChat, Friends, Clans, Battles, Duel, RustStore, GameStoresRUST, Duelist, ArenaTournament, XFarmRoom;
        private Configuration.ExchangerSetting.CourseController actualyCourse = null;
        private const String arrowLogRemoved = "=======>";
        private const String actionLogReceived = (LanguageEn ? "received" : "получил");
        private const String transferPrivilage = "iqeconomic.transferuse";
        private Int32 GetPlayerPhysicMoney(BasePlayer player) {
            Configuration.GeneralSetting.PhysicsItem physicConfig = config.generalSetting.physicsItem;
            Int32 balance = 0;
            List<Item> allItems = GetAllItems(player);
            foreach (Item itemInInventory in allItems) {
                if (physicConfig.IsPhysicMoney(itemInInventory)) balance += itemInInventory.amount;
            }
            Pool.FreeUnmanaged(ref allItems);
            return balance;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                if (config.earningCoins.droppedItem == null) {
                    config.earningCoins.droppedItem = new Configuration.EarningCoins.DroppedItem() {
                        isUseDropped = false, dropItemPresets = new Dictionary<String, Configuration.EarningCoins.DroppedItem.DropSetting>() {
                            ["heli_crate"]
                            = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 100, amountMin = 5, amountMax = 10
                            }
                            , ["bradley_crate"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 80, amountMin = 10, amountMax = 15
                            }
                            , ["crate_elite"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 70, amountMin = 2, amountMax = 3
                            }
                            , ["crate_normal"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 50, amountMin = 1, amountMax = 2
                            }
                            , ["crate_normal_2"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 50, amountMin = 1, amountMax = 2
                            }
                            , ["crate_basic"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 20, amountMin = 1, amountMax = 1
                            }
                            , ["crate_tools"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 20, amountMin = 1, amountMax = 1
                            }
                            ,
                        }
                    }
                    ;
                }
                if (config.earningCoins.droppedItem.dropItemPresets == null || config.earningCoins.droppedItem.dropItemPresets.Count == 0) {
                    config.earningCoins.droppedItem = new Configuration.EarningCoins.DroppedItem() {
                        isUseDropped = false, dropItemPresets = new Dictionary<String, Configuration.EarningCoins.DroppedItem.DropSetting>() {
                            ["heli_crate"]
                            = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 100, amountMin = 5, amountMax = 10
                            }
                            , ["bradley_crate"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 80, amountMin = 10, amountMax = 15
                            }
                            , ["crate_elite"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 70, amountMin = 2, amountMax = 3
                            }
                            , ["crate_normal"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 50, amountMin = 1, amountMax = 2
                            }
                            , ["crate_normal_2"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 50, amountMin = 1, amountMax = 2
                            }
                            , ["crate_basic"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 20, amountMin = 1, amountMax = 1
                            }
                            , ["crate_tools"] = new Configuration.EarningCoins.DroppedItem.DropSetting() {
                                rare = 20, amountMin = 1, amountMax = 1
                            }
                            ,
                        }
                    }
                    ;
                }
                if (config.earningCoins.killedBarrels == null) {
                    config.earningCoins.killedBarrels = new Configuration.EarningCoins.PresetEarning() {
                        useEarning = false, permissionEarning = String.Empty, rare = 20, countMoney = 3
                    }
                    ;
                }
                if (config.generalSetting.interfaceSetting.colorsUI == null) {
                    config.generalSetting.interfaceSetting.colorsUI = new Configuration.GeneralSetting.InterfaceSetting.ColorsSetting() {
                        colorText = "0.969 0.922 0.882 1", colorPanel = "0.969 0.922 0.882 0.03137255"
                    }
                    ;
                }
                if (config.generalSetting.interfaceSetting.positionUI == null) {
                    config.generalSetting.interfaceSetting.positionUI = new Configuration.GeneralSetting.InterfaceSetting.PositionsSetting() {
                        balanceIconHided = new Configuration.GeneralSetting.InterfaceSetting.PositionsSetting.PositionPreset() {
                            anchorMin = "1 0", anchorMax = "1 0", offsetMin = "-235.733 15.867", offsetMax = "-209.733 41.867"
                        }
                        , balancePanel = new Configuration.GeneralSetting.InterfaceSetting.PositionsSetting.PositionPreset {
                            anchorMin = "1 0", anchorMax = "1 0", offsetMin = "-340.067 15.867", offsetMax = "-238.067 41.867"
                        }
                        , firstButton = new Configuration.GeneralSetting.InterfaceSetting.PositionsSetting.PositionPreset {
                            anchorMin = "1 0", anchorMax = "1 0", offsetMin = "-235.733765 43.667567", offsetMax = "-209.73345 69.66776"
                        }
                        , twoButton = new Configuration.GeneralSetting.InterfaceSetting.PositionsSetting.PositionPreset {
                            anchorMin = "1 0", anchorMax = "1 0", offsetMin = "-235.73356 71.84754", offsetMax = "-209.73365 97.84776"
                        }
                    }
                    ;
                }
            }
            catch {
                PrintWarning(LanguageEn ? "Error #49" + $"reading the configuration 'oxide/config/{Name}', creating a new configuration! #33" : "Ошибка #49" + $"чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию! #33");
                LoadDefaultConfig();
            }
            NextTick(SaveConfig);
        }
        private void GetPlayerSQL(String userID, BasePlayer player = null) {
            if (sqlConnection == null) return;
            Sql sql = SQL_SelectPlayer(userID);
            sqlLibrary.Query(sql, sqlConnection, list => {
                if (list == null || list.Count == 0) {
                    PlayerInfo.Import(userID, new PlayerInfo {
                        Balance = 0, LimitBalance = 0, Time = 0, DateTime = CurrentTime, IsHide = false,
                    }
                    );
                    if (player) DrawUI_HudPanel(player);
                    return;
                }
                Dictionary<String, Object> entry = list[0];
                Int32 balance = ReadInt(entry["balance"]);
                Int32 limit = ReadInt(entry["limit_balance"]);
                Int32 time = ReadInt(entry["time"]);
                Boolean hide = ReadBool(entry["is_hide"]);
                PlayerInfo.Import(userID, new PlayerInfo {
                    Balance = balance, LimitBalance = limit, Time = time, DateTime = CurrentTime, IsHide = hide,
                }
                );
                if (player) DrawUI_HudPanel(player);
            }
            );
        }
        private void OnEntityDeath(BradleyAPC entity, HitInfo info) {
            Configuration.EarningCoins.PresetEarning earning = config.earningCoins.killedBradley;
            if (!earning.useEarning) return;
            if (!entity || info == null) return;
            BasePlayer player = info.InitiatorPlayer;
            if(!IsTakeEarning(player, earning)) return;
            AddBalance(player, earning.countMoney, TypeLog.Action, earning.useChatAlert ? "CHAT_ALERT_EARNING_DESTROY_BRADLEY" : default, earning.useNoteAlert);
        }
        public class CourseInfo {
            public Double lastUpdateCourseTime = 0;
            public Int32 keyCourse;
        }
        void API_REMOVE_BALANCE(UInt64 userID, Int32 balance) {
            String idString = userID.ToString();
            API_REMOVE_BALANCE(idString, balance);
        }
        private static Configuration config = new Configuration();
        private Sql SQL_UpsertPlayer(String steamId, Int32 balance, Int32 limit, Int32 time, Double lastConn, Boolean isHide) {
            return Sql.Builder.Append($"INSERT INTO `{config.generalSetting.mySQLConnectionSettings.dbTableName}` (steamid,balance,limit_balance,`time`,last_connection,`is_hide`) " + $"VALUES (@0,@1,@2,@3,@4,@5) " + $"ON DUPLICATE KEY UPDATE " + $"balance=@1, limit_balance=@2, `time`=@3, last_connection=@4, `is_hide`=@5;", steamId, balance.ToString(), limit.ToString(), time.ToString(), lastConn.ToString(System.Globalization.CultureInfo.InvariantCulture), isHide ? "true" : "false" );
        }
        Boolean API_IS_REMOVED_BALANCE(String userID, Int32 amount) {
            if (!UInt64.TryParse(userID, out UInt64 id)) return false;
            BasePlayer player = BasePlayer.FindByID(id);
            return player && DoesHaveEnoughBalance(player, amount);
        }
        private readonly Dictionary<UInt64, BasePlayer> heliLastAttacker = new();
        private static void AddUI(BasePlayer player, String json) {
            if (!player || player.net?.connection == null) return;
            CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("AddUI", player.net.connection), json);
        }
        private Dictionary<BasePlayer, Int32> exchangerDataPlayer = new();
        private const Boolean LanguageEn = false;
        private void UpdateExchangerCourse() {
            Configuration.ExchangerSetting.CourseController courseUpdated = GetActualyCourse();
            if (actualyCourse != null && courseUpdated == actualyCourse) return;
            actualyCourse = courseUpdated;
            if (courseData.keyCourse == courseUpdated.secondsAfterWipe) return;
            courseData.keyCourse = actualyCourse.secondsAfterWipe;
            courseData.lastUpdateCourseTime = CurrentTime;
            if (!config.exchangerSetting.useMessageUpdateCourse) return;
            foreach (BasePlayer basePlayer in BasePlayer.activePlayerList) SendChat(GetLang("CHAT_ALERT_COURSE_UPDATE", basePlayer.UserIDString, config.commandExchanger), basePlayer);
        }
        void API_TRANSFERS(UInt64 userID, BasePlayer transferUser, Int32 balance) {
            BasePlayer player = BasePlayer.FindByID(userID);
            if (!player) return;
            if (!transferUser) return;
            TransferToPlayer(player, transferUser, balance);
        }
        private Boolean DoesHaveEnoughBalance(Int32 balancePlayer, Int32 amount = 0) {
            if (balancePlayer == 0) return true;
            return balancePlayer >= amount;
        }
        private void OnPlayerSleep(BasePlayer player) {
            if (!player) return;
            if (_interface == null) return;
            InterfaceBuilder.DestroyPlayerUI(player);
        }
        private Boolean isUsedExchanger = false;
        private const Int32 timeUpdateCourse = 600;
        private Connection sqlConnection = null;
        public String FormatTime(TimeSpan time, string userId) {
            if (time.Days > 0) return Format(time.Days, GetLang("EXCHANGER_COURSE_TITLE_FORMAT_TIME_DAYS", userId));
            if (time.Hours > 0) return Format(time.Hours, GetLang("EXCHANGER_COURSE_TITLE_FORMAT_TIME_HOURSE", userId));
            if (time.Minutes > 0) return Format(time.Minutes, GetLang("EXCHANGER_COURSE_TITLE_FORMAT_TIME_MINUTES", userId));
            return time.Seconds > 0 ? Format(time.Seconds, GetLang("EXCHANGER_COURSE_TITLE_FORMAT_TIME_SECONDS", userId)) : String.Empty;
        }
        private void DrawUI_StaticHider(BasePlayer player, Boolean hideStatus) {
            if (_interface == null) return;
            String panelType = !hideStatus ? "UI_Hide_Panel_Static" : "UI_UnHide_Panel_Static";
            DestroyUI(player, InterfaceBuilder.UI_PANEL_STATIC_HIDER);
            List<String> cashedStaticPanel = GetOrSetCacheUI(panelType);
            if (cashedStaticPanel != null) {
                foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
            }
            else {
                String Interface = InterfaceBuilder.GetInterface(panelType);
                if (Interface == null) return;
                List<String> newUI = GetOrSetCacheUI(panelType, Interface);
                cashedStaticPanel = newUI;
                foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
            }
        }
        private Sql SQL_CreateTableIfNotExists() {
            return Sql.Builder.Append($"CREATE TABLE IF NOT EXISTS `{config.generalSetting.mySQLConnectionSettings.dbTableName}` (" + "`id` INT NOT NULL AUTO_INCREMENT," + "`steamid` VARCHAR(32) NOT NULL," + "`balance` VARCHAR(20) NOT NULL," + "`limit_balance` VARCHAR(20) NOT NULL," + "`time` VARCHAR(20) NOT NULL," + "`last_connection` VARCHAR(32) NOT NULL," + "`is_hide` VARCHAR(6) NOT NULL," + "PRIMARY KEY(`id`)," + "UNIQUE KEY `ux_steamid` (`steamid`)" + $") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;");
        }
        private Boolean IsOnlyTakeEarning(BasePlayer player, Configuration.EarningCoins.PresetEarning earning) => earning.IsEarning(player);
        private ImageUI _imageUI;
        private void HookController() {
            Configuration.EarningCoins earningCoins = config.earningCoins;
            if (!earningCoins.timeTracked.useAfkChecker) {
                Unsubscribe(nameof(OnPlayerChat));
                Unsubscribe(nameof(OnPlayerCommand));
                Unsubscribe(nameof(OnItemCraft));
                Unsubscribe(nameof(OnItemCraftCancelled));
            }
            if (!isUsedUI) {
                Unsubscribe(nameof(OnPlayerSleepEnded));
                Unsubscribe(nameof(OnPlayerSleep));
            }
            if (!isUsedSQL) Unsubscribe(nameof(CanUserLogin));
            else {
                Unsubscribe(nameof(OnNewSave));
                Unsubscribe(nameof(OnPlayerConnected));
            }
            if (config.generalSetting.typeCoins == TypeCoins.Virtual) {
                Unsubscribe(nameof(OnLootSpawn));
                Unsubscribe(nameof(OnItemSplit));
            }
            else {
                Unsubscribe(nameof(OnLootEntity));
                if (!config.earningCoins.droppedItem.isUseDropped) Unsubscribe(nameof(OnLootSpawn));
                if (config.generalSetting.physicsItem.skinID == 0 || plugins.Find("Stacks") || plugins.Find("Loottable") || plugins.Find("CustomSkinsStacksFix") || plugins.Find("SkinBox") || plugins.Find("StackModifier")) {
                    Unsubscribe(nameof(OnPluginLoaded));
                    Unsubscribe(nameof(OnItemSplit));
                }
            }
            Boolean anyGather = earningCoins.resourceGatherEarning.Count == 0 || earningCoins.resourceGatherEarning.Any(x => x.Value.useEarning);
            if(!anyGather) Unsubscribe(nameof(OnDispenserBonusReceived));
            Boolean anyCollectable = earningCoins.resourceCollectable.Count == 0 || earningCoins.resourceCollectable.Any(x => x.Value.useEarning);
            if(!anyCollectable) Unsubscribe(nameof(OnCollectiblePickedup));
            if (!isUsedUI && !earningCoins.killedPlayer.useEarning && !earningCoins.killedNpcs.useEarning && !config.generalSetting.physicsItem.useSaveDeath) Unsubscribe(nameof(OnPlayerDeath));
            if(!config.generalSetting.physicsItem.useSaveDeath || config.generalSetting.typeCoins == TypeCoins.Virtual) Unsubscribe(nameof(OnPlayerRespawned));
            if (!earningCoins.killedBradley.useEarning && !earningCoins.killedAnimal.useEarning && !earningCoins.killedBarrels.useEarning) Unsubscribe(nameof(OnEntityDeath));
            if (!earningCoins.killedHelicopter.useEarning) {
                Unsubscribe(nameof(OnPatrolHelicopterKill));
                Unsubscribe(nameof(OnPatrolHelicopterTakeDamage));
            }
            if(!earningCoins.killedHelicopter.useEarning && !earningCoins.droppedItem.isUseDropped) Unsubscribe(nameof(OnEntityKill));
        }
        private void StoreAddedBalance(BasePlayer player, (Int32 exchangeCoins, Int32 storeMoney) exchangeDetail, UInt64 userID = 0) {
            MoscovOVHBalanceSet(player, exchangeDetail, userID);
            GameStoreBalanceSet(player, exchangeDetail, userID);
        }
        private void GameStoreBalanceSet(BasePlayer player, (Int32 exchangeCoins, Int32 storeMoney) exchangeDetail, UInt64 userID = 0) {
            if (!config.exchangerSetting.storeSetting.useGameStores) return;
            if (!GameStoresRUST) {
                PrintWarning(LanguageEn ? "GameStores store is not configured" : "У вас не установлен магазин GameStores");
                return;
            }
            if (exchangeDetail.storeMoney <= 0) return;
            Boolean isSetOffline = !player || exchangeDetail.exchangeCoins <= 0;
            userID = !isSetOffline ? player.userID : userID;
            PlayerInfo pInfo = PlayerInfo.Get(userID.ToString());
            if (!isSetOffline) {
                if (config.exchangerSetting.limitStoreMoney > 0 && pInfo != null) {
                    Int32 limit = config.exchangerSetting.limitStoreMoney;
                    Int32 left = Math.Max(0, limit - pInfo.LimitBalance);
                    if (left <= 0 || exchangeDetail.storeMoney <= 0) return;
                    if (exchangeDetail.storeMoney > left) {
                        Int32 allowedPacksMoney = left;
                        Int32 allowedCoins = (allowedPacksMoney / actualyCourse.storeMoney) * actualyCourse.coin;
                        if (allowedCoins <= 0) return;
                        exchangeDetail = (allowedCoins, (allowedCoins * actualyCourse.storeMoney) / actualyCourse.coin);
                    }
                    pInfo.LimitBalance += exchangeDetail.storeMoney;
                }
                RemoveBalance(player, exchangeDetail.exchangeCoins, TypeLog.Exchanger);
                SendChat(GetLang("CHAT_ALERT_EXCHANGED_SUCCES", player.UserIDString), player);
            }
            GameStoresRUST.CallHook("API_ChangePlayerBalance", userID, exchangeDetail.storeMoney, "plus", null, new Action<Boolean, String>((code, result) => {
                LogToFile("DebugGS", $"GameStores DebugFile : [{DateTime.Now:dd : HH:mm:ss}] {userID} isSetOffline : {isSetOffline}, exchangeCoins : {exchangeDetail.exchangeCoins}, code : {code}, result : {result}", this);
                if (code) {
                    return;
                }
                if (isSetOffline) return;
                SendChat(GetLang("CHAT_ALERT_EXCHANGED_FAIL", player.UserIDString), player);
            }
            ));
        }
        private void RemoveBalance(BasePlayer player, Int32 amount, TypeLog typeLog) {
            if (!player) return;
            PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
            if (pInfo == null) return;
            RemoveBalance(player, pInfo, amount, typeLog);
        }
        void API_TRANSFERS(UInt64 userID, String transferUserID, Int32 balance) {
            BasePlayer player = BasePlayer.FindByID(userID);
            if (!player) return;
            TransferToPlayer(player, transferUserID, balance);
        }
        private void DrawUI_UpdateHider(BasePlayer player, Boolean typeHide) {
            if (!isUsedUI) return;
            if (player.IsSleeping()) return;
            if (_interface == null) return;
            String panelType = String.Empty;
            if (typeHide) {
                DrawUI_StaticIconBalance(player);
                panelType = "UI_UnHide_Panel_Update";
            }
            else {
                panelType = "UI_Hide_Panel_Update";
                DrawUI_StaticPanelBalance(player);
            }
            List<String> cashedStaticPanel = GetOrSetCacheUI(panelType);
            if (cashedStaticPanel != null) {
                foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
            }
            else {
                String Interface = InterfaceBuilder.GetInterface(panelType);
                if (Interface == null) return;
                List<String> newUI = GetOrSetCacheUI(panelType, Interface);
                cashedStaticPanel = newUI;
                foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
            }
        }
        private void OnPatrolHelicopterKill(PatrolHelicopter patrolHelicopter, HitInfo info) {
            UInt64 patrolNetID = patrolHelicopter.net.ID.Value;
            BasePlayer player = info.InitiatorPlayer;
            if (!IsRealPlayer(player)) return;
            heliKilleds[patrolNetID] = player;
        }
        private Boolean isUsedUI = false;
        private void DisconnectedPlayer(BasePlayer player) {
            if (isUsedSQL) {
                PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
                if (pInfo == null) return;
                ImportPlayerSQL(player.UserIDString, pInfo.Balance, pInfo.LimitBalance, pInfo.Time, pInfo.DateTime, pInfo.IsHide);
                return;
            }
            PlayerInfo.Save(player.UserIDString);
            PlayerInfo.Remove(player.UserIDString);
        }
        private Boolean IsDuel(UInt64 userID) {
            Object obj = Interface.Oxide.RootPluginManager.GetPlugin("AimTraining")?.CallHook("IsArenaPlayer", userID);
            if (obj is Boolean) return (Boolean)obj;
            if (Battles) return (Boolean)Battles?.Call("IsPlayerOnBattle", userID);
            if (Duel) return (Boolean)Duel?.Call("IsPlayerOnActiveDuel", BasePlayer.FindByID(userID));
            if (Duelist) return (Boolean)Duelist?.Call("inEvent", BasePlayer.FindByID(userID));
            if (ArenaTournament) return ArenaTournament.Call<Boolean>("IsOnTournament", userID);
            if (XFarmRoom) return XFarmRoom.Call<Boolean>("API_PlayerInRoom", userID);
            return false;
        }
        private void OnPlayerRespawned(BasePlayer player) {
            if (!saveAfterDeath.TryGetValue(player, out Int32 balance)) return;
            if (balance == 0) return;
            AddBalance(player, balance, TypeLog.ReturnedSaveAfterDeath);
        }
        private void WriteData() => Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQEconomic/Exchanger/UpdateCourseTime", courseData);
        private Dictionary<String, List<String>> cachedUI = new();
        private void OnEntityDeath(LootContainer entity, HitInfo info) {
            if (!entity.PrefabName.Contains("barrel") || entity.PrefabName.Contains("hobobarrel")) return;
            Configuration.EarningCoins.PresetEarning earning = config.earningCoins.killedBarrels;
            if (!earning.useEarning) return;
            if (!entity || info == null) return;
            BasePlayer player = info.InitiatorPlayer;
            if(!IsTakeEarning(player, earning)) return;
            AddBalance(player, earning.countMoney, TypeLog.Action, earning.useChatAlert ? "CHAT_ALERT_EARNING_DESTROY_BARREL" : default, earning.useNoteAlert);
        }
        private void ConnectedPlayer(BasePlayer player) {
            PlayerInfo pInfo = PlayerInfo.Load(player.UserIDString);
            if (pInfo != null) {
                pInfo.DateTime = CurrentTime;
                return;
            }
            PlayerInfo.Import(player.UserIDString, new PlayerInfo {
                Balance = 0, LimitBalance = 0, Time = 0, DateTime = CurrentTime, IsHide = false,
            }
            );
            PlayerInfo.Save(player.UserIDString);
        }
        private void ImportPlayerSQL(String userID, Int32 balance, Int32 limitBalance, Int32 time, Double dateTime, Boolean isHide, Boolean isMigrate = false) {
            if (sqlConnection == null) return;
            Sql upsert = SQL_UpsertPlayer(userID, balance, limitBalance, time, dateTime, isHide);
            sqlLibrary.Insert(upsert, sqlConnection, _ => {
                if (!isMigrate) Puts(LanguageEn ? $"Player {userID} data has been inserted/updated in the database" : $"Данные игрока {userID} были внесены/обновлены в базе данных");
            }
            );
        }
        private void RemovePhysicMoney(BasePlayer player, Int32 amount) {
            List<Item> physicMoney = GetPhysicsItems(player);
            foreach (Item pItem in physicMoney) {
                if (amount <= 0) break;
                if (pItem.amount >= amount) {
                    pItem.amount -= amount;
                    if (pItem.amount == 0) {
                        pItem.RemoveFromContainer();
                        pItem.Remove();
                    }
                    amount = 0;
                }
                else {
                    amount -= pItem.amount;
                    pItem.RemoveFromContainer();
                    pItem.Remove();
                }
                pItem.MarkDirty();
            }
            Pool.FreeUnmanaged(ref physicMoney);
        }
        private Boolean IsFriends(BasePlayer player, UInt64 targetID) {
            List<UInt64> friendList = GetFriendList(player);
            Boolean isFriend = friendList != null && friendList.Contains(targetID);
            Pool.FreeUnmanaged(ref friendList);
            return isFriend;
        }
        void API_TRANSFERS(BasePlayer player, UInt64 transferUserID, Int32 balance) {
            if (!player) return;
            BasePlayer targetPlayer = BasePlayer.FindByID(transferUserID);
            if (!targetPlayer) return;
            TransferToPlayer(player, targetPlayer, balance);
        }
        private readonly Core.MySql.Libraries.MySql sqlLibrary = Interface.Oxide.GetLibrary<Core.MySql.Libraries.MySql>();
        private void DrawUI_UpdateExchangeLimite_Menu(BasePlayer player, Int32 limitExchanged) {
            if (!exchangerDataPlayer.ContainsKey(player)) return;
            if (player.IsSleeping()) return;
            if (_interface == null) return;
            String Interface = InterfaceBuilder.GetInterface("UI_Exchanger_Update_Limite_Label");
            if (Interface == null) return;
            Interface = Interface.Replace("%EXCHANGER_ACTUALY_LIMITE%", GetLang("EXCHANGER_ACTUALY_LIMITE", player.UserIDString, limitExchanged));
            AddUI(player, Interface);
        }
        void API_TRANSFERS(UInt64 userID, UInt64 transferUserID, Int32 balance) {
            BasePlayer player = BasePlayer.FindByID(userID);
            if (!player) return;
            TransferToPlayer(player, transferUserID.ToString(), balance);
        }
        private void TrackedPlayers() {
            Configuration.EarningCoins.PresetEarning timerEarning = config.earningCoins.timeTracked.timeTrackerPreset;
            Boolean isCheckAFK = config.earningCoins.timeTracked.useAfkChecker;
            List<BasePlayer> pList = Pool.Get<List<BasePlayer>>();
            pList.AddRange(BasePlayer.activePlayerList);
            foreach (BasePlayer player in pList) {
                PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
                if (pInfo == null) continue;
                if(!IsOnlyTakeEarning(player, timerEarning)) continue;
                if(isCheckAFK) if (player.IdleTime > 30) continue;
                pInfo.Time += timeTracker / 60;
                if (pInfo.Time >= config.earningCoins.timeTracked.timeMinuteGame) {
                    AddBalance(player, pInfo, timerEarning.countMoney, TypeLog.Action, timerEarning.useChatAlert ? "CHAT_ALERT_EARNING_TIME_TRACKED" : default);
                    pInfo.Time = 0;
                }
            }
            Pool.FreeUnmanaged(ref pList);
        }
        Boolean API_IS_REMOVED_BALANCE(BasePlayer player, Int32 amount) => DoesHaveEnoughBalance(player, amount);
        private void ConsoleCommandBalance(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            ChatCommandBalance(player);
        }
        private static Boolean IsUnblockExchangerCourse(Int32 timeExchange) => ((SaveRestore.SaveCreatedTime.ToUniversalTime().Subtract(epoch).TotalSeconds + timeExchange) - CurrentTime) <= 0;
        private void GetAndFunctionalBalancePlayerSQL(String userID, Boolean addOrRemove, Int32 amount = 0) {
            if (sqlConnection == null) return;
            sqlLibrary.Query(SQL_SelectPlayer(userID), sqlConnection, list => {
                if (list == null || list.Count == 0) {
                    Int32 balance = addOrRemove ? amount : 0;
                    PlayerInfo.Import(userID, new PlayerInfo {
                        Balance = balance, LimitBalance = 0, Time = 0, DateTime = CurrentTime, IsHide = false,
                    }
                    );
                }
                else {
                    var entry = list[0];
                    Int32 balance = ReadInt(entry["balance"]);
                    Int32 limit = ReadInt(entry["limit_balance"]);
                    Int32 time = ReadInt(entry["time"]);
                    Double last = ReadDouble(entry["last_connection"]);
                    Boolean hide = ReadBool(entry["is_hide"]);
                    Int32 newBalance = addOrRemove ? balance + amount : Math.Max(balance - amount, 0);
                    PlayerInfo.Import(userID, new PlayerInfo {
                        Balance = newBalance, LimitBalance = limi
// ... [Code preview truncated due to length. Full source in attached file] ...

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