Money/Bank.cs

Bank account logic for the roleplay gamemode. Holds a player's balance, applies deposits and withdrawals through Move, and sends each ledger entry to the backend via Backend.BankOps so the phone app can show history.

Networking
namespace HorizonRP;

/// <summary>
/// HZ BANK : le compte de chaque joueur (<see cref="RoleplayPlayer.Bank"/>) et son historique.
/// Tout mouvement passe par <see cref="Move"/>, sur l'hôte : le solde change et le mouvement part
/// à l'API (hz_bank_ops, serverBankOps), d'où l'application du téléphone tire l'historique —
/// dépôts et retraits au distributeur, paiements par carte, virements, retouches du staff.
///
/// Le numéro de compte se tire du SteamID comme le numéro de téléphone (<see cref="Phone.AccountOf"/>,
/// compteDe() d'api.php) : on le donne pour recevoir un virement, même hors ligne.
/// </summary>
public static class Bank
{
	public sealed class Op
	{
		public long Id { get; set; }
		public int Amount { get; set; }
		public int Balance { get; set; }
		public string Kind { get; set; }
		public string Label { get; set; }
		public string Counterpart { get; set; }
		public string CreatedAt { get; set; }
	}

	/// <summary>
	/// Hôte : un mouvement sur le compte (positif : crédit). Rend faux si le solde n'y suffit pas
	/// (rien n'est alors débité). <paramref name="kind"/> : depot, retrait, carte, virement_envoye,
	/// virement_recu, remboursement, staff (la liste fermée d'api.php).
	/// </summary>
	public static bool Move( RoleplayPlayer player, int delta, string kind, string label, string counterpart = null )
	{
		if ( player is null || delta == 0 )
			return delta == 0;
		if ( player.Bank + delta < 0 )
			return false;
		player.Bank += delta;
		Record( player, delta, kind, label, counterpart );
		return true;
	}

	/// <summary>Hôte : note un mouvement déjà fait sur le solde (le staff qui fixe une valeur).</summary>
	public static void Record( RoleplayPlayer player, int delta, string kind, string label, string counterpart = null )
	{
		if ( player is null || delta == 0 || !Backend.IsOnline )
			return;
		_ = Backend.BankOps( new[]
		{
			new { steamId = player.SteamId.ToString(), amount = delta, balance = player.Bank, kind, label, counterpart },
		} );
	}
}