C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections;
using UnityEngine.Networking;
using Pool = Facepunch.Pool;
using ConVar;
using System.Collections.Generic;
using Oxide.Core;
using Object = System.Object;
using Oxide.Core.Plugins;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using System.Linq;
using Oxide.Core.Database;
using System;
using System.Text;
namespace Oxide.Plugins {
[Info("IQEconomic", "Forum: https://topplugin.ru Ds: alone_sempai Vk: https://vk.com/rustnastroika", "1.0.5")]
[Description("Экономика на ваш сервер")]
public class IQEconomic : RustPlugin {
private void RegisteredPermission() {
permission.RegisterPermission(transferPrivilage, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.killedAnimal.permissionEarning)) permission.RegisterPermission(config.earningCoins.killedAnimal.permissionEarning, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.killedPlayer.permissionEarning)) permission.RegisterPermission(config.earningCoins.killedPlayer.permissionEarning, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.killedBradley.permissionEarning)) permission.RegisterPermission(config.earningCoins.killedBradley.permissionEarning, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.killedHelicopter.permissionEarning)) permission.RegisterPermission(config.earningCoins.killedHelicopter.permissionEarning, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.killedNpcs.permissionEarning)) permission.RegisterPermission(config.earningCoins.killedNpcs.permissionEarning, this);
if (!String.IsNullOrWhiteSpace(config.earningCoins.timeTracked.timeTrackerPreset.permissionEarning)) permission.RegisterPermission(config.earningCoins.timeTracked.timeTrackerPreset.permissionEarning, this);
foreach (KeyValuePair<String, Configuration.EarningCoins.PresetEarning> presetEarning in config.earningCoins.resourceGatherEarning) {
if (!String.IsNullOrWhiteSpace(presetEarning.Value.permissionEarning)) permission.RegisterPermission(presetEarning.Value.permissionEarning, this);
}
foreach (KeyValuePair<String, Configuration.EarningCoins.PresetEarning> presetEarning in config.earningCoins.resourceCollectable) {
if (!String.IsNullOrWhiteSpace(presetEarning.Value.permissionEarning)) permission.RegisterPermission(presetEarning.Value.permissionEarning, this);
}
}
private Boolean isUsedSQL = false;
private void OnPlayerConnected(BasePlayer player) => ConnectedPlayer(player);
private Int32 GetBalancePlayer(PlayerInfo pInfo) => pInfo?.Balance ?? 0;
private static Boolean IsUnblockExchangerCourse(Int32 timeExchange) => ((SaveRestore.SaveCreatedTime.ToUniversalTime().Subtract(epoch).TotalSeconds + timeExchange) - CurrentTime) <= 0;
private enum TypeLog {
API, Command, Exchanger, ExchangerReturned, Transfer, Action, SaveAfterDeath, ReturnedSaveAfterDeath,
}
private void AddBalance(BasePlayer player, Int32 amount, TypeLog typeLog, String alertMessage = default) {
if (!player) return;
PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
if (pInfo == null) return;
AddBalance(player, pInfo, amount, typeLog, alertMessage);
}
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 const String arrowLogRemoved = "=======>";
private Boolean isUsedUI = false;
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>();
}
}
}
private Boolean DoesHaveEnoughBalance(BasePlayer player, Int32 amount = 0) {
Int32 balancePlayer = GetBalancePlayer(player);
if (balancePlayer == 0) return false;
return balancePlayer >= amount;
}
/// <summary>
/// - Добавлен сброс лимита на обмен валюты при вайпе сервера
/// - Добавлена команда для сброса лимита на обмен валюты : iq.eco limit.reset SteamID
/// - Добавлена дополнительная проверка на плагины, влияющие на стаки физических монет, для исключения конфликтов
/// - Улучшен поиск игроков по нику при выполнении обмена валютой между игроками
/// - Добавлена команда позволяющая перенести все данные игроков с дата-файла в MySQL : migrate.data
/// Plans :
/// TODO: Убрать создание дата-файла в случае если все функции отключены, лимиты, UI, включена физическая монета
// TODO: Добавить кд на обмен
/// </summary>
[PluginReference]
Plugin IQChat, Friends, Clans, Battles, Duel, RustStore, GameStoresRUST, Duelist, ArenaTournament, XFarmRoom;
private void TransferToPlayer(BasePlayer player, String nameOrID, Int32 amount) {
if (String.IsNullOrWhiteSpace(nameOrID)) {
SendChat(GetLang("CHAT_ALERT_TRANSFER_NO_NAME", player.UserIDString), player);
return;
}
BasePlayer targetPlayer = BasePlayer.Find(nameOrID);
if (targetPlayer == null) {
SendChat(GetLang("CHAT_ALERT_TRANSFER_PLAYER_OFFLINE", player.UserIDString), player);
return;
}
if (!IsValidTransfer(player, targetPlayer, amount)) return;
ExecuteTransfer(player, targetPlayer, amount);
}
// private void ChatCommandBalance(BasePlayer player)
// {
// if (!player) return;
// Int32 balancePlayer = GetBalancePlayer(player);
// SendChat(GetLang("CHAT_ALERT_BALANCE", player.UserIDString, balancePlayer), player);
// }
Boolean API_MONEY_TYPE() => config.generalSetting.typeCoins == TypeCoins.Virtual;
private void ExchangedProcess(BasePlayer player, (Int32 exchangeCoins, Int32 storeMoney) exchangeDetail) {
PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
if (pInfo == null) return;
if (IsLimiteBalance(pInfo)) return;
exchangerDataPlayer[player] = 1;
StoreAddedBalance(player, exchangeDetail);
}
private enum TypeCoins {
Virtual, Physics
}
private Boolean IsLimiteBalance(BasePlayer player) {
Int32 limitExchange = config.exchangerSetting.limitStoreMoney;
if (limitExchange <= 0) return false;
PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
if (pInfo == null) return false;
return pInfo.LimitBalance >= limitExchange;
}
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 void LogAction(Object playerOrUserID, Int32 amount, TypeLog log, Boolean addOrRemove) {
if (!config.generalSetting.useLogger) return;
String logArrow = arrowLogRemoved;
String logAction = actionLogRemoved;
if (addOrRemove) {
logArrow = arrowLogReceived;
logAction = actionLogReceived;
}
String playerInfo = playerOrUserID switch {
BasePlayer player => $"{player.displayName} ({player.UserIDString})", String userID => $"OfflinePlayer ({userID})", _ => "Unknown"
}
;
String logInfo = $"{logArrow} [{log}] {playerInfo} {logAction} {amount}";
LogToFile("IQEconomic", logInfo, _, true, true);
}
// [ConsoleCommand("UI_Economic_Command")]
// private void UI_Economic_Command(ConsoleSystem.Arg arg)
// {
// BasePlayer player = arg.Player();
// if (!player) return;
// if (!arg.HasArgs()) return;
//
// String type = arg.GetString(0);
//
// Int32 balancePlayer = GetBalancePlayer(player);
//
// switch (type)
// {
// case "hide.controller":
// {
// PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
// if (pInfo == null) return;
//
// pInfo.IsHide = !pInfo.IsHide;
// DrawUI_UpdateHider(player, pInfo.IsHide);
// break;
// }
//
// case "exchanger.multiplier":
// {
// if (!isUsedExchanger) return;
// String multiplierGet = arg.GetString(1);
// if (!Int32.TryParse(multiplierGet, out Int32 multiplier)) return;
//
// PlayerInfo pInfo = PlayerInfo.Get(player.UserIDString);
// if (pInfo == null) return;
//
// Int32 limitExchanged = GetLimiteExchanged(pInfo);
//
// UpdateMultiplier(player, balancePlayer, limitExchanged, multiplier);
// break;
// }
//
// case "exchanger.run.all":
// {
// if (!isUsedExchanger) return;
// (Int32 exchangeCoins, Int32 storeMoney) exchangeDetail = actualyCourse.GetFullExchangeDetails(balancePlayer);
// ExchangedProcess(player, exchangeDetail);
// break;
// }
//
// case "exchanger.run.one":
// {
// if (!isUsedExchanger) return;
// Int32 multiplier = exchangerDataPlayer.GetValueOrDefault(player, 1);
// (Int32 exchangeCoins, Int32 storeMoney) exchangeDetail = actualyCourse.GetExchangeDetails(balancePlayer, multiplier);
// ExchangedProcess(player, exchangeDetail);
// break;
// }
//
// case "exchanger.close":
// {
// if (!isUsedExchanger) return;
// if (exchangerDataPlayer.ContainsKey(player))
// exchangerDataPlayer.Remove(player);
//
// DestroyUI(player, InterfaceBuilder.UI_PANEL_STATIC_EXCHANGER_MENU);
// break;
// }
// }
// }
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);
return;
}
if (!IsOnlyTakeEarning(attacker, earningNpc)) return;
AddBalance(attacker, earningNpc.countMoney, TypeLog.Action, earningNpc.useChatAlert ? "CHAT_ALERT_EARNING_KILLED_NPC" : default);
}
private Dictionary<UInt64, BasePlayer> heliKilleds = new ();
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 static Double CurrentTime => DateTime.UtcNow.Subtract(epoch).TotalSeconds;
private static IQEconomic _;
public CourseInfo courseData = new CourseInfo();
private void RemoveBalance(BasePlayer player, PlayerInfo pInfo, Int32 amount, TypeLog typeLog) {
if (!player) return;
if (config.generalSetting.typeCoins == TypeCoins.Physics) {
Int32 balancePlayer = GetBalancePlayer(player);
if (!DoesHaveEnoughBalance(balancePlayer)) {
RemovePhysicMoney(player, balancePlayer);
LogAction(player, balancePlayer, typeLog, false);
}
else {
RemovePhysicMoney(player, amount);
LogAction(player, amount, typeLog, false);
}
UpdateExchangedUI(player, balancePlayer, GetLimiteExchanged(pInfo));
Interface.Oxide.CallHook("OnRemovedBalance", player.userID.Get(), amount, player, pInfo.Balance);
return;
}
if (!DoesHaveEnoughBalance(pInfo.Balance)) {
pInfo.Balance = 0;
LogAction(player, pInfo.Balance, typeLog, false);
}
else {
pInfo.Balance -= amount;
LogAction(player, amount, typeLog, false);
}
DrawUI_UpdateTitleBalance(player, pInfo);
UpdateExchangedUI(player, pInfo.Balance, GetLimiteExchanged(pInfo));
Interface.Oxide.CallHook("OnRemovedBalance", player.userID.Get(), amount, player, pInfo.Balance);
}
private void DrawUI_StaticExchangerPanel(BasePlayer player) {
if (_interface == null) return;
DestroyUI(player, InterfaceBuilder.UI_PANEL_STATIC_EXCHANGER);
List<String> cashedStaticPanel = GetOrSetCacheUI("UI_Exchanger_Panel_Static");
if (cashedStaticPanel != null) {
foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
}
else {
String Interface = InterfaceBuilder.GetInterface("UI_Exchanger_Panel_Static");
if (Interface == null) return;
List<String> newUI = GetOrSetCacheUI("UI_Exchanger_Panel_Static", Interface);
cashedStaticPanel = newUI;
foreach (String uiCached in cashedStaticPanel) AddUI(player, uiCached);
}
}
Boolean API_IS_USER(String userID) {
PlayerInfo playerData = PlayerInfo.Get(userID);
return playerData != null;
}
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 ImageUI _imageUI;
private void TrackedPlayers() {
Configuration.EarningCoins.PresetEarning timerEarning = config.earningCoins.timeTracked.timeTrackerPreset;
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;
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);
}
void API_REMOVE_BALANCE(UInt64 userID, Int32 balance) {
String idString = userID.ToString();
API_REMOVE_BALANCE(idString, balance);
}
private Timer timerUpdateCourse = null;
private void OnNewSave(String filename) => CleanerDataFiles();
private void Init() {
_ = this;
isUsedSQL = config.generalSetting.mySQLConnectionSettings.IsUsedMySQL();
isUsedUI = config.generalSetting.typeCoins == TypeCoins.Virtual && config.generalSetting.interfaceSetting.useUI;
isUsedExchanger = !String.IsNullOrWhiteSpace(config.commandExchanger) && config.exchangerSetting.useExchanger;
isUsedStores = config.exchangerSetting.storeSetting.useGameStores || config.exchangerSetting.storeSetting.useMoscovOvh;
if(isUsedExchanger) ReadData();
HookController();
}
private void HookController() {
Configuration.EarningCoins earningCoins = config.earningCoins;
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 {
if (!config.generalSetting.physicsItem.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(OnEntityKill));
}
}
private void DrawUI_UpdateExchangeOne_Menu(BasePlayer player, Int32 balancePlayer, Int32 limiteExchanged, Int32 multiplier = 1) {
if (_interface == null) return;
String Interface = InterfaceBuilder.GetInterface("UI_Exchanger_Update_OneExchange_Button");
if (Interface == null) return;
Interface = Interface.Replace("%ONE_COURSE_TITLE%", actualyCourse.GetMultipliedCourseString(player, balancePlayer, multiplier, limiteExchanged));
AddUI(player, Interface);
}
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
private void ImportPlayerSQL(String userID, Int32 balance, Int32 limitBalance, Int32 time, Double dateTime, Boolean isHide, Boolean isMigrate = false) {
if (sqlConnection == null) return;
Configuration.GeneralSetting.MySQLConnection sqlInfo = config.generalSetting.mySQLConnectionSettings;
String hideString = isHide.ToString();
String sqlQuery = $"UPDATE {sqlInfo.dbTableName} SET `steamid` = @0, `balance` = @1,`limit_balance` = @2,`time` = @3,`last_connection` = @4, `is_hide` = @5 WHERE `steamid` = @0";
Sql updateCommand = Sql.Builder.Append(sqlQuery, userID, balance, limitBalance, time, dateTime, hideString);
sqlLibrary.Update(updateCommand, sqlConnection, rowsAffected => {
if (rowsAffected > 0) return;
String Query = String.Format(SQL_Query_InsertUser(), userID, balance, limitBalance, time, dateTime, hideString);
Sql sql = Sql.Builder.Append(Query);
sqlLibrary.Insert(sql, sqlConnection, rowsAffecteds => {
if (!isMigrate) Puts(LanguageEn? $"" : $"Данные игрока {userID} были внесены в базу-данных");
}
);
}
);
}
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);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
private const Boolean LanguageEn = false;
private static Configuration config = new Configuration();
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 {
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));
}
}
private void WriteData() => Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQEconomic/Exchanger/UpdateCourseTime", courseData);
private class InterfaceBuilder {
public static InterfaceBuilder Instance;
public const String UI_PANEL_STATIC_BALANCE = "UI_PANEL_STATIC_BALANCE";
public const String UI_PANEL_STATIC_EXCHANGER = "UI_PANEL_STATIC_EXCHANGER";
public const String UI_PANEL_STATIC_EXCHANGER_MENU = "UI_PANEL_STATIC_EXCHANGER_MENU";
public const String UI_PANEL_STATIC_HIDER = "UI_PANEL_STATIC_HIDER";
public Dictionary<String, String> Interfaces;
private const String FontMaterial = "assets/content/ui/namefontmaterial.mat";
private readonly String colorPanel = config.generalSetting.interfaceSetting.colorsUI.colorPanel;
private readonly String colorText = config.generalSetting.interfaceSetting.colorsUI.colorText;
private readonly String OffsetMinExchangerDefault = config.generalSetting.interfaceSetting.positionUI.firstButton.offsetMin;
private readonly String OffsetMaxExchangerDefault = config.generalSetting.interfaceSetting.positionUI.firstButton.offsetMax;
private readonly String OffsetMinHiderDefault = config.generalSetting.interfaceSetting.positionUI.twoButton.offsetMin;
private readonly String OffsetMaxHiderDefault = config.generalSetting.interfaceSetting.positionUI.twoButton.offsetMax;
private readonly String AnchorMinExchanger = config.generalSetting.interfaceSetting.positionUI.firstButton.anchorMin;
private readonly String AnchorMaxExchanger = config.generalSetting.interfaceSetting.positionUI.firstButton.anchorMax;
private readonly String AnchorMinHider = config.generalSetting.interfaceSetting.positionUI.twoButton.anchorMin;
private readonly String AnchorMaxHider = config.generalSetting.interfaceSetting.positionUI.twoButton.anchorMax;
private String anchorMinExchanger = String.Empty;
private String anchorMaxExchanger = String.Empty;
private String anchorMinHider = String.Empty;
private String anchorMaxHider = String.Empty;
private String offsetMinExchanger = String.Empty;
private String offsetMaxExchanger = String.Empty;
private String offsetMinHider = String.Empty;
private String offsetMaxHider = String.Empty;
public InterfaceBuilder() {
Instance = this;
Interfaces = new Dictionary<String, String>();
Configuration.GeneralSetting.InterfaceSetting.PresetUI presetUI = config.generalSetting.interfaceSetting.presetUI;
SetOffsets(presetUI.useTransferButton && config.exchangerSetting.useExchanger, presetUI.useHideUI);
// Building_StaticMenuBalance();
// Building_StaticIconBalance();
//
// Building_StaticTitleBalance();
// Building_UpdateTitleBalance();
//
// Building_StaticHider("UI_Hide_Panel_Static", "ICON_HIDE");
// Building_UpdateHider("UI_Hide_Panel_Update", "ICON_HIDE");
//
// Building_StaticHider("UI_UnHide_Panel_Static", "ICON_UNHIDE");
// Building_UpdateHider("UI_UnHide_Panel_Update", "ICON_UNHIDE");
//
// Building_StaticButtonExchanger();
// Building_StaticMenuExchanger();
// Building_UpdateBalance();
// Building_UpdateLimite();
// Building_UpdateCourseCoin();
// Building_UpdateCourseStoreMoney();
// Building_UpdateCourseTime();
// Building_UpdateButtonExchangeAll();
// Building_UpdateButtonExchangeOne();
}
private void SetOffsets(Boolean useExchangerButton, Boolean useHideUI) {
if (useExchangerButton && useHideUI) {
anchorMinExchanger = AnchorMinExchanger;
anchorMaxExchanger = AnchorMaxExchanger;
anchorMinHider = AnchorMinHider;
anchorMaxHider = AnchorMaxHider;
offsetMinExchanger = OffsetMinExchangerDefault;
offsetMaxExchanger = OffsetMaxExchangerDefault;
offsetMinHider = OffsetMinHiderDefault;
offsetMaxHider = OffsetMaxHiderDefault;
}
else if (useExchangerButton || useHideUI) {
anchorMinExchanger = AnchorMinExchanger;
anchorMaxExchanger = AnchorMaxExchanger;
anchorMinHider = anchorMinExchanger;
anchorMaxHider = anchorMaxExchanger;
offsetMinExchanger = OffsetMinExchangerDefault;
offsetMaxExchanger = OffsetMaxExchangerDefault;
offsetMinHider = offsetMinExchanger;
offsetMaxHider = offsetMaxExchanger;
}
}
public static void AddInterface(String name, String json) {
if (!Instance.Interfaces.TryAdd(name, json)) {
_.PrintError($"Error! Tried to add existing cui elements! -> {name}");
return;
}
}
public static String GetInterface(String name) {
if (Instance.Interfaces.TryGetValue(name, out String json) == false) {
_.PrintWarning($"Warning! UI elements not found by name! -> {name}");
}
return json;
}
public static void DestroyAll() {
for (Int32 i = 0; i < BasePlayer.activePlayerList.Count; i++) {
BasePlayer player = BasePlayer.activePlayerList[i];
DestroyPlayerUI(player);
}
}
public static void DestroyPlayerUI(BasePlayer player) {
DestroyUI(player, UI_PANEL_STATIC_BALANCE);
DestroyUI(player, UI_PANEL_STATIC_HIDER);
DestroyUI(player, UI_PANEL_STATIC_EXCHANGER);
DestroyUI(player, UI_PANEL_STATIC_EXCHANGER_MENU);
}
private void Building_StaticMenuBalance() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = UI_PANEL_STATIC_BALANCE, Parent = "Overlay", DestroyUi = UI_PANEL_STATIC_BALANCE, Components = {
new CuiRawImageComponent {
Color = colorPanel, Png = _._imageUI.GetImage("PANEL_BALANCE"), Material = FontMaterial
}
, new CuiRectTransformComponent {
AnchorMin = config.generalSetting.interfaceSetting.positionUI.balancePanel.anchorMin, AnchorMax = config.generalSetting.interfaceSetting.positionUI.balancePanel.anchorMax, OffsetMin = config.generalSetting.interfaceSetting.positionUI.balancePanel.offsetMin, OffsetMax = config.generalSetting.interfaceSetting.positionUI.balancePanel.offsetMax
}
}
}
);
container.Add(new CuiElement {
Name = "MINI_PANEL_ICON_BALANCE", Parent = UI_PANEL_STATIC_BALANCE, DestroyUi = "MINI_PANEL_ICON_BALANCE", Components = {
new CuiImageComponent {
Color = colorPanel, Material = FontMaterial
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "53.333 -13", OffsetMax = "79.333 13"
}
}
}
);
container.Add(new CuiElement {
Name = "ICON_BALANCE", Parent = "MINI_PANEL_ICON_BALANCE", DestroyUi = "ICON_BALANCE", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = _._imageUI.GetImage("ICON_BALANCE")
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
}
}
);
AddInterface("UI_Balance_Panel_Static", container.ToJson());
}
private void Building_StaticIconBalance() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = UI_PANEL_STATIC_BALANCE, Parent = "Overlay", DestroyUi = UI_PANEL_STATIC_BALANCE, Components = {
new CuiImageComponent {
Color = colorPanel, Material = FontMaterial
}
, new CuiRectTransformComponent {
AnchorMin = config.generalSetting.interfaceSetting.positionUI.balanceIconHided.anchorMin, AnchorMax = config.generalSetting.interfaceSetting.positionUI.balanceIconHided.anchorMax, OffsetMin = config.generalSetting.interfaceSetting.positionUI.balanceIconHided.offsetMin, OffsetMax = config.generalSetting.interfaceSetting.positionUI.balanceIconHided.offsetMax
}
}
}
);
container.Add(new CuiElement {
Name = "ICON_BALANCE", Parent = UI_PANEL_STATIC_BALANCE, DestroyUi = "ICON_BALANCE", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = _._imageUI.GetImage("ICON_BALANCE")
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
}
}
);
AddInterface("UI_Balance_Panel_Icon_Static", container.ToJson());
}
private void Building_StaticTitleBalance() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = "BALANCE_TITLE", Parent = UI_PANEL_STATIC_BALANCE, DestroyUi = "BALANCE_TITLE", Components = {
new CuiTextComponent {
Text = "%BALANCE_TITLE%", Font = "robotocondensed-bold.ttf", FontSize = 12, Align = TextAnchor.MiddleLeft, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "6.794 0.333", OffsetMax = "-1.807 -0.333"
}
}
}
);
AddInterface("UI_Balance_Title_Static", container.ToJson());
}
private void Building_UpdateTitleBalance() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = "BALANCE_TITLE", Parent = UI_PANEL_STATIC_BALANCE, Update = true, Components = {
new CuiTextComponent {
Text = "%BALANCE_TITLE%"
}
,
}
}
);
AddInterface("UI_Balance_Title_Update", container.ToJson());
}
private void Building_StaticButtonExchanger() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = UI_PANEL_STATIC_EXCHANGER, Parent = "Overlay", DestroyUi = UI_PANEL_STATIC_EXCHANGER, Components = {
new CuiImageComponent {
Color = colorPanel, Material = FontMaterial
}
, new CuiRectTransformComponent {
AnchorMin = anchorMinExchanger, AnchorMax = anchorMaxExchanger, OffsetMin = offsetMinExchanger, OffsetMax = offsetMaxExchanger
}
}
}
);
container.Add(new CuiElement {
Name = "ICON_EXCHANGER", Parent = UI_PANEL_STATIC_EXCHANGER, DestroyUi = "ICON_EXCHANGER", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = _._imageUI.GetImage("ICON_EXCHANGER")
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
}
}
);
container.Add(new CuiButton {
Button = {
Color = "0 0 0 0", Command = config.commandExchanger
}
, Text = {
Text = "", Font = "robotocondensed-bold.ttf", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
}
, "ICON_EXCHANGER", "EXCHANGER_BUTTON", "EXCHANGER_BUTTON");
AddInterface("UI_Exchanger_Panel_Static", container.ToJson());
}
private void Building_StaticMenuExchanger() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = UI_PANEL_STATIC_EXCHANGER_MENU, Parent = "Overlay", DestroyUi = UI_PANEL_STATIC_EXCHANGER_MENU, Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = _._imageUI.GetImage("PANEL_EXCAHNGER")
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-204 79.067", OffsetMax = "189.333 128.4"
}
}
}
);
container.Add(new CuiElement {
Name = "BALANCE_EXCHANGER", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "BALANCE_EXCHANGER", Components = {
new CuiTextComponent {
Text = "%EXCHANGER_ACTUALY_BALANCE%", Font = "robotocondensed-bold.ttf", FontSize = 8, Align = TextAnchor.UpperLeft, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "3.687 -1.053", OffsetMax = "230.98 11.453"
}
}
}
);
container.Add(new CuiElement {
Name = "LIMITE_LABEL_EXCHANGER", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "LIMITE_LABEL_EXCHANGER", Components = {
new CuiTextComponent {
Text = "%EXCHANGER_ACTUALY_LIMITE%", Font = "robotocondensed-bold.ttf", FontSize = 8, Align = TextAnchor.UpperLeft, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "3.687 7.674", OffsetMax = "230.98 20.18"
}
}
}
);
container.Add(new CuiElement {
Name = "STORE_LABEL", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "STORE_LABEL", Components = {
new CuiTextComponent {
Text = "%EXCHANGER_STORE_INFO%", Font = "robotocondensed-regular.ttf", FontSize = 8, Align = TextAnchor.UpperLeft, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "3.687 -9.786", OffsetMax = "359.841 2.72"
}
}
}
);
container.Add(new CuiElement {
Name = "COURSE_UPDATE_TIME", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "COURSE_UPDATE_TIME", Components = {
new CuiTextComponent {
Text = "%LAST_TIME_UPDATE_COURSE%", Font = "robotocondensed-bold.ttf", FontSize = 10, Align = TextAnchor.MiddleRight, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-50.294 -18.708", OffsetMax = "-13.274 -5.958"
}
}
}
);
container.Add(new CuiElement {
Name = "COURSE_COIN", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "COURSE_COIN", Components = {
new CuiTextComponent {
Text = "%EXCHANGER_COURSE_COIN%", Font = "robotocondensed-bold.ttf", FontSize = 12, Align = TextAnchor.MiddleRight, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-52.26 -0.32", OffsetMax = "-5.918 17.253"
}
}
}
);
container.Add(new CuiElement {
Name = "COURSE_STORE_MONEY", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "COURSE_STORE_MONEY", Components = {
new CuiTextComponent {
Text = "%EXCHANGER_COURSE_STORE_MONEY%", Font = "robotocondensed-bold.ttf", FontSize = 10, Align = TextAnchor.MiddleRight, Color = colorText
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-52.26 -11.12", OffsetMax = "-5.919 6.453"
}
}
}
);
container.Add(new CuiElement {
Name = "ALL_EXCHANGE_COURSE_LABEL", Parent = UI_PANEL_STATIC_EXCHANGER_MENU, DestroyUi = "ALL_EXCHANGE_COURSE_LABEL", Components = {
new CuiTextComponent {
Text = "%FULL_COURSE_TITLE%", Font = "robotocondensed-bold.ttf", FontSize = 10, Align = TextAnchor.MiddleCenter, Color = colorText
// ... [Code preview truncated due to length. Full source in attached file] ...