全站通知:
            
            
        
模块:Mail
                  
                  
                  刷
                  
                     
                               
                               历
                            
                  
                    
                      
                        
                        编
                      
                    
                
            
            
            
            
            
            跳到导航
            跳到搜索
            
            
                
            
            
            
            
        
    local utils = require("Module:Utils")
local items = require("Module:Items")
local quest = require("Module:Quest")
local MailData = mw.loadData('Module:Mail/data')
local p = {}
-- 清理文本,处理换行符和玩家名称占位符
local function cleanText(text)
    if not text then return "" end
    -- 处理换行符
    text = text:gsub("%^", "\n")
    -- 处理玩家名称占位符
    text = text:gsub("@", utils.expandTemplate("玩家", {}))
    return text
end
-- 获取物品显示名称(参考Dialogue中的getItemDisplayName)
local function getItemDisplayName(itemId, count)
    local templateArgs = {}
    if itemId == "(O)126" or itemId == "126" then
        templateArgs[1] = "Strange Doll (green)"
    elseif itemId == "(O)127" or itemId == "127" then
        templateArgs[1] = "Strange Doll (yellow)"
    else
        local chineseName = items.getEnglishNameById(itemId)
        if chineseName and chineseName ~= "" then
            templateArgs[1] = chineseName
        else
            return nil
        end
    end
    -- 如果存在数量且大于1,将数量作为第二个参数传递
    if count and count > 1 then templateArgs[2] = tostring(count) end
    templateArgs.class = "inline"
    return utils.expandTemplate("Name", templateArgs)
end
-- 中文物品拼接逻辑
local function joinItems(items)
    if not items or #items == 0 then
        return ""
    elseif #items == 1 then
        return items[1]
    elseif #items == 2 then
        -- 两个时:A或B
        return items[1] .. "或" .. items[2]
    else
        -- 三个或以上时:A、B或C / A、B、C或D
        local result = ""
        for i = 1, #items - 2 do result = result .. items[i] .. "、" end
        result = result .. items[#items - 1] .. "或" .. items[#items]
        return result
    end
end
-- 解析信件内容,分离标题、内容和物品信息
local function parseMailContent(mailText, recipeParam)
    if not mailText then return nil, nil, nil end
    -- 分离标题部分 [#]标题
    local content, title = mailText:match("^(.*)%[#%](.*)$")
    if not content then
        content = mailText
        title = ""
    end
    -- 解析物品信息
    local items = {}
    local cleanContent = content
    -- 处理 %item 命令
    cleanContent = cleanContent:gsub("%%item%s+([^%%]+)%%%%",
                                     function(itemCommand)
        local parts = {}
        for part in itemCommand:gmatch("%S+") do
            table.insert(parts, part)
        end
        if #parts >= 1 then
            local itemType = parts[1]
            if itemType == "id" then
                -- %item id (O)388 50 %%
                local i = 2
                while i <= #parts do
                    if parts[i] and parts[i + 1] then
                        table.insert(items, {
                            type = "item",
                            id = parts[i],
                            count = tonumber(parts[i + 1]) or 1
                        })
                        i = i + 2
                    else
                        break
                    end
                end
            elseif itemType == "money" then
                -- %item money 500 501 %%
                if parts[2] and parts[3] then
                    local min = tonumber(parts[2]) or 0
                    local max = tonumber(parts[3]) or min
                    table.insert(items, {
                        type = "money",
                        amount = min -- 使用最小值作为金币数量
                    })
                elseif parts[2] then
                    local amount = tonumber(parts[2]) or 0
                    table.insert(items, {type = "money", amount = amount})
                end
            elseif itemType == "cookingRecipe" then
                -- %item cookingRecipe %%
                table.insert(items, {
                    type = "cookingRecipe",
                    recipe = recipeParam or "unknown"
                })
            elseif itemType == "craftingRecipe" then
                -- %item craftingRecipe Tea_Sapling %%
                table.insert(items, {
                    type = "craftingRecipe",
                    recipe = parts[2] or "unknown"
                })
            elseif itemType == "quest" then
                -- %item quest 1 true %%
                table.insert(items, {
                    type = "quest",
                    questId = parts[2] or "unknown",
                    auto = parts[3] == "true"
                })
            elseif itemType == "conversationTopic" then
                -- %item conversationTopic ElliottGone2 0 %%
                table.insert(items, {
                    type = "conversationTopic",
                    topic = parts[2] or "unknown",
                    days = tonumber(parts[3]) or 0
                })
            elseif itemType == "itemRecovery" then
                -- %item itemRecovery %%
                table.insert(items, {type = "itemRecovery"})
            end
        end
        return "" -- 移除物品命令文本
    end)
    -- 处理旧版物品命令
    cleanContent = cleanContent:gsub("%%item%s+object%s+([^%%]+)%%%%",
                                     function(objectCommand)
        local parts = {}
        for part in objectCommand:gmatch("%S+") do
            table.insert(parts, part)
        end
        local i = 1
        while i <= #parts do
            if parts[i] and parts[i + 1] then
                table.insert(items, {
                    type = "item",
                    id = "(O)" .. parts[i],
                    count = tonumber(parts[i + 1]) or 1
                })
                i = i + 2
            else
                break
            end
        end
        return ""
    end)
    cleanContent = cleanContent:gsub("%%item%s+bigobject%s+([^%%]+)%%%%",
                                     function(bigObjectCommand)
        local parts = {}
        for part in bigObjectCommand:gmatch("%S+") do
            table.insert(parts, part)
        end
        for _, id in ipairs(parts) do
            table.insert(items, {type = "item", id = "(BC)" .. id, count = 1})
        end
        return ""
    end)
    cleanContent = cleanContent:gsub("%%item%s+furniture%s+([^%%]+)%%%%",
                                     function(furnitureCommand)
        local parts = {}
        for part in furnitureCommand:gmatch("%S+") do
            table.insert(parts, part)
        end
        for _, id in ipairs(parts) do
            table.insert(items, {type = "item", id = "(F)" .. id, count = 1})
        end
        return ""
    end)
    -- 清理多余的空白
    cleanContent = cleanContent:gsub("%s+", " ")
    cleanContent = cleanContent:gsub("^%s+", "")
    cleanContent = cleanContent:gsub("%s+$", "")
    return cleanText(cleanContent), cleanText(title), items
end
-- 获取信件的标题
function p.getTitle(frame)
    local mailId = frame.args[1]
    if not mailId then return "错误:未提供信件ID" end
    local mailText = MailData[mailId]
    if not mailText then return "错误:未找到信件 " .. mailId end
    local recipeParam = frame.args.recipe
    local _, title, _ = parseMailContent(mailText, recipeParam)
    return title or ""
end
-- 获取信件的内容
function p.getContent(frame)
    local mailId = frame.args[1]
    if not mailId then return "错误:未提供信件ID" end
    local mailText = MailData[mailId]
    if not mailText then return "错误:未找到信件 " .. mailId end
    local recipeParam = frame.args.recipe
    local content, _, _ = parseMailContent(mailText, recipeParam)
    return content or ""
end
-- 获取信件的物品信息
function p.getItems(frame)
    local mailId = frame.args[1]
    if not mailId then return "错误:未提供信件ID" end
    local mailText = MailData[mailId]
    if not mailText then return "错误:未找到信件 " .. mailId end
    local recipeParam = frame.args.recipe
    local _, _, items = parseMailContent(mailText, recipeParam)
    if not items or #items == 0 then return "" end
    local result = {}
    for _, item in ipairs(items) do
        if item.type == "item" then
            -- 6. 如果是普通物品,获取各个物品的名称,然后通过Name模板展开
            local displayName = getItemDisplayName(item.id, item.count)
            if displayName then
                table.insert(result, displayName)
            else
                local itemText = item.id
                if item.count and item.count > 1 then
                    itemText = itemText .. " x" .. item.count
                end
                table.insert(result, itemText)
            end
        elseif item.type == "money" then
            -- 2. 如果是金币,金币数量视为参数一,使用模板price展开
            table.insert(result,
                         utils.expandTemplate("price", {tostring(item.amount)}))
        elseif item.type == "cookingRecipe" then
            -- 4. 如果是烹饪配方,检查传入的参数中是否有recipe=xxx
            if item.recipe and item.recipe ~= "unknown" then
                table.insert(result, utils.expandTemplate("Recipe", {
                    item.recipe, "36", "center"
                }))
            else
                table.insert(result, "<!-- 烹饪配方 -->")
            end
        elseif item.type == "craftingRecipe" then
            -- 3. 如果是制作配方,将配方名称的下划线替换为空格,然后使用模板Recipe展开
            local recipeName = item.recipe:gsub("_", " ")
            table.insert(result, utils.expandTemplate("Recipe", {
                recipeName, "36", "center"
            }))
        elseif item.type == "quest" then
            -- 5. 如果是任务,联动Quest输出任务的简要信息
            local questName = quest.getQuestName(item.questId)
            local questDesc = quest.getQuestDesc(item.questId)
            if questName and questName ~= "" then
                table.insert(result, questName ..
                                 (questDesc and questDesc ~= "" and
                                     (":" .. questDesc) or ""))
            else
                table.insert(result, "任务:" .. item.questId ..
                                 (item.auto and "(自动接受)" or ""))
            end
        elseif item.type == "conversationTopic" then
            -- 1. 如果是对话话题,那么把它用<!-- -->进行包裹(视作注释)
            table.insert(result,
                         "<!-- 对话话题:" .. item.topic .. "(" ..
                             item.days .. "天)-->")
        elseif item.type == "itemRecovery" then
            table.insert(result, "失物招领")
        end
    end
    return joinItems(result)
end
-- 同时获取信件的标题、内容、物品
function p.getAll(frame)
    local mailId = frame.args[1]
    if not mailId then return "错误:未提供信件ID" end
    local mailText = MailData[mailId]
    if not mailText then return "错误:未找到信件 " .. mailId end
    local recipeParam = frame.args.recipe
    local content, title, items = parseMailContent(mailText, recipeParam)
    local result = {}
    -- 标题
    if title and title ~= "" then
        table.insert(result, "'''标题:'''" .. title)
    end
    -- 内容
    if content and content ~= "" then
        table.insert(result, "'''内容:'''\n" .. content)
    end
    -- 物品
    if items and #items > 0 then
        local itemTexts = {}
        for _, item in ipairs(items) do
            if item.type == "item" then
                -- 6. 如果是普通物品,获取各个物品的名称,然后通过Name模板展开
                local displayName = getItemDisplayName(item.id, item.count)
                if displayName then
                    table.insert(itemTexts, displayName)
                else
                    local itemText = item.id
                    if item.count and item.count > 1 then
                        itemText = itemText .. " x" .. item.count
                    end
                    table.insert(itemTexts, itemText)
                end
            elseif item.type == "money" then
                -- 2. 如果是金币,金币数量视为参数一,使用模板price展开
                table.insert(itemTexts, utils.expandTemplate("price", {
                    tostring(item.amount)
                }))
            elseif item.type == "cookingRecipe" then
                -- 4. 如果是烹饪配方,检查传入的参数中是否有recipe=xxx
                if item.recipe and item.recipe ~= "unknown" then
                    table.insert(itemTexts, utils.expandTemplate("Recipe", {
                        item.recipe, "36", "center"
                    }))
                else
                    table.insert(itemTexts, "<!-- 烹饪配方 -->")
                end
            elseif item.type == "craftingRecipe" then
                -- 3. 如果是制作配方,将配方名称的下划线替换为空格,然后使用模板Recipe展开
                local recipeName = item.recipe:gsub("_", " ")
                table.insert(itemTexts, utils.expandTemplate("Recipe", {
                    recipeName, "36", "center"
                }))
            elseif item.type == "quest" then
                -- 5. 如果是任务,联动Quest输出任务的简要信息
                local questName = quest.getQuestName(item.questId)
                local questDesc = quest.getQuestDesc(item.questId)
                if questName and questName ~= "" then
                    table.insert(itemTexts, questName ..
                                     (questDesc and questDesc ~= "" and
                                         (":" .. questDesc) or ""))
                else
                    table.insert(itemTexts, "任务:" .. item.questId ..
                                     (item.auto and "(自动接受)" or ""))
                end
            elseif item.type == "conversationTopic" then
                -- 1. 如果是对话话题,那么把它用<!-- -->进行包裹(视作注释)
                table.insert(itemTexts, "<!-- 对话话题:" .. item.topic ..
                                 "(" .. item.days .. "天)-->")
            elseif item.type == "itemRecovery" then
                table.insert(itemTexts, "失物招领")
            end
        end
        if #itemTexts > 0 then
            table.insert(result, "'''物品:'''" .. joinItems(itemTexts))
        end
    end
    return table.concat(result, "\n\n")
end
-- 设置信件变量(不输出内容)
function p.setVars(frame)
    local mailId = frame.args[1]
    if not mailId then return "" end
    local mailText = MailData[mailId]
    if not mailText then return "" end
    local recipeParam = frame.args.recipe
    local content, title, items = parseMailContent(mailText, recipeParam)
    -- 设置标题变量
    if title and title ~= "" then
        frame:callParserFunction('#vardefine', {'mail_title', title})
    end
    -- 设置内容变量
    if content and content ~= "" then
        frame:callParserFunction('#vardefine',
                                 {'mail_content', content:gsub('\n', '\n\n')})
    end
    -- 设置物品变量
    if items and #items > 0 then
        local itemTexts = {}
        for _, item in ipairs(items) do
            if item.type == "item" then
                -- 6. 如果是普通物品,获取各个物品的名称,然后通过Name模板展开
                local displayName = getItemDisplayName(item.id, item.count)
                if displayName then
                    table.insert(itemTexts, displayName)
                else
                    local itemText = item.id
                    if item.count and item.count > 1 then
                        itemText = itemText .. " x" .. item.count
                    end
                    table.insert(itemTexts, itemText)
                end
            elseif item.type == "money" then
                -- 2. 如果是金币,金币数量视为参数一,使用模板price展开
                table.insert(itemTexts, utils.expandTemplate("price", {
                    tostring(item.amount)
                }))
            elseif item.type == "cookingRecipe" then
                -- 4. 如果是烹饪配方,检查传入的参数中是否有recipe=xxx
                if item.recipe and item.recipe ~= "unknown" then
                    table.insert(itemTexts, utils.expandTemplate("Recipe", {
                        item.recipe, "36", "center"
                    }))
                else
                    table.insert(itemTexts, "<!-- 烹饪配方 -->")
                end
            elseif item.type == "craftingRecipe" then
                -- 3. 如果是制作配方,将配方名称的下划线替换为空格,然后使用模板Recipe展开
                local recipeName = item.recipe:gsub("_", " ")
                table.insert(itemTexts, utils.expandTemplate("Recipe", {
                    recipeName, "36", "center"
                }))
            elseif item.type == "quest" then
                -- 5. 如果是任务,联动Quest输出任务的简要信息
                local questName = quest.getQuestName(item.questId)
                local questDesc = quest.getQuestDesc(item.questId)
                if questName and questName ~= "" then
                    table.insert(itemTexts, questName ..
                                     (questDesc and questDesc ~= "" and
                                         (":" .. questDesc) or ""))
                else
                    table.insert(itemTexts, "任务:" .. item.questId ..
                                     (item.auto and "(自动接受)" or ""))
                end
            elseif item.type == "conversationTopic" then
                -- 1. 如果是对话话题,那么把它用<!-- -->进行包裹(视作注释)
                table.insert(itemTexts, "<!-- 对话话题:" .. item.topic ..
                                 "(" .. item.days .. "天)-->")
            elseif item.type == "itemRecovery" then
                table.insert(itemTexts, "失物招领")
            end
        end
        if #itemTexts > 0 then
            frame:callParserFunction('#vardefine',
                                     {'mail_receive', joinItems(itemTexts)})
        end
    end
    -- 不输出任何内容
    return ""
end
p.debug = function()
    return p.getAll {args = {"Shane"}} -- elliottLetter1
end
return p
                
                    沪公网安备 31011002002714 号