Module:Match/Dota: Difference between revisions

From TwogPedia
mNo edit summary
mNo edit summary
Line 96: Line 96:
local results = cargo.query(tables, fields, cargoArgs)
local results = cargo.query(tables, fields, cargoArgs)
if #results == 0 then
if #results == 0 then
local mapData = mw.ext.externaldata.getWebData({
        local mapData = mw.ext.externaldata.getWebData({
format = 'json',
        url = 'https://api.opendota.com/api/matches/' .. map.id,
    url = 'https://api.opendota.com/api/matches/' .. map.id
format = 'CSV with header',
})
})
             
if mapData.__json.picks_bans then
if mapData then
local pickBans = mapData.__json.picks_bans
local json = mw.text.jsonDecode(mapData.__text)
local pickBans = json.picks_bans
map.p1picks = ''
map.p1picks = ''
map.p2picks = ''
map.p2picks = ''
Line 124: Line 124:
                map.p1bans = removeEndComma(map.p1bans)
                map.p1bans = removeEndComma(map.p1bans)
                map.p2bans = removeEndComma(map.p2bans)
                map.p2bans = removeEndComma(map.p2bans)
                 
                -- Check if dire team had api_id entered
                local dire_id = mapData.__json.dire_team_id
                local dire_id = json.dire_team_id
               
                local dire = dire_id == tonumber(p1_api) and 1 or dire_id == tonumber(p2_api) and 2 or nil
                local dire = dire_id == p1_api and 1 or dire_id == 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_id = json.radiant_team_id
                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
                -- set winner
                -- if json.radiant_win then
                -- map.winner = dire == 1 and 2 or 1
                -- else
                -- map.winner = dire == 1 and 1 or 2
                -- end
 
                if not map.dire and dire then
                if not map.dire and dire then
map.dire = dire
map.dire = dire
Line 138: Line 150:
                end
                end
                end
                end
                local radiantKills = mapData.__json.radiant_score
                local radiantKills = json.radiant_score
                local direKills = mapData.__json.dire_score
                local direKills = json.dire_score
                if not map.p1kills then
                if not map.p1kills then
                map.p1kills = dire == 1 and direKills or radiantKills
                map.p1kills = dire == 1 and direKills or radiantKills
Line 147: Line 159:
                end
                end
                 
                 
local duration = mapData.__json.duration
local duration = json.duration
local seconds = duration % 60
local seconds = duration % 60
Line 174: Line 186:
frame:callParserFunction{name = '#cargo_store:', args = {_table = 'Maps_Dota', map=i, api_id = map.id, matchID = results[1]._ID, duration = map.duration, p1picks = map.p1picks, p2picks = map.p2picks, p1bans = map.p1bans, p2bans = map.p2bans, dire = map.dire, fp = map.fp, winner = map.winner, p1kills = map.p1kills, p2kills = map.p2kills, yt = map.yt, vod = map.vod}}
frame:callParserFunction{name = '#cargo_store:', args = {_table = 'Maps_Dota', map=i, api_id = map.id, matchID = results[1]._ID, duration = map.duration, p1picks = map.p1picks, p2picks = map.p2picks, p1bans = map.p1bans, p2bans = map.p2bans, dire = map.dire, fp = map.fp, winner = map.winner, p1kills = map.p1kills, p2kills = map.p2kills, yt = map.yt, vod = map.vod}}
 
DotaMatch.main(map, hover, i, results)
DotaMatch.main(map, hover, i, results)
end
end

Revision as of 21:33, 18 October 2023

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

local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo
local html = require('Module:MatchHTML')
local DotaMatch = {}
local heroesData = mw.loadData('Module:Data/Dota/Heroes')

local VariablesLua = mw.ext.VariablesLua
-- add picks/bans to hover 
function DotaMatch.main(map, hover, i)
	local mapHeader = mw.html.create('div'):wikitext('Map ' .. i .. ' '):attr('style', 'font-size: 0.9rem;')
	-- VODs etc
	if map.yt then
		mapHeader:wikitext('[[File:Youtube.png|20x20px|https://www.youtube.com/watch?v=' .. map.yt .. ']]')
	end
	if map.id then
		mapHeader:wikitext('[[File:Dotabuff.png|20x20px|https://www.dotabuff.com/matches/' .. map.id .. ']]')
		mapHeader:wikitext('[[File:Datdota.png|20x20px|https://www.datdota.com/matches/' .. map.id .. ']]')
		mapHeader:wikitext('[[File:Stratz.png|20x20px|https://stratz.com/matches/' .. map.id .. ']]')
	end

	hover:node(mapHeader)
	local dire = map.dire or 'unknown'
	local picks = mw.html.create('div'):addClass('details-game')
	local p1picks = mw.html.create('div'):addClass(dire == '1' and 'details-picks dire' or 'details-picks radiant')
	local p2picks = mw.html.create('div'):addClass(dire == '2' and 'details-picks dire' or 'details-picks radiant')
	local iconSize = '28px'
	-- Loop through first teams picks
	if map.p1picks then
		local p1picksSplit = mw.text.split(map.p1picks, ',')
		for j = 1, #p1picksSplit do
			local hero = getHero(mw.text.trim(p1picksSplit[j]))
			--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
			p1picks:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
		end
	end
	
	-- create the duration/winner part
	local duration = mw.html.create('div'):addClass('details-duration')
		:node(mw.html.create('div'):wikitext(map.winner == '1' and 'W' or ''))
		:node(mw.html.create('div'):node(mw.html.create('abbr'):attr('title', 'Map duration'):wikitext(map.duration)))
		:node(mw.html.create('div'):wikitext(map.winner == '2' and 'W' or ''))

	-- Loop through second teams picks
	if map.p2picks then
		local p2picksSplit = mw.text.split(map.p2picks, ',')
		for j = 1, #p2picksSplit do
			local hero = getHero(mw.text.trim(p2picksSplit[j]))
			--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
			p2picks:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
		end
	end
	hover:node(picks:node(p1picks):node(duration):node(p2picks))

	local bans = mw.html.create('div'):addClass('details-game')
	local p1bans = mw.html.create('div'):addClass('details-picks'):addClass( dire == '1' and 'details-picks dire' or 'details-picks radiant')
	local p2bans = mw.html.create('div'):addClass('details-picks'):addClass( dire == '2' and 'details-picks dire' or 'details-picks radiant')
	
	-- Loop through first teams bans
	if map.p1bans then
		local p1bansSplit = mw.text.split(map.p1bans, ',')
		for j = 1, #p1bansSplit do
			local hero = getHero(mw.text.trim(p1bansSplit[j]))
			--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
			p1bans:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
		end
	end
		
	-- Loop through second teams bans
	if map.p2bans then
		local p2bansSplit = mw.text.split(map.p2bans, ',')
		for j = 1, #p2bansSplit do
			local hero = getHero(mw.text.trim(p2bansSplit[j]))
			--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
			p2bans:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
		end
	end
	
	hover:node(bans:node(mw.html.create('div'):addClass('w-100'):wikitext('Bans')):node(mw.html.create('div'):addClass('w-100'):node(p1bans):node(p2bans)))
	
	
	return ''
end

function DotaMatch.picksBans(maps, p1_api, p2_api, hover, results, frame)
	if #maps > 0 then
		for i = 1, #maps do
			local map = maps[i]
			if map.id and map.winner and not map.p1picks and not map.p1bans then
				local tables = 'Maps_Dota'
				local fields = 'winner, p1picks, p2picks, p1bans, p2bans, dire, fp, p1kills, p2kills, duration'
				local whereStr = 'api_id="' .. map.id .. '" AND winner IS NOT NULL'
			
				local cargoArgs = {
					where = whereStr
				}
				
				local results = cargo.query(tables, fields, cargoArgs)
				if #results == 0 then
			        local mapData = mw.ext.externaldata.getWebData({
			        	url = 'https://api.opendota.com/api/matches/' .. map.id,
						format = 'CSV with header',
					})
              
					if mapData then
						local json = mw.text.jsonDecode(mapData.__text)
						local pickBans = json.picks_bans
						map.p1picks = ''
						map.p2picks = ''
						map.p1bans = ''
						map.p2bans = ''
						local fp = nil
						for j = 1, #pickBans do
							local selection = pickBans[j]
							if j == 1 then fp = selection.team end
							if selection.is_pick then 
								map['p' .. selection.team + 1 .. 'picks'] = map['p' .. selection.team + 1 .. 'picks'] .. getHero(selection.hero_id) .. ','
							else
								map['p' .. selection.team + 1 .. 'bans'] = 	map['p' .. selection.team + 1 .. 'bans'] .. getHero(selection.hero_id) .. ','
							end
						end
		                
			            map.p1picks = removeEndComma(map.p1picks)
		                map.p2picks = removeEndComma(map.p2picks)
		                map.p1bans = removeEndComma(map.p1bans)
		                map.p2bans = removeEndComma(map.p2bans)
		                -- Check if dire team had api_id entered
		                local dire_id = json.dire_team_id
		                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_id = json.radiant_team_id
		                	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
		                -- set winner
		                -- if json.radiant_win then 
		                -- 	map.winner = dire == 1 and 2 or 1
		                -- else
		                -- 	map.winner = dire == 1 and 1 or 2
		                -- end

		                if not map.dire and dire then
							map.dire = dire
		                end
		                if not map.fp and fp ~= nil then
		                	if fp == 0 then
		                		map.fp = dire == 1 and 2 or 1
		                	else
		                		map.fp = dire
		                	end
		                end
		                local radiantKills = json.radiant_score
		                local direKills = json.dire_score
		                if not map.p1kills then
		                	map.p1kills = dire == 1 and direKills or radiantKills
		                end
		                if not map.p2kills then
		                	map.p2kills = dire == 2 and direKills or radiantKills
		                end
		                
						local duration = json.duration
						local seconds = duration % 60
						
						local minutes = (duration - seconds) / 60
						if seconds < 10 then seconds = "0" .. tostring(seconds) end
						map.duration = minutes .. ':' .. seconds
					end
				else
					map.p1picks = results[1].p1picks
					map.p2picks = results[1].p2picks
					map.p1bans = results[1].p1bans
					map.p2bans = results[1].p2bans
					map.dire = results[1].dire
					map.fp = results[1].fp
					map.p1kills = results[1].p1kills
					map.p2kills = results[1].p2kills
					map.duration = results[1].duration
				end
			else 
				-- Go through normal picks and bans and turn them into proper hero names
				if map.p1picks then listToNames(map, map.p1picks, "p1picks")end
				if map.p2picks then listToNames(map, map.p2picks, "p2picks")end
				if map.p1bans then listToNames(map, map.p1bans, "p1bans")end
				if map.p2bans then listToNames(map, map.p2bans, "p2bans")end
			end
			
			frame:callParserFunction{name = '#cargo_store:', args = {_table = 'Maps_Dota', map=i, api_id = map.id, matchID = results[1]._ID, duration = map.duration, p1picks = map.p1picks, p2picks = map.p2picks, p1bans = map.p1bans, p2bans = map.p2bans, dire = map.dire, fp = map.fp, winner = map.winner, p1kills = map.p1kills, p2kills = map.p2kills, yt = map.yt, vod = map.vod}}

			DotaMatch.main(map, hover, i, results)
		end
    	
	end
	return map
end

function listToNames(map, list, var)
	local split = mw.text.split(list, ',')
	map[var] = ''

	for i = 1, #split do 
		map[var] = map[var] .. getHero(mw.text.trim(split[i])) .. ','
        map[var] = removeEndComma(map[var])
	end
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 removeEndComma(inputString)
    -- Use the string.match function to check if the string ends with a comma
    if inputString:match(",$") then
        -- If it does, use string.sub to remove the last character (the comma)
        return inputString:sub(1, -2)
    else
        -- If not, return the input string as it is
        return inputString
    end
end

return DotaMatch