มอดูล:Version

จาก ARK Wiki
ไปยังการนำทาง ไปยังการค้นหา
Template-info.png Documentation

local p = {}
local Data = mw.loadData('Module:Version/data')

local Info = Data.Info
local Count = Data.Count
local ToIndex = Data.ToIndex
local Current = Data.Current
local ServerClientCollisions = Data.ServerClientCollisions

p.Platform = {
	PC = 'PC', Xbox = 'Xbox', PS = 'PS', Mobile = 'Mobile', Switch = 'Switch',
}
p.OnlyReleasedFor = {
	Client = 'ClientOnly',
	Server = 'ServerOnly',
}

local PlatformLowerCaseToStd = {
	pc = p.Platform.PC, xbox = p.Platform.Xbox, ps = p.Platform.PS, mobile = p.Platform.Mobile,
	switch = p.Platform.Switch,
}
local OnlyReleasedForLowerCaseToStd = {
	client = p.OnlyReleasedFor.Client,
	server = p.OnlyReleasedFor.Server,
}


function PlatformLowerCaseToStd:getCanonical(input)
	input = PlatformLowerCaseToStd[input:lower()] or input
	assert(p.Platform[input], "platform must be one of the following (case-insensitive): PC, Xbox, PS, Mobile, Switch")
	return input
end


function OnlyReleasedForLowerCaseToStd:getCanonical(input)
	input = OnlyReleasedForLowerCaseToStd[input:lower()] or input
	assert(p.OnlyReleasedFor[input], "'only' must be one of the following (case-insensitive): Client, Server")
	return input
end


local function _assertVersionIsValid(platform, version)
	assert(ToIndex[platform][version], string.format('unknown %s version %s', platform, version))
end


local function _getArgsFromFrame(frame)
	local args = frame.args
	local platform = PlatformLowerCaseToStd:getCanonical(args[1])
	local nr = args[2]
	local only = args.onlyReleasedFor == '' and nil or args.onlyReleasedFor
	return platform, p.getVersionIndex(platform, nr, only)
end


function p.getVersionIndex(platform, version, only)
	-- If looking for specifically for a client or server release, branch off.
	if only then
		assert(ServerClientCollisions[platform][version], "'only' may only be specified for a version with different release dates for client and server")
		local a = ToIndex[platform][version]
		assert(a ~= nil, string.format('unknown %s version %s', platform, version))
		local b = a-1
		if Info[a][only] == true then
			return a
		elseif Info[b][1] == version and Info[b][only] == true then
			return b
		end
	else
		local out = ToIndex[platform][version]
		assert(out ~= nil, string.format('unknown %s version %s', platform, version))
		return out
	end
end


function p.getVersionInfo(platform, index)
	return Info[platform][index]
end


function p.getReleaseDate(platform, index)
	local info = Info[platform][index]
	return info and info[2] or nil
end


function p.getReleaseDateW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.getReleaseDate(platform, index) or ''
end


function p.getCurrentVersionIndex(platform)
	return ToIndex[platform][Current[platform]]
end


function p.getCurrentVersionName(platform)
	return Current[platform]
end


function p.getCurrentVersionNameW(f)
	return Current[PlatformLowerCaseToStd:getCanonical(f.args[1])] or ''
end
p.getCurrentVersionW = p.getCurrentVersionNameW


function p.getCurrentVersionReleaseDate(platform)
	return p.getReleaseDate(platform, p.getCurrentVersionIndex(platform))
end


function p.getPreviousVersionName(platform, index)
	-- TODO: properly handle colliding names
	index = index - 1
	return index >= 1 and Info[platform][index][1] or nil
end


function p.getPreviousVersionNameW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.getPreviousVersionName(platform, index) or ''
end
p.getPreviousVersionW = p.getPreviousVersionNameW


function p.getNextVersionName(platform, index)
	index = index + 1
	return index <= Count[platform] and Info[platform][index][1] or nil
end


function p.getNextVersionNameW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.getNextVersionName(platform, index) or ''
end
p.getNextVersionW = p.getNextVersionNameW


function p.isVersionMajor(platform, index)
	local previous = p.getPreviousVersionName(platform, index)
	if previous == nil then
		return true
	end
	return tonumber(Info[platform][index][1]:match('(%d+)%.')) > tonumber(previous:match('(%d+)%.'))
end


function p.isVersionMajorW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.isVersionMajor(platform, index) and 'Yes' or ''
end


function p.getVersionLink(platform, index)
	local version = Info[platform][index]
	if platform == p.Platform.PC then
		return version[1]
	end
	return platform .. ' ' .. version[1]
end


function p.getVersionLinkW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.getVersionLink(platform, index)
end


function p.getVersionBuildAvailability(platform, index)
	local info = Info[platform][index]
	return info and (info.ServerOnly and 'server') or (info.ClientOnly and 'client') or nil
end


function p.getVersionBuildAvailabilityW(f)
	local platform, index = _getArgsFromFrame(f)
	return p.getVersionBuildAvailability(platform, index) or ''
end


-- prototype A
function p.renderVersionListInLineW(f)
	local platform = PlatformLowerCaseToStd:getCanonical(f.args[1])
	local line = tonumber(f.args[2])
	local separator = f.args[3] or ' '
	local lineMax = f.args[4] and tonumber(f.args[4]) or nil
	assert(line ~= nil, 'version line must be a number, e.g. 340')
	if lineMax == nil then
		lineMax = line - (line%10) + 10
	end
	
	local versions = {}
	for index, version in ipairs(Info[platform]) do
		local major = tonumber(version[1]:match('(%d+)%.'))
		if major >= line and major < lineMax then
			table.insert(versions, string.format('[[%s|%s]]', p.getVersionLink(platform, index), version[1]))
		end
	end
	
	return table.concat(versions, separator)
end


-- prototype B
function p.renderListOfVersionsInMajorsW(f)
	local platform = PlatformLowerCaseToStd:getCanonical(f.args[1])
	local separator = f.args[2] or ' '

	-- Collect major versions from arguments
	local majors = {}
	for index, majorToMatch in ipairs(f.args) do
		if index > 2 then
			local major = tonumber(majorToMatch)
			assert(major ~= nil, 'version major must be a number, e.g. 340')
			majors[major] = true
		end
	end

	-- Collect the versions
	local versions = {}
	local guard = {}
	for _, version in ipairs(Data.Info[platform]) do
		local nr = version[1]
		-- Check if caller requested this major to be tracked
		local major = tonumber(nr:match('(%d+)%.'))
		if majors[major] then
			if ServerClientCollisions[platform][nr] then
				-- There's two releases in the database for this version number. Ensure only one is written.
				if guard[nr] == nil then
					versions[#versions+1] = nr
					guard[nr] = true
				end
			else
				versions[#versions+1] = nr
			end
		elseif #versions > 0 then
			-- We've rendered matching versions and found a mismatch, finish the loop
			break
		end
	end
	
	-- Render the list
	local html = {}
	for _, version in ipairs(versions) do
		if platform == p.Platform.PC then
			html[#html+1] = string.format('[[%s]]', version)
		else
			html[#html+1] = string.format('[[%s %s|%s]]', platform, version, version)
		end
	end
	
	return table.concat(html, separator)
end


return p