Dynamic onPlayerCommand

Started by habi, Aug 09, 2023, 08:10 AM

Previous topic - Next topic

habi

Hi, this is dynamic onPlayerCommand. You can add/remove/list all the commands.

Anywhere, you can do mycmds.add("hukama", function... ); So when /hukama is typed this function gets called. You can also later remove it by mycmds.remove("hukama").

Let us move to the code

//scripts/onPlayerCommand.nut
assert(getroottable() == this )
//That was to make sure all our codes work

assert(getdelegate()==null)
//Normally nobody sets delegate to roottable. Some do, they have to modify codes

local onPlayerCommand = {

}

//The table hides slots 'add', 'remove', 'ScriptonPlayerCommand'
onPlayerCommand.setdelegate(
{
function add(cmd, func)
{
//The command is not already present
assert(this.rawin(cmd)==false)

//Check cmd is string
assert(typeof(cmd)=="string")

//Check function parameters
//1. Check if parameters slot exist in getinfos table
assert(func.getinfos().rawin("parameters"))
//2. Check if including this, the no:of parameters of function is 3 ( this, player,  text ) (cmd not needed)
assert(func.getinfos().parameters.len()==3)
//Add it to our table also lowercase
this.rawset(cmd.tolower(), func);
}
function remove(cmd)
{
assert(this.rawin(cmd))
this.rawdelete(cmd.tolower())
}
function getcmds()
{
local cmds="";
foreach(key, value in this){
cmds+="/"+key+" ";
}
return cmds;
}
//rawdelete returns value of the slot if present, so we can safely :
ScriptonPlayerCommand=rawdelete("onPlayerCommand")
}
)
//The table onPlayerCommand will be a free variable to functions following / inside table
local table={
//Alternative Event
function onPlayerCommandAlt( player, cmd , text )
{
//Convert cmd to lowercase
cmd=cmd.tolower();

cmd in onPlayerCommand ? onPlayerCommand.rawget(cmd)(player, text):
onPlayerCommand.ScriptonPlayerCommand!=null?
onPlayerCommand.ScriptonPlayerCommand(player, cmd, text):
cmd=="cmds"?ClientMessage(onPlayerCommand.getcmds()==""?"No cmds available":onPlayerCommand.getcmds(), player, 0, 100, 0):
cmd!="rcon"?ClientMessage("This cmd does not exist. Use /cmds", player,0,255,0):null;
}
function _get(idx)
{
if(idx=="onPlayerCommand")
return onPlayerCommandAlt
else throw(null);
}
//When reloading, place the 'onPlayerCommand' of script under ScriptonPlayerCommand
function _newslot(key, value)
{
key=="onPlayerCommand"?onPlayerCommand.ScriptonPlayerCommand=value:rawset(key, value);
}
}

setdelegate(table);

return onPlayerCommand;

//scripts/main.nut
function onScriptLoad()
{
   mycmds<-dofile("scripts/main.nut");
}

Now global variable mycmds have it. In the next line of onScriptLoad or any possible place, you can start adding your commands.

Let us add an "/info" command
mycmds.add("info", function(player, text){ ClientMessage("Server developed by Mr. X and Mr. Y", player, 0, 255, 0); } );function (player, text){ : The prototype of the function. It takese two parameters. Unlike onPlayerCommand, here we not need 'cmd' parameter.

Homework: Try what happens when you type /cmds in game.
Find out what is returned when you call mycmds.getcmds() in script.
Can you have onPlayerCommand also along with this one? Which one is called ?

Have a nice day!

2b2ttianxiu

a custom load and execute commad function, likely minecraft command system.