├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.MD
├── include
└── timerfix.inc
├── lib
└── sdk
│ ├── amx
│ ├── amx.h
│ ├── amx2.h
│ ├── getch.c
│ ├── getch.h
│ └── sclinux.h
│ ├── amxplugin.cpp
│ ├── amxplugin2.cpp
│ └── plugincommon.h
├── pawn.json
├── src
├── CFreeSlotManager.h
├── COSTime.cpp
├── COSTime.h
├── CServerHooks.cpp
├── CServerHooks.h
├── CSingleton.h
├── CStorage.cpp
├── CStorage.h
├── CTimer.cpp
├── CTimer.h
├── CTimerManager.cpp
├── CTimerManager.h
├── exports.def
├── natives.cpp
├── natives.h
├── plugin.cpp
└── plugin.h
└── tests
└── receiving_error.pwn
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8.4)
2 | project(timerfix)
3 |
4 | if (CMAKE_VERSION VERSION_GREATER 3.1.3)
5 | cmake_policy(SET CMP0054 NEW)
6 | endif ()
7 |
8 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
9 | if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
10 | message(FATAL_ERROR "Building for Windows requires -A Win32 flag. (cmake ./ -A Win32)")
11 | endif()
12 |
13 | add_definitions (-DWIN32 -D_WIN32 -D__STDC__)
14 |
15 | file(GLOB TIMERFIX_SRC
16 | ${CMAKE_CURRENT_SOURCE_DIR}/src/exports.def
17 | )
18 |
19 | set (CMAKE_C_FLAGS "/Zp1 /W4 /MT")
20 | set (CMAKE_CXX_FLAGS "/Zp1 /W4 /EHsc /MT")
21 | set (CMAKE_SHARED_LINKER_FLAGS "/NOLOGO /MACHINE:X86")
22 |
23 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
24 |
25 | add_definitions (-DLINUX)
26 | set(LINKER_FLAGS "-m32 -shared -O3 -static-libstdc++")
27 |
28 | set(CMAKE_C_FLAGS "-m32 -O3 -w -Ilib")
29 | set(CMAKE_CXX_FLAGS "-m32 -O3 -w -Ilib -std=c++14")
30 | set(CMAKE_SHARED_LINKER_FLAGS ${LINKER_FLAGS})
31 |
32 | set(CMAKE_CXX_COMPILER "/usr/bin/g++")
33 | set(CMAKE_C_COMPILER "/usr/bin/gcc")
34 | set(CMAKE_SHARED_LIBRARY_PREFIX "")
35 |
36 | else ()
37 | message(FATAL_ERROR "Sorry, but Timer Fix building supports only MSVC++ and GNU compilers")
38 | endif()
39 |
40 | include_directories (
41 | ${CMAKE_CURRENT_SOURCE_DIR}/src
42 | ${CMAKE_CURRENT_SOURCE_DIR}/lib
43 | )
44 |
45 | file(GLOB TIMERFIX_SRC
46 | ${TIMERFIX_SRC}
47 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
48 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h
49 | )
50 | source_group("" FILES ${FCNPC_SRC})
51 |
52 | file(GLOB SDK_SRC
53 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/sdk/amx/*.h
54 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/sdk/*.cpp
55 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/sdk/amx/*.h
56 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/sdk/amx/*.c
57 | )
58 | source_group(${LIBRARY_GROUP}SDK FILES ${SDK_SRC})
59 |
60 | add_library (${PROJECT_NAME} SHARED ${TIMERFIX_SRC}
61 | ${SDK_SRC})
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Kash Cherry
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # Timer-Fix-plugin
2 | This plugin makes timers more accurate. [Topic](https://forum.sa-mp.com/showthread.php?t=650736).
3 |
This plugin is no longer supported.
4 |
Previous versions on the Releases page might have problems and bugs, use at your own risk.
5 |
6 | ## Usage
7 | Plugin uses default SA-MP natives so you don't have to change your code. Example:
8 | ```Pawn
9 | #include
10 |
11 | forward Function();
12 | public Function()
13 | {
14 | printf("Function called after 1 second.");
15 | }
16 |
17 | forward FunctionWithArguments(number);
18 | public FunctionWithArguments(number)
19 | {
20 | printf("Function called after 2 seconds. Number: %d", number);
21 | }
22 |
23 | main()
24 | {
25 | SetTimer("Function", 1000, false);
26 | SetTimerEx("FunctionWithArguments", 2000, false, "d", 10);
27 | }
28 | ```
29 |
30 | ## Natives
31 | ```Pawn
32 | native SetCustomTimer(const funcname[], interval, delay, count);
33 | ```
34 | Replacement for a standart native function that includes additional parameters.
35 | * delay - the delay before the timer starts.
36 | * count - count of executions.
37 |
38 | **Note:** if you want timer to repeat put -1 instead of `count`.
39 | Example: `SetCustomTimer("Test", 1000, 500, -1);`
40 |
41 | ```Pawn
42 | native SetCustomTimerEx(const funcname[], interval, delay, count, const format[], {Float,_}:...);
43 | ```
44 | The same function but with argument passing.
45 | **Note:** if you want timer to repeat put -1 instead of `count`.
46 | Example: `SetCustomTimerEx("Test", 1000, 500, -1, "i", 1);`
47 |
48 | ```Pawn
49 | native PauseTimer(timerid);
50 | ```
51 | Stops the timer but doesn't delete it.
52 |
Use the ContinueTimer() to start it again.
53 | * Note: the callback will be executed after the time remaining before the call.
54 |
55 | ```Pawn
56 | native ContinueTimer(timerid);
57 | ```
58 | Continues the timer after pausing.
59 |
60 | ```Pawn
61 | native AddTimerHandler(timerid, handler[]);
62 | ```
63 | Adds the custom callback for the timer.
64 |
For example:
65 | ```pawn
66 | new a = SetTimer("function_1");
67 | AddTimerHandler(a, "function_2");
68 | ```
69 | The timer will execute both callbacks.
70 |
71 | * Note: arguments will be passed to both functions.
72 |
73 | ```Pawn
74 | native RemoveTimerHandler(timerid, handler[]);
75 | ```
76 | Removes the added handler.
77 |
78 | Another natives.
79 | ```Pawn
80 | native KillAllTimers();
81 | native IsValidTimer(timerid);
82 | native GetTimerInterval(timerid);
83 | native SetTimerInterval(timerid, interval);
84 | native GetTimerRemainingTime(timerid);
85 | native GetCountOfRunningTimers();
86 | ```
87 |
88 | ## Building
89 | Build a shared library is provided for only two platforms.
90 |
91 | ### Windows
92 | 1. First of all you should download [CMake](https://cmake.org) from the official site.
93 | 2. Then clone this repository or download source code from the [Releases page](https://github.com/KashCherry/Timer-Fix-plugin/releases).
94 | 3. Generate project with CMake for MSVC.
95 | 4. Build generated project (Don't forget to change configuration to Release Win32).
96 |
97 | ### Linux
98 | 1. Install everything you need to build a library (if not installed)
99 | ```
100 | // Ubuntu, Debian, etc
101 | apt-get install cmake
102 | apt-get install git
103 | apt-get install gcc-multilib g++-multilib
104 |
105 | // CentOS
106 | yum install cmake
107 | yum install git
108 | yum install gcc-multilib g++-multilib
109 | ```
110 | 2. Clone this repository
111 | ```
112 | git clone --recursive https://github.com/KashCherry/Timer-Fix-plugin
113 | ```
114 | 3. Generate project with CMake in this folder or create other one
115 | ```
116 | mkdir build && cd build && cmake ..
117 | ```
118 | 4. Build generated project with make
119 | ```
120 | make
121 | ```
122 |
123 | ## License
124 | Licensed under MIT License. Learn more about it [here](https://github.com/KashCherry/Timer-Fix-plugin/blob/master/LICENSE).
125 |
--------------------------------------------------------------------------------
/include/timerfix.inc:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #if defined _timerfix_kashcherry_included
6 | #endinput
7 | #endif
8 | #define _timerfix_kashcherry_included
9 | // -----------------------------------------------------------------------------------
10 | #define INVALID_TIMER_ID (0)
11 | // -----------------------------------------------------------------------------------
12 |
13 | /*
14 | * Replacement for a standart native function that includes additional parameters.
15 | * delay - the delay before the timer starts.
16 | * count - count of executions.
17 | */
18 | native SetCustomTimer(const funcname[], interval, delay, count);
19 |
20 | /*
21 | * The same function but with argument passing.
22 | */
23 | native SetCustomTimerEx(const funcname[], interval, delay, count, const format[], {Float,_}:...);
24 | native KillAllTimers();
25 | native IsValidTimer(timerid);
26 | native GetTimerInterval(timerid);
27 | native SetTimerInterval(timerid, interval);
28 | native GetTimerRemainingTime(timerid);
29 | native GetCountOfRunningTimers();
30 |
31 | /*
32 | * Stops the timer but doesn't delete it.
33 | * Use the ContinueTimer() to start it again.
34 | * Note: the callback will be executed after the time remaining before the call.
35 | */
36 | native PauseTimer(timerid);
37 |
38 | /*
39 | * Continues the timer after pausing.
40 | */
41 | native ContinueTimer(timerid);
42 | /*
43 | * Adds the custom callback for timer.
44 | * For example:
45 | * new a = SetTimer("function_1");
46 | * AddTimerHandler(a, "function_2");
47 | * The timer will execute both callbacks.
48 | *
49 | * Note: arguments will also be passed to both functions.
50 | */
51 | native AddTimerHandler(timerid, handler[]);
52 | /*
53 | * Removes the added handler.
54 | */
55 | native RemoveTimerHandler(timerid, handler[]);
56 |
--------------------------------------------------------------------------------
/lib/sdk/amx/amx.h:
--------------------------------------------------------------------------------
1 | /* Pawn Abstract Machine (for the Pawn language)
2 | *
3 | * Copyright (c) ITB CompuPhase, 1997-2005
4 | *
5 | * This software is provided "as-is", without any express or implied warranty.
6 | * In no event will the authors be held liable for any damages arising from
7 | * the use of this software.
8 | *
9 | * Permission is granted to anyone to use this software for any purpose,
10 | * including commercial applications, and to alter it and redistribute it
11 | * freely, subject to the following restrictions:
12 | *
13 | * 1. The origin of this software must not be misrepresented; you must not
14 | * claim that you wrote the original software. If you use this software in
15 | * a product, an acknowledgment in the product documentation would be
16 | * appreciated but is not required.
17 | * 2. Altered source versions must be plainly marked as such, and must not be
18 | * misrepresented as being the original software.
19 | * 3. This notice may not be removed or altered from any source distribution.
20 | *
21 | * Version: $Id: amx.h,v 1.5 2006/03/26 16:56:15 spookie Exp $
22 | */
23 |
24 | #if defined FREEBSD && !defined __FreeBSD__
25 | #define __FreeBSD__
26 | #endif
27 | #if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
28 | #include "sclinux.h"
29 | #endif
30 |
31 | #include
32 |
33 | #ifndef AMX_H_INCLUDED
34 | #define AMX_H_INCLUDED
35 | #define HAVE_STDINT_H
36 | #if defined HAVE_STDINT_H
37 | #include
38 | #else
39 | #if defined __LCC__ || defined __DMC__ || defined LINUX
40 | #if defined HAVE_INTTYPES_H
41 | #include
42 | #else
43 | #include
44 | #endif
45 | #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
46 | /* The ISO C99 defines the int16_t and int_32t types. If the compiler got
47 | * here, these types are probably undefined.
48 | */
49 | #if defined __MACH__
50 | #include
51 | typedef unsigned short int uint16_t;
52 | typedef unsigned long int uint32_t;
53 | #elif defined __FreeBSD__
54 | #include
55 | #else
56 | typedef short int int16_t;
57 | typedef unsigned short int uint16_t;
58 | #if defined SN_TARGET_PS2
59 | typedef int int32_t;
60 | typedef unsigned int uint32_t;
61 | #else
62 | typedef long int int32_t;
63 | typedef unsigned long int uint32_t;
64 | #endif
65 | #if defined __WIN32__ || defined _WIN32 || defined WIN32
66 | typedef __int64 int64_t;
67 | typedef unsigned __int64 uint64_t;
68 | #define HAVE_I64
69 | #elif defined __GNUC__
70 | typedef long long int64_t;
71 | typedef unsigned long long uint64_t;
72 | #define HAVE_I64
73 | #endif
74 | #endif
75 | #endif
76 | #define HAVE_STDINT_H
77 | #endif
78 | #if defined _LP64 || defined WIN64 || defined _WIN64
79 | #if !defined __64BIT__
80 | #define __64BIT__
81 | #endif
82 | #endif
83 |
84 | #include
85 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
86 | #if !defined alloca
87 | #define alloca(n) _alloca(n)
88 | #endif
89 | #endif
90 |
91 | #if !defined arraysize
92 | #define arraysize(array) (sizeof(array) / sizeof((array)[0]))
93 | #endif
94 |
95 | #ifdef __cplusplus
96 | extern "C" {
97 | #endif
98 |
99 | #if defined PAWN_DLL
100 | #if !defined AMX_NATIVE_CALL
101 | #define AMX_NATIVE_CALL __stdcall
102 | #endif
103 | #if !defined AMXAPI
104 | #define AMXAPI __stdcall
105 | #endif
106 | #endif
107 |
108 | /* calling convention for native functions */
109 | #if !defined AMX_NATIVE_CALL
110 | #define AMX_NATIVE_CALL
111 | #endif
112 | /* calling convention for all interface functions and callback functions */
113 | #if !defined AMXAPI
114 | #if defined STDECL
115 | #define AMXAPI __stdcall
116 | #elif defined CDECL
117 | #define AMXAPI __cdecl
118 | #elif defined GCC_HASCLASSVISIBILITY
119 | #define AMXAPI __attribute__ ((visibility("default")))
120 | #else
121 | #define AMXAPI
122 | #endif
123 | #endif
124 | #if !defined AMXEXPORT
125 | #define AMXEXPORT
126 | #endif
127 |
128 | /* File format version Required AMX version
129 | * 0 (original version) 0
130 | * 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
131 | * 2 (compressed files) 2
132 | * 3 (public variables) 2
133 | * 4 (opcodes SWAP.pri/alt and PUSHADDR) 4
134 | * 5 (tagnames table) 4
135 | * 6 (reformatted header) 6
136 | * 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
137 | * 8 (opcode STMT, renewed debug interface) 8
138 | */
139 | #define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
140 | #define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
141 | #define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
142 |
143 | #if !defined PAWN_CELL_SIZE
144 | #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
145 | #endif
146 | #if PAWN_CELL_SIZE==16
147 | typedef uint16_t ucell;
148 | typedef int16_t cell;
149 | #elif PAWN_CELL_SIZE==32
150 | typedef uint32_t ucell;
151 | typedef int32_t cell;
152 | #elif PAWN_CELL_SIZE==64
153 | typedef uint64_t ucell;
154 | typedef int64_t cell;
155 | #else
156 | #error Unsupported cell size (PAWN_CELL_SIZE)
157 | #endif
158 |
159 | #define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
160 | #define UNLIMITED (~1u >> 1)
161 |
162 | struct tagAMX;
163 | typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
164 | typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
165 | cell *result, cell *params);
166 | typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
167 | #if !defined _FAR
168 | #define _FAR
169 | #endif
170 |
171 | #if defined _MSC_VER
172 | #pragma warning(disable:4103) /* disable warning message 4103 that complains
173 | * about pragma pack in a header file */
174 | #pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
175 | #endif
176 |
177 | /* Some compilers do not support the #pragma align, which should be fine. Some
178 | * compilers give a warning on unknown #pragmas, which is not so fine...
179 | */
180 | #if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
181 | #define AMX_NO_ALIGN
182 | #endif
183 |
184 | #if defined __GNUC__
185 | #define PACKED __attribute__((packed))
186 | #else
187 | #define PACKED
188 | #endif
189 |
190 | #if !defined AMX_NO_ALIGN
191 | #if defined LINUX || defined __FreeBSD__
192 | #pragma pack(1) /* structures must be packed (byte-aligned) */
193 | #elif defined MACOS && defined __MWERKS__
194 | #pragma options align=mac68k
195 | #else
196 | #pragma pack(push)
197 | #pragma pack(1) /* structures must be packed (byte-aligned) */
198 | #if defined __TURBOC__
199 | #pragma option -a- /* "pack" pragma for older Borland compilers */
200 | #endif
201 | #endif
202 | #endif
203 |
204 | typedef struct tagAMX_NATIVE_INFO {
205 | const char _FAR *name PACKED;
206 | AMX_NATIVE func PACKED;
207 | } PACKED AMX_NATIVE_INFO;
208 |
209 | #define AMX_USERNUM 4
210 | #define sEXPMAX 19 /* maximum name length for file version <= 6 */
211 | #define sNAMEMAX 31 /* maximum name length of symbol name */
212 |
213 | typedef struct tagAMX_FUNCSTUB {
214 | ucell address PACKED;
215 | char name[sEXPMAX+1] PACKED;
216 | } PACKED AMX_FUNCSTUB;
217 |
218 | typedef struct tagFUNCSTUBNT {
219 | ucell address PACKED;
220 | uint32_t nameofs PACKED;
221 | } PACKED AMX_FUNCSTUBNT;
222 |
223 | /* The AMX structure is the internal structure for many functions. Not all
224 | * fields are valid at all times; many fields are cached in local variables.
225 | */
226 | typedef struct tagAMX {
227 | unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
228 | unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
229 | AMX_CALLBACK callback PACKED;
230 | AMX_DEBUG debug PACKED; /* debug callback */
231 | /* for external functions a few registers must be accessible from the outside */
232 | cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
233 | cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
234 | cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
235 | cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
236 | cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
237 | cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
238 | int flags PACKED; /* current status, see amx_Flags() */
239 | /* user data */
240 | long usertags[AMX_USERNUM] PACKED;
241 | void _FAR *userdata[AMX_USERNUM] PACKED;
242 | /* native functions can raise an error */
243 | int error PACKED;
244 | /* passing parameters requires a "count" field */
245 | int paramcount;
246 | /* the sleep opcode needs to store the full AMX status */
247 | cell pri PACKED;
248 | cell alt PACKED;
249 | cell reset_stk PACKED;
250 | cell reset_hea PACKED;
251 | cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
252 | #if defined JIT
253 | /* support variables for the JIT */
254 | int reloc_size PACKED; /* required temporary buffer for relocations */
255 | long code_size PACKED; /* estimated memory footprint of the native code */
256 | #endif
257 | } PACKED AMX;
258 |
259 | /* The AMX_HEADER structure is both the memory format as the file format. The
260 | * structure is used internaly.
261 | */
262 | typedef struct tagAMX_HEADER {
263 | int32_t size PACKED; /* size of the "file" */
264 | uint16_t magic PACKED; /* signature */
265 | char file_version PACKED; /* file format version */
266 | char amx_version PACKED; /* required version of the AMX */
267 | int16_t flags PACKED;
268 | int16_t defsize PACKED; /* size of a definition record */
269 | int32_t cod PACKED; /* initial value of COD - code block */
270 | int32_t dat PACKED; /* initial value of DAT - data block */
271 | int32_t hea PACKED; /* initial value of HEA - start of the heap */
272 | int32_t stp PACKED; /* initial value of STP - stack top */
273 | int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
274 | int32_t publics PACKED; /* offset to the "public functions" table */
275 | int32_t natives PACKED; /* offset to the "native functions" table */
276 | int32_t libraries PACKED; /* offset to the table of libraries */
277 | int32_t pubvars PACKED; /* the "public variables" table */
278 | int32_t tags PACKED; /* the "public tagnames" table */
279 | int32_t nametable PACKED; /* name table */
280 | } PACKED AMX_HEADER;
281 |
282 | #if PAWN_CELL_SIZE==16
283 | #define AMX_MAGIC 0xf1e2
284 | #elif PAWN_CELL_SIZE==32
285 | #define AMX_MAGIC 0xf1e0
286 | #elif PAWN_CELL_SIZE==64
287 | #define AMX_MAGIC 0xf1e1
288 | #endif
289 |
290 | enum {
291 | AMX_ERR_NONE,
292 | /* reserve the first 15 error codes for exit codes of the abstract machine */
293 | AMX_ERR_EXIT, /* forced exit */
294 | AMX_ERR_ASSERT, /* assertion failed */
295 | AMX_ERR_STACKERR, /* stack/heap collision */
296 | AMX_ERR_BOUNDS, /* index out of bounds */
297 | AMX_ERR_MEMACCESS, /* invalid memory access */
298 | AMX_ERR_INVINSTR, /* invalid instruction */
299 | AMX_ERR_STACKLOW, /* stack underflow */
300 | AMX_ERR_HEAPLOW, /* heap underflow */
301 | AMX_ERR_CALLBACK, /* no callback, or invalid callback */
302 | AMX_ERR_NATIVE, /* native function failed */
303 | AMX_ERR_DIVIDE, /* divide by zero */
304 | AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
305 | AMX_ERR_INVSTATE, /* invalid state for this access */
306 |
307 | AMX_ERR_MEMORY = 16, /* out of memory */
308 | AMX_ERR_FORMAT, /* invalid file format */
309 | AMX_ERR_VERSION, /* file is for a newer version of the AMX */
310 | AMX_ERR_NOTFOUND, /* function not found */
311 | AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
312 | AMX_ERR_DEBUG, /* debugger cannot run */
313 | AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
314 | AMX_ERR_USERDATA, /* unable to set user data field (table full) */
315 | AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
316 | AMX_ERR_PARAMS, /* parameter error */
317 | AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
318 | AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
319 | };
320 |
321 | /* AMX_FLAG_CHAR16 0x01 no longer used */
322 | #define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
323 | #define AMX_FLAG_COMPACT 0x04 /* compact encoding */
324 | #define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
325 | #define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
326 | #define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
327 | #define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
328 | #define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
329 | #define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
330 |
331 | #define AMX_EXEC_MAIN -1 /* start at program entry point */
332 | #define AMX_EXEC_CONT -2 /* continue from last address */
333 |
334 | #define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
335 |
336 | #if !defined AMX_COMPACTMARGIN
337 | #define AMX_COMPACTMARGIN 64
338 | #endif
339 |
340 | /* for native functions that use floating point parameters, the following
341 | * two macros are convenient for casting a "cell" into a "float" type _without_
342 | * changing the bit pattern
343 | */
344 | #if PAWN_CELL_SIZE==32
345 | #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
346 | #define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
347 | #elif PAWN_CELL_SIZE==64
348 | #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
349 | #define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
350 | #else
351 | #error Unsupported cell size
352 | #endif
353 |
354 | #define amx_StrParam(amx,param,result) \
355 | do { \
356 | cell *amx_cstr_; int amx_length_; \
357 | amx_GetAddr((amx), (param), &amx_cstr_); \
358 | amx_StrLen(amx_cstr_, &amx_length_); \
359 | if (amx_length_ > 0 && \
360 | ((result) = (char*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
361 | amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_ + 1); \
362 | else (result) = NULL; \
363 | } while (0)
364 |
365 | uint16_t * AMXAPI amx_Align16(uint16_t *v);
366 | uint32_t * AMXAPI amx_Align32(uint32_t *v);
367 | #if defined _I64_MAX || defined HAVE_I64
368 | uint64_t * AMXAPI amx_Align64(uint64_t *v);
369 | #endif
370 | int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
371 | int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
372 | int AMXAPI amx_Cleanup(AMX *amx);
373 | int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
374 | int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
375 | int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
376 | int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
377 | int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
378 | int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
379 | int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
380 | int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
381 | int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
382 | int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
383 | int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
384 | int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
385 | int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
386 | int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
387 | int AMXAPI amx_Init(AMX *amx, void *program);
388 | int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
389 | int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
390 | int AMXAPI amx_NameLength(AMX *amx, int *length);
391 | AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
392 | int AMXAPI amx_NumNatives(AMX *amx, int *number);
393 | int AMXAPI amx_NumPublics(AMX *amx, int *number);
394 | int AMXAPI amx_NumPubVars(AMX *amx, int *number);
395 | int AMXAPI amx_NumTags(AMX *amx, int *number);
396 | int AMXAPI amx_Push(AMX *amx, cell value);
397 | int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
398 | int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
399 | int AMXAPI amx_RaiseError(AMX *amx, int error);
400 | int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
401 | int AMXAPI amx_Release(AMX *amx, cell amx_addr);
402 | int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
403 | int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
404 | int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
405 | int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
406 | int AMXAPI amx_StrLen(const cell *cstring, int *length);
407 | int AMXAPI amx_UTF8Check(const char *string, int *length);
408 | int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
409 | int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
410 | int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
411 |
412 | #if PAWN_CELL_SIZE==16
413 | #define amx_AlignCell(v) amx_Align16(v)
414 | #elif PAWN_CELL_SIZE==32
415 | #define amx_AlignCell(v) amx_Align32(v)
416 | #elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
417 | #define amx_AlignCell(v) amx_Align64(v)
418 | #else
419 | #error Unsupported cell size
420 | #endif
421 |
422 | #define amx_RegisterFunc(amx, name, func) \
423 | amx_Register((amx), amx_NativeInfo((name),(func)), 1);
424 |
425 | #if !defined AMX_NO_ALIGN
426 | #if defined LINUX || defined __FreeBSD__
427 | #pragma pack() /* reset default packing */
428 | #elif defined MACOS && defined __MWERKS__
429 | #pragma options align=reset
430 | #else
431 | #pragma pack(pop) /* reset previous packing */
432 | #endif
433 | #endif
434 |
435 | #ifdef __cplusplus
436 | }
437 | #endif
438 |
439 | #endif /* AMX_H_INCLUDED */
440 |
--------------------------------------------------------------------------------
/lib/sdk/amx/amx2.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------
2 | //
3 | // SA-MP Multiplayer Modification For GTA:SA
4 | // Copyright 2013 SA-MP Team, Dan
5 | //
6 | //----------------------------------------------------------
7 |
8 | #pragma once
9 |
10 | //----------------------------------------------------------
11 |
12 | #include
13 |
14 | //----------------------------------------------------------
15 |
16 | #include "amx.h"
17 |
18 | //----------------------------------------------------------
19 |
20 | #define USENAMETABLE(hdr) \
21 | ((hdr)->defsize==sizeof(AMX_FUNCSTUBNT))
22 |
23 | #define NUMENTRIES(hdr,field,nextfield) \
24 | (unsigned)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize)
25 |
26 | #define GETENTRY(hdr,table,index) \
27 | (AMX_FUNCSTUB *)((unsigned char*)(hdr) + (unsigned)(hdr)->table + (unsigned)index*(hdr)->defsize)
28 |
29 | #define GETENTRYNAME(hdr,entry) \
30 | (USENAMETABLE(hdr) ? \
31 | (char *)((unsigned char*)(hdr) + (unsigned)((AMX_FUNCSTUBNT*)(entry))->nameofs) : \
32 | ((AMX_FUNCSTUB*)(entry))->name)
33 |
34 | //----------------------------------------------------------
35 |
36 | extern int AMXAPI amx_PushAddress(AMX *amx, cell *address);
37 | extern void AMXAPI amx_Redirect(AMX *amx, const char *from, ucell to, AMX_NATIVE *store);
38 | extern int AMXAPI amx_GetCString(AMX *amx, cell param, char *&dest);
39 | extern void AMXAPI amx_SetCString(AMX *amx, cell param, char *str, int len);
40 | extern std::string AMXAPI amx_GetCppString(AMX *amx, cell param);
41 | extern void AMXAPI amx_SetCppString(AMX *amx, cell param, std::string str, int len);
42 |
43 | //----------------------------------------------------------
44 | // EOF
--------------------------------------------------------------------------------
/lib/sdk/amx/getch.c:
--------------------------------------------------------------------------------
1 | /* Extremely inefficient but portable POSIX getch() */
2 | #ifndef WIN32
3 |
4 | #include
5 | #include
6 | #include /* for tcgetattr() and tcsetattr() */
7 | #include /* for read() */
8 | #include
9 | #include
10 | #include
11 | #include "getch.h"
12 |
13 | #ifndef STDIN_FILENO
14 | # define STDIN_FILENO 0
15 | #endif
16 |
17 | int
18 | getch (void)
19 | {
20 | struct termios save_termios;
21 | struct termios ios;
22 | int c = 0;
23 |
24 | if (!isatty (STDIN_FILENO))
25 | return EOF;
26 |
27 | if (tcgetattr (STDIN_FILENO, &save_termios) < 0)
28 | return EOF;
29 |
30 | ios = save_termios;
31 | ios.c_lflag &= ~(ICANON | ECHO | ISIG);
32 | ios.c_cc[VMIN] = 1; /* read() will return with one char */
33 | ios.c_cc[VTIME] = 0; /* read() blocks forever */
34 |
35 | if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0)
36 | return EOF;
37 |
38 | if (read (STDIN_FILENO, &c, 1) != 1)
39 | c = EOF;
40 |
41 | tcsetattr (STDIN_FILENO, TCSANOW, &save_termios);
42 |
43 | return c;
44 | }
45 |
46 | int
47 | kbhit (void)
48 | {
49 | struct termios save_termios;
50 | struct termios ios;
51 | fd_set inp;
52 | struct timeval timeout = {0, 0};
53 | int result;
54 |
55 | if (!isatty (STDIN_FILENO))
56 | return 0;
57 |
58 | if (tcgetattr (STDIN_FILENO, &save_termios) < 0)
59 | return 0;
60 |
61 | ios = save_termios;
62 | ios.c_lflag &= ~(ICANON | ECHO | ISIG);
63 | ios.c_cc[VMIN] = 1; /* read() will return with one char */
64 | ios.c_cc[VTIME] = 0; /* read() blocks forever */
65 |
66 | if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0)
67 | return 0;
68 |
69 | /* set up select() args */
70 | FD_ZERO(&inp);
71 | FD_SET(STDIN_FILENO, &inp);
72 |
73 | result = select (STDIN_FILENO+1, &inp, NULL, NULL, &timeout) == 1;
74 |
75 | tcsetattr (STDIN_FILENO, TCSANOW, &save_termios);
76 |
77 | return result;
78 | }
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/lib/sdk/amx/getch.h:
--------------------------------------------------------------------------------
1 | /* Extremely inefficient but portable POSIX getch(), see getch.c */
2 | #ifndef GETCH_H
3 | #define GETCH_H
4 |
5 | #if defined __cplusplus
6 | extern "C" {
7 | #endif
8 | int getch(void);
9 | int kbhit(void);
10 |
11 | #if defined __cplusplus
12 | }
13 | #endif
14 |
15 | #endif /* GETCH_H */
16 |
--------------------------------------------------------------------------------
/lib/sdk/amx/sclinux.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Things needed to compile under linux.
3 | *
4 | * Should be reworked totally to use GNU's 'configure'
5 | */
6 | #ifndef SCLINUX_H
7 | #define SCLINUX_H
8 |
9 | /* getchar() is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the
10 | * controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling
11 | * terminal tty's in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must
12 | * be put back correctly when the function ends. See GETCH.C for an implementation.
13 | *
14 | * For interactive use of SRUN/SDBG if would be much better to use GNU's readline package: the user would be able to
15 | * have a complete emacs/vi like line editing system.
16 | */
17 | #include "getch.h"
18 |
19 | #define stricmp(a,b) strcasecmp(a,b)
20 | #define strnicmp(a,b,c) strncasecmp(a,b,c)
21 |
22 | /*
23 | * WinWorld wants '\'. Unices do not.
24 | */
25 | #define DIRECTORY_SEP_CHAR '/'
26 | #define DIRECTORY_SEP_STR "/"
27 |
28 | /*
29 | * SC assumes that a computer is Little Endian unless told otherwise. It uses
30 | * (and defines) the macros BYTE_ORDER and BIG_ENDIAN.
31 | * For Linux, we must overrule these settings with those defined in glibc.
32 | */
33 | #if !defined __BYTE_ORDER
34 | # include
35 | #endif
36 |
37 | #if defined __OpenBSD__ || defined __FreeBSD__
38 | # define __BYTE_ORDER BYTE_ORDER
39 | # define __LITTLE_ENDIAN LITTLE_ENDIAN
40 | # define __BIG_ENDIAN BIG_ENDIAN
41 | #endif
42 |
43 | #if !defined __BYTE_ORDER
44 | # error "Can't figure computer byte order (__BYTE_ORDER macro not found)"
45 | #endif
46 |
47 | #endif /* SCLINUX_H */
48 |
--------------------------------------------------------------------------------
/lib/sdk/amxplugin.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------
2 | //
3 | // SA-MP Multiplayer Modification For GTA:SA
4 | // Copyright 2004-2009 SA-MP Team
5 | //
6 | //----------------------------------------------------------
7 | //
8 | // This provides an interface to call amx library functions
9 | // within samp-server.
10 | //
11 | //----------------------------------------------------------
12 |
13 | #include "amx/amx.h"
14 | #include "plugincommon.h"
15 |
16 | //----------------------------------------------------------
17 |
18 | void *pAMXFunctions;
19 |
20 | //----------------------------------------------------------
21 |
22 | #if (defined __WIN32__ || defined _WIN32 || defined WIN32) && defined _MSC_VER
23 |
24 | // Optimized Inline Assembly Thunks for MS VC++
25 |
26 | _declspec(naked) uint16_t *AMXAPI amx_Align16(uint16_t *v)
27 | {
28 | _asm mov eax, pAMXFunctions;
29 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Align16 * 4];
30 | }
31 |
32 | _declspec(naked) uint32_t *AMXAPI amx_Align32(uint32_t *v)
33 | {
34 | _asm mov eax, pAMXFunctions;
35 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Align32 * 4];
36 | }
37 |
38 | #if defined _I64_MAX || defined HAVE_I64
39 | _declspec(naked) uint64_t *AMXAPI amx_Align64(uint64_t *v)
40 | {
41 | _asm mov eax, pAMXFunctions;
42 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Align64 * 4];
43 | }
44 | #endif
45 |
46 | _declspec(naked) int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr)
47 | {
48 | _asm mov eax, pAMXFunctions;
49 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Allot * 4];
50 | }
51 |
52 | _declspec(naked) int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
53 | {
54 | _asm mov eax, pAMXFunctions;
55 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Callback * 4];
56 | }
57 |
58 | _declspec(naked) int AMXAPI amx_Cleanup(AMX *amx)
59 | {
60 | _asm mov eax, pAMXFunctions;
61 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Cleanup * 4];
62 | }
63 |
64 | _declspec(naked) int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data)
65 | {
66 | _asm mov eax, pAMXFunctions;
67 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Clone * 4];
68 | }
69 |
70 | _declspec(naked) int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
71 | {
72 | _asm mov eax, pAMXFunctions;
73 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Exec * 4];
74 | }
75 |
76 | _declspec(naked) int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
77 | {
78 | _asm mov eax, pAMXFunctions;
79 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_FindNative * 4];
80 | }
81 |
82 | _declspec(naked) int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index)
83 | {
84 | _asm mov eax, pAMXFunctions;
85 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_FindPublic * 4];
86 | }
87 |
88 | _declspec(naked) int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr)
89 | {
90 | _asm mov eax, pAMXFunctions;
91 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_FindPubVar * 4];
92 | }
93 |
94 | _declspec(naked) int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
95 | {
96 | _asm mov eax, pAMXFunctions;
97 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_FindTagId * 4];
98 | }
99 |
100 | _declspec(naked) int AMXAPI amx_Flags(AMX *amx,uint16_t *flags)
101 | {
102 | _asm mov eax, pAMXFunctions;
103 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Flags * 4];
104 | }
105 |
106 | _declspec(naked) int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr)
107 | {
108 | _asm mov eax, pAMXFunctions;
109 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetAddr * 4];
110 | }
111 |
112 | _declspec(naked) int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
113 | {
114 | _asm mov eax, pAMXFunctions;
115 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetNative * 4];
116 | }
117 |
118 | _declspec(naked) int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname)
119 | {
120 | _asm mov eax, pAMXFunctions;
121 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetPublic * 4];
122 | }
123 |
124 | _declspec(naked) int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr)
125 | {
126 | _asm mov eax, pAMXFunctions;
127 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetPubVar * 4];
128 | }
129 |
130 | _declspec(naked) int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size)
131 | {
132 | _asm mov eax, pAMXFunctions;
133 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetString * 4];
134 | }
135 |
136 | _declspec(naked) int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id)
137 | {
138 | _asm mov eax, pAMXFunctions;
139 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetTag * 4];
140 | }
141 |
142 | _declspec(naked) int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
143 | {
144 | _asm mov eax, pAMXFunctions;
145 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_GetUserData * 4];
146 | }
147 |
148 | _declspec(naked) int AMXAPI amx_Init(AMX *amx, void *program)
149 | {
150 | _asm mov eax, pAMXFunctions;
151 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Init * 4];
152 | }
153 |
154 | _declspec(naked) int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
155 | {
156 | _asm mov eax, pAMXFunctions;
157 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_InitJIT * 4];
158 | }
159 |
160 | _declspec(naked) int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap)
161 | {
162 | _asm mov eax, pAMXFunctions;
163 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_MemInfo * 4];
164 | }
165 |
166 | _declspec(naked) int AMXAPI amx_NameLength(AMX *amx, int *length)
167 | {
168 | _asm mov eax, pAMXFunctions;
169 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NameLength * 4];
170 | }
171 |
172 | _declspec(naked) AMX_NATIVE_INFO *AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func)
173 | {
174 | _asm mov eax, pAMXFunctions;
175 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NativeInfo * 4];
176 | }
177 |
178 | _declspec(naked) int AMXAPI amx_NumNatives(AMX *amx, int *number)
179 | {
180 | _asm mov eax, pAMXFunctions;
181 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NumNatives * 4];
182 | }
183 |
184 | _declspec(naked) int AMXAPI amx_NumPublics(AMX *amx, int *number)
185 | {
186 | _asm mov eax, pAMXFunctions;
187 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NumPublics * 4];
188 | }
189 |
190 | _declspec(naked) int AMXAPI amx_NumPubVars(AMX *amx, int *number)
191 | {
192 | _asm mov eax, pAMXFunctions;
193 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NumPubVars * 4];
194 | }
195 |
196 | _declspec(naked) int AMXAPI amx_NumTags(AMX *amx, int *number)
197 | {
198 | _asm mov eax, pAMXFunctions;
199 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_NumTags * 4];
200 | }
201 |
202 | _declspec(naked) int AMXAPI amx_Push(AMX *amx, cell value)
203 | {
204 | _asm mov eax, pAMXFunctions;
205 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Push * 4];
206 | }
207 |
208 | _declspec(naked) int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells)
209 | {
210 | _asm mov eax, pAMXFunctions;
211 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_PushArray * 4];
212 | }
213 |
214 | _declspec(naked) int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar)
215 | {
216 | _asm mov eax, pAMXFunctions;
217 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_PushString * 4];
218 | }
219 |
220 | _declspec(naked) int AMXAPI amx_RaiseError(AMX *amx, int error)
221 | {
222 | _asm mov eax, pAMXFunctions;
223 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_RaiseError * 4];
224 | }
225 |
226 | _declspec(naked) int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number)
227 | {
228 | _asm mov eax, pAMXFunctions;
229 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Register * 4];
230 | }
231 |
232 | _declspec(naked) int AMXAPI amx_Release(AMX *amx, cell amx_addr)
233 | {
234 | _asm mov eax, pAMXFunctions;
235 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_Release * 4];
236 | }
237 |
238 | _declspec(naked) int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback)
239 | {
240 | _asm mov eax, pAMXFunctions;
241 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_SetCallback * 4];
242 | }
243 |
244 | _declspec(naked) int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug)
245 | {
246 | _asm mov eax, pAMXFunctions;
247 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_SetDebugHook * 4];
248 | }
249 |
250 | _declspec(naked) int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size)
251 | {
252 | _asm mov eax, pAMXFunctions;
253 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_SetString * 4];
254 | }
255 |
256 | _declspec(naked) int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
257 | {
258 | _asm mov eax, pAMXFunctions;
259 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_SetUserData * 4];
260 | }
261 |
262 | _declspec(naked) int AMXAPI amx_StrLen(const cell *cstring, int *length)
263 | {
264 | _asm mov eax, pAMXFunctions;
265 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_StrLen * 4];
266 | }
267 |
268 | _declspec(naked) int AMXAPI amx_UTF8Check(const char *string, int *length)
269 | {
270 | _asm mov eax, pAMXFunctions;
271 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_UTF8Check * 4];
272 | }
273 |
274 | _declspec(naked) int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value)
275 | {
276 | _asm mov eax, pAMXFunctions;
277 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_UTF8Get * 4];
278 | }
279 |
280 | _declspec(naked) int AMXAPI amx_UTF8Len(const cell *cstr, int *length)
281 | {
282 | _asm mov eax, pAMXFunctions;
283 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_UTF8Len * 4];
284 | }
285 |
286 | _declspec(naked) int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value)
287 | {
288 | _asm mov eax, pAMXFunctions;
289 | _asm jmp dword ptr[eax + PLUGIN_AMX_EXPORT_UTF8Put * 4];
290 | }
291 |
292 | #else
293 |
294 | // Unoptimized Thunks (Linux/BSD/non MSVC++)
295 |
296 | typedef uint16_t * AMXAPI (*amx_Align16_t)(uint16_t *v);
297 | uint16_t * AMXAPI amx_Align16(uint16_t *v)
298 | {
299 | amx_Align16_t fn = ((amx_Align16_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align16];
300 | return fn(v);
301 | }
302 |
303 | typedef uint32_t * AMXAPI (*amx_Align32_t)(uint32_t *v);
304 | uint32_t * AMXAPI amx_Align32(uint32_t *v)
305 | {
306 | amx_Align32_t fn = ((amx_Align32_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align32];
307 | return fn(v);
308 | }
309 |
310 | #if defined _I64_MAX || defined HAVE_I64
311 | typedef uint64_t * AMXAPI (*amx_Align64_t)(uint64_t *v);
312 | uint64_t * AMXAPI amx_Align64(uint64_t *v)
313 | {
314 | amx_Align64_t fn = ((amx_Align64_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align64];
315 | return fn(v);
316 | }
317 | #endif
318 |
319 | typedef int AMXAPI (*amx_Allot_t)(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
320 | int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr)
321 | {
322 | amx_Allot_t fn = ((amx_Allot_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Allot];
323 | return fn(amx, cells, amx_addr, phys_addr);
324 | }
325 |
326 | typedef int AMXAPI (*amx_Callback_t)(AMX *amx, cell index, cell *result, cell *params);
327 | int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
328 | {
329 | amx_Callback_t fn = ((amx_Callback_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Callback];
330 | return fn(amx, index, result, params);
331 | }
332 |
333 | typedef int AMXAPI (*amx_Cleanup_t)(AMX *amx);
334 | int AMXAPI amx_Cleanup(AMX *amx)
335 | {
336 | amx_Cleanup_t fn = ((amx_Cleanup_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Cleanup];
337 | return fn(amx);
338 | }
339 |
340 | typedef int AMXAPI (*amx_Clone_t)(AMX *amxClone, AMX *amxSource, void *data);
341 | int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data)
342 | {
343 | amx_Clone_t fn = ((amx_Clone_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Clone];
344 | return fn(amxClone, amxSource, data);
345 | }
346 |
347 | typedef int AMXAPI (*amx_Exec_t)(AMX *amx, cell *retval, int index);
348 | int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
349 | {
350 | amx_Exec_t fn = ((amx_Exec_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec];
351 | return fn(amx, retval, index);
352 | }
353 |
354 | typedef int AMXAPI (*amx_FindNative_t)(AMX *amx, const char *name, int *index);
355 | int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
356 | {
357 | amx_FindNative_t fn = ((amx_FindNative_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_FindNative];
358 | return fn(amx, name, index);
359 | }
360 |
361 | typedef int AMXAPI (*amx_FindPublic_t)(AMX *amx, const char *funcname, int *index);
362 | int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index)
363 | {
364 | amx_FindPublic_t fn = ((amx_FindPublic_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_FindPublic];
365 | return fn(amx, funcname, index);
366 | }
367 |
368 | typedef int AMXAPI (*amx_FindPubVar_t)(AMX *amx, const char *varname, cell *amx_addr);
369 | int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr)
370 | {
371 | amx_FindPubVar_t fn = ((amx_FindPubVar_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_FindPubVar];
372 | return fn(amx, varname, amx_addr);
373 | }
374 |
375 | typedef int AMXAPI (*amx_FindTagId_t)(AMX *amx, cell tag_id, char *tagname);
376 | int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
377 | {
378 | amx_FindTagId_t fn = ((amx_FindTagId_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_FindTagId];
379 | return fn(amx, tag_id, tagname);
380 | }
381 |
382 | typedef int AMXAPI (*amx_Flags_t)(AMX *amx,uint16_t *flags);
383 | int AMXAPI amx_Flags(AMX *amx,uint16_t *flags)
384 | {
385 | amx_Flags_t fn = ((amx_Flags_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Flags];
386 | return fn(amx,flags);
387 | }
388 |
389 | typedef int AMXAPI (*amx_GetAddr_t)(AMX *amx,cell amx_addr,cell **phys_addr);
390 | int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr)
391 | {
392 | amx_GetAddr_t fn = ((amx_GetAddr_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetAddr];
393 | return fn(amx,amx_addr,phys_addr);
394 | }
395 |
396 | typedef int AMXAPI (*amx_GetNative_t)(AMX *amx, int index, char *funcname);
397 | int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
398 | {
399 | amx_GetNative_t fn = ((amx_GetNative_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetNative];
400 | return fn(amx, index, funcname);
401 | }
402 |
403 | typedef int AMXAPI (*amx_GetPublic_t)(AMX *amx, int index, char *funcname);
404 | int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname)
405 | {
406 | amx_GetPublic_t fn = ((amx_GetPublic_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetPublic];
407 | return fn(amx, index, funcname);
408 | }
409 |
410 | typedef int AMXAPI (*amx_GetPubVar_t)(AMX *amx, int index, char *varname, cell *amx_addr);
411 | int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr)
412 | {
413 | amx_GetPubVar_t fn = ((amx_GetPubVar_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetPubVar];
414 | return fn(amx, index, varname, amx_addr);
415 | }
416 |
417 | typedef int AMXAPI (*amx_GetString_t)(char *dest,const cell *source, int use_wchar, size_t size);
418 | int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size)
419 | {
420 | amx_GetString_t fn = ((amx_GetString_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetString];
421 | return fn(dest,source, use_wchar, size);
422 | }
423 |
424 | typedef int AMXAPI (*amx_GetTag_t)(AMX *amx, int index, char *tagname, cell *tag_id);
425 | int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id)
426 | {
427 | amx_GetTag_t fn = ((amx_GetTag_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetTag];
428 | return fn(amx, index, tagname, tag_id);
429 | }
430 |
431 | typedef int AMXAPI (*amx_GetUserData_t)(AMX *amx, long tag, void **ptr);
432 | int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
433 | {
434 | amx_GetUserData_t fn = ((amx_GetUserData_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_GetUserData];
435 | return fn(amx, tag, ptr);
436 | }
437 |
438 | typedef int AMXAPI (*amx_Init_t)(AMX *amx, void *program);
439 | int AMXAPI amx_Init(AMX *amx, void *program)
440 | {
441 | amx_Init_t fn = ((amx_Init_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Init];
442 | return fn(amx, program);
443 | }
444 |
445 | typedef int AMXAPI (*amx_InitJIT_t)(AMX *amx, void *reloc_table, void *native_code);
446 | int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
447 | {
448 | amx_InitJIT_t fn = ((amx_InitJIT_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_InitJIT];
449 | return fn(amx, reloc_table, native_code);
450 | }
451 |
452 | typedef int AMXAPI (*amx_MemInfo_t)(AMX *amx, long *codesize, long *datasize, long *stackheap);
453 | int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap)
454 | {
455 | amx_MemInfo_t fn = ((amx_MemInfo_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_MemInfo];
456 | return fn(amx, codesize, datasize, stackheap);
457 | }
458 |
459 | typedef int AMXAPI (*amx_NameLength_t)(AMX *amx, int *length);
460 | int AMXAPI amx_NameLength(AMX *amx, int *length)
461 | {
462 | amx_NameLength_t fn = ((amx_NameLength_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NameLength];
463 | return fn(amx, length);
464 | }
465 |
466 | typedef AMX_NATIVE_INFO * AMXAPI (*amx_NativeInfo_t)(const char *name, AMX_NATIVE func);
467 | AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func)
468 | {
469 | amx_NativeInfo_t fn = ((amx_NativeInfo_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NativeInfo];
470 | return fn(name, func);
471 | }
472 |
473 | typedef int AMXAPI (*amx_NumNatives_t)(AMX *amx, int *number);
474 | int AMXAPI amx_NumNatives(AMX *amx, int *number)
475 | {
476 | amx_NumNatives_t fn = ((amx_NumNatives_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NumNatives];
477 | return fn(amx, number);
478 | }
479 |
480 | typedef int AMXAPI (*amx_NumPublics_t)(AMX *amx, int *number);
481 | int AMXAPI amx_NumPublics(AMX *amx, int *number)
482 | {
483 | amx_NumPublics_t fn = ((amx_NumPublics_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NumPublics];
484 | return fn(amx, number);
485 | }
486 |
487 | typedef int AMXAPI (*amx_NumPubVars_t)(AMX *amx, int *number);
488 | int AMXAPI amx_NumPubVars(AMX *amx, int *number)
489 | {
490 | amx_NumPubVars_t fn = ((amx_NumPubVars_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NumPubVars];
491 | return fn(amx, number);
492 | }
493 |
494 | typedef int AMXAPI (*amx_NumTags_t)(AMX *amx, int *number);
495 | int AMXAPI amx_NumTags(AMX *amx, int *number)
496 | {
497 | amx_NumTags_t fn = ((amx_NumTags_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_NumTags];
498 | return fn(amx, number);
499 | }
500 |
501 | typedef int AMXAPI (*amx_Push_t)(AMX *amx, cell value);
502 | int AMXAPI amx_Push(AMX *amx, cell value)
503 | {
504 | amx_Push_t fn = ((amx_Push_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Push];
505 | return fn(amx, value);
506 | }
507 |
508 | typedef int AMXAPI (*amx_PushArray_t)(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
509 | int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells)
510 | {
511 | amx_PushArray_t fn = ((amx_PushArray_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_PushArray];
512 | return fn(amx, amx_addr, phys_addr, array, numcells);
513 | }
514 |
515 | typedef int AMXAPI (*amx_PushString_t)(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
516 | int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar)
517 | {
518 | amx_PushString_t fn = ((amx_PushString_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_PushString];
519 | return fn(amx, amx_addr, phys_addr, string, pack, use_wchar);
520 | }
521 |
522 | typedef int AMXAPI (*amx_RaiseError_t)(AMX *amx, int error);
523 | int AMXAPI amx_RaiseError(AMX *amx, int error)
524 | {
525 | amx_RaiseError_t fn = ((amx_RaiseError_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_RaiseError];
526 | return fn(amx, error);
527 | }
528 |
529 | typedef int AMXAPI (*amx_Register_t)(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
530 | int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number)
531 | {
532 | amx_Register_t fn = ((amx_Register_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Register];
533 | return fn(amx, nativelist, number);
534 | }
535 |
536 | typedef int AMXAPI (*amx_Release_t)(AMX *amx, cell amx_addr);
537 | int AMXAPI amx_Release(AMX *amx, cell amx_addr)
538 | {
539 | amx_Release_t fn = ((amx_Release_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_Release];
540 | return fn(amx, amx_addr);
541 | }
542 |
543 | typedef int AMXAPI (*amx_SetCallback_t)(AMX *amx, AMX_CALLBACK callback);
544 | int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback)
545 | {
546 | amx_SetCallback_t fn = ((amx_SetCallback_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_SetCallback];
547 | return fn(amx, callback);
548 | }
549 |
550 | typedef int AMXAPI (*amx_SetDebugHook_t)(AMX *amx, AMX_DEBUG debug);
551 | int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug)
552 | {
553 | amx_SetDebugHook_t fn = ((amx_SetDebugHook_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_SetDebugHook];
554 | return fn(amx, debug);
555 | }
556 |
557 | typedef int AMXAPI (*amx_SetString_t)(cell *dest, const char *source, int pack, int use_wchar, size_t size);
558 | int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size)
559 | {
560 | amx_SetString_t fn = ((amx_SetString_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_SetString];
561 | return fn(dest, source, pack, use_wchar, size);
562 | }
563 |
564 | typedef int AMXAPI (*amx_SetUserData_t)(AMX *amx, long tag, void *ptr);
565 | int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
566 | {
567 | amx_SetUserData_t fn = ((amx_SetUserData_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_SetUserData];
568 | return fn(amx, tag, ptr);
569 | }
570 |
571 | typedef int AMXAPI (*amx_StrLen_t)(const cell *cstring, int *length);
572 | int AMXAPI amx_StrLen(const cell *cstring, int *length)
573 | {
574 | amx_StrLen_t fn = ((amx_StrLen_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_StrLen];
575 | return fn(cstring, length);
576 | }
577 |
578 | typedef int AMXAPI (*amx_UTF8Check_t)(const char *string, int *length);
579 | int AMXAPI amx_UTF8Check(const char *string, int *length)
580 | {
581 | amx_UTF8Check_t fn = ((amx_UTF8Check_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_UTF8Check];
582 | return fn(string, length);
583 | }
584 |
585 | typedef int AMXAPI (*amx_UTF8Get_t)(const char *string, const char **endptr, cell *value);
586 | int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value)
587 | {
588 | amx_UTF8Get_t fn = ((amx_UTF8Get_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_UTF8Get];
589 | return fn(string, endptr, value);
590 | }
591 |
592 | typedef int AMXAPI (*amx_UTF8Len_t)(const cell *cstr, int *length);
593 | int AMXAPI amx_UTF8Len(const cell *cstr, int *length)
594 | {
595 | amx_UTF8Len_t fn = ((amx_UTF8Len_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_UTF8Len];
596 | return fn(cstr, length);
597 | }
598 |
599 | typedef int AMXAPI (*amx_UTF8Put_t)(char *string, char **endptr, int maxchars, cell value);
600 | int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value)
601 | {
602 | amx_UTF8Put_t fn = ((amx_UTF8Put_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_UTF8Put];
603 | return fn(string, endptr, maxchars, value);
604 | }
605 |
606 | #endif
607 |
608 | //----------------------------------------------------------
609 | // EOF
610 |
--------------------------------------------------------------------------------
/lib/sdk/amxplugin2.cpp:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------
2 | //
3 | // SA-MP Multiplayer Modification For GTA:SA
4 | // Copyright 2013 SA-MP Team, Dan
5 | //
6 | //----------------------------------------------------------
7 |
8 | #include
9 | #include
10 |
11 | //----------------------------------------------------------
12 |
13 | #include
14 |
15 | //----------------------------------------------------------
16 |
17 | #include "amx/amx2.h"
18 |
19 | //----------------------------------------------------------
20 |
21 | int AMXAPI amx_PushAddress(AMX *amx, cell *address) {
22 | AMX_HEADER *hdr;
23 | unsigned char *data;
24 | cell xaddr;
25 | /* reverse relocate the address */
26 | assert(amx != NULL);
27 | hdr = (AMX_HEADER *) amx->base;
28 | assert(hdr != NULL);
29 | assert(hdr->magic == AMX_MAGIC);
30 | data = (amx->data != NULL) ? amx->data : amx->base + (int) hdr->dat;
31 | xaddr = (cell) ((unsigned char*) address-data);
32 | if ((ucell) xaddr >= (ucell) amx->stp) {
33 | return AMX_ERR_MEMACCESS;
34 | }
35 | return amx_Push(amx,xaddr);
36 | }
37 |
38 | void AMXAPI amx_Redirect(AMX *amx, const char *from, ucell to, AMX_NATIVE *store) {
39 | AMX_HEADER *hdr = (AMX_HEADER*) amx->base;
40 | AMX_FUNCSTUB *func;
41 | for (int idx = 0, num = NUMENTRIES(hdr, natives, libraries); idx != num; ++idx) {
42 | func = GETENTRY(hdr, natives, idx);
43 | if (!strcmp(from, GETENTRYNAME(hdr, func))) {
44 | if (store) {
45 | *store = (AMX_NATIVE) func->address;
46 | }
47 | func->address = to;
48 | return;
49 | }
50 | }
51 | }
52 |
53 | int AMXAPI amx_GetCString(AMX *amx, cell param, char *&dest) {
54 | cell *ptr;
55 | amx_GetAddr(amx, param, &ptr);
56 | int len;
57 | amx_StrLen(ptr, &len);
58 | dest = (char*) malloc((len + 1) * sizeof(char));
59 | if (dest != NULL) {
60 | amx_GetString(dest, ptr, 0, UNLIMITED);
61 | dest[len] = 0;
62 | return len;
63 | }
64 | return 0;
65 | }
66 |
67 | void AMXAPI amx_SetCString(AMX *amx, cell param, char *str, int len) {
68 | cell *dest;
69 | amx_GetAddr(amx, param, &dest);
70 | amx_SetString(dest, str, 0, 0, len);
71 | }
72 |
73 | std::string AMXAPI amx_GetCppString(AMX *amx, cell param) {
74 | char *tmp;
75 | amx_StrParam(amx, param, tmp);
76 | if (tmp != NULL) {
77 | return tmp;
78 | }
79 | return "";
80 | }
81 |
82 | void AMXAPI amx_SetCppString(AMX *amx, cell param, std::string str, int len) {
83 | cell *dest;
84 | amx_GetAddr(amx, param, &dest);
85 | amx_SetString(dest, str.c_str(), 0, 0, len);
86 | }
87 |
88 | //----------------------------------------------------------
89 | // EOF
--------------------------------------------------------------------------------
/lib/sdk/plugincommon.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------
2 | //
3 | // SA-MP Multiplayer Modification For GTA:SA
4 | // Copyright 2004-2009 SA-MP Team
5 | //
6 | //----------------------------------------------------------
7 |
8 | #pragma once
9 |
10 | //----------------------------------------------------------
11 |
12 | #define SAMP_PLUGIN_VERSION 0x0200
13 |
14 | //----------------------------------------------------------
15 |
16 | #ifdef __cplusplus
17 | #define PLUGIN_EXTERN_C extern "C"
18 | #else
19 | #define PLUGIN_EXTERN_C
20 | #endif
21 |
22 | #if defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
23 | #ifndef __GNUC__
24 | #pragma message "Warning: Not using a GNU compiler."
25 | #endif
26 | #define PLUGIN_CALL
27 | #ifndef SAMPSVR
28 | // Compile code with -fvisibility=hidden to hide non-exported functions.
29 | #define PLUGIN_EXPORT PLUGIN_EXTERN_C __attribute__((visibility("default")))
30 | #else
31 | #define PLUGIN_EXPORT PLUGIN_EXTERN_C
32 | #endif
33 | #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
34 | #ifndef _MSC_VER
35 | #pragma message "Warning: Not using a VC++ compiler."
36 | #endif
37 | #define PLUGIN_CALL __stdcall
38 | #define PLUGIN_EXPORT PLUGIN_EXTERN_C
39 | #else
40 | #error "You must define one of WIN32, LINUX or FREEBSD"
41 | #endif
42 |
43 | //----------------------------------------------------------
44 |
45 | enum SUPPORTS_FLAGS
46 | {
47 | SUPPORTS_VERSION = SAMP_PLUGIN_VERSION,
48 | SUPPORTS_VERSION_MASK = 0xffff,
49 | SUPPORTS_AMX_NATIVES = 0x10000,
50 | SUPPORTS_PROCESS_TICK = 0x20000
51 | };
52 |
53 | //----------------------------------------------------------
54 |
55 | enum PLUGIN_DATA_TYPE
56 | {
57 | // For some debugging
58 | PLUGIN_DATA_LOGPRINTF = 0x00, // void (*logprintf)(char* format, ...)
59 |
60 | // AMX
61 | PLUGIN_DATA_AMX_EXPORTS = 0x10, // void* AmxFunctionTable[] (see PLUGIN_AMX_EXPORT)
62 | PLUGIN_DATA_CALLPUBLIC_FS = 0x11, // int (*AmxCallPublicFilterScript)(char *szFunctionName)
63 | PLUGIN_DATA_CALLPUBLIC_GM = 0x12, // int (*AmxCallPublicGameMode)(char *szFunctionName)
64 |
65 | };
66 |
67 | //----------------------------------------------------------
68 |
69 | enum PLUGIN_AMX_EXPORT
70 | {
71 | PLUGIN_AMX_EXPORT_Align16 = 0,
72 | PLUGIN_AMX_EXPORT_Align32 = 1,
73 | PLUGIN_AMX_EXPORT_Align64 = 2,
74 | PLUGIN_AMX_EXPORT_Allot = 3,
75 | PLUGIN_AMX_EXPORT_Callback = 4,
76 | PLUGIN_AMX_EXPORT_Cleanup = 5,
77 | PLUGIN_AMX_EXPORT_Clone = 6,
78 | PLUGIN_AMX_EXPORT_Exec = 7,
79 | PLUGIN_AMX_EXPORT_FindNative = 8,
80 | PLUGIN_AMX_EXPORT_FindPublic = 9,
81 | PLUGIN_AMX_EXPORT_FindPubVar = 10,
82 | PLUGIN_AMX_EXPORT_FindTagId = 11,
83 | PLUGIN_AMX_EXPORT_Flags = 12,
84 | PLUGIN_AMX_EXPORT_GetAddr = 13,
85 | PLUGIN_AMX_EXPORT_GetNative = 14,
86 | PLUGIN_AMX_EXPORT_GetPublic = 15,
87 | PLUGIN_AMX_EXPORT_GetPubVar = 16,
88 | PLUGIN_AMX_EXPORT_GetString = 17,
89 | PLUGIN_AMX_EXPORT_GetTag = 18,
90 | PLUGIN_AMX_EXPORT_GetUserData = 19,
91 | PLUGIN_AMX_EXPORT_Init = 20,
92 | PLUGIN_AMX_EXPORT_InitJIT = 21,
93 | PLUGIN_AMX_EXPORT_MemInfo = 22,
94 | PLUGIN_AMX_EXPORT_NameLength = 23,
95 | PLUGIN_AMX_EXPORT_NativeInfo = 24,
96 | PLUGIN_AMX_EXPORT_NumNatives = 25,
97 | PLUGIN_AMX_EXPORT_NumPublics = 26,
98 | PLUGIN_AMX_EXPORT_NumPubVars = 27,
99 | PLUGIN_AMX_EXPORT_NumTags = 28,
100 | PLUGIN_AMX_EXPORT_Push = 29,
101 | PLUGIN_AMX_EXPORT_PushArray = 30,
102 | PLUGIN_AMX_EXPORT_PushString = 31,
103 | PLUGIN_AMX_EXPORT_RaiseError = 32,
104 | PLUGIN_AMX_EXPORT_Register = 33,
105 | PLUGIN_AMX_EXPORT_Release = 34,
106 | PLUGIN_AMX_EXPORT_SetCallback = 35,
107 | PLUGIN_AMX_EXPORT_SetDebugHook = 36,
108 | PLUGIN_AMX_EXPORT_SetString = 37,
109 | PLUGIN_AMX_EXPORT_SetUserData = 38,
110 | PLUGIN_AMX_EXPORT_StrLen = 39,
111 | PLUGIN_AMX_EXPORT_UTF8Check = 40,
112 | PLUGIN_AMX_EXPORT_UTF8Get = 41,
113 | PLUGIN_AMX_EXPORT_UTF8Len = 42,
114 | PLUGIN_AMX_EXPORT_UTF8Put = 43,
115 | };
116 |
117 | //----------------------------------------------------------
118 | // EOF
119 |
--------------------------------------------------------------------------------
/pawn.json:
--------------------------------------------------------------------------------
1 | {
2 | "user": "KashCherry",
3 | "repo": "Timer-Fix-plugin",
4 | "resources": [
5 | {
6 | "name": "^timerfix-(.+)-win32.zip$",
7 | "platform": "windows",
8 | "archive": true,
9 | "includes": [""],
10 | "plugins": ["timerfix.dll"]
11 | },
12 | {
13 | "name": "^timerfix-(.+)-debian10.tar.gz$",
14 | "platform": "linux",
15 | "archive": true,
16 | "includes": [""],
17 | "plugins": ["timerfix.so"]
18 | }
19 | ],
20 | "runtime": {
21 | "plugins": ["KashCherry/Timer-Fix-plugin"]
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/CFreeSlotManager.h:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #pragma once
6 |
7 | #include "CSingleton.h"
8 | #include "plugin.h"
9 | #include
10 | #include
11 |
12 | class CFreeSlotManager : public CSingleton
13 | {
14 | private:
15 | std::queue m_queueFreeSlots;
16 | cell m_iHighestId;
17 |
18 | public:
19 | CFreeSlotManager()
20 | {
21 | m_iHighestId = 1;
22 | }
23 |
24 | ~CFreeSlotManager()
25 | {
26 | while (!m_queueFreeSlots.empty()) m_queueFreeSlots.pop();
27 | }
28 |
29 | cell GetId()
30 | {
31 | cell id = m_iHighestId;
32 | if (!m_queueFreeSlots.empty())
33 | {
34 | id = m_queueFreeSlots.front();
35 | m_queueFreeSlots.pop();
36 | }
37 | else
38 | {
39 | m_iHighestId++;
40 | }
41 | return id;
42 | }
43 |
44 | void Remove(cell id)
45 | {
46 | m_queueFreeSlots.push(id);
47 | }
48 | };
--------------------------------------------------------------------------------
/src/COSTime.cpp:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #include "COSTime.h"
6 |
7 | #ifdef _WIN32
8 | #include
9 | #else
10 | #include
11 | #include
12 | #endif
13 |
14 | uint64_t COSTime::Current()
15 | {
16 | uint64_t time = 0;
17 | #ifdef _WIN32
18 | LARGE_INTEGER liCount;
19 | LARGE_INTEGER liFrec;
20 |
21 | QueryPerformanceCounter(&liCount);
22 | QueryPerformanceFrequency(&liFrec);
23 |
24 | uint64_t quotient, remainder;
25 | quotient = ((liCount.QuadPart) / liFrec.QuadPart);
26 | remainder = ((liCount.QuadPart) % liFrec.QuadPart);
27 | time = quotient * 1000000 + (remainder * 1000000 / liFrec.QuadPart);
28 | #else
29 | timeval timeVal;
30 | gettimeofday(&timeVal, 0);
31 | time = static_cast((timeVal.tv_sec) * 1000000 + (timeVal.tv_usec));
32 | #endif
33 | return (time / 1000);
34 | }
--------------------------------------------------------------------------------
/src/COSTime.h:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #pragma once
6 |
7 | #include "CSingleton.h"
8 | #include
9 |
10 | class COSTime : public CSingleton
11 | {
12 | public:
13 | uint64_t Current();
14 | };
--------------------------------------------------------------------------------
/src/CServerHooks.cpp:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #include "CServerHooks.h"
6 | #include "natives.h"
7 |
8 | #define GETNAME_SAFE(hdr,entry) \
9 | (((hdr)->defsize==sizeof(AMX_FUNCSTUBNT)) ? \
10 | (char *)((unsigned char*)(hdr) + (unsigned)((AMX_FUNCSTUBNT*)(entry))->nameofs) : \
11 | ((AMX_FUNCSTUB*)(entry))->name)
12 |
13 | #define NATIVESIZE_SAFE(hdr,field,nextfield) \
14 | (unsigned)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize)
15 |
16 | #define GETNATIVE_SAFE(hdr,table,index) \
17 | (AMX_FUNCSTUB *)((unsigned char*)(hdr) + (unsigned)(hdr)->table + (unsigned)index*(hdr)->defsize)
18 |
19 | extern logprintf_t logprintf;
20 |
21 | CServerHooks::CServerHooks()
22 | {
23 | m_pFunctionDataStorage.clear();
24 | m_pNativeDataStorage.clear();
25 |
26 | m_pNativeDataStorage.insert(std::make_pair("SetTimer", false));
27 | m_pNativeDataStorage.insert(std::make_pair("SetTimerEx", false));
28 | m_pNativeDataStorage.insert(std::make_pair("KillTimer", false));
29 | }
30 |
31 | CServerHooks::~CServerHooks()
32 | {
33 | m_pFunctionDataStorage.clear();
34 | m_pNativeDataStorage.clear();
35 | }
36 |
37 | bool CServerHooks::Apply(AMX* amx)
38 | {
39 | if (!amx && !m_pAMX)
40 | return false;
41 |
42 | if (amx)
43 | m_pAMX = amx;
44 |
45 | AMX_HEADER* pHeader = reinterpret_cast(m_pAMX->base);
46 | AMX_FUNCSTUB* pFunc;
47 | if (pHeader)
48 | {
49 | for (int i = 0, num = NATIVESIZE_SAFE(pHeader, natives, libraries); i != num; ++i)
50 | {
51 | /*pFunc = reinterpret_cast(((unsigned char*)pHeader + pHeader->natives + i * pHeader->defsize));*/
52 | pFunc = GETNATIVE_SAFE(pHeader, natives, i);
53 | if (pFunc)
54 | {
55 | //std::map::iterator iter = m_pNativeDataStorage.find(pFunc->name);
56 | std::map::iterator iter = m_pNativeDataStorage.find(GETNAME_SAFE(pHeader, pFunc));
57 | if (iter != m_pNativeDataStorage.end())
58 | {
59 | // Not used in current version.
60 | //m_pFunctionDataStorage.insert(std::make_pair(pFunc, pFunc->address));
61 | iter->second = true;
62 | if (iter->first == "SetTimer")
63 | pFunc->address = (ucell)n_SetTimer;
64 | else if (iter->first == "SetTimerEx")
65 | pFunc->address = (ucell)n_SetTimerEx;
66 | else if (iter->first == "KillTimer")
67 | pFunc->address = (ucell)n_KillTimer;
68 | }
69 | }
70 | }
71 | }
72 |
73 | return true;
74 | }
75 |
76 | bool CServerHooks::Restore(AMX* amx)
77 | {
78 | if (!amx && !m_pAMX)
79 | return false;
80 |
81 | if (amx)
82 | m_pAMX = amx;
83 |
84 | for (std::map::iterator iter = m_pFunctionDataStorage.begin(); iter != m_pFunctionDataStorage.end();)
85 | {
86 | std::map::iterator inviter = m_pNativeDataStorage.find(GETNAME_SAFE(reinterpret_cast(m_pAMX->base), iter->first));
87 | if (inviter != m_pNativeDataStorage.end())
88 | {
89 | if (inviter->second)
90 | {
91 | iter->first->address = iter->second;
92 | inviter->second = false;
93 | m_pFunctionDataStorage.erase(iter++);
94 | continue;
95 | }
96 | }
97 |
98 | iter++;
99 | }
100 |
101 | return true;
102 | }
103 |
104 | bool CServerHooks::Checks()
105 | {
106 | bool bResult = true;
107 |
108 | for (std::map::iterator iter = m_pNativeDataStorage.begin(); iter != m_pNativeDataStorage.end(); iter++)
109 | {
110 | if (iter->second == false/* && m_pFunctionDataStorage.find(iter->first.c_str()) == m_pFunctionDataStorage.end()*/)
111 | {
112 | logprintf("[timerfix.plugin] error: hook on native '%s' has not been installed.", iter->first.c_str());
113 | // Let user to know all problems
114 | bResult = false;
115 | }
116 | }
117 |
118 | return bResult;
119 | }
--------------------------------------------------------------------------------
/src/CServerHooks.h:
--------------------------------------------------------------------------------
1 | // -----------------------------------------------------------------------------------
2 | // Timer Fix plugin for San Andreas Multiplayer
3 | // Copyright (c) 2018-2020, KashCherry
4 | // -----------------------------------------------------------------------------------
5 | #pragma once
6 |
7 | #include "CSingleton.h"
8 | #include "plugin.h"
9 | #include
10 | #include |