AMX Mod X 1.9 API Changes
⇅
.Contents
Documentation
A large part of the scripting documentation has been improved and an online version with searching capability can be found at https://amxmodx.org/api/.
Gamedata
As stated in the Release Notes, we have now gamedata files to avoid to hard code data related to the game or engine. Such files located in the amxmodx/data/gamedata/
directory.
Gamedata files shipped with AMX Mod X can and will be updated at any time, therefore it is strongly discouraged to edit them manually.
To make custom gamedata changes, please use the custom
folder under the gamedata
directory. All files under this directory are parsed (in an undefined order) after the main files are loaded. They will never be overwritten.
The files structure is currently arranged this way:
├─ common.games
│ ├─ entities.games
│ │ └─ $mod
│ │ ├─ offsets-$class.txt
│ │ ├─ ...
│ ├─ gamerules.games
│ │ └─ $mod
│ │ ├─ offsets-$class.txt
│ │ ├─ ...
│ ├─ hostages.games
│ │ └─ $mod
│ │ ├─ offsets-$class.txt
│ │ ├─ ...
│ ├─ others.games
│ │ └─ $mod
│ │ ├─ offsets-$class.txt
│ │ ├─ ...
│ ├─ functions.engine.txt
│ ├─ globalvars.engine.txt
│ └─ master.games.txt
├─ modules.games
│ ├─ master.games.txt
│ └─ game.cstrike.txt
The main directories are:
common.games
contains the shared data.modules.games
contains the data per module.
In those directories, you will find:
master.games.txt
which references all the files to be loaded by the core/modules.
Inside common.games
directory:
entities.games
,entities.games
,entities.games
andothers.games
directories contains the $class member's offset per-$mod. Related to gamerules object but also player, hostage, item and weapons entities.functions.engine.txt
contains the symbols/signatures of functions in the engine.globalvars.engine.txt
contains the symbols/signatures of global variables in the engine.
Inside modules.games
directory:
game.cstrike.txt
contains CS-specific data such as the symbol/signatures of functions and others static datas.
Compiler
Along a bunch of fixed issues, there are some improvements/features worth to be noted.
Emscripten support
The AMX Mod X Compiler can now be compiled with Emscripten allowing it to run inside of a web browser.
A good example is Spider, a web-based, entirely client-side, editor and compiler for [Source]Pawn development (by asherkin).
Increased Limits
Name/function and input line maximum length (in characters) have been increased.
Description | Old value | New value |
---|---|---|
Name/Function | 31
|
63
|
Input Line | 511
|
4095
|
Predefined Constants
Global | Description |
---|---|
__BINARY_NAME__
|
Name of the compiled plugin. Example: admin.amxx
|
__BINARY_PATH__
|
Absolute path to the compiled plugin. Example: /home/hlds/cstrike/addons/amxmodx/plugins/admin.amxx
|
__LINE__
|
Current line from the plugin's source code. |
Pragma
A new #pragma deprecated
has been added to tell the compiler that this specific native
/stock
is deprecated.
This will issue a warning upon the compilation.
#pragma deprecated Some comment here. native foo();
At compilation:
[...] warning 233: symbol "foo" is marked as deprecated: Some comment here.
String Literal Contatenation
This basically allows you to concatenate literal strings and stringizing a parameter in macro substitution only (so possible breakage is very limited).
Description | Symbol |
---|---|
To concatenate | +
|
To Stringize | #
|
#define PROJECT_AUTHOR "AMX Mod X" #define PROJECT_COPYRIGHT "Copyright (C) 2017 " + PROJECT_AUTHOR #define VERSION_MAJOR "1" #define VERSION_MINOR "9" #define VERSION_RELEASE "0" #define VERSION VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_RELEASE #define log(%1) "logging: " + #%1 + "\n" foo() { server_print(log(hello)); }
Internal Core Changes
String Buffer
The buffer size AMX Mod X uses internally to retrieve strings has been increased from 3k
to 16k
.
MAX_STRING_LENGTH
define has been added in amxconst.inc
.You probably should not use this define to actually declare a buffer unless you absolutely have to.
Look at
#pragma dynamic
to increase a plugins available memory.New Core APIs
Automatic Config File
This provides a system for plugins to automatically generate config files with plugin's cvars which get executed on load.
This is done via the AutoExecConfig
native.
Once all configuration files are executed, OnConfigsExecuted
is called. This forward will always be called, even if your plugin had no configs or if it was loaded late.
Native | Description |
---|---|
AutoExecConfig
|
⇅ Specifies that the given config file should be executed after plugin load.
/** * Specifies that the given config file should be executed after plugin load. * * @note OnConfigsExecuted() will not be called until the config file has executed, * but it will be called if the execution fails. * @note The name parameter should not contain dots, otherwise file will not be executed. * * @param autoCreate If true, and the config file does not exist, such a config * file will be automatically created and populated with * information from the plugin's registered cvars. * @param name Name of the config file, excluding the .cfg extension. * If empty, <plugin.filename.cfg> is assumed. * @param folder Folder under plugins/ to use. * * @noreturn */ native AutoExecConfig(bool:autoCreate = true, const name[] = "", const folder[] = ""); |
Forward | Description |
---|---|
OnConfigsExecuted
|
⇅ Called when the map has loaded, and all configs are done executing.
/** * Called when the map has loaded, and all configs are done executing. * This includes servercfgfile (server.cfg), amxx.cfg, plugin's config, and * per-map config. * * @note This is best place to initialize plugin functions which are based on cvar data. * @note This will always be called once and only once per map. It will be * called few seconds after plugin_cfg(). * * @noreturn */ forward OnConfigsExecuted(); |
OnAutoConfigsBuffered
|
⇅ Called when the map has loaded, right after plugin_cfg but any time before OnConfigsExecuted .
/** * Called when the map has loaded, right after plugin_cfg() but any time * before OnConfigsExecuted. It's called after amxx.cfg and all * AutoExecConfig() exec commands have been added to the server command buffer. * * @note This will always be called once and only once per map. * * @noreturn */ forward OnAutoConfigsBuffered(); |
#include <amxmodx> public plugin_init() { register_plugin("Hat", "User", "1.0"); create_cvar("mysqlk_database", "", .description = "MySQL database"); create_cvar("mysqlk_host", "localhost", .description = "MySQL host, use this to configure various^nthings for your server."); AutoExecConfig(); }
That would export a config file that looks like this:
// This file was auto-generated by AMX Mod X (v1.9) // Cvars for plugin "Hat" by "User" (hat.amxx, v1.0) // MySQL database // - // Default: "" mysqlk_database "" // MySQL host, use this to configure various // things for your server. // - // Default: "localhost" mysqlk_host "localhost"
DataPack
This offers you a way to dynamically store and move around various types of data.
Datapacks provide a way to store and move around arbitrary amounts (and types) of data in AMX Mox X, available from datapack.inc
.
Data is packed into a single cell value - the DataPack
handle. This handle can be passed around more easily, can be returned by functions and can simulate advanced concepts like string consummation.
Native | Description |
---|---|
Creating & Disposing | |
CreateDataPack
|
⇅ Creates a new datapack./** * Creates a new datapack. * * @return New datapack handle, which must be freed via DestroyDataPack(). */ native DataPack:CreateDataPack(); |
DestroyDataPack
|
⇅ Destroys the datapack and frees its memory./** * Destroys the datapack and frees its memory. * * @param pack Datapack handle * * @return True if disposed, false otherwise */ native DestroyDataPack(&DataPack:pack); |
Resetting | |
ResetPack
|
⇅ Resets the datapack read/write position to the start./** * Resets the datapack read/write position to the start. * * @param pack Datapack handle * @param clear If true, clears the contained data * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native ResetPack(DataPack:pack, bool:clear = false); |
Writing data | |
WritePackCell
|
⇅ Packs a cell value into a datapack./** * Packs a cell value into a datapack. * * @param pack Datapack handle * @param cell Cell value to pack * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native WritePackCell(DataPack:pack, any:cell); |
WritePackFloat
|
⇅ Packs a float value into a datapack./** * Packs a float value into a datapack. * * @param pack Datapack handle * @param val Float value to pack * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native WritePackFloat(DataPack:pack, Float:val); |
WritePackString
|
⇅ Packs a string into a datapack./** * Packs a string into a datapack. * * @param pack Datapack handle * @param str String to pack * * @return Length of copied string * @error If an invalid handle is provided, an error will be thrown. */ native WritePackString(DataPack:pack, const str[]); |
Reading data | |
ReadPackCell
|
⇅ Reads a cell from a Datapack./** * Reads a cell from a Datapack. * * @param pack Datapack handle * * @return Cell value * @error If an invalid handle is provided, or not enough data is left * in the datapack, an error will be thrown. */ native any:ReadPackCell(DataPack:pack); |
ReadPackFloat
|
⇅ Reads a float from a Datapack./** * Reads a float from a datapack. * * @param pack Datapack handle * * @return Float value * @error If an invalid handle is provided, or not enough data is left * in the datapack, an error will be thrown. */ native Float:ReadPackFloat(DataPack:pack); |
ReadPackString
|
⇅ Reads a string from a Datapack./** * Reads a string from a Datapack. * * @param pack Datapack handle * @param buffer Buffer to copy string to * @param maxlen Maximum size of buffer * * @return Number of cells written to buffer * @error If an invalid handle is provided, or not enough data is left * in the datapack, an error will be thrown. */ native ReadPackString(DataPack:pack, buffer[], maxlen); |
Managing position | |
GetPackPosition
|
⇅ Returns the datapack read/write position./** * Returns the datapack read/write position. * * @param pack Datapack handle * * @return Position in the datapack, only usable with calls to SetPackPosition * @error If an invalid handle is provided, an error will be thrown. */ native DataPackPos:GetPackPosition(DataPack:pack); |
SetPackPosition
|
⇅ Sets the datapack read/write position./** * Sets the datapack read/write position. * * @note This should only ever be used with (known to be valid) positions * returned by GetPackPosition(). It is not possible for plugins to safely * compute datapack positions. * * @param pack Datapack handle * @param position New position to set * * @noreturn * @error If an invalid handle is provided, or the new position is * out of datapack bounds, an error will be thrown. */ native SetPackPosition(DataPack:pack, DataPackPos:position); |
#include <amxmodx> public plugin_init() { // Creating new const DataPack:pack = CreateDataPack(); // Writing WritePackCell(pack, refCell); WritePackFloat(pack, refFloat); WritePackString(pack, refString); // Reset before reading ResetPack(pack); server_print("Datapack is readable: %s", !IsPackEnded(pack) ? "yes" : "no"); // Reading new cellValue = ReadPackCell(pack); new Float:floatValue = ReadPackFloat(pack); new buffer[32]; ReadPackString(pack, buffer, charsmax(buffer)); server_print("cellValue = %d, floatValue = %f, buffer = %s", cellValue, floatValue, buffer) server_print("Datapack is no more readable: %s", IsPackEnded(pack) ? "yes" : "no"); // Clear all data ResetPack(pack, .clear = true); server_print("Datapack is empty: %s", IsPackEnded(pack) ? "yes" : "no"); // Disposing DestroyDataPack(pack); }
Game Config Parser
Now we have gamedata files, we strongly encourage any plugins which hardcode static game datas to use the following API.
Native | Description |
---|---|
Loading & Closing file | |
LoadGameConfigFile
|
⇅ Loads a game config file./** * Loads a game config file. * * @note The file path must be relative to the 'gamedata' folder under the data folder * and the extension should be omitted. * * @param file File to load * * @return A handle to the game config file */ native GameConfig:LoadGameConfigFile(const file[]); |
CloseGameConfigFile
|
⇅ Destroys a game config and frees its memory./** * Destroys a game config and frees its memory. * * @note The function automatically sets the variable passed to it to 0 to aid * in preventing accidental usage after destroy. * * @param handle Game config handle * * @return 1 on success, 0 if an invalid handle was passed in */ native CloseGameConfigFile(&GameConfig:handle); |
Getting value | |
GameConfGetOffset
|
⇅ Returns an offset value./** * * * @param handle Game config handle * @param key Key to retrieve from the offset section * * @return An offset, or -1 on failure * @error Invalid game config handle */ native GameConfGetOffset(GameConfig:handle, const key[]); |
GameConfGetClassOffset
|
⇅ Returns an offset value given a classname./** * Returns an offset value given a classname. * * @param handle Game config handle * @param classname Class name to match from the offset section * @param key Key to retrieve from the offset section * * @return An offset, or -1 on failure * @error Invalid game config handle */ native GameConfGetClassOffset(GameConfig:handle, const classname[], const key[]); |
GameConfGetKeyValue
|
⇅ Gets the value of a key from the "Keys" section./** * Gets the value of a key from the "Keys" section. * * @param handle Game config handle * @param key Key to retrieve from the Keys section * @param buffer Destination string buffer * @param maxlen Maximum length of output string buffer * * @return True if key existed, false otherwise * @error Invalid game config handle */ native bool:GameConfGetKeyValue(GameConfig:handle, const key[], buffer[], maxlen); |
GameConfGetAddress
|
⇅ Finds an address calculation in a GameConfig file./** * Finds an address calculation in a GameConfig file. * * @param handle Game config handle * @param name Name of the property to find * * @return An address calculated on success, otherwise 0 on failure. * @error Invalid game config handle */ native GameConfGetAddress(GameConfig:handle, const name[]); |
Any default and new gamedata files must be located in /amxmodx/data/gamedata/
directory.
You can create your own directories inside as well.
Filename format
The file name must end with .txt
extension, e.g. myfile.txt
Loading a specific file
The right way to load a file is to provide the filename without .txt
extension.
E.g. LoadGameConfigFile("myfile")
will try to load /data/gamedata/myfile.txt
.
Loading multiple files
You are able to load several at once via a master file, named master.game.txt
.
A master file is basically a way to tell the parser to load any files listed inside and nothing else.
You can also specify whether a file should be loaded depending the mod name (such as cstrike
) or engine (dedicated server: engine_ds
or listen server: engine_ls
).
For example:
├─ gamedata │ └─ myfolder │ ├─ myfile1.txt │ ├─ myfile2.txt │ ├─ myfile3.txt │ └─ master.game.txt
master.game.txt
:
"Game Master" // Must start with this. { "myfile1.txt" // No option, will be loaded all the time { } "myfile2.txt" // Will be loaded for both servers { "engine" "engine_ds" "engine" "engine_ls" } "myfile3.txt" // Will be loaded only if the mod is Counter-Strike. { "game" "cstrike" } }
Then to load, you only need to provide your directory, e.g. LoadGameConfigFile("myfolder")
.
This will looks at the /gamedata/myfolder/master.game.txt
file and will load the listed files from there.
Config file format
The config file has a specific format as well. This must to start with:
"Games" { }
Then, you need to tell on what game the date will be loaded.
There are different values:
"<game name>"
, such ascstrike
"*"
or"#default"
to match any game
"Games" { "cstrike" { // Counter-Strike only } "#default" { // Any game // Note you can create multiple game blocks. } }
If you need to create a block which inherit multiple games or engine, you can achieve it with #supported
key.
"Games" { "#default" // Must start with this { "#supported" { "game" "cstrike" "game" "czero" "engine" "engine_ds" // you can specify the engine as well. } // Data } }
Data Type
There are 5 different types of datas that you are allowed to store:
- Signature:
- Retrieves an address from either a symbol or bytes. E.g.
@g_pGameRules
or\xDC\x2A\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x56
- Symbol must start with
@
. - For use with
GameConfGetAddress
native.
- Address:
- Reads a value from a given address (usually from signature reference)
- For use with
GameConfGetAddress
native.
- Offset:
- A platform-dependent value (windows, linux or mac)
- For use with
GameConfGetOffset
native.
- Class Offset:
- Same as Offset but can be grouped into a classname
- For use with
GameConfGetClassOffset
native.
- Keyvalue:
- simple key associated to a value.
- For use with
GameConfGetKeyValue
native.
"Games" { "#default" { "Signatures" { "SV_DropClient" { "library" "engine" // This can be either "server" (mod), "engine_ds" (dedicated server) or "engine_ls' (listen server) "windows" "\x55\x8B\x2A\x81\x2A\x2A\x2A\x2A\x2A\x8B\x2A\x2A\x53\x56\x8D" "linux" "@SV_DropClient" "mac" "@SV_DropClient" // Note: A symbol must start always with '@' } "g_pGameRules" { "library" "server" "windows" "\x8B\x2A\x2A\x2A\x2A\x2A\x85\x2A\x74\x2A\x8B\x2A\xFF\x2A\x2A\xA1" // StartFrame() "linux" "@g_pGameRules" "mac" "@g_pGameRules" } } "Offsets" { "something" { "windows" "4" "linux" "2" "mac" "0" } } "Classes" { "CSomething" { "Offsets" { "windows" "4" "linux" "2" "mac" "0" } } } "Addresses" { "GameRulesPointer" // Gets the address of "g_pGameRules", adds 2 bytes on windows and 0 byte on linux/mac. { "signature" "g_pGameRules" "windows" { "read" "2" } "read" "0" } "Something" // Gets the address of "SV_DropClient" and adds 5 bytes, on linux platform only. { "linux" { signature "SV_DropClient" "read" "5" } } } "Keys" { "key1" "value1" "Key2" "value2" } } }
Hasher
Supports several new hash types: CRC32, MD5, SHA*, Keccak*.
md5
and md5_file
natives.Native | Description |
---|---|
hash_string
|
⇅ Generates a hash value (message digest)./** * Generates a hash value (message digest) * * @param string String to be hashed. * @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file. * @param output Output string to store hash in. * @param outputSize The maximum size of the output string to store hash in. * * @return Number of written bytes. */ native hash_string(const string[], const HashType:type, output[], const outputSize); |
hash_file
|
⇅ Generates a hash value using the contents of a given file./** * Generates a hash value using the contents of a given file * * @param fileName Path of file to be hashed. * @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file. * @param output Output string to store hash in. * @param outputSize The maximum size of the output string to store hash in. * * @return Number of written bytes. * @error If the file couldn't be opened, an error is thrown. */ native hash_file(const fileName[], const HashType:type, output[], const outputSize); |
The available HashType
constants are:
Hash_Crc32
Hash_Md5
Hash_Sha1
Hash_Sha256
Hash_Sha3_224
Hash_Sha3_256
Hash_Sha3_384
Hash_Sha3_512
Hash_Keccak_224
Hash_Keccak_256
Hash_Keccak_384
Hash_Keccak_512
#include <amxmodx> public plugin_init() { new hash1[32]; new const message[] = "Hello World!"; new const length = hash_string(message, Hash_Md5, hash1, charsmax(hash1)); server_print("hash1 = %s", hash1); new hash2[32]; new const fileName[] = "server.cfg"; new const length = hash_file(message, Hash_Md5, hash2, charsmax(hash2)); server_print("hash2 = %s", hash2); }
Stack Structure
A stack is a LIFO (last in, first out) dynamic vector of of items.
Stacks provide only two operations:
- Push, adding an item to the top.
- Pop, removing an item from the top, in reverse-push order.
testsuite
directory, see stacktest.sma.Native | Description |
---|---|
Creating & Destroying | |
CreateStack
|
⇅ Creates a stack structure./** * Creates a stack structure. A stack is a LIFO (last in, first out) vector of * of items. It has O(1) insertion and O(1) removal. * * @note Stacks provide only two operations: Push (adding an item to the top) * and Pop (remove an item from the top, in reverse-push order). * @note The contents of the stack are uniform; i.e. storing a string and then * retrieving it as an integer is NOT the same as str_to_num()! * @note The "blocksize" determines how many cells each stack slot has, it can * not be changed after creation. * * @param blocksize The number of cells each entry in the stack can hold * * @return New stack Handle, which must be freed via DestroyStack() * @error If an invalid blocksize is provided an error will be * thrown. */ native Stack:CreateStack(blocksize = 1); |
DestroyStack
|
⇅ Destroys a stack and frees its memory./** * Destroys a stack and frees its memory. * * @note The function automatically sets the variable passed to it to 0 to aid * in preventing accidental usage after destroy. * * @param handle Stack to destroy * * @return 1 if the Stack was destroyed, 0 if nothing had to be * destroyed (invalid handle) */ native DestroyStack(&Stack:handle); |
Pushing Data | |
PushStackCell
|
⇅ Pushes a value onto the end of the stack, adding a new index./** * Pushes a value onto the end of the stack, adding a new index. * * @note This may safely be used even if the stack has a blocksize greater than * 1. * * @param handle Stack handle * @param value Value to push * * @noreturn * @error If an invalid handle is provided or the resizing * operation runs out of memory, an error will be thrown. */ native PushStackCell(Stack:handle, any:value); |
PushStackString
|
⇅ Pushes a string onto the end of a stack, truncating it if it is too long./** * Pushes a string onto the end of a stack, truncating it if it is too long. * * @param handle Stack handle * @param value String to push * * @noreturn * @error If an invalid handle is provided or the resizing * operation runs out of memory, an error will be thrown. */ native PushStackString(Stack:handle, const value[]); |
PushStackArray
|
⇅ Pushes an array of cells onto the end of a stack./** * Pushes an array of cells onto the end of a stack. The cells are pushed as a * block (i.e. the entire array takes up one stack slot), rather than pushing * each cell individually. * * @param handle Stack handle * @param values Block of values to copy * @param size If not set, the number of elements copied from the array * will be equal to the blocksize, if set higher than the * blocksize, the operation will be truncated, * * @noreturn * @error If an invalid handle is provided or the resizing * operation runs out of memory, an error will be thrown. */ native PushStackArray(Stack:handle, const any:values[], size= -1); |
Poping Data | |
PopStackCell
|
⇅ Pops a cell value from a stack./** * Pops a cell value from a stack. * * @param handle Stack handle * @param value Variable to store the value in * @param block Optionally specify which block to read from (useful if the * blocksize is > 0) * @param asChar Optionally read as a byte instead of a cell * * @return True on success, false if the stack is empty. * @error If an invalid handle, invalid block or invalid byte is * provided, an error will be thrown. */ native bool:PopStackCell(Stack:handle, &any:value, block = 0, bool:asChar = false); |
PopStackString
|
⇅ Pops a string value from a stack./** * Pops a string value from a stack. * * @param handle Stack handle * @param buffer Buffer to copy string to * @param maxlength Maximum size of the buffer * @param written Variable to store number of characters copied to * * @return True on success, false if the stack is empty * @error If an invalid handle is provided an error will be thrown. */ native bool:PopStackString(Stack:handle, buffer[], maxlength, &written = 0); |
PopStackArray
|
⇅ Pops an array of cells from a stack./** * Pops an array of cells from a stack. * * @param handle Stack handle * @param buffer Array to copy value to * @param size Size of buffer, if not set (-1) assumes the size is equal to * the stack blocksize * * @return True on success, false if the stack is empty * @error If an invalid handle is provided an error will be thrown. */ native bool:PopStackArray(Stack:handle, any:buffer[], size = -1); |
Others | |
IsStackEmpty
|
⇅ Returns if a stack is empty./** * Returns if a stack is empty. * * @param handle Stack handle * * @return True if empty, false if not empty * @error If an invalid handle is provided an error will be thrown. */ native bool:IsStackEmpty(Stack:handle); |
Stock | Description |
---|---|
PopStack
|
⇅ Pops a value off a stack, ignoring it completely./** * Pops a value off a stack, ignoring it completely. * * @param handle Stack handle * * @return True if a value was popped, false if stack is empty * @error If an invalid handle is provided an error will be thrown. */ stock PopStack(Stack:handle) { new value; return PopStackCell(handle, value); } |
Text Parser INI/SMC
Event-based text parser to read data in an unified way. It supports INI and SMC (similar to VTF) formats.
testsuite
directory, see textparse.sma.SMC Format
/** * The SMC file format is defined as: * WHITESPACE: 0x20, \n, \t, \r * IDENTIFIER: Any ASCII character EXCLUDING ", {, }, ;, //, / *, or WHITESPACE. * STRING : Any set of symbols enclosed in quotes. * * Note: if a STRING does not have quotes, it is parsed as an IDENTIFIER. * * Basic syntax is comprised of SECTIONBLOCKs. * A SECTIONBLOCK defined as: * * SECTIONNAME * { * OPTION * } * * OPTION can be repeated any number of times inside a SECTIONBLOCK. * A new line will terminate an OPTION, but there can be more than one OPTION per line. * OPTION is defined any of: * "KEY" "VALUE" * SECTIONBLOCK * * SECTIONNAME, KEY, VALUE, and SINGLEKEY are strings * SECTIONNAME cannot have trailing characters if quoted, but the quotes can be optionally removed. * If SECTIONNAME is not enclosed in quotes, the entire sectionname string is used (minus surrounding whitespace). * If KEY is not enclosed in quotes, the key is terminated at first whitespace. * If VALUE is not properly enclosed in quotes, the entire value string is used (minus surrounding whitespace). * The VALUE may have inner quotes, but the key string may not. * * WHITESPACE should be ignored. * Comments are text occurring inside the following tokens, and should be stripped * unless they are inside literal strings: * ;<TEXT> * //<TEXT> * / *<TEXT> * / * * Example file below: * "SomeSection" * { * /** * * Some comment * */ * "Key" "value" * } */
Native | Description |
---|---|
SMC_CreateParser
|
⇅ Creates a new SMC parser.
/** * Parser invalid code. */ enum SMCParser { Invalid_SMCParser = 0 }; /** * Parse result directive. */ enum SMCResult { SMCParse_Continue, /* Continue parsing */ SMCParse_Halt, /* Stop parsing here */ SMCParse_HaltFail /* Stop parsing and return failure */ }; /** * Creates a new SMC parser. * This is used to set parse hooks. * * @return A new handle to an SMC Parse structure. */ native SMCParser:SMC_CreateParser(); |
SMC_DestroyParser
|
⇅ Disposes of an SMC parser.
/** * Disposes of an SMC parser. * * @param handle Handle to an SMC Parse structure. * * @return True if disposed, false otherwise. */ native SMC_DestroyParser(&SMCParser:handle); |
SMC_ParseFile
|
⇅ Parses a config file.
/** * Parses a config file. * * @param handle A handle to an SMC Parse structure. * @param file A string containing the file path. * @param line An optional by reference cell to store the last line number read. * @param col An optional by reference cell to store the last column number read. * @param data An optional handle or value to pass through to callback functions * * @return An SMCParseError result. * @error Invalid or corrupt handle. */ native SMCError:SMC_ParseFile(SMCParser:handle, const file[], &line = 0, &col = 0, any:data = 0); /** * Parse error codes. */ enum SMCError { SMCError_Okay = 0, /* No error */ SMCError_StreamOpen, /* Stream failed to open */ SMCError_StreamError, /* The stream died... somehow */ SMCError_Custom, /* A custom handler threw an error */ SMCError_InvalidSection1, /* A section was declared without quotes, and had extra tokens */ SMCError_InvalidSection2, /* A section was declared without any header */ SMCError_InvalidSection3, /* A section ending was declared with too many unknown tokens */ SMCError_InvalidSection4, /* A section ending has no matching beginning */ SMCError_InvalidSection5, /* A section beginning has no matching ending */ SMCError_InvalidTokens, /* There were too many unidentifiable strings on one line */ SMCError_TokenOverflow, /* The token buffer overflowed */ SMCError_InvalidProperty1, /* A property was declared outside of any section */ }; |
SMC_SetParseStart
|
⇅ Sets the SMC_ParseStart function of a parse handle.
/** * Sets the SMC_ParseStart function of a parse handle. * * @note Below is the prototype of callback: * - * Called when parsing is started. * * @param handle Handle to an SMC Parse structure. * @param data Handle or value passed in SMC_ParseFile * * @noreturn * * public OnParseStart(SMCParser:handle, any:data) * - * @param handle Handle to an SMC Parse structure. * @param func A ParseStart callback. * * @noreturn * @error Invalid or corrupt handle. */ native SMC_SetParseStart(SMCParser:handle, const func[]); |
SMC_SetParseEnd
|
⇅ Sets the SMC_ParseEnd function of a parse handle.
/** * Sets the SMC_ParseEnd function of a parse handle. * * @note Below is the prototype of callback: * - * Called when parsing is halted. * * @param handle Handle to an SMC Parse structure. * @param halted True if abnormally halted, false otherwise. * @param failed True if parsing failed, false otherwise. * @param data Handle or value passed in SMC_ParseFile * * @noreturn * * public OnParseEnd(SMCParser:handle, bool:halted, bool:failed, any:data) * - * @param handle Handle to an SMC Parse structure. * @param func A ParseEnd callback. * * @noreturn * @error Invalid or corrupt handle. */ native SMC_SetParseEnd(SMCParser:handle, const func[]); |
SMC_SetReaders
|
⇅ Sets the three main reader functions.
/** * Sets the three main reader functions. * * @note Enclosing quotes are always stripped. * @note Below is the prototype of callbacks: * - * NewSection: * Called when the parser finds a new section or sub-section. * * @param handle Handle to an SMC Parse structure. * @param name String containing section name. * @param data Handle or value passed in SMC_ParseFile * * @return An SMCResult action to take. * * public SMCResult:OnNewSection(SMCParser:handle, const name[], any:data) * * KeyValue: * Called when the parser finds a new key/value pair. * * @param handle Handle to an SMC Parse structure. * @param key String containing key name. * @param value String containing value name. * @param data Handle or value passed in SMC_ParseFile * * @return An SMCResult action to take. * * public SMCResult:OnKeyValue(SMCParser:handle, const key[], const value[], any:data) * * EndSection: * Called when the parser finds the end of the current section. * * @param handle Handle to an SMC Parse structure. * @param data Handle or value passed in SMC_ParseFile * * @return An SMCResult action to take. * * public SMCResult:OnEndSection(SMCParser:handle, any:data) * - * @param handle Handle to an SMC Parse structure. * @param kv A KeyValue callback. * @param ns An optional NewSection callback. * @param es An optional EndSection callback. * * @noreturn */ native SMC_SetReaders(SMCParser:smc, const kvFunc[], const nsFunc[] = "", const esFunc[] = ""); |
SMC_SetRawLine
|
⇅ Sets a raw line reader on an text parser handle.
/** * Sets a raw line reader on an text parser handle. * * @note Below is the prototype of callbacks: * - * Called whenever a raw line is read. * * @param handle Handle to an SMC Parse structure. * @param line A string containing the raw line from the file. * @param lineno The line number it occurs on. * @param data Handle or value passed in SMC_ParseFile * * @return An SMCResult action to take. * * public SMCResult:SMC_RawLine(SMCParser:handle, const line[], lineno, any:data) * - * @param handle Handle to an SMC Parse structure. * @param func A RawLine callback. * * @noreturn */ native SMC_SetRawLine(SMCParser:handle, const func[]); |
SMC_GetErrorString
|
⇅ Gets an error string for an SMCError code.
/** * Gets an error string for an SMCError code. * * @note SMCError_Okay returns false. * @note SMCError_Custom (which is thrown on SMCParse_HaltFail) returns false. * * @param error The SMCParseError code. * @param buffer A string buffer for the error (contents undefined on failure). * @param buf_max The maximum size of the buffer. * * @return True on success, false otherwise. */ native bool:SMC_GetErrorString(SMCError:error, buffer[], buf_max); |
INI Format
/** * The INI file format is defined as: * WHITESPACE: 0x20, \n, \t, \r * IDENTIFIER: A-Z a-z 0-9 _ - , + . $ ? / * STRING : Any set of symbols * * Basic syntax is comprised of SECTIONs. * A SECTION is defined as: * [SECTIONNAME] * OPTION * OPTION * OPTION... * * SECTIONNAME is an IDENTIFIER. * OPTION can be repeated any number of times, once per line. * OPTION is defined as one of: * KEY = "VALUE" * KEY = VALUE * KEY * Where KEY is an IDENTIFIER and VALUE is a STRING. * * WHITESPACE should always be omitted. * COMMENTS should be stripped, and are defined as text occurring in: * ;<TEXT> * * Example file below. Note that the second line is technically invalid. * The event handler must decide whether this should be allowed. * --FILE BELOW-- * [gaben] * hi = clams * bye = "NO CLAMS" * * [valve] * cannot * maintain * products */
Native | Description |
---|---|
INI_CreateParser
|
⇅ Creates a new SMC parser.
/** * Parser invalid code. */ enum INIParser { Invalid_INIParser = 0 }; /** * Creates a new INI parser. * This is used to set parse hooks. * * @return A new handle to an INI Parse structure. */ native INIParser:INI_CreateParser(); |
INI_DestroyParser
|
⇅ Disposes of an INI parser.
/** * Disposes of an INI parser. * * @param handle Handle to an INI Parse structure. * * @return True if disposed, false otherwise. */ native INI_DestroyParser(&INIParser:handle); |
INI_ParseFile
|
⇅ Parses an INI config file.
/** * Parses an INI config file. * * @param handle A handle to an INI Parse structure. * @param file A string containing the file path. * @param line An optional by reference cell to store the last line number read. * @param col An optional by reference cell to store the last column number read. * @param data An optional handle or value to pass through to callback functions * * @return An SMCParseError result. * @error Invalid or corrupt handle. */ native bool:INI_ParseFile(INIParser:handle, const file[], &line = 0, &col = 0, any:data = 0); |
INI_ParseStart
|
⇅ Sets the INI_ParseStart function of a parse handle.
/** * Sets the INI_ParseStart function of a parse handle. * * @note Below is the prototype of callback: * - * Called when parsing is started. * * @param handle A handle to an INI Parse structure. * @param data Handle or value passed in INI_ParseFile * * @noreturn * * public OnParseStart(INIParser:handle, any:data) * - * @param handle Handle to an INI Parse structure. * @param func A ParseStart callback. * * @noreturn * @error Invalid or corrupt handle. */ native INI_SetParseStart(INIParser:handle, const func[]); |
INI_SetParseEnd
|
⇅ Sets the INI_ParseEnd function of a parse handle.
/** * Sets the INI_ParseEnd function of a parse handle. * * @note Below is the prototype of callback: * - * Called when parsing is halted. * * @param handle A handle to an INI Parse structure. * @param halted True if abnormally halted, false otherwise. * @param data Handle or value passed in INI_ParseFile * * @noreturn * * public OnParseEnd(INIParser:handle, bool:halted, any:data) * - * @param handle Handle to an INI Parse structure. * @param func A ParseEnd callback. * * @noreturn * @error Invalid or corrupt handle. */ native INI_SetParseEnd(INIParser:handle, const func[]); |
INI_SetReaders
|
⇅ Sets the two main reader functions.
/** * Sets the two main reader functions. * * @note Below is the prototype of callback: * - * NewSection: * Called when the parser finds a new section. * * @param handle Handle to an INI Parse structure. * @param section Name of section in between the [ and ] characters. * @param invalid_tokens True if invalid tokens were detected in the name. * @param close_bracket True if a closing bracket was detected, false otherwise. * @param extra_tokens True if extra tokens were detected on the line. * @param curtok Contains current token in the line where the section name starts. * You can add to this offset when failing to point to a token. * @param data Handle or value passed in INI_ParseFile * * @return True to keep parsing, false otherwise. * * public bool:OnNewSection(INIParser:handle, const section[], bool:invalid_tokens, bool:close_bracket, bool:extra_tokens, curtok, any:data) * * KeyValue: * Called when the parser finds a new key/value pair. * * @param handle Handle to an INI Parse structure. * @param key Name of key. * @param value String containing value (with quotes stripped, if any). * @param invalid_tokens Whether or not the key contained invalid tokens. * @param equal_token There was an '=' sign present (in case the value is missing). * @param quotes Whether value was enclosed in quotes. * @param curtok Contains the token index of the start of the value string. * This can be changed when returning false. * @param data Handle or value passed in INI_ParseFile * * @return True to keep parsing, false otherwise. * * public bool:OnKeyValue(INIParser:handle, const key[], const value[], bool:invalid_tokens, bool:equal_token, bool:quotes, curtok, any:data) * - * @param handle Handle to an INI Parse structure. * @param kv A KeyValue callback. * @param ns An optional NewSection callback. * * @noreturn */ native INI_SetReaders(INIParser:smc, const kvFunc[], const nsFunc[] = "" ); |
INI_SetRawLine
|
⇅ Sets a raw line reader on an INI parser handle.
/** * Sets a raw line reader on an INI parser handle. * * @note Below is the prototype of callback: * - * Called whenever a raw line is read. * * @param handle The INI Parse handle. * @param line Contents of line. * @param lineno The line number it occurs on. * @param curtok Pointer to optionally store failed position in string. * @param data Handle or value passed in INI_ParseFile * * @return True to keep parsing, false otherwise. * * public bool:OnRawLine(INIParser:smc, const line[], lineno, curtok, any:data) * * @param handle Handle to an INI Parse structure. * @param func A RawLine callback. * * @noreturn */ native INI_SetRawLine(INIParser:handle, const func[]); |
Existing core APIs additions
Client
Behavior changes
- The following natives can now be used on connecting players:
find_player
,get_players
andengclient_print
(console only). set_user_rendering
defaultcolor
andamount
are now set to 0 to follow game behavior.
(Dis)connection
client_disconnect
forward is deprecated in favor of client_disconnected
.This will be called in some additional cases that
client_disconnect
doesn't cover, most notably when a client aborts the connection process. It is guaranteed to pair with the
client_connect
forward.Forward | Description |
---|---|
client_connectex
|
⇅ Called when a client is connecting./** * Called when a client is connecting. * * @note This forward is called too early to do anything that directly affects * the client. * * @param id Client index * @param name Client name * @param ip Client ip address with port * @param reason A reason that will be displayed when player gets rejected (can be overwritten) * * @return PLUGIN_CONTINUE to let a client join to the server * PLUGIN_HANDLED or higher to prevent a client to join */ forward client_connectex(id, const name[], const ip[], reason[128]); |
client_disconnected
|
⇅ Called when a client is disconnected from the server./** * Called when a client is disconnected from the server. * * @note This will be called in some additional cases that client_disconnect doesn't cover, * most notably when a client aborts the connection process. It is guaranteed to pair * with the client_connect() forward. * @note When this fires the player entity is still valid (e.g. is_user_connected(id) will * return true), but no networked commands will reach the client. * * @param id Client index * @param drop If true, the game has explicitly dropped the client * @param message If drop is true, a writable buffer containing the disconnect info message * @param maxlen Maximum size of buffer * * @noreturn */ forward client_disconnected(id, bool:drop, message[], maxlen); |
client_remove
|
⇅ Called when a client entity has been removed from the server./** * Called when a client entity has been removed from the server. * * @note This fires after the client_disconnected() forward, when the player entity has been * removed (e.g. is_user_connected(id) will return false). * * @param id Client index * @param drop If true, the game has explicitly dropped the client * @param message If drop is true, contains the disconnect info message * * @noreturn */ forward client_remove(id, bool:drop, const message[]); |
New Natives & Stocks
For the sake of better understanding and readability, find_player
and get_players
have now their counterparts which use the flags ⇅ as name constants instead of letter. It is encouraged to use them instead.
/** * FindPlayerFlags constants for find_player_ex() */ enum FindPlayerFlags (<<= 1) { FindPlayer_None = 0, // None FindPlayer_MatchName = 1, // Match with name FindPlayer_MatchNameSubstring, // Match with name substring FindPlayer_MatchAuthId, // Match with authid FindPlayer_MatchIP, // Match with ip FindPlayer_MatchTeam, // Match with team name FindPlayer_ExcludeDead, // Do not include dead clients FindPlayer_ExcludeAlive, // Do not include alive clients FindPlayer_ExcludeBots, // Do not include bots FindPlayer_ExcludeHuman, // Do not include human clients FindPlayer_LastMatched, // Return last matched client instead of the first FindPlayer_MatchUserId, // Match with userid FindPlayer_CaseInsensitive, // Match case insensitively FindPlayer_IncludeConnecting // Include connecting clients }
Native & Stock | Description |
---|---|
find_player_ex
|
⇅ Finds a player given a filter./** * Find a player given a filter. * * @note If matching by userid, do not also specify FindPlayer_MatchName, FindPlayer_MatchNameSubstring * or FindPlayer_MatchAuthId, or the function may not return a correct result. * * @param flags Filtering flags (enum FindPlayerFlags); valid flags are: * FindPlayer_MatchName - match with name * FindPlayer_MatchNameSubstring - match with name substring * FindPlayer_MatchAuthId - match with authid * FindPlayer_MatchIP - match with ip * FindPlayer_MatchTeam - match with team name * FindPlayer_ExcludeDead - do not include dead clients * FindPlayer_ExcludeAlive - do not include alive clients * FindPlayer_ExcludeBots - do not include bots * FindPlayer_ExcludeHuman - do not include human clients * FindPlayer_LastMatched - return last matched client instead of the first * FindPlayer_MatchUserId - match with userid * FindPlayer_CaseInsensitive - match case insensitively * FindPlayer_IncludeConnecting - include connecting clients * @param ... String to match against (integer if FindPlayer_MatchUserId is specified) * * @return Client index, or 0 if no client was found */ native find_player_ex(FindPlayerFlags:flags, ...); |
get_players_ex
|
⇅ Stores a filtered list of client indexes to an array./** * Stores a filtered list of client indexes to an array. * * @note Example retrieving all alive CTs: * get_players_ex(players, num, GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT") * * @param players Array to store indexes to * @param num Variable to store number of indexes to * @param flags Optional filtering flags (enum GetPlayersFlags); valid flags are: * GetPlayers_None - No filter (Default) * GetPlayers_ExcludeDead - do not include dead clients * GetPlayers_ExcludeAlive - do not include alive clients * GetPlayers_ExcludeBots - do not include bots * GetPlayers_ExcludeHuman - do not include human clients * GetPlayers_MatchTeam - match with team * GetPlayers_MatchNameSubstring - match with part of name * GetPlayers_CaseInsensitive - match case insensitive * GetPlayers_ExcludeHLTV - do not include HLTV proxies * GetPlayers_IncludeConnecting - include connecting clients * @param team String to match against if the "e" or "f" flag is specified * * @noreturn */ stock get_players_ex(players[MAX_PLAYERS], &num, GetPlayersFlags:flags = GetPlayers_None, const team[] = "") { new strFlags[10]; get_flags(_:flags, strFlags, charsmax(strFlags)); get_players(players, num, strFlags, team); } |
findPlayer() { new const dead_player = find_player_ex(FindPlayer_MatchName | FindPlayer_ExcludeAlive, "egg"); } getPlayer() { new playersList[MAX_PLAYERS], playersCount; get_players_ex(playersList, playersCount, GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT"); }
New params
Native | parameter | Description |
---|---|---|
user_silentkill
|
flag
|
⇅ If nonzero, the death will not affect the client's score.stock user_silentkill(index, flag = 1) { static msgid = 0; new msgblock; if (!msgid) { msgid = get_user_msgid("DeathMsg"); } msgblock = get_msg_block(msgid); set_msg_block(msgid, BLOCK_ONCE); user_kill(index, flag); set_msg_block(msgid, msgblock); return 1; } |
Forward | parameter | Description |
---|---|---|
client_authorized
|
authid
|
forward client_authorized(id, const authid[]); | Client auth
Command
Callback
Native | Description |
---|---|
amxclient_cmd
|
⇅ Executes a command from the client without actually sending it to the client's DLL. Similar to engclient_cmd with the difference this triggers plugin command hooks.
/** * Execute a command from the client without actually sending it to the client's * DLL. This triggers plugin command hooks. * * @note This emulates a client command on the server side, and is an excellent * tool to force a client to do certain actions related to the game. * @note The command has to stand alone in the command parameter, only add * arguments using the designated parameters. * @note Commands emulated using this function will trigger other plugin's * command hooks. For an alternative that doesn't, see engclient_cmd() * * @param index Client index, use 0 to execute from all clients * @param command Client command to execute on * @param arg1 Optional command arguments * @param arg2 Optional command arguments * * @noreturn * @error If a single client is specified and the index is not within * the range of 1 to MaxClients, an error will be thrown. */ native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = ""); |
Arguments conversion
New natives to retrieve a command's argument directly as an integer or float instead of as a string (read_argv()
).
Native | Description |
---|---|
read_argv_int
|
⇅ Retrieves argument of client command as integer value.
/** * Retrieves argument of client command as integer value. * * @note Should only be used inside of the client_command() forward. * * @param id Argument index starting from 1 * * @return Integer value */ native read_argv_int(id); |
read_argv_float
|
⇅ Retrieves argument of client command as float value.
/** * Retrieves argument of client command as float value. * * @note Should only be used inside of the client_command() forward. * * @param id Argument index starting from 1 * * @return Float value */ native Float:read_argv_float(id); |
#include <amxmodx> public plugin_init() { register_clcmd("set_level", "@OnSetLevel", .info = "<value> - Sets a custom level"); } @OnSetLevel(const client, const command_level, const command_id) { new const value = read_argv_int(1); }
Translatable description
In order to encourage the translations of command's description, a new parameter is available.
This is useful for use with the amx_help
client command for example.
Native | parameter | Description |
---|---|---|
register_clcmd register_concmd register_srvcmd
|
info_ml
|
⇅ If true, the parameter info will be looked up as multilingual key./** * Registers a callback to be called when the client executes a command from the * console. * * @note For a list of possible access flags, see the ADMIN_* constants in * amxconst.inc * @note Opting in to FlagManager enables the admin privileges to be overwritten * by the end user via the cmdaccess.ini config file. * @note Automatic detection for FlagManager will only include a command if it * has required privileges (flags is not -1) and it is not a command * starting with "say". * * @param client_cmd Command to register * @param function Callback function * @param flags Admin privilege flags required * @param info Command description * @param FlagManager 0 opts out of flag manager, 1 opts in, -1 selects * automatically * @param info_ml If true, the parameter "info" will be looked up as multilingual key * * @return Command id, 0 on failure * @error If an invalid callback function is specified, an error * will be thrown. */ native register_clcmd(const client_cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false); /** * Registers a callback to be called when the client or server executes a * command from the console. * * @note For a list of possible access flags, see the ADMIN_* constants in * amxconst.inc * @note Opting in to FlagManager enables the admin privileges to be overwritten * by the end user via the cmdaccess.ini config file. * @note Automatic detection for FlagManager will only include a command if it * has required privileges (flags is not -1) and it is not a command * starting with "say". * * @param client_cmd Command to register * @param function Callback function * @param flags Admin privilege flags required * @param info Command description * @param FlagManager 0 opts out of flag manager, 1 opts in, -1 selects * automatically * @param info_ml If true, the parameter "info" will be looked up as multilingual key * * @return Command id, 0 on failure * @error If an invalid callback function is specified, an error * will be thrown. */ native register_concmd(const cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false); /** * Registers a callback to be called when the server executes a command from the * console. * * @note For a list of possible access flags, see the ADMIN_* constants in * amxconst.inc * * @param client_cmd Command to register * @param function Callback function * @param flags Admin privilege flags required * @param info Command description * @param info_ml If true, the parameter "info" will be looked up as multilingual key * * @return Command id, 0 on failure * @error If an invalid callback function is specified, an error * will be thrown. */ native register_srvcmd(const server_cmd[], const function[], flags = -1, const info[] = "", bool:info_ml = false); |
[en] MY_KEY = Hello world!
#include <amxmodx> public plugin_init() { register_clcmd("my_command", "OnMyCommand", ADMIN_CFG, "MY_KEY", .info_ml = true); }
Cvar
In order to manage cvars more easily, several new cvar features have been added.
cvars.inc
include file.Hooking
You can now hook when a cvar value has changed. This allows plugins to react to cases where other plugins or clients change a cvar's value.
Native | Description |
---|---|
hook_cvar_change
|
⇅ To create a hook
/** * Creates a hook for when a cvar's value is changed. * * @note Changing the cvar value from within this forward can lead to infinite * recursion and should be avoided. * @note The callback will be called in the following manner: * * public cvar_change_callback(pcvar, const old_value[], const new_value[]) * * pcvar - Pointer to cvar that was changed * old_value - Buffer containing the previous value of the cvar * new_value - Buffer containing the new value of the cvar * * The return value is ignored * * @param pcvar Pointer to cvar * @param callback Name of callback function * * @return Callback handle that can be used with * [disable|enable]_cvar_hook * @error If an invalid cvar pointer or callback function is provided, * an error will be thrown. */ native cvarhook:hook_cvar_change(pcvar, const callback[]); |
disable_cvar_hook
|
⇅ To disable a hook
/** * Disables a cvar hook, stopping it from being called. * * @note Use the handle returned by hook_cvar_change as the parameter here. * * @param handle Forward to disable * @error If an invalid hook handle is provided, an error will be * thrown. */ native disable_cvar_hook(cvarhook:handle); |
enable_cvar_hook
|
⇅ To enable a hook/** * Enables a cvar hook, restoring it to being called. * * @note Use the handle returned by hook_cvar_change as the parameter here. * * @param handle Forward to enable * @error If an invalid hook handle is provided, an error will be * thrown. */ native enable_cvar_hook(cvarhook:handle); |
#include <amxmodx> new cvarhook:CvarHandle; public plugin_init() { CvarHandle = hook_cvar_change(get_cvar_pointer("mp_timelimit"), "@OnTimelimitChange"); register_concmd("enable_hook" , "@OnConsoleCommand_EnableHook"); register_concmd("disable_hook", "@OnConsoleCommand_DisableHook"); } @OnTimelimitChange(const pointer, const old_value[], const new_value[]) { server_print("mp_timelimit: %s -> %s", old_value, new_value); } @OnClientCommand_EnableHook() { enable_cvar_hook(CvarHandle); } @OnClientCommand_DisableHook() { disable_cvar_hook(CvarHandle); }
Binding
There are situations where you don't need to hook/manage a cvar value and you would wish to not deal with cvar pointers.
You can now bind a cvar's value to a global variable. This means that variable value will be always up to date.
Native | Description |
---|---|
bind_pcvar_num
|
⇅ To bind an integer/** * Binds a cvar's integer value to a global variable. The variable will then * always contain the current cvar value as it is automatically kept up to date. * * @note The variable *has* to be a global or a static variable. Local variables * created within functions can not be used for technical reasons. * @note Variables can not be bound to multiple cvars. * * @param pcvar Pointer to cvar * @param var Global variable to keep updated * * @noreturn * @error If an invalid cvar pointer or variable is provided, an error * will be thrown. */ native bind_pcvar_num(pcvar, &any:var); |
bind_pcvar_float
|
⇅ To bind a float/** * Binds a cvar's float value to a global variable. The variable will then * always contain the current cvar value as it is automatically kept up to date. * * @note The variable *has* to be a global or a static variable. Local variables * created within functions can not be used for technical reasons. * @note Variables can not be bound to multiple cvars. * * @param pcvar Pointer to cvar * @param var Global variable to keep updated * * @noreturn * @error If an invalid cvar pointer or variable is provided, an error * will be thrown. */ native bind_pcvar_float(pcvar, &Float:var); |
bind_pcvar_string
|
⇅ To bind a string/** * Binds a cvar's string value to a global array. The array will then * always contain the current cvar value as it is automatically kept up to date. * * @note The array *has* to be a global or a static array. Local arrays * created within functions can not be used for technical reasons. * @note Arrays can not be bound to multiple cvars. * * @param pcvar Pointer to cvar * @param var Global array to keep updated * @param varlen Maximum length of string array * * @noreturn * @error If an invalid cvar pointer or variable is provided, an error * will be thrown. */ native bind_pcvar_string(pcvar, any:var[], varlen); |
#include <amxmodx> new CvarTimelimit; new Float:CvarBuyTime; new CvarSomething[32]; public plugin_init() { bind_pcvar_num(get_cvar_pointer("mp_timelimit"), CvarTimelimit); bind_pcvar_float(get_cvar_pointer("mp_buytime"), CvarBuyTime); bind_pcvar_string(register_cvar("amx_something", "something"), CvarSomething, charsmax(CvarSomething)); server_print("mp_timelimit current value: %d", CvarTimelimit); server_print("mp_buytime current value: %f", CvarBuyTime); server_print("amx_something current value: %s", CvarSomething); }
Boundary
Having a better control over a cvar's value, we can enforce the value to be in a defined boundary.
Description | Native |
---|---|
get_pcvar_bounds
|
⇅ To get a boundary/** * Retrieves the specified value boundary of a cvar. * * @param pcvar Pointer to cvar * @param type Type of boundary to retrieve * @param value Variable to store the specified boundary to * * @return True if the cvar has a boundary set, false otherwise * @error If an invalid cvar pointer or boundary type is provided, * an error will be thrown. */ native bool:get_pcvar_bounds(pcvar, CvarBounds:type, &Float:value); |
set_pcvar_bounds
|
⇅ To set a boundary/** * Sets the specified boundary of a cvar. * * @param pcvar Pointer to cvar * @param type Type of boundary to set * @param set If true the cvar boundary will be set, otherwise it will be * removed (value is ignored) * @param value Floating point value to use as the boundary * * @noreturn * @error If an invalid cvar pointer or boundary type is provided, an * error will be thrown. */ native set_pcvar_bounds(pcvar, CvarBounds:type, bool:set, Float:value = 0.0); |
CvarBounds
has the following values:
CvarBound_Upper
CvarBound_Lower
#include <amxmodx> public plugin_init() { new const pointer = register_cvar("amx_leet", "1337"); // Defines min and max value set_pcvar_bounds(pointer, CvarBound_Lower, .set = true, 0.0); set_pcvar_bounds(pointer, CvarBound_Upper, .set = true, 42.0); // Current value should be "42". server_print("amx_something current value: %f", get_pcvar_float(pointer)); // Removes the lower bound. set_pcvar_bounds(pointer, CvarBound_Lower, .set = false); new Float:value; if (get_pcvar_bounds(pointer, CvarBound_Upper, value)) { server_print("amx_something should have an upper bound: %f", value); } if (!get_pcvar_bounds(pointer, CvarBound_Upper, value)) { server_print("amx_something should not have an lower bound); } }
Constant
A missing FCVAR_NOEXTRAWHITEPACE
flag has been added.
It automatically strips trailing/leading white space from the string value.
Creating
A new create_cvar
⇅ native has been added, similar to register_cvar
but with two new features:
/** * Creates a new cvar for the engine. * * @note This has the same effect as register_cvar() but provides more options. * @note For a list of possible cvar flags see FCVAR_* constants above. * @note If an already existing cvar is registered it will not be duplicated. * The default value is only set when the cvar is registered for the very * first time since the server was started. Cvar bounds are overwritten * by the create_cvar() call just as if they were re-set using * set_pcvar_bounds(). * @note The returned cvar pointer should be used with the get_pcvar_* and * set_pcvar_* set of functions. * * @param name Cvar name * @param string Default cvar value * @param flags Optional bitsum of flags specifying cvar behavior * @param description Optional description of the cvar * @param has_min Optional boolean that specifies if the cvar has a * minimum value * @param min_val Minimum floating point value * @param has_max Optional boolean that specifies if the cvar has a * maximum value * @param max_val Maximum floating point value * * @return Unique cvar pointer * @error If invalid bounds are provided (min_val > max_val or * vice versa), an error will be thrown. */ native create_cvar(const name[], const string[], flags = FCVAR_NONE, const description[] = "", bool:has_min = false, Float:min_val = 0.0, bool:has_max = false, Float:max_val = 0.0);
Description | Similar to command, you can explain shorlty what does the cvar. The message can be retrieved with get_plugins_cvar and can be read from amxx cvars detailed output. The description is used with AutoExecConfig for example.
|
Boudary | You can set directly a boudary, either a minimum value, a maximum value or both. |
#include <amxmodx> public plugin_init() { create_cvar("amx_something1", "1", FCVAR_NONE, "My description here", true, 1.0, true, 42.0); create_cvar("amx_something2", "2", .description = "My description here", .has_min = true, min_val = 1.0, .has_max = true, .max_val = 42.0); create_cvar("amx_something3", "3", .has_min = true, min_val = 1.0); create_cvar("amx_something4", "4", .has_max = true, max_val = 42.0); }
Command
The amxx cvars
shows now more informations about a cvar state.
Here an example of output:
Managed cvars: NAME VALUE PLUGIN HOOKED MIN MAX - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ 1] amx_mode 1 admin.amxx no - - [ 2] amx_password_field _pw admin.amxx no - - [ 3] amx_default_access z admin.amxx no - - [ 4] amx_vote_ratio 0.02 admin.amxx no - - [ 5] amx_something something test-hook.amxx yes - - [ 6] amx_leet 42 test-bounds.amxx no 0.00 42.00 ...
It can show further details if you specify a cvar or index from the table: amxx cvars <index or cvar name>
amxx cvars 6 Cvar details : Cvar name : amx_leet Value : 42 Def. value : 1337 Description : Flags : FCVAR_EXTDLL STATUS PLUGIN INFOS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Registered test-bounds.amxx - Min value test-bounds.amxx 0.000000 Max value test-bounds.amxx 42.000000
Others
Native | Description |
---|---|
get_pcvar_bool
|
⇅ Returns an boolean value from a cvar via direct pointer access./** * Returns an boolean value from a cvar via direct pointer access. * * @param pcvar Pointer to cvar to retrieve value from * * @return Cvar value, converted to bool * @error If an invalid cvar pointer is provided, an error will be * thrown. */ native bool:get_pcvar_bool(pcvar); |
set_pcvar_bool
|
⇅ Sets a boolean value to a cvar via direct pointer access./** * Sets a boolean value to a cvar via direct pointer access. * * @param pcvar Pointer to cvar to set value of * @param num Value to set cvar to * * @noreturn * @error If an invalid cvar pointer is provided, an error will be * thrown. */ native set_pcvar_bool(pcvar, bool:num); |
CellArray
A bunch of natives have been added to complete the existing API. You are now able to:
- Clone an array
- Resize an array
- Find a value or string inside an array
- Control more precisely how the data is retrieved/saved
A good example is the Stack Structure API which is actually based on Array (internal library, that's it).
reserved
parameter in ArrayCreate
was intended to create blank entries that would immediately be usable with ArrayGet/Set
functions. This functionality was never working as intended, and can now be achieved using
ArrayResize
.
Cloning
Native | Description |
---|---|
ArrayClone
|
⇅ Clones an array./** * Clones an array, returning a new handle with the same size and data. * * @param which Array handle * * @return Handle to the cloned array on success, 0 otherwise * @error If an invalid handle is provided an error will be * thrown. */ native Array:ArrayClone(Array:which); |
#include <amxmodx> public plugin_init() { new Array:list = ArrayCreate(); ArrayPushCell(list, 1); ArrayPushCell(list, 2); ArrayPushCell(list, 3); new Array:clone_list = ArrayClone(list); // ArrayDestroy(clone_list); ArrayDestroy(list); }
Resizing
Native | Description |
---|---|
ArrayResize
|
⇅ Resizes an array./** * Resizes an array. * * @note If the size is smaller than the current array size the array is * truncated and data lost. * * @param which Array handle * @param newsize New size * * @noreturn * @error If an invalid handle is provided or the resizing * operation runs out of memory, an error will be thrown. */ native bool:ArrayResize(Array:which, newsize); |
#include <amxmodx> public plugin_init() { new Array:list = ArrayCreate(.cellsize = 1, .reserved = 3); ArrayPushCell(list, 1); ArrayPushCell(list, 2); ArrayPushCell(list, 3); new const count = ArraySize(list); ArrayResize( list, count + 1); // Add a new allocated and available slot ArraySetCell(list, count, 4); // Notice you can use directly ArraySet server_print("Last value = %d, Cloned list size = %d", ArrayGetCell(list, count), ArraySize(list)); // Should be 4. ArrayDestroy(list); }
Finding a value
Native | Description |
---|---|
ArrayFindValue
|
⇅ Searches through the array and returns the index of the first occurence of the specified value./** * Searches through the array and returns the index of the first occurence of * the specified value. * * @param which Array handle * @param item Value to search for * * @return Array index on success, -1 if the value can't be found * @error If an invalid handle is provided an error will be * thrown. */ native ArrayFindValue(Array:which, any:item); |
ArrayFindString
|
⇅ Searches through the array and returns the index of the first occurence of the specified string./** * Searches through the array and returns the index of the first occurence of * the specified string. * * @param which Array handle * @param item String to search for * * @return Array index on success, -1 if the string can't be found * @error Invalid handle. */ native ArrayFindString(Array:which, const item[]); |
#include <amxmodx> public plugin_init() { new Array:list = ArrayCreate(.cellsize = 16); ArrayPushString(list, "something"); ArrayPushString(list, "is"); ArrayPushCell(list, 42); ArrayPushString(list, "hidden"); new index = ArrayFindValue(list, 42); server_print("Cell index = %d", index); // should be 2 index = ArrayFindString(list, "hidden"); server_print("String index = %d", index); // should be 3 ArrayDestroy(list); }
Sorting
Along two new ArraySort
and SortADTArray
natives, there is also a new Sort_Random
method.
Native | Description |
---|---|
ArraySortEx
|
⇅ A faster version of ArraySort ./** * A faster version of ArraySort, the sorting algorithm then uses the custom * comparison function to sort the data. * * @note The advantage of this function is that the data of the elements being * compared is directly passed to the function, instead of the item * indexes that are passed by ArraySort. This removes the need for calling * ArrayGet[Cell|String|Array] every time before being able to compare the * elements. * * @note For Arrays with a cellsize of 1 (used for storing integers and floats), * the function is called in the following manner: * * public MySortFunc(Array:array, elem1, elem2, const data[], data_size) * * array - Array handle in its current un-sorted state * elem1, elem2 - Current element pair being compared * data[] - Extra data array passed to the sort func * data_size - Size of extra data * * @note For Arrays with a cellsize larger than 1 (used for storing arrays and * strings), the function is called in the following manner: * * public MySortFunc(Array:array, elem1[], elem2[], const data[], data_size) * * array - Array handle in its current un-sorted state * elem1[], elem2[] - Current element pair being compared * data[] - Extra data array passed to the sort func * data_size - Size of extra data * * * @note The comparison function should return: * -1 if elem1 should go before elem2 * 0 if elem1 and elem2 are equal * 1 if elem1 should go after elem2 * * @note All parameters after item2 are optional and do not need to be specified * and used. * @note Unlike the sorting.inc version, the array passed to the callback is not * in mid-sorted state. * * @param array Array handle * @param comparefunc Callback function used for comparison * @param data Extra data that is passed through to the callback * @param data_size Size of extra data * * @noreturn * @error If an invalid handle or an invalid callback is provided * an error will be thrown. */ native ArraySortEx(Array:array, const comparefunc[], data[]="", data_size=0); |
SortADTArray
|
⇅ To sort directly with a sort method./** * Sort an ADT Array. Specify the type as Integer, Float, or String. * * @param array Array Handle to sort * @param order Sort order to use, same as other sorts. * @param type Data type stored in the ADT Array * @noreturn */ native SortADTArray(Array:array, SortMethod:order, SortType:type); Note: SortMethod has the following values:
|
New params
Native | parameter | Description |
---|---|---|
ArrayGetArray ArraySetArray ArrayPushArray
|
size
|
⇅ Controls the number of elements to use./** * @param size If not set, assumes the buffer size is equal to the * cellsize. Otherwise, the specified size is used. */ native ArrayGetArray(Array:which, item, any:output[], size = -1); native ArraySetArray(Array:which, item, const any:input[], size =-1); native ArrayPushArray(Array:which, const any:input[], size = -1); |
ArrayGetCell ArraySetCell
|
achar block
|
⇅ Specifies which block and retrieves a value as byte./** * @param block If the array has a cellsize >1 this optionally specifies * which block to read from * @param asChar If true reads the value as a byte instead of a cell */ native any:ArrayGetCell(Array:which, item, block = 0, bool:asChar = false); |
CellTrie
The word "Trie" in this API is historical. As of AMX Mod X 1.9, tries have been internally replaced with hash tables, which have O(1)
insertion time instead of O(n)
.
As consequence, the API has been completed and you can now:
- Get a trie size
- Control more precisely the data on insertion/retrieval
- Iterate over a trie
Getting size
Native | Description |
---|---|
TrieGetSize
|
⇅ Returns the number of entries in a hash map./** * Returns the number of entries in a hash map. * * @param handle Map handle * * @return Number of elements in the hash map * @error If an invalid handle is provided an error will be * thrown. */ native TrieGetSize(Trie:handle); |
Iterating
There are two ways to iterate over a trie:
- Snapshots
- As the name suggested, it will duplicate the whole set of keys (only) into a separate list. Any changes to the original list will not affect the snapshot.
It's an expensive operation, but can be stored.
Native Description TrieSnapshotCreate
⇅ Creates a snapshot of all keys in a hash map. /** * Creates a snapshot of all keys in a hash map. If the map is changed * afterwards, the changes are not reflected in the snapshot. * Keys are not sorted. * * @param handle Map handle * * @return New map snapshot handle, which must be freed via * TrieSnapshotDestroy() * @error If an invalid handle is provided an error will be * thrown. */ native Snapshot:TrieSnapshotCreate(Trie:handle);
TrieSnapshotLength
⇅ Returns the number of keys in a map snapshot. /** * Returns the number of keys in a map snapshot. Note that this may be * different from the size of the map, since the map can change after the * snapshot of its keys was taken. * * @param handle Map snapshot handle * * @return Number of keys * @error If an invalid handle is provided an error will be * thrown. */ native TrieSnapshotLength(Snapshot:handle);
TrieSnapshotGetKey
⇅ Retrieves the key string of a given key in a map snapshot. /** * Retrieves the key string of a given key in a map snapshot. * * @param handle Map snapshot handle * @param index Key index (starting from 0) * @param buffer String buffer * @param maxlength Maximum buffer length * * @return Number of bytes written to the buffer * @error If an invalid handle is provided an error will be * thrown. or index out of range */ native TrieSnapshotGetKey(Snapshot:handle, index, buffer[], maxlength);
TrieSnapshotDestroy
⇅ Retrieves the key string of a given key in a map snapshot. /** * Destroys a map snapshot and frees its memory. * * @note The function automatically sets the variable passed to it to 0 to aid * in preventing accidental usage after destroy. * * @param handle Map snapshot handle * * @return 1 on success, 0 if an invalid handle was passed in */ native TrieSnapshotDestroy(&Snapshot:handle);
- Note:The keys are not sorted.
- Example:⇅
#include <amxmodx> public plugin_init() { new Trie:list = TrieCreate(); { TrieSetString(list, "adventure", "time!"); TrieSetString(list, "butterflies", "bees"); TrieSetString(list, "egg", "egg"); } new Snapshot:keys = TrieSnapshotCreate(list); { new const length = TrieSnapshotLength(keys); new key[32]; for (new const i = 0; i < length; ++i) { TrieSnapshotGetKey(keys, i, buffer, charmax(buffer)); server_print("buffer = %s", buffer); } } TrieSnapshotDestroy(keys); }
- Iterator
- A contrario, Iterators are designed to be short-lived and not stored, and creating them is very cheap.
Reading data from an iterator is just as fast as reading directly from the map.
This is useful if you just need to iterate (or eventually updating values of existing keys, which is allowed)
Native Description TrieIterCreate
⇅ Creates an iterator for a map. /** * Creates an iterator for a map. It provides iterative read-only access to the * maps contents. * * @note Removing or adding keys to the underlying map will invalidate all its * iterators. Updating values of existing keys is allowed and the changes * will be immediately reflected in the iterator. * @note Iterators are designed to be short-lived and not stored, and creating * them is very cheap. Reading data from an iterator is just as fast as * reading directly from the map. * @note Just like in snapshots the keys are not sorted. * * @return New iterator handle, which must be freed via TrieIterDestroy(). * @error Invalid Handle */ native TrieIter:TrieIterCreate(Trie:handle);
TrieIterEnded
⇅ Returns if the iterator has reached its end and no more data can be read. /** * Returns if the iterator has reached its end and no more data can be read. * * @param handle Iterator handle * * @return True if iterator has reached the end, false otherwise * @error Invalid Handle * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native bool:TrieIterEnded(TrieIter:handle);
TrieIterNext
⇅ Advances the iterator to the next key/value pair if one is available. /** * Advances the iterator to the next key/value pair if one is available. * * @param handle Iterator handle * * @error Invalid Handle * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native TrieIterNext(TrieIter:handle);
TrieIterGetKey
⇅ Retrieves the key the iterator currently points to. /** * Retrieves the key the iterator currently points to. * * @param handle Iterator handle. * @param key Buffer to store the current key in. * @param outputsize Maximum size of string buffer. * * @return Nnumber of bytes written to the buffer * @error Invalid handle * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native TrieIterGetKey(TrieIter:handle, key[], outputsize);
TrieIterGetSize
⇅ Retrieves the number of elements in the underlying map. /** * Retrieves the number of elements in the underlying map. * * @note When used on a valid iterator this is exactly the same as calling TrieGetSize on the map directly. * * @param handle Iterator handle * * @return Number of elements in the map * @error Invalid handle * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native TrieIterGetSize(TrieIter:handle);
TrieIterGetCell
⇅ Retrieves a value at the current position of the iterator. /** * Retrieves a value at the current position of the iterator. * * @param handle Iterator handle * @param value Variable to store value in * * @return True on success, false if the iterator is empty or the current * value is an array or a string. * @error Invalid handle * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native bool:TrieIterGetCell(TrieIter:handle, &any:value);
TrieIterGetString
⇅ Retrieves a string at the current position of the iterator. /** * Retrieves a string at the current position of the iterator. * * @param handle Iterator handle * @param buffer Buffer to store the string in * @param outputsize Maximum size of string buffer * @param size Optional parameter to store the number of bytes written to the buffer. * * @return True on success, false if the iterator is empty or the current value * is not a string. * @error Invalid handle * Invalid buffer size * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native bool:TrieIterGetString(TrieIter:handle, buffer[], outputsize, &size = 0);
TrieIterGetArray
⇅ Retrieves an array at the current position of the iterator. /** * Retrieves an array at the current position of the iterator. * * @param handle Iterator handle * @param buffer Buffer to store the array * @param outputsize Maximum size of buffer * @param size Optional parameter to store the number of bytes written to the buffer * * @return True on success, false if the iterator is empty or the current * value is not an array. * @error Invalid handle * Invalid buffer size * Iterator has been closed (underlying map destroyed) * Iterator is outdated */ native bool:TrieIterGetArray(TrieIter:handle, any:array[], outputsize, &size = 0);
TrieIterDestroy
⇅ Destroys an iterator handle. /** * Destroys an iterator handle. * * @param handle Iterator handle. * * @return True on success, false if the value was never set. */ native TrieIterDestroy(&TrieIter:handle);
- Note:The keys are not sorted.
- Example:⇅
#include <amxmodx> public plugin_init() { new Trie:list = TrieCreate(); { TrieSetString(list, "adventure", "time!"); TrieSetString(list, "butterflies", "bees"); TrieSetString(list, "hello", "world!"); } new TrieIter:iter = TrieIterCreate(list); { new key[32], key_length; new value[32], value_length; while (!TrieIterEnded(iter)) { key_length = TrieIterGetKey(iter, key, charsmax(key)); TrieIterGetString(iter, value, charsmax(value), value_length); server_print("%s (%d) -> %s (%d)", key, key_length, value, value_length); // Should throw an error // TrieSetString(t, "monkey", "island"); // TrieDeleteKey(t, "full"); // TrieClear(t); TrieIterNext(iter); } } TrieIterDestroy(iter); TrieDestroy(list); }
New params
Native | parameter | Description |
---|---|---|
TrieSetString TrieSetArray
|
replace
|
⇅ Makes operation fail if key already set./** * @param replace If false the operation will fail if the key is already set */ native TrieSetCell(Trie:handle, const key[], any:value, bool:replace = true); native TrieSetString(Trie:handle, const key[], const value[], bool:replace = true); native TrieSetArray(Trie:handle, const key[], const any:buffer[], size, bool:replace = true); |
TrieGetString TrieGetArray
|
size
|
⇅ Returns the number of bytes written in the buffer./** * @param size Optional variable to store the number of cells written * to the array in */ native bool:TrieGetString(Trie:handle, const key[], output[], outputsize, &size = 0); native bool:TrieGetArray(Trie:handle, const key[], any:output[], outputsize, &size = 0); |
Event
New natives
Native | Description |
---|---|
register_event_ex
|
⇅ Registers a function to be called on a given game event. A wrapper of register_event using flags as strings./** * Registers a function to be called on a given game event. * * @note Examples for event conditions: * "2=c4" - Second parameter of message must be the string "c4" * "3>10" - Third parameter of message must be greater than 10 * "3!4" - Third parameter of message must not be equal to 4 * "2&Buy" - Second parameter of message must contain "Buy" substring * "2!Buy" - Second parameter of message must not equal "Buy" * @note Due to a long-standing bug that would break compatibility with older * plugins, the client id should be checked for alive/dead state if using * flags "d" or "e". * @note If multiple conditions are specified for a single parameter, only one * of them has to hold true for the event function to be called. * * @param event Name of event that should be hooked * @param function Name of callback function * @param flags Flags used for filtering events (enum RegisterEventFlags); the valid flags are: * RegisterEvent_Global - Global event (sent to every client) * RegisterEvent_Single - Event sent to single client * RegisterEvent_OnceForMultiple - Call only once when repeated to multiple clients * RegisterEvent_OnlyDead - Call only if sent to dead client * RegisterEvent_OnlyAlive - Call only if sent to alive client * RegisterEvent_OnlyHuman - Call only if sent to human client (RegisterEvent_Single required) * RegisterEvent_OnlyBots - Call only if sent to bot (RegisterEvent_Single required) * @param cond Condition string used for filtering events, built as: * "<argument number><comparison operator><value>" * Argument number is the argument position to be filtered * The comparison operator may be: * "=" for equality comparison (all argument types) * "!" for inequality comparison (all argument types) * "&" for bitwise and (int argument) or substring * comparison (string argument) * "<" for less than comparison (int/float arguments) * ">" for greater than comparison (int/float arguments) * The argument is compared to the specified value accordingly * @param ... Any number of additional conditions * * @return Event handle * @error If an invalid event name or callback function is provided, * an error will be thrown. */ native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...); |
enable_event disable_event
|
⇅ Enables a function hook of a game event which has been previously registered with register_event or register_event_ex ./** * Enables a function hook of a game event which has been previously registered with register_event and register_event_ex(). * * @param handle Value returned from register_event() or register_event_ex() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native enable_event(handle); register_event or register_event_ex ./** * Disables a function hook of a game event which has been previously registered with register_event and register_event_ex(). * * @param handle Value returned from register_event() or register_event_ex() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native disable_event(handle); |
enable_logevent disable_logevent
|
⇅ Enables a function hook of a game log event which has been previously registered with register_logevent ./** * Enables a function hook of a game log event which has been previously registered with register_logevent(). * * @param handle Value returned from register_logevent() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native enable_logevent(handle); register_logevent ./** * Disables a function hook of a game log event which has been previously registered with register_logevent(). * * @param handle Value returned from register_logevent() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. */ native disable_logevent(handle); |
New flags
Native | flags | Description |
---|---|---|
register_event
|
"f" "g"
|
⇅ Call only if sent to human client ("b" flag required) Call only if sent to bot ("b" flag required). /** * Registers a function to be called on a given game event. * * @note Please consider using register_event_ex() instead which allows you to * use named constants for flags instead of letters. * @note Examples for event conditions: * "2=c4" - Second parameter of message must be the string "c4" * "3>10" - Third parameter of message must be greater than 10 * "3!4" - Third parameter of message must not be equal to 4 * "2&Buy" - Second parameter of message must contain "Buy" substring * "2!Buy" - Second parameter of message must not equal "Buy" * @note Due to a long-standing bug that would break compatibility with older * plugins, the client id should be checked for alive/dead state if using * flags "d" or "e". * @note If multiple conditions are specified for a single parameter, only one * of them has to hold true for the event function to be called. * * @param event Name of event that should be hooked * @param function Name of callback function * @param flags Flags used for filtering events, the valid flags are: * "a" - Global event (sent to every client) * "b" - Event sent to single client * "c" - Call only once when repeated to multiple clients * "d" - Call only if sent to dead client * "e" - Call only if sent to alive client * "f" - Call only if sent to human client ("b" flag required) * "g" - Call only if sent to bot ("b" flag required) * @param cond Condition string used for filtering events, built as: * "<argument number><comparison operator><value>" * Argument number is the argument position to be filtered * The comparison operator may be: * - "=" for equality comparison (all argument types) * - "!" for inequality comparison (all argument types) * - "&" for bitwise and (int argument) or substring * comparison (string argument) * - "<" for less than comparison (int/float arguments) * - ">" for greater than comparison (int/float arguments) * The argument is compared to the specified value accordingly * @param ... Any number of additional conditions * * @return Event handle * @error If an invalid event name or callback function is provided, * an error will be thrown. */ native register_event(const event[], const function[], const flags[], const cond[] = "", ...); |
File
Valve FileSystems
Thanks to the IFileSystem interface from HLSDK, we are now able to make more operations possible with files via Valve File System through Valve search paths (example: download directory).
This is handy when you want to deal with files which are not necessary existing directly in the game directory.
Not all natives are concerned. This features some new natives and enhanced others existing ones with small quality of life changes.
Valve Paths
Path ID | Description |
---|---|
GAME
|
All paths related to current mod, including fallback. Depending settings, it includes: <gamedir>_lv /_addon /_language /_hd and <gamedir> itself.
|
GAMECONFIG
|
The default writable directory: <gamedir> .
|
GAMEDOWNLOAD
|
The download directory: <gamedir>_download .
|
GAME_FALLBACK
|
All paths related to fallback game, same as GAME (example: czero has cstrike as fallback. Others mods have usually the default game valve , including cstrike ).
|
DEFAULTGAME
|
All paths related to the default game which is valve, same as GAME .
|
BASE
|
The base path where server is installed. |
Native Support
Some natives supports partially Valve FS, where a path ID can't be provided and this will search in all paths instead.
Native | parameter | Description |
---|---|---|
delete_file unlink file_exists partiallydir_exists partiallyfile_size fopen mkdir open_dir
|
use_valve_fs valve_path_id
|
⇅ Uses the Valve file system via a search path from gameinfo./**
* @note Registered paths ID are (in priority order) :
* GAME All paths related to current mod, including fallback
* Depending settings, it includes: <gamedir>_lv/_addon/_<language>/_hd
* and <gamedir> itself
* GAMECONFIG The default writable directory (<gamedir>)
* GAMEDOWNLOAD The download directory (<gamedir>_download)
* GAME_FALLBACK All paths related to fallback game, same as GAME
* DEFAULTGAME All paths related to the default game which is "valve", same as GAME
* BASE The base path where server is installed
*
* Note that some paths are non-writable. It includes all <gamedir>_* (expect _download)
* and DEFAULTGAME. Any file inside a non-writable path will be ignored if you try to open
* it in writing mode.
*
* @param use_valve_fs If true, the Valve file system will be used instead
* This can be used to finred files existing in valve
* search paths, rather than solely files existing directly
* in the gamedir.
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths
*/ |
Some natives are not adjusted because not exposed by Valve FS:
rename_file
rmdir
New Natives
Native | Description |
---|---|
FileReadInt8 FileReadUint8 FileReadInt16 FileReadUint16 FileReadInt32
|
⇅ Reads a single value from a file. More sane and better designed natives to read a single value (proper type, unsigned byte/short support and returns 1 or 0). /** * Reads a single int8 (byte) from a file. The returned value is sign- * extended to an int32. * * @param file Handle to the file * @param data Variable to store the data read * * @return True on success, false on failure */ native bool:FileReadInt8(file, &any:data); /** * Reads a single uint8 (unsigned byte) from a file. The returned value is * zero-extended to an int32. * * @param file Handle to the file * @param data Variable to store the data read * * @return True on success, false on failure */ native bool:FileReadUint8(file, &any:data); /** * Reads a single int16 (short) from a file. The value is sign-extended to * an int32. * * @param file Handle to the file * @param data Variable to store the data read * * @return True on success, false on failure */ native bool:FileReadInt16(file, &any:data); /** * Reads a single unt16 (unsigned short) from a file. The value is zero- * extended to an int32. * * @param file Handle to the file * @param data Variable to store the data read * * @return True on success, false on failure */ native bool:FileReadUint16(file, &any:data); /** * Reads a single int32 (int/cell) from a file. * * @param file Handle to the file * @param data Variable to store the data read * * @return True on success, false on failure */ native bool:FileReadInt32(file, &any:data); |
FileWriteInt8 FileWriteInt16 FileWriteInt32
|
⇅ Writes a single value from a file. More sane and better designed natives to write a single value (proper type, unsigned byte/short support and returns 1 or 0). /** * Writes a single int8 (byte) to a file. * * @param file Handle to the file * @param data Data to write (truncated to an int8) * * @return True on success, false on failure */ native bool:FileWriteInt8(file, any:data); /** * Writes a single int16 (short) to a file. * * @param file Handle to the file * @param data Data to write (truncated to an int16) * * @return True on success, false on failure */ native bool:FileWriteInt16(file, any:data); /** * Writes a single int32 (int/cell) to a file. * * @param file Handle to the file * @param data Data to write * * @return True on success, false on failure */ native bool:FileWriteInt32(file, any:data); |
GetFileTime
|
⇅ Returns a file timestamp as a unix timestamp./** * File time modes for use with GetFileTime(). */ enum FileTimeType { FileTime_LastAccess, /* Last access (not available on FAT) */ FileTime_Created, /* Creation (not available on FAT) */ FileTime_LastChange, /* Last modification */ }; /** * Returns a file timestamp as a unix timestamp. * * @param file File name * @param tmode Time mode, see FileTime_* constants * * @return Returns a file timestamp as a unix timestamp */ native GetFileTime(const file[], FileTimeType:tmode); |
SetFilePermissions
|
⇅ Changes a file or directories permissions./** * Changes a file or directories permissions. * * @param path Path to the file * @param mode Permissions to set, see FPERM_* constants * * @return True on success, false otherwise */ native bool:SetFilePermissions(const path[], mode); |
New params
Native | parameter | Description |
---|---|---|
fputs
|
null_term
|
⇅ True to append NULL terminator, false otherwise./** * Writes a line of text to a text file. * * @param file Handle to the file * @param text String to write * @param null_term True to append NULL terminator, false otherwise * * @return 0 on success, -1 otherwise */ native fputs(file, const text[], bool:null_term = false); |
mkdir
|
mode
|
⇅ Permissions (default is o=rx,g=rx,u=rwx). Note that folders must have the execute bit set on Linux. On Windows, the mode is ignored. /** * Creates a directory. * * @param path Path to create * @param mode Permissions (default is o=rx,g=rx,u=rwx). Note that folders must have * the execute bit set on Linux. On Windows, the mode is ignored. * @param use_valve_fs If true, the Valve file system will be used instead * This can be used to create folders in the game's * Valve search paths, rather than directly in the gamedir. * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for default * In this case, mode is ignored * * @return 0 on success, -1 otherwise */ native mkdir(const dirname[], mode = FPERM_DIR_DEFAULT, bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG"); |
open_dir next_file
|
type
|
⇅ Optional variable to store the file type./** * Opens a directory/folder for contents enumeration. * * @note Directories are closed with close_dir(). * * @param dir Path to open. * @param firstfile String buffer to hold first file name * @param length Maximum size of the string buffer * @param type Optional variable to store the file type * @param use_valve_fs If true, the Valve file system will be used instead. * This can be used to find files existing in any of * the Valve search paths, rather than solely files * existing directly in the gamedir. * @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths. * * @return Handle to the directory, 0 otherwise */ native open_dir(dir[], firstfile[], length, &FileType:type = FileType_Unknown, bool:use_valve_fs = false, const valve_path_id[] = "GAME"); /** * Reads the next directory entry as a local filename. * * @note Contents of buffers are undefined when returning false. * @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux. * * @param dirh Handle to a directory * @param buffer String buffer to hold directory name * @param length Maximum size of string buffer * @param type Optional variable to store the file type. FileType_* constants * * @return 1 on success, 0 if there are no more files to read. */ native next_file(dirh, buffer[], length, &FileType:type = FileType_Unknown); |
Others
There are as well some minor additions or changes:
- Added a new define
PLATFORM_MAX_PATH
⇅ to represent a maximum path length.
/** * Maximum path length. */ #define PLATFORM_MAX_PATH 256
- Added
any:
tag to some natives. read_dir
:outlen
parameter is now optional.read_file
:txtlen
parameter is now optional. Adjusted as well buffer to 2048 to match buffer size inwrite_file
.file_size
: Fixed potential issue with old compiled plugin which doesn't have the flag parameter. AddedFSOPT_*
⇅ constants as well for use with this flag parameter.
/** * Options for use with file_size() flag parameter. */ #define FSOPT_BYTES_COUNT 0 /* Returns the file size in number of bytes */ #define FSOPT_LINES_COUNT 1 /* Returns how many lines there are in this file */ #define FSOPT_END_WITH_LF 2 /* Returns whether the last line is '\n' */
General
Constant
- Added
DMG_GRENADE
constant (Counter-Strike only) - Added missing
SVC_
messages (PR 223)SVC_RESOURCELOCATION
SVC_SENDCVARVALUE
SVC_SENDCVARVALUE2
Forward
- Added
FP_VAL_BYREF
to pass values by reference in forwards. ExecuteForward
can now be called without the need to create variable for returned value.
Others
Native | Description |
---|---|
has_map_ent_class
|
⇅ Returns if a map contains at least one entity with the provided class name./** * Returns if a map contains at least one entity with the provided class name. * * @param classname Entity classname to match * * @return True if an entity is found, false otherwise */ native bool:has_map_ent_class(const classname[]); |
engine_changelevel
|
⇅ Changes the map.
Note:This has the same behavior as using the "changelevel" server command, but will also trigger the server_changelevel forward in AMXX plugins.It will also notify any Metamod plugins that are hooking the pfnChangeLevel function./** * Changes the map. * * @note This calls the pfnChangelLevel engine function. * @note This has the same behavior as using the "changelevel" server command, * but will also trigger the server_changelevel() forward in AMXX * plugins. It will also notify any Metamod plugins that are hooking * the pfnChangeLevel function. * * @param map Map name to change to * * @noreturn */ native engine_changelevel(const map[]); |
RequestFrame
|
⇅ Creates a single use hook for the next frame./** * Creates a single use hook for the next frame. * * @param callback Function to be executed on the next frame. * @param data Optional data to be passed to the callback function. * * @note Callback function prototype: * public function(data) * * @noreturn */ native RequestFrame(const callback[], any:data = 0); |
Stock | Description |
---|---|
set_task_ex
|
⇅ Calls a function after a specified time has elapsed.
Note:Similar to set_task but it allows you to use named constants for flags instead of letters./** * SetTaskFlags constants for set_task_ex() */ enum SetTaskFlags (<<= 1) { SetTask_Once = 0, // None; execute callback after the specified amount of time (Default) SetTask_RepeatTimes = 1, // Repeat timer a set amount of times SetTask_Repeat, // Loop indefinitely until timer is stopped SetTask_AfterMapStart, // Time interval is treated as absolute time after map start SetTask_BeforeMapChange // Time interval is treated as absolute time before map change }; /** * Calls a function after a specified time has elapsed. * * @param time Time interval to assign * @param function Function to execute * @param id Task id to assign * @param parameter Data to pass through to callback * @param len Size of data * @param flags Optional flags (enum SetTaskFlags); valid flags are: * SetTask_Once - Execute callback once (Default) * SetTask_RepeatTimes - repeat timer a set amount of times * SetTask_Repeat - loop indefinitely until timer is stopped * SetTask_AfterMapStart - time interval is treated as absolute * time after map start * SetTask_BeforeMapChange - time interval is treated as absolute * time before map change * @param repeat If the SetTask_RepeatTimes flag is set, the task will be repeated this * many times * * @noreturn * @error If an invalid callback function is provided, an error is * thrown. */ stock set_task_ex(Float:time, const function[], id = 0, const any:parameter[] = "", len = 0, SetTaskFlags:flags = SetTask_Once, repeat = 0) { new strFlags[2]; // There should never be a need to set more than 1 flag get_flags(_:flags, strFlags, charsmax(strFlags)); set_task(time, function, id, parameter, len, strFlags, repeat); } |
XS
Stock | Description |
---|---|
xs_vec_len_2d
|
⇅ Computes the length of a 2D vector./** * Computes the length of a 2D vector. * * @param vec The vector to compute the length of. * * @return The length of the input vector. */ stock Float:xs_vec_len_2d(const Float:vec[]) { return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1]); } |
xs_vec_distance
|
⇅ Computes the distance between two vectors (points)./** * Computes the distance between two vectors (points). * * @param vec1 First vector. * @param vec2 Second vector. * * @return The distance between two vectors. */ stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[]) { return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) + (vec1[2]-vec2[2]) * (vec1[2]-vec2[2])); } |
xs_vec_distance_2d
|
⇅ Computes the distance between two 2D vectors (points)./** * Computes the distance between two 2D vectors (points). * * @param vec1 First vector. * @param vec2 Second vector. * * @return The distance between two vectors. */ stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[]) { return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1])); } |
xs_vec_add_scaled
|
⇅ Adds the second vector scaled by a scalar to the first./** * Adds the second vector scaled by a scalar to the first. * * @param in1 Vector to add to. * @param in2 Vector to scale and add. * @param scalar Scalar to scale the second vector with. * @param out The output vector. Can be one of the input vectors. * * @noreturn */ stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) { out[0] = in1[0] + in2[0] * scalar; out[1] = in1[1] + in2[1] * scalar; out[2] = in1[2] + in2[2] * scalar; } |
xs_vec_sub_scaled
|
⇅ Subtracts the second vector scaled by a scalar from the first one./** * Subtracts the second vector scaled by a scalar from the first one. * * @param in1 Vector to subtract from. * @param in2 Vector to scale and subtract. * @param scalar Scalar to scale the second vector with. * @param out The output vector. Can be one of the input vectors. * * @noreturn */ stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) { out[0] = in1[0] - in2[0] * scalar; out[1] = in1[1] - in2[1] * scalar; out[2] = in1[2] - in2[2] * scalar; } |
Menu
Timeout
Timeout is now added to newmenus, working similar to those of show_menu
.
When a menu is acted upon after the specified timeout has run out it will pass a new MENU_TIMEOUT
status code into the menu handler.
Actions are:
- player disconnect
- selecting an item,
- cancelling/destroying the menu in the plugin,
- sending a different menu or using
get_user_menu
on a player with an open menu.
Just like with the old menus timeouts are not actively polled, and MENU_TIMEOUT
is not guaranteed to fire directly after the time has run out.
Also get_user_menu
will detect timeouts and reset the menu flags, which is why it also has to trigger the callback.
Native | parameter | Description |
---|---|---|
menu_display
|
time
|
If >=0 menu will timeout after this many seconds. |
New native & stock
Native | Description |
---|---|
menu_addblank2
|
Note:This fixes an unexpected behavior with the original ones when slot param is set to 1
| Adds a blank line to a menu, always shifting the numbering down.
Stock | Description |
---|---|
reset_menu
|
Resets the client's menu. |
New properties
Property | Description |
---|---|
MEXIT_FORCE
|
Forces a proper exit button on unpaginated menus |
MPROP_SHOWPAGE
|
Whether to show the page number in menu title |
MEXIT_FORCE
|
Function to be called on Back and Next
Prototype of callback: Called when parsing is halted.
@param id Playeer's index
@param status Either MENU_BACK or MENU_MORE
public function(id, status);
Note:An example is available in the
testsuite directory, see menu_page_callback_test.sma. |
Others
menu_item_getinfo
's arguments are now optionalshow_menu]
native is allowed to send empty text
Message
New natives
The float version of message_begin
, write_angle
, write_coord_f
, emessage_begin
, ewrite_coord
and ewrite_angle
:
Native | Description |
---|---|
message_begin_f write_angle_f write_coord_f
|
/** * Marks the beginning of a client message. * * @note You may generate menus, smoke, shockwaves, thunderlights, * intermission and many other messages. * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages * @note You may also refer to the messages_const.inc file for examples. * @note This function is the same as message_begin(), but the origin * argument accepts only float values in this one. * @note Each message starts with a message_begin() or message_begin_f() function * and ends with message_end(). The specific message arguments go in between * these two by using the write_*() functions found in messages.inc. * * @param dest Destination type (see MSG_* constants in messages_const.inc) * @param msg_type Message id * @param origin Message origin * @param player Client index receiving the message or 0 for all clients * * @noreturn * @error If an invalid message id is specified or an invalid number * of parameters is passed, an error will be thrown. */ native message_begin_f(dest, msg_type, const Float:origin[3] = {0.0,0.0,0.0}, player = 0); /** * Writes an angle entry to a message using a float value. * * @note This function should only be used in between a message_begin() * or message_begin_f() and a message_end() function. Trying to use * it outside of these functions will crash the server immediately. * * @param x Angle to write * * @noreturn */ native write_angle_f(Float:x); /** * Writes a coordinate entry to a message using a float value. * * @note This function should only be used in between a message_begin() * or message_begin_f() and a message_end() function. Trying to use * it outside of these functions will crash the server immediately. * * @param x Coordinate to write * * @noreturn */ native write_coord_f(Float:x); | Marks the beginning of a client message.
zmessage_begin_f ewrite_coord_f ewrite_angle_f
|
/**
* Marks the beginning of a client message. * * @note You may generate menus, smoke, shockwaves, thunderlights, * intermission and many other messages. * @note For a list of HL game events, visit https://wiki.alliedmods.net/Half-Life_1_Game_Events * @note For a list of HL engine messages, visit https://wiki.alliedmods.net/Half-Life_1_Engine_Messages * @note You may also refer to the messages_const.inc file for examples. * @note This function is the same as message_begin_f(), except that the messages * sent with this one are also sent to all other AMXX and Metamod plugins. * This means that if you send one of these messages, other plugins will * be notified of that message, which was previously impossible. * @note BE CAREFUL! Using this incorrectly, or not for its intended purpose, * could cause infinite recursion or something just as bad! * @note This function is the same as emessage_begin(), but the origin * argument accepts only float values in this one. * @note Each message starts with a emessage_begin() or emessage_begin_f() function * and ends with emessage_end(). The specific message arguments go in between * these two by using the ewrite_*() functions found in messages.inc. * * @param dest Destination type (see MSG_* constants in messages_const.inc) * @param msg_type Message id * @param origin Message origin * @param player Client index receiving the message or 0 for all clients * * @noreturn * @error If an invalid message id is specified or an invalid number * of parameters is passed, an error will be thrown. */ native emessage_begin_f(dest, msg_type, const Float:origin[3] = {0.0,0.0,0.0}, player = 0); </pawn>/** * Writes a coordinate entry to a message using a float value. * * @note This function should only be used in between a emessage_begin() * or emessage_begin_f() and a emessage_end() function. Trying to use * it outside of these functions will crash the server immediately. * * @param x Coordinate to write * * @noreturn */ native ewrite_coord_f(Float:x); /** * Writes an angle entry to a message using a float value. * * @note This function should only be used in between a emessage_begin() * or emessage_begin_f() and a emessage_end() function. Trying to use * it outside of these functions will crash the server immediately. * * @param x Angle to write * * @noreturn */ native ewrite_angle_f(Float:x); | Marks the beginning of a client message.
Native | Description |
---|---|
client_print_color
|
⇅ Sends colored chat messages to clients.
Note:Counter-strike only. /** * Sends colored chat messages to clients. * * @note This only works in Counter-Strike 1.6 and Condition Zero. * @note The colors can be modified inside of the format string using special * characters. These characters can be included using the escape character * green x04 ; use location color from this point forward * red/blue/grey x03 ; use team color from this point forward * red/blue/grey x02 ; use team color to the end of the client name * ; This only works at the start of the string, * ; and precludes using other control characters * default x01 ; use default color from this point forward * @note The team color is defined by the sender's index. Alternatively, a * specific team color can be enforced using the print_team_* constants in * amxconst.inc * @note Usage examples: * client_print_color(id, print_team_red, "^4Green ^3Red ^1Default") * client_print_color(id, id2, "^4Green ^3id2's team color, ^1Default") * @note Including colors in ML can be done using the same escaping method: * EXAMPLE_ML_KEY = ^4Green ^3Team color ^1Default * @note This functions return value behaves differently depending on what is * used as the client index: If 0 is specified, then the function will * return 0 if nothing has been sent (no client connected). If either a * single client is specified, or there is at least one client connected, * the number of printed characters will refer to the message that is sent * last, to the client with the highest index. * * @param index Client index, use 0 to display to all clients * @param sender Client index used as the message sender * @param fmt Formatting rules * @param ... Variable number of formatting parameters * * @return Number of printed characters * @error If a single client is specified and the index is not within * the range of 1 to MaxClients, an error will be thrown. */ native client_print_color(index, sender, const message[], any:...); |
set_dhudmessage show_dhudmessage
|
/** * Sets display parameters for director hudmessages. * * @note For the hudmessage coordinates x and y, -1.0 will center the message * on the respective axis. * @note These parameters stay until the next call to set_dhudmessage overwrites * them. Multiple calls to show_dhudmessage will therefore re-use the same * parameters. The parameters are not stored per-plugin, so other plugins * can overwrite them. * * @param red Red component of hudmessage color * @param green Green component of hudmessage color * @param blue Blue component of hudmessage color * @param x Location of the message on the x axis in percent * @param y Location of the message on the y axis in percent * @param effects Display effect * @param fxtime Duration of the effect * @param holdtime Time the message stays on screen * @param fadeintime Time it takes the message to fully appear (fade-in) * @param fadeouttime Time it takes the message to fully disappear (fade-out) * * @noreturn */ native set_dhudmessage(red = 200, green = 100, blue = 0, Float:x = -1.0, Float:y = 0.35, effects = 0, Float:fxtime = 6.0, Float:holdtime = 12.0, Float:fadeintime = 0.1, Float:fadeouttime = 0.2); /** * Displays a director message on the client HUD. * * @note Use set_dhudmessage to define how the message should look on screen. * @note Unlike the classic HUD message, which is channel-based, director * messages are stack-based. You can have up to 8 messages displaying at * once. If more are added, they will be overwritten in the order they were * sent. There is no way to clear a specific message. * @note The message has a maximum length of 128 characters which this function * will automatically enforce. * @note This functions return value behaves differently depending on what is * used as the client index: If 0 is specified, then the function will * return 0 if nothing has been sent (no client connected). If either a * single client is specified, or there is at least one client connected, * the number of printed characters will refer to the message that is sent * last, to the client with the highest index. * * @param index Client index, use 0 to display to all clients * @param message Formatting rules * @param ... Variable number of formatting parameters * * @return Number of printed characters * @error If a single client is specified and the index is not within * the range of 1 to MaxClients, an error will be thrown. */ native show_dhudmessage(index, const message[], any:...); | Sets display parameters for director hudmessages.
elog_message
|
/** * Logs a message hookable by plugins to the current server log file. * * @note The log will include a timestamp with the message. * @note The message can be hooked using "register_logevent". * * @param string Formatting rules * @param ... Variable number of formatting parameters * * @return Number of printed characters */ native elog_message(const message[], any:...); | Logs a message hookable by plugins to the current server log file.
Stock | Description |
---|---|
client_printex
|
⇅ Sends a predefined text message to player./** * Sends a predefined text message to player. * Predefined texts are default game messages which will be translated * to player's game language, e.g. #Game_join_ct. * * @note Set index to 0 to send text globally. * * @note There does not necessarily have to be a total of 6 arguments. * It will depend if message takes arguments, e.g.: * client_printex(id, print_chat, "#Game_join_ct", "Pimp Daddy") * client_printex(id, print_chat, "1", "#Game_radio", "Pimp Daddy", "Hello world!") * * @param index Index of the player, use 0 to send to all players. * @param type The message destination. See print_* constants. * @param msg_name The custom or predefined message to send. * @param msg_param1 Optional message argument. * @param msg_param2 Optional message argument. * @param msg_param3 Optional message argument. * @param msg_param4 Optional message argument. * * @noreturn */ stock client_printex(index, type, const msg_name[], const msg_param1[] = "", const msg_param2[] = "", const msg_param3[] = "", const msg_param4[] = "") { new ch = msg_name[0]; // If not a predefined message, we don't care about it and forward directly to client_print. // Special case for radio message. msg_name is an index, msg_param1 #Game_radio*, etc. Checking index should be enough. if (ch != '#' && (type != print_radio || !strtol(msg_name))) { return client_print(index, type, msg_name, msg_param1, msg_param2, msg_param3, msg_param4); } // Even if message starts with '#', we should check its length for safety. new length = strlen(msg_name); // If string is larger than expected, we forward to client_print which will cut message properly. // This means also this can't be a predefined game message. // Max console length: 128 = \n (126) + \0 (127) // Max SayText length: 192 = \n (190) + \0 (191) if ((length > 126 && (print_notify <= type <= print_console)) || ( length > 190 && (print_chat <= type <= print_radio))) { return client_print(index, type, msg_name, msg_param1, msg_param2, msg_param3, msg_param4); } static msgTextMsg; if (!msgTextMsg) { msgTextMsg = get_user_msgid("TextMsg"); } message_begin(index > 0 ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, msgTextMsg, {0,0,0}, index); write_byte(type); write_string(msg_name); if (msg_param1[0]) { write_string(msg_param1); } if (msg_param2[0]) { write_string(msg_param2); } if (msg_param3[0]) { write_string(msg_param3); } if (msg_param4[0]) { write_string(msg_param4); } message_end(); return 1; } |
Others
- Added
MSG_INIT
support inmessage_begin
native - Set
set_hudmessage
default channel to-1
to reflect auto-channeling support
String
- Constants and stocks from
string.inc
have been moved in their own filesstring_const.inc
andstring_stocks.inc
. strlen
has been moved fromcore.inc
tostring.inc
.strbreak
is now replaced by a backwards compatibility stock.
Conversion
Native | Description |
---|---|
strtol
|
⇅ Parses the string interpreting its content as an integral number of the specified base , which is returned as integer value. The function also sets the value of endPos to point to the position of the first character after the number./** * Parses the 'string' interpreting its content as an integral number of the specified 'base', * which is returned as integer value. The function also sets the value of 'endPos' to point * to the position of the first character after the number. * * This is the same as C++ strtol function with a difference on second param. * * The function first discards as many whitespace characters as necessary until the first * non-whitespace character is found. Then, starting from this character, takes as many * characters as possible that are valid following a syntax that depends on the 'base' parameter, * and interprets them as a numerical value. Finally, a position of the first character following * the integer representation in 'string' is stored in 'endPos'. * * If the value of 'base' is zero, the syntax expected is similar to that of integer constants, * which is formed by a succession of : * An optional sign character (+ or -) * An optional prefix indicating octal or hexadecimal base ("0" or "0x"/"0X" respectively) * A sequence of decimal digits (if no base prefix was specified) or either octal or hexadecimal digits if a specific prefix is present * * If the 'base' value is between 2 and 36, the format expected for the integral number is a succession * of any of the valid digits and/or letters needed to represent integers of the specified radix * (starting from '0' and up to 'z'/'Z' for radix 36). The sequence may optionally be preceded by * a sign (either + or -) and, if base is 16, an optional "0x" or "0X" prefix. * * If the first sequence of non-whitespace characters in 'string' is not a valid integral number * as defined above, or if no such sequence exists because either 'string' is empty or it contains * only whitespace characters, no conversion is performed. * * @param string The string to parse. * @param endPos The position of the first character following the number. * On success and when containing only numbers, position is at the end of string, meaning equal to 'string' length. * On failure, position is sets always to 0. * @param base The numerical base (radix) that determines the valid characters and their interpretation. * If this is 0, the base used is determined by the format in the sequence. * @return On success, the function returns the converted integral number as integer value. * If no valid conversion could be performed, a zero value is returned. * If the value read is out of the range of representable values by a cell, * the function returns 'cellmin' or 'cellmax'. */ native strtol(const string[], &endPos = 0, base = 0); |
strtof
|
⇅ Parses the string interpreting its content as an floating point number and returns its value as a float. The function also sets the value of endPos to point to the position of the first character after the number./** * Parses the 'string' interpreting its content as an floating point number and returns its value as a float. * The function also sets the value of 'endPos' to point to the position of the first character after the number. * * This is the same as C++ strtod function with a difference on second param. * * The function first discards as many whitespace characters as necessary until the first * non-whitespace character is found. Then, starting from this character, takes as many * characters as possible that are valid and interprets them as a numerical value. * Finally, a position of the first character following the float representation in 'string' * is stored in 'endPos'. * * If the first sequence of non-whitespace characters in 'string' is not a valid float number * as defined above, or if no such sequence exists because either 'string' is empty or it contains * only whitespace characters, no conversion is performed. * * @param string The string to parse. * @param endPos The position of the first character following the number. * On success and when containing only numbers, position is at the end of string, meaning equal to 'string' length. * On failure, position is sets always to 0. * @return On success, the function returns the converted floating point number as float value. * If no valid conversion could be performed, a zero value is returned. */ native Float:strtof(const string[], &endPos = 0); |
Format specifier
Specifier | Description |
---|---|
%b
|
Binary digits in the value |
%n
|
Requires a client index. Expands to a string containing the player's name. If the client index is 0, the string will be: Console
|
%N
|
Requires a client index. Expands to 1<2><3><4> where 1 is the player's name, 2 is the player's userid, 3 is the player's SteamID, and 4 the player's team name. If the client index is 0, the string will be: Console<0><Console><Console>
|
%l
|
Translates a phrase from a key. Similar to %L with the difference it will use the client's index set internally by the function.This is only allowed in functions which act directly on one or more clients. Note:To complement this, a new ⇅
SetGlobalTransTarget native to set the current index has been added.This is useful to be used before with natives which are not player-oriented", like a bunch of formatex ./** * Sets the global language target. * * @note This is useful for creating functions * that will be compatible with the %l format specifier. Note that invalid * indexes can be specified but the error will occur during translation, * not during this function call. * * @param client Client index or LANG_SERVER * @noreturn */ native SetGlobalTransTarget(client); Example:⇅
client_print(index, print_chat, "%L", index, "EGG"); can be now client_print(index, print_chat, "%l", "EGG"); |
Formatting
set_fail_state
has now the ability to format a text.- A new native for simple inline formatting:
Native Description fmt
⇅ Formats and returns a string according to the AMX Mod X format rules. Note:This should only be used for simple inline formatting like in the above example.
Avoid using this function to store strings into variables as an additional copying step is required.Note:The buffer size is defined byMAX_FMT_LENGTH
.Example:/**
* Formats and returns a string according to the AMX Mod X format rules * (see documentation). * * @note Example: menu_additem(menu, fmt("My first %s", "item")). * @note This should only be used for simple inline formatting like in the above example. * Avoid using this function to store strings into variables as an additional * copying step is required. * @note The buffer size is defined by MAX_FMT_LENGTH. * * @param format Formatting rules. * @param ... Variable number of format parameters. * * @return Formatted string */
native [MAX_FMT_LENGTH]fmt(const format[], any:...);
Others
Native | Description |
---|---|
strtok2
|
⇅ Breaks a string in two by token.
Note:This function has been added due to strtok being buggy in some situations. Trim flags:⇅
/** * Below are the trim flags for strtok2 * * You can specify how the left and right buffers will * be trimmed by strtok2. LTRIM trims spaces from the * left side. RTRIM trims from the right side. * * The defines TRIM_INNER, TRIM_OUTER and TRIM_FULL are * shorthands for commonly used flag combinations. * * When the initial string is trimmed, using TRIM_INNER * for all subsequent strtok2 calls will ensure that left * and right are always trimmed from both sides. * * Examples: * str1[] = " This is * some text " * strtok2(str1, left, 24, right, 24, '*', TRIM_FULL) * left will be "This is", right will be "some text" * * str2[] = " Here is | an | example " * trim(str2) * strtok2(str2, left, 24, right, 24, '|', TRIM_INNER) * left will be "Here is", right will be "an | example" * strtok2(right, left, 24, right, 24, '|', TRIM_INNER) * left will be "an", right will be "example" * * str3[] = " One - more " * strtok2(str3, left, 24, right, 24, '-', TRIM_OUTER) * left will be "One ", right will be " more" * * str4[] = " Final . example " * strtok2(str4, left, 24, right, 24, '.', LTRIM_LEFT|LTRIM_RIGHT) * left will be "Final ", right will be "example " */ #define LTRIM_LEFT (1<<0) #define RTRIM_LEFT (1<<1) #define LTRIM_RIGHT (1<<2) #define RTRIM_RIGHT (1<<3) #define TRIM_INNER RTRIM_LEFT|LTRIM_RIGHT #define TRIM_OUTER LTRIM_LEFT|RTRIM_RIGHT #define TRIM_FULL TRIM_OUTER|TRIM_INNER /** * Breaks a string in two by token. * * @note Only available in 1.8.3 and above. * * @param text String to tokenize * @param left Buffer to store left half * @param llen Size of left buffer * @param right Buffer to store right half * @param rlen Size of right buffer * @param token Token to split by * @param trim Flags for trimming behavior, see above * * @return Returns position of token in string if found, * -1 if token was not found */ native strtok2(const text[], left[], const llen, right[], const rlen, const token = ' ', const trim = 0); |
Stock | Description |
---|---|
explode_string
|
⇅ Breaks a string into pieces and stores each piece into an array of buffers./** * Breaks a string into pieces and stores each piece into an array of buffers. * * @param text The string to split. * @param split The string to use as a split delimiter. * @param buffers An array of string buffers (2D array). * @param maxStrings Number of string buffers (first dimension size). * @param maxStringLength Maximum length of each string buffer. * @param copyRemainder False (default) discard excess pieces, true to ignore * delimiters after last piece. * @return Number of strings retrieved. */ stock explode_string(const text[], const split[], buffers[][], maxStrings, maxStringLength, bool:copyRemainder = false) { new reloc_idx, idx, total; if (maxStrings < 1 || !split[0]) { return 0; } while ((idx = split_string(text[reloc_idx], split, buffers[total], maxStringLength)) != -1) { reloc_idx += idx; if (++total == maxStrings) { if (copyRemainder) { copy(buffers[total-1], maxStringLength, text[reloc_idx-idx]); } return total; } } copy(buffers[total++], maxStringLength, text[reloc_idx]); return total; } |
implode_strings
|
⇅ Joins an array of strings into one string, with a join string inserted in between each given string.This function complements explode_string ./** * Joins an array of strings into one string, with a "join" string inserted in * between each given string. This function complements ExplodeString. * * @param strings An array of strings. * @param numStrings Number of strings in the array. * @param join The join string to insert between each string. * @param buffer Output buffer to write the joined string to. * @param maxLength Maximum length of the output buffer. * @return Number of bytes written to the output buffer. */ stock implode_strings(const strings[][], numStrings, const join[], buffer[], maxLength) { new total, length, part_length; new join_length = strlen(join); for (new i=0; i<numStrings; i++) { length = copy(buffer[total], maxLength-total, strings[i]); total += length; if (length < part_length) { break; } if (i != numStrings - 1) { length = copy(buffer[total], maxLength-total, join); total += length; if (length < join_length) { break; } } } return total; } |
UTF-8
An effort has been made to provide UTF-8 safety for formatting-capable functions.
This includes precision with %s
e.g. %.12s
.
Few specific functions have been updated as well:
console_print
client_print
,client_print_color
get_user_name
get_concmd
,get_clcmd
,get_srvcmd
get_cvar_string
,get_pcvar_string
format_time
read_data
get_localinfo
read_argv
,read_args
read_logdata
,read_logargv
get_module
read_file
fgets
ReadPackString
ArrayGetString
TrieGetString
strtok
,strtok2
strbreak
isdigit
,isalnum
,isspace
,isalpha
UTF-8 support has been added in the following functions:
containi
strfind
(with ignorecase set)strcmp
(with ignorecase set)strncmp
(with ignorecase set)equali
replace_string
(with ignorecase set)replace_stringex
(with ignorecase set)get_players
(with name and ignorecase flags set)find_player
(with name and ignorecase flags set)
New natives have been added:
Native | Description |
---|---|
is_char_upper is_char_lower is_char_mb
|
⇅ Returns whether an alphabetic character is uppercase./** * Returns whether an alphabetic character is uppercase. * * @note Only available in 1.8.3 and above. * @note Multi-byte characters will always return false. * * @param ch Character to test. * @return True if character is uppercase, otherwise false. */ native bool:is_char_upper(ch); /** * Returns whether an alphabetic character is lowercase. * * @note Only available in 1.8.3 and above. * @note Multi-byte characters will always return false. * * @param ch Character to test. * @return True if character is lowercase, otherwise false. */ native bool:is_char_lower(ch); /** * Returns if a character is multi-byte or not. * * @note Only available in 1.8.3 and above. * * @param ch Character to test. * @return 0 for a normal 7-bit ASCII character, * otherwise number of bytes in multi-byte character. */ native is_char_mb(ch); |
is_string_category
|
⇅ Checks if the input string conforms to the category specified by the flags./** * Checks if the input string conforms to the category specified by the flags. * * @note This function can be used to check if the code points in a string are part * of a category. Valid flags are part of the UTF8C_* list of defines. * The category for a code point is defined as part of the entry in * UnicodeData.txt, the data file for the Unicode code point database. * @note Flags parameter must be a combination of UTF8C_* flags or a single UTF8C_IS* flag. * In order to main backwards compatibility with POSIX functions like `isdigit` * and `isspace`, compatibility flags have been provided. Note, however, that * the result is only guaranteed to be correct for code points in the Basic * Latin range, between U+0000 and 0+007F. Combining a compatibility flag with * a regular category flag will result in undefined behavior. * @note The function is greedy. This means it will try to match as many code * points with the matching category flags as possible and return the offset in * the input in bytes. * * @param input The string to check * @param input_size Size of the string, use 1 to check one character regardless its size * @param flags Requested category, see UTF8C_* flags * @param output_size Number of bytes in the input that conform to the specified * category flags * @return True if the whole input of `input_size` conforms to the specified * category flags, false otherwise */ native bool:is_string_category(const input[], input_size, flags, &output_size = 0); |
get_char_bytes
|
⇅ Returns the number of bytes a character is using./** * Returns the number of bytes a character is using. This is * for multi-byte characters (UTF-8). For normal ASCII characters, * this will return 1. * * @note Only available in 1.8.3 and above. * * @param source Source input string. * @return Number of bytes the current character uses. */ native get_char_bytes(const source[]); |
mb_strotolower mb_strtoupper mb_ucfirst mb_strtotitle
|
⇅ Performs a multi-byte safe (UTF-8) conversion of all chars in string to lower case./** * Performs a multi-byte safe (UTF-8) conversion of all chars in string to lower case. * * @note Although most code points can be converted in-place, there are notable * exceptions and the final length can vary. * @note Case mapping is not reversible. That is, toUpper(toLower(x)) != toLower(toUpper(x)). * * @param string The string to convert. * @param maxlength Optional size of the buffer. If 0, the length of the original string * will be used instead. * * @return Number of bytes written. */ native mb_strtolower(string[], maxlength = 0); /** * Performs a multi-byte safe (UTF-8) conversion of all chars in string to upper case. * * @note Although most code points can be converted in-place, there are notable * exceptions and the final length can vary. * @note Case mapping is not reversible. That is, toUpper(toLower(x)) != toLower(toUpper(x)). * * @param string The string to convert. * @param maxlength Optional size of the buffer. If 0, the length of the original string * will be used instead. * * @return Number of bytes written. */ native mb_strtoupper(string[], maxlength = 0); /** * Performs a multi-byte safe (UTF-8) conversion of a string's first character to upper case. * * @note Although most code points can be converted in-place, there are notable * exceptions and the final length can vary. * * @param string The string to convert. * @param maxlength Optional size of the buffer. If 0, the length of the original string * will be used instead. * * @return Number of bytes written. */ native mb_ucfirst(string[], maxlength = 0); /** * Performs a multi-byte safe (UTF-8) conversion of all chars in string to title case. * * @note Although most code points can be converted in-place, there are notable * exceptions and the final length can vary. * @note Any type of punctuation can break up a word, even if this is * not grammatically valid. This happens because the titlecasing algorithm * does not and cannot take grammar rules into account. * @note Examples: * The running man | The Running Man * NATO Alliance | Nato Alliance * You're amazing at building libraries | You'Re Amazing At Building Libraries * * @param string The string to convert. * @param maxlength Optional size of the buffer. If 0, the length of the original string * will be used instead. * * @return Number of bytes written. */ native mb_strtotitle(string[], maxlength = 0); |
replace_string replace_stringex
|
⇅ Given a string, replaces all occurrences of a search string with a replacement string.
Note:Similar to replace_all stock, but implemented as native and with different algorithm.This native doesn't error on bad buffer size and will smartly cut off the string in a way that pushes old data out. /** * Given a string, replaces all occurrences of a search string with a * replacement string. * * @note Similar to replace_all() stock, but implemented as native and * with different algorithm. This native doesn't error on bad * buffer size and will smartly cut off the string in a way * that pushes old data out. * * @note Only available in 1.8.3 and above. * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. * * @param text String to perform search and replacements on. * @param maxlength Maximum length of the string buffer. * @param search String to search for. * @param replace String to replace the search string with. * @param caseSensitive If true (default), search is case sensitive. * * @return Number of replacements that were performed. */ native replace_string(text[], maxlength, const search[], const replace[], bool:caseSensitive = true); ⇅ Given a string, replaces the first occurrence of a search string with a replacement string. Note:Similar to replace native, but implemented as native and with different algorithm.This native doesn't error on bad buffer size and will smartly cut off the string in a way that pushes old data out. /** * Given a string, replaces the first occurrence of a search string with a * replacement string. * * @note Similar to replace() native, but implemented with more options and * with different algorithm. This native doesn't error on bad * buffer size and will smartly cut off the string in a way * that pushes old data out. * * @note Only available in 1.8.3 and above. * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. * * @param text String to perform search and replacements on. * @param maxlength Maximum length of the string buffer. * @param search String to search for. * @param replace String to replace the search string with. * @param searchLen If higher than -1, its value will be used instead of * a strlen() call on the search parameter. * @param replaceLen If higher than -1, its value will be used instead of * a strlen() call on the replace parameter. * @param caseSensitive If true (default), search is case sensitive. * * @return Index into the buffer (relative to the start) from where * the last replacement ended, or -1 if no replacements were * made. */ native replace_stringex(text[], maxlength, const search[], const replace[], searchLen = -1, replaceLen = -1, bool:caseSensitive = true); |
strncmp
|
⇅ Compares two strings parts lexographically./** * Compares two strings parts lexographically. * * @note Only available in 1.8.3 and above. * @note This supports multi-byte characters (UTF-8) on case insensitive comparison. * * @param string1 First string (left). * @param string2 Second string (right). * @param num Number of characters to compare. * @param ignorecase If true, comparison is case insensitive. * If false (default), comparison is case sensitive. * @return -1 if string1 < string2 * 0 if string1 == string2 * 1 if string1 > string2 */ native strncmp(const string1[], const string2[], num, bool:ignorecase = false); |
New stocks:
Stock | Description |
---|---|
char_to_upper
|
⇅ Returns an uppercase character to a lowercase character./** * Returns an uppercase character to a lowercase character. * * @note Only available in 1.8.3 and above. * * @param chr Characer to convert. * @return Lowercase character on success, * no change on failure. */ stock char_to_upper(chr) { if (is_char_lower(chr)) { return (chr & ~(1<<5)); } return chr; } |
char_to_lower
|
⇅ Returns a lowercase character to an uppercase character./** * Returns a lowercase character to an uppercase character. * * @note Only available in 1.8.3 and above. * * @param chr Characer to convert. * @return Uppercase character on success, * no change on failure. */ stock char_to_lower(chr) { if (is_char_upper(chr)) { return (chr | (1<<5)); } return chr; } |
Existing module APIs additions
AMXX SDK
the following functions have been added:
Function | Description |
---|---|
MF_SetAmxStringUTF8Char
|
Sets UTF-8 string from char* input |
MF_SetAmxStringUTF8Cell
|
Sets UTF-8 string from cell* input |
MF_GetAmxStringNull
|
Gets string with NULL_STRING support
|
MF_GetAmxVectorNull
|
Gets a vector with NULL_VECTOR support
|
MF_GetConfigManager
|
Gets the config manager for use with gamedata files |
CStrike
All hardcoded game datas are now moved to its own gamedata file located in data/gamedata/modules.games/game.cstrike.txt
.
See AMX_Mod_X_1.9_Release_Notes#Gamedata for more information.
Constant
Numerous constants from the game have added. See the cstrike_const.inc.
Additionally for two natives:
CS_NORESET
constant for use withcs_set_user_team
for skipping the model resetTRAIN_*
⇅ constants for use withcs_get_user_driving
/** * Train status values */ #define TRAIN_ACTIVE 0x80 #define TRAIN_NEW 0xc0 #define TRAIN_OFF 0x00 #define TRAIN_NEUTRAL 0x01 #define TRAIN_SLOW 0x02 #define TRAIN_MEDIUM 0x03 #define TRAIN_FAST 0x04 #define TRAIN_BACK 0x05
Entity
Native | Description |
---|---|
cs_create_entity
|
⇅ Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper.
Note:Unlike other mods CS keeps track of entities using a custom hashtable. This function adds entities to this hashtable, providing benefits over the default CreateNamedEntity (used by
/** * Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper. * * @note Unlike other mods CS keeps track of entities using a custom hashtable. * This function adds entities to this hashtable, providing benefits over * the default CreateNamedEntity (used by create_entity() for example): * - Storing entities in a hashtable allows CS to improve classname lookup * performance compared to functions like FindEntityByString (used by * find_ent_by_class() for example) that usually have to loop * through all entities incrementally. * - As CS exclusively uses the hashtable for classname lookup, entities * created using the default engine functions will not be found by the * game. For example "weaponbox" entities are supposed to be * automatically cleaned up on round restart but are not considered if * they have not been added to the hashtable. * @note The faster hashtable lookup can be utilized with cs_find_ent_by_class() * @note When creating an entity the classname has to be valid in the mod, as * the engine needs to link the entity to an existing class internally. * The classname string that is stored in the entvar struct * (EV_SZ_classname) is separate from this association and can later be * freely changed to serve other purposes. * * @param classname Entity class name * * @return Index of the created entity (> 0), 0 otherwise */ native cs_create_entity(const classname[]); |
cs_find_ent_by_class cs_find_ent_by_owner
|
⇅ Finds an entity in the world using Counter-Strike's custom FindEntityByString wrapper./** * Finds an entity in the world using Counter-Strike's custom FindEntityByString * wrapper. * * @note Unlike other mods CS keeps track of entities using a custom hashtable. * This function utilizes the hasthable and allows for considerably faster * classname lookup compared to the default FindEntityByString (used by * find_ent_by_class() for example). * @note This exclusively considers entities in the hashtable, created by the * game itself, using cs_create_entity(), or added via cs_set_ent_class(). * * @param start_index Entity index to start searching from. -1 to start from * the first entity * @param classname Classname to search for * * @return Entity index > 0 if found, 0 otherwise */ native cs_find_ent_by_class(start_index, const classname[]); /** * Finds an entity in the world using Counter-Strike's custom FindEntityByString * wrapper, matching by owner. * * @note Unlike other mods CS keeps track of entities using a custom hashtable. * This function utilizes the hasthable and allows for considerably faster * classname lookup compared to the default FindEntityByString (used by * find_ent_by_owner() for example). * @note This exclusively considers entities in the hashtable, created by the * game itself, using cs_create_entity(), or added via cs_set_ent_class(). * * @param start_index Entity index to start searching from. -1 to start from * the first entity * @param classname Classname to search for * @param owner Entity index to search for entity's owner * * @return Entity index > 0 if found, 0 otherwise */ native cs_find_ent_by_owner(start_index, const classname[], owner); Note:Those functions utilize the hasthable and allows for considerably faster classname lookup compared to the default FindEntityByString (used by
find_ent_by_class for example).This exclusively considers entities in the hashtable, created by the game itself, using cs_create_entity , or added via cs_set_ent_class ). |
cs_set_ent_class
|
⇅ Sets a custom classname of an entity.
Note:This function adds or updates the classname in the hasthable as well. This is useful for use with cs_find_ent_by_class and cs_find_ent_by_owner ./** * Sets a custom classname of an entity. * * @note Unlike other mods CS keeps track of entities using a custom hashtable. * This function adds or updates the classname in the hasthable as well. * This is useful for use with cs_find_ent_by_class() and cs_find_ent_by_owner(). * * @param index Entity index * @param classname Classname to update for * * @noreturn */ native cs_set_ent_class(index, const classname[]); |
Buying
You can now easily detect when an item is being purchased.
Forward | Description |
---|---|
CS_OnBuyAttempt
|
⇅ Called when a client attempts to purchase an item.
Note:This is called immediately when the client issues a buy command. The game has not yet checked if the client can actually buy the weapon. /** * Called when a client attempts to purchase an item. * * @note This is called immediately when the client issues a buy command. The * game has not yet checked if the client can actually buy the weapon. * @note For a list of possible item ids see the CSI_* constants. * * @param index Client index * @param item Item id * * @return PLUGIN_CONTINUE to let the buy attempt continue * PLUGIN_HANDLED to block the buy attempt */ forward CS_OnBuyAttempt(index, item); |
CS_OnBuy
|
⇅ Called when a client purchases an item.
Note:This is called right before the user receives the item and before the money is deducted from their cash reserves. /** * Called when a client purchases an item. * * @note This is called right before the user receives the item and before the * money is deducted from their cash reserves. * @note For a list of possible item ids see the CSI_* constants. * * @param index Client index * @param item Item id * * @return PLUGIN_CONTINUE to let the buy continue * PLUGIN_HANDLED to block the buy */ forward CS_OnBuy(index, item); |
CSI_*
⇅ constants/** * Constants used for the CS_OnBuy() and CS_OnBuyAttempt() forwards. * * @note While these mostly overlap with the CSW_* constants the CSI_* constants * contain custom AMXX values that do not correspond to any real value in * the game. The CSI_* constants should therefore be used for consistency. */ #define CSI_NONE CSW_NONE #define CSI_P228 CSW_P228 #define CSI_GLOCK CSW_GLOCK // Unused by game, See CSI_GLOCK18. #define CSI_SCOUT CSW_SCOUT #define CSI_HEGRENADE CSW_HEGRENADE #define CSI_XM1014 CSW_XM1014 #define CSI_C4 CSW_C4 #define CSI_MAC10 CSW_MAC10 #define CSI_AUG CSW_AUG #define CSI_SMOKEGRENADE CSW_SMOKEGRENADE #define CSI_ELITE CSW_ELITE #define CSI_FIVESEVEN CSW_FIVESEVEN #define CSI_UMP45 CSW_UMP45 #define CSI_SG550 CSW_SG550 #define CSI_GALIL CSW_GALIL #define CSI_FAMAS CSW_FAMAS #define CSI_USP CSW_USP #define CSI_GLOCK18 CSW_GLOCK18 #define CSI_P228 CSW_AWP #define CSI_MP5NAVY CSW_MP5NAVY #define CSI_M249 CSW_M249 #define CSI_M3 CSW_M3 #define CSI_M4A1 CSW_M4A1 #define CSI_TMP CSW_TMP #define CSI_G3SG1 CSW_G3SG1 #define CSI_FLASHBANG CSW_FLASHBANG #define CSI_DEAGLE CSW_DEAGLE #define CSI_SG552 CSW_SG552 #define CSI_AK47 CSW_AK47 #define CSI_KNIFE CSW_KNIFE #define CSI_P90 CSW_P90 #define CSI_SHIELDGUN CSW_SHIELDGUN // The real CS value, use CSI_SHELD instead. #define CSI_VEST CSW_VEST // Custom #define CSI_VESTHELM CSW_VESTHELM // Custom #define CSI_DEFUSER 33 // Custom #define CSI_NVGS 34 // Custom #define CSI_SHIELD 35 // Custom - The value passed by the forward, more convenient for plugins. #define CSI_PRIAMMO 36 // Custom #define CSI_SECAMMO 37 // Custom #define CSI_MAX_COUNT 38 #define CSI_LAST_WEAPON CSW_LAST_WEAPON #define CSI_ALL_WEAPONS CSW_ALL_WEAPONS #define CSI_ALL_PISTOLS CSW_ALL_PISTOLS #define CSI_ALL_SHOTGUNS CSW_ALL_SHOTGUNS #define CSI_ALL_SMGS CSW_ALL_SMGS #define CSI_ALL_RIFLES CSW_ALL_RIFLES #define CSI_ALL_SNIPERRIFLES CSW_ALL_SNIPERRIFLES #define CSI_ALL_MACHINEGUNS CSW_ALL_MACHINEGUNS #define CSI_ALL_GRENADES CSW_ALL_GRENADES #define CSI_ALL_ARMORS CSW_ALL_ARMORS #define CSI_ALL_GUNS CSW_ALL_GUNS
#include <amxmodx> #include <cstrike> public CS_OnBuyAttempt(index, item) { if (item == CSI_AWP) { client_print(index, print_chat, "You tried to buy an AWP."); return PLUGIN_HANDLED; // <-- Use this to block a buying } } public CS_OnBuy(index, item) { if (item == CSI_DEAGLE) { client_print(index, print_chat, "You just bought a deagle and you're about to receive it."); } }
Items info
Native | Description |
---|---|
cs_get_user_weapon_entity
|
⇅ Returns active weapon entity./** * Returns active weapon entity. * * @param playerIndex Player index * * @return Weapon entity index on success or 0 if there is no active weapon * @error If the client index is not within the range of 1 to * maxClients, or the client is not connected, an error will be * thrown. */ native cs_get_user_weapon_entity(playerIndex); |
cs_get_user_weapon
|
⇅ Returns weapon index of the active weapon.
Note:More reliable than get_user_weapon ./** * Returns weapon index of the active weapon. * * @note More reliable than get_user_weapon. * * @param playerIndex Player index * @param clip Optional variable to store clip ammo to * @param ammo Optional variable to store backpack ammo to * * @return Weapon index on success or 0 if there is no active weapon * @error If the client index is not within the range of 1 to * maxClients, or the client is not connected, an error will be * thrown. */ native cs_get_user_weapon(playerIndex, &clip = 0, &ammo = 0); |
cs_get_item_id
|
⇅ Returns the item id associated with an item name and its aliases.
Note:The item name is case sensitive an can be with or without weapon_ and item_ prefixes. This can be a command alias as well.Values examples: ak47 , weapon_ak47 , kevlar , item_kevlar , vest , bullpup , .../** * Returns the item id associated with an item name and its aliases. * * @note The item name is case sensitive an can be with or without * weapon_ and item_ prefixes. This can be a command alias as well. * Values examples: ak47, weapon_ak47, kevlar, item_kevlar, vest, bullpup, ... * * @param name Alias or classname * @param classid If item is a weapon, variable to store the associated * weapon class id in (CS_WEAPONCLASS_* constants) * * @return Item id (CSI_* constants) */ native any:cs_get_item_id(const name[], &CsWeaponClassType:classid = CS_WEAPONCLASS_NONE); |
cs_get_translated_item_alias
|
⇅ Returns an item name associated with a command alias.
Note:The alias is case sensitive.
Note:If not an alias to a weapon, buffer will be set with the original alias. /** * Returns an item name associated with a command alias. * * @note The alias is case sensitive. * @note If not an alias to a weapon, buffer will be set with the original alias. * * @param alias Alias name * @param itemname Buffer to store item name to * @param maxlength Maximum buffer size * * @return True if alias is translated, false otherwise */ native bool:cs_get_translated_item_alias(const alias[], itemname[], maxlength); |
cs_get_item_alias
|
⇅ Returns the alias name associated with an item index./** * Returns the alias name associated with an item index. * * @param itemid Item id (CSI_* constants) * @param name Buffer to store alias name to * @param name_maxlen Maximum buffer size * @param altname Optional buffer to store if available alternative alias name to * @param altname_maxlen Maximum buffer size * * @return True if alias is found, false otherwise */ native bool:cs_get_item_alias(itemid, name[], name_maxlen, altname[] = "", altname_maxlen = 0); |
cs_get_weapon_info
|
⇅ Returns some information about a weapon.
Note:The alias is case sensitive.
Note:If not an alias to a weapon, buffer will be set with the original alias. /** * Weapon info types for use with cs_get_weapon_info(). */ enum CsWeaponInfo { CS_WEAPONINFO_COST = 0, CS_WEAPONINFO_CLIP_COST = 1, CS_WEAPONINFO_BUY_CLIP_SIZE = 2, CS_WEAPONINFO_GUN_CLIP_SIZE = 3, CS_WEAPONINFO_MAX_ROUNDS = 4, CS_WEAPONINFO_AMMO_TYPE = 5, }; /** * Returns some information about a weapon. * * @param weapon_id Weapon id, see CSW_* constants * @param type Info type, see CS_WEAPONINFO_* constants * * @return Weapon information value * @error If weapon_id and type are out of bound, an error will be thrown. */ native any:cs_get_weapon_info(weapon_id, CsWeaponInfo:type); |
Stock | Description |
---|---|
cs_get_weapon_class
|
⇅ Returns a weapon class id associated with a weapon id./** * Returns a weapon class id associated with a weapon id. * * @param weapon_id Weapon id (CSI_* constants) * * @return Weapon class id (CS_WEAPONCLASS_* constants) */ stock CsWeaponClassType:cs_get_weapon_class(weapon_id) { new CsWeaponClassType:type = CS_WEAPONCLASS_NONE; if (cs_is_valid_itemid(weapon_id, .weapon_only = true) || weapon_id == CSI_SHIELD) { switch (weapon_id) { case CSI_SHIELDGUN, CSI_SHIELD: { type = CS_WEAPONCLASS_PISTOL; } case CSI_KNIFE: { type = CS_WEAPONCLASS_KNIFE; } default: { new const bits = (1 << weapon_id); if(bits & CSI_ALL_PISTOLS) { type = CS_WEAPONCLASS_PISTOL; } else if(bits & CSI_ALL_GRENADES) { type = CS_WEAPONCLASS_GRENADE; } else if(bits & CSI_ALL_SMGS) { type = CS_WEAPONCLASS_SUBMACHINEGUN; } else if(bits & CSI_ALL_SHOTGUNS) { type = CS_WEAPONCLASS_SHOTGUN; } else if(bits & CSI_ALL_MACHINEGUNS) { type = CS_WEAPONCLASS_MACHINEGUN; } else if(bits & CSI_ALL_RIFLES) { type = CS_WEAPONCLASS_RIFLE; } else if(bits & CSI_ALL_SNIPERRIFLES) { type = CS_WEAPONCLASS_SNIPERRIFLE; } } } } return type; } |
cs_is_valid_itemid
|
⇅ Checks whether an item id is not out of bounds./** * Checks whether an item id is not out of bounds. * * @param id Item id (CSI_* constants) * @param weapon_only If true, only the real weapon ids will be checked, * including shield as well * * @return True if item id is valid, false otherwise */ stock bool:cs_is_valid_itemid(id, bool:weapon_only = false) { if (id <= CSI_NONE) { return false; } if (id > CSI_LAST_WEAPON && id != CSI_SHIELDGUN && weapon_only) { return false; } if (id >= CSI_MAX_COUNT) { return false; } return true; } |
New params
Forward | Parameter | Description |
---|---|---|
cs_set_user_deaths
|
scoreboard
|
⇅ If true the scoreboard will be updated to reflect the new value./** * Sets client's deaths. * * @param index Client index * @param newdeaths New value to set * @param scoreboard If true the scoreboard will be updated to reflect the new value. * * @noreturn * @error If the client index is not within the range of 1 to * MaxClients, or the client is not connected, an error * will be thrown. */ native cs_set_user_deaths(index, newdeaths, bool:scoreboard = true); |
cs_get_armoury_type cs_set_armoury_type
|
count
|
⇅ Optional variable to store in the number of times that an item can be retrieved from the same entity before being hidden./** * Returns the armoury entity's weapon id. * * @note Not all weapon ids are supported by Counter-Strike, an armoury entity * can not be a pistol, a knife or a bomb for exmaple. The full list is: * CSW_SCOUT, CSW_HEGRENADE, CSW_XM1014, CSW_MAC10, CSW_AUG, * CSW_SMOKEGRENADE, CSW_AWP, CSW_MP5NAVY, CSW_M249, CSW_M3, CSW_M4A1, * CSW_TMP, CSW_G3SG1, CSW_VEST, CSW_VESTHELM, CSW_FLASHBANG, * CSW_SG552, CSW_AK47, CSW_P90 * * @param index Armoury entity index * @param count Optional variable to store in the number of times that an item can be retrieved * from the same entity before being hidden * * @return Weapon id * @error If a non-armoury entity is provided, an error will be * thrown. */ native cs_get_armoury_type(index, &count = 1); /** * Sets the amoury entity type. * * @note Not all weapon ids are supported by Counter-Strike, an armoury entity * can not be a pistol, a knife or a bomb for exmaple. The full list is: * CSW_SCOUT, CSW_HEGRENADE, CSW_XM1014, CSW_MAC10, CSW_AUG, * CSW_SMOKEGRENADE, CSW_AWP, CSW_MP5NAVY, CSW_M249, CSW_M3, CSW_M4A1, * CSW_TMP, CSW_G3SG1, CSW_VEST, CSW_VESTHELM, CSW_FLASHBANG, * CSW_SG552, CSW_AK47, CSW_P90 * @note This does not update the entity model. * @note On restart, entity is always unhidden and the count is restored (this can not be below 1). * * @param index Armoury entity index * @param type Weapon id * @param count Number of times that an item can be retrieved from * the same entity before being hidden * If zero, the entity is hidden * If below zero, nothing is set * @noreturn * @error If a non-armoury entity is provided, an error will be * thrown. */ native cs_set_armoury_type(index, type, count = -1); |
cs_set_user_model
|
update_index
|
⇅ If true, the modelindex is updated as well.
Note:Updating modelindex is useful for custom models which don't have the same structure as the default ones (hitbox, etc..). Model must be precached before /** * Sets the client's player model. * * @note This is not a one-time set. The CStrike module will remember the * selected model and try to prevent attempts at changing the player * model, or immediately re-apply it if necessary. * @note Updating modelindex is useful for custom models which don't have * the same structure as the default ones (hitbox, etc..). Model must * be precached before. * * @param index Client index * @param model Model name * @param update_index If true, the modelindex is updated as well * * @noreturn * @error If the client index is not within the range of 1 to * MaxClients, the client is not connected, the provided * model is empty, or if modeindex is updated and the * provided model is not precached, an error will be thrown. */ native cs_set_user_model(index, const model[], bool:update_index = false); |
Others
- Hostage natives will work now with
monster_scientist
entity (alias ofhostage_entity
) cs_get_user_armor
Template:Armortype parameter is now optionalcs_set_weapon_silen
Template:Draw animation has a new value of 2 which follows game behavior to properly draw the animation
Engine
Entity
Native | Description |
---|---|
entity_intersects
|
⇅ Returns if two entities bounding boxes intersect by comparing their absolute minimum and maximum origins./** * Returns if two entities bounding boxes intersect by comparing their absolute * minimum and maximum origins. * * @param entity Entity index 1 * @param other Entity index 2 * * @return True if entities intersect, false otherwise * @error If an invalid entity index is provided, an error will be * thrown. */ native bool:entity_intersects(entity, other); |
set_ent_rendering
|
⇅ Sets rendering options of an entity./** * Sets rendering options of an entity. * * @note For a list of valid rendering effects see the kRenderFx* constants in * amxconst.inc * @note For a list of valid rendering modes see the kRender* constants in * amxconst.inc * @note Rendering amount has different meanings depending on the rendering * effect and mode used on the entity. * * @param index Entity index * @param fx Rendering effect * @param r Red component of rendering color * @param g Green component of rendering color * @param b Blue component of rendering color * @param render Rendering mode * @param amount Rendering amount * * @noreturn * @error If an invalid entity index is provided, an error will be * thrown. */ native set_ent_rendering(index, fx = kRenderFxNone, r = 0, g = 0, b = 0, render = kRenderNormal, amount = 0); |
Hook
You can now unregister hooks from: register_impulse
, register_think
and register_touch
.
Forward | Description |
---|---|
unregister_impulse
|
⇅ Removes a previously registered impulse hook./** * Removes a previously registered impulse hook. * * @param registerid Impulse forward id * * @return 1 on success, 0 if nothing was removed */ native unregister_impulse(registerid); |
unregister_think
|
⇅ Removes a previously registered think hook./** * Removes a previously registered think hook. * * @param registerid Think forward id * * @return 1 on success, 0 if nothing was removed */ native unregister_think(registerid); |
unregister_touch
|
⇅ Removes a previously registered touch hook./** * Removes a previously registered touch hook. * * @param registerid Touch forward id * * @return 1 on success, 0 if nothing was removed */ native unregister_touch(registerid); |
Miscellaneous
is_visible
is now working on player.set_ent_rendering
is new working on non-players entities.get_info_keybuffer
can now retrieve local key buffer (i.e. using-1
).trace_hull
gets a newend
destination parameter to make it useful.
Safer Natives
Safer natives which returns -1
if not entity found instead of 0
0 which is a valid value (worldspawn).
Native | Description |
---|---|
get_global_edict2
|
⇅ Safe version of get_global_edict .Returns a edict type value from the server globals. /** * Returns a edict type value from the server globals. * * @note For a list of valid edict type entries, see the GL_* constants in * engine_const.inc under the "Edict" section. * @note This native returns -1 as a safe error value if the edict retrieved is * an invalid entity. Otherwise it is identical to get_global_edict(). * * @param variable Entry to retrieve from * * @return Value of specified entry * @error If an invalid entry is provided, an error will be thrown. */ native get_global_edict2(variable); |
entity_get_edict2
|
⇅ Safe version of entity_get_edict .Returns an edict type value from an entities entvar struct. /** * Returns an edict type value from an entities entvar struct. * * @note For a list of valid edict type entries, see the EV_ENT_* constants in * engine_const.inc * @note This native returns -1 as a safe error value if the edict retrieved * from the entvar is an invalid entity. Otherwise it is identical to * entity_get_edict(). * * @param iIndex Entity index * @param iKey Entry to retrieve from * * @return Entity index in specified entry, -1 if the edict in the * entvar is not a valid entity or an invalid entry was * specified * @error If an invalid entity index is provided, an error will be * thrown. */ native entity_get_edict2(iIndex, iKey); |
Usercmd
get_usercmd
andset_usercmd
are now working and can be used inclient_cmdStart
forward.
Forward Description client_cmdStart
⇅ Called for CmdStart() on a client. /** * Called for CmdStart() on a client. * * @note Use [get|set]_usercmd() to read and modify information in the usercmd * struct. * * @param id Client index * * @return PLUGIN_CONTINUE to ignore, PLUGIN_HANDLED or higher to block */ forward client_cmdStart(id);
Fakemeta
KVD
This allows the creation of new KVD structures that can be used with Hamsandwich (Ham_Keyvalue
).
Native | Description |
---|---|
create_kvd free_kvd
|
⇅ Creates a KeyValueData handle./** * Creates a KeyValueData handle. * * @note Handles should be freed using free_kvd(). * * @return New KeyValueData handle */ native create_kvd(); KeyValueData handle./** * Frees a KeyValueData handle. * * @param kvd_handle KeyValueData handle * * @noreturn */ native free_kvd(kvd_handle); |
Entity's Private Data (gamedata)
This is now possible to manage value from an entity's private data based off a class and member name.
The related gamedata files are located in data/gamedata/common.games/entities.games
directory.
foo() { new const item = get_ent_data_entity("CBasePlayer", "m_pActiveItem"); }
Native | Description |
---|---|
get_ent_data set_ent_data
|
⇅ Retrieves an integer value from an entity's private data based off a class and member name./** * Retrieves an integer value from an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * integer, boolean, short, character, pointer, structure, class, * stringint and function. Unsigned variants (if applicable) are supported * and will be converted automatically. * * @param entity Entity index * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Integer value * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native any:get_ent_data(entity, const class[], const member[], element = 0); /** * Sets an integer value to an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * integer, boolean, short, character, pointer, stringint and function. * Unsigned variants (if applicable) are supported and will be converted * automatically. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Value to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native set_ent_data(entity, const class[], const member[], any:value, element = 0); |
get_ent_data_float set_ent_data_float
|
⇅ Retrieves an float value from an entity's private data based off a class and member name./** * Retrieves a float value from an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * * @param entity Entity index * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Float value * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native Float:get_ent_data_float(entity, const class[], const member[], element = 0); /** * Sets a float value to an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Value to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native set_ent_data_float(entity, const class[], const member[], Float:value, element = 0); |
get_ent_data_vector set_ent_data_vector
|
⇅ Retrieves a vector from an entity's private data based off a class and member name./** * Retrieves a vector from an entity's private data based off a class and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Vector buffer to store data in * @param element Element to retrieve (starting from 0) if member is an array * * @noreturn * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native get_ent_data_vector(entity, const class[], const member[], Float:value[3], element = 0); /** * Sets a vector to an entity's private data based off a class and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Vector to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native set_ent_data_vector(entity, const class[], const member[], Float:value[3], element = 0); |
get_ent_data_entity set_ent_data_entity
|
⇅ Retrieves an entity index from an entity's private data based off a class and member name./** * Retrieves an entity index from an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * classptr, entvars, edict and ehandle. * * @param entity Entity index * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Entity index if found, -1 otherwise * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native get_ent_data_entity(entity, const class[], const member[], element = 0); /** * Sets an entity index to an entity's private data based off a class * and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * classptr, entvars, edict and ehandle. * @note Pass -1 as value to act as C++ NULL. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Entity index to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If an invalid entity or value is provided, either class or member * is empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native set_ent_data_entity(entity, const class[], const member[], value, element = 0); |
get_ent_data_string set_ent_data_string
|
⇅ Retrieves a string from an entity's private data based off a class and member name./** * Retrieves a string from an entity's private data based off a class and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * string, stringptr. * * @param entity Entity index * @param class Class name * @param member Member name * @param value Buffer to store data in * @param maxlen Maximum size of the buffer * @param element Element to retrieve (starting from 0) if member is an array * * @return Number of cells written to buffer * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native get_ent_data_string(entity, const class[], const member[], value[], maxlen, element = 0); /** * Sets a string to an entity's private data based off a class and member name. * * @note Unlike the [get|set]_pdata_* natives that require compiling the class * member offset into the plugin, this native instead retrieves the * necessary offset from the AMXX gamedata files at runtime, based on the * provided class and member name. * @note This native is safer than [get|set]_pdata_* as it can perform stricter * offset and typing checks. * @note This native is used to access the following (C++/engine) data types: * string, stringptr. * * @param entity Entity index * @param class Class name * @param member Member name * @param value String to set * @param element Element to set (starting from 0) if member is an array * * @return Number of cells written to buffer * @error If an invalid entity is provided, either class or member is * empty, no offset is found or an invalid offset is retrieved, * or the data type does not match, an error will be thrown. */ native set_ent_data_string(entity, const class[], const member[], const value[], element = 0); |
get_ent_data_size
|
⇅ Retrieves the size of array of n entity class member./** * Retrieves the size of array of n entity class member. * * @param class Class name * @param member Member name * * @return Size of array (in elements), otherwise 1 if member is not an array * @error If either class or member is empty, no offset is found or an invalid * offset is retrieved, an error will be thrown. */ native get_ent_data_size(const class[], const member[]); |
find_ent_data_info
|
⇅ Finds a offset based off an entity class and member name./** * Finds a offset based off an entity class and member name. * * @param class Class name * @param member Member name * @param type Optional variable to store member type in (FIELD_* constants) * @param arraysize Optional variable to store array size in, if member is an array * @param unsigned Optional variable to store whether member is unsigned (short and char types only) * * @return Class member offset * @error If either class or member is empty, no offset is found or an invalid * offset is retrieved, an error will be thrown. */ native find_ent_data_info(const class[], const member[], &FieldType:type = FIELD_NONE, &arraysize = 0, &bool:unsigned = false); |
Entity's Private Data
While it's encouraged to use the new natives based off gamedata, this completes the list with new data types supported: edict, bool, byte, short and ehandle.
Native | Description |
---|---|
get_pdata_ent set_pdata_ent
|
⇅ Tries to retrieve an edict pointer from an entity's private data./** * Tries to retrieve an edict pointer from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_ent searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _Offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return -2 if an invalid entity was found. * -1 if an empty entity was found. * Otherwise, an entity index is returned. */ native get_pdata_ent(_index, _offset, _linuxdiff = 20, _macdiff = 20); /** * Sets an edict pointer to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_ent searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _value Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_ent(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); |
get_pdata_bool set_pdata_bool
|
⇅ Returns a boolean from an entity's private data./** * Returns a boolean from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_bool searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return An boolean value is returned. */ native bool:get_pdata_bool(_index, _offset, _linuxdiff = 20, _macdiff = 20); /** * Sets a boolean to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_bool searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _value Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_bool(_index, _offset, bool:_value, _linuxdiff = 20, _macdiff = 20); |
get_pdata_byte set_pdata_byte
|
⇅ Returns a byte value from an entity's private data./** * Returns a byte value from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_byte searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return A byte value is returned. */ native get_pdata_byte(_index, _offset, _linuxdiff = 20, _macdiff = 20); /** * Sets a byte value to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_byte searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _value Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_byte(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); |
get_pdata_short set_pdata_short
|
⇅ Returns a short value from an entity's private data./** * Returns a short value from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_short searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return A short value is returned. */ native get_pdata_short(_index, _offset, _linuxdiff = 20, _macdiff = 20); /** * Sets a short value to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_short searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _value Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_short(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); |
get_pdata_vector set_pdata_vector
|
⇅ Returns a vector from an entity's private data./** * Returns a vector from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_vector searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _output Vector returned by reference. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native get_pdata_vector(_index, _offset, Float:_output[3], _linuxdiff = 20, _macdiff = 20); /** * Sets a vector to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_vector searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _Offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _origin Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_vector(_index, _offset, Float:_origin[3], _linuxdiff = 20, _macdiff = 20); |
get_pdata_ehandle set_pdata_ehandle
|
⇅ Tries to retrieve an edict (entity encapsulation) pointer from an entity's private data./** * Tries to retrieve an edict (entity encapsulation) pointer from an entity's private data. * * This function is byte-addressable. Unlike get_pdata_int() which searches in byte increments of 4, * get_pdata_ehandle searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return -2 if an invalid entity was found. * -1 if an empty entity was found. * 0 if serialnumber is not matching. * Otherwise, an entity index is returned. */ native get_pdata_ehandle(_index, _offset, _linuxdiff = 20, _macdiff = 20); /** * Sets an edict (entity encapsulation) pointer to an entity's private data. * * This function is byte-addressable. Unlike set_pdata_int() which searches in byte increments of 4, * set_pdata_ehandle searches in increments of 1. * * _linuxdiff value is what to add to the _offset for linux servers. * _macdiff value is what to add to the _offset for os x servers. * * A log error is thrown on invalid _index and _Offset. * * @param _index Entity index. * @param _offset Offset to search. * @param _value Value to set. * @param _linuxdiff Linux difference. * @param _macdiff Mac OS X difference. * @return 1 on success. */ native set_pdata_ehandle(_index, _offset, _value, _linuxdiff = 20, _macdiff = 20); |
Gamerules
You have now the ability to manage a value using the gamerules object based off a class and member name.
The gamedata files are located in /data/gamedata/common.games/gamerules.games
directory.
foo() { new const score = get_gamerules_int("CHalfLifeMultiplay", "m_iNumCTWins"); }
Native | Description |
---|---|
get_gamerules_int set_gamerules_int
|
⇅ Retrieves an integer value from the gamerules object based off a class and member name./** * Retrieves an integer value from the gamerules object based off a class * and member name. * * @note This native is used to access the following (C++/engine) data types: * integer, boolean, short, character, pointer, structure, class, * stringint and function. Unsigned variants (if applicable) are supported * and will be converted automatically. * * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Integer value * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native any:get_gamerules_int(const class[], const member[], element = 0); /** * Sets an integer value to the gamerules objecta based off a class * and member name. * * @note This native is used to access the following (C++/engine) data types: * integer, boolean, short, character, pointer, stringint and function. * Unsigned variants (if applicable) are supported and will be converted * automatically. * * @param class Class name * @param member Member name * @param value Value to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native set_gamerules_int(const class[], const member[], any:value, element = 0); |
get_gamerules_float set_gamerules_float
|
⇅ Retrieves a float value from the gamerules object based off a class and member name./** * Retrieves a float value from the gamerules object based off a class * and member name. * * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Float value * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native Float:get_gamerules_float(const class[], const member[], element = 0); /** * Sets a float value to the gamerules object based off a class * and member name. * * @param class Class name * @param member Member name * @param value Value to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native set_gamerules_float(const class[], const member[], Float:value, element = 0); |
get_gamerules_vector set_gamerules_vector
|
⇅ Retrieves a vector from the gamerules object based off a class and member name./** * Retrieves a vector from the gamerules object based off a class and member name. * * @param class Class name * @param member Member name * @param value Vector buffer to store data in * @param element Element to retrieve (starting from 0) if member is an array * * @noreturn * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native get_gamerules_vector(const class[], const member[], Float:value[3], element = 0); /** * Sets a vector to the gamerules object based off a class and member name. * * @param class Class name * @param member Member name * @param value Vector to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native set_gamerules_vector(const class[], const member[], Float:value[3], element = 0); |
get_gamerules_entity set_gamerules_entity
|
⇅ Retrieves an entity index from the gamerules object based off a class and member name./** * Retrieves an entity index from the gamerules object based off a class * and member name. * * @note This native is used to access the following (C++/engine) data types: * classptr, entvars, edict and ehandle. * * @param class Class name * @param member Member name * @param element Element to retrieve (starting from 0) if member is an array * * @return Entity index if found, -1 otherwise * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native get_gamerules_entity(const class[], const member[], element = 0); /** * Sets an entity index to the gamerules object based off a class * and member name. * * @note This native is used to access the following (C++/engine) data types: * classptr, entvars, edict and ehandle. * @note Pass -1 as value to act as C++ NULL. * * @param class Class name * @param member Member name * @param value Entity index to set * @param element Element to set (starting from 0) if member is an array * * @noreturn * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native set_gamerules_entity(const class[], const member[], value, element = 0); |
get_gamerules_string set_gamerules_string
|
⇅ Retrieves a string from the gamerules object based off a class and member name./** * Retrieves a string from the gamerules object based off a class and member name. * * @note This native is used to access the following (C++/engine) data types: * string, stringptr. * * @param class Class name * @param member Member name * @param value Buffer to store data in * @param maxlen Maximum size of the buffer * @param element Element to retrieve (starting from 0) if member is an array * * @return Number of cells written to buffer * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native get_gamerules_string(const class[], const member[], value[], maxlen, element = 0); /** * Sets a string to the gamerules object based off a class and member name. * * @note This native is used to access the following (C++/engine) data types: * string, stringptr. * * @param class Class name * @param member Member name * @param value String to set * @param element Element to set (starting from 0) if member is an array * * @return Number of cells written to buffer * @error If member is empty, no offset is found or an invalid offset * is retrieved, or the data type does not match, an error will * be thrown. */ native set_gamerules_string(const class[], const member[], const value[], element = 0); |
get_gamerules_size
|
⇅ Retrieves the size of array of a gamerules class member./** * Retrieves the size of array of a gamerules class member. * * @param class Class name * @param member Member name * * @return Size of array (in elements), otherwise 1 if member is not an array * @error If either class or member is empty, no offset is found or an invalid * offset is retrieved, an error will be thrown. */ native get_gamerules_size(const class[], const member[]); |
find_gamerules_info
|
⇅ Finds a gamerules offset based off a class and member name./** * Finds a gamerules offset based off a class and member name. * * @param class Class name * @param member Member name * @param type Optional variable to store member type in (FIELD_* constants) * @param arraysize Optional variable to store array size in, if member is an array * @param unsigned Optional variable to store whether member is unsigned (short and char types only) * * @return Class member offset * @error If either class or member is empty, no offset is found or an invalid * offset is retrieved, an error will be thrown. */ native find_gamerules_info(const class[], const member[], &FieldType:type = FIELD_NONE, &arraysize = 0, &bool:unsigned = false); |
Stock | Description |
---|---|
get_field_basetype
|
⇅ Returns the data field base type based off a specific field type./** * Returns the data field base type based off a specific field type. * * @note From an AMXX plugin perspective, the (C++/engine) data types can be grouped * in five base types: integer, float, vector, entity and string. This stock is * essentially for convenience and debug purpose. * * @param type Class member type (FIELD_* constants) * @param type_name Optional buffer to store base type name in * @param maxlen Maximum size of the buffer * * @return Base field type (BASEFIELD_* constants) */ stock BaseFieldType:get_field_basetype(FieldType:type, type_name[] = "", maxlen = 0) { static const baseFieldTypeNames[BaseFieldType][] = { "none", "integer", "float", "vector", "entity", "string", }; new BaseFieldType:baseType = BASEFIELD_NONE; switch (type) { case FIELD_INTEGER, FIELD_STRINGINT, FIELD_SHORT , FIELD_CHARACTER, FIELD_CLASS , FIELD_STRUCTURE, FIELD_POINTER, FIELD_FUNCTION, FIELD_BOOLEAN: { baseType = BASEFIELD_INTEGER; } case FIELD_FLOAT: { baseType = BASEFIELD_FLOAT; } case FIELD_VECTOR: { baseType = BASEFIELD_VECTOR; } case FIELD_CLASSPTR, FIELD_ENTVARS, FIELD_EDICT, FIELD_EHANDLE: { baseType = BASEFIELD_ENTITY; } case FIELD_STRINGPTR, FIELD_STRING: { baseType = BASEFIELD_STRING; } } if (maxlen > 0) { copy(type_name, maxlen, baseFieldTypeNames[baseType]); } return baseType; } |
Miscellaneous
get/set_pdata_cbase
can now be used at map end whereas player's private datas are still valid.EngFunc_PlayBackEvent
can now receive a null invoker.KeyValueData
usage is now compatible with Hamsandwich module.
GeoIP
Library
The module uses the new MaxMind GeoIP2 API
. The relevant advantages are:
- Should be more precise
- Data is localized (current supported languages:
de
,en
,es
,fr
,ja
,ru
,pt-BR
,zh-CN
)
If you want further information, see What’s New in GeoIP2.
GeoIP.dat
is replaced with GeoLite2-Country.mmdb
(default, downloadable) or GeoLite2-City.mmdb
(downloadable).Command
A geoip
command is available for troubleshooting: geoip <command> [argument]
Command | Description |
---|---|
version
|
⇅ Displays the geoip database metadata such as the current loaded database and its version.Database metadata Node count: 3998109 Record size: 28 bits IP version: IPv6 Binary format: 2.0 Build epoch: 1501721259 (2017-08-03 00:47:39 UTC) Type: GeoLite2-City Languages: de en es fr ja pt-BR ru zh-CN Description: en: GeoLite2 City database |
dump <ip> [output file]
|
⇅ Dumps all data from an IP address formatted in a JSON-ish fashion. An output file is mod-based and if not provided, it will print in the console. /**
* GEOIP2 DATA EXAMPLE:
*
* {
* "city": {
* "confidence": 25,
* "geoname_id": 54321,
* "names": {
* "de": "Los Angeles",
* "en": "Los Angeles",
* "es": "Los Ýngeles",
* "fr": "Los Angeles",
* "ja": "ロサンゼルス市",
* "pt-BR": "Los Angeles",
* "ru": "Лоѝ-Ннджелеѝ",
* "zh-CN": "洛杉矶"
* }
* },
* "continent": {
* "code": "NA",
* "geoname_id": 123456,
* "names": {
* "de": "Nordamerika",
* "en": "North America",
* "es": "América del Norte",
* "fr": "Amérique du Nord",
* "ja": "北アメリカ",
* "pt-BR": "América do Norte",
* "ru": "Севернаѝ Нмерика",
* "zh-CN": "北美洲"
*
* }
* },
* "country": {
* "confidence": 75,
* "geoname_id": "6252001",
* "iso_code": "US",
* "names": {
* "de": "USA",
* "en": "United States",
* "es": "Estados Unidos",
* "fr": "États-Unis",
* "ja": "アメリカ坈衆国",
* "pt-BR": "Estados Unidos",
* "ru": "СШН",
* "zh-CN": "美国"
* }
* },
* "location": {
* "accuracy_radius": 20,
* "latitude": 37.6293,
* "longitude": -122.1163,
* "metro_code": 807,
* "time_zone": "America/Los_Angeles"
* },
* "postal": {
* "code": "90001",
* "confidence": 10
* },
* "registered_country": {
* "geoname_id": "6252001",
* "iso_code": "US",
* "names": {
* "de": "USA",
* "en": "United States",
* "es": "Estados Unidos",
* "fr": "États-Unis",
* "ja": "アメリカ坈衆国",
* "pt-BR": "Estados Unidos",
* "ru": "СШН",
* "zh-CN": "美国"
* }
* },
* "represented_country": {
* "geoname_id": "6252001",
* "iso_code": "US",
* "names": {
* "de": "USA",
* "en": "United States",
* "es": "Estados Unidos",
* "fr": "États-Unis",
* "ja": "アメリカ坈衆国",
* "pt-BR": "Estados Unidos",
* "ru": "СШН",
* "zh-CN": "美国"
* },
* "type": "military"
* },
* "subdivisions": [
* {
* "confidence": 50,
* "geoname_id": 5332921,
* "iso_code": "CA",
* "names": {
* "de": "Kalifornien",
* "en": "California",
* "es": "California",
* "fr": "Californie",
* "ja": "カリフォルニア",
* "ru": "Калифорниѝ",
* "zh-CN": "加州"
* }
* }
* ],
* "traits": {
* "autonomous_system_number": "1239",
* "autonomous_system_organization": "Linkem IR WiMax Network",
* "domain": "example.com",
* "is_anonymous_proxy": true,
* "is_transparent_proxy": true,
* "isp": "Linkem spa",
* "ip_address": "1.2.3.4",
* "organization": "Linkem IR WiMax Network",
* "user_type": "traveler",
* },
* "maxmind": {
* "queries_remaining": "54321"
* }
* }
*/ |
Deprecated natives
geoip_country
has been marked as deprecated in favor of geoip_country_ex
.
Hardcoding the maximum buffer length and returning "error" if nothing is found, were not quite the good idea.
New natives
The natives which can output localized data, have a new id
⇅ parameter in order to retrieve data into the player's language.
/**
* @param id An optional player's index in order to return the result
* in the player's language, if supported.
* -1: the default language, which is english.
* 0: the server language. You can use LANG_SERVER define.
* >=1: the player's language.
*/
Native | Database | Localized | Description |
---|---|---|---|
geoip_country_ex
|
Country / City | ✓ | ⇅ Looks up the full country name.
/** * Looks up the full country name for the given IP address. * * @param ip The IP address to lookup. * @param result The result of the geoip lookup. * @param len The maximum length of the result buffer. * @param id An optional player's index in order to return the result * in the player's language, if supported. * -1: the default language, which is english. * 0: the server language. You can use LANG_SERVER define. * >=1: the player's language. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_country_ex(const ip[], result[], len, id = -1); |
geoip_city
|
City | ✓ | ⇅ Returns the (localized) city name.
/** * Look up the full city name for the given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * @param result The result of the geoip look up. * @param len The maximum length of the result buffer. * @param id An optional player's index in order to return the result * in the player's language, if supported. * -1: the default language, which is english. * 0: the server language. You can use LANG_SERVER define. * >=1: the player's language. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_city(const ip[], result[], len, id = -1); |
geoip_continent_code
|
City | ✗ | ⇅ Returns the continent code. Example: EU (Europe)
/** * Looks up the continent code for a given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * @note The code can be retrieved as integer (See CONTINENT_* constants.) or string (2 characters). * @note Possible continent codes are AF, AN, AS, EU, NA, OC, SA for * Africa(1), Antarctica(2), Asia(3), Europe(4), North America(5), Oceania(6), South America(7). * * @param ip The IP address to look up. * @param result The result of the geoip look up. * * @return The continent id on successful lookup, 0 otherwise. */ enum Continent { CONTINENT_UNKNOWN = 0, CONTINENT_AFRICA, CONTINENT_ANTARCTICA, CONTINENT_ASIA, CONTINENT_EUROPE, CONTINENT_NORTH_AMERICA, CONTINENT_OCEANIA, CONTINENT_SOUTH_AMERICA, }; native Continent:geoip_continent_code(const ip[], result[3]); |
geoip_continent_name
|
City | ✓ | ⇅ Returns the (localized) continent name. Example: Europe
/** * Look up the full continent name for the given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * @param result The result of the geoip look up. * @param len The maximum length of the result buffer. * @param id An optional player's index in order to return the result * in the player's language, if supported. * -1: the default language, which is english. * 0: the server language. You can use LANG_SERVER define. * >=1: the player's language. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_continent_name(const ip[], result[], len, id = -1); |
geoip_region_code
|
City | ✗ | ⇅ Returns a region code.
/** * Look up the region/state code for the given IP address. * e.g. "US-OH", "DE-HH", IT-82, "FR-U", etc. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * @param result The result of the geoip look up. * @param len The maximum length of the result buffer. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_region_code(const ip[], result[], len); |
geoip_region_name
|
City | ✓ | ⇅ Returns a (localized) region name.
/** * Look up the full region/state name for the given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * @param result The result of the geoip look up. * @param len The maximum length of the result buffer. * @param id An optional player's index in order to return the result * in the player's language, if supported. * -1: the default language, which is english. * 0: the server language. You can use LANG_SERVER define. * >=1: the player's language. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_region_name(const ip[], result[], len, id = -1); |
geoip_latitude
|
City | ✗ | ⇅ Returns a city's latitude.
/** * Look up the city's latitude for the given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * * @return The result of the geoip look up, 0 if latitude is not found. */ native Float:geoip_latitude(const ip[]); |
geoip_longitude
|
City | ✗ | ⇅ Returns a city's longitude.
/** * Look up the city's longitude for the given IP address. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * * @return The result of the geoip look up, 0 if longitude is not found. */ native Float:geoip_longitude(const ip[]); |
geoip_distance
|
City | ✗ | ⇅ Calculates the distance between geographical coordinates.
/** * Calculate the distance between geographical coordinates, latitude and longitude. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param lat1 The first IP latitude. * @param lon1 The first IP longitude. * @param lat2 The second IP latitude. * @param lon2 The second IP longitude. * @param system The system of measurement, 0 = Metric(kilometers) or 1 = English(miles). * * @return The distance as result in specified system of measurement. */ #define SYSTEM_METRIC 0 // kilometers #define SYSTEM_IMPERIAL 1 // statute miles native Float:geoip_distance(Float:lat1, Float:lon1, Float:lat2, Float:lon2, system = SYSTEM_METRIC); |
geoip_timezone
|
City | ✗ | ⇅ Returns a full time zone. Example: Europe/Paris
/** * Look up the full time zone for the given IP address. * e.g. America/Los_Angeles, Europe/Paris. * * @note This native requires GeoIP City database, which can be retrieved from: * http://dev.maxmind.com/geoip/geoip2/geolite2/ (MaxMind DB binary) * * @param ip The IP address to look up. * @param result The result of the geoip look up. * @param len The maximum length of the result buffer. * * @return The result length on successful lookup, 0 otherwise. */ native geoip_timezone(const ip[], result[], len); |
Hamsandwich
Games support
The following games are now supported:
- Deathmatch Classic
- Adrenaline Gamer
- Opposing Forces
The following games have been updated to their latest version:
- Sven Coop v5.13
ItemInfo structure
A new set of functions have added to manage the {ItemInfo
structure.
Native | Description |
---|---|
CreateHamItemInfo
|
⇅ Creates an ItemInfo handle. The handle can be used in GetHamItemInfo and SetHamItemInfo ./** * Creates an ItemInfo handle. This value should never be altered. * The handle can be used in Get/SetHamItemInfo. * * NOTE: You must call FreeHamItemInfo() on every handle made with CreateHamItemInfo(). * * @return A new ItemInfo handle. */ native CreateHamItemInfo(); |
FreeHamItemInfo
|
⇅ Frees an ItemIndo handle created with CreateHamItemInfo ./** * Frees an ItemIndo handle created with CreateHamItemInfo(). Do not call * this more than once per handle, or on handles not created through * CreateHamItemInfo(). * * @param itemInfo_handle ItemInfo handle created via CreateHamItemInfo(). * @noreturn */ native FreeHamItemInfo(itemInfo_handle); |
GetHamItemInfo SetHamItemInfo
|
⇅ Gets a parameter on the fly of the current hook./** * Gets a parameter on the fly of the current hook. * Use this on parameters that are iteminfo result handles. * * @param iteminfo_handle Item info handle. * @param type Item info type. See HamItemInfo constants. */ native GetHamItemInfo(iteminfo_handle, HamItemInfo:type, any:...); /** * Sets a parameter on the fly of the current hook. * Use this on parameters that are iteminfo result handles. * * @param iteminfo_handle Item info handle. * @param type Item info type. See HamItemInfo_ constants. */ native SetHamItemInfo(iteminfo_handle, HamItemInfo:type, any:...); |
SetHamParamItemInfo
|
⇅ Sets a parameter on the fly of the current hook. This has no effect in post hooks./** * Sets a parameter on the fly of the current hook. This has no effect in post hooks. * Use this on parameters that are trace result handles. * * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". * @param iteminfo_handle The value to change it to. */ native SetHamParamItemInfo(which, iteminfo_handle); |
Miscellaneous
Native | Description |
---|---|
SetParamEntity2
|
⇅ Sets a parameter on the fly of the current hook. This has no effect in post hooks
Note: Same as
.SetHamParamEntity except the changes made by this native are reflected in the corresponding post forward./** * Sets a parameter on the fly of the current hook. This has no effect in post hooks. * Use this on parameters that are entities. * * @note Same as SetHamParamEntity except the changes made by this native are reflected in the corresponding post forward. * * @param which Which parameter to change. Starts at 1, and works up from the left to right. 1 is always "this". * @param value The value to change it to. */ native SetHamParamEntity2(which, value); |
Special bot
RegisterHam
has now the ability to register a bot without player
classname.
Native | Parameter | Description |
---|---|---|
RegisterHam
|
specialbot
|
⇅ Whether or not to enable support for bot without "player" classname./** * Hooks the virtual table for the specified entity class. * An example would be: RegisterHam(Ham_TakeDamage, "player", "player_hurt"); * Look at the Ham enum for parameter lists. * * @param function The function to hook. * @param EntityClass The entity classname to hook. * @param callback The forward to call. * @param post Whether or not to forward this in post. * @param specialbot Whether or not to enable support for bot without "player" classname. * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. */ native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0, bool:specialbot = false); |
For convenience a stock to make more intuitive registering a function on "player":
Stock | Description |
---|---|
RegisterHamPlayer
|
⇅ Hooks the virtual table for the player class./** * Hooks the virtual table for the player class. * An example would be: RegisterHam(Ham_TakeDamage, "player_hurt"); * Look at the Ham enum for parameter lists. * * @param function The function to hook. * @param callback The forward to call. * @param post Whether or not to forward this in post. * @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off. */ stock HamHook:RegisterHamPlayer(Ham:function, const Callback[], Post=0) { return RegisterHam(function, "player", Callback, Post, true); } |
Virtual function
A lot of missing virtual functions have been added for all games.
Some of the existing common functions have been renamed because they are mod-dependent.
Short overview:
- ⇅ Common
Ham_ChangeYaw Ham_HasHumanGibs Ham_HasAlienGibs Ham_FadeMonster Ham_GibMonster Ham_BecomeDead Ham_IRelationship Ham_PainSound Ham_ReportAIState Ham_MonsterInitDead Ham_Look Ham_BestVisibleEnemy Ham_FInViewCone Ham_FVecInViewCone Ham_GetDeathActivity Ham_Item_GetItemInfo
- ⇅ Common (not supported by Counter-Strike, The Specialists and Natural Selection mods)
Ham_RunAI, Ham_MonsterThink, Ham_MonsterInit, Ham_CheckLocalMove, Ham_Move, Ham_MoveExecute, Ham_ShouldAdvanceRoute, Ham_GetStoppedActivity, Ham_Stop, Ham_CheckRangeAttack1, Ham_CheckRangeAttack2, Ham_CheckMeleeAttack1, Ham_CheckMeleeAttack2, Ham_ScheduleChange, Ham_CanPlaySequence, Ham_CanPlaySentence, Ham_PlaySentence, Ham_PlayScriptedSentence, Ham_SentenceStop, Ham_GetIdealState, Ham_SetActivity, Ham_CheckEnemy, Ham_FTriangulate, Ham_SetYawSpeed, Ham_BuildNearestRoute, Ham_FindCover, Ham_CoverRadius, Ham_FCanCheckAttacks, Ham_CheckAmmo, Ham_IgnoreConditions, Ham_FValidateHintType, Ham_FCanActiveIdle, Ham_ISoundMask, Ham_HearingSensitivity, Ham_BarnacleVictimBitten, Ham_BarnacleVictimReleased, Ham_PrescheduleThink, Ham_DeathSound, Ham_AlertSound, Ham_IdleSound, Ham_StopFollowing,
- ⇅ Specific to Counter-Strike
Ham_CS_Item_IsWeapon Ham_CS_Weapon_SendWeaponAnim Ham_CS_Player_ResetMaxSpeed Ham_CS_Player_IsBot Ham_CS_Player_GetAutoaimVector Ham_CS_Player_Blind Ham_CS_Player_OnTouchingWeapon
- ⇅ Specific to Day Of Defeat
Ham_DOD_SetScriptReset Ham_DOD_Item_SpawnDeploy Ham_DOD_Item_SetDmgTime Ham_DOD_Item_DropGren Ham_DOD_Weapon_IsUseable Ham_DOD_Weapon_Aim Ham_DOD_Weapon_flAim Ham_DOD_Weapon_RemoveStamina Ham_DOD_Weapon_ChangeFOV Ham_DOD_Weapon_ZoomOut Ham_DOD_Weapon_ZoomIn Ham_DOD_Weapon_GetFOV Ham_DOD_Weapon_PlayerIsWaterSniping Ham_DOD_Weapon_UpdateZoomSpeed Ham_DOD_Weapon_Special Ham_DOD_Weapon_SendWeaponAnim
- ⇅ Specific to Earth's Special Forces
Ham_ESF_IsFighter Ham_ESF_IsBuddy Ham_ESF_EmitSound Ham_ESF_EmitNullSound Ham_ESF_IncreaseStrength Ham_ESF_IncreasePL Ham_ESF_SetPowerLevel Ham_ESF_SetMaxPowerLevel Ham_ESF_StopAniTrigger Ham_ESF_StopFly Ham_ESF_HideWeapon Ham_ESF_ClientRemoveWeapon Ham_ESF_SendClientsCustomModel Ham_ESF_CanTurbo Ham_ESF_CanPrimaryFire Ham_ESF_CanSecondaryFire Ham_ESF_CanStopFly Ham_ESF_CanBlock Ham_ESF_CanRaiseKi Ham_ESF_CanRaiseStamina Ham_ESF_CanTeleport Ham_ESF_CanStartFly Ham_ESF_CanStartPowerup Ham_ESF_CanJump Ham_ESF_CanWallJump Ham_ESF_IsSuperJump Ham_ESF_IsMoveBack Ham_ESF_CheckWallJump Ham_ESF_EnableWallJump Ham_ESF_DisableWallJump Ham_ESF_ResetWallJumpVars Ham_ESF_GetWallJumpAnim Ham_ESF_GetWallJumpAnim2 Ham_ESF_SetWallJumpAnimation Ham_ESF_SetFlyMoveType Ham_ESF_IsFlyMoveType Ham_ESF_IsWalkMoveType Ham_ESF_SetWalkMoveType Ham_ESF_DrawChargeBar Ham_ESF_StartBlock Ham_ESF_StopBlock Ham_ESF_StartFly Ham_ESF_GetMaxSpeed Ham_ESF_SetAnimation Ham_ESF_PlayAnimation Ham_ESF_GetMoveForward Ham_ESF_GetMoveRight Ham_ESF_GetMoveUp Ham_ESF_AddBlindFX Ham_ESF_RemoveBlindFX Ham_ESF_DisablePSBar Ham_ESF_AddBeamBoxCrosshair Ham_ESF_RemoveBeamBoxCrosshair Ham_ESF_DrawPSWinBonus Ham_ESF_DrawPSBar Ham_ESF_LockCrosshair Ham_ESF_UnLockCrosshair Ham_ESF_RotateCrosshair Ham_ESF_UnRotateCrosshair Ham_ESF_WaterMove Ham_ESF_CheckTimeBasedDamage Ham_ESF_DoesSecondaryAttack Ham_ESF_DoesPrimaryAttack Ham_ESF_RemoveSpecialModes Ham_ESF_StopTurbo Ham_ESF_TakeBean Ham_ESF_GetPowerLevel Ham_ESF_RemoveAllOtherWeapons Ham_ESF_StopSwoop Ham_ESF_SetDeathAnimation Ham_ESF_SetModel Ham_ESF_AddAttacks Ham_ESF_EmitClassSound Ham_ESF_CheckLightning Ham_ESF_FreezeControls Ham_ESF_UnFreezeControls Ham_ESF_UpdateKi Ham_ESF_UpdateHealth Ham_ESF_GetTeleportDir Ham_ESF_Weapon_HolsterWhenMeleed
- ⇅ Specific to Natural Selection
Ham_NS_SetBoneController Ham_NS_SaveDataForReset Ham_NS_GetHull Ham_NS_GetMaxWalkSpeed Ham_NS_SetTeamID Ham_NS_GetEffectivePlayerClass Ham_NS_GetAuthenticationMask Ham_NS_EffectivePlayerClassChanged Ham_NS_NeedsTeamUpdate Ham_NS_SendTeamUpdate Ham_NS_SendWeaponUpdate Ham_NS_InitPlayerFromSpawn Ham_NS_PackDeadPlayerItems Ham_NS_GetAnimationForActivity Ham_NS_StartObserver Ham_NS_StopObserver Ham_NS_GetAdrenalineFactor Ham_NS_GiveNamedItem Ham_NS_Suicide Ham_NS_GetCanUseWeapon Ham_NS_Weapon_GetWeaponPrimeTime Ham_NS_Weapon_PrimeWeapon Ham_NS_Weapon_GetIsWeaponPrimed Ham_NS_Weapon_GetIsWeaponPriming Ham_NS_Weapon_DefaultDeploy Ham_NS_Weapon_DefaultReload Ham_NS_Weapon_GetDeployTime
- ⇅ Specific to Sven Coop
Ham_SC_GetClassification Ham_SC_IsMonster Ham_SC_IsPhysX Ham_SC_IsPointEntity Ham_SC_IsMachine Ham_SC_CriticalRemove Ham_SC_UpdateOnRemove Ham_SC_FVisible Ham_SC_FVisibleFromPos Ham_SC_IsFacing Ham_SC_GetPointsForDamage Ham_SC_GetDamagePoints Ham_SC_OnCreate Ham_SC_OnDestroy Ham_SC_IsValidEntity Ham_SC_ShouldFadeOnDeath Ham_SC_SetupFriendly Ham_SC_ReviveThink Ham_SC_Revive Ham_SC_StartMonster Ham_SC_CheckRangeAttack1_Move Ham_SC_CheckRangeAttack2_Move Ham_SC_CheckMeleeAttack1_Move Ham_SC_CheckMeleeAttack2_Move Ham_SC_CheckTankUsage Ham_SC_SetGaitActivity Ham_SC_FTriangulate Ham_SC_FTriangulateExtension Ham_SC_FindCoverGrenade Ham_SC_FindCoverDistance Ham_SC_FindAttackPoint Ham_SC_FValidateCover Ham_SC_NoFriendlyFire1 Ham_SC_NoFriendlyFire2 Ham_SC_NoFriendlyFire3 Ham_SC_NoFriendlyFireToPos Ham_SC_FVisibleGunPos Ham_SC_FInBulletCone Ham_SC_CallGibMonster Ham_SC_CheckTimeBasedDamage Ham_SC_IsMoving Ham_SC_IsPlayerFollowing Ham_SC_StartPlayerFollowing Ham_SC_StopPlayerFollowing Ham_SC_UseSound Ham_SC_UnUseSound Ham_SC_RideMonster Ham_SC_CheckAndApplyGenericAttacks Ham_SC_CheckScared Ham_SC_CheckCreatureDanger Ham_SC_CheckFallDamage Ham_SC_CheckRevival Ham_SC_MedicCallSound Ham_SC_TakeHealth, Ham_SC_TakeArmor, Ham_SC_GiveAmmo, Ham_SC_CheckAttacker, Ham_SC_Player_IsConnected, Ham_SC_Player_MenuInputPerformed Ham_SC_Player_IsMenuInputDone Ham_SC_Player_SpecialSpawn Ham_SC_Player_IsValidInfoEntity Ham_SC_Player_LevelEnd Ham_SC_Player_VoteStarted Ham_SC_Player_CanStartNextVote Ham_SC_Player_Vote Ham_SC_Player_HasVoted Ham_SC_Player_ResetVote Ham_SC_Player_LastVoteInput Ham_SC_Player_InitVote Ham_SC_Player_TimeToStartNextVote Ham_SC_Player_ResetView Ham_SC_Player_GetLogFrequency Ham_SC_Player_LogPlayerStats Ham_SC_Player_DisableCollisionWithPlayer Ham_SC_Player_EnableCollisionWithPlayer Ham_SC_Player_CanTouchPlayer Ham_SC_Item_Materialize Ham_SC_Weapon_BulletAccuracy Ham_SC_Weapon_TertiaryAttack Ham_SC_Weapon_BurstSupplement Ham_SC_Weapon_GetP_Model Ham_SC_Weapon_GetW_Model Ham_SC_Weapon_GetV_Model Ham_SC_Weapon_PrecacheCustomModels Ham_SC_Weapon_IsMultiplayer Ham_SC_Weapon_FRunfuncs Ham_SC_Weapon_SetFOV Ham_SC_Weapon_FCanRun Ham_SC_Weapon_CustomDecrement Ham_SC_Weapon_SetV_Model Ham_SC_Weapon_SetP_Model Ham_SC_Weapon_ChangeWeaponSkin
- ⇅ Specific to Opposing Force
Ham_OPF_MySquadTalkMonsterPointer Ham_OPF_WeaponTimeBase
- ⇅ Specific to Team Fortress Classic
Ham_TFC_DB_GetItemName Ham_TFC_IsTriggered Ham_TFC_Killed Ham_TFC_RadiusDamage Ham_TFC_RadiusDamage2 Ham_TFC_Weapon_GetNextAttackDelay Ham_TFC_Weapon_SendWeaponAnim
- ⇅ Specific to The Specialists
Ham_TS_Weapon_AlternateAttack
See ham_const.inc for a full list (it starts from line 1182).
MySQL
Connectivity
To improve the connectivity, few features have been added.
Feature | Description |
---|---|
Reconnection | This has MySQL automatically reconnects if times out or loses connection through MYSQL_OPT_RECONNECT option.This should prevent "MySQL server has gone away" errors after a while. |
Timeout | This establishes a default read/write timeout for MySQL connectivity through MYSQL_OPT_CONNECT_TIMEOUT option. A new option to set globally the timeout (60s by default) can be found in core.ini ⇅ and a new amx_sql_timeout cvar in sql.cfg ⇅.
; MySQL default timeout mysql_timeout 60 amx_sql_timeout "60" |
Miscellaneous
- Module threading has been updated to be more responsive. This should help in reducing potential hang up in situations such as on change map or lost connection.
Character Set
Stock | Description |
---|---|
MySQL_SetCharset
|
⇅ Sets the character set of the current connection./** * Sets the character set of the current connection. * Like SET NAMES .. in mysql, but stays after connection problems. * * If a connection tuple is supplied, this should be called before SQL_Connect or SQL_ThreadQuery. * Also note the change will remain until you call this function with another value. * This native does nothing in SQLite. * * Example: "utf8", "latin1" * * @param h Database or connection tuple Handle. * @param charset The character set string to change to. * @return True, if character set was changed, false otherwise. */ native bool:SQL_SetCharset(Handle:h, const charset[]); |
RegEx
Library
The internal PCRE library version has been updated from 6.4
to 8.35
and has been compiled with UTF-8 support.
If you are interested, see the changelog.
Miscellaneous
regex_subtr
: The internal static buffer has been increased to match the same size as core and has been made UTF-8 safe.- The maximum number of sub-patterns has been increased from
30
to150
.
New Natives & Stocks
Native | Description |
---|---|
regex_compile_ex
|
⇅ Precompiles a regular expression.
Note:Similar as regex_compile/_c but with the differences that you can use directly PCRE_* ⇅ flags and the error parameter is an integer associated to REGEX_ERROR_* ⇅ flags./** * Precompiles a regular expression. * * @note Use this if you intend on using the same expression multiple times. * Pass the regex handle returned here to regex_match_c() to check for matches. * * @note Unlike regex_compile(), this allows you to use PCRE flags directly. * * @param pattern The regular expression pattern. * @param flags General flags for the regular expression, see PCRE_* defines. * @param error Error message encountered, if applicable. * @param maxLen Maximum string length of the error buffer. * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return Valid regex handle (> 0) on success, or -1 on failure. */ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Flags for compiling regex expressions. * These come directly from the pcre library and can be used in regex_compile_ex. */ #define PCRE_CASELESS 0x00000001 /* Ignore Case */ #define PCRE_MULTILINE 0x00000002 /* Multilines (affects ^ and $ so that they match the start/end of a line rather than matching the start/end of the string). */ #define PCRE_DOTALL 0x00000004 /* Single line (affects . so that it matches any character, even new line characters). */ #define PCRE_EXTENDED 0x00000008 /* Pattern extension (ignore whitespace and # comments). */ #define PCRE_ANCHORED 0x00000010 /* Force pattern anchoring. */ #define PCRE_DOLLAR_ENDONLY 0x00000020 /* $ not to match newline at end. */ #define PCRE_UNGREEDY 0x00000200 /* Invert greediness of quantifiers */ #define PCRE_NOTEMPTY 0x00000400 /* An empty string is not a valid match. */ #define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */ #define PCRE_NEVER_UTF 0x00010000 /* Lock out interpretation of the pattern as UTF-8 */ #define PCRE_FIRSTLINE 0x00040000 /* Force matching to be before newline */ #define PCRE_DUPNAMES 0x00080000 /* Allow duplicate names for subpattern */ #define PCRE_NEWLINE_CR 0x00100000 /* Specify that a newline is indicated by a single character CR ) */ #define PCRE_NEWLINE_CRLF 0x00300000 /* specify that a newline is indicated by the two-character CRLF sequence ) Overrides the default */ #define PCRE_NEWLINE_ANY 0x00400000 /* Specify that any Unicode newline sequence should be recognized. ) newline definition (LF) */ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Specify that any of CR, LF and CRLF sequences should be recognized ) */ #define PCRE_UCP 0x20000000 /* Change the way PCRE processes \B, \b, \D, \d, \S, \s, \W, \w etc. to use Unicode properties */ /** * Regex expression error codes. * This can be used with regex_compile_ex and regex_match_ex. */ enum /*RegexError*/ { REGEX_ERROR_NONE = 0, /* No error */ REGEX_ERROR_NOMATCH = -1, /* No match was found */ REGEX_ERROR_NULL = -2, REGEX_ERROR_BADOPTION = -3, REGEX_ERROR_BADMAGIC = -4, REGEX_ERROR_UNKNOWN_OPCODE = -5, REGEX_ERROR_NOMEMORY = -6, REGEX_ERROR_NOSUBSTRING = -7, REGEX_ERROR_MATCHLIMIT = -8, REGEX_ERROR_CALLOUT = -9, /* Never used by PCRE itself */ REGEX_ERROR_BADUTF8 = -10, REGEX_ERROR_BADUTF8_OFFSET = -11, REGEX_ERROR_PARTIAL = -12, REGEX_ERROR_BADPARTIAL = -13, REGEX_ERROR_INTERNAL = -14, REGEX_ERROR_BADCOUNT = -15, REGEX_ERROR_DFA_UITEM = -16, REGEX_ERROR_DFA_UCOND = -17, REGEX_ERROR_DFA_UMLIMIT = -18, REGEX_ERROR_DFA_WSSIZE = -19, REGEX_ERROR_DFA_RECURSE = -20, REGEX_ERROR_RECURSIONLIMIT = -21, REGEX_ERROR_NULLWSLIMIT = -22, /* No longer actually used */ REGEX_ERROR_BADNEWLINE = -23, REGEX_ERROR_BADOFFSET = -24, REGEX_ERROR_SHORTUTF8 = -25, REGEX_ERROR_RECURSELOOP = -26, REGEX_ERROR_JIT_STACKLIMIT = -27, REGEX_ERROR_BADMODE = -28, REGEX_ERROR_BADENDIANNESS = -29, REGEX_ERROR_DFA_BADRESTART = -30, REGEX_ERROR_JIT_BADOPTION = -31, REGEX_ERROR_BADLENGTH = -32, REGEX_ERROR_UNSET = -33 }; |
regex_match_all regex_match_all_c
|
⇅ Matches a string against a regular (compiled) expression pattern, matching all occurrences of the pattern inside the string.
Note:This is similar to using the g flag in perl regex./** * Matches a string against a regular expression pattern, matching all occurrences of the * pattern inside the string. This is similar to using the "g" flag in perl regex. * * @note If you intend on using the same regular expression pattern * multiple times, consider using regex_compile and regex_match_ex * instead of making this function reparse the expression each time. * * @note Flags only exist in amxmodx 1.8 and later. * * @note You should free the returned handle with regex_free() * when you are done extracting all of the substrings. * * @param string The string to check. * @param pattern The regular expression pattern. * @param flags General flags for the regular expression, see PCRE_* defines. * @param error Error message encountered, if applicable. * @param maxLen Maximum string length of the error buffer. * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) * -1 = Error in pattern (error message and offset # in error and ret) * 0 = No match. * >1 = Handle for getting more information (via regex_substr) */ native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Matches a string against a pre-compiled regular expression pattern, matching all * occurrences of the pattern inside the string. This is similar to using the "g" flag * in perl regex. * * @note You should free the returned handle (with regex_free()) * when you are done with this pattern. * * @note Use the regex handle passed to this function to extract * matches with regex_substr(). * * @param pattern The regular expression pattern. * @param string The string to check. * @param ret Error code, if applicable, or number of results on success. * See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) * 0 = No match. * >1 = Number of results. */ native regex_match_all_c(const string[], Regex:pattern, &ret = 0); |
Stock | Description |
---|---|
regex_match_simple
|
⇅ Matches a string against a regular expression pattern. Useful if you need to use the pattern one time.}/** * Matches a string against a regular expression pattern. * * @note If you intend on using the same regular expression pattern * multiple times, consider using compile regex_compile_ex and regex_match* * instead of making this function reparse the expression each time. * * @param str The string to check. * @param pattern The regular expression pattern. * @param flags General flags for the regular expression. * @param error Error message, if applicable. * @param maxLen Maximum length of the error buffer. * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) * -1 = Pattern error (error code is stored in ret) * 0 = No match. * >1 = Number of results. */ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0) { new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen, errcode); if (regex < REGEX_OK) { return -1; } new substrings = regex_match_c(str, regex); regex_free(regex); return substrings; } |
Socket
- WinSock is now update from version
1.1
to2.2
- Natives won't be registered if WinSock can't be started
Improvements
Native | Parameter | Description |
---|---|---|
⇅ socket_open
|
_flags
|
The following flags are additive:
/** * Error reporting */ #define SOCK_ERROR_OK 0 /* No error */ #define SOCK_ERROR_CREATE_SOCKET 1 /* Couldn't create a socket */ #define SOCK_ERROR_SERVER_UNKNOWN 2 /* Server unknown */ #define SOCK_ERROR_WHILE_CONNECTING 3 /* Error while connecting */ /** * Connects to the given node and service via TCP/UDP. * * @note There's 2 types of error reporting on this function that you can use. * @note Default error codes: * 0 - No error * 1 - Error while creating socket * 2 - Couldn't resolve hostname * 3 - Couldn't connect * @note New, more expressive libc error codes: * https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html * https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno.h * https://msdn.microsoft.com/en-us/library/ms740668.aspx * * @note The currently available bit flags are: * - SOCK_NON_BLOCKING : if set, the socket will be on nonblocking mode * - SOCK_LIBC_ERRORS : if set, the new libc errors will be seen on _error * * @note If no flags are set, the behaviour of the function will not be modified. * * @note Multiple flags may be set at the same time using the | operator. * For example, SOCK_NON_BLOCKING|SOCK_LIBC_ERRORS will create a nonblocking socket with libc error codes. * * @note If you're creating a new nonblocking socket, _hostname should be numeric to avoid calling the * name resolution server and potentially blocking the call. * * @note If the socket is a nonblocking one, the returned socket descriptor may be still connecting and * further checks should be done with socket_is_writable() before trying to send data. * * @param _hostname Node to connect to * @param _port Service to connect to * @param _protocol Connect via SOCKET_TCP or SOCKET_UDP * @param _error Set an error code here if anything goes wrong * @param _flags Optional bit flags that change the behaviour of the function * * @return A socket descriptor (a positive integer) on success * -1 on failure */ native socket_open(const _hostname[], _port, _protocol = SOCKET_TCP, &_error, _flags = 0); |
New natives
Native | Description |
---|---|
socket_is_writable
|
⇅ Checks if a socket is marked as writable./** * Checks if a socket is marked as writable. * * @note Use this function to check if a nonblocking socket is ready to be used. * @note Set _timeout to 0 avoid blocking the call. * @note An UDP socket is always writable. * * @param _socket Socket descriptor * @param _timeout Amount of time to block the call waiting for the socket to be marked as writable or * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) * * @return 1 if the socket is marked as writable * 0 otherwise */ native socket_is_writable(_socket, _timeout = 100000); |
socket_is_readable
|
⇅ Checks if a socket is marked as readable.
Note:This function is an alias of socket_change which is now deprecated./** * Checks if a socket is marked as readable. * * @note You can use this function to make sure there's something on the socket and avoid a blocking call. * @note Set _timeout to 0 avoid blocking the call. * @note A socket will become readable if there's any data or an EOF. * * @param _socket Socket descriptor * @param _timeout Amount of time to block the call waiting for the socket to be marked as readable or * for the timeout to expire, in µSeconds (1 sec = 1000000 µsec) * * @return 1 if the socket is marked as readable * 0 otherwise */ native socket_is_readable(_socket, _timeout = 100000); |
SQLite
Library
The SQLite library version has been updated from 3.3.13
to 3.8.8.2
.
If you are interested, see the changelog.
Character Set
Stock | Description |
---|---|
SQL_SetCharset
|
⇅ Sets the character set of the current connection./** * Sets the character set of the current connection. * Like SET NAMES .. in mysql, but stays after connection problems. * * If a connection tuple is supplied, this should be called before SQL_Connect or SQL_ThreadQuery. * Also note the change will remain until you call this function with another value. * This native does nothing in SQLite. * * Example: "utf8", "latin1" * * @param h Database or connection tuple Handle. * @param charset The character set string to change to. * @return True, if character set was changed, false otherwise. */ native bool:SQL_SetCharset(Handle:h, const charset[]); |
Miscellaneous
- The
queuetime
value is now properly passed to theSQL_ThreadQuery
callback.
New module
JSON
A JSON module is now part of the official AMX Mod X package.
Essentially:
- Supports decoding and encoding (also with pretty format)
- Relies on Parson, which is lighweight and simple JSON library written in C
- Supports dot notation (Values can be accessed by typing objectA.objectB.value)
- Allows us to iterate through arrays and objects
Native | Description |
---|---|
General | |
json_parse
|
⇅ Parses JSON string or a file that contains JSON./** * Parses JSON string or a file that contains JSON. * * @note Needs to be freed using json_free() native. * * @param string String to parse * @param is_file True to treat string param as filename, false otherwise * @param with_comments True if parsing JSON includes comments (it will ignore them), false otherwise * * @return JSON handle, Invalid_JSONValue if error occurred */ native JSON:json_parse(const string[], bool:is_file = false, bool:with_comments = false); |
json_equals
|
⇅ Checks if the first value is the same as the second one./** * Checks if the first value is the same as the second one. * * @param value1 JSON handle * @param value2 JSON handle * * @return True if they are the same, false otherwise * @error If passed value is not a valid handle */ native bool:json_equals(const JSON:value1, const JSON:value2); |
json_validate
|
⇅ Validates json by checking if object have identically named fields with matching types./** * Validates json by checking if object have identically named * fields with matching types. * * @note Schema {"name":"", "age":0} will validate * {"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"}, * but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}. * * @note In case of arrays, only first value in schema * is checked against all values in tested array. * * @note Empty objects ({}) validate all objects, * empty arrays ([]) validate all arrays, * null validates values of every type. * * @param schema JSON handle * @param value JSON handle * * @return True if passed value is valid, false otherwise * @error If a schema handle or value handle is invalid */ native bool:json_validate(const JSON:schema, const JSON:value); |
json_get_parent
|
⇅ Gets value's parent handle./** * Gets value's parent handle. * * @note Parent's handle needs to be freed using json_free() native. * * @param value JSON handle * * @return Parent's handle */ native JSON:json_get_parent(const JSON:value); |
json_get_type
|
⇅ Gets JSON type of passed value./** * Gets JSON type of passed value. * * @param value JSON handle * * @return JSON type (JSONType constants) * @error If a value handle is invalid */ native JSONType:json_get_type(const JSON:value); |
json_init_object json_init_array json_init_string json_init_number json_init_real json_init_bool
|
⇅ Inits an empty object./** * Inits an empty object. * * @note Needs to be freed using json_free() native. * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_object(); /** * Inits an empty array. * * @note Needs to be freed using json_free() native. * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_array(); /** * Inits string data. * * @note Needs to be freed using json_free() native. * * @param value String that the handle will be initialized with * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_string(const value[]); /** * Inits a number. * * @note Needs to be freed using json_free() native. * * @param value Integer number that the handle will be initialized with * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_number(value); /** * Inits a real number. * * @note Needs to be freed using json_free() native. * * @param value Real number that the handle will be initialized with * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_real(Float:value); /** * Inits a boolean value. * * @note Needs to be freed using json_free() native. * * @param value Boolean value that the handle will be initialized with * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_bool(bool:value); |
json_init_null
|
⇅ Inits a null./** * Inits a null. * * @note Needs to be freed using json_free() native. * * @return JSON handle, Invalid_JSON if error occurred */ native JSON:json_init_null(); |
json_deep_copy
|
⇅ Creates deep copy of passed value./** * Creates deep copy of passed value. * * @note Needs to be freed using json_free() native. * * @param value JSON handle to be copied * * @return JSON handle, Invalid_JSON if error occurred * @error If passed value is not a valid handle */ native JSON:json_deep_copy(const JSON:value); |
json_free
|
⇅ Frees handle./** * Frees handle. * * @param handle JSON handle to be freed * * @return True if succeed, false otherwise * @error If passed handle is not a valid handle */ native bool:json_free(&JSON:handle); |
json_get_string json_get_number json_get_real json_get_bool
|
⇅ Gets string data./** * Gets string data. * * @param value JSON handle * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * * @return The number of cells written to the buffer * @error If passed value is not a valid handle */ native json_get_string(const JSON:value, buffer[], maxlen); /** * Gets a number. * * @param value JSON handle * * @return Number * @error If passed value is not a valid handle */ native json_get_number(const JSON:value); /** * Gets a real number. * * @param value JSON handle * * @return Real number * @error If passed value is not a valid handle */ native Float:json_get_real(const JSON:value); /** * Gets a boolean value. * * @param value JSON handle * * @return Boolean value * @error If passed value is not a valid handle */ native bool:json_get_bool(const JSON:value); |
Array | |
json_array_get_value json_array_get_string json_array_get_number json_array_get_real json_array_get_bool json_array_get_count
|
⇅ Gets a value from the array./** * Gets a value from the array. * * @note Needs to be freed using json_free() native. * * @param array Array handle * @param index Position in the array (starting from 0) * * @return JSON handle, Invalid_JSON if error occurred * @error If passed handle is not a valid array */ native JSON:json_array_get_value(const JSON:array, index); /** * Gets string data from the array. * * @param array Array handle * @param index Position in the array (starting from 0) * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * * @return The number of cells written to the buffer * @error If passed handle is not a valid array */ native json_array_get_string(const JSON:array, index, buffer[], maxlen); /** * Gets a number from the array. * * @param array Array handle * @param index Position in the array (starting from 0) * * @return The number as integer * @error If passed handle is not a valid array */ native json_array_get_number(const JSON:array, index); /** * Gets a real number from the array. * * @param array Array handle * @param index Position in the array (starting from 0) * * @return The number as float * @error If passed handle is not a valid array */ native Float:json_array_get_real(const JSON:array, index); /** * Gets a boolean value from the array. * * @param array Array handle * @param index Position in the array (starting from 0) * * @return Boolean value * @error If passed handle is not a valid array */ native bool:json_array_get_bool(const JSON:array, index); /** * Gets count of the elements in the array. * * @param array Array handle * * @return Number of elements in the array * @error If passed handle is not a valid array */ native json_array_get_count(const JSON:array); |
json_array_replace_value json_array_replace_string json_array_replace_number json_array_replace_real json_array_replace_bool json_array_replace_null
|
⇅ Replaces an element in the array with value./** * Replaces an element in the array with value. * * @param array Array handle * @param index Position in the array to be replaced * @param value JSON handle to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_value(JSON:array, index, const JSON:value); /** * Replaces an element in the array with string data. * * @param array Array handle * @param index Position in the array to be replaced * @param string String to copy * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_string(JSON:array, index, const string[]); /** * Replaces an element in the array with number. * * @param array Array handle * @param index Position in the array to be replaced * @param number Number to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_number(JSON:array, index, number); /** * Replaces an element in the array with real number. * * @param array Array handle * @param index Position in the array to be replaced * @param number Real number to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_real(JSON:array, index, Float:number); /** * Replaces an element in the array with boolean value. * * @param array Array handle * @param index Position in the array to be replaced * @param boolean Boolean value to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_bool(JSON:array, index, bool:boolean); /** * Replaces an element in the array with null. * * @param array Array handle * @param index Position in the array to be replaced * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_replace_null(JSON:array, index); |
json_array_append_value json_array_append_string json_array_append_number json_array_append_real json_array_append_bool json_array_append_null
|
⇅ Appends a value in the array./** * Appends a value in the array. * * @param array Array handle * @param value JSON handle to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_value(JSON:array, const JSON:value); /** * Appends string data in the array. * * @param array Array handle * @param string String to copy * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_string(JSON:array, const string[]); /** * Appends a number in the array. * * @param array Array handle * @param number Number to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_number(JSON:array, number); /** * Appends a real number in the array. * * @param array Array handle * @param number Real number to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_real(JSON:array, Float:number); /** * Appends a boolean value in the array.Appends a boolean value in the array. * * @param array Array handle * @param boolean Boolean value to set * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_bool(JSON:array, bool:boolean); /** * Appends a null in the array. * * @param array Array handle * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_append_null(JSON:array); |
json_array_remove
|
⇅ Removes an element from the array./** * Removes an element from the array. * * @note Order of values in array may change during execution. * * @param array Array handle * @param index Position in the array (starting from 0) * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_remove(JSON:array, index); |
json_array_clear
|
⇅ Removes all elements from the array./** * Removes all elements from the array. * * @param array Array handle * * @return True if succeed, false otherwise * @error If passed handle is not a valid array */ native bool:json_array_clear(JSON:array); |
Object | |
json_object_get_value json_object_get_string json_object_get_number json_object_get_real json_object_get_bool
|
⇅ Gets a value from the object./** * Gets a value from the object. * * @note Needs to be freed using json_free() native. * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return JSON handle, Invalid_JSON if error occurred * @error If passed handle is not a valid object */ native JSON:json_object_get_value(const JSON:object, const name[], bool:dot_not = false); /** * Gets string data from the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * @param dot_not True to use dot notation, false to not * * @return The number of cells written to the buffer * @error If passed handle is not a valid object */ native json_object_get_string(const JSON:object, const name[], buffer[], maxlen, bool:dot_not = false); /** * Gets a number from the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return Number * @error If passed handle is not a valid object */ native json_object_get_number(const JSON:object, const name[], bool:dot_not = false); /** * Gets a real number from the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return Real number * @error If passed handle is not a valid object */ native Float:json_object_get_real(const JSON:object, const name[], bool:dot_not = false); /** * Gets a boolean value from the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return Boolean value * @error If passed handle is not a valid object */ native bool:json_object_get_bool(const JSON:object, const name[], bool:dot_not = false); |
json_object_get_count json_object_get_name
|
⇅ Gets count of the keys in the object./** * Gets count of the keys in the object. * * @param object Object handle * * @return Keys count * @error If passed handle is not a valid object */ native json_object_get_count(const JSON:object); /** * Gets name of the object's key. * * @param object Object handle * @param index Position from which get key name * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * * @return The number of cells written to the buffer * @error If passed handle is not a valid object */ native json_object_get_name(const JSON:object, index, buffer[], maxlen); |
json_object_get_value_at
|
⇅ Gets a value at the specified position from the object./** * Gets a value at the specified position from the object. * * @note Needs to be freed using json_free() native. * * @param object Object handle * @param index Position from which get key name * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * * @return The number of cells written to the buffer * @error If passed handle is not a valid object */ native JSON:json_object_get_value_at(const JSON:object, index); |
json_object_has_value
|
⇅ Checks if the object has a value with a specific name and type./** * Checks if the object has a value with a specific name and type. * * @param object Object handle * @param name Key name * @param type Type of value, if JSONError type will not be checked * @param dot_not True to use dot notation, false to not * * @return True if has, false if not * @error If passed handle is not a valid object */ native bool:json_object_has_value(const JSON:object, const name[], JSONType:type = JSONError, bool:dot_not = false); |
json_object_set_value json_object_set_string json_object_set_number json_object_set_real json_object_set_bool json_object_set_null
|
⇅ Sets a value in the object./** * Sets a value in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param value JSON handle to set * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_value(JSON:object, const name[], const JSON:value, bool:dot_not = false); /** * Sets string data in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param string String to copy * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_string(JSON:object, const name[], const string[], bool:dot_not = false); /** * Sets a number in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param number Number to set * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_number(JSON:object, const name[], number, bool:dot_not = false); /** * Sets a real number in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param number Real number to set * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_real(JSON:object, const name[], Float:number, bool:dot_not = false); /** * Sets a boolean value in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param boolean Boolean value to set * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_bool(JSON:object, const name[], bool:boolean, bool:dot_not = false); /** * Sets a null in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * @note It also removes the old value if any. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_set_null(JSON:object, const name[], bool:dot_not = false); |
json_object_remove
|
⇅ Removes a key and its value in the object./** * Removes a key and its value in the object. * * @note If dot notation is used some values may be inaccessible * because valid names in JSON can contain dots. * * @param object Object handle * @param name Key name * @param dot_not True to use dot notation, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_remove(JSON:object, const name[], bool:dot_not = false); |
json_object_clear
|
⇅ Removes all keys and their values in the object./** * Removes all keys and their values in the object. * * @param object Object handle * * @return True if succeed, false otherwise * @error If passed handle is not a valid object */ native bool:json_object_clear(JSON:object); |
Serialization | |
json_serial_size
|
⇅ Gets size of serialization./** * Gets size of serialization. * * @param value JSON handle * @param pretty True to count size for pretty format, false to not * @param null_byte True to include null byte, false to not * * @return Size of serialized string * @error If passed handle is not a valid value */ native json_serial_size(const JSON:value, bool:pretty = false, bool:null_byte = false); |
json_serial_to_string
|
⇅ Copies serialized string to the buffer./** * Copies serialized string to the buffer. * * @param value JSON handle * @param buffer Buffer to copy string to * @param maxlen Maximum size of the buffer * @param pretty True to format pretty JSON string, false to not * * @return The number of cells written to the buffer * @error If passed handle is not a valid value */ native json_serial_to_string(const JSON:value, buffer[], maxlen, bool:pretty = false); |
json_serial_to_file
|
⇅ Copies serialized string to the file./** * Copies serialized string to the file. * * @param value JSON handle * @param file Path to the file * @param pretty True to format pretty JSON string, false to not * * @return True if succeed, false otherwise * @error If passed handle is not a valid value */ native bool:json_serial_to_file(const JSON:value, const file[], bool:pretty = false); |
/* * JSON types */ enum JSONType { JSONError = -1, JSONNull = 1, JSONString = 2, JSONNumber = 3, JSONObject = 4, JSONArray = 5, JSONBoolean = 6 }; /* * JSON invalid handle */ enum JSON { Invalid_JSON = -1 } /** * Helper macros for checking type */ #define json_is_object(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONObject) #define json_is_array(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONArray) #define json_is_string(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONString) #define json_is_number(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONNumber) #define json_is_bool(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONBoolean) #define json_is_null(%1) (%1 != Invalid_JSON && json_get_type(%1) == JSONNull) #define json_is_true(%1) (%1 != Invalid_JSON && json_is_bool(%1) && json_get_bool(%1)) #define json_is_false(%1) (%1 != Invalid_JSON && json_is_bool(%1) && !json_get_bool(%1))