打开/关闭搜索
搜索
打开/关闭菜单
1K
5.2K
4
8.2K
星砂岛百科
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
上传文件
打开/关闭外观设置菜单
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
本站正在进行早期测试,目前仍存在许多内容的缺失。
查看“︁模块:Machine”︁的源代码
来自星砂岛百科
查看
阅读
查看源代码
查看历史
associated-pages
模块
讨论
更多操作
←
模块:Machine
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:已验证邮箱用户
您没有权限编辑
模块
命名空间内的页面。
您必须确认您的电子邮件地址才能编辑页面。请通过
参数设置
设置并确认您的电子邮件地址。
您可以查看和复制此页面的源代码。
local common = require('Module:Common') local item_common = require('Module:ItemCommon') local item = require('Module:Item') local css = require('Module:CSS') local p = {} local FIELD_MAP = { type = 't', type_display = 'td', item_level = 'lv', rarity = 'r', sell_price = 'sp', base_value = 'bv', max_stack = 'ms', max_quality = 'mq', tags = 'g', origin = 'o', locked_origin = 'lo', use_description = 'ud', unlock_title = 'ut', construct_template = 'ct', construction_template_count = 'ctc', energy_capacity = 'ec', production_formula = 'pf', production_formula_origin = 'pfo', craft = 'c', upgrade = 'u', prev_machine = 'pm', next_machine = 'nm', } local RECIPE_FIELD_DEFAULTS = { result = 'r', result_count = 'rc', materials = 'm', time = 't', machine = 'mc', cooking_method = 'cm', } local data_cache local mapping_cache local recipe_cache local recipe_list local item_recipe_cache local field_map = RECIPE_FIELD_DEFAULTS local function is_empty(value) if value == nil then return true end for _ in pairs(value) do return false end return true end local function count_array(arr) if type(arr) ~= 'table' then return 0 end local count = 0 for _ in pairs(arr) do count = count + 1 end return count end local function load_data() if data_cache then return end local raw_data raw_data, mapping_cache = item_common.loadDomainData('数据:Machine/machine_index.json') if type(raw_data) == 'table' and type(raw_data.records) == 'table' then data_cache = raw_data.records else data_cache = raw_data or {} end end local function find_record(key) load_data() return item_common.findRecord(data_cache, mapping_cache, key) end local function get_short_field(field) return FIELD_MAP[field] or field end local function get_record_field(record, key, field) if type(record) ~= 'table' then return nil end local short_key = get_short_field(field) if record[short_key] ~= nil then return record[short_key] end if record[field] ~= nil then return record[field] end if field == 'id' or field == 'name' or field == 'name_en' then return item_common.getIdentityField(record, key, field) end return nil end local function get_craft_field(craft, short_key, long_key) if type(craft) ~= 'table' then return nil end if craft[short_key] ~= nil then return craft[short_key] end return craft[long_key] end local function format_time(seconds) seconds = tonumber(seconds) or 0 if seconds <= 0 then return '' end if seconds < 60 then return tostring(math.floor(seconds)) .. '秒' end local minutes = math.floor(seconds / 60) local remain = math.floor(seconds % 60) if remain == 0 then return tostring(minutes) .. '分' end return tostring(minutes) .. '分' .. tostring(remain) .. '秒' end local function render_materials(frame, materials) if is_empty(materials) then return '' end local item_ids = {} for item_id in pairs(materials) do item_ids[#item_ids + 1] = item_id end item_common.sortItemKeys(item_ids) local parts = {} for _, item_id in ipairs(item_ids) do parts[#parts + 1] = frame:expandTemplate{ title = 'Item', args = { item_id, tostring(materials[item_id]), class = 'block' }, } end return table.concat(parts, '') end local function render_item_template(frame, item_id) local resolved_id = common.trim(item_id or '') if resolved_id == '' then return '' end local css_out = css.quickCall('Item') or '' return css_out .. item.renderItemWithArgs(frame, { resolved_id }) end local function page_exists(title_text) local title = mw.title.new(common.trim(title_text)) return title and title.exists or false end local function render_machine_reference(machine_id) local resolved_id = common.trim(machine_id or '') if resolved_id == '' then return '' end local machine_name = common.trim(item.getNameByKey(resolved_id) or '') if machine_name == '' then machine_name = resolved_id end local image_name = resolved_id .. '.png' local has_icon = common.filePageExists(image_name) local out = { '<span class="itemtemplate itemtemplateblock recipe-usage-machine-chip">' } if has_icon then out[#out + 1] = '<span class="item-icon-container">' out[#out + 1] = ('[[File:%s|24x24px|link=]]'):format(image_name) out[#out + 1] = '</span>' end out[#out + 1] = '<span class="item-text">' if page_exists(machine_name) then out[#out + 1] = ('[[%s|%s]]'):format(machine_name, machine_name) else out[#out + 1] = mw.text.encode(machine_name) end out[#out + 1] = '</span>' out[#out + 1] = '</span>' return table.concat(out) end local function render_craft_table(title_text, station_label, station_value, materials_label, materials_value, time_label, time_value, exp_label, exp_value) local out = {} out[#out + 1] = '<div class="recipe-usage-table-wrap">' out[#out + 1] = '<table class="wikitable machine-craft-table recipe-usage-table">' out[#out + 1] = '<tr><th colspan="2">' .. title_text .. '</th></tr>' out[#out + 1] = '<tr><th>' .. station_label .. '</th><td>' .. station_value .. '</td></tr>' out[#out + 1] = '<tr><th>' .. materials_label .. '</th><td>' .. materials_value .. '</td></tr>' if time_value ~= '' then out[#out + 1] = '<tr><th>' .. time_label .. '</th><td>' .. time_value .. '</td></tr>' end if exp_value ~= '' then out[#out + 1] = '<tr><th>' .. exp_label .. '</th><td>' .. exp_value .. '</td></tr>' end out[#out + 1] = '</table>' out[#out + 1] = '</div>' return table.concat(out, '\n') end local function is_array_table(value) if type(value) ~= 'table' then return false end local count = 0 for key in pairs(value) do if type(key) ~= 'number' then return false end count = count + 1 end if count == 0 then return false end for index = 1, count do if value[index] == nil then return false end end return true end local function normalize_material_options(materials) if type(materials) ~= 'table' then return {} end if is_array_table(materials) then local options = {} for _, option in ipairs(materials) do if type(option) == 'table' and not is_empty(option) then options[#options + 1] = option end end return options end if is_empty(materials) then return {} end return { materials } end local function render_material_option(frame, materials) if type(materials) ~= 'table' or is_empty(materials) then return '' end local item_ids = {} for item_id in pairs(materials) do item_ids[#item_ids + 1] = item_id end item_common.sortItemKeys(item_ids) local parts = {} for _, item_id in ipairs(item_ids) do parts[#parts + 1] = item.renderItemWithArgs(frame, { item_id, tostring(materials[item_id]), class = 'block' }) end return table.concat(parts, '') end local function filter_material_option(materials, excluded_item_id) if type(materials) ~= 'table' then return {} end local filtered = {} for item_id, count in pairs(materials) do if item_id ~= excluded_item_id then filtered[item_id] = count end end return filtered end local function render_material_option_or_empty(frame, materials) local rendered = render_material_option(frame, materials) if rendered == '' then return '—' end return rendered end local function render_recipe_materials(frame, materials, excluded_item_id) local options = normalize_material_options(materials) if #options == 0 then return '' end if excluded_item_id and excluded_item_id ~= '' then local filtered_options = {} local has_non_empty_option = false for _, option in ipairs(options) do local filtered = filter_material_option(option, excluded_item_id) if not is_empty(filtered) then has_non_empty_option = true end filtered_options[#filtered_options + 1] = filtered end if not has_non_empty_option then return '—' end options = filtered_options end if #options == 1 then return render_material_option_or_empty(frame, options[1]) end local out = {} out[#out + 1] = '<div class="recipe-usage-option-label">可选材料方案</div>' out[#out + 1] = '<ul class="recipe-usage-option-list">' for _, option in ipairs(options) do out[#out + 1] = '<li>' .. render_material_option_or_empty(frame, option) .. '</li>' end out[#out + 1] = '</ul>' return table.concat(out, '') end local function material_counts_for_item(materials, item_id) local counts = {} local seen = {} for _, option in ipairs(normalize_material_options(materials)) do local count = tonumber(option[item_id]) or 0 if count > 0 and not seen[count] then seen[count] = true counts[#counts + 1] = count end end table.sort(counts) return counts end local function render_material_count_list(counts) if #counts == 0 then return '' end if #counts == 1 then return tostring(counts[1]) end local out = { '<ul class="recipe-usage-count-list">' } for _, count in ipairs(counts) do out[#out + 1] = '<li>' .. tostring(count) .. '</li>' end out[#out + 1] = '</ul>' return table.concat(out, '') end local function load_recipes() if recipe_cache then return end local data = common.loadJsonData('数据:Machine/machine_recipes.json') or {} recipe_list = data.recipes or {} recipe_cache = data.by_machine or {} item_recipe_cache = data.by_item or {} field_map = (data._meta or {}).field_map or RECIPE_FIELD_DEFAULTS end local function recipe_time_text(recipe) if not recipe then return '' end local value = tonumber(recipe[field_map.time]) or 0 if value <= 0 then return '' end return format_time(value) end local function render_recipe_result(frame, recipe) if not recipe then return '' end local result_id = recipe[field_map.result] if not result_id or result_id == '' then return '' end local result_count = tonumber(recipe[field_map.result_count]) or 1 if result_count > 1 then return item.renderItemWithArgs(frame, { result_id, tostring(result_count), class = 'block' }) end return item.renderItemWithArgs(frame, { result_id, class = 'block' }) end local function machine_group_heading(frame, machine_id) local rendered = render_machine_reference(machine_id) if rendered == '' then return '' end return '<div class="recipe-usage-machine"><div class="recipe-usage-machine-label">' .. rendered .. '</div></div>' end local function compare_recipe_ids(left_rid, right_rid) local left_recipe = recipe_list[left_rid + 1] local right_recipe = recipe_list[right_rid + 1] if not left_recipe or not right_recipe then return (tonumber(left_rid) or 0) < (tonumber(right_rid) or 0) end local left_result_id = common.trim(left_recipe[field_map.result] or '') local right_result_id = common.trim(right_recipe[field_map.result] or '') if left_result_id ~= right_result_id then return item_common.compareItemKeys(left_result_id, right_result_id) end local left_machine_id = common.trim(left_recipe[field_map.machine] or '') local right_machine_id = common.trim(right_recipe[field_map.machine] or '') if left_machine_id ~= right_machine_id then return item_common.compareItemKeys(left_machine_id, right_machine_id) end local left_time = tonumber(left_recipe[field_map.time]) or 0 local right_time = tonumber(right_recipe[field_map.time]) or 0 if left_time ~= right_time then return left_time < right_time end return left_rid < right_rid end local function sort_recipe_ids(recipe_ids) if type(recipe_ids) ~= 'table' or #recipe_ids <= 1 then return recipe_ids end table.sort(recipe_ids, compare_recipe_ids) return recipe_ids end local function split_recipe_groups_by_machine(recipe_ids) local ordered_groups = {} local groups_by_machine = {} for _, rid in ipairs(recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then local machine_id = common.trim(recipe[field_map.machine] or '') local group = groups_by_machine[machine_id] if not group then group = { machine_id = machine_id, recipe_ids = {}, } groups_by_machine[machine_id] = group ordered_groups[#ordered_groups + 1] = group end group.recipe_ids[#group.recipe_ids + 1] = rid end end local featured_groups = {} local remaining_ids = {} for _, group in ipairs(ordered_groups) do sort_recipe_ids(group.recipe_ids) if #group.recipe_ids >= 3 then featured_groups[#featured_groups + 1] = group else for _, rid in ipairs(group.recipe_ids) do remaining_ids[#remaining_ids + 1] = rid end end end table.sort(featured_groups, function(left_group, right_group) return item_common.compareItemKeys(left_group.machine_id, right_group.machine_id) end) sort_recipe_ids(remaining_ids) return featured_groups, remaining_ids end function p.getField(frame) local key = common.getArg(frame, 1, '') local field = common.getArg(frame, 2, '') if field == '' then return '' end local record = find_record(key) if not record then return '' end local craft = get_record_field(record, key, 'craft') if field == 'craft_machine' and craft then local machine_id = get_craft_field(craft, 'm', 'machine') if machine_id and machine_id ~= '' then return render_item_template(frame, machine_id) end return '' end if field == 'craft_time' and craft then return format_time(get_craft_field(craft, 't', 'time')) end if field == 'craft_exp' and craft then return common.toText(get_craft_field(craft, 'e', 'exp')) end local upgrade = get_record_field(record, key, 'upgrade') if field == 'upgrade_from' and upgrade then local from_id = get_craft_field(upgrade, 'f', 'from_machine') if from_id and from_id ~= '' then local from_name = item.getNameByKey(from_id) if from_name and from_name ~= '' then return '[[' .. from_name .. ']]' end end return '' end if field == 'upgrade_time' and upgrade then return format_time(get_craft_field(upgrade, 't', 'time')) end if field == 'upgrade_exp' and upgrade then return common.toText(get_craft_field(upgrade, 'e', 'exp')) end if field == 'construction_template_count' then local value = tonumber(get_record_field(record, key, field)) or 0 if value <= 0 then return '' end return tostring(value) end if field == 'energy_capacity' then local value = tonumber(get_record_field(record, key, field)) or 0 if value <= 0 then return '' end return tostring(value) end if field == 'prev_machine' then local prev_id = get_record_field(record, key, 'prev_machine') if prev_id and prev_id ~= '' then return render_item_template(frame, prev_id) end return '' end if field == 'next_machine' then local next_id = get_record_field(record, key, 'next_machine') if next_id and next_id ~= '' then return render_item_template(frame, next_id) end return '' end return common.toText(get_record_field(record, key, field)) end function p.ingredientList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local craft = get_record_field(record, key, 'craft') if not craft then return '' end return render_materials(frame, get_craft_field(craft, 'mat', 'materials')) end function p.upgradeIngredientList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local upgrade = get_record_field(record, key, 'upgrade') if not upgrade then return '' end return render_materials(frame, get_craft_field(upgrade, 'mat', 'materials')) end function p.craftInfo(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local out = {} local craft = get_record_field(record, key, 'craft') local craft_materials = get_craft_field(craft, 'mat', 'materials') if craft and not is_empty(craft_materials) then local machine_id = get_craft_field(craft, 'm', 'machine') local machine_display = '—' if machine_id and common.trim(machine_id) ~= '' then local machine_name = item.getNameByKey(machine_id) if machine_name and machine_name ~= '' then machine_display = '[[' .. machine_name .. ']]' end end out[#out + 1] = render_craft_table( '制造配方', '制造站', machine_display, '材料', render_materials(frame, craft_materials), '时间', format_time(get_craft_field(craft, 't', 'time')), '经验', common.toText(get_craft_field(craft, 'e', 'exp')) ) end local upgrade = get_record_field(record, key, 'upgrade') local upgrade_materials = get_craft_field(upgrade, 'mat', 'materials') if upgrade and not is_empty(upgrade_materials) then local from_id = get_craft_field(upgrade, 'f', 'from_machine') local from_display = '—' if from_id and common.trim(from_id) ~= '' then local from_name = item.getNameByKey(from_id) if from_name and from_name ~= '' then from_display = '[[' .. from_name .. ']]' end end out[#out + 1] = render_craft_table( '升级配方', '升级自', from_display, '材料', render_materials(frame, upgrade_materials), '时间', format_time(get_craft_field(upgrade, 't', 'time')), '经验', common.toText(get_craft_field(upgrade, 'e', 'exp')) ) end local css_out = (css.quickCall('Item') or '') .. (css.quickCall('RecipeUsage') or '') return css_out .. table.concat(out, '\n') end function p.recipeList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local machine_id = get_record_field(record, key, 'id') if not machine_id or machine_id == '' then return '' end load_recipes() local recipe_ids = recipe_cache[mw.ustring.lower(machine_id)] if not recipe_ids then return '该机器暂无独有配方。' end local has_time = false for _, rid in ipairs(recipe_ids) do local recipe = recipe_list[rid + 1] if recipe and recipe_time_text(recipe) ~= '' then has_time = true break end end local out = {} out[#out + 1] = '<div class="recipe-usage-table-wrap">' out[#out + 1] = '<table class="wikitable recipe-usage-table">' out[#out + 1] = '<tr><th>产物</th><th>材料</th>' if has_time then out[#out + 1] = '<th>时间</th>' end out[#out + 1] = '</tr>' local ordered_recipe_ids = {} for _, rid in ipairs(recipe_ids) do ordered_recipe_ids[#ordered_recipe_ids + 1] = rid end sort_recipe_ids(ordered_recipe_ids) for _, rid in ipairs(ordered_recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. render_recipe_result(frame, recipe) .. '</td>' out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' if has_time then out[#out + 1] = '<td>' .. recipe_time_text(recipe) .. '</td>' end out[#out + 1] = '</tr>' end end out[#out + 1] = '</table>' out[#out + 1] = '</div>' local css_out = (css.quickCall('Item') or '') .. (css.quickCall('RecipeUsage') or '') return css_out .. table.concat(out, '\n') end local function recipe_ids_have_time(recipe_ids) for _, rid in ipairs(recipe_ids) do local recipe = recipe_list[rid + 1] if recipe and recipe_time_text(recipe) ~= '' then return true end end return false end local function render_product_recipe_table(frame, recipe_ids, include_machine_column) local ordered_recipe_ids = {} for _, rid in ipairs(recipe_ids) do ordered_recipe_ids[#ordered_recipe_ids + 1] = rid end sort_recipe_ids(ordered_recipe_ids) local has_time = recipe_ids_have_time(ordered_recipe_ids) local out = {} out[#out + 1] = '<div class="recipe-usage-table-wrap">' out[#out + 1] = '<table class="wikitable recipe-usage-table">' out[#out + 1] = '<tr><th>产出</th>' if include_machine_column then out[#out + 1] = '<th>机器</th>' end out[#out + 1] = '<th>所需材料</th>' if has_time then out[#out + 1] = '<th>时间</th>' end out[#out + 1] = '</tr>' for _, rid in ipairs(ordered_recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. render_recipe_result(frame, recipe) .. '</td>' if include_machine_column then out[#out + 1] = '<td>' .. render_machine_reference(recipe[field_map.machine]) .. '</td>' end out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' if has_time then out[#out + 1] = '<td>' .. recipe_time_text(recipe) .. '</td>' end out[#out + 1] = '</tr>' end end out[#out + 1] = '</table>' out[#out + 1] = '</div>' return table.concat(out, '') end local function render_ingredient_recipe_table(frame, recipe_ids, current_item_id, include_machine_column) local ordered_recipe_ids = {} for _, rid in ipairs(recipe_ids) do ordered_recipe_ids[#ordered_recipe_ids + 1] = rid end sort_recipe_ids(ordered_recipe_ids) local out = {} out[#out + 1] = '<div class="recipe-usage-table-wrap">' out[#out + 1] = '<table class="wikitable recipe-usage-table">' out[#out + 1] = '<tr><th>产物</th>' if include_machine_column then out[#out + 1] = '<th>机器</th>' end out[#out + 1] = '<th>所需材料</th></tr>' for _, rid in ipairs(ordered_recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then local counts = material_counts_for_item(recipe[field_map.materials], current_item_id) if #counts > 0 then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. render_recipe_result(frame, recipe) .. '</td>' if include_machine_column then out[#out + 1] = '<td>' .. render_machine_reference(recipe[field_map.machine]) .. '</td>' end out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' out[#out + 1] = '</tr>' end end end out[#out + 1] = '</table>' out[#out + 1] = '</div>' return table.concat(out, '') end local function append_recipe_usage_sections(out, frame, recipe_ids, current_item_id, section_title, render_table) local featured_groups, remaining_ids = split_recipe_groups_by_machine(recipe_ids) out[#out + 1] = '<div class="recipe-usage-section">' out[#out + 1] = '<h3 class="recipe-usage-section-title">' .. section_title .. '</h3>' for _, group in ipairs(featured_groups) do local heading = machine_group_heading(frame, group.machine_id) if heading ~= '' then out[#out + 1] = heading end out[#out + 1] = render_table(frame, group.recipe_ids, current_item_id, false) end if #remaining_ids > 0 then if #featured_groups > 0 then out[#out + 1] = '<h4 class="recipe-usage-subtitle">其他制作站</h4>' end out[#out + 1] = render_table(frame, remaining_ids, current_item_id, true) end out[#out + 1] = '</div>' end function p.itemRecipes(frame) local item_key = common.getArg(frame, 1, '') if item_key == '' then item_key = common.getCurrentTitleText() end local item_id = item.getIdByKey(item_key) if not item_id or item_id == '' then return '' end load_recipes() local item_data = item_recipe_cache[mw.ustring.lower(item_id)] if not item_data then return '' end local product_ids = item_data.p or {} local ingredient_ids = item_data.i or {} local product_count = count_array(product_ids) local ingredient_count = count_array(ingredient_ids) if product_count == 0 and ingredient_count == 0 then return '' end local out = {} if product_count > 0 then append_recipe_usage_sections(out, frame, product_ids, item_id, '制作配方', function(current_frame, recipe_ids_for_table, _, include_machine_column) return render_product_recipe_table(current_frame, recipe_ids_for_table, include_machine_column) end) end if ingredient_count > 0 then if #out > 0 then out[#out + 1] = '' end append_recipe_usage_sections(out, frame, ingredient_ids, item_id, '用于制作', render_ingredient_recipe_table) end local css_out = (css.quickCall('Item') or '') .. (css.quickCall('RecipeUsage') or '') return css_out .. '<div class="recipe-usage">' .. table.concat(out, '\n') .. '</div>' end function p.machineAsIngredient(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local machine_id = get_record_field(record, key, 'id') if not machine_id or machine_id == '' then return '' end load_recipes() local item_data = item_recipe_cache[mw.ustring.lower(machine_id)] if not item_data or not item_data.i or count_array(item_data.i) == 0 then return '' end local ordered_recipe_ids = {} for _, rid in ipairs(item_data.i) do ordered_recipe_ids[#ordered_recipe_ids + 1] = rid end sort_recipe_ids(ordered_recipe_ids) local out = {} out[#out + 1] = '<div class="recipe-usage-table-wrap">' out[#out + 1] = '<table class="wikitable recipe-usage-table">' out[#out + 1] = '<tr><th>产物</th><th>所需数量</th></tr>' for _, rid in ipairs(ordered_recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then local counts = material_counts_for_item(recipe[field_map.materials], machine_id) if #counts > 0 then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. render_recipe_result(frame, recipe) .. '</td>' out[#out + 1] = '<td>' .. render_material_count_list(counts) .. '</td>' out[#out + 1] = '</tr>' end end end out[#out + 1] = '</table>' out[#out + 1] = '</div>' local css_out = (css.quickCall('Item') or '') .. (css.quickCall('RecipeUsage') or '') return css_out .. table.concat(out, '\n') end return p
该页面嵌入的页面:
模板:Tl
(
查看源代码
)
模块:ArgsUtil
(
查看源代码
)
模块:Machine/doc
(
查看源代码
)
模块:Template link
(
查看源代码
)
返回
模块:Machine
。
查看“︁模块:Machine”︁的源代码
来自星砂岛百科