A SA-MP plugin enhancing the capabilities of the Pawn programming language
str_capacity
and str_reserve
to control the internal string's buffer capacity.str_addr
, var_addr
, and co. now have a second parameter specifying the particular behaviour of strings copied into the dynamic string via amx_SetString
. For example, amx_buffer_string_auto_fit
allows resizing the string to fit any number of characters inside. Note that not all SA-MP functions use amx_SetString
, so this will only improve interop with those that do.PAWNPLUS_NO_AMX_HOOKS
and PAWNPLUS_NO_FILE_HOOKS
. This allows circumventing Zeex/samp-plugin-crashdetect#127 if the server is launched via PAWNPLUS_NO_FILE_HOOKS=1 ./samp03svr
or
export PAWNPLUS_NO_FILE_HOOKS=1
./samp03svr
pawn_try_call_native_msg
and similar functions to correctly load their arguments.Unifies the result of str_addr
and str_buf_addr
(and var_addr
and var_buf_addr
) so that both functions can be used interchangeably. AmxStringBuffer:
(and str_buf_addr
) should still be used in situations where the implementation of the native is known to rely on the value being an actual address of the character data, but it is valid to be used instead of str_addr
in all situations.
Please note that the address returned from str_addr
and str_buf_addr
is meant to be temporary, only to be used for the native for which it was created for. and might become unusable sooner than in the previous versions.
pp_max_recursion
now returns the old value.
pp_toggle_exec_hook
can be used to disable modifications to the AMX execution, at the cost of making certain advanced features (like async, threading, custom callbacks etc.) unavailable.
task_
)await_str
(_s
) (#49 from @Se8870).handler_inverted_return
for compatibility with y_hooks (#52 from @AGraber).math_random_generator
(and the random_generator
enum) to set the concrete generator for random functions.pawn_on_init
and pawn_on_exit
use shorter names internally, allowing 7 characters longer identifiers. Scripts do not have to be recompiled.generator_mt19937
(used to be generator_minstd_rand0
on Linux). See this article for more details on how random number generation works between compilers. Consistency of generated numbers with previous versions is not guaranteed!
tagof
and sizeof
in parameters for older compilers with YSI (see #48).regex_cached_addr
verifies that the memory location was not destroyed.str_set_format
allows using the target string during the formatting before it is replaced.amx_FindPublic
hook to hide new callbacks from amx_NumPublics
called inside the original function.amx_Exec
has null retval
. (#53 from @AGraber).Note: Starting from this release, the "-static" binary is compiled on a different machine than before and may not work on old systems.
str_register_format
and str_get_format_tag
functions and the tag_op_format
tag operation. More here.str_val_*
functions have a new format
string parameter to use the format operation instead of string conversion. The value corresponds to a format specifier in str_format
.{
, }
) in str_format
may be followed by a format specifier like an argument substitution.tag_set_op_expr
to allow handling a tag operation with an expression.regex_start_at_pos
to treat the pos
argument as an absolute start of the string (for ^
).pp_daytime
to obtain the time of day in milliseconds.d
format selector does not necessarily imply signed integer conversion when applied on tagged values, only "decimal", meaning it can be used on Float:
and unsigned:
.str_format
and similar functions treat a sole "%s"
format string specially and do not use a tag operation, primarily to speed-up the case of appending a single string via str_append_format
.unit:
in the include. This does not denote an actual tag, only that the function always returns 1 (or raises an error on failure).task_set_error
raises an error when used with a non-error code.var_delete
raises an error when used on an invalid variant reference.CreateFileW
in addition to CreateFileA
to accomodate for different host environments. It is now also restricted to .amx
files. This could affect plugins that use CreateFileA
to open a file, then close the file and expect the file to be immediately available with CreateFileW
again, or that use CreateFileW
to open a file, close it and then try to open it in another thread. The lifetime of all prolonged handles still ends with the next tick, and now also when an AMX is fully loaded.ConstStringTag:
is used instead of StringTag:
in a couple of places.regex_cached_addr
is used on a dynamic string.tag_uid_amx_guard
to the include.tag_call_op
now also supports tag_op_handle
.iter_set_*
is now regarded as cell-returning in metadata.amx_commit
(thanks @GermanAizek).CreateFileA
/fopen
, fixing crashes on some platforms.expr_parse
supports hex escape sequences for producing any character cell via its numeric value. The syntax is \xXX
or \uXXXXXXXX
.false
is returned.pp_module_name
fixed for Linux.Additions:
map_new
and pool_new
allow specifying the ordered state at creation.bool:stay
parameter for iter_erase
specifying the iterator shouldn't move to the next element. Usable in loops. New iter_empty
function, also usable via operator!
.var_iter
accepts count like in iter_repeat
. handle_iter
added.Fixes:
math_try_round
, math_try_floor
, math_try_ceiling
, and math_try_truncate
for when the result might not fit in a 32-bit integer.PP_ALL_TAGS
.start
parameter in str_get
is actually used.*_delete_deep
is called on an ordered pool.list_sort_expr
added for sorting lists based on an expression.math_random_seed
added to configure the random generator; the initial seed is also different each time.pawn_add_filter
pushes the addresses of arguments directly if possible.expr_parse
.async
pseudo-attribute for functions using the async pattern (together with return async
).await
macro has an alternative definition supporting multiline expression, but requires additional configuration for all tags (enabled via PP_MULTILINE_AWAIT
).await_arr
and await_var
added.{…}
is used in str_format
and it doesn't correspond to a color code or a parameter selector, it is parsed and executed as a piece of code.%f
in str_format
accepts a width parameter.str_append_format
added.pawn_create_callback
can be used to create a new callback/public function and attach it to the current script. The function consists of an expression that is executed every time the public function is called._pp@on_init@
will be called first before every other function, when the script is loaded. Any function whose name starts with _pp@on_exit@
will be called last after all other functions, when the script is unloaded. Macros pawn_on_init
and pawn_on_exit
can be used for easy creation of these functions.pp_public_min_index
or pp_use_funcidx
. Callback handlers can be registered for negative indices.pawn_register_callback
or pawn_add_hook
) now accept v
, h
, and x
as new types of values. v
corresponds to a Variant:
argument which is copied to the closure and loaded when it is restored, h
corresponds to a Handle:
argument which is prolonged by the closure (so the underlying object is not destroyed) and whose value is loaded when the closure is restored, and x
corresponds to an Expression:
argument containing an expression which is executed every time the argument is restored.pp_on_error
is only called for a native called directly by the script. Errors in internally called natives are handled or propagated by the code that called them. pawn_try_call_native
never invokes pp_on_error
.signed:
and unsigned:
values can raise an error.collect
operation is now correctly called in some places.reset_stk
and reset_hea
are now used to correctly restore the original values of stk
and hea
, fixing a memory leak that happened when a public function with parameters was stored (because the parameters were not taken into account when stk
was restored).signed:
and unsigned:
subtraction fixed.new val1 = 5, val2 = 10;
print_s(str_format("the sum of {val1} and {val2} is {val1 + val2}"));
new Map:m = map_new();
map_add(m, 1, 10);
map_add(m, 2, 21);
map_add(m, 3, 30);
map_add(m, 4, 41);
map_add(m, 5, 50);
map_remove_if(m, expr_parse("10*$key != $value")); //removes 2 and 4
static Expression:expr;
if(!expr)
{
expr = expr_parse("$value*$value");
amx_guard(expr);
}
pawn_on_init[callback1]
{
new id = pawn_create_callback("OnPlayerConnect", expr_const(0));
pawn_register_callback(amx_encode_public(id), "MyOnPlayerConnect");
}