通过 Sulfur.wiki 可快速访问本维基!
本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~
编辑帮助:目录 • BWIKI反馈留言板
通过 Sulfur.wiki 可快速访问本维基!
本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~
模块:JSONFetcher
此模块的文档可以在模块:JSONFetcher/doc创建
local p = {}
local json = mw.text.jsonDecode
local cache = require "mw.ext.LuaCache"
-- 获取 JSON 数据
function p.getData(frame)
local jsonPage = '火湖:物品数据.json' -- 数据页面路径
local cacheKey = "data_" .. jsonPage -- 第一层缓存键
local cachedData = cache.get(cacheKey)
if cachedData then
return json(cachedData) -- 如果第一层缓存命中,直接返回解析后的数据
end
local content = mw.title.new(jsonPage):getContent()
if not content then
return "无法获取数据"
end
local data = json(content)
if not data then
return "数据格式错误"
end
-- 将原始 JSON 数据存入第一层缓存
cache.set(cacheKey, content, 3600)
return data
end
-- 获取嵌套值,支持 ! 分隔符和数组索引
function p.fetch(frame)
-- 获取调用参数并生成缓存键
local key = frame.args[1]
local filters = frame.args[2] or ""
local cacheKey = "fetch_" .. (key or "") .. "_" .. filters -- 第一层缓存键
local secondCacheKey = cacheKey .. "_filtered" -- 第二层缓存键
-- 检查第二层缓存
local secondCachedResult = cache.get(secondCacheKey)
if secondCachedResult then
return secondCachedResult -- 如果第二层缓存命中,直接返回结果
end
-- 检查第一层缓存
local cachedResult = cache.get(cacheKey)
if cachedResult then
return cachedResult -- 如果第一层缓存命中,直接返回结果
end
local data = p.getData(frame)
if type(data) == "string" then
return data -- 如果出错,直接返回错误信息
end
if not key then
return "未指定参数"
end
-- 解析键,支持 ! 分隔符来进行索引
local function getNestedValue(data, key)
for part in key:gmatch("[^!]+") do
part = part:match("^%s*(.-)%s*$") -- 去掉前后空格
if type(data) == "table" then
local index = tonumber(part)
if index then
data = data[index]
else
data = data[part] or data["." .. part]
end
else
return nil
end
end
return data
end
-- 检查是否需要排除或保留指定的键或值(精确匹配)
local function matchesExact(item, pattern)
if not pattern then return false end
for matchPattern in pattern:gmatch("[^;]+") do
matchPattern = matchPattern:match("^%s*(.-)%s*$") -- 去掉空格
if tostring(item) == matchPattern then
return true
end
end
return false
end
-- 解析保留和排除参数
local function parseFilterParameter(filters)
if not filters then return nil, nil, nil, nil end
local excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern
for part in filters:gmatch("[^;]+") do
part = part:match("^%s*(.-)%s*$")
if part:sub(1, 3) == "!k:" then
excludeKeyPattern = part:sub(4)
elseif part:sub(1, 3) == "!v:" then
excludeValuePattern = part:sub(4)
elseif part:sub(1, 2) == "k:" then
includeKeyPattern = part:sub(3)
elseif part:sub(1, 2) == "v:" then
includeValuePattern = part:sub(3)
end
end
return excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern
end
-- 递归过滤嵌套数据
local function filterNestedData(data, excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern)
if type(data) ~= "table" then
-- 对非表数据应用值排除和保留规则(精确匹配)
if matchesExact(data, excludeValuePattern) then
return nil
end
if includeValuePattern and not matchesExact(data, includeValuePattern) then
return nil
end
return data
end
-- 对表数据应用键排除、键保留和递归过滤(精确匹配)
local filteredData = {}
for k, v in pairs(data) do
if matchesExact(k, excludeKeyPattern) then
-- 排除键
elseif includeKeyPattern and not matchesExact(k, includeKeyPattern) then
-- 不符合保留键规则
elseif tostring(k):match("^%?_") then
-- 排除以 ?_ 开头的键
else
local filteredValue = filterNestedData(v, excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern)
if filteredValue ~= nil then
filteredData[k] = filteredValue
end
end
end
return filteredData
end
-- 获取嵌套数据
local value = getNestedValue(data, key)
if value == nil then
return nil
end
-- 解析排除和保留规则
local excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern = parseFilterParameter(filters)
-- 过滤数据
local filteredValue = filterNestedData(value, excludeKeyPattern, excludeValuePattern, includeKeyPattern, includeValuePattern)
-- 生成返回值
local result
if type(filteredValue) == "table" then
local keys = {}
for k, _ in pairs(filteredValue) do
table.insert(keys, k)
end
result = table.concat(keys, ", ")
else
result = tostring(filteredValue)
end
-- 将未过滤结果存入第一层缓存
cache.set(cacheKey, result, 3600)
-- 将最终过滤结果存入第二层缓存
cache.set(secondCacheKey, result, 3600)
return result
end
return p