Module:Player
From eSportsAmaze
More actions
Documentation for this module may be created at Module:Player/doc
local p = {}
local cargo = mw.ext.cargo
local html = mw.html
-- ============================================================
-- HELPER FUNCTIONS
-- ============================================================
-- Currency Formatter
local function formatCurrency(amount)
if not amount then return "0" end
local n = tonumber(amount) or 0
local formatted = tostring(n):reverse():gsub("(%d%d%d)(%d%d%d)","%1,%2"):reverse()
return '<span class="indian-currency">₹ ' .. formatted .. '</span>'
end
-- Social Icons
local function getSocials(args)
local container = html.create('div'):addClass('fib-socials')
local hasSocials = false
local platforms = {
{arg='instagram', file='Icon_instagram.png'},
{arg='twitter', file='Icon_twitter.png'},
{arg='youtube', file='Icon_youtube.png'},
{arg='discord', file='Icon_discord.png'},
{arg='facebook', file='Icon_facebook.png'}
}
for _, p in ipairs(platforms) do
if args[p.arg] and args[p.arg] ~= "" then
hasSocials = true
container:wikitext('[[File:' .. p.file .. '|24px|link=' .. args[p.arg] .. '|class=social-img]]')
end
end
if hasSocials then return tostring(container) else return "" end
end
-- [[ FIX: ROBUST RANK LOOKUP ]]
-- Checks BOTH "Players/Jonathan" AND "Jonathan"
local function getKraftonRank(fullPageName, displayName)
local sqlFull = fullPageName:gsub("'", "\\'")
local sqlShort = displayName:gsub("'", "\\'")
local whereClause = string.format("(name = '%s' OR name = '%s') AND type='Player'", sqlFull, sqlShort)
local results = cargo.query("Krafton_Rankings", "rank", { where = whereClause, limit = 1 })
if results and #results > 0 then
return "#" .. results[1].rank
else
return "Unranked"
end
end
-- ============================================================
-- MAIN 1: PLAYER INFOBOX (WITH RANK FIX)
-- ============================================================
function p.infobox(frame)
local args = frame:getParent().args
-- Variables
local fullPageName = mw.title.getCurrentTitle().text -- Players/Jonathan
local displayName = args.id or mw.title.getCurrentTitle().subpageText -- Jonathan
local image = args.image or ""
local root = html.create('div'):addClass('flat-infobox')
-- 1. Header
root:tag('div'):addClass('fib-header')
:tag('div'):addClass('fib-title'):wikitext(displayName)
-- 2. Image
local imgContainer = root:tag('div'):addClass('fib-image')
if image ~= "" then
imgContainer:wikitext('[[File:' .. image .. '|250px]]')
else
imgContainer:wikitext('[[File:Player_Placeholder.png|200px|link=]]')
end
-- 3. EARNINGS CALCULATION (Robust)
local totalEarnings = 0
local sqlNameFull = fullPageName:gsub("'", "\\'")
local sqlNameShort = displayName:gsub("'", "\\'")
-- PART A: INDIVIDUAL AWARDS
if cargo and cargo.query then
local pWhere = string.format("(player = '%s' OR player = '%s')", sqlNameFull, sqlNameShort)
local pResults = cargo.query("PrizeMoney", "SUM(prize)=total", { where = pWhere })
if pResults and #pResults > 0 and pResults[1].total then
totalEarnings = totalEarnings + (tonumber(pResults[1].total) or 0)
end
end
-- PART B: TEAM WINNINGS (Verified via Roster)
if cargo and cargo.query then
local rosterTable = "Tournament_Teams"
local rosterFields = "tournament, team"
local rosterWhere = string.format(
"p1='%s' OR p1='%s' OR p2='%s' OR p2='%s' OR p3='%s' OR p3='%s' OR p4='%s' OR p4='%s' OR p5='%s' OR p5='%s' OR p6='%s' OR p6='%s'",
sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort,
sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort
)
local participation = cargo.query(rosterTable, rosterFields, { where = rosterWhere, limit=500 })
if participation and #participation > 0 then
local prizeConditions = {}
for _, row in ipairs(participation) do
if row.tournament and row.team then
table.insert(prizeConditions, string.format("(tournament='%s' AND team='%s')", row.tournament:gsub("'", "\\'"), row.team:gsub("'", "\\'")))
end
end
if #prizeConditions > 0 then
local complexWhere = "(" .. table.concat(prizeConditions, " OR ") .. ") AND (player='' OR player IS NULL)"
local teamPrizes = cargo.query("PrizeMoney", "SUM(prize)=team_total", { where = complexWhere })
if teamPrizes and #teamPrizes > 0 and teamPrizes[1].team_total then
totalEarnings = totalEarnings + (tonumber(teamPrizes[1].team_total) or 0)
end
end
end
end
-- 4. Status & Rank Grid
local statusColor = "#333"
local statusText = args.status or "Active"
if args.status then
local s = args.status:lower()
if s == "active" then statusColor = "#16a34a"
elseif s == "inactive" or s == "banned" or s == "retired" then statusColor = "#dc2626"
end
end
local grid1 = root:tag('div'):addClass('fib-grid')
grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Status'):done():tag('div'):addClass('fib-value-sm'):css('color', statusColor):wikitext(statusText):done()
-- [[ FIX: PASS BOTH NAMES TO RANK FUNCTION ]]
local rankVal = getKraftonRank(fullPageName, displayName)
grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Krafton Rank'):done():tag('div'):addClass('fib-value-sm'):wikitext(rankVal):done()
-- 5. Role & Nation Grid
local grid2 = root:tag('div'):addClass('fib-grid')
grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Nationality'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.nationality or 'India'):done()
grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Role'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.role or 'Player'):done()
-- 6. Earnings (Highlight)
if totalEarnings > 0 then
root:tag('div'):addClass('fib-prize')
:tag('div'):addClass('fib-label-sm'):wikitext('Approx. Earnings'):done()
:tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(totalEarnings)):done()
end
-- 7. Info List
local list = root:tag('div'):addClass('fib-list')
local function addRow(label, value)
if value and value ~= "" then
list:tag('div'):addClass('fib-row'):tag('div'):addClass('fib-label'):wikitext(label):done():tag('div'):addClass('fib-data'):wikitext(value):done()
end
end
addRow('Real Name', args.real_name)
addRow('Born', args.birth_date)
if args.current_team then
addRow('Current Team', '[[' .. args.current_team .. ']]')
end
addRow('Game', args.game or "BGMI")
-- 8. Team History
local history = cargo.query("Player_Former_Teams", "team, join_date, leave_date", {
where = "player_id = '" .. fullPageName:gsub("'", "\\'") .. "'",
orderBy = "join_date DESC",
limit = 10
})
if #history > 0 then
list:tag('div'):addClass('fib-header'):css('font-size','0.95em'):css('padding','10px'):css('margin-top','15px'):css('border-radius','6px'):wikitext('Team History')
local histTable = list:tag('table'):css('width','100%'):css('font-size','0.9em'):css('border-collapse','collapse'):css('margin-top','5px')
for _, hRow in ipairs(history) do
local tr = histTable:tag('tr'):css('border-bottom','1px solid #e2e8f0')
tr:tag('td'):css('padding','8px 4px'):css('font-weight','600'):wikitext('[[' .. hRow.team .. ']]')
local dates = (hRow.join_date and mw.getContentLanguage():formatDate('M y', hRow.join_date) or '?') .. ' – ' .. (hRow.leave_date and mw.getContentLanguage():formatDate('M y', hRow.leave_date) or 'Now')
tr:tag('td'):css('text-align','right'):css('padding','8px 4px'):css('color','#64748b'):wikitext(dates)
end
else
local historyShort = cargo.query("Player_Former_Teams", "team, join_date, leave_date", {
where = "player_id = '" .. displayName:gsub("'", "\\'") .. "'",
orderBy = "join_date DESC",
limit = 10
})
if #historyShort > 0 then
list:tag('div'):addClass('fib-header'):css('font-size','0.95em'):css('padding','10px'):css('margin-top','15px'):css('border-radius','6px'):wikitext('Team History')
local histTable = list:tag('table'):css('width','100%'):css('font-size','0.9em'):css('border-collapse','collapse'):css('margin-top','5px')
for _, hRow in ipairs(historyShort) do
local tr = histTable:tag('tr'):css('border-bottom','1px solid #e2e8f0')
tr:tag('td'):css('padding','8px 4px'):css('font-weight','600'):wikitext('[[' .. hRow.team .. ']]')
local dates = (hRow.join_date and mw.getContentLanguage():formatDate('M y', hRow.join_date) or '?') .. ' – ' .. (hRow.leave_date and mw.getContentLanguage():formatDate('M y', hRow.leave_date) or 'Now')
tr:tag('td'):css('text-align','right'):css('padding','8px 4px'):css('color','#64748b'):wikitext(dates)
end
end
end
-- 9. Socials
root:wikitext(getSocials(args))
return tostring(root)
end
-- ============================================================
-- MAIN 2: FORMER PLAYERS TABLE (For Team Pages)
-- ============================================================
function p.formerPlayers(frame)
local args = frame:getParent().args
local team = args.team or mw.title.getCurrentTitle().text
local results = cargo.query("Player_Former_Teams, Players", "Player_Former_Teams.player_id=id, Players.real_name=Name, Player_Former_Teams.role=role, Player_Former_Teams.join_date=join_date, Player_Former_Teams.leave_date=leave_date", {
joinOn = "Player_Former_Teams.player_id = Players._pageName",
where = "Player_Former_Teams.team = '" .. team:gsub("'", "\\'") .. "' AND Player_Former_Teams.leave_date != ''",
orderBy = "Player_Former_Teams.leave_date DESC"
})
local root = html.create('table'):addClass('wikitable flat-table sortable'):css('width','100%')
local header = root:tag('tr')
header:tag('th'):wikitext('ID'); header:tag('th'):wikitext('Name'); header:tag('th'):wikitext('Role'); header:tag('th'):wikitext('Duration')
if #results > 0 then
for _, row in ipairs(results) do
local tr = root:tag('tr')
tr:tag('td'):css('font-weight','bold'):wikitext('[[' .. row.id .. ']]')
tr:tag('td'):wikitext(row.Name)
tr:tag('td'):wikitext(row.role)
local range = (row.join_date and mw.getContentLanguage():formatDate('M Y', row.join_date) or '?') .. ' – ' .. (row.leave_date and mw.getContentLanguage():formatDate('M Y', row.leave_date) or '?')
tr:tag('td'):attr('data-sort-value', row.leave_date):wikitext(range)
end
else
return '<div style="font-style:italic; color:#64748b; padding:10px;">No former players found for this team.</div>'
end
return tostring(root)
end
return p