Skip to content

Commit

Permalink
feat(match2): replace walkover and resulttype with status on ma…
Browse files Browse the repository at this point in the history
…tch level on standardized wikis (#5041)

* feat(match2): replace `walkover` and `resulttype` with `status` on match level

* fix walkover backwards

* fix resulttype value for walkovers
  • Loading branch information
Rathoz authored Nov 6, 2024
1 parent 734beba commit 765b6ff
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 17 deletions.
40 changes: 36 additions & 4 deletions components/match2/commons/match.lua
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ end
---Final processing of records before being stored to LPDB.
---@param records table
function Match._prepareRecordsForStore(records)
Match._prepareMatchRecordForStore(records.matchRecord)
Match._prepareMatchRecordForStore(records.matchRecord, records.opponentRecords)
for opponentIndex, opponentRecord in ipairs(records.opponentRecords) do
Match.clampFields(opponentRecord, Match.opponentFields)
for _, playerRecord in ipairs(records.playerRecords[opponentIndex]) do
Expand All @@ -321,7 +321,10 @@ function Match._prepareRecordsForStore(records)
end

---@param match table
function Match._prepareMatchRecordForStore(match)
---@param opponents table[]?
function Match._prepareMatchRecordForStore(match, opponents)
Match._commonBackwardsCompatabilityForV3API(match, opponents)

match.dateexact = Logic.readBool(match.dateexact) and 1 or 0
match.finished = Logic.readBool(match.finished) and 1 or 0
match.match2bracketdata = match.match2bracketdata or match.bracketdata
Expand Down Expand Up @@ -379,6 +382,35 @@ function Match._prepareGameRecordForStore(matchRecord, gameRecord)
Match.clampFields(gameRecord, Match.gameFields)
end

---Adds fields needed for backwards compatibility with API v3.
---walkover and resulttype are added to record.
---@param record table #game or match record
---@param opponents table[]? #opponents of the record
function Match._commonBackwardsCompatabilityForV3API(record, opponents)
if record.finished then
if not record.walkover then
local function calculateWalkover()
local walkoverOpponent = Array.find(opponents or {}, function(opponent)
return opponent.status == 'FF' or opponent.status == 'DQ' or opponent.status == 'L'
end)
return walkoverOpponent and walkoverOpponent.status:lower() or ''
end
record.walkover = calculateWalkover()
end

if not record.resulttype then
if record.status == 'notplayed' then
record.resulttype = 'np'
elseif record.winner == 0 then
record.resulttype = 'draw'
elseif record.walkover ~= '' then
record.resulttype = 'default'
else
record.resulttype = ''
end
end
end
end

Match.matchFields = Table.map({
'bestof',
Expand All @@ -400,7 +432,7 @@ Match.matchFields = Table.map({
'parentname',
'patch',
'publishertier',
'resulttype',
'resulttype', -- LPDB API v3: backwards compatibility
'series',
'shortname',
'status',
Expand All @@ -409,7 +441,7 @@ Match.matchFields = Table.map({
'tournament',
'type',
'vod',
'walkover',
'walkover', -- LPDB API v3: backwards compatibility
'winner',
'section',
}, function(_, field) return field, true end)
Expand Down
45 changes: 32 additions & 13 deletions components/match2/commons/match_group_input_util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ MatchGroupInputUtil.RESULT_TYPE = {
NOT_PLAYED = 'np',
DRAW = 'draw',
}

MatchGroupInputUtil.MATCH_STATUS = {
NOT_PLAYED = 'notplayed',
}

MatchGroupInputUtil.WALKOVER = {
FORFEIT = 'ff',
DISQUALIFIED = 'dq',
Expand Down Expand Up @@ -608,7 +613,17 @@ function MatchGroupInputUtil.isNotPlayed(winnerInput, finishedInput)
or (type(finishedInput) == 'string' and MatchGroupInputUtil.isNotPlayedInput(finishedInput))
end

---@param winnerInput integer|string|nil
---@param finishedInput string?
---@return string? #Match Status
function MatchGroupInputUtil.getMatchStatus(winnerInput, finishedInput)
if MatchGroupInputUtil.isNotPlayed(winnerInput, finishedInput) then
return MatchGroupInputUtil.MATCH_STATUS.NOT_PLAYED
end
end

---Should only be called on finished matches or maps
---@deprecated
---@param winnerInput integer|string|nil
---@param finishedInput string?
---@param opponents {score: number?, status: string}[]
Expand All @@ -627,18 +642,18 @@ function MatchGroupInputUtil.getResultType(winnerInput, finishedInput, opponents
end
end

---@param resultType string?
---@param status string
---@param winnerInput integer|string|nil
---@param opponents {score: number, status: string, placement: integer?}[]
---@return integer? # Winner
function MatchGroupInputUtil.getWinner(resultType, winnerInput, opponents)
if resultType == MatchGroupInputUtil.RESULT_TYPE.NOT_PLAYED then
function MatchGroupInputUtil.getWinner(status, winnerInput, opponents)
if status == MatchGroupInputUtil.RESULT_TYPE.NOT_PLAYED or status == MatchGroupInputUtil.MATCH_STATUS.NOT_PLAYED then
return nil
elseif Logic.isNumeric(winnerInput) then
return tonumber(winnerInput)
elseif resultType == MatchGroupInputUtil.RESULT_TYPE.DRAW then
elseif MatchGroupInputUtil.isDraw(opponents, winnerInput) then
return MatchGroupInputUtil.WINNER_DRAW
elseif resultType == MatchGroupInputUtil.RESULT_TYPE.DEFAULT then
elseif MatchGroupInputUtil.hasSpecialStatus(opponents) then
return MatchGroupInputUtil.getDefaultWinner(opponents)
elseif MatchGroupInputUtil.findOpponentWithFirstPlace(opponents) then
return MatchGroupInputUtil.findOpponentWithFirstPlace(opponents)
Expand Down Expand Up @@ -670,6 +685,7 @@ function MatchGroupInputUtil.getHighestScoringOpponent(opponents)
return Array.indexOf(scores, FnUtil.curry(Operator.eq, maxScore))
end

---@deprecated
---@param resultType string?
---@param opponents {status: string}[]
---@return string? # Walkover Type
Expand All @@ -679,6 +695,7 @@ function MatchGroupInputUtil.getWalkover(resultType, opponents)
end
end

---@deprecated
---@param opponents {status: string}[]
---@return string?
function MatchGroupInputUtil.getWalkoverType(opponents)
Expand Down Expand Up @@ -805,20 +822,23 @@ function MatchGroupInputUtil._opponentWithStatus(opponents, status)
return Array.indexOf(opponents, function (opponent) return opponent.status == status end)
end

---@deprecated
-- function to check for forfeits
---@param opponents {status: string?}[]
---@return boolean
function MatchGroupInputUtil.hasForfeit(opponents)
return MatchGroupInputUtil._opponentWithStatus(opponents, MatchGroupInputUtil.STATUS.FORFEIT) ~= 0
end

---@deprecated
-- function to check for DQ's
---@param opponents {status: string?}[]
---@return boolean
function MatchGroupInputUtil.hasDisqualified(opponents)
return MatchGroupInputUtil._opponentWithStatus(opponents, MatchGroupInputUtil.STATUS.DISQUALIFIED) ~= 0
end

---@deprecated
-- function to check for W/L
---@param opponents {status: string?}[]
---@return boolean
Expand All @@ -833,7 +853,7 @@ function MatchGroupInputUtil.hasScore(opponents)
return MatchGroupInputUtil._opponentWithStatus(opponents, MatchGroupInputUtil.STATUS.SCORE) ~= 0
end

-- Get the winner when resulttype=default
-- Get the winner when letter results (W/L etc)
---@param opponents {status: string?}[]
---@return integer
function MatchGroupInputUtil.getDefaultWinner(opponents)
Expand All @@ -848,12 +868,12 @@ end
--- If Winner = 0, means it was a draw, return 1
--- If Winner = -1, means that mean no team won, returns 2
--- Otherwise return 2
---@param resultType string?
---@param status string?
---@param winner integer?
---@param opponentIndex integer
---@return integer?
function MatchGroupInputUtil.placementFromWinner(resultType, winner, opponentIndex)
if resultType == MatchGroupInputUtil.RESULT_TYPE.NOT_PLAYED then
function MatchGroupInputUtil.placementFromWinner(status, winner, opponentIndex)
if status == MatchGroupInputUtil.RESULT_TYPE.NOT_PLAYED or status == MatchGroupInputUtil.MATCH_STATUS.NOT_PLAYED then
return nil
end
if winner == 0 or winner == opponentIndex then
Expand Down Expand Up @@ -1145,11 +1165,10 @@ function MatchGroupInputUtil.standardProcessMatch(match, Parser, mapProps)
match.finished = MatchGroupInputUtil.matchIsFinished(match, opponents)

if match.finished then
match.resulttype = MatchGroupInputUtil.getResultType(winnerInput, finishedInput, opponents)
match.walkover = MatchGroupInputUtil.getWalkover(match.resulttype, opponents)
match.winner = MatchGroupInputUtil.getWinner(match.resulttype, winnerInput, opponents)
match.status = MatchGroupInputUtil.getMatchStatus(winnerInput, finishedInput)
match.winner = MatchGroupInputUtil.getWinner(match.status, winnerInput, opponents)
Array.forEach(opponents, function(opponent, opponentIndex)
opponent.placement = MatchGroupInputUtil.placementFromWinner(match.resulttype, match.winner, opponentIndex)
opponent.placement = MatchGroupInputUtil.placementFromWinner(match.status, match.winner, opponentIndex)
end)
end

Expand Down
5 changes: 5 additions & 0 deletions components/match2/commons/match_group_util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ MatchGroupUtil.types.GameOpponent = TypeUtil.struct({
type = 'string',
})

---@alias MatchStatus 'notplayed'|''|nil
MatchGroupUtil.types.Status = TypeUtil.optional(TypeUtil.literalUnion('notplayed', ''))
---@alias ResultType 'default'|'draw'|'np'
MatchGroupUtil.types.ResultType = TypeUtil.literalUnion('default', 'draw', 'np')
---@alias WalkoverType 'l'|'ff'|'dq'
Expand Down Expand Up @@ -249,6 +251,7 @@ MatchGroupUtil.types.Game = TypeUtil.struct({
---@field mode string?
---@field opponents standardOpponent[]
---@field resultType ResultType?
---@field status MatchStatus
---@field stream table
---@field tickername string?
---@field tournament string?
Expand All @@ -272,6 +275,7 @@ MatchGroupUtil.types.Match = TypeUtil.struct({
mode = 'string',
opponents = TypeUtil.array(MatchGroupUtil.types.Opponent),
resultType = 'string?',
status = MatchGroupUtil.types.Status,
stream = 'table',
tickername = 'string?',
tournament = 'string?',
Expand Down Expand Up @@ -530,6 +534,7 @@ function MatchGroupUtil.matchFromRecord(record)
parent = record.parent,
patch = record.patch,
resultType = nilIfEmpty(record.resulttype),
status = nilIfEmpty(record.status),
stream = Json.parseIfString(record.stream) or {},
tickername = record.tickername,
timestamp = tonumber(Table.extract(extradata, 'timestamp')),
Expand Down

0 comments on commit 765b6ff

Please sign in to comment.