SMITE Esports Wiki
[checked revision][checked revision]
Ispoonz (talk | contribs)
(Created page with "local util_args = require('Module:ArgsUtil') local util_vars = require('Module:VarsUtil') local util_cargo = require('Module:CargoUtil') local util_table = require('Module:Tab...")
 
([ST])
Tag: Reverted
(3 intermediate revisions by the same user not shown)
Line 24: Line 24:
 
local h = {}
 
local h = {}
 
local p = {}
 
local p = {}
−
function p.start(frame)
+
function p.start(args)
 
i18n.initGlobalFromFile('MatchSchedule')
 
i18n.initGlobalFromFile('MatchSchedule')
 
local args = util_args.merge(true)
 
local args = util_args.merge(true)
Line 38: Line 38:
 
end
 
end
 
h.setStartVars(args)
 
h.setStartVars(args)
−
return '<table class="wikitable">', tbl
+
return '<table class="wikitable">' --, tbl
 
end
 
end
   
Line 46: Line 46:
 
args.winner = '0'
 
args.winner = '0'
 
end
 
end
  +
  +
local display_start = args.round and p.start(args) or ''
 
 
 
local match_tbl = h.makeCargoMatchFields(args)
 
local match_tbl = h.makeCargoMatchFields(args)
Line 68: Line 70:
 
 
 
local display_match = h.makeMatchDisplay(match_tbl, args)
 
local display_match = h.makeMatchDisplay(match_tbl, args)
  +
−
return h.printMatchRow(display_match, display_games)
+
return h.printMatchRow(display_start, display_match, display_games)
 
end
 
end
   
Line 79: Line 82:
 
util_vars.resetGlobalIndex('N_MatchInTab')
 
util_vars.resetGlobalIndex('N_MatchInTab')
 
util_vars.setVar('OverviewPage', util_esports.getOverviewPage())
 
util_vars.setVar('OverviewPage', util_esports.getOverviewPage())
−
util_vars.setVar('TabName', args.tab)
+
util_vars.setVar('TabName', args.tab or args.round)
 
util_vars.setVarOnlyIf('Bestof', args.bestof)
 
util_vars.setVarOnlyIf('Bestof', args.bestof)
 
util_vars.setVarOnlyIf('MVPPoints', args.mvppoints)
 
util_vars.setVarOnlyIf('MVPPoints', args.mvppoints)

Revision as of 18:23, 17 January 2022

Documentation for this module may be created at Module:MatchSchedule/doc

local util_args = require('Module:ArgsUtil')
local util_vars = require('Module:VarsUtil')
local util_cargo = require('Module:CargoUtil')
local util_table = require('Module:TableUtil')
local util_time = require('Module:TimeUtil')
local util_text = require('Module:TextUtil')
local util_esports = require('Module:EsportsUtil')
local m_phase = require('Module:Phase')
local m_team = require('Module:Team')

local i18n = require('Module:I18nUtil')
local lang = mw.getLanguage('en')

local MATCH_FIELDS = { 'Round', 'Group', 'Team1', 'Team2', 'Result', 'Points', 'PointsTB', 'BestOf', 'DateTime_UTC', 'DateTime_PST', 'DateTime_CET', 'DateTime_KST', 'PBP', 'Color', 'MVP', 'VodInterview', 'With', 'VodHighlights', 'Recap', 'Reddit' }

local GAME_ARGS = { 'Blue', 'Red', 'Winner', 'FF', 'Selection', 'MatchHistory', 'Recap', 'Vod', 'VodPB', 'VodGameStart', 'VodPostgame', 'VodHighlights', 'VodInterview', 'InterviewWith', 'InterviewWithLinks', 'MVP', 'MVPLink', 'MVPPoints', 'BlueFootnote', 'RedFootnote' }

local GAME_FIELDS = { 'Blue', 'Red', 'Winner', 'FF', 'Selection', 'MatchHistory', 'Recap', 'Vod', 'VodPB', 'VodGameStart', 'VodPostgame', 'VodHighlights', 'VodInterview', 'InterviewWith', 'MVP' }

local ALLOWED_TZ = { PST = true, KST = true, CET = true }

local arg_sep = '%s*;;;%s*'

local h = {}
local p = {}
function p.start(args)
	i18n.initGlobalFromFile('MatchSchedule')
	local args = util_args.merge(true)
	local tbl = mw.html.create()
	args.tab = args.tab and m_phase.longname(args.tab) or 'Matches'
	tbl:tag('tr'):tag('th'):attr('colspan','50'):wikitext(args.tab)
	local tr = tbl:tag('tr')
	for _, v in ipairs(MATCH_FIELDS) do
		tr:tag('th'):wikitext(i18n.print(v))
	end
	for _, v in ipairs(GAME_FIELDS) do
		tr:tag('th'):wikitext(i18n.print(v))
	end
	h.setStartVars(args)
	return '<table class="wikitable">' --, tbl
end

function p.main(frame)
	local args = util_args.merge(true)
	if lang:lc(args.winner or '') == 'draw' then
		args.winner = '0'
	end
	
	local display_start = args.round and p.start(args) or ''
	
	local match_tbl = h.makeCargoMatchFields(args)
	
	local display_games, games_cargo
	if args.game1 then
		local games_tbl = util_args.numberedArgsToTable(args, 'game')
		util_table.mapInPlace(games_tbl, h.splitGameArgs)
		games_cargo = h.makeCargoGameFields(games_tbl, match_tbl)
		display_games = util_table.mapSafe(games_tbl, h.makeGameDisplay)
		h.addGameTotalScoreToMatchAndValidate(match_tbl, games_cargo, util_args.castAsBool(args.ignorewarnings))
	end
	
	if util_cargo.doWeStoreCargo(args.nocargo, 'Data') then
		util_cargo.store(match_tbl)
		if games_cargo then
			for _, game in ipairs(games_cargo) do
				util_cargo.store(game)
			end
		end
	end
	
	local display_match = h.makeMatchDisplay(match_tbl, args)
	
	return h.printMatchRow(display_start, display_match, display_games)
end

function p.endTable(frame)
	return '</table>'
end

function h.setStartVars(args)
	util_vars.setGlobalIndex('N_TabInPage')
	util_vars.resetGlobalIndex('N_MatchInTab')
	util_vars.setVar('OverviewPage', util_esports.getOverviewPage())
	util_vars.setVar('TabName', args.tab or args.round)
	util_vars.setVarOnlyIf('Bestof', args.bestof)
	util_vars.setVarOnlyIf('MVPPoints', args.mvppoints)
	util_vars.setVarOnlyIf('shownname', args.shownname)
	if args.phase then
		local thisphase = m_phase.longname(args.phase)
		local lastphase = util_vars.getVar('Phase')
		if lastphase ~= thisphase then
			util_vars.setVar('Phase', thisphase)
			util_vars.setGlobalIndex('Phase_N')
		end
	end
end

function h.getTZData(args)
	if not args.date then
		return {}
	end
	local time = ('%s %s'):format(args.date, args.time or '23:59')
	if not args.timezone or not ALLOWED_TZ[args.timezone] then
		error('Missing or invalid timezone. Allowed values: PST, CET, KST.')
	end
	local tz = args.timezone or 'PST'
	local dst = util_args.norm(args.dst)
	return util_time.getTimezones(time, tz, dst)
end

function h.makeCargoMatchFields(args)
	local tzdata = h.getTZData(args)
	local tbl = {
		_table = 'MatchSchedule',
		Team1 = m_team.teamlinkname(args.team1),
		Team2 = m_team.teamlinkname(args.team2),
		Team1Points = args.team1points,
		Team2Points = args.team2points,
		Team1PointsTB = args.team1pointstb,
		Team2PointsTB = args.team2pointstb,
		DateTime_UTC = tzdata.UTC,
		DateTime_PST = tzdata.PST,
		DateTime_CET = tzdata.CET,
		DateTime_KST = tzdata.KST,
		HasTime = args.time and 'Yes',
		OverviewPage = util_vars.getVar('OverviewPage'),
		Winner = args.winner,
		Team1Score = args.team1score,
		Team2Score = args.team2score,
		FF = args.ff,
		DST = args.dst,
		IsFlexibleStart = util_args.castAsBool(args.flex) and 'Yes' or 'No',
		
		BestOf = args.bestof or util_vars.getVar('Bestof'),
		ShownRound = args.round or util_vars.getVar('Round'),
		Phase = util_vars.getVar('Phase'),
		N_MatchInPage = util_vars.setGlobalIndex('MS_Overall'),
		Tab = util_vars.getVar('TabName'),
		N_MatchInTab = util_vars.setGlobalIndex('N_MatchInTab'),
		N_TabInPage = util_vars.getGlobalIndex('N_TabInPage'),
		N_Page = util_vars.getVar('N_Page'),
		
		IsTiebreaker = args.istb and 'Yes' or 'No',
		
		Stream = args.stream,
		StreamDisplay = args.streamdisplay,
		Venue = args.venue,
		CastersPBP = args.pbp,
		CastersPBPLinks = args.pbplinks or args.pbp,
		CastersColor = args.color,
		CastersColorLinks = args.colorlinks or args.color,
		MVP = args.mvp,
		MVPLink = util_esports.ucfirstLink(args.mvplink, args.mvp),
		MVPPoints = args.mvppoints or util_vars.getVar('MVPPoints'),
		VodInterview = args.vodinterview,
		VodHighlights = args.vodhl,
		InterviewWith = args.with,
		InterviewWithLinks = util_esports.ucfirstLinks(args.withlinks, args.with),
		Recap = args.recap,
		Reddit = args.reddit,
		
		Team1Footnote = args.team1footnote,
		Team2Footnote = args.team2footnote,
		Footnote = args.footnote,
	}
	tbl.InitialN_MatchInTab = args.initialorder or tbl.N_MatchInTab
	local title = mw.title.getCurrentTitle().text
	tbl.UniqueMatch = title .. '_' .. tbl.Tab .. '_' .. tbl.N_MatchInTab
	tbl.ShownName = args.shownname or util_vars.getVar('shownname') or tbl.OverviewPage
	
	tbl.Team1Final = args.team1final and m_team.teamlinkname(args.team1final) or tbl.Team1
	tbl.Team2Final = args.team2final and m_team.teamlinkname(args.team2final) or tbl.Team2
	h.getMatchDay(tbl, tzdata.UTC, args.matchday)
	return tbl
end

function h.getMatchDay(tbl, tzdata, gameday)
	local thistime = tonumber(util_time.unix(tzdata))
	local lasttime = tonumber(util_vars.getVar('MatchTime') or '')
	local lastday = tonumber(util_vars.getVar('MatchDay') or '')
	util_vars.setVar('MatchTime', thistime)
	if gameday then
		tbl.MatchDay = gameday
		util_vars.setVar('MatchDay', gameday)
	elseif not lasttime then
		tbl.MatchDay = 1
		util_vars.setVar('MatchDay', 1)
	elseif (thistime - lasttime) > 43200 then
		tbl.MatchDay = lastday + 1
		util_vars.setVar('MatchDay', lastday + 1)
	else
		tbl.MatchDay = lastday
		util_vars.setVar('MatchDay', lastday)
	end
end

function h.makeCargoGameFields(args, match)
	local tbl = {}
	for i, game in ipairs(args) do
		tbl[i] = mw.clone(game)
		thisgame = tbl[i] -- alias for convenience
		thisgame._table = 'MatchScheduleGame'
		thisgame.Blue = game.Blue and m_team.teamlinkname(game.Blue)
		thisgame.Red = game.Red and m_team.teamlinkname(game.Red)
		
		thisgame.MVPLink = util_esports.ucfirstLink(thisgame.MVPLink, thisgame.MVP)
		thisgame.MVPPoints = thisgame.MVPPoints or match.MVPPoints
		
		thisgame.InterviewWithLinks = util_esports.ucfirstLinks(thisgame.InterviewWithLinks, thisgame.InterviewWith)
		
		thisgame.OverviewPage = match.OverviewPage
		thisgame.N_GameInMatch = i
		thisgame.UniqueMatch = match.UniqueMatch
		thisgame.N_MatchInTab = match.N_MatchInTab
		thisgame.N_TabInPage = match.N_TabInPage
		thisgame.N_Page = match.N_Page
		thisgame.UniqueLine = match.UniqueMatch .. '_' .. i
		if thisgame.Selection then
			h.sideSelection(thisgame)
		end
		
		local allowed_teams = { [match.Team1] = true, [match.Team2] = true }
		
		if thisgame.Blue and not allowed_teams[thisgame.Blue] then
			error(('%s: Invalid blue team (%s) in match %s game %s'):format(match.Tab, thisgame.Blue, thisgame.N_MatchInTab, i))
		end
		if thisgame.Red and not allowed_teams[thisgame.Red] then
			error(('%s: Invalid red team (%s) in game %s in match %s'):format(match.Tab, thisgame.Red, thisgame.N_MatchInTab, i))
		end
	end
	return tbl
end

function h.sideSelection(thisgame)
	if thisgame.Selection == '1' or thisgame.Selection == '2' then
		h.selectionFromNumber(thisgame, match)
	else
		h.selectionFromName(thisgame)
	end
end

function h.selectionFromNumber(thisgame)
	if thisgame.Selection == '1' then
		thisgame.ShownName = thisgame.Blue
	elseif thisgame.Selection == '2' then
		thisgame.ShownName = thisgame.Red
	end
end

function h.selectionFromName(thisgame)
	local ssel = m_team.teamlinkname(thisgame.Selection)
	if ssel == thisgame.Blue then
		thisgame.Selection = 1
	elseif ssel == thisgame.Red then
		thisgame.Selection = 2
	elseif thisgame.Blue and thisgame.Red then
		error(('Invalid side selection entry of %s in match %s game %s'):format(thisgame.Selection, thisgame.N_MatchInTab, i))
	end
	thisgame.ShownName = ssel
end

function h.makeMatchDisplay(tbl, args)
	local display = mw.clone(tbl)
	display.Result = ("%s - %s"):format(
		tbl.Winner == '1' and ("'''%s'''"):format(tbl.Team1Score or '') or tbl.Team1Score or '',
		tbl.Winner == '2' and ("'''%s'''"):format(tbl.Team2Score or '') or tbl.Team2Score or ''
	)
	display.Team1 = m_team.plainlinked(tbl.Team1)
	display.Team2 = m_team.plainlinked(tbl.Team2)
	display.DateTime_UTC = tbl.DateTime_UTC and lang:formatDate('D Y-m-d H:i', tbl.DateTime_UTC)
	display.DateTime_PST = tbl.DateTime_PST and tbl.DateTime_PST:match('(%d%d:%d%d)')
	display.DateTime_CET = tbl.DateTime_CET and tbl.DateTime_CET:match('(%d%d:%d%d)')
	display.DateTime_KST = tbl.DateTime_KST and tbl.DateTime_KST:match('(%d%d:%d%d)')
	display.Points = (tbl.Team1Points or tbl.Team2Points) and ('%s - %s'):format(tbl.Team1Points or '', tbl.Team2Points or '')
	display.PointsTB = (tbl.Team1PointsTB or tbl.Team2PointsTB) and ('%s - %s'):format(tbl.Team1PointsTB or '', tbl.Team2PointsTB or '')
	display.PBP = util_esports.concatLinksFromStrings(args.pbplinks, args.pbp)
	display.Color = util_esports.concatLinksFromStrings(args.colorlinks, args.color)
	display.MVP = util_esports.concatLinksFromStrings(args.mvplink, args.mvp)
	display.With = util_esports.concatLinksFromStrings(args.withlinks, args.with)
	display.Reddit = args.reddit and ('[%s]'):format(args.reddit)
	display.Recap = args.recap and ('[%s]'):format(args.recap)
	display.VodInterview = args.vodinterview and ('[%s]'):format(args.vodinterview)
	display.VodHighlights = args.vodhl and ('[%s]'):format(args.vodhl)
	return display
end

function h.makeGameDisplay(game)
	local display = mw.clone(game)
	display.Blue = game.Blue and m_team.short(game.Blue) or '[[Category:Data Pages Missing Per-Game Data]]'
	display.Red = game.Red and m_team.short(game.Red) or '[[Category:Data Pages Missing Per-Game Data]]'
	display.Vod = h.printExternalLink(game.Vod)
	display.VodPB = h.printExternalLink(game.VodPB)
	display.VodGameStart = h.printExternalLink(game.VodGameStart)
	display.VodPostgame = h.printExternalLink(game.VodPostgame)
	display.VodHighlights = h.printExternalLink(game.VodHighlights)
	display.Recap = h.printExternalLink(game.recap)
	display.VodInterview = h.printExternalLink(game.VodInterview)
	display.MatchHistory = h.printExternalLink(game.MatchHistory)
	display.MVP = util_esports.concatLinksFromStrings(game.MVPLink, game.MVP)
	display.InterviewWith = util_esports.concatLinksFromStrings(game.InterviewWithLinks, game.InterviewWith)
	return display
end

function h.printExternalLink(url)
	if not url then
		return nil
	end
	return ('[%s]'):format(url)
end

function h.splitGameArgs(row)
	return util_args.splitArgs(row, GAME_ARGS, arg_sep)
end

function h.addGameTotalScoreToMatchAndValidate(match_tbl, games_cargo, ignorewarnings)
	local team1 = match_tbl.Team1
	local team2 = match_tbl.Team2
	local matchScores = {
		[team1] = match_tbl.Team1Score,
		[team2] = match_tbl.Team2Score,
	}
	local gameScores = {
		[team1] = 0,
		[team2] = 0,
		hasTotals = false,
	}
	h.countGameScores(gameScores, games_cargo)
	if match_tbl.Winner then
		h.validateTotalScores(matchScores, gameScores, match_tbl, ignorewarnings)
	elseif gameScores.hasTotals then
		match_tbl.Team1Score = gameScores[team1]
		match_tbl.Team2Score = gameScores[team2]
	end
end

function h.countGameScores(gameScores, games_cargo)
	for _, game in ipairs(games_cargo) do
		local winKey = (game.Winner == '1' and 'Blue') or (game.Winner == '2' and 'Red')
		if winKey then
			gameScores.hasTotals = true
			local winTeam = game[winKey]
			gameScores[winTeam] = (gameScores[winTeam] or 0) + 1
		end
	end
end

function h.validateTotalScores(matchScores, gameScores, match_tbl, ignorewarnings)
	if not gameScores.hasTotals then return end
	if ignorewarnings then return end
	if match_tbl.FF then return end
	for team, v in pairs(matchScores) do
		v = v and tonumber(v)
		if gameScores[team] ~= v then
			error('Non-matching match & game scores for team ' .. team)
		end
	end
end

function h.printMatchRow(display_match, games)
	if not games then games = { {} } end
	local ngames = #games
	local tbl = mw.html.create()
	for i, game in ipairs(games) do
		local tr = tbl:tag('tr')
		if i == 1 then
			for _, v in ipairs(MATCH_FIELDS) do
				tr:tag('td'):attr('rowspan',ngames):wikitext(display_match[v])
			end
		end
		h.printGameRow(tr, game)
	end
	return tbl
end

function h.printGameRow(tr, game)
	for _, v in ipairs(GAME_FIELDS) do
		tr:tag('td'):wikitext(game[v])
	end
	return
end

return p