此模块的文档可以在Module:游戏版本/doc创建
-- 游戏版本
local p = {}
local utils = require([[Module:Utils]])
local vData = mw.loadData([[Module:Data/版本]])
local vInfo = mw.loadData([[Module:Data/版本信息]])
local mbox = require([[Module:Mbox]])
local date = require('Dev:Date')
local getArgs = require('Dev:Arguments').getArgs
local fstr = mw.ustring.format -- shortcut for formattig a string
-- 消息变量
-- $1 页面版本
-- $2 当前稳定版
-- $3 上次更新距今时间 20210824200236
-- $4 改动的版本
-- $5 改动的版本(测试版)
p.COLOR_TYPE = {
TEST = "message",
RECENT = "message",
AUTO = "message",
OUTDATED = "warning"
}
p.HEADER = {
TEST = "本文反映了当前稳定版本的信息", -- TEST 指页面版本号在稳定版本之后,属于新测试版;这样的页面应该同时保留测试版信息和稳定版信息,所以它至少会反映最新的稳定版信息,但是不一定是最新的测试版信息;关于测试版的提示交给了 p.MSG 和 p.CHANGE_IN_TEST
RECENT = "本文反映了当前稳定版本的信息",
AUTO = "本文上次更新于$3前,期间稳定版本没有相关更新",
OUTDATED = "本文可能包含过时信息"
}
p.MSG = {
TEST = "本页面反映的游戏版本为测试版:$1,可能包含了测试版中的新特性。当前稳定版:$2。",
RECENT = "本页面反映了当前稳定版($2)的[[版本历史|最新]]信息。",
AUTO = "截至当前稳定版本($2),本词条所述内容没有出现在[[版本历史|更新日志]]中,但页面中的其它信息可能会受到影响。本页面反映的游戏版本:$1。",
OUTDATED = "本页面可能含有相对于当前版本($2)过时的信息。自本页面所反映的游戏版本($1)以来,已知以下更新中有与本词条相关的变更:$4。"
}
p.CHANGED_IN_TEST =
"本词条所述内容在测试分支中有相关变更,详见:$5。"
p.IMG = {
TEST = "符号_对勾.png",
RECENT = "符号_对勾.png",
AUTO = "符号_对勾.png",
OUTDATED = "复制人.png"
}
p.CATEGORY = {
TEST = "包含测试版信息的页面",
RECENT = "包含最新信息的页面",
AUTO = "未找到过时信息的页面",
OUTDATED = "可能包含过时信息的页面"
}
-- 消息变量
-- $1 版本页面
-- $2 版本
-- $3 版本号
-- $4 发表时间
-- $5 大版本名
local PAGE_VERSION =
'[[$1|$2]]<sup><abbr title="版本 $3 发布于 $4;大版本:“$5”">更多</abbr></sup>'
local MAX_VERSION =
'[[$1|$2]]<sup><abbr title="“$5”发布于 $4;版本号:$3">更多</abbr></sup>'
local function funcAnd(p1, p2) return function(x) return p1(x) and p2(x) end end
-- Release / Hotfix
local function notTest(id) return vData[id].type ~= "Test" end
local function isRelease(id) return vData[id].type == "Release" end
local function isSO(id) return vData[id].so end
local function isBase(id) return vData[id].base end
local function hasName(id) return vData[id].name ~= nil and vData[id].name ~= "" end
-- Get the max key of a table
local function tbMaxKey(tb, predicate)
local mk = -math.huge
for k, _ in pairs(tb) do if predicate(k) and k > mk then mk = k end end
return mk
end
local function sortedVersionLinks(vs)
table.sort(vs, function(v1, v2) return v1.num > v2.num end)
return utils.map(vs, function(v)
return fstr("[[%s|%s-%d]]", v.page, v.prefix, v.num)
end)
end
function p.getBuild(args)
local code = args[1]
local build = tonumber(args.build)
build = build or vInfo.code2build[code] or 0
return build
end
function p._main(args)
local cats = {}
local ex = (type(args.ex) == "string") and (args.ex:upper() == 'SO')
local isCurrEx = ex and isSO or isBase
local build = p.getBuild(args)
local buildPage = vData[build] and vData[build].page
local maxBuild = tbMaxKey(vData, funcAnd(isCurrEx, notTest))
local maxMajorBuild = tbMaxKey(vData, funcAnd(funcAnd(isCurrEx, hasName),
isRelease))
-- Get unreflected changes
local unreflectedRelease = {}
local unreflectedTest = {}
local currPageTitle = args.pagename
for k, v in pairs(vData) do
if k > build then
if (type(v.affected_pages) == "string") and
(v.affected_pages:upper() == "ALL") then
-- 强制计入 unreflectedRelease
table.insert(unreflectedRelease, v)
elseif type(v.affected_pages) == "table" then
for _, page in pairs(v.affected_pages) do
if page == currPageTitle then
if k > maxBuild then
table.insert(unreflectedTest, v)
else
table.insert(unreflectedRelease, v)
end
break
end
end
end
end
end
unreflectedRelease = sortedVersionLinks(unreflectedRelease)
unreflectedTest = sortedVersionLinks(unreflectedTest)
-- Get maxBuildShown
local versionTemplate =
'[[%s|%s]]<sup><abbr title="版本 %d 发布于 %s">更多</abbr></sup>'
local maxBuildDate = date(vData[maxBuild].release_date):fmt(
"%Y 年 %m 月 %d 日")
local maxMajorBuildName = vData[maxMajorBuild].zhName or
vData[maxMajorBuild].name
local maxBuildWithPrefix = fstr("%s-%d", vData[maxBuild].prefix, maxBuild)
local maxBuildShown = utils.getMsg(MAX_VERSION, vData[maxBuild].page,
maxBuildWithPrefix, maxBuild,
maxBuildDate, maxMajorBuildName)
-- Get buildPageShown (current page)
local buildPageShown = nil
if buildPage == nil then
if build ~= 0 then
buildPageShown = fstr("[[版本历史|版本 %s]]", build)
else
buildPageShown = "[[版本历史|未知版本]]"
end
else
local buildPrefix = vData[build].prefix or 'default'
local buildWithPrefix =
vData[build].prefix == nil and tostring(build) or
fstr("%s-%d", vData[build].prefix, build)
local majorBuildName = vInfo.prefixName[buildPrefix] or ("未知")
local buildDate = date(vData[build].release_date):fmt(
"%Y 年 %m 月 %d 日")
buildPageShown = utils.getMsg(PAGE_VERSION, buildPage, buildWithPrefix,
build, buildDate, majorBuildName)
end
local status = nil
local function getMsg(m)
local days = (date() - date(args.revisionTimestamp)):spandays()
local showRel = unreflectedRelease and
table.concat(unreflectedRelease, ' • ')
local showTest = unreflectedTest and
table.concat(unreflectedTest, ' • ')
return utils.getMsg(m, buildPageShown, maxBuildShown,
fstr(" %d 天", days), showRel, showTest)
end
if build > tbMaxKey(vData, notTest) then
status = "TEST"
elseif #unreflectedRelease == 0 then
if maxMajorBuild <= build then
status = "RECENT"
else
status = "AUTO"
end
else
status = "OUTDATED"
end
local noticeMsg = getMsg(p.MSG[status])
if #unreflectedTest ~= 0 then
noticeMsg = noticeMsg .. getMsg(p.CHANGED_IN_TEST)
end
-- border color and img file
local mboxArgs = {
imagewidth = '50px',
text = noticeMsg,
id = "version",
collapsed = "true",
type = p.COLOR_TYPE[status],
image = p.IMG[status],
header = getMsg(p.HEADER[status])
}
local out = tostring(mbox._main(mboxArgs))
if not args.nocat then
if args[1] ~= nil then
table.insert(cats, utils.maintenanceCats.deprecatedParams(
"请使用 build 参数,用法详见[[Template:游戏版本]]"))
end
if args.build == nil and (args[1] and vInfo.code2build[args[1]]) == nil then
table.insert(cats, utils.maintenanceCats
.invalidParams(
"用法详见[[Template:游戏版本]]"))
end
table.insert(cats, fstr("[[Category:%s]]", p.CATEGORY[status]))
out = out .. table.concat(cats, "")
end
return out
end
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236"}
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236", 'AP'}
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236", 'temp'}
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236", build='1'}
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236", build='476058'}
-- test by: =p._main{pagename="冰箱", revisionTimestamp="20210824200236", build='476059', ex='SO'}
function p.main(frame) return p._main(getArgs(frame)) end
-- test by: =p.latest()
function p.latest(frame)
local latest = {test = 0, hotfix = 0, release = 0}
local latestVersion = {}
for k, v in pairs(vData) do
for _, build in ipairs({'test', 'hotfix', 'release'}) do
if v.type:lower() == build and k > latest[build] then
latest[build] = k
latestVersion[build] = v
end
end
end
local releaseDate = date(latestVersion.release.release_date):fmt(
"%Y 年 %m 月 %d 日")
local releasePage = latestVersion.release.page
local releaseName = latestVersion.release.zhName or
latestVersion.release.name or releasePage
local out = fstr(
"《缺氧》的最近大型更新是于 %s发布的[[%s|%s]]。",
releaseDate, releasePage, releaseName)
if latest.hotfix > latest.release then
out = out ..
fstr("目前游戏运行于热修复版本 [[%s|%s-%s]]。",
latestVersion.hotfix.page, latestVersion.hotfix.prefix,
latestVersion.hotfix.num)
end
if latest.test > latest.release then
out = out ..
fstr('测试分支的最新测试版本为 [[%s|%s-%s]]。',
latestVersion.test.page, latestVersion.test.prefix,
latestVersion.test.num)
end
return out
end
return p