C#:
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
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 Random = UnityEngine.Random;
namespace Oxide.Plugins
{
[Info("Bank System", "Mevent", "1.2.2")]
public class BankSystem : RustPlugin
{
#region Fields
[PluginReference] private Plugin
ImageLibrary = null,
Notify = null,
UINotify = null,
StackSizeController = null,
StackModifier = null,
Economics = null;
private const string Layer = "UI.BankSystem";
private static BankSystem _instance;
private readonly Dictionary<BasePlayer, ATMData> _atmByPlayer = new Dictionary<BasePlayer, 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
}
#region Colors
private string _color1;
private string _color2;
private string _color3;
private string _color4;
private string _color5;
private string _color6;
private string _color7;
private string _color8;
#endregion
#endregion
#region Config
private Configuration _config;
private class Configuration
{
[JsonProperty(PropertyName = "Работать с Notify?")]
public readonly bool UseNotify = true;
[JsonProperty(PropertyName = "Команды", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly string[] Commands = {"bank"};
[JsonProperty(PropertyName = "Разрешение (например: banksystem.use)")]
public readonly string Permission = string.Empty;
[JsonProperty(PropertyName = "Стартовый баланс")]
public readonly int StartingBalance = 100;
[JsonProperty(PropertyName = "Изображение карты")]
public readonly string CardImage = "https://i.imgur.com/Br9z7Ou.png";
[JsonProperty(PropertyName = "Изображение пополнения")]
public readonly string DepositImage = "https://i.imgur.com/h2bqMu4.png";
[JsonProperty(PropertyName = "Изображение снятия")]
public readonly string WithdrawImage = "https://i.imgur.com/lwVwxm3.png";
[JsonProperty(PropertyName = "Изображение перевода")]
public readonly string TransferImage = "https://i.imgur.com/TBIxUnz.png";
[JsonProperty(PropertyName = "Изображение выхода")]
public readonly string ExitImage = "https://i.imgur.com/OGoMu9N.png";
[JsonProperty(PropertyName = "Отключить кнопку закрытия в шапке банкомата")]
public bool AtmDisableCloser = false;
[JsonProperty(PropertyName = "Настройка валюты")]
public readonly CurrencySettings Currency = new CurrencySettings
{
DisplayName = "RUSTNote",
ShortName = "sticks",
Skin = 2536195910
};
[JsonProperty(PropertyName = "Авто-создание карты")]
public readonly bool CardAutoCreation = false;
[JsonProperty(PropertyName = "Использовать срок действия карты?")]
public readonly bool UseCardExpiry = true;
[JsonProperty(PropertyName = "Срок действия карты (в днях)")]
public readonly int CardExpiryDate = 7;
[JsonProperty(PropertyName = "Настройка БАНКОМАТА")]
public readonly ATMSettings Atm = new ATMSettings
{
MinWithdrawal = 5,
MinDeposit = 5,
MinDepositFee = 0,
MaxDepositFee = 10,
StepDepositFee = 0.1f,
MinWithdrawalFee = 0,
MaxWithdrawalFee = 10,
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,
DefaultWithdrawalFee = 1,
DefaultBreakPercent = 1,
BreakPercent = new Dictionary<string, float>
{
["banksystem.vip"] = 0.7f,
["banksystem.premium"] = 0.5f
},
Spawn = new SpawnSettings
{
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}"
};
[JsonProperty(PropertyName = "Настройка отслеживания")]
public readonly TrackingSettings Tracking = new TrackingSettings
{
CostTable = new Dictionary<string, float>
{
["sulfur.ore"] = 0.5f,
["metal.ore"] = 0.5f,
["hq.metal.ore"] = 0.5f,
["stones"] = 0.5f,
["crate_elite"] = 10f,
["crate_normal"] = 7f,
["crate_normal_2"] = 4
}
};
[JsonProperty(PropertyName = "Настройка вайпа данных")]
public readonly WipeSettings Wipe = new WipeSettings
{
Players = false,
Logs = true,
ATMs = true
};
[JsonProperty(PropertyName = "Настройка NPC")]
public readonly NPCSettings NPC = new NPCSettings
{
NPCs = new List<string>
{
"1234567",
"7654321",
"4644687478"
}
};
[JsonProperty(PropertyName = "Настройка экономики")]
public readonly EconomySettings Economy = new EconomySettings
{
Self = true,
AddHook = "Deposit",
BalanceHook = "Balance",
RemoveHook = "Withdraw",
PluginName = "Economics"
};
[JsonProperty(PropertyName = "Настройка выпадения",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly 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 = "Цвета")] public readonly Colors Colors = new Colors
{
Color1 = "#0E0E10",
Color2 = "#161617",
Color3 = "#4B68FF",
Color4 = "#74884A",
Color5 = "#FF6060",
Color6 = "#C4C4C4",
Color7 = "#CD4632",
Color8 = "#595651"
};
}
private class Colors
{
[JsonProperty(PropertyName = "Цвет 1")]
public string Color1;
[JsonProperty(PropertyName = "Цвет 2")]
public string Color2;
[JsonProperty(PropertyName = "Цвет 3")]
public string Color3;
[JsonProperty(PropertyName = "Цвет 4")]
public string Color4;
[JsonProperty(PropertyName = "Цвет 5")]
public string Color5;
[JsonProperty(PropertyName = "Цвет 6")]
public string Color6;
[JsonProperty(PropertyName = "Цвет 7")]
public string Color7;
[JsonProperty(PropertyName = "Цвет 8")]
public string Color8;
}
public class DropInfo
{
[JsonProperty(PropertyName = "Включить")]
public bool Enabled;
[JsonProperty(PropertyName = "Префаб")]
public string PrefabName;
[JsonProperty(PropertyName = "Шанс")] public int DropChance;
[JsonProperty(PropertyName = "Мин.количество")]
public int MinAmount;
[JsonProperty(PropertyName = "Макс.количество")]
public int MaxAmount;
}
private class EconomySettings
{
[JsonProperty(PropertyName = "Использовать собственную систему экономики?")]
public bool Self;
[JsonProperty(PropertyName = "Plugin name")]
public string PluginName;
[JsonProperty(PropertyName = "Balance add hook")]
public string AddHook;
[JsonProperty(PropertyName = "Balance remove hook")]
public string RemoveHook;
[JsonProperty(PropertyName = "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 Math.Round(Convert.ToDouble(plugin.Call(BalanceHook, player)), 2);
}
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 = "NPCs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> NPCs = new List<string>();
}
private class WipeSettings
{
[JsonProperty(PropertyName = "Очищать данные игроков?")]
public bool Players;
[JsonProperty(PropertyName = "Очищать логи?")]
public bool Logs;
[JsonProperty(PropertyName = "Очищать данные банкоматов?")]
public bool ATMs;
}
private class SpawnSettings
{
[JsonProperty(PropertyName = "Монументы", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, ATMPosition> Monuments;
}
private class ATMPosition
{
[JsonProperty(PropertyName = "Включено")]
public bool Enabled;
[JsonProperty(PropertyName = "Отображаемое имя")]
public string DisplayName;
[JsonProperty(PropertyName = "Позиция")]
public Vector3 Position;
[JsonProperty(PropertyName = "Поворот")]
public float Rotation;
[JsonProperty(PropertyName = "Комиссия с пополнения")]
public float DepositFee;
[JsonProperty(PropertyName = "Комиссия со снятия")]
public float WithdrawFee;
}
private class TrackingSettings
{
[JsonProperty(PropertyName = "Таблица стоимости (shortname - cost)",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> CostTable;
}
private class CurrencySettings
{
[JsonProperty(PropertyName = "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = "Short Name")]
public string ShortName;
[JsonProperty(PropertyName = "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
{
[JsonProperty(PropertyName = "Минимальный депозит (количество)")]
public float MinDeposit;
[JsonProperty(PropertyName = "Минимальное снятие (количество)")]
public float MinWithdrawal;
[JsonProperty(PropertyName = "Минимальная комиссия с пополнения")]
public float MinDepositFee;
[JsonProperty(PropertyName = "Максимальная комиссия с пополнения")]
public float MaxDepositFee;
[JsonProperty(PropertyName = "Комиссия по умолчанию с пополнения")]
public float DefaultDepositFee;
[JsonProperty(PropertyName = "Шаг комиссии с пополнения")]
public float StepDepositFee;
[JsonProperty(PropertyName = "Минимальная комиссия со снятия")]
public float MinWithdrawalFee;
[JsonProperty(PropertyName = "Максимальная комиссия со снятия")]
public float MaxWithdrawalFee;
[JsonProperty(PropertyName = "Комиссия по умолчанию со снятия")]
public float DefaultWithdrawalFee;
[JsonProperty(PropertyName = "Шаг комиссии со снятия")]
public float StepWithdrawalFee;
[JsonProperty(PropertyName = "Процент поломки по умолчанию за каждую операцию")]
public float DefaultBreakPercent;
[JsonProperty(PropertyName = "Процент поломки за каждую операцию",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> BreakPercent;
[JsonProperty(PropertyName = "Настройка ремонта")]
public RepairSettings Repair;
[JsonProperty(PropertyName = "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = "Skin")] public ulong Skin;
[JsonProperty(PropertyName = "Настройка спавна")]
public SpawnSettings Spawn;
[JsonProperty(PropertyName = "Имя магазина ({id} {owner})")]
public string ShopName;
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 = "Предметы (за 1%)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<RepairItemConf> Items = new List<RepairItemConf>();
}
private class RepairItemConf
{
[JsonProperty(PropertyName = "Short Name")]
public string ShortName;
[JsonProperty(PropertyName = "Количество (за 1%)")]
public float Amount;
[JsonProperty(PropertyName = "Skin")] public ulong Skin;
[JsonProperty(PropertyName = "Название (пусто - по умолчанию)")]
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();
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig()
{
_config = new Configuration();
}
#endregion
#region Data
private PluginData _data;
private LogsData _logs;
private ATMsData _atms;
#region Save
private void SaveData()
{
SavePlayers();
SaveLogs();
SaveATMs();
}
private void SavePlayers()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Players", _data);
}
private void SaveLogs()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Logs", _logs);
}
private void SaveATMs()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/ATMs", _atms);
}
#endregion
#region Load
private void LoadData()
{
LoadPlayers();
LoadLogs();
LoadATMs();
}
private void LoadPlayers()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{Name}/Players");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
}
private void LoadLogs()
{
try
{
_logs = Interface.Oxide.DataFileSystem.ReadObject<LogsData>($"{Name}/Logs");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_logs == null) _logs = new LogsData();
}
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()
{
WipePlayers();
WipeLogs();
WipeATMs();
}
private void WipePlayers()
{
if (_data == null)
LoadPlayers();
_data.Players.Clear();
PrintWarning("Players wiped!");
}
private void WipeLogs()
{
if (_logs == null)
LoadLogs();
_logs.Players?.Clear();
PrintWarning("Logs wiped!");
}
private void WipeATMs()
{
if (_atms == null)
LoadATMs();
_atms.ATMs?.Clear();
_atms.LastATMID = 0;
PrintWarning("ATMs wiped!");
}
#endregion
#region Players
private class PluginData
{
[JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<ulong, PlayerData> Players = new Dictionary<ulong, PlayerData>();
}
private class PlayerData
{
[JsonProperty(PropertyName = "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = "Balance")]
public int Balance;
[JsonProperty(PropertyName = "Card Number")]
public string Card;
[JsonProperty(PropertyName = "Card Date")]
public DateTime CardDate;
}
private PlayerData GetPlayerData(BasePlayer player)
{
return GetPlayerData(player.userID);
}
private PlayerData GetPlayerData(ulong member)
{
if (!_data.Players.ContainsKey(member))
_data.Players.Add(member, new PlayerData());
return _data.Players[member];
}
#endregion
#region Logs
private class LogsData
{
[JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<ulong, PlayerLogs> Players = new Dictionary<ulong, PlayerLogs>();
}
private class PlayerLogs
{
[JsonProperty(PropertyName = "Transfers", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<TransferData> Transfers = new List<TransferData>();
[JsonProperty(PropertyName = "Gather Logs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<GatherLogData> GatherLogs = new List<GatherLogData>();
}
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 = _instance._color3;
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 = _instance._color5;
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 = _instance._color3;
icon = _instance.Msg(player, SelfTransferlIconTitle);
symbol = _instance.Msg(player, SelfTransferSymbolTitle);
description = _instance.Msg(player, SelfTransferOperationDescription,
_instance.GetPlayerData(SenderId)?.DisplayName);
}
else
{
color = _instance._color5;
icon = _instance.Msg(player, TransferlIconTitle);
symbol = _instance.Msg(player, TransferSymbolTitle);
description = _instance.Msg(player, TransferOperationDescription,
_instance.GetPlayerData(TargetId)?.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 = "1 1 1 1"
}
}, 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 = "1 1 1 1"
}
}, 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 = "1 1 1 0.5"
}
}, 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
}
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;
}
private PlayerLogs GetPlayerLogs(BasePlayer player)
{
return GetPlayerLogs(player.userID);
}
private PlayerLogs GetPlayerLogs(ulong member)
{
if (!_logs.Players.ContainsKey(member))
_logs.Players.Add(member, new PlayerLogs());
return _logs.Players[member];
}
#endregion
#region ATMs
private class ATMsData
{
[JsonProperty(PropertyName = "Last ATM ID")]
public int LastATMID;
[JsonProperty(PropertyName = "ATMs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<ATMData> ATMs = new List<ATMData>();
}
private class ATMData
{
[JsonProperty(PropertyName = "Enity ID")]
public uint 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 = _instance._config.Atm.DefaultBreakPercent;
_instance._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));
}
private void OnServerInitialized(bool initial)
{
LoadImages();
LoadColors();
if (StackSizeController || StackModifier)
Unsubscribe(nameof(OnItemSplit));
if (Economics)
Unsubscribe(nameof(Balance));
if (!string.IsNullOrEmpty(_config.Permission) &&
!permission.PermissionExists(_config.Permission))
permission.RegisterPermission(_config.Permission, this);
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;
GetAvatar(player.userID,
avatar => ImageLibrary?.Call("AddImage", avatar, $"avatar_{player.UserIDString}"));
var data = GetPlayerData(player);
if (data == null) return;
data.DisplayName = player.displayName;
if (_config.UseCardExpiry)
CheckCard(player.userID);
if (_config.CardAutoCreation && !HasCard(player))
CreateCard(player);
}
private void OnServerSave()
{
timer.In(Random.Range(2, 7), SavePlayers);
timer.In(Random.Range(2, 7), SaveATMs);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
CuiHelper.DestroyUi(player, Layer);
_vendingMachines.ForEach(entity =>
{
if (entity != null)
entity.Kill();
});
SaveData();
_instance = null;
}
#region Wipe
private void OnNewSave(string filename)
{
if (_config.Wipe.Players) WipePlayers();
if (_config.Wipe.Logs) WipeLogs();
if (_config.Wipe.ATMs) WipeATMs();
}
#endregion
#region Loot
private void OnLootSpawn(LootContainer container)
{
if (container == null) return;
var dropInfo = _config.Drop.Find(x => x.Enabled && x.PrefabName.Contains(container.PrefabName));
if (dropInfo == null || Random.Range(0, 100) > dropInfo.DropChance) return;
NextTick(() =>
{
if (container == null) return;
var inventory = container.inventory;
if (inventory == null) return;
if (inventory.capacity <= inventory.itemList.Count)
inventory.capacity = inventory.itemList.Count + 1;
_config.Currency.ToItem(Random.Range(dropInfo.MinAmount, dropInfo.MaxAmount))
?.MoveToContainer(inventory);
});
}
#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 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,
OwnerId = player.userID,
Balance = 0,
Condition = 100,
DepositFee = _config.Atm.DefaultDepositFee,
WithdrawalFee = _config.Atm.DefaultWithdrawalFee
};
_atms.ATMs.Add(data);
if (!string.IsNullOrEmpty(_config.Atm.ShopName))
{
entity.shopName = _config.Atm.ShopName.Replace("{id}", data.ID.ToString()).Replace("{owner}", player.displayName);
entity.UpdateMapMarker();
}
}
private void OnEntityDeath(VendingMachine entity, HitInfo hitInfo)
{
if (entity == null || entity.net == null)
return;
_atms.ATMs.RemoveAll(x => x.EntityID == entity.net.ID);
}
private bool? CanUseVending(BasePlayer player, VendingMachine machine)
{
if (machine == null || player == null || machine.skinID != _config.Atm.Skin) return null;
var data = _atms.ATMs.Find(x => x.EntityID == machine.net.ID);
if (data == null)
return null;
if (!HasCard(player))
{
SendNotify(player, NotBankCard, 1);
return false;
}
if (!data.CanOpen())
{
SendNotify(player, BrokenATM, 1);
return false;
}
_atmByPlayer[player] = data;
ATMUi(player, First: true);
return false;
}
private void OnEntityKill(VendingMachine machine)
{
if (machine == null || machine.skinID != _config.Atm.Skin) return;
LogToFile(Name, Environment.StackTrace, this);
}
#endregion
#region Split
private Item OnItemSplit(Item item, int amount)
{
if (item == null || item.info.shortname != _config.Currency.ShortName ||
_config.Currency.Skin != item.skin) return null;
item.amount -= amount;
var newItem = ItemManager.CreateByItemID(item.info.itemid, 1, item.skin);
newItem.amount = amount;
newItem.condition = item.condition;
if (!string.IsNullOrEmpty(item.name)) newItem.name = item.name;
if (item.IsBlueprint()) newItem.blueprintTarget = item.blueprintTarget;
item.MarkDirty();
return newItem;
}
private object CanCombineDroppedItem(DroppedItem droppedItem, DroppedItem targetItem)
{
if (droppedItem == null || targetItem == null) return null;
var item = droppedItem.GetItem();
if (item == null) return null;
var tItem = targetItem.GetItem();
if (tItem == null || item.skin == tItem.skin) return null;
return item.skin == _config.Currency.Skin || tItem.skin == _config.Currency.Skin;
}
private object CanStackItem(Item item, Item targetItem)
{
if (item == null || targetItem == null || item.skin == targetItem.skin) return null;
return item.info.shortname == targetItem.info.shortname &&
(item.skin == _config.Currency.Skin || targetItem.skin == _config.Currency.Skin) &&
item.skin == targetItem.skin
? (object) (item.amount + targetItem.amount < item.info.stackable)
: null;
}
#endregion
#region Tracking
#region Gather Tracking
private void OnCollectiblePickup(Item item, BasePlayer player)
{
OnGather(player, item.info.shortname, item.amount);
}
private void OnCropGather(GrowableEntity plant, Item item, BasePlayer player)
{
OnGather(player, item.info.shortname, item.amount);
}
private void OnDispenserBonus(ResourceDispenser dispenser, BasePlayer player, Item item)
{
OnGather(player, item.info.shortname, item.amount);
}
private void OnDispenserGather(ResourceDispenser dispenser, BasePlayer player, Item item)
{
OnGather(player, item.info.shortname, item.amount);
}
private void OnGather(BasePlayer player, string shortname, int amount)
{
if (player == null || string.IsNullOrEmpty(shortname) || amount <= 0) return;
AddPlayerTracking(GatherLogType.Gather, player, shortname, amount);
}
#endregion
#region Loot
private readonly Dictionary<uint, ulong> _lootedContainers = new Dictionary<uint, ulong>();
private void OnLootEntity(BasePlayer player, LootContainer container)
{
if (player == null || container == null || container.net == null) return;
var netID = container.net.ID;
if (_lootedContainers.ContainsKey(netID)) return;
_lootedContainers.Add(netID, player.userID);
AddPlayerTracking(GatherLogType.Loot, player, container.ShortPrefabName);
}
#endregion
#endregion
#endregion
#region Commands
private void CmdOpenBank(IPlayer cov, string command, string[] args)
{
var player = cov?.Object as BasePlayer;
if (player == null) return;
if (!string.IsNullOrEmpty(_config.Permission) &&
!player.HasPermission(_config.Permission))
{
SendNotify(player, NoPermissions, 1);
return;
}
MainUi(player, first: true);
}
[ConsoleCommand("UI_BankSystem")]
private void CmdConsoleBank(ConsoleSystem.Arg arg)
{
var player = arg?.Player();
if (player == null || !arg.HasArgs()) return;
switch (arg.Args[0])
{
case "close":
{
_atmByPlayer.Remove(player);
break;
}
case "cardcreate":
{
CreateCard(player);
MainUi(player);
break;
}
case "page":
{
ulong targetId;
int amount, transactionPage, gatherPage;
if (!arg.HasArgs(5) ||
!int.TryParse(arg.Args[1], out amount) ||
!ulong.TryParse(arg.Args[2], out targetId) ||
!int.TryParse(arg.Args[3], out transactionPage) ||
!int.TryParse(arg.Args[4], out gatherPage)) return;
MainUi(player, amount, targetId, transactionPage, gatherPage);
break;
}
case "setamount":
{
ulong targetId;
int amount, transactionPage, gatherPage;
if (!arg.HasArgs(5) ||
!ulong.TryParse(arg.Args[1], out targetId) ||
!int.TryParse(ar
// ... [Code preview truncated due to length. Full source in attached file] ...