neon-sprawl/server/NeonSprawl.Server/Game/Contracts/ContractIssueApi.cs

97 lines
3.7 KiB
C#

using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
namespace NeonSprawl.Server.Game.Contracts;
/// <summary>Maps <c>POST /game/players/{{id}}/contracts/issue</c> (NEO-151).</summary>
public static class ContractIssueApi
{
public static WebApplication MapContractIssueApi(this WebApplication app)
{
app.MapPost(
"/game/players/{id}/contracts/issue",
(string id, ContractIssueRequest? body, IPositionStateStore positions,
IContractTemplateRegistry templateRegistry, IEncounterDefinitionRegistry encounterRegistry,
IItemDefinitionRegistry itemRegistry, ISkillDefinitionRegistry skillRegistry,
IFactionDefinitionRegistry factionRegistry, IContractInstanceStore instanceStore,
IFactionStandingStore standingStore, IRewardDeliveryStore deliveryStore,
TimeProvider timeProvider) =>
{
var trimmedId = id.Trim();
if (trimmedId.Length == 0 || !positions.TryGetPosition(trimmedId, out _))
{
return Results.NotFound();
}
if (body is null || body.SchemaVersion != ContractIssueRequest.CurrentSchemaVersion)
{
return Results.BadRequest();
}
var normalizedTemplateId = ContractInstanceIds.NormalizeTemplateId(body.TemplateId);
var normalizedSeedBucket = ContractInstanceIds.NormalizeSeedBucket(body.SeedBucket);
var normalizedBodyPlayerId = ContractInstanceIds.NormalizePlayerId(body.PlayerId);
if (normalizedTemplateId.Length == 0 ||
normalizedSeedBucket.Length == 0 ||
normalizedBodyPlayerId.Length == 0)
{
return Results.BadRequest();
}
var normalizedPathPlayerId = ContractInstanceIds.NormalizePlayerId(trimmedId);
if (!string.Equals(normalizedBodyPlayerId, normalizedPathPlayerId, StringComparison.Ordinal))
{
return Results.BadRequest();
}
var result = ContractGeneratorOperations.TryIssue(
trimmedId,
normalizedTemplateId,
normalizedSeedBucket,
body.ZoneDifficultyBand,
templateRegistry,
encounterRegistry,
itemRegistry,
skillRegistry,
factionRegistry,
instanceStore,
standingStore,
timeProvider);
return Results.Json(
MapIssueResponse(trimmedId, result, templateRegistry, deliveryStore));
});
return app;
}
internal static ContractIssueResponse MapIssueResponse(
string playerId,
ContractIssueOperationResult result,
IContractTemplateRegistry templateRegistry,
IRewardDeliveryStore deliveryStore)
{
ContractInstanceRowJson? contract = null;
if (result.Snapshot is { } snapshot)
{
contract = ContractListApi.MapInstanceRow(
playerId,
snapshot,
templateRegistry,
deliveryStore,
result.EncounterTemplateId);
}
return new ContractIssueResponse
{
Issued = result.Success,
ReasonCode = result.ReasonCode,
Contract = contract,
};
}
}