Documentation for this module may be created at Module:MapData/doc
local cargo = mw.ext.cargo
local getArgs = require('Module:Arguments').getArgs
local heroesData = mw.loadData('Module:Data/Dota/Heroes')
local p = {}
function p.main(frame)
local args = getArgs(frame)
local game = args.game
if args.size == 'team' then
local p1_api = getTeamPage(args.p1, game)
local p2_api = getTeamPage(args.p2, game)
local warnings = mw.html.create('div')
local container = mw.html.create('div'):node(warnings)
local output = mw.html.create('div')
if not p1_api and not p2_api then warnings:wikitext('Neither team has their api entered in their infobox. The Map/Dota string will need manual entry for more or less everything') end
if game == 'Dota2' then
local str = ''
local mapData = mw.ext.externaldata.getWebData({
url = 'https://api.opendota.com/api/matches/' .. args.api,
format = 'CSV with header',
})
if mapData then
local json = mw.text.jsonDecode(mapData.__text)
local pickBans = json.picks_bans
local radiantPicks = {}
local direPicks = {}
local radiantBans = {}
local direBans = {}
local radiantPlayers = {}
local direPlayers = {}
local players = json.players
local fp = nil
for j = 1, #pickBans do
local selection = pickBans[j]
-- If first ban, then set if fp is radiant (0) or dire (1)
if j == 1 then fp = selection.team end
if selection.is_pick then
if selection.team == 0 then
table.insert(radiantPlayers, getPlayer(players, selection.hero_id))
table.insert(radiantPicks, getHero(selection.hero_id))
else
table.insert(direPlayers, getPlayer(players, selection.hero_id))
table.insert(direPicks, getHero(selection.hero_id))
end
else
if selection.team == 0 then
table.insert(radiantBans, getHero(selection.hero_id))
else
table.insert(direBans, getHero(selection.hero_id))
end
end
end
-- Check if dire team had api_id entered
local dire_id = json.dire_team_id
local radiant_id = json.radiant_team_id
if tonumber(p1_api) ~= dire_id and tonumber(p1_api) ~= radiant_id then warnings:wikitext(args.p1 .. ' does not have an api_id entered') end
if tonumber(p2_api) ~= dire_id and tonumber(p2_api) ~= radiant_id then warnings:wikitext(args.p2 .. ' does not have an api_id entered') end
local dire = dire_id == tonumber(p1_api) and 1 or dire_id == tonumber(p2_api) and 2 or nil
-- If dire team doesn't have api_id entered, then check if maybe radiant does
if dire == nil then
local radiant = radiant_id == tonumber(p1_api) and 1 or radiant_id == tonumber(p2_api) and 2 or nil
if radiant then dire = radiant == 1 and 2 or 1 end
end
local duration = json.duration
local seconds = duration % 60
local minutes = (duration - seconds) / 60
if seconds < 10 then seconds = "0" .. tostring(seconds) end
local duration = minutes .. ':' .. seconds
-- If neither team had api, then spell out which team did what and user has to manually assign
if dire == nil then
local radiant_team = json.radiant_team
local radiant_name = radiant_team.name
local radiant_api = radiant_team.team_id
local radiantStr = 'Radiant side is team ' .. radiant_name .. ' with API_ID: ' .. radiant_api
local dire_team = json.dire_team
local dire_name = dire_team.name
local dire_api = dire_team.team_id
local radiantTh = mw.html.create('th'):wikitext(radiant_name)
local direTh = mw.html.create('th'):wikitext(dire_name)
local header = mw.html.create('tr'):addClass('headerRow'):node(radiantTh):node(direTh)
local picksRow = mw.html.create('tr'):addClass('bodyRow'):node(td(table.concat(radiantPicks, ','))):node(td(table.concat(direPicks, ',')))
local playersRow = mw.html.create('tr'):addClass('bodyRow'):node(td(table.concat(radiantPlayers, ','))):node(td(table.concat(direPlayers, ',')))
local bansRow = mw.html.create('tr'):addClass('bodyRow'):node(td(table.concat(radiantBans, ','))):node(td(table.concat(direBans, ',')))
local apiRow = mw.html.create('tr'):addClass('bodyRow'):node(td(radiant_api)):node(td(dire_api))
local side = mw.html.create('tr'):addClass('bodyRow'):node(td('Radiant')):node(td('Dire'))
local fpRow = mw.html.create('tr'):addClass('bodyRow')
local winRow = mw.html.create('tr'):addClass('bodyRow')
local killRow = mw.html.create('tr'):addClass('bodyRow'):node(td(json.radiant_score .. ' kills')):node(td(json.dire_score .. ' kills'))
local teamTable = mw.html.create('table'):addClass('striped-table'):node(header):node(side):node(apiRow):node(fpRow):node(winRow):node(killRow):node(picksRow):node(playersRow):node(bansRow)
if fp == 0 then
fpRow:node(td('First pick'))
else
fpRow:node(td('')):node(td('First pick'))
end
if json.radiant_win then
winRow:node(td('Winner'))
else
winRow:node(td('')):node(td('Winner'))
end
container:node(teamTable)
str = '|winner=|dire=|fp=|p1picks=|p1players=|p2picks=|p2players=|p1bans=|p2bans=|p1kills=|p2kills=' .. '|duration=' .. duration
else
-- set winner
local winner = nil
if json.radiant_win then
winner = dire == 1 and 2 or 1
else
winner = dire == 1 and 1 or 2
end
if fp ~= nil then
if fp == 0 then
fp = dire == 1 and 2 or 1
else
fp = dire
end
end
local radiantKills = json.radiant_score
local direKills = json.dire_score
local p1kills = dire == 1 and direKills or radiantKills
local p2kills = dire == 2 and direKills or radiantKills
local p1picks = dire == 1 and table.concat(direPicks, ',') or table.concat(radiantPicks, ',')
local p2picks = dire == 2 and table.concat(direPicks, ',') or table.concat(radiantPicks, ',')
local p1bans = dire == 1 and table.concat(direBans, ',') or table.concat(radiantBans, ',')
local p2bans = dire == 2 and table.concat(direBans, ',') or table.concat(radiantBans, ',')
local p1players = dire == 1 and table.concat(direPlayers, ',') or table.concat(radiantPlayers, ',')
local p2players = dire == 2 and table.concat(direPlayers, ',') or table.concat(radiantPlayers, ',')
str = '|winner=' .. winner .. '|dire=' .. dire .. '|fp=' .. fp .. '|p1picks=' .. p1picks .. '|p1players=' .. p1players .. '|p2picks=' .. p2picks.. '|p2players=' .. p2players .. '|p1bans=' .. p1bans .. '|p2bans=' .. p2bans .. str .. '|p1kills=' .. p1kills .. '|p2kills=' .. p2kills .. '|duration=' .. duration
end
else
output:wikitext('No match found. It has to be finished before data can be fetched')
end
str = '{{Map/Dota|id=' .. args.api .. str .. '|yt=}}'
output:wikitext(str)
end
return container:node(output)
else
end
end
function getPlayer(tbl, hero_id)
for _, player in pairs(tbl) do
-- Check if the current player's hero_id matches the target hero_id
if player.hero_id == hero_id then
-- Found the player with the desired hero_id
local tables = 'People'
local fields = '_pageName'
local cargoArgs = {
where = 'api_id="' .. player.account_id .. '"'
}
local results = cargo.query(tables, fields, cargoArgs)
if #results > 0 then
return results[1]._pageName
else
-- local player = mw.ext.externaldata.getWebData({
-- url = 'https://api.opendota.com/api/players/' .. player.account_id,
-- format = 'CSV with header',
-- })
-- if player then
-- return player.__text.profile.name
-- else
return player.account_id
-- end
end
end
end
end
function td (value)
return mw.html.create('td'):wikitext(value)
end
function getHero(idOrName)
if type(idOrName) == "string" then idOrName = string.lower(idOrName) end
for _, hero in ipairs(heroesData) do
if hero.id == idOrName then
return hero.localized_name
else
for _, name in ipairs(hero.names) do
if name == idOrName then
return hero.localized_name
end
end
end
end
return "Hero not found " .. idOrName
end
function getTeamPage(team, game)
-- Check if shorthand of a team was used
local tables = 'Teams'
local fields = '_pageName, shorthand, api_id'
local cargoArgs = {
where = 'api_id IS NOT NULL AND _pageName LIKE "' .. game .. '/%" AND ( shorthand = "' .. team .. '" OR _pageName="' .. game .. '/' .. team .. '")'
}
local results = cargo.query(tables, fields, cargoArgs)
return #results > 0 and results[1].api_id or nil
end
return p