Ulysses

General => Developers Corner => Topic started by: Aaron113 on November 05, 2010, 01:15:25 PM

Title: ULX Commands
Post by: Aaron113 on November 05, 2010, 01:15:25 PM
Can I have an example of how to create an advanced ULX command?  (Logging, prints in chat, every argument)


I have been working on ULX commands lately and it would be nice to know how some of this works.  I have no been able to use logString or get it to print into chat without using ULib.tsayColor() or filex.Append().
Title: Re: ULX Commands
Post by: JamminR on November 05, 2010, 05:59:09 PM
Though long and drawn out, I did a article comparing old to new ULX command structure a while back.
Maybe it can help you a bit.
http://forums.ulyssesmod.net/index.php/topic,4464.0.html
It's quite heavily commented in the code examples.

There's also the docs for ULib, which of course, those code examples use much of for the commands.
http://www.ulyssesmod.net/docs
Title: Re: ULX Commands
Post by: Aaron113 on November 05, 2010, 08:19:13 PM
Mind explaining the logging part to me?
Code: [Select]
explode:logString( "#1s exploded #2s with #3i damage in a #4i radius blast area" )

Whats with the s changing to an i?
Title: Re: ULX Commands
Post by: JamminR on November 05, 2010, 09:24:55 PM
s = string
i = integer
There are others I think. I forget what they are.
Megiddo/Stickly Man, others around here who have taken formal coding classes can probably tell you the name of that style of string/variable substitution.
I've seen it used in other scripting languages when it comes to string output.
Megiddo used it (to much less extent) in older ULX string manipulation. Was usually #T for target.

In relation to current (SVN) ULib command objects and that 'rocket' example,
#1 is (always?) person who ran the command.
2,3,4... equals each additional "addparam" value.
#2s (string) in that example is the player(s) that the command was performed on.
#3i (integer) is set as damag.
#4i (integer) is radius.
In the actual log command, you could change it to " with a #4i radius and #3i damage".
Those numbers don't have to be in order in the logString command.
They just have to match what parameter order you give the command object.
Title: Re: ULX Commands
Post by: Megiddo on November 06, 2010, 07:20:12 AM
You're right on JamminR. It's just a slight variation on string.format().
Title: Re: ULX Commands
Post by: Aaron113 on November 06, 2010, 02:13:27 PM
So what about the echoing into chat?  I looked though ULX and didn't see any ULib.tsayColor() on the commands.
Title: Re: ULX Commands
Post by: Aaron113 on November 06, 2010, 02:45:06 PM
Whats wrong with this that is not logging or echoing into chat?


Code: [Select]
local CATEGORY_NAME = "Custom"


function ulx.warn( calling_ply, target_plys, Reason )
end
local warn = ulx.command( CATEGORY_NAME, "ulx warn", ulx.warn, "!warn" )
warn:addParam{ type=ULib.cmds.PlayerArg }
warn:addParam{ type=ULib.cmds.StringArg, hint="reason", ULib.cmds.takeRestOfLine }
warn:defaultAccess( ULib.ACCESS_ADMIN )
warn:help( "Warn a player." )
warn:logString( "#1s warned #2s for #3s" )
Title: Re: ULX Commands
Post by: Aaron113 on November 06, 2010, 03:27:38 PM
Also, some help with setting common options.  Like ban has: spammer, Minge, Griefer, ect.
Title: Re: ULX Commands
Post by: JamminR on November 06, 2010, 07:10:09 PM
I just spent about half hour poking around regarding your echo command to screen issue.
At first, I thought ULib might be expecting a 'return' function as I saw a few return <boolean>, <String message> at the end of some functions that looked like what would be output to a user.
Then I realized, not every ulx function has that and it seems to be meant as an override.
Are you getting the command logged to your ulx server logfile?
Is the command actually running? I know we put in some checks that if for any reason the command doesn't run, it doesn't echo.
In your (currently blank) function, try something as simple as a print to console Msg() and "return" with nothing else.

Megiddo, does logString do more than write to a log file. From log.lua, it didn't look like it. And if not, what should he do to have it echo to the screen?

As for the ban, there is a 'completes' variable you can pass in your parameters.
Pass it a table, and the parameter will suggest whatever is in the table after previous parameters are chosen (if any).

Cbrad24's recent ULX rate (http://forums.ulyssesmod.net/index.php/topic,5020.0.html) release shows this in action.
It has a screenshot of the 'legal' gmod allowed ratings after having typed

Earlier in his code, he sets up a table
Code: [Select]
ulx.ratings = { "naughty", "like", "love", "artistic", "star", "builder" }

Then in his command setup, he uses the following parameter after the Players parameter.
Code: [Select]
rate:addParam{ type=ULib.cmds.StringArg, completes=ulx.ratings, hint="rating", error="invalid rating \"%s\" specified", ULib.cmds.restrictToCompletes }
If you wanted to allow for more than just that table, you could leave out ULib.cmds.restrictToCompletes
It's pretty obvious what that does. :)

Have you seen http://ulyssesmod.net/docs/files/lua/ulib/shared/commands-lua.html ?
It has much on the command system ULX uses and the available parameters.
Title: Re: ULX Commands
Post by: Aaron113 on November 06, 2010, 08:36:08 PM
Quote
Are you getting the command logged to your ulx server logfile?
Is the command actually running? I know we put in some checks that if for any reason the command doesn't run, it doesn't echo.
In your (currently blank) function, try something as simple as a print to console Msg() and "return" with nothing else.
I've had to do filex.Append and ULib.tsayColor() for logging and echoing.  I know for a fact the command is running.  I just took all my code out.

Quote
Have you seen http://ulyssesmod.net/docs/files/lua/ulib/shared/commands-lua.html ?
It has much on the command system ULX uses and the available parameters.
I have seen it.  It can just be a bit confusing.
Title: Re: ULX Commands
Post by: Megiddo on November 07, 2010, 08:57:19 AM
Unfortunately ULX isn't documented as well as ULib. You need to return true from the function in the event of success, otherwise ULX assumes that there was something wrong with the input (trying to jail a ragdoll, etc).

Tested with return true:
Quote
[ULX]Megiddo: !warn me one two
You warned yourself for one two
Title: Re: ULX Commands
Post by: JamminR on November 07, 2010, 01:08:56 PM
Megiddo, thanks for confirming. I'd thought that was the case but wasn't sure. I remembered <command object>:<Ulib.mds.*> checking for success, but had forgotten how it went about doing that.

Aaron113, do you understand how the addparam work with the "completes" variable table suggestions from the rate code I showed?
I can write a longer bit of example command code with comments if needed.
Title: Re: ULX Commands
Post by: Aaron113 on November 08, 2010, 11:08:58 AM
Aaron113, do you understand how the addparam work with the "completes" variable table suggestions from the rate code I showed?
I can write a longer bit of example command code with comments if needed.
A longer version would be nice.  I haven't had time to try anything since you posted before.
Title: Re: ULX Commands
Post by: JamminR on November 09, 2010, 07:28:41 PM
Here's code including 'suggestions' for autocomplete of your warning system.
I've not tested it.

Code: [Select]
local CATEGORY_NAME = "Custom"
-- Set table for autocomplete suggestions.
my_warn_reasons = { "Spamming", "Rude", "Language", "Arguing with a mod", "Prop Killing" }
-- Set your function as normal
function ulx.warn( calling_ply, target_plys, Reason )
return true
end
-- set your command as normal
local warn = ulx.command( CATEGORY_NAME, "ulx warn", ulx.warn, "!warn" )
warn:addParam{ type=ULib.cmds.PlayerArg }
-- Here, you deviate. You give addParam an additional table, "completes", set in previous table, "my_warn_reasons"
-- After you've typed "ulx warn <some player>" in console, the dropdown will contain the table. If you type the first
-- few letters of a word from the table (for instance, "S", "Spamming" would attempt to auto complete).
warn:addParam{ type=ULib.cmds.StringArg, hint="reason", completes=my_warn_reasons, ULib.cmds.takeRestOfLine }
warn:defaultAccess( ULib.ACCESS_ADMIN )
warn:help( "Warn a player." )
warn:logString( "#1s warned #2s for #3s" )

See http://ulyssesmod.net/docs/files/lua/ulib/shared/commands-lua.html#cmds.StringArg
According to that, the following apply with ULib.cmds.StringArg
"hint" = Gives hint as part of error (if error not overridden)
"completes" = Table of strings to be used as auto complete in option.
"ULib.cmds.restrictToCompletes" - Obvious, allow only what is given in "completes" as input.
or
"ULib.cmds.takeRestOfLine" - Obvious, take rest of line
"error" = Allow overriding the default command object error (allows for customization)
"autocomplete_fn" = Allow override of the default ULib autocomplete function.
"repeat_min", combined with "ULib.cmds.takeRestOfLine", from the description at our docs site, well, I'm not fully sure what it is myself.

Megiddo, explain repeat_min in a different way than stated at ulib docs?
Title: Re: ULX Commands
Post by: Megiddo on November 09, 2010, 08:48:52 PM
I think hint is just used for autocomplete and command syntax. Repeat min ensures that an argument is repeated at least n times (and also states that it CAN be repeated). This was mainly added for XGUI's benefit, but it's useful for ULX as well.

For example:
vote:addParam{ type=ULib.cmds.StringArg, hint="options", ULib.cmds.takeRestOfLine, repeat_min=2, repeat_max=10 }

That's a line from the ulx vote definition. It makes sure that there are at least 2 options given, and a maximum of 10. (I need to document repeat_max :P)
Title: Re: ULX Commands
Post by: Aaron113 on November 10, 2010, 01:40:13 PM
Thanks for the help!  I'll get to working on this more possibly some time later today or tomorrow.
Title: Re: ULX Commands
Post by: JamminR on November 11, 2010, 05:59:39 PM
You're welcome.
I've not been motivated this past year to contribute to the ULib codebase directly, and haven't been on Steam enough to indirectly contribute in discussions with Megiddo. (I miss you, man!)
ULib/Lua assistance like this help keep me sharp and exercise my brain.
I'd not even realized until helping you that repeat_min and _max had been added to the StringArg object.
Always enjoy learning our new toys.
:P
Title: Re: ULX Commands
Post by: Aaron113 on November 20, 2010, 09:35:50 PM
Finally got around to adding the autocompletes.  Works well.
Title: Re: ULX Commands
Post by: Aaron113 on March 14, 2011, 04:24:01 PM
I think hint is just used for autocomplete and command syntax. Repeat min ensures that an argument is repeated at least n times (and also states that it CAN be repeated). This was mainly added for XGUI's benefit, but it's useful for ULX as well.

For example:
vote:addParam{ type=ULib.cmds.StringArg, hint="options", ULib.cmds.takeRestOfLine, repeat_min=2, repeat_max=10 }

That's a line from the ulx vote definition. It makes sure that there are at least 2 options given, and a maximum of 10. (I need to document repeat_max :P)

Is there a way to get all the values into a table without having a million arguments in the function?
Title: Re: ULX Commands
Post by: Megiddo on March 14, 2011, 07:52:35 PM
Is there a way to get all the values into a table without having a million arguments in the function?

They're optional, so only specify them if you need them. This is a named parameter (http://en.wikipedia.org/wiki/Named_parameter) design.
Title: Re: ULX Commands
Post by: Aaron113 on March 15, 2011, 05:49:10 AM
vote:addParam{ type=ULib.cmds.StringArg, hint="options", ULib.cmds.takeRestOfLine, repeat_min=2, repeat_max=10 }

I was talking about this portion.  I wouldn't want to create 10 extra arguments and check to see if a value was entered for each one.
Title: Re: ULX Commands
Post by: Megiddo on March 15, 2011, 06:25:00 AM
I was talking about this portion.  I wouldn't want to create 10 extra arguments and check to see if a value was entered for each one.

I'm not sure what you mean
Title: Re: ULX Commands
Post by: JamminR on March 15, 2011, 06:58:40 AM
Aaron, even I have to admit, I'm a bit confused at what you're asking, and I'm normally pretty good at seeing the root question my team members miss.
Do you mean you set up the first one or two argument checks, then want a table of anything else typed in that you didn't account for?
Thats what the "takerestofline" bit is for. It's not a table, its a string, but if you think you'll really need it as a table, it can be converted using any normal string to table means.
http://ulyssesmod.net/docs/files/lua/ulib/shared/commands-lua.html#cmds.takeRestOfLine
Title: Re: ULX Commands
Post by: Aaron113 on March 15, 2011, 01:28:59 PM
Instead of doing this...
Code: [Select]
function ulx.whatever( ply, string1, string2, string3, string4, string5, string6, string7, string8, string9, string10 )

Would it be possible to make it...
Code: [Select]
function ulx.whatever( ply, tableOfStrings )
Because I've only been able to do the first one.  I can't figure out any other way.
Title: Re: ULX Commands
Post by: Megiddo on March 15, 2011, 01:34:47 PM
As JamminR said, use cmds.takeRestOfLine. If you'd like to split it into a table, use ULib.splitArgs (http://ulyssesmod.net/docs/files/lua/ulib/shared/misc-lua.html#splitArgs)
Title: Re: ULX Commands
Post by: Aaron113 on March 15, 2011, 01:45:14 PM
Maybe I'll just work out something else.  Thanks anyway.