Difference between revisions of "Lua Mod API"
(warning about etprint) |
|||
(18 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
__NOEDITSECTION__ | __NOEDITSECTION__ | ||
− | ETPro now supports | + | [[ETPro]] now supports server-side mods via the [http://www.lua.org/ Lua] scripting language. For more information about Lua, visit the [http://www.lua.org/manual/5.0/ Reference manual], the online edition of the book [http://www.lua.org/pil/ Programming in Lua] or the [http://lua-users.org/wiki/ lua-users wiki]. A list of text editors for coding LUA can be found [http://wiki.ptokax.ath.cx/doku.php/misc/editors here]. |
− | ETPro has an embedded | + | ETPro has an embedded Lua 5.0.2 interpreter, and if present will load user-defined scripts from the ETPro directory. It also provides an "et" library of function calls for Lua that allow access to the server engine, and provides callbacks so a server side mod may trigger on specific server events. |
− | The following standard | + | The following standard Lua libraries are initialized by default and available to ETPro Lua scripts: |
− | [http://www.lua.org/manual/5.0/manual.html#5.1 basic], [http://www.lua.org/manual/5.0/manual.html#5.4 table], [http://www.lua.org/manual/5.0/manual.html#5.6 i/o], [http://www.lua.org/manual/5.0/manual.html#5.3 string], [http://www.lua.org/manual/5.0/manual.html#5.5 math]. | + | [http://www.lua.org/manual/5.0/manual.html#5.1 basic], [http://www.lua.org/manual/5.0/manual.html#5.4 table], [http://www.lua.org/manual/5.0/manual.html#5.6 i/o], [http://www.lua.org/manual/5.0/manual.html#5.7 os] (available features vary depending on your OS), [http://www.lua.org/manual/5.0/manual.html#5.3 string], [http://www.lua.org/manual/5.0/manual.html#5.5 math]. |
− | A list of | + | A list of ETPro mods can be found [[:Category:ETPro:Mods|here]]. |
− | A | + | A tutorial about ETPro Lua scripting can be found [[Lua Tutorials|here]]. |
− | API | + | API requests can be discussed at the [[Talk:Lua_Mod_API|Lua Mod API talk page]]. |
==client commands== | ==client commands== | ||
Line 44: | Line 44: | ||
:Returns the '''modname''' and sha1 '''signature''' for the mod loaded in the VM slot '''vmnumber'''. Returns nil, nil if the VM slot is invalid. | :Returns the '''modname''' and sha1 '''signature''' for the mod loaded in the VM slot '''vmnumber'''. Returns nil, nil if the VM slot is invalid. | ||
'''success''' = et.IPCSend( '''vmnumber''', '''message''' ) | '''success''' = et.IPCSend( '''vmnumber''', '''message''' ) | ||
− | :Sends the string '''message''' to the mod in the VM slot indicated by '''vmnumber'''. The mod receiving '''message''' must have an ''et_IPCReceive()'' callback. If the message is successfully sent, '''success''' will be 1. On failure it will be 0. | + | :Sends the string '''message''' to the mod in the VM slot indicated by '''vmnumber'''. The mod receiving '''message''' must have an ''et_IPCReceive()'' callback. If the message is successfully sent, '''success''' will be 1. On failure it will be 0. See the [[Lua:IPC|Lua IPC]] page for a simple example. |
<br> | <br> | ||
Line 91: | Line 91: | ||
:Sends a chat command on behalf of client '''clientNum''' with the mode '''mode''' (see et.SAY_* constants) and chat text '''text'''. | :Sends a chat command on behalf of client '''clientNum''' with the mode '''mode''' (see et.SAY_* constants) and chat text '''text'''. | ||
et.ClientUserinfoChanged( '''clientNum''' ) | et.ClientUserinfoChanged( '''clientNum''' ) | ||
− | :Loads the new Userinfo of '''clientNum''' and stores it in the configstring and client variables | + | :Loads the new [[Userinfo]] of '''clientNum''' and stores it in the configstring and client variables |
<br> | <br> | ||
===userinfo=== | ===userinfo=== | ||
'''userinfo''' = et.trap_GetUserinfo( '''clientnum''' ) | '''userinfo''' = et.trap_GetUserinfo( '''clientnum''' ) | ||
− | :Returns the contents of the | + | :Returns the contents of the [[Userinfo]] string for the client '''clientnum''' |
et.trap_SetUserinfo( '''clientnum''', '''userinfo''' ) | et.trap_SetUserinfo( '''clientnum''', '''userinfo''' ) | ||
− | :Sets the | + | :Sets the [[Userinfo]] string for the client '''clientnum''' to '''userinfo''' |
<br> | <br> | ||
Line 154: | Line 154: | ||
'''entnum''' = et.G_TempEntity( '''origin''', '''event''' ) | '''entnum''' = et.G_TempEntity( '''origin''', '''event''' ) | ||
:Spawns a new TempEntity of event type '''event''' and places it at '''origin''' in the world. | :Spawns a new TempEntity of event type '''event''' and places it at '''origin''' in the world. | ||
− | |||
et.G_FreeEntity( '''entnum''' ) | et.G_FreeEntity( '''entnum''' ) | ||
:Frees the entity '''entnum''' | :Frees the entity '''entnum''' | ||
Line 198: | Line 197: | ||
:Called when a client begins (becomes active, and enters the gameworld). '''clientNum''' is the client slot id. | :Called when a client begins (becomes active, and enters the gameworld). '''clientNum''' is the client slot id. | ||
et_ClientUserinfoChanged( '''clientNum''' ) | et_ClientUserinfoChanged( '''clientNum''' ) | ||
− | :Called when a client's Userinfo string has changed. '''clientNum''' is the client slot id. | + | :Called when a client's [[Userinfo]] string has changed. '''clientNum''' is the client slot id. |
+ | :'''note:''' In ETPro 3.2.6 and below, this only gets called when the players CS_PLAYERS config string changes, rather than every time the userinfo changes. This only happens for a subset of userinfo fields. | ||
et_ClientSpawn( '''clientNum''', '''revived''' ) | et_ClientSpawn( '''clientNum''', '''revived''' ) | ||
− | :Called when a client is spawned. '''clientNum''' is the client slot id. '''revived''' is 1 if the client was spawned by | + | :Called when a client is spawned. '''clientNum''' is the client slot id. '''revived''' is 1 if the client was spawned by being revived. |
<br> | <br> | ||
Line 214: | Line 214: | ||
===xp=== | ===xp=== | ||
et_UpgradeSkill( '''cno''', '''skill''' ) | et_UpgradeSkill( '''cno''', '''skill''' ) | ||
− | :Called when client on slot '''cno''' gets | + | :Called when client on slot '''cno''' gets an upgrade on skill '''skill'''. Return -1 to override (abort) the qagame function, anything else to "passthrough". Callback may modify skills (or do anything else it wants) during passthrough. |
− | + | et_SetPlayerSkill( '''cno''', '''skill''' ) | |
− | :Called when | + | :Called when clients (on slot '''cno''') skill level '''skill''' is set. Return -1 to override (abort) the qagame function, anything else to "passthrough". Callback may modify skills (or do anything else it wants) during passthrough. |
+ | <br> | ||
===miscellaneous=== | ===miscellaneous=== | ||
Line 223: | Line 224: | ||
et_Print( '''text''' ) | et_Print( '''text''' ) | ||
:Called whenever the server or qagame prints a string to the console. | :Called whenever the server or qagame prints a string to the console. | ||
+ | :'''WARNING!''' ''text'' may contain a player name + their chat message. This makes it '''very easy''' to spoof. '''DO NOT TRUST STRINGS OBTAINED IN THIS WAY''' | ||
et_Obituary( '''victim''', '''killer''', '''meansOfDeath''' ) | et_Obituary( '''victim''', '''killer''', '''meansOfDeath''' ) | ||
:Called whenever a player is killed. | :Called whenever a player is killed. | ||
Line 259: | Line 261: | ||
A: table.foreach(et, function (func, value) _G[func] = value; end) | A: table.foreach(et, function (func, value) _G[func] = value; end) | ||
− | Q: How do a | + | Q: How do a reload my lua file without restarting the whole server?<br> |
− | A: | + | A: Use ''map_restart'', ''reset_match'' or simply change the map. |
Q: Can I see some sample code?<br> | Q: Can I see some sample code?<br> | ||
− | A: [[ETPro:Lua Sample Code]] | + | A: [[ETPro:Lua Sample Code|Lua sample code]] |
− | Q: Is there a list of [[ETPro]] mods?<br> | + | Q: Is there a list of [[ETPro]] Lua mods?<br> |
A: Yes, [[:Category:ETPro:Mods|here]]. | A: Yes, [[:Category:ETPro:Mods|here]]. | ||
Line 272: | Line 274: | ||
Q: OMG why has et_ClientSay been removed?<br> | Q: OMG why has et_ClientSay been removed?<br> | ||
− | A: | + | A: That's a secret but, to keep the function as it was, just add the following code to your et_ClientCommand() function<br> |
<pre> -- et_ClientSay had to be removed in order to intercept all commands | <pre> -- et_ClientSay had to be removed in order to intercept all commands | ||
-- so here's a wrapper for that | -- so here's a wrapper for that | ||
Line 289: | Line 291: | ||
</pre> | </pre> | ||
− | + | [[Category:Lua]] | |
− | [[Category: | + | |
− | + |
Latest revision as of 21:42, 23 March 2008
ETPro now supports server-side mods via the Lua scripting language. For more information about Lua, visit the Reference manual, the online edition of the book Programming in Lua or the lua-users wiki. A list of text editors for coding LUA can be found here.
ETPro has an embedded Lua 5.0.2 interpreter, and if present will load user-defined scripts from the ETPro directory. It also provides an "et" library of function calls for Lua that allow access to the server engine, and provides callbacks so a server side mod may trigger on specific server events.
The following standard Lua libraries are initialized by default and available to ETPro Lua scripts: basic, table, i/o, os (available features vary depending on your OS), string, math.
A list of ETPro mods can be found here.
A tutorial about ETPro Lua scripting can be found here.
API requests can be discussed at the Lua Mod API talk page.
Contents
client commands
lua_status
- lists all currently loaded lua modules.
- lua mods cannot override this client command.
server commands
lua_status
- lists all currently loaded lua modules.
cvars
lua_modules
- (default "", disabled)
- space separated list of lua modules for ETPro to load. modules will be run in the order listed.
lua_allowedmodules
- (default "", disabled)
- if set, only lua modules with the matching sha1 signatures listed in this cvar will be allowed to load.
- changing either cvar will cause all currently loaded modules to :quit and be unloaded until the next map_restart.
et library calls
modules
et.RegisterModname( modname )
- Registers a descriptive string modname for this mod.
vmnumber = et.FindSelf()
- Returns a number indicating the VM slot the current mod is loaded into.
modname, signature = et.FindMod( vmnumber )
- Returns the modname and sha1 signature for the mod loaded in the VM slot vmnumber. Returns nil, nil if the VM slot is invalid.
success = et.IPCSend( vmnumber, message )
- Sends the string message to the mod in the VM slot indicated by vmnumber. The mod receiving message must have an et_IPCReceive() callback. If the message is successfully sent, success will be 1. On failure it will be 0. See the Lua IPC page for a simple example.
printing
et.G_Print( text )
- Prints the string text to the server console.
et.G_LogPrint( text )
- Prints the string text to the server console and writes it to the server log.
argument handling
These functions are to be used within the command callback functions.
args = et.ConcatArgs( index )
- Returns all arguments beginning from index concatenated into a single string args
argcount = et.trap_Argc()
- Returns a number indicating the number of command line arguments in the command buffer.
arg = et.trap_Argv( argnum )
- Returns the contents of the command line argument argnum.
cvars
cvarvalue = et.trap_Cvar_Get( cvarname )
- Returns the value of the cvar cvarname as a string. If there is no cvar named cvarname, returns a zero length string.
et.trap_Cvar_Set( cvarname, cvarvalue )
- Sets the cvar cvarname to cvarvalue
configstrings
configstringvalue = et.trap_GetConfigstring( index )
- Returns the string configstringvalue containing the contents of the configstring index
et.trap_SetConfigstring( index, configstringvalue )
- Sets the configstring index to the string configstringvalue
server
et.trap_SendConsoleCommand( when, command )
- Sends the command command to the server console, to be executed when (see et.EXEC_* constants)
clients
et.trap_DropClient( clientnum, reason, ban_time )
- Disconnects clientnum from the server, with descriptive string reason reported to clients. ban_time is the time in seconds to ban the client from the server. ban_time is optional and may be entirely omitted, in which case the ban time defaults to the cvar b_defaultbantime
et.trap_SendServerCommand( clientnum, command )
- Sends the command command to the client clientnum. If clientnum is -1, the command is broadcast to all connected clients.
et.G_Say( clientNum, mode, text )
- Sends a chat command on behalf of client clientNum with the mode mode (see et.SAY_* constants) and chat text text.
et.ClientUserinfoChanged( clientNum )
- Loads the new Userinfo of clientNum and stores it in the configstring and client variables
userinfo
userinfo = et.trap_GetUserinfo( clientnum )
- Returns the contents of the Userinfo string for the client clientnum
et.trap_SetUserinfo( clientnum, userinfo )
- Sets the Userinfo string for the client clientnum to userinfo
string utility functions
infostring = et.Info_RemoveKey( infostring, key )
- Removes key key from infostring infostring and returns the modified infostring.
infostring = et.Info_SetValueForKey( infostring, key, value )
- Sets the key key in the infostring infostring to value and returns the modified infostring. If value is an empty string, key is removed from the string.
keyvalue = et.Info_ValueForKey( infostring, key )
- Returns the value of the key key in the infostring infostring. If key is not present in the string, an empty string is returned.
cleanstring = et.Q_CleanStr( string )
- Returns string stripped of all color codes
ET filesystem
fd, len = et.trap_FS_FOpenFile( filename, mode )
- Attempts to open the file filename with the access mode mode (see et.FS_ constants). Returns the filedescriptor fd and file length len. On error, len returns -1.
filedata = et.trap_FS_Read( fd, count )
- Reads count bytes from filedescriptor fd.
count = et.trap_FS_Write( filedata, count, fd )
- Attempts to write count bytes of filedata to filedescriptor fd. Returns number of bytes successfully written.
et.trap_FS_Rename( oldname, newname )
- Renames file oldname to newname.
et.trap_FS_FCloseFile( fd )
- Closes filedescriptor fd
indexes
soundindex = et.G_SoundIndex( filename )
- Returns an index to the soundfile indicated by filename
modelindex = et.G_ModelIndex( filename )
- Returns an index to the model indicated by filename
sound
et.G_globalSound( sound )
- Plays the global sound indicated by the filename sound.
et.G_Sound( entnum, soundindex )
- Plays the sound soundindex at the location of entity entnum
miscellaneous
milliseconds = et.trap_Milliseconds()
- Returns a number indicating the current server time in milliseconds.
et.G_Damage( target, inflictor, attacker, damage, dflags, mod )
- Does damage amount of damage on target inflicted by inflictor and cased by attacker
- target, inflictor, attacker are entity numbers
- dflags is a bitflag number to decide how the damage is inflickted, see dflags flaglist
- mod is a number from 0 up to 64 o set the type of damage, see mod list
entities
entnum = et.G_Spawn()
- Spawns a new entity and returns the new entity number.
entnum = et.G_TempEntity( origin, event )
- Spawns a new TempEntity of event type event and places it at origin in the world.
et.G_FreeEntity( entnum )
- Frees the entity entnum
spawnval = et.G_GetSpawnVar( entnum, key )
- Returns the value of spawnvar key for entity entnum
et.G_SetSpawnVar( entnum, key, value )
- Sets the spawnvar key to value for entity entnum
integer entnum = et.G_SpawnGEntityFromSpawnVars( string spawnvar, string spawnvalue, ... )
- This function can only be called inside the et_InitGame callback
et.trap_LinkEntity( entnum )
- Links the entity entnum
et.trap_UnlinkEntity( entnum )
- Unlinks the entity entnum
(variable) = et.gentity_get ( entnum, Fieldname ,arrayindex )
- Gets the value of Fieldname from entity entnum out of the g_entity struct. For NULL entities or clients, nil is returned.
- arrayindex is used to specify which element of an array entity field to get. It is required when accessing array type fields. Entity field array indexes start at 0.
et.gentity_set( entnum, Fieldname, arrayindex, (value) )
- Sets the value of Fieldname from entity entnum in the g_entity struct to (value)
- arrayindex is used to specify which element of an array entity field to set.
et.G_AddEvent( ent, event, eventparm' )
- Adds event event whit eventparameter eventparm' to entity ent
callbacks
qagame execution
et_InitGame( levelTime, randomSeed, restart )
- Called when qagame initializes. levelTime is the current level time in milliseconds. randomSeed is a number that can be used to seed random number generators. restart indicates if et_InitGame() is being called due to a map restart (1) or not (0).
et_ShutdownGame( restart )
- Called when qagame shuts down. restart indicates if the shutdown is being called due to a map_restart (1) or not (0).
et_RunFrame( levelTime )
- Called when qagame runs a server frame. levelTime is the current level time in milliseconds.
et_Quit()
- Called when ETPro unloads the mod. The mod should close all open filedescriptors and perform all cleanup.
client management
rejectreason = et_ClientConnect( clientNum, firstTime, isBot )
- Called when a client attempts to connect to the server. clientNum is the client slot id, firstTime indicates if this is a new connection (1) or a reconnection (0). isBot indicates if the client is a bot (1) or not (0). If the mod accepts the connection, it should return nil. Otherwise, the mod should return a string describing the reason the client connection was rejected.
et_ClientDisconnect( clientNum )
- Called when a client disconnects. clientNum is the client slot id.
et_ClientBegin( clientNum )
- Called when a client begins (becomes active, and enters the gameworld). clientNum is the client slot id.
et_ClientUserinfoChanged( clientNum )
- Called when a client's Userinfo string has changed. clientNum is the client slot id.
- note: In ETPro 3.2.6 and below, this only gets called when the players CS_PLAYERS config string changes, rather than every time the userinfo changes. This only happens for a subset of userinfo fields.
et_ClientSpawn( clientNum, revived )
- Called when a client is spawned. clientNum is the client slot id. revived is 1 if the client was spawned by being revived.
commands
intercepted = et_ClientCommand( clientNum, command )
- Called when a command is received from a client. clientNum is the client slot id. command is the command. The mod should return 1 if the command was intercepted by the mod, and 0 if the command was ignored by the mod and should be passed through to the server (and other mods in the chain).
- The actual command can be accessed through the argument handling functions, as seen in the ETPro:Lua Sample Code.
intercepted = et_ConsoleCommand()
- Called when a command is entered on the server console. The mod should return 1 if the command was intercepted by the mod, and 0 if the command was ignored by the mod and should be passed through to the server (and other mods in the chain).
- The actual command can be accessed through the argument handling functions, as seen in the ETPro:Lua Sample Code.
xp
et_UpgradeSkill( cno, skill )
- Called when client on slot cno gets an upgrade on skill skill. Return -1 to override (abort) the qagame function, anything else to "passthrough". Callback may modify skills (or do anything else it wants) during passthrough.
et_SetPlayerSkill( cno, skill )
- Called when clients (on slot cno) skill level skill is set. Return -1 to override (abort) the qagame function, anything else to "passthrough". Callback may modify skills (or do anything else it wants) during passthrough.
miscellaneous
et_IPCReceive( vmnumber, message )
- Called when another mod sends an et.IPCSend() message to this mod. vmnumber is the VM slot number of the sender, and message is the message.
et_Print( text )
- Called whenever the server or qagame prints a string to the console.
- WARNING! text may contain a player name + their chat message. This makes it very easy to spoof. DO NOT TRUST STRINGS OBTAINED IN THIS WAY
et_Obituary( victim, killer, meansOfDeath )
- Called whenever a player is killed.
predefined constants
et.EXEC_NOW
et.EXEC_INSERT
et.EXEC_APPEND
et.FS_READ
et.FS_WRITE
et.FS_APPEND
et.FS_APPEND_SYNC
et.SAY_ALL
et.SAY_TEAM
et.SAY_BUDDY
et.SAY_TEAMNL
et.HOSTARCH
- set to WIN32 or UNIX depending on the host architecture qagame is running on.
LUA_PATH
- set to fs_homepath/fs_game/?.lua in order to ease use of the require function.
configs
If a config is loaded, all modules are shutdown and reloaded. If a certified config is loaded, all modules are shutdown and reloaded, and additionally the following functions are disabled: require(), loadfile(), loadlib(), loadstring(), dofile()
caveats
Like qagame, lua modules are unloaded and reloaded on map_restart and map changes. This means that all global variables and other information is lost. Mods may choose to store persistent data in cvars or external files.
FAQ
Q: OMG I hate the libary prefix et.* on everything!!11!1oneone
A: table.foreach(et, function (func, value) _G[func] = value; end)
Q: How do a reload my lua file without restarting the whole server?
A: Use map_restart, reset_match or simply change the map.
Q: Can I see some sample code?
A: Lua sample code
Q: Is there a list of ETPro Lua mods?
A: Yes, here.
Q: OMG my mod doesn't work!
A: Make sure you added your mod's filename to the lua_modules cvar (e.g. set lua_modules mymod.lua).
Q: OMG why has et_ClientSay been removed?
A: That's a secret but, to keep the function as it was, just add the following code to your et_ClientCommand() function
-- et_ClientSay had to be removed in order to intercept all commands -- so here's a wrapper for that arg0 = et.trap_Argv(0) -- get the main command if arg0 == "say" then return et_ClientSay( clientNum, et.SAY_ALL, et.ConcatArgs(1)) elseif arg0 == "say_team" then return et_ClientSay( clientNum, et.SAY_TEAM, et.ConcatArgs(1)) elseif arg0 == "say_buddy" then return et_ClientSay( clientNum, et.SAY_BUDDY, et.ConcatArgs(1)) elseif arg0 == "say_teamnl" then return et_ClientSay( clientNum, et.SAY_TEAMNL, et.ConcatArgs(1)) end -- et_ClientSay wrapper end