2017-06-14 23:37:18 -07:00
|
|
|
--[[ LICENSE HEADER
|
|
|
|
|
|
|
|
MIT Licensing
|
|
|
|
|
|
|
|
Copyright © 2017 Jordan Irwin
|
|
|
|
|
|
|
|
See: LICENSE.txt
|
|
|
|
--]]
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- List Items API
|
|
|
|
--
|
|
|
|
-- @script api.lua
|
|
|
|
|
2017-06-14 23:37:18 -07:00
|
|
|
|
2017-07-23 15:24:27 -07:00
|
|
|
-- Boilerplate to support localized strings if intllib mod is installed.
|
|
|
|
local S
|
2017-07-24 12:00:01 -07:00
|
|
|
if core.global_exists('intllib') then
|
2017-07-23 15:24:27 -07:00
|
|
|
if intllib.make_gettext_pair then
|
|
|
|
S = intllib.make_gettext_pair()
|
|
|
|
else
|
|
|
|
S = intllib.Getter()
|
|
|
|
end
|
|
|
|
else
|
|
|
|
S = function(s) return s end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Valid option switches.
|
|
|
|
--
|
|
|
|
-- @table known_switches
|
|
|
|
-- @local
|
2017-08-01 12:28:08 -07:00
|
|
|
-- @field -v Display descriptions.
|
|
|
|
local known_switches = {'-v',}
|
|
|
|
|
2017-08-03 14:35:34 -07:00
|
|
|
--- Valid list types.
|
|
|
|
--
|
|
|
|
-- @table known_lists
|
|
|
|
-- @local
|
|
|
|
local known_lists = {
|
|
|
|
'items',
|
|
|
|
'entities',
|
2017-08-03 21:47:58 -07:00
|
|
|
'nodes',
|
2017-08-03 14:35:34 -07:00
|
|
|
'ores',
|
|
|
|
}
|
|
|
|
|
2017-08-03 18:09:06 -07:00
|
|
|
if listitems.enable_mobs then
|
|
|
|
table.insert(known_lists, 'mobs')
|
|
|
|
end
|
|
|
|
|
2017-08-01 12:28:08 -07:00
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Checks if a parameter is a switch beginning with "-".
|
|
|
|
--
|
|
|
|
-- @function isSwitch
|
|
|
|
-- @local
|
|
|
|
-- @tparam string param String that is checked for dash prefix.
|
|
|
|
-- @treturn boolean ***true*** if parameter type is "switch" prefixed with dash.
|
2017-08-01 12:28:08 -07:00
|
|
|
local function isSwitch(param)
|
|
|
|
if param then
|
|
|
|
return #param == 2 and string.find(param, '-') == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Checks if value is contained in list.
|
|
|
|
--
|
|
|
|
-- @function listContains
|
|
|
|
-- @local
|
|
|
|
-- @tparam table tlist List to be iterated.
|
|
|
|
-- @tparam string v String to search for in list.
|
|
|
|
-- @treturn boolean ***true*** if string found within list.
|
2017-08-01 12:28:08 -07:00
|
|
|
local function listContains(tlist, v)
|
|
|
|
for index, value in ipairs(tlist) do
|
|
|
|
if v == value then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Retrieves a simplified table containing string names of registered items or entities.
|
|
|
|
--
|
|
|
|
-- @function getRegistered
|
|
|
|
-- @local
|
|
|
|
-- @tparam string r_type Must be either "items" or "entities".
|
2017-08-03 11:09:16 -07:00
|
|
|
-- @treturn table Either a list of registered item or entity names & descriptions.
|
|
|
|
-- @note Ore names are located in the "ore" field of the registered tables
|
2017-08-02 12:55:42 -07:00
|
|
|
local function getRegistered(r_type)
|
2017-08-03 11:09:16 -07:00
|
|
|
-- Default is "items"
|
|
|
|
r_type = r_type or 'items'
|
2017-08-01 12:28:08 -07:00
|
|
|
|
2017-08-02 12:55:42 -07:00
|
|
|
local o_names = {}
|
|
|
|
local objects = {}
|
|
|
|
local o_temp = {}
|
2017-08-01 12:28:08 -07:00
|
|
|
|
2017-08-03 11:09:16 -07:00
|
|
|
if r_type == 'entities' then
|
2017-08-02 12:55:42 -07:00
|
|
|
o_temp = core.registered_entities
|
2017-08-03 21:47:58 -07:00
|
|
|
elseif r_type == 'nodes' then
|
|
|
|
o_temp = core.registered_nodes
|
2017-08-03 11:09:16 -07:00
|
|
|
elseif r_type == 'ores' then
|
|
|
|
o_temp = core.registered_ores
|
2017-08-03 18:09:06 -07:00
|
|
|
elseif r_type == 'mobs' then
|
|
|
|
o_temp = mobs.spawning_mobs
|
2017-08-03 11:09:16 -07:00
|
|
|
else
|
|
|
|
o_temp = core.registered_items
|
2017-08-01 12:28:08 -07:00
|
|
|
end
|
2017-06-14 23:37:18 -07:00
|
|
|
|
2017-08-02 12:55:42 -07:00
|
|
|
for name, def in pairs(o_temp) do
|
2017-08-03 11:09:16 -07:00
|
|
|
-- Ore names are located in the 'ore' field of the table
|
|
|
|
if r_type == 'ores' then
|
|
|
|
name = def.ore
|
2017-08-03 18:09:06 -07:00
|
|
|
elseif r_type == 'mobs' then
|
|
|
|
def = {}
|
2017-08-03 11:09:16 -07:00
|
|
|
end
|
|
|
|
|
2017-08-02 12:55:42 -07:00
|
|
|
table.insert(objects, {name=name, descr=def.description,})
|
|
|
|
table.insert(o_names, name)
|
2017-08-01 14:07:57 -07:00
|
|
|
end
|
|
|
|
|
2017-08-02 12:55:42 -07:00
|
|
|
-- FIXME: More efficient method to sort output?
|
|
|
|
table.sort(o_names)
|
|
|
|
local o_sorted = {}
|
|
|
|
for i, name in ipairs(o_names) do
|
|
|
|
for I, entity in ipairs(objects) do
|
2017-08-01 14:07:57 -07:00
|
|
|
if entity.name == name then
|
2017-08-02 12:55:42 -07:00
|
|
|
table.insert(o_sorted, entity)
|
2017-08-01 14:07:57 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-02 12:55:42 -07:00
|
|
|
return o_sorted
|
2017-08-02 12:42:14 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Compares a string from a list of substrings.
|
|
|
|
--
|
|
|
|
-- @function compareSubstringList
|
|
|
|
-- @tparam table ss_list
|
|
|
|
-- @tparam string s_value
|
|
|
|
-- @treturn boolean
|
2017-06-14 23:37:18 -07:00
|
|
|
local function compareSubstringList(ss_list, s_value)
|
|
|
|
for index, substring in ipairs(ss_list) do
|
|
|
|
-- Tests for substring (does not need to match full string)
|
|
|
|
if string.find(s_value, substring) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Extracts switches prefixed with "-" from parameter list.
|
|
|
|
--
|
|
|
|
-- @function extractSwitches
|
|
|
|
-- @local
|
|
|
|
-- @tparam table plist
|
|
|
|
-- @treturn table
|
2017-08-01 12:28:08 -07:00
|
|
|
local function extractSwitches(plist)
|
|
|
|
local switches = {}
|
|
|
|
local params = {}
|
|
|
|
if plist ~= nil then
|
|
|
|
for i, p in ipairs(plist) do
|
|
|
|
-- Check if string starts with "-"
|
|
|
|
if isSwitch(p) then
|
|
|
|
table.insert(switches, p)
|
|
|
|
else
|
|
|
|
table.insert(params, p)
|
|
|
|
end
|
|
|
|
end
|
2017-06-14 23:37:18 -07:00
|
|
|
end
|
|
|
|
|
2017-08-01 12:28:08 -07:00
|
|
|
return {switches, params}
|
2017-06-14 23:37:18 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Replaces duplicates found in a list.
|
|
|
|
--
|
|
|
|
-- @function removeListDuplicates
|
|
|
|
-- @local
|
|
|
|
-- @tparam table tlist
|
|
|
|
-- @treturn table
|
2017-06-14 23:37:18 -07:00
|
|
|
local function removeListDuplicates(tlist)
|
|
|
|
local cleaned = {}
|
2017-07-24 14:27:54 -07:00
|
|
|
if tlist ~= nil then
|
|
|
|
for index, value in ipairs(tlist) do
|
|
|
|
if not listContains(cleaned, value) then
|
|
|
|
table.insert(cleaned, value)
|
|
|
|
end
|
2017-06-14 23:37:18 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return cleaned
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Searches & formats list for matching strings.
|
|
|
|
--
|
|
|
|
-- @function formatMatching
|
|
|
|
-- @local
|
|
|
|
-- @tparam string player
|
|
|
|
-- @tparam table nlist
|
|
|
|
-- @tparam table params
|
|
|
|
-- @tparam table switches
|
|
|
|
-- @tparam boolean lower
|
|
|
|
-- @treturn table
|
2017-08-02 16:53:13 -07:00
|
|
|
local function formatMatching(player, nlist, params, switches, lower)
|
|
|
|
-- Defaults to case-insensitive
|
|
|
|
lower = lower == nil or lower == true
|
|
|
|
|
2017-07-24 15:21:17 -07:00
|
|
|
local matching = {}
|
|
|
|
|
2017-08-01 12:28:08 -07:00
|
|
|
local show_descr = false
|
|
|
|
if switches ~= nil then
|
|
|
|
show_descr = listContains(switches, '-v')
|
|
|
|
end
|
|
|
|
|
2017-08-01 14:07:57 -07:00
|
|
|
core.chat_send_player(player, '\n' .. S('Searching in names ...'))
|
2017-08-01 12:28:08 -07:00
|
|
|
|
|
|
|
if params == nil then
|
|
|
|
params = {}
|
|
|
|
end
|
|
|
|
|
2017-07-24 15:21:17 -07:00
|
|
|
-- Use entire list if no parameters supplied
|
|
|
|
if next(params) == nil then
|
2017-08-01 13:39:51 -07:00
|
|
|
for i, item in ipairs(nlist) do
|
2017-08-01 13:40:35 -07:00
|
|
|
if show_descr and item.descr ~= nil then
|
2017-08-01 13:39:51 -07:00
|
|
|
table.insert(matching, item.name .. ' (' .. item.descr .. ')')
|
|
|
|
else
|
|
|
|
table.insert(matching, item.name)
|
2017-08-01 12:28:08 -07:00
|
|
|
end
|
|
|
|
end
|
2017-07-24 15:21:17 -07:00
|
|
|
else
|
|
|
|
-- Fill matching list
|
2017-08-01 13:40:35 -07:00
|
|
|
for i, item in ipairs(nlist) do
|
2017-08-02 16:53:13 -07:00
|
|
|
local name = item.name
|
|
|
|
-- Case-insensitive matching
|
|
|
|
if lower then
|
|
|
|
name = string.lower(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
if compareSubstringList(params, name) then
|
2017-08-01 13:40:35 -07:00
|
|
|
if show_descr and item.descr ~= nil then
|
|
|
|
table.insert(matching, item.name .. ' (' .. item.descr .. ')')
|
2017-08-01 12:28:08 -07:00
|
|
|
else
|
2017-08-01 13:40:35 -07:00
|
|
|
table.insert(matching, item.name)
|
2017-08-01 12:28:08 -07:00
|
|
|
end
|
2017-07-24 15:21:17 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return matching
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Setting to display a bulleted list.
|
|
|
|
--
|
|
|
|
-- @setting listitems.bullet_list
|
|
|
|
-- @settype boolean
|
2017-08-03 18:02:38 -07:00
|
|
|
-- @default true
|
2017-07-24 02:45:12 -07:00
|
|
|
local bullet_list = core.settings:get_bool('listitems.bullet_list')
|
|
|
|
if bullet_list == nil then
|
|
|
|
-- Default is true
|
|
|
|
bullet_list = true
|
|
|
|
end
|
|
|
|
|
|
|
|
local bullet = ''
|
|
|
|
if bullet_list then
|
|
|
|
bullet = S('•') .. ' '
|
|
|
|
end
|
|
|
|
|
2017-07-24 12:06:31 -07:00
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Displays list to player.
|
|
|
|
--
|
|
|
|
-- @function displayList
|
|
|
|
-- @local
|
|
|
|
-- @tparam string player
|
|
|
|
-- @tparam table dlist
|
2017-07-24 14:32:39 -07:00
|
|
|
local function displayList(player, dlist)
|
|
|
|
if dlist ~= nil then
|
|
|
|
for i, n in ipairs(dlist) do
|
|
|
|
core.chat_send_player(player, bullet .. n)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- Show player number of items listed
|
2017-08-01 14:07:57 -07:00
|
|
|
core.chat_send_player(player, S('Objects listed:') .. ' ' .. tostring(#dlist))
|
2017-07-24 14:32:39 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- Custom registration function for chat commands.
|
|
|
|
--
|
|
|
|
-- @function registerChatCommand
|
|
|
|
-- @local
|
|
|
|
-- @tparam string cmd_name
|
|
|
|
-- @tparam table def
|
2017-07-24 14:30:05 -07:00
|
|
|
local function registerChatCommand(cmd_name, def)
|
|
|
|
listitems.logInfo('Registering chat command "' .. cmd_name .. '"')
|
|
|
|
core.register_chatcommand(cmd_name, def)
|
|
|
|
end
|
2017-07-24 12:06:31 -07:00
|
|
|
|
2017-07-24 12:00:01 -07:00
|
|
|
|
2017-08-02 17:36:00 -07:00
|
|
|
--- *listitems* base function.
|
|
|
|
--
|
|
|
|
-- Lists registered items or entities.
|
|
|
|
--
|
|
|
|
-- @function listitems.list
|
|
|
|
-- @tparam string player Name of player to receive message output.
|
2017-08-03 11:09:16 -07:00
|
|
|
-- @tparam string l_type Objects to list (either "items", "entities", or "ores").
|
2017-08-03 16:36:25 -07:00
|
|
|
-- @tparam string switches String list of switch options for manipulating output.
|
|
|
|
-- @tparam string params String list of parameters.
|
2017-08-02 17:36:00 -07:00
|
|
|
-- @tparam boolean lower Case-insensitive matching if ***true***.
|
|
|
|
-- @treturn boolean
|
2017-08-03 16:36:25 -07:00
|
|
|
function listitems.list(player, l_type, switches, params, lower)
|
2017-08-02 17:03:32 -07:00
|
|
|
-- Default list type is "items"
|
|
|
|
l_type = l_type or 'items'
|
2017-08-02 16:56:51 -07:00
|
|
|
lower = lower == nil or lower == true
|
2017-08-02 12:43:02 -07:00
|
|
|
|
2017-08-03 16:34:42 -07:00
|
|
|
if not listContains(known_lists, l_type) then
|
2017-08-03 16:35:03 -07:00
|
|
|
listitems.logWarn('listitems.list called with unknown list type: ' .. tostring(l_type))
|
2017-08-02 12:43:02 -07:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2017-08-02 17:03:32 -07:00
|
|
|
if type(params) == 'string' then
|
|
|
|
if lower then
|
|
|
|
-- Make parameters case-insensitive
|
|
|
|
-- FIXME: Switches should not be case-insensitive
|
|
|
|
params = string.lower(params)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Split parameters into list & remove duplicates
|
|
|
|
params = removeListDuplicates(string.split(params, ' '))
|
|
|
|
elseif lower then
|
|
|
|
for i in pairs(params) do
|
|
|
|
params[i] = string.lower(params[i])
|
|
|
|
end
|
2017-08-02 16:56:51 -07:00
|
|
|
end
|
|
|
|
|
2017-08-02 17:03:32 -07:00
|
|
|
if type(switches) == 'string' then
|
|
|
|
switches = string.split(switches, ' ')
|
|
|
|
end
|
2017-08-02 12:43:02 -07:00
|
|
|
|
|
|
|
for i, s in ipairs(switches) do
|
|
|
|
if not listContains(known_switches, s) then
|
2017-08-03 14:34:38 -07:00
|
|
|
core.chat_send_player(player, S('Error: Unknown option:') .. ' ' .. s)
|
2017-08-02 12:43:02 -07:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
all_objects = getRegistered(l_type)
|
2017-08-02 17:00:33 -07:00
|
|
|
local matched_items = formatMatching(player, all_objects, params, switches, lower)
|
2017-08-02 12:43:02 -07:00
|
|
|
|
|
|
|
displayList(player, matched_items)
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-03 15:09:33 -07:00
|
|
|
--- Helper function called from within chat commands.
|
|
|
|
--
|
|
|
|
-- @function list
|
|
|
|
-- @local
|
|
|
|
-- @param player
|
|
|
|
-- @param params
|
|
|
|
local function list(player, l_type, params)
|
|
|
|
local switches = string.split(params, ' ')
|
|
|
|
|
|
|
|
local type_ok = true
|
|
|
|
if not l_type then
|
|
|
|
core.chat_send_player(player, S('Error: Must specify list type'))
|
|
|
|
type_ok = false
|
|
|
|
elseif not listContains(known_lists, l_type) then
|
|
|
|
core.chat_send_player(player, S('Error: Unknown list type:') .. ' ' .. l_type)
|
|
|
|
type_ok = false
|
|
|
|
end
|
|
|
|
|
|
|
|
if not type_ok then
|
|
|
|
core.chat_send_player(player, S('Recognized list types:') .. ' ' .. table.concat(known_lists, ', '))
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
switches = extractSwitches(switches)
|
|
|
|
params = removeListDuplicates(switches[2])
|
|
|
|
switches = switches[1]
|
|
|
|
|
|
|
|
-- DEBUG:
|
|
|
|
if listitems.debug then
|
|
|
|
listitems.log('action', 'List type: ' .. l_type)
|
|
|
|
listitems.log('action', 'Switches:')
|
|
|
|
for i, s in ipairs(switches) do
|
|
|
|
listitems.log('action', ' ' .. s)
|
|
|
|
end
|
|
|
|
listitems.log('action', 'Parameters:')
|
|
|
|
for i, p in ipairs(params) do
|
|
|
|
listitems.log('action', ' ' .. p)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-03 16:36:25 -07:00
|
|
|
return listitems.list(player, l_type, switches, params)
|
2017-08-03 15:09:33 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-08-03 17:06:10 -07:00
|
|
|
if listitems.enable_generic then
|
|
|
|
--- General *list* chat command
|
|
|
|
--
|
|
|
|
-- @chatcmd list
|
|
|
|
-- @chatparam type
|
|
|
|
-- @chatparam [-v]
|
|
|
|
-- @chatparam [string1]
|
|
|
|
-- @chatparam [string2]
|
|
|
|
-- @chatparam ...
|
|
|
|
-- @treturn boolean
|
|
|
|
registerChatCommand('list', {
|
|
|
|
params = S('type') .. ' [-v] [' .. S('string1') .. '] [' .. S('string2') .. '] ...',
|
|
|
|
description = S('List registered items or entities'),
|
|
|
|
func = function(player, params)
|
|
|
|
local params = string.split(params, ' ')
|
|
|
|
local l_type = table.remove(params, 1)
|
|
|
|
params = table.concat(params, ' ')
|
|
|
|
|
|
|
|
return list(player, l_type, params)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|
2017-08-03 15:10:18 -07:00
|
|
|
|
|
|
|
|
|
|
|
-- Chat commands aliases.
|
|
|
|
for i, cmd in ipairs(known_lists) do
|
|
|
|
registerChatCommand('list' .. cmd, {
|
|
|
|
params = '[-v] [' .. S('string1') .. '] [' .. S('string2') .. '] ...',
|
|
|
|
description = S('List registered ' .. cmd),
|
|
|
|
func = function(player, params)
|
|
|
|
return list(player, cmd, params)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|