首页
随机
登录
设置
关于DJMAX中文资料库
免责声明
DJMAX中文资料库
搜索
查看“︁模块:Db”︁的源代码
←
模块:Db
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
local p = {} -- [[------------------------------------------------------------------]] -- [[ 1. 国际化和常量 ]] -- [[------------------------------------------------------------------]] local i18n = { ['true'] = '是', ['false'] = '否', ['none'] = '无', ['category_missing_value'] = '缺失%s', ['error_no_type'] = '<span class="error">Db:调用时必须提供type参数。</span>', ['error_find_keys_args'] = '<span class="error">Db:findKeysByValue必须提供field和value参数。</span>', ['error_generate_table_args'] = '<span class="error">Db:generateListTable调用缺少field或columns参数。</span>', } -- [[------------------------------------------------------------------]] -- [[ 2. 表格标题映射 ]] -- [[------------------------------------------------------------------]] local displayNames = { ['title'] = '歌曲标题', ['composer'] = '艺术家', ['bpm'] = 'BPM', ['singer'] = '歌手', ['genre'] = '流派', ['id'] = '歌曲ID', ['key'] = 'KEY音', ['bga'] = 'BGA作者', ['duration'] = '时长', ['pack'] = '曲包', ['4b_nm'] = '4B NM', ['4b_nm_notes'] = '4B NM', ['4b_hd'] = '4B HD', ['4b_hd_notes'] = '4B HD', ['4b_mx'] = '4B MX', ['4b_mx_notes'] = '4B MX', ['4b_sc'] = '4B SC', ['4b_sc_notes'] = '4B SC', ['5b_nm'] = '5B NM', ['5b_nm_notes'] = '5B NM', ['5b_hd'] = '5B HD', ['5b_hd_notes'] = '5B HD', ['5b_mx'] = '5B MX', ['5b_mx_notes'] = '5B MX', ['5b_sc'] = '5B SC', ['5b_sc_notes'] = '5B SC', ['6b_nm'] = '6B NM', ['6b_nm_notes'] = '6B NM', ['6b_hd'] = '6B HD', ['6b_hd_notes'] = '6B HD', ['6b_mx'] = '6B MX', ['6b_mx_notes'] = '6B MX', ['6b_sc'] = '6B SC', ['6b_sc_notes'] = '6B SC', ['8b_nm'] = '8B NM', ['8b_nm_notes'] = '8B NM', ['8b_hd'] = '8B HD', ['8b_hd_notes'] = '8B HD', ['8b_mx'] = '8B MX', ['8b_mx_notes'] = '8B MX', ['8b_sc'] = '8B SC', ['8b_sc_notes'] = '8B SC', } -- **Pack 缩写映射表(用户输入缩写 -> 完整包名,键使用大写以便不区分大小写查询)** local packAbbreviations = { ['VL'] = 'V LIBERTY', ['VL2'] = 'V LIBERTY 2', ['VL3'] = 'V LIBERTY 3', ['VE'] = 'V EXTENSION', ['VE2'] = 'V EXTENSION 2', ['VE3'] = 'V EXTENSION 3', ['VE4'] = 'V EXTENSION 4', ['VE5'] = 'V EXTENSION 5', ['P1'] = 'PORTABLE 1', ['P2'] = 'PORTABLE 2', ['P3'] = 'PORTABLE 3', ['CE'] = 'CLAZZIQUAI', ['BS'] = 'BLACK SQUARE', ['TR'] = 'TRILOGY', ['T1'] = 'TECHNIKA', ['T2'] = 'TECHNIKA 2', ['T3'] = 'TECHNIKA 3', ['R'] = 'RESPECT', ['RV'] = 'RESPECT V', ['ARC'] = 'ARCAEA', ['BA'] = 'BLUE ARCHIVE', ['CY'] = 'CYTUS', ['CHU'] = 'CHUNITHM', ['DE'] = 'DEEMO', ['EZ'] = 'EZ2ON', ['GC'] = 'GROOVE COASTER', ['MD'] = 'MUSE DASH', ['ESTI'] = 'ESTIMATE', ['FC'] = 'FALCOM', ['GF'] = 'GIRL\'S FRONTLINE', ['GG'] = 'GUILTY GEAR', ['MAP'] = 'MAPLESTORY', ['NXN'] = 'NEXON', ['TK'] = 'TEKKEN', ['TB1'] = 'PLI: TRIBUTE VOL.1', ['645141'] = 'PLI: 64514 VOL.1', } -- [[------------------------------------------------------------------]] -- [[ 3. 本地辅助函数定义 ]] -- [[------------------------------------------------------------------]] local function GetValuesTable() return mw.loadData('Module:db_song') end local function ValueFromValuesByKey(values, key) if values and key then return values[key] end return nil end -- **Pack 缩写解析** local function resolvePackValue(input) if type(input) ~= 'string' then return input end -- 尝试查找缩写(不区分大小写,因为 packAbbreviations 的键是大写) local upperInput = string.upper(input) if packAbbreviations[upperInput] then return packAbbreviations[upperInput] end -- 找不到缩写,返回原始输入 return input end local function formatSingleValue(value, fieldType) if value == nil then return i18n['none'] elseif type(value) == 'boolean' then return value and i18n['true'] or i18n['false'] elseif type(p.valueMappingMethod[fieldType]) == 'function' then return p.valueMappingMethod[fieldType](value) else return tostring(value) end end local function formatBPMValue(valueString) if string.find(valueString, '-') then return '<span style="color:red;">' .. valueString .. '</span>' end return valueString end -- **格式化 key 值 (仅在表格中使用)** local function formatKeyValue(value) if type(value) == 'boolean' then local color = value and 'green' or 'red' local text = value and i18n['true'] or i18n['false'] return '<span style="color:' .. color .. ';">' .. text .. '</span>' end return tostring(value) end local function getDifficultyDetails(field) local checkField = field and string.lower(mw.text.trim(field)) or '' local difficultyFields = { ['4b_nm'] = true, ['4b_hd'] = true, ['4b_mx'] = true, ['4b_sc'] = true, ['5b_nm'] = true, ['5b_hd'] = true, ['5b_mx'] = true, ['5b_sc'] = true, ['6b_nm'] = true, ['6b_hd'] = true, ['6b_mx'] = true, ['6b_sc'] = true, ['8b_nm'] = true, ['8b_hd'] = true, ['8b_mx'] = true, ['8b_sc'] = true, } if difficultyFields[checkField] == true then local mode = checkField:sub(-2) return checkField:match("^(%d+)b"), mode end return nil, nil end -- **核心:难度样式应用 (仅用于表格,并处理可能存在的 'sc' 前缀)** local function formatDifficultyStyles(valueString, mode) if valueString == '-' or valueString == i18n['none'] then return valueString end local displayString = valueString local numValue = tonumber(valueString) if mode == 'sc' and numValue == nil then local stripped = valueString:match("^[Ss][Cc](%d+)$") if stripped then numValue = tonumber(stripped) displayString = stripped end end if numValue == nil then return valueString end local style = '' if mode == 'sc' then local blueGlow = ' text-shadow: 0 0 5px #3D66FF, 0 0 8px #3D66FF;' style = 'font-weight: bold;' if numValue >= 1 and numValue <= 5 then style = style .. ' color: #E00075;' elseif numValue >= 6 and numValue <= 10 then style = style .. ' color: #C604E3;' elseif numValue >= 11 and numValue <= 12 then style = style .. ' color: #3D66FF;' elseif numValue == 13 then style = style .. ' color: orange;' .. blueGlow elseif numValue == 14 then style = style .. ' color: red;' .. blueGlow elseif numValue == 15 then style = style .. ' color: purple;' .. blueGlow end elseif (mode == 'nm' or mode == 'hd' or mode == 'mx') then if numValue == 14 then style = 'font-weight: bold; color: orange;' elseif numValue == 15 then style = 'font-weight: bold; color: red;' end end if style ~= '' then return '<span style="' .. style .. '">' .. displayString .. '</span>' end return displayString end -- **NOTES 字段加粗/变色逻辑** local function formatNotesValue(valueString, context) local numValue = tonumber(valueString) if numValue and numValue >= 2000 then local content = valueString if context == 'table' then -- --- 表格环境 (高优先级颜色 + 加粗) --- if numValue >= 3000 then -- Table, >= 3000: 紫色加粗 return '<span style="font-weight: bold; color: purple;">' .. content .. '</span>' elseif numValue >= 2000 then -- Table, 2000 <= X < 3000: 红色加粗 return '<span style="font-weight: bold; color: red;">' .. content .. '</span>' end else -- --- 非表格环境 (仅加粗) --- return '<b>' .. content .. '</b>' end end -- 如果小于 2000,返回原始字符串 return valueString end -- **SC 前缀应用 (仅用于 p.value)** local function applySCPrefix(valueString, fieldType) local isSC = string.match(fieldType, '_sc$') if isSC and valueString ~= i18n['none'] and valueString ~= '-' then if not valueString:lower():find('sc') then return 'sc' .. valueString end end return valueString end -- 4. 值格式化方法 (valueMappingMethod) p.valueMappingMethod = { ['duration'] = (function (value) if type(value) == 'number' then local minutes = math.floor(value / 60) local seconds = value % 60 return string.format('%d:%02d', minutes, seconds) end return value end), -- key 字段在非表格环境中的默认处理 (例如 p.value 调用) ['key'] = (function(value) if type(value) == 'boolean' then return value and i18n['true'] or i18n['false'] end return tostring(value) end) } -- [[------------------------------------------------------------------]] -- [[ 5. 外部调用函数 (p.*) ]] -- [[------------------------------------------------------------------]] function p.value(f) local args = f local frame = mw.getCurrentFrame() if f == frame then args = require('Module:ProcessArgs').merge(true) end local argTargetName = mw.text.trim(args[1] or '') local argTypeString = args.type local argNocat = args.nocat if not argTypeString then return i18n['error_no_type'] end local values = GetValuesTable() local songEntry = ValueFromValuesByKey(values, argTargetName) if not songEntry then if not argNocat then local title = mw.title.getCurrentTitle() if title.namespace == 0 and not title.isSubpage then return '?' .. '[[Category:' .. string.format(i18n['category_missing_value'], '歌曲ID ' .. argTargetName) .. ']]' end end return i18n['none'] end local fieldNames = mw.text.split(argTypeString, ',') local resultTable = {} for _, argType in ipairs(fieldNames) do argType = mw.text.trim(argType) local value = ValueFromValuesByKey(songEntry, argType) -- 使用 formatSingleValue 处理 BPM/Duration/Key(boolean->text) 等映射 local formattedValue = formatSingleValue(value, argType) formattedValue = applySCPrefix(formattedValue, argType) -- 非表格环境下应用 NOTES 格式化(仅加粗) if string.match(argType, '_notes$') then formattedValue = formatNotesValue(formattedValue, 'text') end table.insert(resultTable, formattedValue) end return table.concat(resultTable, ' / ') end function p.generateListTable(f) local args = require('Module:ProcessArgs').merge(true) local conditionField = mw.text.trim(args.field or '') local conditionValue = args.value local displayFieldsString = mw.text.trim(args.columns or '') local isPackFilter = (conditionField == 'pack') -- 定义 pack 筛选标记 -- ** 预处理 conditionValue ** if type(conditionValue) == 'string' then local trimmedValue = mw.text.trim(conditionValue) local lowerValue = string.lower(trimmedValue) if lowerValue == 'true' or trimmedValue == '是' then conditionValue = true elseif lowerValue == 'false' or trimmedValue == '否' then conditionValue = false else local num = tonumber(trimmedValue) -- 核心修复:如果是 Pack 筛选,即使能转为数字也不转,保持字符串以便后续缩写解析和不区分大小写比较 if num ~= nil and not isPackFilter then conditionValue = num else conditionValue = trimmedValue end end end if conditionField == '' or displayFieldsString == '' then return i18n['error_generate_table_args'] end local songData = GetValuesTable() local displayFields = mw.text.split(displayFieldsString, ',') local matchingKeys = {} local shouldFilter = conditionValue ~= nil -- 如果是 pack 筛选,提前解析 conditionValue 以支持缩写 local resolvedConditionValue = nil if isPackFilter and type(conditionValue) == 'string' then resolvedConditionValue = resolvePackValue(conditionValue) end for songId, songEntry in pairs(songData) do if not shouldFilter then table.insert(matchingKeys, songId) else local currentValue = ValueFromValuesByKey(songEntry, conditionField) local match = false -- 1. 数字和布尔值的精确匹配 if currentValue == conditionValue then match = true -- 2. 字符串匹配 elseif type(currentValue) == 'string' and type(conditionValue) == 'string' then -- 2a. Pack 字段: 缩写解析后的精确匹配 (Case-insensitive Exact Match) if isPackFilter then local targetValue = resolvedConditionValue -- 这会是完整的包名或原始输入 if string.upper(currentValue) == string.upper(targetValue) then match = true end -- 2b. 其他字符串字段: 模糊匹配 (Case-insensitive Fuzzy Match) else local searchString = conditionValue -- 模糊匹配:只要 currentValue 包含 searchString(不区分大小写) if string.find(string.upper(currentValue), string.upper(searchString), 1, true) then match = true end end end if match then table.insert(matchingKeys, songId) end end end table.sort(matchingKeys) if #matchingKeys == 0 then return '未找到符合条件的歌曲。' end local output = {} -- 表格样式 table.insert(output, '{| class="wikitable sortable" style="width: 100%; margin: 0 auto; text-align: center;"') -- 构造表格头部:添加宽度样式控制 table.insert(output, '|-') for _, field in ipairs(displayFields) do field = mw.text.trim(field) local _, mode = getDifficultyDetails(field) local headerContent = displayNames[field] or field local headerStyle = '' local separator = ' ' -- 默认分隔符是空格 -- BPM/Key/Duration 字段,固定宽度 6% if field == 'bpm' or field == 'key' or field == 'duration' then headerStyle = ' style="width: 6%;"' separator = ' | ' -- Pack 字段,固定宽度 8% elseif field == 'pack' then headerStyle = ' style="width: 10%;"' separator = ' | ' elseif mode then -- 谱面难度字段 (3.2% 固定宽度) headerStyle = ' style="width: 3.2%;"' separator = ' | ' elseif string.match(field, '_notes$') then -- NOTES 字段 (4% 固定宽度) headerStyle = ' style="width: 4%;"' separator = ' | ' end -- MediaWiki 表格头单元格: ! style | Content table.insert(output, '!' .. headerStyle .. separator .. headerContent) end -- 构造表格行 for _, songId in ipairs(matchingKeys) do local songEntry = songData[songId] table.insert(output, '|-') for _, field in ipairs(displayFields) do field = mw.text.trim(field) local rawValue = ValueFromValuesByKey(songEntry, field) -- 获取格式化的值 local formattedValue = formatSingleValue(rawValue, field) -- 应用内容样式 (BPM/Key) if field == 'bpm' then formattedValue = formatBPMValue(formattedValue) elseif field == 'key' then formattedValue = formatKeyValue(rawValue) -- 对 key 字段应用颜色逻辑,使用原始值 (rawValue) end local _, mode = getDifficultyDetails(field) if mode then formattedValue = formatDifficultyStyles(formattedValue, mode) end -- *** NOTES 字段样式逻辑 (包含 _sc_notes 默认颜色) *** if string.match(field, '_notes$') then local numValue = tonumber(rawValue) -- 1. 检查是否为高优先级(>= 2000/3000) if numValue and numValue >= 2000 then -- 高优先级:应用红/紫色的 formatNotesValue formattedValue = formatNotesValue(formattedValue, 'table') -- 2. 检查是否为所有 _sc_notes 字段且为低优先级(< 2000) elseif string.match(field, '_sc_notes$') then -- sc_notes 默认颜色:3d66ff (如果值不是高优先级) formattedValue = '<span style="color: #3d66ff;">' .. formattedValue .. '</span>' end end local cellContent = formattedValue -- CRITICAL FIX: 如果内容是单个 '-', 增加空格以避免被解析为行分隔符 '|-'. if cellContent == '-' then cellContent = ' -' end table.insert(output, '|' .. cellContent) end end table.insert(output, '|}') return table.concat(output, '\n') end return p
该页面使用的模板:
模块:Db/doc
(
查看源代码
)
返回
模块:Db
。