minetest_cmdtool/init.lua
2018-01-16 21:19:59 +01:00

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)