Module:IDInfo

来自Minecraft基岩版开发Wiki
[创建 | 历史 | 清除缓存]文档页面
此模块没有文档页面。如果你知道如何使用模块,请创建它。
local p = {}
local merge = require('Module:ProcessArgs').merge

p.ObjectType = {
	['biome'] = 'Biome',
	['block'] = 'Block',
	['effect'] = 'Effect',
	['enchantment'] = 'Enchantment',
	['entity'] = 'Entity',
	['environment'] = 'Env',
	['item'] = 'Item',
	['mod'] = 'Mod',
}

function p.getObjectType(str)
	str = mw.ustring.lower(str)
	if p.ObjectType[str] ~= nil then
		return p.ObjectType[str]
	elseif str == 'env' then
		return 'Env'
	elseif mw.title.getCurrentTitle():inNamespaces(3004, 3005) then
		return 'Mod'
	else
		return 'Other'
	end
end

function p.getIdentifier(str, namespace)
	if str == '-' then
		return '-', '-'
	end
	local config = mw.text.jsonDecode(mw.title.makeTitle('Data', 'IDInfo'):getContent() or '{}')
	local function parse(_str, data)
		if string.match(_str, '^minecraft:[^:]+:%d+$') then
			return string.match(_str, '^(minecraft:[^:]+):(%d+)$')
		elseif namespace and not string.match(_str, '^[^:]+:[^:]+:?.*$') then
			return 'minecraft:' .. _str, data
		else
			return _str, data
		end
	end

	local identifier, data = parse(str, nil)
	if config.IDTranslation and config.IDTranslation[identifier] then
		identifier, data = parse(config.IDTranslation[identifier], data)
	end
	return identifier, data or 0
end

function p.getObjectData(objectType, subPage)
	return mw.text.jsonDecode(mw.title.makeTitle('Data', objectType .. '/' .. subPage):getContent() or '{}')
end

function p.getValue(objectData, data, key)
	if data ~= nil and objectData.Data then
		return (objectData.Data[(tonumber(data) or 0) + 1] and objectData.Data[(tonumber(data) or 0) + 1][key]) or
				(objectData.Data[1] and objectData.Data[1][key])
	end
	return objectData[key]
end

function p.getKey(objectType, identifier, data)
	local Key = p.getValue(p.getObjectData(objectType, identifier), data, 'Key')
	if Key then
		return Key
	elseif objectType == 'Biome' then
		return '-'
	elseif objectType == 'Block' then
		return string.gsub('tile.' .. identifier .. '.name', 'minecraft:', '', 1)
	elseif objectType == 'Effect' then
		return string.gsub('effect.' .. identifier, ':', '.')
	elseif objectType == 'Enchantment' then
		return string.gsub('enchantment.' .. identifier, ':', '.')
	elseif objectType == 'Entity' then
		return string.gsub('entity.' .. identifier .. '.name', 'minecraft:', '', 1)
	elseif objectType == 'Env' then
		return '-'
	elseif objectType == 'Item' then
		return string.gsub('item.' .. identifier .. '.name', 'minecraft:', '', 1)
	else
		return '-'
	end
end

function p.getName(objectType, identifier, data, language)
	local name = mw.text.jsonDecode(mw.getCurrentFrame():expandTemplate { title = 'Data:Lang/en_US' })[
			p.getKey(objectType, identifier, data)]
	if language == 'en_US' or language == 'en' or language == 'English' or language == nil then
		return name
	elseif language == 'zh_CN' or language == 'zh' or language == 'Chinese' then
		return require('Module:Autolink').invlink(name, 'nolink', objectType .. 'Sprite')
	end
	return nil
end

function p.getNumericID(objectType, identifier)
	return p.getObjectData(objectType, identifier).NumericID
end

function p.getTags(objectType, identifier, data)
	return p.getValue(p.getObjectData(objectType, identifier), data, 'Tags')
end

function p.getMainInfo(objectType, identifier, data, language)
	return p.getName(objectType, identifier, data, language),
			p.getNumericID(objectType, identifier),
			p.getKey(objectType, identifier, data)
end

function p.main(f)
	local args = merge(true)
	local language, mode, objectType = args.language or 'zh_CN', mw.ustring.lower(args.mode), p.getObjectType(args.type)
	local identifier, data = p.getIdentifier(args.id or '-',
		objectType == 'Block' or objectType == 'Entity' or objectType == 'Item')
	data = args.data or data
	if mode == 'name' then
		return p.getName(objectType, identifier, data, language)
	elseif mode == 'numericid' then
		return p.getNumericID(objectType, identifier)
	elseif mode == 'key' then
		return p.getKey(objectType, identifier, data)
	elseif mode == 'tags' then
		return table.concat(p.getTags(objectType, identifier, data), ',')
	end
	return nil
end

function p.infobox(f)
	local args = merge(true)
	local objectType = p.getObjectType(mw.getCurrentFrame().args.ObjectType)
	local object = require('Module:IDInfo/' .. objectType)
	local infoboxArgs = {
		image = 'No_image.svg',
		invimage = 'none',
		subheader = object.subheader,
		footer = args.notes or args.footer,
		title = args.namespaceid or args.title or
				mw.ustring.gsub(mw.ustring.gsub(mw.ustring.lower(mw.title.getCurrentTitle().text), '_%(.*%)$', ''), ' ', '_')
	}
	local dictionary = {}
	local Attributes = {
		identical = {}
	}
	local Data = {}
	if (
			args.autocomplete == 'true' or
					(args.autocomplete ~= 'false' and mw.title.getCurrentTitle():inNamespaces(0, 3000, 3001))) then
		local objectData = p.getObjectData(objectType, infoboxArgs.title)
		for attribute, value in pairs(objectData) do
			Attributes.identical[attribute] = value
		end
		if type(Attributes.identical.Data) == 'table' then
			local images = {}
			for data, value in ipairs(objectData.Data) do
				if type(value) == 'table' then
					if Attributes[data] == nil then
						Attributes[data] = {}
						table.insert(Data, data)
					end
					if value.Key then
						local name = p.getName(objectType, infoboxArgs.title, data - 1, 'en_US') or 'none'
						table.insert(images, name .. '.png')
						infoboxArgs['invimage' .. data] = name
					end
					for key, v in pairs(value) do
						Attributes[data][mw.ustring.lower(key)] = v
					end
				end
			end
			args.image = args.image or table.concat(images, ';')
		end
		Attributes.identical.Data = nil
	end
	for _, attribute in ipairs(object.attributeList) do
		dictionary[mw.ustring.lower(attribute)] = attribute
		local temp = p.getObjectData(objectType, attribute)
		if temp[infoboxArgs.title] ~= nil then
			if type(temp[infoboxArgs.title]) == 'table' then
				for data, value in pairs(temp[infoboxArgs.title]) do
					Attributes[data][attribute] = value
				end
			else
				Attributes.identical[attribute] = temp[infoboxArgs.title]
			end
		end
	end
	for i, v in pairs(args) do
		if type(i) == 'string' then
			local name, data = mw.ustring.match(i, '^(.-)(%d*)$')
			data = tonumber(data) and tonumber(data) + 1 or 'identical'
			if name == 'image' then
				infoboxArgs[i] = v
			elseif name == 'invimage' then
				infoboxArgs[name .. data] = v
			else
				if dictionary[name] then
					if Attributes[data] == nil then
						Attributes[data] = {}
						table.insert(Data, data)
					end
					Attributes[data][dictionary[name]] = v
				end
			end
		end
	end
	infoboxArgs.invimage0 = infoboxArgs.invimageidentical
	infoboxArgs.invimageidentical = nil
	Attributes = object.format(Attributes)
	table.sort(Data)
	local function getAttribute(data, attribute, index)
		local temporaryAttribute = Attributes[data][attribute]
		if type(temporaryAttribute) == 'table' then
			local i = 1
			if type(index) == 'table' then
				while (type(temporaryAttribute) == 'table') do
					temporaryAttribute = temporaryAttribute[index[i] or 1] or temporaryAttribute[1]
					i = i + 1
				end
			else
				while (type(temporaryAttribute) == 'table') do
					temporaryAttribute = temporaryAttribute[index or 1] or temporaryAttribute[1]
					i = i + 1
				end
			end
		end
		return temporaryAttribute
	end

	local function getIdentity(row)
		if type(row.field) == 'table' then
			for _, subrow in ipairs(row.field) do
				if type(subrow) == 'table' and not getIdentity(subrow) then
					return false
				end
			end
		elseif row.field ~= nil and Data[1] ~= nil then
			local attribute = object.attributeList[row.field]
			local temp = getAttribute(Data[1], attribute, row.index)
			for _, data in ipairs(Data) do
				if temp ~= getAttribute(data, attribute, row.index) then
					return false
				end
			end
			Attributes.identical[attribute] = temp or Attributes.identical[attribute]
		end
		return true
	end

	for i, row in ipairs(object.infoboxRows) do
		if type(row) ~= 'table' then
			table.remove(object.infoboxRows, i)
		else
			object.infoboxRows[i]['identical'] = getIdentity(row)
		end
	end
	local function getInfoboxRows(data)
		local function getHtml(label, field, isSubRow)
			if field == nil then
				return ''
			end
			local result = tostring(mw.html.create('div'):addClass('infobox-row')
				:tag('div'):addClass('infobox-cell-header'):wikitext("'''" .. label .. "'''"):done()
				:tag('div'):addClass('infobox-cell-data'):wikitext(field):done()
				:done())
			if isSubRow then
				return '<div class="infobox-rows subinfobox">' .. result .. '</div>'
			end
			return result
		end

		local function rowParser(row, isSubRow)
			if type(row) ~= 'table' then
				return ''
			end
			local field = ''
			if type(row.field) == 'table' then
				local temp = {}
				for _, subrow in ipairs(row.field) do
					table.insert(temp, rowParser(subrow, true))
				end
				field = table.concat(temp, '')
				if field ~= '' then
					return getHtml(row.label, field, isSubRow)
				end
			elseif row.field ~= nil then
				local attribute = object.attributeList[row.field]
				field = getAttribute(data, attribute, row.index)
				if field ~= '' then
					return getHtml(row.label, field, isSubRow)
				end
			end
			return ''
		end

		local temp = {}
		for _, row in ipairs(object.infoboxRows) do
			if data == 'identical' == row.identical then
				table.insert(temp, rowParser(row, false))
			end
		end
		local rows = table.concat(temp, '')
		if rows ~= '' then
			return (
					data ~= 'identical' and
							mw.ustring.format('</div><div class="infobox-subheader">数据值:%d</div><div class="infobox-rows">',
								tonumber(data) - 1) or '') .. rows
		end
		return ''
	end

	local infoboxRows = {
		getInfoboxRows('identical')
	}
	for _, data in ipairs(Data) do
		table.insert(infoboxRows, getInfoboxRows(data))
	end
	infoboxArgs.rows = table.concat(infoboxRows, '')
	return require('Module:Infobox').infobox(infoboxArgs)
end

return p