125 lines
3.8 KiB
Lua
125 lines
3.8 KiB
Lua
local NEWLINE = "\n"
|
|
local DESCRIPTION = "Command Tool"
|
|
local MAX_CMD_TOOLTIP_LEN = 48
|
|
|
|
local split_commands = function(commands_string)
|
|
return string.split(commands_string, NEWLINE)
|
|
end
|
|
|
|
local set_commands = function(itemstack, commands_string)
|
|
local meta = itemstack:get_meta()
|
|
meta:set_string("cmd", commands_string)
|
|
local cmds = split_commands(commands_string)
|
|
local first_cmd
|
|
if #cmds >= 1 then
|
|
first_cmd = cmds[1]
|
|
if string.len(first_cmd) > MAX_CMD_TOOLTIP_LEN then
|
|
first_cmd = string.sub(first_cmd, 1, MAX_CMD_TOOLTIP_LEN) .. " (…)"
|
|
end
|
|
local tooltip = DESCRIPTION .. NEWLINE .. first_cmd
|
|
if #cmds == 2 then
|
|
tooltip = tooltip .. NEWLINE .. string.format("… and %d more command", #cmds - 1)
|
|
elseif #cmds > 2 then
|
|
tooltip = tooltip .. NEWLINE .. string.format("… and %d more commands", #cmds - 1)
|
|
end
|
|
meta:set_string("description", tooltip)
|
|
else
|
|
meta:set_string("description", "")
|
|
end
|
|
return itemstack
|
|
end
|
|
|
|
-- Returns a table of commands in a command tool itemstack
|
|
local get_commands = function(itemstack)
|
|
local meta = itemstack:get_meta()
|
|
local cmd_str = meta:get_string("cmd")
|
|
local cmds = split_commands(cmd_str)
|
|
return cmds
|
|
end
|
|
|
|
local execute_command = function(itemstack, player, pointed_thing)
|
|
local player_name = player:get_player_name()
|
|
local cmds = get_commands(itemstack)
|
|
if not cmds then
|
|
return
|
|
end
|
|
local player_privs = minetest.get_player_privs(player_name)
|
|
for c=1, #cmds do
|
|
local cmd = cmds[1]
|
|
-- Split command string into command name and parameters
|
|
local cmd_split = string.split(cmd, " ", false, 1)
|
|
local cmd_name
|
|
-- Perform some checks:
|
|
-- 1. Command exists
|
|
-- 2. Player has all required privileges
|
|
if cmd_split then
|
|
-- Get command name
|
|
cmd_name = cmd_split[1]
|
|
local cmd_params = ""
|
|
if cmd_split[2] then
|
|
cmd_params = cmd_split[2]
|
|
end
|
|
local def = minetest.registered_chatcommands[cmd_name]
|
|
if def then
|
|
local required_privs = def.privs
|
|
for priv, _ in pairs(required_privs) do
|
|
if player_privs[priv] ~= true then
|
|
minetest.chat_send_player(player_name, "Insufficient privileges for using command “"..cmd_name.."”! You need the “"..priv.."” privilege.")
|
|
return
|
|
end
|
|
end
|
|
-- All tests survived!
|
|
-- Call the command
|
|
def.func(player_name, cmd_params)
|
|
else
|
|
minetest.chat_send_player(player_name, "The command “"..cmd_name.."” does not exist!")
|
|
return
|
|
end
|
|
else
|
|
minetest.chat_send_player(player_name, "Invalid command!")
|
|
return
|
|
end
|
|
-- One iteration is done. We continue with the next command.
|
|
end
|
|
end
|
|
|
|
local open_command_configuration = function(itemstack, player, pointed_thing)
|
|
local player_name = player:get_player_name()
|
|
local commands = get_commands(itemstack)
|
|
local commands_str = ""
|
|
if commands then
|
|
for c=1, #commands do
|
|
commands_str = commands_str .. commands[c]
|
|
if c < #commands then
|
|
commands_str = commands_str .. "\n"
|
|
end
|
|
end
|
|
end
|
|
local formspec =
|
|
"size[6,6]"..
|
|
"textarea[0.25,0;6,5;commands;Commands:;"..minetest.formspec_escape(commands_str).."]"..
|
|
"button_exit[0.5,5;2,1;ok;OK]"..
|
|
"button_exit[3.5,5;2,1;cancel;Cancel]"
|
|
minetest.show_formspec(player_name, "cmdtool", formspec)
|
|
end
|
|
|
|
minetest.register_tool("cmdtool:cmdtool", {
|
|
description = DESCRIPTION,
|
|
inventory_image = "cmdtool_cmdtool.png",
|
|
wield_imagee = "cmdtool_cmdtool.png",
|
|
on_use = execute_command,
|
|
on_place = open_command_configuration,
|
|
on_secondary_use = open_command_configuration,
|
|
})
|
|
|
|
-- Set commands
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "cmdtool" and fields.ok and fields.commands ~= nil then
|
|
local wield_tool = player:get_wielded_item()
|
|
if wield_tool:get_name() == "cmdtool:cmdtool" then
|
|
local updated_tool = set_commands(wield_tool, fields.commands)
|
|
player:set_wielded_item(updated_tool)
|
|
end
|
|
end
|
|
end)
|