Add bank toolshed commands (#40614)
* add bank commands * Follow convention * use protoId * make logic better * Move stuff to shared * Make things dirty * Move UpdateBankAccount to shared as well * nullable + resolve * Fix commands * make things less legible * typo * same typo * im dumb * I don't know how to spell * replace select with foreach Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com> * replace select with foreach again --------- Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com>
This commit is contained in:
@@ -1,20 +1,15 @@
|
|||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.DeviceLinking.Systems;
|
using Content.Server.DeviceLinking.Systems;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.Shuttles.Systems;
|
|
||||||
using Content.Server.Stack;
|
using Content.Server.Stack;
|
||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Access.Systems;
|
using Content.Shared.Access.Systems;
|
||||||
using Content.Shared.Administration.Logs;
|
using Content.Shared.Administration.Logs;
|
||||||
using Content.Server.Radio.EntitySystems;
|
using Content.Server.Radio.EntitySystems;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.Components;
|
|
||||||
using Content.Shared.Cargo.Prototypes;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
using Content.Shared.Paper;
|
using Content.Shared.Paper;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
@@ -76,49 +71,4 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
UpdateTelepad(frameTime);
|
UpdateTelepad(frameTime);
|
||||||
UpdateBounty();
|
UpdateBounty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateBankAccount(
|
|
||||||
Entity<StationBankAccountComponent?> ent,
|
|
||||||
int balanceAdded,
|
|
||||||
ProtoId<CargoAccountPrototype> account,
|
|
||||||
bool dirty = true)
|
|
||||||
{
|
|
||||||
UpdateBankAccount(
|
|
||||||
ent,
|
|
||||||
balanceAdded,
|
|
||||||
new Dictionary<ProtoId<CargoAccountPrototype>, double> { {account, 1} },
|
|
||||||
dirty: dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds or removes funds from the <see cref="StationBankAccountComponent"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ent">The station.</param>
|
|
||||||
/// <param name="balanceAdded">The amount of funds to add or remove.</param>
|
|
||||||
/// <param name="accountDistribution">The distribution between individual <see cref="CargoAccountPrototype"/>.</param>
|
|
||||||
/// <param name="dirty">Whether to mark the bank account component as dirty.</param>
|
|
||||||
[PublicAPI]
|
|
||||||
public void UpdateBankAccount(
|
|
||||||
Entity<StationBankAccountComponent?> ent,
|
|
||||||
int balanceAdded,
|
|
||||||
Dictionary<ProtoId<CargoAccountPrototype>, double> accountDistribution,
|
|
||||||
bool dirty = true)
|
|
||||||
{
|
|
||||||
if (!Resolve(ent, ref ent.Comp))
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var (account, percent) in accountDistribution)
|
|
||||||
{
|
|
||||||
var accountBalancedAdded = (int) Math.Round(percent * balanceAdded);
|
|
||||||
ent.Comp.Accounts[account] += accountBalancedAdded;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ev = new BankBalanceUpdatedEvent(ent, ent.Comp.Accounts);
|
|
||||||
RaiseLocalEvent(ent, ref ev, true);
|
|
||||||
|
|
||||||
if (!dirty)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Dirty(ent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
93
Content.Server/Station/Commands/BankCommand.cs
Normal file
93
Content.Server/Station/Commands/BankCommand.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Server.Administration;
|
||||||
|
using Content.Server.Cargo.Systems;
|
||||||
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Cargo.Components;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Toolshed;
|
||||||
|
|
||||||
|
namespace Content.Server.Station.Commands;
|
||||||
|
|
||||||
|
[ToolshedCommand, AdminCommand(AdminFlags.Admin)]
|
||||||
|
public sealed class BankCommand : ToolshedCommand
|
||||||
|
{
|
||||||
|
private CargoSystem? _cargo;
|
||||||
|
|
||||||
|
[CommandImplementation("accounts")]
|
||||||
|
public IEnumerable<BankAccount> Accounts([PipedArgument] EntityUid station)
|
||||||
|
{
|
||||||
|
_cargo ??= GetSys<CargoSystem>();
|
||||||
|
|
||||||
|
foreach (var (account, _) in _cargo.GetAccounts(station))
|
||||||
|
{
|
||||||
|
yield return new BankAccount(account.Id, station, _cargo, EntityManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandImplementation("accounts")]
|
||||||
|
public IEnumerable<BankAccount> Accounts([PipedArgument] IEnumerable<EntityUid> stations)
|
||||||
|
=> stations.SelectMany(Accounts);
|
||||||
|
|
||||||
|
[CommandImplementation("account")]
|
||||||
|
public BankAccount Account([PipedArgument] EntityUid station, ProtoId<CargoAccountPrototype> account)
|
||||||
|
{
|
||||||
|
_cargo ??= GetSys<CargoSystem>();
|
||||||
|
|
||||||
|
return new BankAccount(account.Id, station, _cargo, EntityManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandImplementation("account")]
|
||||||
|
public IEnumerable<BankAccount> Account([PipedArgument] IEnumerable<EntityUid> stations, ProtoId<CargoAccountPrototype> account)
|
||||||
|
=> stations.Select(x => Account(x, account));
|
||||||
|
|
||||||
|
[CommandImplementation("adjust")]
|
||||||
|
public IEnumerable<BankAccount> Adjust([PipedArgument] IEnumerable<BankAccount> @ref, int by)
|
||||||
|
{
|
||||||
|
_cargo ??= GetSys<CargoSystem>();
|
||||||
|
var bankAccounts = @ref.ToList();
|
||||||
|
foreach (var bankAccount in bankAccounts.ToList())
|
||||||
|
{
|
||||||
|
_cargo.TryAdjustBankAccount(bankAccount.Station, bankAccount.Account, by, true);
|
||||||
|
}
|
||||||
|
return bankAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandImplementation("set")]
|
||||||
|
public IEnumerable<BankAccount> Set([PipedArgument] IEnumerable<BankAccount> @ref, int by)
|
||||||
|
{
|
||||||
|
_cargo ??= GetSys<CargoSystem>();
|
||||||
|
var bankAccounts = @ref.ToList();
|
||||||
|
foreach (var bankAccount in bankAccounts.ToList())
|
||||||
|
{
|
||||||
|
_cargo.TrySetBankAccount(bankAccount.Station, bankAccount.Account, by, true);
|
||||||
|
}
|
||||||
|
return bankAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandImplementation("amount")]
|
||||||
|
public IEnumerable<int> Amount([PipedArgument] IEnumerable<BankAccount> @ref)
|
||||||
|
{
|
||||||
|
_cargo ??= GetSys<CargoSystem>();
|
||||||
|
return @ref.Select(bankAccount => (success: _cargo.TryGetAccount(bankAccount.Station, bankAccount.Account, out var money), money))
|
||||||
|
.Where(result => result.success)
|
||||||
|
.Select(result => result.money);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly record struct BankAccount(
|
||||||
|
string Account,
|
||||||
|
Entity<StationBankAccountComponent?> Station,
|
||||||
|
CargoSystem Cargo,
|
||||||
|
IEntityManager EntityManager)
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (!Cargo.TryGetAccount(Station, Account, out var money))
|
||||||
|
{
|
||||||
|
return $"{EntityManager.ToPrettyString(Station)} Account {Account} : (not a account)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"{EntityManager.ToPrettyString(Station)} Account {Account} : {money}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Cargo.Components;
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.Cargo.Prototypes;
|
using Content.Shared.Cargo.Prototypes;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
@@ -55,6 +56,151 @@ public abstract class SharedCargoSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
return distribution;
|
return distribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns information about the given bank account.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="station">Station to get bank account info from.</param>
|
||||||
|
/// <param name="accountPrototypeId">Bank account prototype ID to get info for.</param>
|
||||||
|
/// <param name="money">The amount of money in the account</param>
|
||||||
|
/// <returns>Whether or not the bank account exists.</returns>
|
||||||
|
public bool TryGetAccount(Entity<StationBankAccountComponent?> station, ProtoId<CargoAccountPrototype> accountPrototypeId, out int money)
|
||||||
|
{
|
||||||
|
money = 0;
|
||||||
|
|
||||||
|
if (!Resolve(station, ref station.Comp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return station.Comp.Accounts.TryGetValue(accountPrototypeId, out money);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a readonly dictionary of all accounts and their money info.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="station">Station to get bank account info from.</param>
|
||||||
|
/// <returns>Whether or not the bank account exists.</returns>
|
||||||
|
public IReadOnlyDictionary<ProtoId<CargoAccountPrototype>, int> GetAccounts(Entity<StationBankAccountComponent?> station)
|
||||||
|
{
|
||||||
|
if (!Resolve(station, ref station.Comp))
|
||||||
|
return new Dictionary<ProtoId<CargoAccountPrototype>, int>();
|
||||||
|
|
||||||
|
return station.Comp.Accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to adjust the money of a certain bank account.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="station">Station where the bank account is from</param>
|
||||||
|
/// <param name="accountPrototypeId">the id of the bank account</param>
|
||||||
|
/// <param name="money">how much money to set the account to</param>
|
||||||
|
/// <param name="createAccount">Whether or not it should create the account if it doesn't exist.</param>
|
||||||
|
/// <param name="dirty">Whether to mark the bank account component as dirty.</param>
|
||||||
|
/// <returns>Whether or not setting the value succeeded.</returns>
|
||||||
|
public bool TryAdjustBankAccount(
|
||||||
|
Entity<StationBankAccountComponent?> station,
|
||||||
|
ProtoId<CargoAccountPrototype> accountPrototypeId,
|
||||||
|
int money,
|
||||||
|
bool createAccount = false,
|
||||||
|
bool dirty = true)
|
||||||
|
{
|
||||||
|
if (!Resolve(station, ref station.Comp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var accounts = station.Comp.Accounts;
|
||||||
|
|
||||||
|
if (!accounts.ContainsKey(accountPrototypeId) && !createAccount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
accounts[accountPrototypeId] += money;
|
||||||
|
var ev = new BankBalanceUpdatedEvent(station, station.Comp.Accounts);
|
||||||
|
RaiseLocalEvent(station, ref ev, true);
|
||||||
|
|
||||||
|
if (!dirty)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Dirty(station);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to set the money of a certain bank account.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="station">Station where the bank account is from</param>
|
||||||
|
/// <param name="accountPrototypeId">the id of the bank account</param>
|
||||||
|
/// <param name="money">how much money to set the account to</param>
|
||||||
|
/// <param name="createAccount">Whether or not it should create the account if it doesn't exist.</param>
|
||||||
|
/// <param name="dirty">Whether to mark the bank account component as dirty.</param>
|
||||||
|
/// <returns>Whether or not setting the value succeeded.</returns>
|
||||||
|
public bool TrySetBankAccount(
|
||||||
|
Entity<StationBankAccountComponent?> station,
|
||||||
|
ProtoId<CargoAccountPrototype> accountPrototypeId,
|
||||||
|
int money,
|
||||||
|
bool createAccount = false,
|
||||||
|
bool dirty = true)
|
||||||
|
{
|
||||||
|
if (!Resolve(station, ref station.Comp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var accounts = station.Comp.Accounts;
|
||||||
|
|
||||||
|
if (!accounts.ContainsKey(accountPrototypeId) && !createAccount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
accounts[accountPrototypeId] = money;
|
||||||
|
var ev = new BankBalanceUpdatedEvent(station, station.Comp.Accounts);
|
||||||
|
RaiseLocalEvent(station, ref ev, true);
|
||||||
|
|
||||||
|
if (!dirty)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Dirty(station);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateBankAccount(
|
||||||
|
Entity<StationBankAccountComponent?> ent,
|
||||||
|
int balanceAdded,
|
||||||
|
ProtoId<CargoAccountPrototype> account,
|
||||||
|
bool dirty = true)
|
||||||
|
{
|
||||||
|
UpdateBankAccount(
|
||||||
|
ent,
|
||||||
|
balanceAdded,
|
||||||
|
new Dictionary<ProtoId<CargoAccountPrototype>, double> { {account, 1} },
|
||||||
|
dirty: dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds or removes funds from the <see cref="StationBankAccountComponent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The station.</param>
|
||||||
|
/// <param name="balanceAdded">The amount of funds to add or remove.</param>
|
||||||
|
/// <param name="accountDistribution">The distribution between individual <see cref="CargoAccountPrototype"/>.</param>
|
||||||
|
/// <param name="dirty">Whether to mark the bank account component as dirty.</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void UpdateBankAccount(
|
||||||
|
Entity<StationBankAccountComponent?> ent,
|
||||||
|
int balanceAdded,
|
||||||
|
Dictionary<ProtoId<CargoAccountPrototype>, double> accountDistribution,
|
||||||
|
bool dirty = true)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent, ref ent.Comp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var (account, percent) in accountDistribution)
|
||||||
|
{
|
||||||
|
var accountBalancedAdded = (int) Math.Round(percent * balanceAdded);
|
||||||
|
ent.Comp.Accounts[account] += accountBalancedAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ev = new BankBalanceUpdatedEvent(ent, ent.Comp.Accounts);
|
||||||
|
RaiseLocalEvent(ent, ref ev, true);
|
||||||
|
|
||||||
|
if (!dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Dirty(ent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetSerializable, Serializable]
|
[NetSerializable, Serializable]
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ command-description-acmd-perms =
|
|||||||
Returns the admin permissions of the given command, if any.
|
Returns the admin permissions of the given command, if any.
|
||||||
command-description-acmd-caninvoke =
|
command-description-acmd-caninvoke =
|
||||||
Check if the given player can invoke the given command.
|
Check if the given player can invoke the given command.
|
||||||
|
command-description-bank-accounts =
|
||||||
|
Returns all accounts on a station.
|
||||||
|
command-description-bank-account =
|
||||||
|
Returns a given bank account from a station.
|
||||||
|
command-description-bank-adjust =
|
||||||
|
Adjusts the money for the given bank account.
|
||||||
|
command-description-bank-set =
|
||||||
|
Sets the money for the given bank account.
|
||||||
|
command-description-bank-amount =
|
||||||
|
Returns the money for the given bank account.
|
||||||
command-description-jobs-jobs =
|
command-description-jobs-jobs =
|
||||||
Returns all jobs on a station.
|
Returns all jobs on a station.
|
||||||
command-description-jobs-job =
|
command-description-jobs-job =
|
||||||
|
|||||||
Reference in New Issue
Block a user