Edit the documentation or categories for this module. This module has an i18n file.
This module runs and makes the following hooks available:
- onMatchHistoryPlayerGetWhere - added by:
{{MVPHistory}}m
- onMatchHistoryPlayerGetJoin - added by:
{{MVPHistory}}m
- onMatchHistoryPlayerPrintColspanHeader - added by:
{{MVPHistory}}m
- onMatchHistoryPlayerGetTables - added by:
{{MVPHistory}}m
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require('Module:EsportsUtil')
local util_form = require('Module:FormUtil')
local util_game = require('Module:GameUtil')
local util_html = require('Module:HtmlUtil')
local util_map = require('Module:MapUtil')
local util_math = require('Module:MathUtil')
local util_sort = require('Module:SortUtil')
local util_stats = require('Module:StatsUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_time = require('Module:TimeUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local i18n = require('Module:i18nUtil')
local Sprite = require('Module:Sprite').sprite
local ChampionList = require('Module:ChampionList')
local RoleList = require('Module:RoleList')
local RegionList = require('Module:RegionList')
local Item = require('Module:Item')
local m_team = require('Module:Team')
local Stats = require('Module:ScoreboardPlayerStats')
local ColumnShowHide = require('Module:ColumnShowHide')
local ReplaceRedirects = require('Module:ReplaceRedirects')
local Hook = require('Module:Hook')
local SETTINGS = require('Module:MatchHistoryPlayer/Settings')
local PRELOAD
local DEFAULT_LIMIT = 50
local s = {}
function s.ItemSprite(id)
return Sprite{
id,
size = 25,
type = 'Item',
--nosize = true,
notext = true,
nolink = true
}
end
function s.SummonerSprite(id)
return Sprite{
id,
size = 25,
type = 'Summoner',
notext = true,
nolink = true
}
end
function s.KeystoneSprite(id)
return Sprite{
id,
size = 25,
type = 'Keystone',
notext = true,
nolink = true,
}
end
local h = {}
local p = {}
function p.main(frame)
local args = util_args.merge()
return p._main(args)
end
function p._main(args)
h.setPreloadAndValidate(args)
i18n.init('MatchHistoryPlayer')
local args2 = h.castArgs(args)
local data = h.getData(args2)
if util_args.castAsBool(args.textonly) then
h.formatDataText(data)
else
h.formatDataPretty(data)
end
return ReplaceRedirects.main(h.makeOutput(data, args, args2))
end
function h.setPreloadAndValidate(args)
local preload = h.getPreload(args.preload)
if args.preload == 'ChampionPlayerTournament' and not args.tournament then
args.preload = 'General'
PRELOAD = h.getPreload('General')
else
PRELOAD = preload
end
util_stats.validatePreload(args, PRELOAD)
end
function h.getPreload(str)
return SETTINGS.preloads[str:lower()]
end
function h.castArgs(args)
local args2 = mw.clone(args)
args2.role = RoleList(args2.role, {sep=','})
args2.champion = ChampionList(args2.champion)
args2.championvs = ChampionList(args2.championvs)
args2.region = RegionList(args2.region)
args2.item = Item(args2.item):get()
return args2
end
-- cargo
function h.getData(args)
local data = util_cargo.queryAndCast(h.getQuery(args))
return data
end
function h.getQuery(args)
return {
tables = h.getTables(args),
join = h.getJoin(args),
fields = h.getFields(args),
where = h.getWhere(args),
limit = h.getLimit(args),
orderBy = h.getOrderBy(args),
}
end
function h.getLimit(args)
return args.limit or DEFAULT_LIMIT
end
function h.getTables(args)
local ret = {
'ScoreboardGames=SG',
'Tournaments=IT',
'ScoreboardPlayers=SP',
'ScoreboardPlayers=SPVs',
'PlayerRedirects=PR',
}
Hook.run('onMatchHistoryPlayerGetTables', ret)
return ret
end
function h.getJoin(args)
local ret = {
'SG.GameId=SP.GameId',
'IT.OverviewPage=SG.OverviewPage',
'SP.UniqueRoleVs=SPVs.UniqueRole',
'SP.Link=PR.AllName',
}
Hook.run('onMatchHistoryPlayerGetJoin', ret)
return ret
end
function h.getFields(args)
local ret = {
'COALESCE(PR._pageName,SP.Link)=Link',
'SP.Name',
'SP.Team',
'SP.Champion',
'SP.Champion=TypedChampion [champion]',
'SP.Kills=K [number]',
'SP.Deaths=D [number]',
'SP.Assists=A [number]',
'SP.Gold=G [number]',
'SP.CS [number]',
'SP.IngameRole=Role',
'SP.IngameRole=TypedRole [role]',
'SP.Items__full=Items [list]',
'SP.Trinket',
'SP.TeamKills [number]',
'SP.TeamGold [number]',
'SP.DamageToChampions=DMG [number]',
'IT.StandardName=Tournament',
'SP.PlayerWin [boolean]',
'SP.GameId',
'SP._pageName',
'SG._pageName=_pageName2',
'SP.SummonerSpells__full=SummonerSpells',
'SP.KeystoneMastery',
'SP.KeystoneRune',
'SP.Side',
'SPVs.Champion=ChampionVs [champion]',
'SPVs.Link=LinkVs',
'SPVs.Name=NameVs',
'SPVs.CS=CSVs [number]',
'SPVs.Team=TeamVs',
'SG.Gamelength_Number=Len [number]',
'SG.Gamelength=LenDisplay',
'SG.DateTime_UTC=Date',
'SG.MatchHistory',
'SG.Patch',
'SG.VOD',
'SG.Team1Picks [championList]',
'SG.Team2Picks [championList]',
'IT.Region [region]',
'IT.Region=RegionPlaintext',
}
return ret
end
function h.getWhere(args)
local tbl = {
util_cargo.whereFromArg('(%s)', args.where),
util_cargo.whereFromArgList('SP.OverviewPage="%s"', args.tournament, nil, util_title.target),
h.getLinkWhereCondition(args.link),
util_cargo.whereFromArgList('SP.Team="%s"', args.team, nil, m_team.teamlinkname),
util_cargo.whereFromCompoundEntity('SP.Champion="%s"', args.champion),
util_cargo.whereFromCompoundEntity('SPVs.Champion="%s"', args.championvs),
util_cargo.whereFromCompoundEntity('SP.IngameRole="%s"', args.role),
util_cargo.whereFromCompoundEntity('IT.Region="%s"', args.region),
util_cargo.whereFromArgList('IT.Year="%s"', args.year),
util_cargo.whereFromArgList('IT.TournamentLevel="%s"', args.tournamentlevel),
args.jungleitem and util_cargo.fakeHolds('SP.Items', args.jungleitem .. ' - .*', ";"),
args.jungleenchant and util_cargo.fakeHolds('SP.Items', '.* - ' .. args.jungleenchant, ";"),
util_cargo.whereFromArgList('SP.KeystoneRune="%s"', args.rune),
util_cargo.whereFromArgList('SP.Trinket="%s"', args.trinket),
util_cargo.whereFromArgList('SG.Patch="%s"', args.patch),
}
if args.item and not util_table.nextNonFalse(tbl) then
tbl[#tbl+1] = ('SP.Items HOLDS "%s"'):format(args.item)
elseif args.item then
tbl[#tbl+1] = util_cargo.fakeHolds('SP.Items', args.item, ";")
end
Hook.run('onMatchHistoryPlayerGetWhere', tbl)
return util_cargo.concatWhere(tbl)
end
function h.getLinkWhereCondition(link)
if not link then return nil end
if mw.title.new(link, '').exists then
return util_cargo.whereFromArgList('PR._pageName="%s"', link, nil, util_title.target)
else
return util_cargo.whereFromArgList('SP.Link="%s"', link, nil, util_title.target)
end
end
function h.getOrderBy(args)
if args.orderBy then return args.orderBy end
if not args.record then
return PRELOAD.orderBy or 'SG.DateTime_UTC DESC'
end
if args.record:lower() == "kda" then
return ("(SP.Kills + SP.Assists) / (CASE WHEN SP.Deaths = 0 THEN 1 ELSE SP.Deaths END) DESC")
end
local order = util_args.castAsBool(args.recordorder) and 'ASC' or 'DESC'
return ('SP.%s %s'):format(args.record, order)
end
--format
function h.formatDataPretty(data)
for n, row in ipairs(data) do
h.formatRowPretty(row, n)
end
end
function h.formatRowPretty(row, n)
util_stats.infoLinks(row)
row.N = n
row.TournamentDisplay = util_stats.tournamentAndRegion(row)
row.ChampionDisplay = row.TypedChampion:image()
row.ChampionLong = row.TypedChampion:flair()
row.ChampionVsDisplay = row.ChampionVs:image()
row.attrs = {
ChampionVsDisplay = {
['data-sort-value'] = row.ChampionVs:get(),
},
ChampionDisplay = {
['data-sort-value'] = row.Champion,
},
CSDiff = {
['data-sort-value'] = row.CSVs and row.CS and row.CS - row.CSVs,
},
}
row.Items = h.concatItemsPretty(row)
row.CSDiff = row.CSVs and row.CS and util_esports.diff(row.CS - row.CSVs)
row.Result = row.PlayerWin and 'Win' or 'Loss'
row.class = row.PlayerWin and 'winner' or 'loser'
row.TeamDisplay = m_team.onlyimagelinked(row.Team)
row.TeamVs = m_team.onlyimagelinked(row.TeamVs)
row.Patch = row.Patch and util_text.intLink('Patch ' .. row.Patch, row.Patch)
h.getKDA(row)
row.Date = util_time.strToDateStr(row.Date)
row.Spells = h.getSpellsPretty(row)
row.Player = util_text.intLink(row.Link, row.Name)
row.ChampionList = h.getChampionsPretty(row, row.Side)
row.ChampionListVs = h.getChampionsPretty(row, util_esports.otherTeamN(row.Side))
row.RoleDisplay = row.TypedRole:get('short')
row.Side = util_game.side_names[row.Side]
row.GoldDisplay = util_math.roundedThousands(row.G)
row.DmgDisplay = util_math.roundedThousands(row.DMG)
end
function h.concatItemsPretty(row)
local tbl = {
util_table.concat(util_map.arrayInPlace(row.Items, s.ItemSprite), ""),
row.Trinket and s.ItemSprite(row.Trinket)
}
return util_table.concat(tbl, ' ')
end
function h.getKDA(row)
local function tryKDA()
row.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
end
if pcall(tryKDA) then
return
else
error(i18n.print('error_kda', row._pageName or row._pageName2 or '???'))
end
end
function h.getSpellsPretty(row)
local tbl = {
util_map.splitAndConcat(row.SummonerSpells, nil, s.SummonerSprite),
row.KeystoneRune and s.KeystoneSprite('Rune ' .. row.KeystoneRune),
row.KeystoneMastery and s.KeystoneSprite('Mastery ' .. row.KeystoneMastery),
}
util_table.removeFalseEntries(tbl, 3)
return util_table.concat(tbl, '', nil)
end
function h.getChampionsPretty(row, N)
return row['Team' .. N .. 'Picks']:images()
end
function h.formatDataText(data)
for n, row in ipairs(data) do
h.formatRowText(row, n)
end
end
function h.formatRowText(row, n)
row.N = n
row.TournamentDisplay = row.Region:name() .. ',' .. row.Tournament
row.ChampionDisplay = row.TypedChampion:name()
row.ChampionLong = row.TypedChampion:name()
row.ChampionVsDisplay = row.ChampionVs:name()
row.CSDiff = row.CSVs and row.CS and util_esports.diff(row.CS - row.CSVs)
row.Result = row.PlayerWin and 'Win' or 'Loss'
row.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
row.Spells = h.getSpellsText(row)
row.Items = h.concatItemsText(row)
row.Player = row.Link
row.ChampionList = row['Team' .. row.Side .. 'Picks']:names()
row.ChampionListVs = row['Team' .. util_esports.otherTeamN(row.Side) .. 'Picks']:names()
row.Scoreboard = util_text.intLink(row._pageName, 'SB')
row.Side = util_game.side_names[row.Side]
row.TeamDisplay = row.Team
end
function h.concatItemsText(row)
local tbl = {
util_table.concat(row.Items),
row.Trinket
}
return util_table.concat(tbl, ' ')
end
function h.getSpellsText(row)
local tbl = {
row.SummonerSpells,
row.KeystoneRune,
row.KeystoneMastery,
}
return util_table.concat(tbl, '', nil, 3)
end
-- print
function h.makeOutput(data, args, args2)
local output = h.initializeOutput()
ColumnShowHide.printToggles(output, PRELOAD.headings)
local tbl = h.initializeTable(output, args)
ColumnShowHide.printTableClass(tbl)
h.printColspanHeader(tbl, args)
h.printHeadings(tbl)
util_html.printEmptySortRow(tbl, #PRELOAD.headings)
h.printRows(tbl, data)
h.printStats(tbl, data, args, #PRELOAD.headings)
h.printPermalink(output, args, args2)
return output
end
function h.initializeOutput()
local output = mw.html.create('div')
:addClass('wide-content-scroll')
return output
end
function h.initializeTable(output, args)
local tbl = output:tag('div'):addClass('wide-content-scroll'):tag('table')
:addClass('wikitable mhplayer sortable plainlinks hoverable-rows')
if args.record then
tbl:addClass(h.getClassName('record-' .. args.record:lower()))
end
return tbl
end
function h.printColspanHeader(tbl, args)
if PRELOAD.noheading then return end
if not Hook.run('onMatchHistoryPlayerPrintColspanHeader', tbl, #PRELOAD.headings) then return end
local displayTbl = {
util_stats.heading(args, 'MatchHistoryPlayer', h.getLimit(args)),
util_stats.openAsQueryLink(SETTINGS.form_info, args)
}
util_html.printColspanHeader(tbl, util_table.concat(displayTbl, ' - '), #PRELOAD.headings)
end
function h.printHeadings(tbl)
local tr = tbl:tag('tr')
:addClass(h.getClassName('headings'))
for _, col in ipairs(PRELOAD.headings) do
local th = tbl:tag('th')
:wikitext(i18n.print(col))
util_html.printCellAttrs(th, SETTINGS, col)
end
end
function h.printRows(tbl, data)
for _, row in ipairs(data) do
local tr = tbl:tag('tr')
tr:addClass(h.getClassName(row.class))
h.printOneRow(tr, row)
end
end
function h.printOneRow(tr, row)
for _, col in ipairs(PRELOAD.headings) do
local td = tr:tag('td')
:addClass(h.getClassFromCol(col))
:wikitext(row[col])
util_html.printCellAttrs(td, row, col)
end
end
function h.getClassFromCol(col)
return h.getClassName(SETTINGS.classes[col])
end
function h.getClassName(str)
if not str then return nil end
return 'mhplayer-' .. str
end
function h.printStats(tbl, data, args, colspan)
if PRELOAD.nostats or util_args.castAsBool(args.nostats) then return end
local statsArgs = h.getArgsForStats(args)
if statsArgs.preload == 'CPTMH' then
local StatsTable = util_html.innerColspanTable(tbl, colspan)
Stats:CPTMH(StatsTable, data, statsArgs)
else
local statsCell = util_html.innerColspanCellOnly(tbl, colspan)
Stats:printOutputFromData(statsCell, data, statsArgs)
end
end
function h.getArgsForStats(args)
local statsArgs = mw.clone(args)
statsArgs.hidetournamentlist = util_args.boolToStringYN(true)
statsArgs.preload = h.guessStatsPreload(statsArgs)
statsArgs.class = 'nested-table'
statsArgs.spl = false
return statsArgs
end
function h.guessStatsPreload(statsArgs)
if not statsArgs.tournament then
return 'ByTournament'
elseif statsArgs.link and statsArgs.champion then
return 'CPTMH'
elseif statsArgs.link then
return 'PlayerByChampion'
elseif statsArgs.champion then
return 'ChampionByPlayer'
else
return 'ByTournament'
end
end
function h.printPermalink(output, args, args2)
if not util_args.castAsBool(args.spl) then return end
util_form.permalink(output, args, SETTINGS.form_info)
output:tag('hr')
output:wikitext(i18n.print('debugInfo'))
output:wikitext(h.getWhere(args2))
util_form.printLog(output)
end
return p