Build & Deploy / build (push) Successful in 31s
Adds SquadService (singleton, process-local) tracking squads by the squadId the client shares across party members, plus a user->squad index so TryGetCompleteSquadInfo (no squadId in request) can resolve the caller's squad. Members are lazily registered on any squad call. - TryGetCompleteSquadInfo: returns the caller's real squad. - SquadMemberReadyForMatch: joins the squad, records readiness/map, returns the squad + whether everyone is ready. - SquadMemberSelectedMap: records the member's selected map. - DbUserService.FindByIdAsync: resolve display name for squad members. Groundwork for the station lobby; assumes the client drives squads via these calls with a shared squadId (to confirm with a 2-client session). Real-time SignalR push (unknown event names) deferred; the squad is carried in responses + TryGetCompleteSquadInfo for now. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
84 lines
3.0 KiB
C#
84 lines
3.0 KiB
C#
using System.Text.Json.Serialization;
|
|
using Prospect.Server.Api.Services.Auth.Extensions;
|
|
using Prospect.Server.Api.Services.CloudScript;
|
|
using Prospect.Server.Api.Services.Database;
|
|
using Prospect.Server.Api.Services.Squad;
|
|
|
|
public class TryGetCompleteSquadInfoRequest
|
|
{
|
|
// Empty request
|
|
}
|
|
|
|
public class FYPlayFabSquad
|
|
{
|
|
[JsonPropertyName("squadId")]
|
|
public string SquadID { get; set; }
|
|
[JsonPropertyName("members")]
|
|
public FYPlayFabSquadMember[] Members { get; set; }
|
|
}
|
|
|
|
public class FYPlayFabSquadMember {
|
|
[JsonPropertyName("profile")]
|
|
public FYPlayFabPlayerProfile Profile { get; set; }
|
|
[JsonPropertyName("onlineState")]
|
|
public int onlineState { get; set; }
|
|
[JsonPropertyName("matchmakingSettings")]
|
|
public FYUserMatchmakingSettings matchmakingSettings { get; set; }
|
|
[JsonPropertyName("mapRowNamesUnlocked")]
|
|
public string[] mapRowNamesUnlocked { get; set; }
|
|
};
|
|
|
|
public class FYPlayFabPlayerProfile {
|
|
[JsonPropertyName("avatarUrl")]
|
|
public string AvatarUrl { get; set; }
|
|
[JsonPropertyName("displayName")]
|
|
public string DisplayName { get; set; }
|
|
[JsonPropertyName("playerId")]
|
|
public string PlayerId { get; set; }
|
|
};
|
|
|
|
public class FYUserMatchmakingSettings {
|
|
[JsonPropertyName("isReadyForMatch")]
|
|
public bool isReadyForMatch;
|
|
[JsonPropertyName("selectedMapName")]
|
|
public string selectedMapName;
|
|
[JsonPropertyName("isSecretLeader")]
|
|
public bool isSecretLeader;
|
|
[JsonPropertyName("purchaseInsuranceRequest")]
|
|
public object purchaseInsuranceRequest; // FYPurchaseInsuranceRequest
|
|
};
|
|
|
|
|
|
[CloudScriptFunction("TryGetCompleteSquadInfo")]
|
|
public class TryGetCompleteSquadInfoFunction : ICloudScriptFunction<TryGetCompleteSquadInfoRequest, FYPlayFabSquad>
|
|
{
|
|
private readonly ILogger<TryGetCompleteSquadInfoFunction> _logger;
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
private readonly SquadService _squadService;
|
|
|
|
public TryGetCompleteSquadInfoFunction(ILogger<TryGetCompleteSquadInfoFunction> logger, IHttpContextAccessor httpContextAccessor, SquadService squadService)
|
|
{
|
|
_httpContextAccessor = httpContextAccessor;
|
|
_logger = logger;
|
|
_squadService = squadService;
|
|
}
|
|
|
|
public Task<FYPlayFabSquad> ExecuteAsync(TryGetCompleteSquadInfoRequest request)
|
|
{
|
|
var context = _httpContextAccessor.HttpContext;
|
|
if (context == null)
|
|
{
|
|
throw new CloudScriptException("CloudScript was not called within a http request");
|
|
}
|
|
var userId = context.User.FindAuthUserId();
|
|
var squad = _squadService.GetByUser(userId);
|
|
if (squad == null)
|
|
{
|
|
// Not in a squad yet — return an empty squad (same as the previous stub).
|
|
return Task.FromResult(new FYPlayFabSquad());
|
|
}
|
|
_logger.LogInformation("TryGetCompleteSquadInfo: user {User} in squad {Squad} ({Count} member(s))", userId, squad.SquadId, squad.Members.Count);
|
|
return Task.FromResult(_squadService.ToClientSquad(squad));
|
|
}
|
|
}
|