C#:
// #define TESTING
#if TESTING
using System.Diagnostics;
#endif
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.BankSystemExtensionMethods;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;
#if CARBON
using Carbon.Base;
using Carbon.Modules;
#endif
namespace Oxide.Plugins
{
[Info("Bank System", "Mevent", "1.3.18")]
public class BankSystem : RustPlugin
{
#region Fields
[PluginReference] private Plugin
ImageLibrary = null,
Notify = null,
UINotify = null,
Economics = null,
LangAPI = null;
private const string Layer = "UI.BankSystem";
private static BankSystem _instance;
private const bool LangRu = false;
private readonly Dictionary<ulong, ATMData> _atmByPlayer = new Dictionary<ulong, ATMData>();
private readonly List<VendingMachine> _vendingMachines = new List<VendingMachine>();
private const string VendingMachinePrefab =
"assets/prefabs/deployable/vendingmachine/vendingmachine.deployed.prefab";
private enum Transaction
{
Deposit,
Withdrawal,
Transfer
}
#if CARBON
private ImageDatabaseModule imageDatabase;
#endif
private bool _enabledImageLibrary;
#endregion
#region Config
private static Configuration _config;
private class Configuration
{
[JsonProperty(PropertyName = LangRu ? "Работать с LangAPI?" : "Work with LangAPI?")]
public bool UseLangAPI = true;
[JsonProperty(PropertyName = LangRu ? "Работать с Notify?" : "Work with Notify?")]
public bool UseNotify = true;
[JsonProperty(PropertyName = LangRu ? "Включить режим офлайн изображений?" : "Enable Offline Image Mode")]
public bool EnableOfflineImageMode = false;
[JsonProperty(PropertyName = LangRu ? "Команды" : "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] Commands = {"bank"};
[JsonProperty(PropertyName = LangRu ? "Разрешение (например: banksystemru.use)" : "Permission (example: banksystem.use)")]
public string Permission = string.Empty;
[JsonProperty(PropertyName = LangRu ? "Стартовый баланс" : "Starting balance")]
public int StartingBalance = 100;
[JsonProperty(PropertyName = LangRu ? "Изображение карты" : "Card Image")]
public string CardImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/card.png";
[JsonProperty(PropertyName = LangRu ? "Изображение пополнения" : "Transit Image")]
public string DepositImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/deposit.png";
[JsonProperty(PropertyName = LangRu ? "Изображение снятия" : "Withdraw Image")]
public string WithdrawImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/withdraw.png";
[JsonProperty(PropertyName = LangRu ? "Изображение перевода" : "Transfer Image")]
public string TransferImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/transfer.png";
[JsonProperty(PropertyName = LangRu ? "Изображение выхода" : "Exit Image")]
public string ExitImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/exit.png";
[JsonProperty(PropertyName = LangRu ? "Отключить кнопку закрытия в заголовке ATM" : "Disable the close button in the ATM header")]
public bool AtmDisableCloser = false;
[JsonProperty(PropertyName = LangRu ? "Настройки валюты" : "Currency Settings")]
public CurrencySettings Currency = new CurrencySettings
{
ControlSplit = true,
DisplayName = "RUSTNote",
ShortName = "sticks",
Skin = 2536195910
};
[JsonProperty(PropertyName = LangRu ? "Показывать всех игроков в Transfer (false - только онлайн)" : "Show all players in Transfer (false - online only)")]
public bool TransferShowAllPlayers = false;
[JsonProperty(PropertyName = LangRu ? "Автоматическое создание карты" : "Card auto-creation")]
public bool CardAutoCreation = false;
[JsonProperty(PropertyName = LangRu ? "Использовать срок действия карты?" : "Use card expiration date?")]
public bool UseCardExpiry = true;
[JsonProperty(PropertyName = LangRu ? "Срок действия карты (в днях)" : "Card expiry date (in days)")]
public int CardExpiryDays = 7;
[JsonProperty(PropertyName = LangRu ? "Настройки ATM" : "ATM Settings")]
public ATMSettings Atm = new ATMSettings
{
MinWithdrawal = 1,
MinDeposit = 1,
EnableDepositFee = true,
MinDepositFee = 0,
MaxDepositFee = 10,
StepDepositFee = 0.1f,
MinWithdrawalFee = 0,
MaxWithdrawalFee = 10,
EnableBreakage = true,
StepWithdrawalFee = 0.1f,
DisplayName = "ATM",
Skin = 2551771822,
Repair = new RepairSettings
{
Items = new List<RepairItemConf>
{
new RepairItemConf
{
ShortName = "scrap",
Amount = 2,
Skin = 0,
Title = string.Empty
},
new RepairItemConf
{
ShortName = "metalpipe",
Amount = 1,
Skin = 0,
Title = string.Empty
},
new RepairItemConf
{
ShortName = "metal.fragments",
Amount = 15,
Skin = 0,
Title = string.Empty
}
}
},
DefaultDepositFee = 1,
EnableWithdrawalFee = true,
DefaultWithdrawalFee = 1,
DefaultBreakPercent = 1,
BreakPercent = new Dictionary<string, float>
{
["banksystem.vip"] = 0.7f,
["banksystem.premium"] = 0.5f
},
Spawn = new SpawnSettings
{
ConfAddons = new ATMConf
{
DisplayName = "ATM",
DepositFee = 0,
WithdrawFee = 0
},
Monuments = new Dictionary<string, ATMPosition>
{
["compound"] = new ATMPosition
{
Enabled = true,
DisplayName = "ATM",
Position = new Vector3(-3.5f,
1.15f,
2.7f),
Rotation = -90,
DepositFee = 0,
WithdrawFee = 0
},
["bandit"] = new ATMPosition
{
Enabled = true,
DisplayName = "ATM",
Position = new Vector3(34.2f,
2.35f,
-24.7f),
Rotation = 135,
DepositFee = 0,
WithdrawFee = 0
}
}
},
ShopName = "ATM #{id}",
Commands = new[]
{
"secret.open.atm"
},
PermissionToOpenATMviaCommand = "banksystem.openatm",
NotifyPlayerWhenNoPermissionInCommandATM = false
};
[JsonProperty(PropertyName = LangRu ? "Настройки отслеживания" : "Tracking Settings")]
public TrackingSettings Tracking = new TrackingSettings
{
InHand = false,
CostTable = new Dictionary<string, float>
{
["sulfur.ore"] = 5f,
["metal.ore"] = 5f,
["hq.metal.ore"] = 5f,
["stone.ore"] = 5f,
["crate_elite"] = 10f,
["crate_normal"] = 7f,
["crate_normal_2"] = 4
},
CollectibleCostTable = new Dictionary<string, float>
{
["sulfur.ore"] = 0.5f,
["metal.ore"] = 0.5f,
["hq.metal.ore"] = 0.5f,
["stones"] = 0.5f
}
};
[JsonProperty(PropertyName = LangRu ? "Настройки очистки" : "Wipe Settings")]
public WipeSettings Wipe = new WipeSettings
{
Players = false,
Logs = true,
ATMs = true
};
[JsonProperty(PropertyName = LangRu ? "Настройки NPC" : "NPC Settings")]
public NPCSettings NPC = new NPCSettings
{
NPCs = new List<string>
{
"1234567",
"7654321",
"4644687478"
}
};
[JsonProperty(PropertyName = LangRu ? "Настройки экономики" : "Economy Settings")]
public EconomySettings Economy = new EconomySettings
{
Self = true,
AddHook = "Deposit",
BalanceHook = "Balance",
RemoveHook = "Withdraw",
PluginName = "Economics"
};
[JsonProperty(PropertyName = LangRu ? "Настройки дропа" : "Drop Settings", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<DropInfo> Drop = new List<DropInfo>
{
new DropInfo
{
Enabled = true,
PrefabName = "assets/bundled/prefabs/radtown/crate_normal.prefab",
DropChance = 50,
MinAmount = 2,
MaxAmount = 5
},
new DropInfo
{
Enabled = true,
PrefabName = "assets/bundled/prefabs/radtown/loot_barrel_2.prefab",
DropChance = 5,
MinAmount = 2,
MaxAmount = 5
},
new DropInfo
{
Enabled = true,
PrefabName = "assets/bundled/prefabs/radtown/loot_barrel_1.prefab",
DropChance = 5,
MinAmount = 2,
MaxAmount = 5
}
};
[JsonProperty(PropertyName = LangRu ? "Цвета" : "Colors")]
public Colors Colors = new Colors
{
Color1 = new IColor("#0E0E10"),
Color2 = new IColor("#161617"),
Color3 = new IColor("#4B68FF"),
Color4 = new IColor("#74884A"),
Color5 = new IColor("#FF6060"),
Color6 = new IColor("#C4C4C4"),
Color7 = new IColor("#CD4632"),
Color8 = new IColor("#595651"),
Color9 = new IColor("#4B68FF", 50),
Color10 = new IColor("#4B68FF", 33),
Color11 = new IColor("#FFFFFF", 20),
Color12 = new IColor("#C4C4C4", 20),
Color13 = new IColor("#FFFFFF"),
Color14 = new IColor("#FFFFFF", 50),
Color15 = new IColor("#FFFFFF", 40),
Color16 = new IColor("#FFFFFF", 70),
Color17 = new IColor("#FFFFFF", 10),
Color18 = new IColor("#FFFFFF", 95),
Color19 = new IColor("#FFFFFF", 30),
};
[JsonProperty(PropertyName = LangRu ? "Настройки UI" : "UI Settings")]
public UserInterface UI = new UserInterface
{
BankWidth = 900f,
BankHeight = 595f,
BankHeaderHeight = 70f,
BankHeaderWidth = 850f,
BankHeaderUpIndent = 65f,
ShowTransactionsHistory = true,
THFieldWidth = 190f,
THButtonMargin = 5f,
THButtonSize = 20f,
ShowGatherHistory = true,
GHFieldWidth = 190f,
GHButtonMargin = 5f,
GHButtonSize = 20f,
ShowCard = true,
CardWidth = 245f,
CardLeftIndent = 25f,
ShowTransfers = true,
Transfers = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "25 -345",
OffsetMax = "175 -325",
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-bold.ttf",
FontSize = 16,
Color = new IColor("#FFFFFF")
},
RecentTransfersTitle = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "25 -360",
OffsetMax = "175 -345",
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = new IColor("#FFFFFF", 50)
},
NoTransactions = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "25 -490",
OffsetMax = "405 -360",
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 14,
Color = new IColor("#FFFFFF", 10)
},
TransferCard = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "25 -515",
OffsetMax = "175 -500",
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = new IColor("#FFFFFF", 50)
},
TransferCardNumber = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "25 -550",
OffsetMax = "175 -520",
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = new IColor("#FFFFFF")
},
TransferCardAmount = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "185 -550",
OffsetMax = "335 -520",
FontSize = 10,
Font = "robotocondensed-regular.ttf",
Align = TextAnchor.MiddleLeft,
Color = new IColor("#FFFFFF")
},
TransferCardButton = new LabelSettings
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "340 -550",
OffsetMax = "400 -520",
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 11,
Color = new IColor("#FFFFFF")
}
};
[JsonProperty(PropertyName = LangRu ? "Настройки логирования" : "Log Settings")]
public LogInfo Logs = new LogInfo
{
CollectGatherLogs = true,
CollectTransfersLogs = true
};
public VersionNumber Version;
}
private class LogInfo
{
[JsonProperty(PropertyName = LangRu ? "Собирать логи сбора?" : "Collect Gather logs?")]
public bool CollectGatherLogs;
[JsonProperty(PropertyName = LangRu ? "Собирать логи переводов?" : "Collect Transfers logs?")]
public bool CollectTransfersLogs;
}
private class UserInterface
{
[JsonProperty(PropertyName = LangRu ? "Банк | Ширина" : "Bank | Width")]
public float BankWidth;
[JsonProperty(PropertyName = LangRu ? "Банк | Высота" : "Bank | Height")]
public float BankHeight;
[JsonProperty(PropertyName = LangRu ? "Банк | Ширина заголовка" : "Bank Header | Width")]
public float BankHeaderWidth;
[JsonProperty(PropertyName = LangRu ? "Банк | Высота заголовка" : "Bank Header | Height")]
public float BankHeaderHeight;
[JsonProperty(PropertyName = LangRu ? "Банк | Отступ сверху заголовка" : "Bank Header | Up Indent")]
public float BankHeaderUpIndent;
[JsonProperty(PropertyName = LangRu ? "Показывать историю транзакций?" : "Show Transactions history?")]
public bool ShowTransactionsHistory;
[JsonProperty(PropertyName = LangRu ? "История транзакций | Ширина поля" : "Transactions history | Field width")]
public float THFieldWidth;
[JsonProperty(PropertyName = LangRu ? "История транзакций | Отступ кнопки страницы" : "Transactions history | Page button margin")]
public float THButtonMargin;
[JsonProperty(PropertyName = LangRu ? "История транзакций | Размер кнопки страницы" : "Transactions history | Page button size")]
public float THButtonSize;
[JsonProperty(PropertyName = LangRu ? "Показывать историю сбора?" : "Show Gather history?")]
public bool ShowGatherHistory;
[JsonProperty(PropertyName = LangRu ? "История сбора | Ширина поля" : "Gather history | Field width")]
public float GHFieldWidth;
[JsonProperty(PropertyName = LangRu ? "История сбора | Отступ кнопки страницы" : "Gather history | Page button margin")]
public float GHButtonMargin;
[JsonProperty(PropertyName = LangRu ? "История сбора | Размер кнопки страницы" : "Gather history | Page button size")]
public float GHButtonSize;
[JsonProperty(PropertyName = LangRu ? "Показывать карту?" : "Show card?")]
public bool ShowCard;
[JsonProperty(PropertyName = LangRu ? "Карта | Ширина" : "Card | Width")]
public float CardWidth;
[JsonProperty(PropertyName = LangRu ? "Карта | Отступ слева" : "Card | Left indent")]
public float CardLeftIndent;
[JsonProperty(PropertyName = LangRu ? "Показывать переводы?" : "Show Transfers?")]
public bool ShowTransfers;
[JsonProperty(PropertyName = LangRu ? "Заголовок: Переводы" : "Title: Transfers")]
public LabelSettings Transfers;
[JsonProperty(PropertyName = LangRu ? "Заголовок: Последние переводы" : "Title: Recent Transfers")]
public LabelSettings RecentTransfersTitle;
[JsonProperty(PropertyName = LangRu ? "Заголовок: У игрока нет транзакций" : "Title: Player has no transactions Title")]
public LabelSettings NoTransactions;
[JsonProperty(PropertyName = LangRu ? "Заголовок: Перевод по карте" : "Title: Transfer by card")]
public LabelSettings TransferCard;
[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Номер карты" : "Transfer by card | Card number")]
public LabelSettings TransferCardNumber;
[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Сумма" : "Transfer by card | Amount")]
public LabelSettings TransferCardAmount;
[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Кнопка перевода" : "Transfer by card | Transfer button")]
public LabelSettings TransferCardButton;
}
private class LabelSettings : InterfacePosition
{
[JsonProperty(PropertyName = LangRu ? "Размер шрифта" : "FontSize")]
public int FontSize;
[JsonProperty(PropertyName = LangRu ? "Выравнивание" : "Align")] [JsonConverter(typeof(StringEnumConverter))]
public TextAnchor Align;
[JsonProperty(PropertyName = LangRu ? "Цвет" : "Color")] public IColor Color;
[JsonProperty(PropertyName = LangRu ? "Шрифт" : "Font")] public string Font;
}
private class InterfacePosition
{
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
}
private class IColor
{
[JsonProperty(PropertyName = LangRu ? "HEX" : "HEX")] public string Hex;
[JsonProperty(PropertyName = LangRu ? "Непрозрачность (0 - 100)" : "Opacity (0 - 100)")]
public float Alpha;
[JsonIgnore] private string _color;
[JsonIgnore]
public string Get
{
get
{
if (string.IsNullOrEmpty(_color))
_color = GetColor();
return _color;
}
}
private string GetColor()
{
if (string.IsNullOrEmpty(Hex)) Hex = "#FFFFFF";
var str = Hex.Trim('#');
if (str.Length != 6) throw new Exception(Hex);
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
public IColor()
{
}
public IColor(string hex, float alpha = 100)
{
Hex = hex;
Alpha = alpha;
}
}
private class Colors
{
[JsonProperty(PropertyName = LangRu ? "Первый цвет" : "First color")]
public IColor Color1;
[JsonProperty(PropertyName = LangRu ? "Второй цвет" : "Second color")]
public IColor Color2;
[JsonProperty(PropertyName = LangRu ? "Третий цвет" : "Third color")]
public IColor Color3;
[JsonProperty(PropertyName = LangRu ? "Четвертый цвет" : "Fourth color")]
public IColor Color4;
[JsonProperty(PropertyName = LangRu ? "Пятый цвет" : "Fifth color")]
public IColor Color5;
[JsonProperty(PropertyName = LangRu ? "Шестой цвет" : "Sixth color")]
public IColor Color6;
[JsonProperty(PropertyName = LangRu ? "Седьмой цвет" : "Seventh color")]
public IColor Color7;
[JsonProperty(PropertyName = LangRu ? "Восьмой цвет" : "Eighth color")]
public IColor Color8;
[JsonProperty(PropertyName = LangRu ? "Девятый цвет" : "Ninth color")]
public IColor Color9;
[JsonProperty(PropertyName = LangRu ? "Десятый цвет" : "Tenth color")]
public IColor Color10;
[JsonProperty(PropertyName = LangRu ? "Одиннадцатый цвет" : "Eleventh color")]
public IColor Color11;
[JsonProperty(PropertyName = LangRu ? "Двенадцатый цвет" : "Twelfth color")]
public IColor Color12;
[JsonProperty(PropertyName = LangRu ? "Тринадцатый цвет" : "Thirteenth color")]
public IColor Color13;
[JsonProperty(PropertyName = LangRu ? "Четырнадцатый цвет" : "Fourteenth color")]
public IColor Color14;
[JsonProperty(PropertyName = LangRu ? "Пятнадцатый цвет" : "Fifteenth color")]
public IColor Color15;
[JsonProperty(PropertyName = LangRu ? "Шестнадцатый цвет" : "Sixteenth color")]
public IColor Color16;
[JsonProperty(PropertyName = LangRu ? "Семнадцатый цвет" : "Seventeenth color")]
public IColor Color17;
[JsonProperty(PropertyName = LangRu ? "Восемнадцатый цвет" : "Eighteenth color")]
public IColor Color18;
[JsonProperty(PropertyName = LangRu ? "Девятнадцатый цвет" : "Nineteenth color")]
public IColor Color19;
}
public class DropInfo
{
[JsonProperty(PropertyName = LangRu ? "Включено" : "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = LangRu ? "Префаб" : "Prefab")]
public string PrefabName;
[JsonProperty(PropertyName = LangRu ? "Шанс" : "Chance")]
public int DropChance;
[JsonProperty(PropertyName = LangRu ? "Минимальное количество" : "Min Amount")]
public int MinAmount;
[JsonProperty(PropertyName = LangRu ? "Максимальное количество" : "Max Amount")]
public int MaxAmount;
}
private class EconomySettings
{
[JsonProperty(PropertyName = LangRu ? "Использовать собственную экономическую систему?" : "Use own economic system?")]
public bool Self;
[JsonProperty(PropertyName = LangRu ? "Название плагина" : "Plugin name")]
public string PluginName;
[JsonProperty(PropertyName = LangRu ? "Хук добавления баланса" : "Balance add hook")]
public string AddHook;
[JsonProperty(PropertyName = LangRu ? "Хук удаления баланса" : "Balance remove hook")]
public string RemoveHook;
[JsonProperty(PropertyName = LangRu ? "Хук показа баланса" : "Balance show hook")]
public string BalanceHook;
public double ShowBalance(BasePlayer player)
{
return ShowBalance(player.UserIDString);
}
public double ShowBalance(ulong player)
{
return ShowBalance(player.ToString());
}
private double ShowBalance(string player)
{
if (Self) return _instance.Balance(player);
var plugin = _instance?.plugins?.Find(PluginName);
if (plugin == null) return 0;
return Convert.ToDouble(Math.Floor(Convert.ToDouble(plugin.Call(BalanceHook, player)))
.ToString("0.00"));
}
public void AddBalance(BasePlayer player, int amount)
{
AddBalance(player.UserIDString, amount);
}
private void AddBalance(ulong player, int amount)
{
AddBalance(player.ToString(), amount);
}
private void AddBalance(string player, int amount)
{
if (Self)
{
_instance.Deposit(player, amount);
return;
}
var plugin = _instance?.plugins.Find(PluginName);
if (plugin == null) return;
switch (PluginName)
{
case "Economics":
plugin.Call(AddHook, player, (double) amount);
break;
default:
plugin.Call(AddHook, player, amount);
break;
}
}
public bool RemoveBalance(BasePlayer player, int amount)
{
return RemoveBalance(player.UserIDString, amount);
}
private bool RemoveBalance(ulong player, int amount)
{
return RemoveBalance(player.ToString(), amount);
}
private bool RemoveBalance(string player, int amount)
{
if (ShowBalance(player) < amount) return false;
if (Self) return _instance.Withdraw(player, amount);
var plugin = _instance?.plugins.Find(PluginName);
if (plugin == null) return false;
switch (PluginName)
{
case "Economics":
plugin.Call(RemoveHook, player, (double) amount);
break;
default:
plugin.Call(RemoveHook, player, amount);
break;
}
return true;
}
public bool Transfer(ulong member, ulong target, int amount)
{
if (!RemoveBalance(member, amount)) return false;
AddBalance(target, amount);
return true;
}
}
private class NPCSettings
{
[JsonProperty(PropertyName = LangRu ? "NPCs" : "NPCs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> NPCs = new List<string>();
}
private class WipeSettings
{
[JsonProperty(PropertyName = LangRu ? "Очистить игроков?" : "Wipe Players?")]
public bool Players;
[JsonProperty(PropertyName = LangRu ? "Очистить логи?" : "Wipe Logs?")]
public bool Logs;
[JsonProperty(PropertyName = LangRu ? "Очистить ATM?" : "Wipe ATMs?")]
public bool ATMs;
}
private class SpawnSettings
{
[JsonProperty(PropertyName = LangRu ? "Monuments" : "Monuments", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, ATMPosition> Monuments;
[JsonProperty(PropertyName = LangRu ? "Настройки для ATM из MonumentAddons" : "Settings for ATMs from MonumentAddons")]
public ATMConf ConfAddons;
}
private class ATMConf
{
[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = LangRu ? "Комиссия за пополнение" : "Deposit Fee")]
public float DepositFee;
[JsonProperty(PropertyName = LangRu ? "Комиссия за снятие" : "Withdraw Fee")]
public float WithdrawFee;
}
private class ATMPosition : ATMConf
{
[JsonProperty(PropertyName = LangRu ? "Включено" : "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = LangRu ? "Позиция" : "Position")]
public Vector3 Position;
[JsonProperty(PropertyName = LangRu ? "Поворот" : "Rotation")]
public float Rotation;
}
private class TrackingSettings
{
[JsonProperty(PropertyName = LangRu ? "Выдавать награду?" : "Handing out an award?")]
public bool InHand;
[JsonProperty(PropertyName = LangRu ? "Таблица стоимости (shortname - cost)" : "Cost Table (shortname - cost)",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> CostTable;
[JsonProperty(PropertyName = LangRu ? "Таблица стоимости предметов (shortname - cost)" : "Collectible Items Cost Table (shortname - cost)",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> CollectibleCostTable;
}
private class CurrencySettings
{
[JsonProperty(PropertyName = LangRu ? "Включить контроль разделения предметов? (если есть ошибки с плагинами стека - стоит выключить)" : "Enable item split control? (if there are errors with stack plugins - it is worth turning off)")]
public bool ControlSplit;
[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = LangRu ? "Короткое название" : "Short Name")]
public string ShortName;
[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;
public Item ToItem(int amount = 1)
{
var item = ItemManager.CreateByName(ShortName, amount, Skin);
if (item == null)
{
Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
return null;
}
if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
return item;
}
}
private class ATMSettings
{
#region Fields
[JsonProperty(PropertyName = LangRu ? "Минимальный депозит (сумма)" : "Minimum deposit (amount)")]
public float MinDeposit;
[JsonProperty(PropertyName = LangRu ? "Минимальный вывод (сумма)" : "Minimum withdrawal (amount)")]
public float MinWithdrawal;
[JsonProperty(PropertyName = LangRu ? "Включить комиссию за пополнение?" : "Enable Deposit fee?")]
public bool EnableDepositFee;
[JsonProperty(PropertyName = LangRu ? "Минимальная комиссия за пополнение" : "Minimum deposit fee")]
public float MinDepositFee;
[JsonProperty(PropertyName = LangRu ? "Максимальная комиссия за пополнение" : "Maximum deposit fee")]
public float MaxDepositFee;
[JsonProperty(PropertyName = LangRu ? "По умолчанию комиссия за пополнение" : "Default deposit fee")]
public float DefaultDepositFee;
[JsonProperty(PropertyName = LangRu ? "Шаг комиссии за пополнение" : "Step deposit fee")]
public float StepDepositFee;
[JsonProperty(PropertyName = LangRu ? "Включить комиссию за вывод?" : "Enable Withdrawal fee?")]
public bool EnableWithdrawalFee;
[JsonProperty(PropertyName = LangRu ? "Минимальная комиссия за вывод" : "Minimum withdrawal fee")]
public float MinWithdrawalFee;
[JsonProperty(PropertyName = LangRu ? "Максимальная комиссия за вывод" : "Maximum withdrawal fee")]
public float MaxWithdrawalFee;
[JsonProperty(PropertyName = LangRu ? "По умолчанию комиссия за вывод" : "Default withdrawal fee")]
public float DefaultWithdrawalFee;
[JsonProperty(PropertyName = LangRu ? "Шаг комиссии за вывод" : "Step withdrawal fee")]
public float StepWithdrawalFee;
[JsonProperty(PropertyName = LangRu ? "Включить поломку?" : "Enable breakage?")]
public bool EnableBreakage = true;
[JsonProperty(PropertyName = LangRu ? "По умолчанию процент поломки во время операции" : "Default breakage percentage during operation")]
public float DefaultBreakPercent;
[JsonProperty(PropertyName = LangRu ? "Процент поломки во время операции" : "Breakage percentage during operation",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> BreakPercent = new Dictionary<string, float>();
[JsonProperty(PropertyName = LangRu ? "Настройки ремонта" : "Repair Settings")]
public RepairSettings Repair;
[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;
[JsonProperty(PropertyName = LangRu ? "Настройки спавна" : "Spawn Settings")]
public SpawnSettings Spawn;
[JsonProperty(PropertyName = LangRu ? "Название магазина ({id} {owner})" : "Shop Name ({id} {owner})")]
public string ShopName;
[JsonProperty(PropertyName = LangRu ? "Команды для открытия меню ATM" : "Commands to open ATM menu",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] Commands = { };
[JsonProperty(PropertyName = LangRu ? "Разрешение для открытия меню ATM через команду" : "Permission to open ATM menu via command")]
public string PermissionToOpenATMviaCommand = string.Empty;
[JsonProperty(PropertyName = LangRu ? "Уведомлять игрока, когда они не имеют разрешения при открытии меню ATM через команду?" :
"Notify a player when they don't have permissions when opening the ATM menu via command?")]
public bool NotifyPlayerWhenNoPermissionInCommandATM;
#endregion
public Item ToItem()
{
var item = ItemManager.CreateByName("vending.machine", 1, Skin);
if (item == null)
return null;
if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
return item;
}
}
private class RepairSettings
{
[JsonProperty(PropertyName = LangRu ? "Предметы (для 1%)" : "Items (for 1%)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<RepairItemConf> Items = new List<RepairItemConf>();
}
private class RepairItemConf
{
[JsonProperty(PropertyName = LangRu ? "Короткое название" : "Short Name")]
public string ShortName;
[JsonProperty(PropertyName = LangRu ? "Количество (для 1%)" : "Amount (for 1%)")]
public float Amount;
[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;
[JsonProperty(PropertyName = LangRu ? "Название (пустое - по умолчанию)" : "Title (empty - default)")]
public string Title;
[JsonIgnore] private string _publicTitle;
[JsonIgnore]
public string PublicTitle
{
get
{
if (string.IsNullOrEmpty(_publicTitle))
{
if (string.IsNullOrEmpty(Title))
_publicTitle = ItemManager.FindItemDefinition(ShortName)?.displayName.translated ??
"UNKNOWN";
else
_publicTitle = Title;
}
return _publicTitle;
}
}
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
if (_config.Version < Version)
UpdateConfigValues();
SaveConfig();
}
catch (Exception ex)
{
PrintError("Your configuration file contains an error. Using default configuration values.");
Debug.LogError(ex.Message);
LoadDefaultConfig();
}
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig()
{
_config = new Configuration();
}
private void UpdateConfigValues()
{
PrintWarning("Config update detected! Updating config values...");
//var baseConfig = new Configuration();
if (_config.Version != default(VersionNumber))
{
if (_config.Version < new VersionNumber(1, 3, 0))
{
ConvertPlayerData();
ConvertPlayerLogs();
}
if (_config.Version < new VersionNumber(1, 3, 6))
{
var color1 = Config["Colors", "Color 1"].ToString();
var color2 = Config["Colors", "Color 2"].ToString();
var color3 = Config["Colors", "Color 3"].ToString();
var color4 = Config["Colors", "Color 4"].ToString();
var color5 = Config["Colors", "Color 5"].ToString();
var color6 = Config["Colors", "Color 6"].ToString();
var color7 = Config["Colors", "Color 7"].ToString();
var color8 = Config["Colors", "Color 8"].ToString();
_config.Colors.Color1 = new IColor(color1);
_config.Colors.Color2 = new IColor(color2);
_config.Colors.Color3 = new IColor(color3);
_config.Colors.Color4 = new IColor(color4);
_config.Colors.Color5 = new IColor(color5);
_config.Colors.Color6 = new IColor(color6);
_config.Colors.Color7 = new IColor(color7);
_config.Colors.Color8 = new IColor(color8);
_config.Colors.Color9 = new IColor(color3, 50);
_config.Colors.Color10 = new IColor(color3, 33);
_config.Colors.Color12 = new IColor(color6, 20);
if (_config.CardImage.Equals("https://i.imgur.com/Br9z7Ou.png"))
_config.CardImage = "https://i.ibb.co/ZMXtF1d/image.png";
if (_config.DepositImage.Equals("https://i.imgur.com/h2bqMu4.png"))
_config.DepositImage = "https://i.ibb.co/R2NT67x/image.png";
if (_config.WithdrawImage.Equals("https://i.imgur.com/lwVwxm3.png"))
_config.WithdrawImage = "https://i.ibb.co/qp6VLDm/image.png";
if (_config.TransferImage.Equals("https://i.imgur.com/TBIxUnz.png"))
_config.TransferImage = "https://i.ibb.co/T2ZNvFf/image.png";
if (_config.ExitImage.Equals("https://i.imgur.com/OGoMu9N.png"))
_config.ExitImage = "https://i.ibb.co/BgssZ0p/image.png";
}
if (_config.Version < new VersionNumber(1, 3, 16))
{
_config.EnableOfflineImageMode = false;
if (_config.CardImage.Contains("https://i.ibb.co/ZMXtF1d/image.png")) _config.CardImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/card.png";
if (_config.DepositImage.Contains("https://i.ibb.co/R2NT67x/image.png")) _config.DepositImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/deposit.png";
if (_config.WithdrawImage.Contains("https://i.ibb.co/qp6VLDm/image.png")) _config.WithdrawImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/withdraw.png";
if (_config.TransferImage.Contains("https://i.ibb.co/T2ZNvFf/image.png")) _config.TransferImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/transfer.png";
if (_config.ExitImage.Contains("https://i.ibb.co/BgssZ0p/image.png")) _config.ExitImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/exit.png";
}
}
_config.Version = Version;
PrintWarning("Config update completed!");
SaveConfig();
}
#endregion
#region Data
private ATMsData _atms;
#region Save
private void SaveATMs()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/ATMs", _atms);
}
#endregion
#region Load
private void LoadData()
{
LoadATMs();
}
private void LoadATMs()
{
try
{
_atms = Interface.Oxide.DataFileSystem.ReadObject<ATMsData>($"{Name}/ATMs");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_atms == null) _atms = new ATMsData();
}
#endregion
#region Wipe
private void WipeData()
{
WipeATMs();
}
private void WipeATMs()
{
if (_atms == null)
LoadATMs();
_atms.ATMs?.Clear();
_atms.LastATMID = 0;
PrintWarning("ATMs wiped!");
}
#endregion
#region Logs
private class TransferData
{
[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
public Transaction Type;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Sender ID")]
public ulong SenderId;
[JsonProperty(PropertyName = "Target ID")]
public ulong TargetId;
public void Get(BasePlayer player, ref CuiElementContainer container, string parent)
{
var color = string.Empty;
var icon = string.Empty;
var symbol = string.Empty;
var title = string.Empty;
var description = string.Empty;
#region Icon
switch (Type)
{
case Transaction.Deposit:
{
color = _config.Colors.Color3.Get;
icon = _instance.Msg(player, DepositIconTitle);
symbol = _instance.Msg(player, DepositSymbolTitle);
title = _instance.Msg(player, DepositOperationTitle);
description = _instance.Msg(player, DepositOperationDescription);
break;
}
case Transaction.Withdrawal:
{
color = _config.Colors.Color5.Get;
icon = _instance.Msg(player, WithdrawalIconTitle);
symbol = _instance.Msg(player, WithdrawalSymbolTitle);
title = _instance.Msg(player, WithdrawalOperationTitle);
description = _instance.Msg(player, WithdrawalOperationDescription);
break;
}
case Transaction.Transfer:
{
var self = TargetId == 0 && SenderId != 0;
if (self)
{
color = _config.Colors.Color3.Get;
icon = _instance.Msg(player, SelfTransferlIconTitle);
symbol = _instance.Msg(player, SelfTransferSymbolTitle);
description = _instance.Msg(player, SelfTransferOperationDescription,
PlayerData.GetNotLoad(SenderId.ToString())?.DisplayName);
}
else
{
color = _config.Colors.Color5.Get;
icon = _instance.Msg(player, TransferlIconTitle);
symbol = _instance.Msg(player, TransferSymbolTitle);
description = _instance.Msg(player, TransferOperationDescription,
PlayerData.GetNotLoad(TargetId.ToString())?.DisplayName);
}
title = _instance.Msg(player, TransferOperationTitle);
break;
}
}
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "0 0",
OffsetMin = "5 5", OffsetMax = "30 30"
},
Image =
{
Color = color
}
}, parent, parent + ".Icon");
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 1"
},
Text =
{
Text = $"{icon}",
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 20,
Color = _config.Colors.Color13.Get
}
}, parent + ".Icon");
#endregion
#region Title
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0.5", AnchorMax = "1 1",
OffsetMin = "35 0", OffsetMax = "-37.5 0"
},
Text =
{
Text = $"{title}",
Align = TextAnchor.LowerLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = _config.Colors.Color13.Get
}
}, parent);
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 0.5",
OffsetMin = "35 0", OffsetMax = "-37.5 0"
},
Text =
{
Text = $"{description}",
Align = TextAnchor.UpperLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = _config.Colors.Color14.Get
}
}, parent);
#endregion
#region Value
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 1",
OffsetMin = "0 0",
OffsetMax = "-10 0"
},
Text =
{
Text = _instance.Msg(player, OperationsValueFormat, symbol, Amount),
Align = TextAnchor.MiddleRight,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = color
}
}, parent);
#endregion
}
}
private enum GatherLogType
{
Gather,
Loot,
Collect,
Kill
}
private class GatherLogData
{
[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
public GatherLogType Type;
[JsonProperty(PropertyName = "Short Name")]
public string ShortName;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
}
#endregion
#region ATMs
private class ATMsData
{
[JsonProperty(PropertyName = "Last ATM ID")]
public int LastATMID;
[JsonProperty(PropertyName = "ATMs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ATMData> ATMs = new List<ATMData>();
}
private class ATMData
{
[JsonProperty(PropertyName = "Enity ID")]
public ulong EntityID;
[JsonProperty(PropertyName = "ATM ID")]
public int ID;
[JsonProperty(PropertyName = "Owner Id")]
public ulong OwnerId;
[JsonProperty(PropertyName = "Withdrawal Fee")]
public float WithdrawalFee;
[JsonProperty(PropertyName = "Deposit Fee")]
public float DepositFee;
[JsonProperty(PropertyName = "Condition")]
public float Condition;
[JsonProperty(PropertyName = "Balance")]
public float Balance;
[JsonProperty(PropertyName = "Is Admin")]
public bool IsAdmin;
public bool IsOwner(BasePlayer player)
{
return IsOwner(player.userID);
}
public bool IsOwner(ulong userId)
{
return OwnerId == userId;
}
public void LoseCondition()
{
if (IsAdmin)
return;
Condition -= LoseConditionAmount();
}
private float LoseConditionAmount()
{
var result = _config.Atm.DefaultBreakPercent;
_config.Atm.BreakPercent.Where(x => OwnerId.HasPermission(x.Key)).ForEach(check =>
{
if (result > check.Value) result = check.Value;
});
return result;
}
public bool CanOpen()
{
return Condition - LoseConditionAmount() > 0;
}
}
#endregion
#endregion
#region Hooks
private void Init()
{
_instance = this;
LoadData();
if (_config.Drop.Count == 0)
Unsubscribe(nameof(OnLootSpawn));
#if TESTING
StopwatchWrapper.OnComplete = DebugMessage;
#endif
}
private void OnServerInitialized(bool initial)
{
LoadImages();
if (_config.Currency.ControlSplit == false)
Unsubscribe(nameof(OnItemSplit));
LoadEconomyHooks();
RegisterPermissions();
RegisterCommands();
foreach (var player in BasePlayer.activePlayerList)
OnPlayerConnected(player);
RenameATMs();
timer.In(20, SpawnATMs);
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.userID.IsSteamId()) return;
#if TESTING
Debug.Log($"[OnPlayerConnected] called GetOrCreate with id={player.UserIDString}");
#endif
var data = PlayerData.GetOrCreate(player.UserIDString);
if (data == null) return;
data.DisplayName = player.displayName;
if (_config.UseCardExpiry)
CheckCard(player.userID);
if (_config.CardAutoCreation && !HasCard(player))
CreateCard(player);
}
private void OnPlayerDisconnected(BasePlayer player)
{
UnloadAndSavePlayer(player.UserIDString);
}
private void OnServerSave()
{
timer.In(Random.Range(2, 7), ClearDataCache);
timer.In(Random.Range(2, 7), SaveATMs);
}
private void Unload()
{
try
{
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, Layer);
UnloadAndSavePlayer(player.UserIDString);
}
_vendingMachines.ForEach(entity =>
{
if (entity != null)
entity.Kill();
});
SaveATMs();
}
finally
{
_instance = null;
_config = null;
}
}
#region Wipe
private void OnNewSave(string filename)
{
if (_config.Wipe.ATMs) WipeATMs();
}
#endregion
#region Loot
private void OnLootSpawn(LootContainer container)
{
if (container == null || _config.Drop.Count <= 0) return;
#if TESTING
SayDebug($"[OnLootSpawn.{container.net.ID}] called");
#endif
var dropInfo = _config.Drop.Find(x => x.Enabled && x.PrefabName.Contains(container.PrefabName));
if (dropInfo == null || Random.Range(0, 100) > dropInfo.DropChance)
{
#if TESTING
SayDebug($"[OnLootSpawn.{container.net.ID}] can't drop");
#endif
return;
}
NextTick(() =>
{
if (container == null)
{
#if TESTING
SayDebug($"[OnLootSpawn.In.Tick] container is null");
#endif
return;
}
var inventory = container.inventory;
if (inventory == null)
{
#if TESTING
SayDebug($"[OnLootSpawn.{container.net.ID}] inventory is null");
#endif
return;
}
if (inventory.capacity <= inventory.itemList.Count)
inventory.capacity = inventory.itemList.Count + 1;
var moveToContainer = _config.Currency.ToItem(Random.Range(dropInfo.MinAmount, dropInfo.MaxAmount))
?.MoveToContainer(inventory);
#if TESTING
SayDebug($"[OnLootSpawn.{container.net.ID}] moveToContainer={moveToContainer}");
#endif
});
}
#endregion
#region NPC
private void OnUseNPC(BasePlayer npc, BasePlayer player)
{
if (player == null || npc == null || !_config.NPC.NPCs.Contains(npc.UserIDString)) return;
if (!string.IsNullOrEmpty(_config.Permission) && !player.HasPermission(_config.Permission))
{
SendNotify(player, NoPermissions, 1);
return;
}
MainUi(player, first: true);
}
#endregion
#region ATM
private void OnEntitySpawned(VendingMachine entity)
{
NextTick(() =>
{
if (entity == null ||
entity.skinID != _config.Atm.Skin ||
_atms.ATMs.Exists(x => x.EntityID == entity.net.ID.Value))
return;
var data = new ATMData
{
ID = ++_atms.LastATMID,
EntityID = entity.net.ID.Value,
OwnerId = 0,
Balance = 0,
Condition = 100,
DepositFee = _config.Atm.Spawn.ConfAddons.DepositFee,
WithdrawalFee = _config.Atm.Spawn.ConfAddons.WithdrawFee,
IsAdmin = true
};
_atms.ATMs.Add(data);
if (!string.IsNullOrEmpty(_config.Atm.ShopName))
{
entity.shopName = _config.Atm.ShopName
.Replace("{id}", data.ID.ToString())
.Replace("{owner}", _config.Atm.Spawn.ConfAddons.DisplayName);
entity.UpdateMapMarker();
}
});
}
private void OnEntityBuilt(Planner plan, GameObject go)
{
if (plan == null || go == null) return;
var entity = go.ToBaseEntity() as VendingMachine;
if (entity == null) return;
var player = plan.GetOwnerPlayer();
if (player == null) return;
var item = player.GetActiveItem();
if (item == null || item.skin != _config.Atm.Skin) return;
var data = new ATMData
{
ID = ++_atms.LastATMID,
EntityID = entity.net.ID.Value,
OwnerId = player.userID
// ... [Code preview truncated due to length. Full source in attached file] ...