Client-side wrapper for the HorizonRP police and justice backend. Defines DTOs for officers, penal code, records, jail, fines and a set of Justice* methods that post JSON payloads to named server endpoints through the shared Backend.Post helper.
namespace HorizonRP;
/// <summary>
/// Les appels de l'API du chantier « Justice et service » (outils/police/CONCEPTION.md, section 2) :
/// effectifs et code pénal, casier (amende, arrestation), prison, amendes payées à l'accueil.
/// Clé du serveur, appelés par l'hôte seul (PoliceService.Service.cs, PoliceActions.cs) après avoir
/// revérifié les droits. Les noms commencent par « Justice » pour ne pas croiser ceux de la tablette
/// (PoliceBackend.Tablet.cs, « Mdt »).
///
/// Les SteamID partent en texte (colonnes VARCHAR de l'API), comme pour la tablette. Les nombres
/// rendus en texte par PHP se lisent quand même (réglages « Web » de System.Text.Json).
/// </summary>
public static partial class Backend
{
/// <summary>Un agent inscrit, tel que serverPoliceSync le rend.</summary>
public sealed class JusticeOfficer
{
/// <summary>BIGINT en base : il peut arriver en nombre JSON comme en texte (lu par <see cref="SteamIdText"/>).</summary>
public object SteamId { get; set; }
/// <summary>Le SteamID en texte, quelle que soit sa forme dans la réponse.</summary>
public string SteamIdText => SteamId?.ToString()?.Trim( '"' );
public int Grade { get; set; }
public string Badge { get; set; }
public string Callsign { get; set; }
}
/// <summary>Une ligne active du code pénal.</summary>
public sealed class JusticePenal
{
public string Id { get; set; }
public string Category { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Class { get; set; }
public int Fine { get; set; }
public int JailMinutes { get; set; }
}
public sealed class JusticePlateFlag
{
public string Plate { get; set; }
public string Reason { get; set; }
}
public sealed class JusticeSyncResponse
{
public bool Ok { get; set; }
public string Error { get; set; }
public List<JusticeOfficer> Officers { get; set; }
public List<JusticePenal> Penal { get; set; }
public List<JusticePlateFlag> Flags { get; set; }
}
public sealed class JusticeRecordResponse
{
public bool Ok { get; set; }
public string Error { get; set; }
public long RecordId { get; set; }
public int FineTotal { get; set; }
public int JailMinutes { get; set; }
public long? FineId { get; set; }
/// <summary>Arrestation : la peine en cours après celle-ci (elle s'ajoute à une peine déjà en cours, plafond 120 min).</summary>
public JusticeJail Jail { get; set; }
}
public sealed class JusticeJail
{
public int SecondsLeft { get; set; }
public int SecondsTotal { get; set; }
}
public sealed class JusticeJailResponse
{
public bool Ok { get; set; }
public string Error { get; set; }
/// <summary>Null : pas en prison.</summary>
public JusticeJail Jail { get; set; }
}
/// <summary>Une amende, pour l'accueil du commissariat.</summary>
public sealed class JusticeFine
{
public long Id { get; set; }
public int Amount { get; set; }
public string Status { get; set; }
public string IssuedAt { get; set; }
public string Title { get; set; }
}
public sealed class JusticeFinesResponse
{
public bool Ok { get; set; }
public string Error { get; set; }
public List<JusticeFine> Fines { get; set; }
}
public sealed class JusticeFinePayResponse
{
public bool Ok { get; set; }
public string Error { get; set; }
/// <summary>Le solde HZ BANK après paiement : l'hôte le reporte sur le joueur (sinon la sauvegarde suivante l'écraserait).</summary>
public int Bank { get; set; }
}
/// <summary>Effectifs, code pénal (lignes actives) et véhicules signalés.</summary>
public static Task<JusticeSyncResponse> JusticeSync()
=> Post<JusticeSyncResponse>( "serverPoliceSync", new { } );
/// <summary>
/// Une ligne du casier écrite en jeu (menu F6) : <paramref name="kind"/> « amende » ou
/// « arrestation ». L'API recalcule amende et peine d'après hz_penal_code.
/// </summary>
public static Task<JusticeRecordResponse> JusticeRecord( ulong steamId, string kind, List<string> charges, string title, string notes, string location, ulong officerSteam, string officerName )
=> Post<JusticeRecordResponse>( "serverPoliceRecord", new { steamId = steamId.ToString(), kind, charges, title, notes, location, officerSteam = officerSteam.ToString(), officerName } );
/// <summary>La peine en cours d'un joueur qui se connecte, ou null.</summary>
public static Task<JusticeJailResponse> JusticeJailLoad( ulong steamId )
=> Post<JusticeJailResponse>( "serverPoliceJail", new { steamId = steamId.ToString() } );
/// <summary>Le temps qui reste (0 = libéré : la ligne est supprimée).</summary>
public static Task<SimpleResponse> JusticeJailSave( ulong steamId, int secondsLeft )
=> Post<SimpleResponse>( "serverPoliceJailSave", new { steamId = steamId.ToString(), secondsLeft } );
public static Task<JusticeFinesResponse> JusticeFines( ulong steamId )
=> Post<JusticeFinesResponse>( "serverPoliceFines", new { steamId = steamId.ToString() } );
/// <summary><paramref name="balance"/> : le solde que le jeu a en mémoire (il fait foi, la base n'est écrite qu'aux sauvegardes).</summary>
public static Task<JusticeFinePayResponse> JusticeFinePay( ulong steamId, long fineId, int balance )
=> Post<JusticeFinePayResponse>( "serverPoliceFinePay", new { steamId = steamId.ToString(), fineId, balance } );
}