Module:Staff

-- local p = {}

local getArgs = require('Module:Arguments').getArgs local loader = require('Module:Loader')

local string, table, yesno, libUtil = loader.require('String', 'Table', 'Yesno', 'LibraryUtil') local checkType = libUtil.checkType

local roles, aliases, members = loader.loadData('Staff/Data', 'Staff/Aliases', 'Staff/Members')

function p.staffRole(frame) local args = getArgs(frame) local name = args[1] local alt = args[2] local plural = yesno(args['plural'] or args['plur'] or args['p'], false) local shorten = yesno(args['short'] or args['shr'] or args['s'], false) local linkAlt = args['link_alt'] or args['link'] or args['linkalt'] or args['la'] or args['l'] local altText = args['alt'] or args['a'] local success, response = pcall(p._staffRole, name, alt, plural, shorten, linkAlt, altText) return success and response or string.error(response) end

function p._staffRole(name, alt, plural, shorten, linkAlt, altText) if type(name) == 'table' then alt = name[2] or name.alt or name.alttext or name.altText plural = name[3] or name.plural shorten = name[4] or name.short or name.shorten linkAlt = name[5] or name.linkAlt or name.link name = name[1] or name.name end if name ==  or name == nil then return  end checkType('_staffRole', 1, name, 'string') checkType('_staffRole', 2, alt, 'string', true) checkType('_staffRole', 3, plural, 'boolean', true) checkType('_staffRole', 4, shorten, 'boolean', true) checkType('_staffRole', 5, linkAlt, 'string', true) checkType('_staffRole', 6, altText, 'string', true) if name:lower:match('(\'?s)$') or plural then plural = true name = name:gsub('(\'?s)$', '') else plural = false end local titleId = aliases[name:gsub('_', ' '):lower] local data = roles[titleId] if not titleId then error(string.format('Invalid staff rank name %s', name), 2) end local function hideAlways(s) return ' ' .. s .. ' '	end if alt then text = alt else if (shorten and plural) then text = data.shortPlural elseif shorten then text = data.short elseif plural then text = data.plural else text = data.title end end if linkAlt and linkAlt:match('https?%:%/%/%S*') then output_text = table.concat{ hideAlways(data.order), '[',			linkAlt, ' ', 			string.wrapHtml(text, ' ', { class=data.class }) ']',		}	elseif linkAlt then output_text = table.concat{ hideAlways(data.order), ,			string.wrapHtml(text, ' ', { class=data.class }),			, }	else output_text = table.concat{ hideAlways(data.order), ,			string.wrapHtml(altText or text, ' ', { class=data.class }),			, }	end return output_text end

function p.staffMsgBox(frame) local args = getArgs(frame) local function createList(ranks) local ret = {} for i, v in ipairs(ranks) do			table.push(ret, 				(#ranks > 2 and i > 1) and ', ' or ,				(#ranks == i and i > 1) and 'and ' or ,				v:match('^([aeiouy]+)') and 'an ' or 'a ', 				p.staffRole{ v },				#ranks == 2 and ' ' or ''			) end return ret end local ranks = {} for k, v in ipairs(args) do		if tonumber(k) or tostring(k):match('^rank[_ ]?%d*$') then table.push(ranks, v)		end end local msgBox = mw.html.create('div') :addClass('messagebox') :attr{ style=args['style'] } :wikitext(table.concat{			'This user is ',			table.concat(createList(ranks), ''),			' on the wiki.',			rank2 and ' ' or ' ',			'The wiki is not affiliated with Hypixel.',			' ',			string.wrapHtml{				text = 'This user is \'\'\'not\'\'\' part of the Hypixel staff and has \'\'\'no\'\'\' power in-game.',				tag = 'span',				attrs = { style='color:red;' }			},		}) return tostring(msgBox) end

-- Project:Staff/user function p.staffLink(frame) local args = getArgs(frame) local staff = args.staff or args.name or args[1] local rank = args.rank or args.r	local showlinks = args.showlinks or args.showlink return p._staffLink(name, rank, { showlinks = showlinks, note = args.notes or args.note or args[2] }) end

function p._staffLink(name, rank, opts) local member = members[name] if not member then string.wrapHtml(('Staff Link: No staff named %s.'):format(name), 'span', { class = 'error' }) end opts = opts or {} rank = rank or 'RB' if (aliases[rank:lower] or rank:lower) == 'bot' then return ('%s'):format(name, name) end local disp = p._staffRole(rank, name, nil, nil, ('User:%s'):format(name)) local bull = '\'\'\'&bull;\'\'\'' local links = (' \'\'\'(%s %s %s %s %s)\'\'\''):format(		p._staffRole(rank, 'wall', nil, nil, ('Message_Wall:%s'):format(name)), bull,		p._staffRole(rank, 'CC Wall', nil, nil, ('w:c:Message_Wall:%s'):format(name)), bull,		p._staffRole(rank, 'contribs', nil, nil, ('Special:Contributions/%s'):format(name))	) local showlinks = opts.showlinks or opts.showlink note = opts.notes or opts.note note = note and (' (%s)'):format(note) or '' return ('%s%s%s'):format(disp, yesno(showlinks, true) and string.wrapHtml(links, 'small') or '', note) end

-- Project:Staff/data function p.staffLookup(frame) local args = getArgs(frame) local lookup = args[1] local mode = args[2] or 'list' return p._staffLookup(lookup, mode) end

function p._staffLookup(lookup, mode) role = roles[aliases[lookup:lower] or lookup:lower] if not role then return string.wrapHtml(('Staff Lookup: Role %s not valid.'):format(lookup), 'span', { class = 'error' }) end local code = role.code local a, count = {}, 0 for staff, staffdata in pairs(members) do		if (code == 'BOT' and staffdata.bot) then a[staff] = staffdata count = count + table.length(mw.text.split(staffdata.bot, '%|')) elseif staffdata.rank:match(code) then a[staff] = staffdata count = count + 1 end end local sortedpairs = table.sortedPairs(a, function(one, two) return one < two end) if mode == 'num' or mode == 'count' then return count elseif mode == 'list' then local t = {} if code == 'BOT' then table.push(t, '{| class="article-table"\n!Bot\n!Operator') for owner, ownerdata in sortedpairs do				local temp = {} -- bots by one owner can be separated by the pipe character (|) for bot in mw.text.gsplit(ownerdata.bot, '%|') do					table.push(temp, p._staffLink(bot, 'bot')) end table.push(t, ('|-\n| %s || %s'):format( table.concat(temp, ', '), p._staffLink(owner, ownerdata.rank:sub(1,2)) -- highest rank ))			end table.push(t, '|}') else for staff, staffdata in sortedpairs do				table.push(t, ('* %s'):format( p._staffLink(staff, code, { note = staffdata.activity }) ))			end end return mw.getCurrentFrame:preprocess((table.concat(t, '\n'))) else return string.wrapHtml(('Staff Lookup: Mode %s not valid.'):format(mode), 'span', { class = 'error' }) end end

return p