缺氧 wiki 编辑团队提示:注册账号并登录后体验更佳,且可通过参数设置定制优化您的浏览体验!

该站点为镜像站点,如果你想帮助这个由玩家志愿编辑的 wiki 站点,请前往原站点参与编辑,
同时欢迎加入编辑讨论群 851803695 与其他编辑者一起参与建设!

全站通知:

模块:游戏版本

来自缺氧WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:游戏版本/doc创建

-- 游戏版本
local p = {}
local utils = require([[Module:Utils]])
local vData = mw.loadData([[Module:Data/版本]])
local vInfo = mw.loadData([[Module:Data/版本信息]])
local mbox = require([[Module:通知框]])
local getArgs = require([[Module:Arguments]]).getArgs
local date = require('Module:Dev/Date')
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 = vData[maxBuild].release_date:gsub("(%d%d)/(%d%d)/(%d%d)", "20%3 年 %1 月 %2 日")
    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 = vData[build].release_date:gsub("(%d%d)/(%d%d)/(%d%d)", "20%3 年 %1 月 %2 日")
        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 = latestVersion.release.release_date:gsub("(%d%d)/(%d%d)/(%d%d)", "20%3 年 %1 月 %2 日")
    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