mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 00:14:00 +00:00
feat(multiplayer): persist ranked arena allocations
This commit is contained in:
@@ -19,6 +19,7 @@ type AcceptedMatchPlan struct {
|
||||
ProposalID string
|
||||
Region string
|
||||
Protocol int
|
||||
ArenaPath string
|
||||
Players []MatchPlayer
|
||||
}
|
||||
|
||||
@@ -40,11 +41,11 @@ ORDER BY player_id
|
||||
FOR UPDATE`
|
||||
|
||||
const AcceptedMatchInsertSQL = `INSERT INTO matches
|
||||
(match_id, playlist, state, region, protocol_version)
|
||||
VALUES ($1, $2, 'ALLOCATING', $3, $4)
|
||||
(match_id, playlist, state, region, protocol_version, arena_path)
|
||||
VALUES ($1, $2, 'ALLOCATING', $3, $4, NULLIF($5, ''))
|
||||
ON CONFLICT (match_id) DO NOTHING`
|
||||
|
||||
const AcceptedMatchSelectSQL = `SELECT playlist, state, region, protocol_version, server_id
|
||||
const AcceptedMatchSelectSQL = `SELECT playlist, state, region, protocol_version, arena_path, server_id
|
||||
FROM matches
|
||||
WHERE match_id = $1
|
||||
FOR UPDATE`
|
||||
@@ -63,7 +64,7 @@ const AcceptedMatchParticipantInsertSQL = `INSERT INTO match_participants
|
||||
(match_id, player_id, ticket_id, slot, team)
|
||||
VALUES ($1, $2, $3, $4, $5)`
|
||||
|
||||
const StoredProposalMatchPlanSQL = `SELECT match_region, match_protocol
|
||||
const StoredProposalMatchPlanSQL = `SELECT match_region, match_protocol, match_arena_path
|
||||
FROM proposals
|
||||
WHERE proposal_id = $1 AND state = 'ACCEPTED'`
|
||||
|
||||
@@ -80,7 +81,7 @@ func PromoteStoredAcceptedProposal(ctx context.Context, db *sql.DB, proposalID s
|
||||
return fmt.Errorf("invalid stored proposal promotion arguments")
|
||||
}
|
||||
plan := AcceptedMatchPlan{MatchID: "match-" + proposalID, ProposalID: proposalID}
|
||||
if err := db.QueryRowContext(ctx, StoredProposalMatchPlanSQL, proposalID).Scan(&plan.Region, &plan.Protocol); err != nil {
|
||||
if err := db.QueryRowContext(ctx, StoredProposalMatchPlanSQL, proposalID).Scan(&plan.Region, &plan.Protocol, &plan.ArenaPath); err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := db.QueryContext(ctx, StoredProposalMatchPlayersSQL, proposalID)
|
||||
@@ -119,11 +120,14 @@ func CreateMatchFromAcceptedProposal(ctx context.Context, db *sql.DB, plan Accep
|
||||
if !validAcceptedPlaylistCount(domain.Playlist(playlist), len(plan.Players)) {
|
||||
return fmt.Errorf("accepted proposal playlist does not match player count")
|
||||
}
|
||||
if domain.Playlist(playlist) == domain.Ranked && plan.ArenaPath == "" {
|
||||
return fmt.Errorf("ranked accepted match plan has no arena")
|
||||
}
|
||||
participants, err := acceptedProposalParticipants(ctx, tx, plan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inserted, err := tx.ExecContext(ctx, AcceptedMatchInsertSQL, plan.MatchID, playlist, plan.Region, plan.Protocol)
|
||||
inserted, err := tx.ExecContext(ctx, AcceptedMatchInsertSQL, plan.MatchID, playlist, plan.Region, plan.Protocol, plan.ArenaPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -216,11 +220,12 @@ func acceptedProposalParticipants(ctx context.Context, tx *sql.Tx, plan Accepted
|
||||
func verifyAcceptedMatchReplay(ctx context.Context, tx *sql.Tx, plan AcceptedMatchPlan, playlist domain.Playlist, tickets map[string]string) error {
|
||||
var existingPlaylist, state, region string
|
||||
var protocol int
|
||||
var arenaPath sql.NullString
|
||||
var serverID sql.NullString
|
||||
if err := tx.QueryRowContext(ctx, AcceptedMatchSelectSQL, plan.MatchID).Scan(&existingPlaylist, &state, ®ion, &protocol, &serverID); err != nil {
|
||||
if err := tx.QueryRowContext(ctx, AcceptedMatchSelectSQL, plan.MatchID).Scan(&existingPlaylist, &state, ®ion, &protocol, &arenaPath, &serverID); err != nil {
|
||||
return err
|
||||
}
|
||||
if existingPlaylist != string(playlist) || state != string(domain.Allocating) || region != plan.Region || protocol != plan.Protocol || serverID.Valid {
|
||||
if existingPlaylist != string(playlist) || state != string(domain.Allocating) || region != plan.Region || protocol != plan.Protocol || arenaPath.String != plan.ArenaPath || arenaPath.Valid != (plan.ArenaPath != "") || serverID.Valid {
|
||||
return domain.ErrConflict
|
||||
}
|
||||
rows, err := tx.QueryContext(ctx, AcceptedMatchParticipantsSQL, plan.MatchID)
|
||||
|
||||
Reference in New Issue
Block a user