--[[
This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see .
]]
commands = {}
command_color = {
error = 0xFFFF6666,
usage = 0xFF6666FF,
success = 0xFF66FF66,
text = 0xFFDDDDFF,
}
function command_deregister(command)
if commands[command] ~= nil then
commands[command] = nil
end
end
function command_msg(status, neth, msg)
if type(neth) == "string" then
irc.write(neth..": "..msg)
else
net_send(neth, common.net_pack("BIz", PKT_CHAT_ADD_TEXT, command_color[status], msg))
end
end
function command_register(settings)
local this = {
command = string.lower(settings.command),
permission = settings.permission,
usage = settings.usage,
func = settings.func
} this.this = this
function this.exec(player, plrid, neth, params, msg)
if this.permission == nil or (not player) or player.has_permission(this.permission) then
this.func(player, plrid, neth, params, msg)
else
command_msg("error", neth, "Error: You do not have permission for this command")
end
end
commands[this.command] = this
end
--You have to deregister aliases separately
function command_register_alias(command, alias)
commands[alias] = commands[command]
end
function command_handle(player, plrid, neth, params, msg)
local status, emsg = pcall(function()
local cmd = string.lower(params[1])
if commands[cmd] ~= nil then
table.remove(params, 1)
commands[cmd].exec(player, plrid, neth, params, msg)
else
command_msg("error", neth, "Error: No such command")
end
end)
if not status then
print("ERROR on running command:", emsg)
pcall(command_msg, "error", neth, emsg)
end
end
command_register({
command = "help",
permission = nil,
usage = "/help [command name]",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 0 then
--TODO: List available commands
elseif table.getn(prms) == 1 then
if commands[prms[1]] == nil then
command_msg("error", neth, "Error: No such command")
elseif (not plr) or plr.has_permission(commands[prms[1]].permission) then
command_msg("usage", neth, "Usage: "..commands[prms[1]].usage)
else
command_msg("error", neth, "Error: You do not have permission for this command")
end
else
this.func(plr, plrid, neth, "help")
end
end
})
-- for testing. not like it can be abused. well, i hope it can't be abused. --GM
command_register({
command = "kickme",
permission = nil,
usage = "/kickme",
func = function(plr, plrid, neth, prms, msg)
server.net_kick(neth, "requested!")
end
})
command_register({
command = "kick",
permission = "kick",
usage = "/kick ",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 1 then
local target
prms[1] = tostring(prms[1])
if prms[1]:sub(0, 1) == "#" then
target = players[tonumber(prms[1]:sub(2))]
end
for i=1,players.max do
if players[i] ~= nil and players[i].name == prms[1] then
target = players[i]
break
end
end
if target then
server.net_kick(target.neth, "requested!")
else
command_msg("error", neth, "Error: Player not found")
end
else
commands["help"].func(plr, plrid, neth, {"piano"})
end
end
})
command_register({
command = "resetscore",
permission = "resetgame",
usage = "/resetscore",
func = function(plr, plrid, neth, prms, msg)
local i
for i=1,players.max do
if players[i] then
players[i].score = 0
players[i].kills = 0
players[i].deaths = 0
players[i].update_score()
end
end
end
})
command_register({
command = "me",
permission = "me",
usage = "/me ",
func = function(plr, plrid, neth, prms, msg)
if not plr then
-- IRC - ignore
elseif table.getn(prms) > 0 then
local m = "* "..plr.name.." "..string.sub(msg,5)
net_broadcast(nil, common.net_pack("BIz", PKT_CHAT_ADD_TEXT, 0xFFFFFFFF, m))
irc.write(m)
else
commands["help"].func(plr, plrid, neth, {"me"})
end
end
})
command_register({
command = "fog",
permission = "resetgame",
usage = "/fog r g b",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 3 then
fog_set(tonumber(prms[1]),
tonumber(prms[2]),
tonumber(prms[3]))
else
commands["help"].func(plr, plrid, neth, {"fog"})
end
end
})
command_register({
command = "resetgame",
permission = "resetgame",
usage = "/resetgame",
func = function(plr, plrid, neth, prms, msg)
mode_reset()
end
})
command_register({
command = "map",
permission = "map",
usage = "/map ",
func = function(plr, plrid, neth, prms, msg)
local status, err = pcall(function()
local _map_loaded = common.map_load(prms[1], "auto")
common.map_set(_map_loaded)
map_loaded = _map_loaded
end)
if not status then
command_msg("error", neth, "Error while loading map: " .. err)
return
end
map_fname = prms[1]
map_name = map_fname
while map_name do
local p = map_name:find("/", 1, true)
if not p then break end
map_name = map_name:sub(p+1)
end
net_broadcast(nil, common.net_pack("B", PKT_NEW_MAP))
mode_reset()
end
})
command_register({
command = "genmap",
permission = "map",
usage = "/genmap ",
func = function(plr, plrid, neth, prms, msg)
local status, err = pcall(function()
local _map_loaded, map_name = loadfile(prms[1])(parse_commandline_options(prms))
common.map_set(_map_loaded)
map_loaded = _map_loaded
end)
if not status then
command_msg("error", neth, "Error while loading map: " .. err)
return
end
map_fname = prms[1]
net_broadcast(nil, common.net_pack("B", PKT_NEW_MAP))
mode_reset()
end
})
command_register({
command = "squad",
permission = "squad",
usage = "/squad (Use \"none\" to leave your squad)",
func = function(plr, plrid, neth, prms, msg)
if not plr then
-- IRC - ignore
elseif table.getn(prms) > 0 then
if prms[1] == "none" then
plr.squad = nil
else
plr.squad = string.sub(msg,8)
end
plr.update_score()
else
commands["help"].func(plr, plrid, neth, {"squad"})
end
end
})
command_register({
command = "kill",
permission = "kill",
usage = "/kill",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 0 then
if plr then
plr.set_health_damage(0, 0xFF800000, plr.name.." shuffled off this mortal coil", plr)
end
else
commands["help"].func(plr, plrid, neth, {"kill"})
end
end
})
command_register({
command = "gmode",
permission = "gmode",
usage = "/gmode #; where 1=normal, 2=spectate, 3=editor",
func = function(plr, plrid, neth, prms, msg)
if not plr then
-- IRC - ignore
elseif table.getn(prms) == 1 then
local n = math.floor(tonumber(prms[1]) or 0)
if n >= 1 and n <= 3 then
plr.mode = n
plr.update_score()
end
else
commands.help.func(plr, plrid, neth, {"gmode"})
end
end
})
command_register({
command = "piano",
permission = "piano",
usage = "/piano ",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 1 then
local target
prms[1] = tostring(prms[1])
if prms[1]:sub(0, 1) == "#" then
target = players[tonumber(prms[1]:sub(2))]
end
for i=1,players.max do
if players[i] ~= nil and players[i].name == prms[1] then
target = players[i]
break
end
end
if target then
target.drop_piano()
else
command_msg("error", neth, "Error: Player not found")
end
else
commands["help"].func(plr, plrid, neth, {"piano"})
end
end
})
command_register({
command = "teleport",
permission = "teleport",
usage = "/teleport |",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 1 then
local target
prms[1] = tostring(prms[1])
if prms[1]:sub(0, 1) == "#" then
target = players[tonumber(prms[1]:sub(2))]
end
for i=1,players.max do
if players[i] ~= nil and players[i].name == prms[1] then
target = players[i]
break
end
end
if target then
local x, y, z = target.x, target.y, target.z
plr.set_pos_recv(x, y, z)
net_broadcast(nil, common.net_pack("BBffffff",
PKT_PLR_POS, plrid, x, y, z, 0.0, 0.0, 0.0))
else
command_msg("error", neth, "Error: Player not found")
end
elseif table.getn(prms) == 3 then
--NOTE: I protest that y is down/same way AoS was
local x, y, z = tonumber(prms[1]), tonumber(prms[2]), tonumber(prms[3])
plr.set_pos_recv(x, y, z)
net_broadcast(nil, common.net_pack("BBffffff",
PKT_PLR_POS, plrid, x, y, z, 0.0, 0.0, 0.0))
else
commands["help"].func(plr, plrid, neth, {"teleport"})
end
end
})
command_register_alias("teleport", "tp")
command_register({
command = "goto",
permission = "goto",
usage = "/goto #X ; where # is letter, X is number in the map's grid system",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 1 then
prms[1] = tostring(prms[1])
local x, z
local success = pcall(function()
x = (string.byte(prms[1]:lower()) - 97) * 64 + 32
z = (tonumber(prms[1]:sub(2, 2)) - 1) * 64 + 32
end)
local xlen, _, zlen = common.map_get_dims()
if (success and x >= 0 and x < xlen and z >= 0 and z < zlen) then
local y = common.map_pillar_get(x, z)[1+1] - 3
plr.set_pos_recv(x, y, z)
net_broadcast(nil, common.net_pack("BBffffff",
PKT_PLR_POS, plrid, x + 0.5, y, z + 0.5, 0.0, 0.0 ,0.0))
else
command_msg("error", neth, "Error: Invalid coordinates")
end
else
commands["help"].func(plr, plrid, neth, {"goto"})
end
end
})
command_register({
command = "intel",
permission = "intelcmd",
usage = "/intel",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 0 then
local i
for i=1,#miscents do
if miscents[i] ~= nil then
local tidx = miscents[i].team
local tname = (tidx and teams[tidx].name) or "Neutral"
command_msg("text", neth, tname.." "..miscents[i].type..": "..miscents[i].x..", "..miscents[i].y..", "..miscents[i].z)
end
end
else
commands["help"].func(plr, plrid, neth, {"intel"})
end
end
})
command_register({
command = "who",
--permission = "irc",
usage = "/who",
func = function(plr, plrid, neth, prms, msg)
local s = ""
local pc = 0
for i=1,players.max do
if players[i] ~= nil then
pc = pc + 1
if s ~= "" then
s = s..", "
end
s = s .. (
"[" .. tostring(players[i].name) ..
" #".. tostring(i) ..
" T".. tostring(players[i].team) ..
"]")
end
end
s = tostring(pc) .. " players: " .. s
command_msg("text", neth, s)
end
})
command_register({
command = "login",
permission = nil,
usage = "/login ",
func = function(plr, plrid, neth, prms, msg)
if not plr then
-- IRC - ignore
elseif table.getn(prms) == 2 then
local success = false
if permissions[prms[1]] ~= nil and prms[2] == permissions[prms[1]].password then
plr.add_permission_group(permissions[prms[1]].perms)
success = true
end
if success then
command_msg("success", neth, "You have successfully logged in as "..prms[1])
else
command_msg("error", neth, "Could not log in to group "..prms[1].." with that password")
end
else
commands["help"].func(plr, plrid, neth, {"login"})
end
end
})
command_register({
command = "permissions",
permission = "permissions",
usage = "/permissions [add/remove] ",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 3 then
local target
prms[1] = tostring(prms[1])
if prms[1]:sub(0, 1) == "#" then
target = players[tonumber(prms[1]:sub(2))]
end
for i=1,players.max do
if players[i] ~= nil and players[i].name == prms[1] then
target = players[i]
break
end
end
if not target then
command_msg("error", neth, "Error: Player not found")
return
end
local add_perm
prms[2] = tostring(prms[2])
if prms[2] == "add" or prms[2] == "a" or prms[2] == "+" then
add_perm = true
elseif prms[2] == "remove" or prms[2] == "rem" or prms[2] == "r" or prms[2] == "-" then
add_perm = false
else
commands["help"].func(plr, plrid, neth, {"permissions"})
return
end
prms[3] = tostring(prms[3])
if add_perm then
target.add_permission(prms[3])
else
target.remove_permission(prms[3])
end
else
commands["help"].func(plr, plrid, neth, {"permissions"})
end
end
})
command_register_alias("permissions", "permission")
command_register_alias("permissions", "perms")
command_register_alias("permissions", "perm")
command_register({
command = "logout",
permission = "logout",
usage = "/logout",
func = function(plr, plrid, neth, prms, msg)
if table.getn(prms) == 0 then
plr.clear_permissions()
plr.add_permission_group(permissions["default"].perms)
command_msg("success", neth, "You have successfully logged out")
else
commands["help"].func(plr, plrid, neth, {"logout"})
end
end
})