├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── Makefile ├── README.md ├── pawn.json ├── samp-plugin-timerfix.sln ├── samp-plugin-timerfix.vcxproj ├── samp-plugin-timerfix.vcxproj.filters ├── src ├── main.cpp ├── main.h ├── natives.cpp ├── natives.h ├── plugin.def ├── plugin.rc ├── resource.h ├── sdk │ ├── amx │ │ ├── amx.h │ │ ├── amx2.h │ │ ├── getch.c │ │ ├── getch.h │ │ └── sclinux.h │ ├── amxplugin.cpp │ ├── amxplugin2.cpp │ ├── plugin.h │ └── plugincommon.h ├── time.cpp ├── time.h ├── timers.cpp └── timers.h └── timerfix.inc /.gitignore: -------------------------------------------------------------------------------- 1 | # ========================= 2 | # Visual Studio 3 | # ========================= 4 | 5 | # User-specific files 6 | *.suo 7 | *.user 8 | *.sln.docstates 9 | 10 | # Build results 11 | *.o 12 | /[Dd]ebug/ 13 | /[Rr]elease/ 14 | /x64/ 15 | /build/ 16 | /[Bb]in/ 17 | /[Oo]bj/ 18 | 19 | # MSTest test Results 20 | [Tt]est[Rr]esult*/ 21 | [Bb]uild[Ll]og.* 22 | 23 | *_i.c 24 | *_p.c 25 | *.ilk 26 | *.meta 27 | *.obj 28 | *.pch 29 | *.pdb 30 | *.pgc 31 | *.pgd 32 | *.rsp 33 | *.sbr 34 | *.tlb 35 | *.tli 36 | *.tlh 37 | *.tmp 38 | *.tmp_proj 39 | *.log 40 | *.vspscc 41 | *.vssscc 42 | .builds 43 | *.pidb 44 | *.log 45 | *.scc 46 | 47 | # Visual C++ cache files 48 | ipch/ 49 | *.aps 50 | *.ncb 51 | *.opensdf 52 | *.sdf 53 | *.cachefile 54 | 55 | # Visual Studio profiler 56 | *.psess 57 | *.vsp 58 | *.vspx 59 | 60 | # Guidance Automation Toolkit 61 | *.gpState 62 | 63 | # ReSharper is a .NET coding add-in 64 | _ReSharper*/ 65 | *.[Rr]e[Ss]harper 66 | 67 | # TeamCity is a build add-in 68 | _TeamCity* 69 | 70 | # DotCover is a Code Coverage Tool 71 | *.dotCover 72 | 73 | # NCrunch 74 | *.ncrunch* 75 | .*crunch*.local.xml 76 | 77 | # Installshield output folder 78 | [Ee]xpress/ 79 | 80 | # DocProject is a documentation generator add-in 81 | DocProject/buildhelp/ 82 | DocProject/Help/*.HxT 83 | DocProject/Help/*.HxC 84 | DocProject/Help/*.hhc 85 | DocProject/Help/*.hhk 86 | DocProject/Help/*.hhp 87 | DocProject/Help/Html2 88 | DocProject/Help/html 89 | 90 | # Click-Once directory 91 | publish/ 92 | 93 | # Publish Web Output 94 | *.Publish.xml 95 | *.pubxml 96 | 97 | # NuGet Packages Directory 98 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 99 | #packages/ 100 | 101 | # Windows Azure Build Output 102 | csx 103 | *.build.csdef 104 | 105 | # Windows Store app package directory 106 | AppPackages/ 107 | 108 | # Others 109 | *.Cache 110 | ClientBin/ 111 | [Ss]tyle[Cc]op.* 112 | ~$* 113 | *~ 114 | *.dbmdl 115 | *.[Pp]ublish.xml 116 | *.pfx 117 | *.publishsettings 118 | 119 | # RIA/Silverlight projects 120 | Generated_Code/ 121 | 122 | # Backup & report files from converting an old project file to a newer 123 | # Visual Studio version. Backup files are not needed, because we have git ;-) 124 | _UpgradeReport_Files/ 125 | Backup*/ 126 | UpgradeLog*.XML 127 | UpgradeLog*.htm 128 | 129 | # SQL Server files 130 | App_Data/*.mdf 131 | App_Data/*.ldf 132 | 133 | # ========================= 134 | # Linux 135 | # ========================= 136 | 137 | .* 138 | !.gitignore 139 | !.travis.yml 140 | *~ 141 | 142 | # ========================= 143 | # OS X 144 | # ========================= 145 | 146 | .DS_Store 147 | .AppleDouble 148 | .LSOverride 149 | Icon 150 | 151 | # Thumbnails 152 | ._* 153 | 154 | # Files that might appear on external disk 155 | .Spotlight-V100 156 | .Trashes 157 | 158 | # ========================= 159 | # Windows 160 | # ========================= 161 | 162 | # Windows image file caches 163 | Thumbs.db 164 | ehthumbs.db 165 | 166 | # Folder config file 167 | Desktop.ini 168 | 169 | # Recycle Bin used on file shares 170 | $RECYCLE.BIN/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | install: 5 | - sudo apt-get update 6 | - sudo apt-get install gcc-multilib g++-multilib 7 | script: 8 | - make -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014, Dan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013-2014, Dan 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright notice, 10 | # this list of conditions and the following disclaimer in the documentation 11 | # and/or other materials provided with the distribution. 12 | # 13 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | .PHONY: build clean 25 | 26 | COMPILE_FLAGS = -c -fPIC -m32 -O3 -w -Wall -Isrc/sdk/amx/ -DLINUX -std=c++11 27 | LIBRARIES = -lrt 28 | 29 | OUTFILE = bin/timerfix.so 30 | 31 | build: 32 | mkdir -p bin 33 | g++ $(COMPILE_FLAGS) src/sdk/*.cpp 34 | g++ $(COMPILE_FLAGS) src/*.cpp 35 | g++ -m32 -shared -static-libstdc++ -o $(OUTFILE) *.o $(LIBRARIES) 36 | 37 | clean: 38 | rm -f *.o 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SA-MP Plugin - Timerfix 2 | ======================= 3 | [![Build Status](https://travis-ci.org/ziggi/samp-plugin-timerfix.svg?branch=master)](https://travis-ci.org/ziggi/samp-plugin-timerfix) 4 | 5 | Timerfix provides an improvement (increases the accuracy) to the timers system existent in SA-MP server. 6 | 7 | In order to enable new natives you must include the "timerfix.inc" file (`#include `). For more information about these, please check `timerfix.inc`. 8 | -------------------------------------------------------------------------------- /pawn.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": "ziggi", 3 | "repo": "samp-plugin-timerfix", 4 | "resources": [ 5 | { 6 | "name": "^timerfix-(.*).zip$", 7 | "platform": "linux", 8 | "archive": true, 9 | "includes": ["."], 10 | "plugins": ["timerfix.so"] 11 | }, 12 | { 13 | "name": "^timerfix-(.*).zip$", 14 | "platform": "windows", 15 | "archive": true, 16 | "includes": ["."], 17 | "plugins": ["timerfix.dll"] 18 | } 19 | ], 20 | "contributors": ["udan11", "IstuntmanI", "ziggi"], 21 | "runtime": { 22 | "plugins": ["ziggi/timerfix"] 23 | } 24 | } -------------------------------------------------------------------------------- /samp-plugin-timerfix.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2012 for Windows Desktop 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "samp-plugin-timerfix", "samp-plugin-timerfix.vcxproj", "{E39FCF7E-6456-4C51-B8D1-6F3EE6BCE715}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Release|Win32 = Release|Win32 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {E39FCF7E-6456-4C51-B8D1-6F3EE6BCE715}.Release|Win32.ActiveCfg = Release|Win32 12 | {E39FCF7E-6456-4C51-B8D1-6F3EE6BCE715}.Release|Win32.Build.0 = Release|Win32 13 | EndGlobalSection 14 | GlobalSection(SolutionProperties) = preSolution 15 | HideSolutionNode = FALSE 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /samp-plugin-timerfix.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {E39FCF7E-6456-4C51-B8D1-6F3EE6BCE715} 15 | sampplugintimerfix 16 | 10.0 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v140_xp 23 | MultiByte 24 | 25 | 26 | DynamicLibrary 27 | false 28 | v142 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | bin\ 42 | timerfix 43 | build\ 44 | 45 | 46 | 47 | Level3 48 | Disabled 49 | 50 | 51 | true 52 | 53 | 54 | 55 | 56 | 57 | true 58 | true 59 | true 60 | src\plugin.def 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /samp-plugin-timerfix.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {d70d3d86-af23-48cc-9992-e59cdcd74890} 6 | 7 | 8 | {2f1817cb-fb42-4fff-b91a-272cc4f1b95d} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | sdk\amx 17 | 18 | 19 | sdk\amx 20 | 21 | 22 | sdk\amx 23 | 24 | 25 | sdk 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | sdk 35 | 36 | 37 | sdk 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "main.h" 27 | 28 | #include 29 | 30 | #define HAVE_STDINT_H 31 | #include "sdk/plugin.h" 32 | #include "sdk/amx/amx2.h" 33 | 34 | #include "time.h" 35 | #include "timers.h" 36 | #include "natives.h" 37 | 38 | extern void *pAMXFunctions; 39 | logprintf_t logprintf; 40 | 41 | const AMX_NATIVE_INFO PluginNatives[] = 42 | { 43 | {"KillPlayerTimers", Natives::KillPlayerTimers}, 44 | {"SetTimer_", Natives::SetTimer_}, 45 | {"SetTimerEx_", Natives::SetTimerEx_}, 46 | {"SetPlayerTimer", Natives::SetPlayerTimer}, 47 | {"SetPlayerTimerEx", Natives::SetPlayerTimerEx}, 48 | {"SetPlayerTimer_", Natives::SetPlayerTimer_}, 49 | {"SetPlayerTimerEx_", Natives::SetPlayerTimerEx_}, 50 | {"GetTimerFunctionName", Natives::GetTimerFunctionName}, 51 | {"SetTimerInterval", Natives::SetTimerInterval}, 52 | {"SetTimerIntervalLeft", Natives::SetTimerIntervalLeft}, 53 | {"GetTimerInterval", Natives::GetTimerInterval}, 54 | {"GetTimerIntervalLeft", Natives::GetTimerIntervalLeft}, 55 | {"SetTimerDelay", Natives::SetTimerDelay}, 56 | {"SetTimerCount", Natives::SetTimerCount}, 57 | {"GetTimerCallsLeft", Natives::GetTimerCallsLeft}, 58 | {"IsValidTimer", Natives::IsValidTimer}, 59 | {"GetActiveTimers", Natives::GetActiveTimers}, 60 | 61 | {NULL, NULL} 62 | }; 63 | 64 | PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() 65 | { 66 | return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES | SUPPORTS_PROCESS_TICK; 67 | } 68 | 69 | PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) 70 | { 71 | logprintf = reinterpret_cast(ppData[PLUGIN_DATA_LOGPRINTF]); 72 | pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS]; 73 | InitTime(); 74 | logprintf(" >> TimerFix " PLUGIN_VERSION " successfully loaded."); 75 | return true; 76 | } 77 | 78 | PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) 79 | { 80 | amx_Redirect(amx, "SetTimer", reinterpret_cast(Natives::SetTimer), NULL); 81 | amx_Redirect(amx, "SetTimerEx", reinterpret_cast(Natives::SetTimerEx), NULL); 82 | amx_Redirect(amx, "KillTimer", reinterpret_cast(Natives::KillTimer), NULL); 83 | amx_Redirect(amx, "GetTickCount", reinterpret_cast(Natives::GetTickCount), NULL); 84 | 85 | return amx_Register(amx, PluginNatives, -1); 86 | } 87 | 88 | PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) 89 | { 90 | for (auto it = timers.begin(); it != timers.end(); ++it) { 91 | struct timer *t = it->second; 92 | if (t->amx == amx) { 93 | DestroyTimer(t); 94 | timers.erase(it); 95 | } 96 | } 97 | return AMX_ERR_NONE; 98 | } 99 | 100 | PLUGIN_EXPORT void PLUGIN_CALL Unload() 101 | { 102 | logprintf("[plugin.timerfix] Plugin successfully unloaded!"); 103 | } 104 | 105 | PLUGIN_EXPORT void PLUGIN_CALL ProcessTick() 106 | { 107 | unsigned long long now = GetMsTime(); 108 | for (auto it = timers.begin(); it != timers.end(); ++it) { 109 | struct timer *t = it->second; 110 | if (t->repeat != 0) { 111 | if (t->next < now) { 112 | t->next += t->interval; 113 | ExecuteTimer(it->second); 114 | if (t->repeat > 0) { 115 | --t->repeat; 116 | } 117 | } 118 | } else { 119 | DestroyTimer(t); 120 | timers.erase(it); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #define PLUGIN_VERSION "v1.8" 29 | 30 | #ifndef CELL_SIZE 31 | #define CELL_SIZE 4 32 | #endif 33 | 34 | #ifndef MAX_INT 35 | #define MAX_INT 2147483647 36 | #endif 37 | 38 | #define INVALID_PLAYER_ID 0xFFFF 39 | 40 | typedef void(*logprintf_t)(char*, ...); 41 | 42 | extern logprintf_t logprintf; 43 | -------------------------------------------------------------------------------- /src/natives.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "natives.h" 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include "main.h" 33 | #include "time.h" 34 | #include "timers.h" 35 | 36 | cell AMX_NATIVE_CALL Natives::GetTickCount(AMX *amx, cell *params) 37 | { 38 | return (int)(GetMsTime() % MAX_INT); 39 | } 40 | 41 | cell AMX_NATIVE_CALL Natives::IsValidTimer(AMX *amx, cell *params) 42 | { 43 | if (params[0] < 1 * CELL_SIZE) { 44 | return 0; 45 | } 46 | int id = params[1]; 47 | if (TimerExists(id)) { 48 | return timers[id]->repeat == -1 || timers[id]->repeat > 0; 49 | } 50 | return 0; 51 | } 52 | 53 | cell AMX_NATIVE_CALL Natives::GetActiveTimers(AMX *amx, cell *params) 54 | { 55 | return timers.size(); 56 | } 57 | 58 | cell AMX_NATIVE_CALL Natives::KillTimer(AMX *amx, cell *params) 59 | { 60 | if (params[0] < 1 * CELL_SIZE) { 61 | return 0; 62 | } 63 | int id = params[1]; 64 | if (TimerExists(id)) { 65 | // Scheduling for deletion. 66 | timers[id]->repeat = 0; 67 | } 68 | return 1; 69 | } 70 | 71 | cell AMX_NATIVE_CALL Natives::KillPlayerTimers(AMX *amx, cell *params) 72 | { 73 | if (params[0] < 1 * CELL_SIZE) { 74 | return 0; 75 | } 76 | int playerid = params[1]; 77 | if (playerid != INVALID_PLAYER_ID) { 78 | for (auto it = timers.begin(); it != timers.end(); ++it) { 79 | struct timer *t = it->second; 80 | if (t->playerid == playerid) { 81 | t->repeat = 0; 82 | } 83 | } 84 | } 85 | return 1; 86 | } 87 | 88 | cell AMX_NATIVE_CALL Natives::SetTimer(AMX *amx, cell *params) 89 | { 90 | if (params[0] < 3 * CELL_SIZE) { 91 | return 0; 92 | } 93 | return CreateTimer(amx, INVALID_PLAYER_ID, params[1], params[2], params[2], params[3] ? -1 : 1, NULL, NULL); 94 | } 95 | 96 | cell AMX_NATIVE_CALL Natives::SetTimerEx(AMX *amx, cell *params) 97 | { 98 | if (params[0] < 4 * CELL_SIZE) { 99 | return 0; 100 | } 101 | return CreateTimer(amx, INVALID_PLAYER_ID, params[1], params[2], params[2], params[3] ? -1 : 1, params[4], ¶ms[5]); 102 | } 103 | 104 | cell AMX_NATIVE_CALL Natives::SetTimer_(AMX *amx, cell *params) 105 | { 106 | if (params[0] < 4 * CELL_SIZE) { 107 | return 0; 108 | } 109 | return CreateTimer(amx, INVALID_PLAYER_ID, params[1], params[2], params[3], params[4], NULL, NULL); 110 | } 111 | 112 | cell AMX_NATIVE_CALL Natives::SetTimerEx_(AMX *amx, cell *params) 113 | { 114 | if (params[0] < 5 * CELL_SIZE) { 115 | return 0; 116 | } 117 | return CreateTimer(amx, INVALID_PLAYER_ID, params[1], params[2], params[3], params[4], params[5], ¶ms[6]); 118 | } 119 | 120 | cell AMX_NATIVE_CALL Natives::SetPlayerTimer(AMX *amx, cell *params) 121 | { 122 | if (params[0] < 4 * CELL_SIZE) { 123 | return 0; 124 | } 125 | return CreateTimer(amx, params[1], params[2], params[3], params[3], params[4] ? -1 : 1, NULL, NULL); 126 | } 127 | 128 | cell AMX_NATIVE_CALL Natives::SetPlayerTimerEx(AMX *amx, cell *params) 129 | { 130 | if (params[0] < 5 * CELL_SIZE) { 131 | return 0; 132 | } 133 | return CreateTimer(amx, params[1], params[2], params[3], params[3], params[4] ? -1 : 1, params[5], ¶ms[6]); 134 | } 135 | 136 | cell AMX_NATIVE_CALL Natives::SetPlayerTimer_(AMX *amx, cell *params) 137 | { 138 | if (params[0] < 5 * CELL_SIZE) { 139 | return 0; 140 | } 141 | return CreateTimer(amx, params[1], params[2], params[3], params[4], params[5], NULL, NULL); 142 | } 143 | 144 | cell AMX_NATIVE_CALL Natives::SetPlayerTimerEx_(AMX *amx, cell *params) 145 | { 146 | if (params[0] < 6 * CELL_SIZE) { 147 | return 0; 148 | } 149 | return CreateTimer(amx, params[1], params[2], params[3], params[4], params[5], params[6], ¶ms[7]); 150 | } 151 | 152 | cell AMX_NATIVE_CALL Natives::GetTimerFunctionName(AMX *amx, cell *params) 153 | { 154 | if (params[0] < 3 * CELL_SIZE) { 155 | return 0; 156 | } 157 | int id = params[1]; 158 | if (!TimerExists(id)) { 159 | amx_SetCString(amx, params[2], "", 1); // "\0" 160 | return 0; 161 | } 162 | int maxlength = params[3]; 163 | amx_SetCString(amx, params[2], timers[id]->func, maxlength); 164 | return 1; 165 | } 166 | 167 | cell AMX_NATIVE_CALL Natives::SetTimerInterval(AMX *amx, cell *params) 168 | { 169 | if (params[0] < 2 * CELL_SIZE) { 170 | return 0; 171 | } 172 | int id = params[1], interval = params[2]; 173 | if (TimerExists(id)) { 174 | timers[id]->interval = interval; 175 | timers[id]->next = GetMsTime() + interval; 176 | } 177 | return 1; 178 | } 179 | 180 | cell AMX_NATIVE_CALL Natives::SetTimerIntervalLeft(AMX *amx, cell *params) 181 | { 182 | if (params[0] < 2 * CELL_SIZE) { 183 | return 0; 184 | } 185 | int id = params[1], interval = params[2]; 186 | if (TimerExists(id)) { 187 | timers[id]->next = GetMsTime() + interval; 188 | } 189 | return 1; 190 | } 191 | 192 | cell AMX_NATIVE_CALL Natives::GetTimerInterval(AMX *amx, cell *params) 193 | { 194 | if (params[0] < 1 * CELL_SIZE) { 195 | return 0; 196 | } 197 | int id = params[1]; 198 | if (TimerExists(id)) { 199 | return timers[id]->interval; 200 | } 201 | return 0; 202 | } 203 | 204 | cell AMX_NATIVE_CALL Natives::GetTimerIntervalLeft(AMX *amx, cell *params) 205 | { 206 | if (params[0] < 1 * CELL_SIZE) { 207 | return 0; 208 | } 209 | int id = params[1]; 210 | if (TimerExists(id)) { 211 | return timers[id]->next - GetMsTime(); 212 | } 213 | return 0; 214 | } 215 | 216 | 217 | cell AMX_NATIVE_CALL Natives::SetTimerDelay(AMX *amx, cell *params) 218 | { 219 | if (params[0] < 2 * CELL_SIZE) { 220 | return 0; 221 | } 222 | int id = params[1], delay = params[2]; 223 | if (TimerExists(id)) { 224 | timers[id]->next = GetMsTime() + delay; 225 | } 226 | return 1; 227 | } 228 | 229 | cell AMX_NATIVE_CALL Natives::SetTimerCount(AMX *amx, cell *params) 230 | { 231 | if (params[0] < 2 * CELL_SIZE) { 232 | return 0; 233 | } 234 | int id = params[1], count = params[2]; 235 | if (TimerExists(id)) { 236 | timers[id]->repeat = count; 237 | } 238 | return 1; 239 | } 240 | 241 | cell AMX_NATIVE_CALL Natives::GetTimerCallsLeft(AMX *amx, cell *params) 242 | { 243 | if (params[0] < 1 * CELL_SIZE) { 244 | return 0; 245 | } 246 | int id = params[1]; 247 | if (TimerExists(id)) { 248 | return timers[id]->repeat; 249 | } 250 | return 0; 251 | } 252 | -------------------------------------------------------------------------------- /src/natives.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #define HAVE_STDINT_H 29 | #include "sdk/amx/amx.h" 30 | #include "sdk/amx/amx2.h" 31 | 32 | class Natives 33 | { 34 | public: 35 | static cell AMX_NATIVE_CALL GetTickCount(AMX *amx, cell *params); 36 | static cell AMX_NATIVE_CALL IsValidTimer(AMX *amx, cell *params); 37 | static cell AMX_NATIVE_CALL GetActiveTimers(AMX *amx, cell *params); 38 | static cell AMX_NATIVE_CALL KillTimer(AMX *amx, cell *params); 39 | static cell AMX_NATIVE_CALL KillPlayerTimers(AMX *amx, cell *params); 40 | static cell AMX_NATIVE_CALL SetTimer(AMX *amx, cell *params); 41 | static cell AMX_NATIVE_CALL SetTimerEx(AMX *amx, cell *params); 42 | static cell AMX_NATIVE_CALL SetTimer_(AMX *amx, cell *params); 43 | static cell AMX_NATIVE_CALL SetTimerEx_(AMX *amx, cell *params); 44 | static cell AMX_NATIVE_CALL SetPlayerTimer(AMX *amx, cell *params); 45 | static cell AMX_NATIVE_CALL SetPlayerTimerEx(AMX *amx, cell *params); 46 | static cell AMX_NATIVE_CALL SetPlayerTimer_(AMX *amx, cell *params); 47 | static cell AMX_NATIVE_CALL SetPlayerTimerEx_(AMX *amx, cell *params); 48 | static cell AMX_NATIVE_CALL GetTimerFunctionName(AMX *amx, cell *params); 49 | static cell AMX_NATIVE_CALL SetTimerInterval(AMX *amx, cell *params); 50 | static cell AMX_NATIVE_CALL SetTimerIntervalLeft(AMX *amx, cell *params); 51 | static cell AMX_NATIVE_CALL GetTimerInterval(AMX *amx, cell *params); 52 | static cell AMX_NATIVE_CALL GetTimerIntervalLeft(AMX *amx, cell *params); 53 | static cell AMX_NATIVE_CALL SetTimerDelay(AMX *amx, cell *params); 54 | static cell AMX_NATIVE_CALL SetTimerCount(AMX *amx, cell *params); 55 | static cell AMX_NATIVE_CALL GetTimerCallsLeft(AMX *amx, cell *params); 56 | private: 57 | Natives(); 58 | ~Natives(); 59 | }; 60 | -------------------------------------------------------------------------------- /src/plugin.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | Supports 3 | Load 4 | Unload 5 | AmxLoad 6 | AmxUnload 7 | ProcessTick 8 | -------------------------------------------------------------------------------- /src/plugin.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ziggi/samp-plugin-timerfix/24637557c0de1534601f3b89e8275c6848910b78/src/plugin.rc -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ziggi/samp-plugin-timerfix/24637557c0de1534601f3b89e8275c6848910b78/src/resource.h -------------------------------------------------------------------------------- /src/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 29 | #endif 30 | 31 | #ifndef AMX_H_INCLUDED 32 | #define AMX_H_INCLUDED 33 | 34 | #if defined HAVE_STDINT_H 35 | #include 36 | #else 37 | #if defined __LCC__ || defined __DMC__ || defined LINUX 38 | #if defined HAVE_INTTYPES_H 39 | #include 40 | #else 41 | #include 42 | #endif 43 | #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L 44 | /* The ISO C99 defines the int16_t and int_32t types. If the compiler got 45 | * here, these types are probably undefined. 46 | */ 47 | #if defined __MACH__ 48 | #include 49 | typedef unsigned short int uint16_t; 50 | typedef unsigned long int uint32_t; 51 | #elif defined __FreeBSD__ 52 | #include 53 | #else 54 | typedef short int int16_t; 55 | typedef unsigned short int uint16_t; 56 | #if defined SN_TARGET_PS2 57 | typedef int int32_t; 58 | typedef unsigned int uint32_t; 59 | #else 60 | typedef long int int32_t; 61 | typedef unsigned long int uint32_t; 62 | #endif 63 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 64 | typedef __int64 int64_t; 65 | typedef unsigned __int64 uint64_t; 66 | #define HAVE_I64 67 | #elif defined __GNUC__ 68 | typedef long long int64_t; 69 | typedef unsigned long long uint64_t; 70 | #define HAVE_I64 71 | #endif 72 | #endif 73 | #endif 74 | #define HAVE_STDINT_H 75 | #endif 76 | #if defined _LP64 || defined WIN64 || defined _WIN64 77 | #if !defined __64BIT__ 78 | #define __64BIT__ 79 | #endif 80 | #endif 81 | 82 | #if HAVE_ALLOCA_H 83 | #include 84 | #endif 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 | -------------------------------------------------------------------------------- /src/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, const 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 45 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 | #define HAVE_STDINT_H 18 | #include "amx/amx2.h" 19 | 20 | //---------------------------------------------------------- 21 | 22 | int AMXAPI amx_PushAddress(AMX *amx, cell *address) { 23 | AMX_HEADER *hdr; 24 | unsigned char *data; 25 | cell xaddr; 26 | /* reverse relocate the address */ 27 | assert(amx != NULL); 28 | hdr = (AMX_HEADER *) amx->base; 29 | assert(hdr != NULL); 30 | assert(hdr->magic == AMX_MAGIC); 31 | data = (amx->data != NULL) ? amx->data : amx->base + (int) hdr->dat; 32 | xaddr = (cell) ((unsigned char*) address-data); 33 | if ((ucell) xaddr >= (ucell) amx->stp) { 34 | return AMX_ERR_MEMACCESS; 35 | } 36 | return amx_Push(amx,xaddr); 37 | } 38 | 39 | void AMXAPI amx_Redirect(AMX *amx, const char *from, ucell to, AMX_NATIVE *store) { 40 | AMX_HEADER *hdr = (AMX_HEADER*) amx->base; 41 | AMX_FUNCSTUB *func; 42 | for (int idx = 0, num = NUMENTRIES(hdr, natives, libraries); idx != num; ++idx) { 43 | func = GETENTRY(hdr, natives, idx); 44 | if (!strcmp(from, GETENTRYNAME(hdr, func))) { 45 | if (store) { 46 | *store = (AMX_NATIVE) func->address; 47 | } 48 | func->address = to; 49 | return; 50 | } 51 | } 52 | } 53 | 54 | int AMXAPI amx_GetCString(AMX *amx, cell param, char *&dest) { 55 | cell *ptr; 56 | amx_GetAddr(amx, param, &ptr); 57 | int len; 58 | amx_StrLen(ptr, &len); 59 | dest = (char*) malloc((len + 1) * sizeof(char)); 60 | if (dest != NULL) { 61 | amx_GetString(dest, ptr, 0, UNLIMITED); 62 | dest[len] = 0; 63 | return len; 64 | } 65 | return 0; 66 | } 67 | 68 | void AMXAPI amx_SetCString(AMX *amx, cell param, const char *str, int len) { 69 | cell *dest; 70 | amx_GetAddr(amx, param, &dest); 71 | amx_SetString(dest, str, 0, 0, len); 72 | } 73 | 74 | std::string AMXAPI amx_GetCppString(AMX *amx, cell param) { 75 | char *tmp; 76 | amx_StrParam(amx, param, tmp); 77 | if (tmp != NULL) { 78 | return tmp; 79 | } 80 | return ""; 81 | } 82 | 83 | void AMXAPI amx_SetCppString(AMX *amx, cell param, std::string str, int len) { 84 | cell *dest; 85 | amx_GetAddr(amx, param, &dest); 86 | amx_SetString(dest, str.c_str(), 0, 0, len); 87 | } 88 | 89 | //---------------------------------------------------------- 90 | // EOF 91 | -------------------------------------------------------------------------------- /src/sdk/plugin.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // 3 | // SA-MP Multiplayer Modification For GTA:SA 4 | // Copyright 2004-2009 SA-MP Team 5 | // 6 | //---------------------------------------------------------- 7 | 8 | #include "plugincommon.h" 9 | #include "amx/amx.h" 10 | 11 | //---------------------------------------------------------- 12 | // EOF 13 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/time.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "time.h" 27 | 28 | #ifdef WIN32 29 | LARGE_INTEGER startTime; 30 | unsigned long long freq; 31 | #else 32 | struct timespec startTime; 33 | #endif 34 | 35 | void InitTime() 36 | { 37 | #ifdef WIN32 38 | LARGE_INTEGER t; 39 | QueryPerformanceFrequency(&t); 40 | freq = t.QuadPart / 1000; 41 | QueryPerformanceCounter(&startTime); 42 | #else 43 | clock_gettime(CLOCK_MONOTONIC, &startTime); 44 | #endif 45 | } 46 | 47 | unsigned long long GetMsTime() 48 | { 49 | #ifdef WIN32 50 | LARGE_INTEGER t; 51 | QueryPerformanceCounter(&t); 52 | return (t.QuadPart - startTime.QuadPart) / freq; 53 | #else 54 | struct timespec t; 55 | clock_gettime(CLOCK_MONOTONIC, &t); 56 | t.tv_sec -= startTime.tv_sec; 57 | t.tv_nsec -= startTime.tv_nsec; 58 | if (t.tv_nsec < 0) { 59 | t.tv_sec -= 1; 60 | t.tv_nsec += 1000000000; 61 | } 62 | return t.tv_sec * 1000 + t.tv_nsec / 1000000; 63 | #endif 64 | } 65 | -------------------------------------------------------------------------------- /src/time.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #if defined _WIN32 29 | #include 30 | #else 31 | #include 32 | #endif 33 | 34 | extern void InitTime(); 35 | extern unsigned long long GetMsTime(); 36 | -------------------------------------------------------------------------------- /src/timers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "timers.h" 27 | 28 | #include 29 | 30 | #include "main.h" 31 | #include "time.h" 32 | 33 | std::map timers; 34 | int lastTimerId = 1; 35 | 36 | int CreateTimer(AMX *amx, cell playerid, cell funcname, cell interval, cell delay, cell repeat, cell format, cell *params) 37 | { 38 | struct timer *t = (struct timer*) malloc(sizeof(struct timer)); 39 | if (t == NULL) { 40 | logprintf("[plugin.timerfix] Cannot allocate memory."); 41 | return 0; 42 | } 43 | memset(t, 0, sizeof(struct timer)); 44 | t->amx = amx; 45 | t->id = lastTimerId++; 46 | t->playerid = playerid; 47 | amx_GetCString(amx, funcname, t->func); 48 | if (amx_FindPublic(amx, t->func, &t->funcidx)) { 49 | logprintf("[plugin.timerfix] %s: Function was not found.", t->func); 50 | DestroyTimer(t); 51 | return 0; 52 | } 53 | if (interval < 0) { 54 | logprintf("[plugin.timerfix] %s: Interval (%d) must be at least 0.", t->func, interval); 55 | DestroyTimer(t); 56 | return 0; 57 | } 58 | t->interval = interval; 59 | t->repeat = repeat; 60 | if (delay < 0) { 61 | logprintf("[plugin.timerfix] %s: Delay (%d) must be at least 0.", t->func, delay); 62 | DestroyTimer(t); 63 | return 0; 64 | } 65 | t->next = GetMsTime() + delay; 66 | if (format != NULL) { 67 | amx_GetCString(amx, format, t->format); 68 | for (int i = 0, len = strlen(t->format), p = 0; i != len; ++i, ++p) { 69 | switch (t->format[i]) { 70 | case 'a': 71 | case 'A': 72 | if (t->format[i + 1] == 0) { 73 | logprintf("[plugin.timerfix] %s: Format '%c' is not correct. Expected 'i' or 'd', but found nothin.", t->func, t->format[i]); 74 | DestroyTimer(t); 75 | return 0; 76 | } 77 | if (t->format[i + 1] != 'i' && t->format[i + 1] != 'I' && t->format[i + 1] != 'd' && t->format[i + 1] != 'D') { 78 | logprintf("[plugin.timerfix] %s: Format '%c' is not correct. Expected 'i' or 'd', but found '%c'.", t->func, t->format[i], t->format[i + 1]); 79 | DestroyTimer(t); 80 | return 0; 81 | } 82 | cell * ptr_arr, *ptr_len, *arr, len; 83 | amx_GetAddr(amx, params[p], &ptr_arr); 84 | amx_GetAddr(amx, params[p + 1], &ptr_len); 85 | if (*ptr_len < 0) { 86 | logprintf("[plugin.timerfix] %s: Array size is lower than 0.", t->func); 87 | DestroyTimer(t); 88 | return 0; 89 | } 90 | len = sizeof(cell)* (*ptr_len); 91 | arr = (cell*)malloc(len); 92 | if (arr != NULL) { 93 | memcpy(arr, ptr_arr, len); 94 | t->params_a.push_back(std::make_pair(arr, *ptr_len)); 95 | } 96 | break; 97 | case 'b': 98 | case 'B': 99 | case 'c': 100 | case 'C': 101 | case 'd': 102 | case 'D': 103 | case 'i': 104 | case 'I': 105 | case 'f': 106 | case 'F': 107 | cell * ptr; 108 | amx_GetAddr(amx, params[p], &ptr); 109 | t->params_c.push_back(*ptr); 110 | break; 111 | case 'p': 112 | case 'P': 113 | case 't': 114 | case 'T': 115 | --p; // We didn't read any parameter. 116 | break; 117 | case 's': 118 | case 'S': 119 | char *str; 120 | amx_GetCString(amx, params[p], str); 121 | t->params_s.push_back(str); 122 | break; 123 | default: 124 | logprintf("[plugin.timerfix] %s: Format '%c' is not recognized.", t->func, t->format[i]); 125 | break; 126 | } 127 | } 128 | } 129 | timers[t->id] = t; 130 | return t->id; 131 | } 132 | 133 | bool TimerExists(int id) 134 | { 135 | return timers.find(id) != timers.end(); 136 | } 137 | 138 | void DestroyTimer(struct timer *&t) 139 | { 140 | free(t->func); 141 | free(t->format); 142 | for (int i = 0, size = t->params_a.size(); i != size; ++i) { 143 | free(t->params_a[i].first); 144 | } 145 | t->params_a.clear(); 146 | t->params_c.clear(); 147 | for (int i = 0, size = t->params_s.size(); i != size; ++i) { 148 | free(t->params_s[i]); 149 | } 150 | t->params_s.clear(); 151 | free(t); 152 | } 153 | 154 | int ExecuteTimer(struct timer *t) 155 | { 156 | cell ret, amx_addr = -1; 157 | if (t->format != NULL) { 158 | int a_idx = t->params_a.size(), c_idx = t->params_c.size(), s_idx = t->params_s.size(); 159 | for (int i = strlen(t->format) - 1; i != -1; --i) { 160 | cell tmp; 161 | switch (t->format[i]) { 162 | case 'a': 163 | case 'A': 164 | --a_idx; 165 | amx_PushArray(t->amx, &tmp, NULL, t->params_a[a_idx].first, t->params_a[a_idx].second); 166 | if (amx_addr == -1) { 167 | amx_addr = tmp; 168 | } 169 | break; 170 | case 'b': 171 | case 'B': 172 | case 'c': 173 | case 'C': 174 | case 'd': 175 | case 'D': 176 | case 'i': 177 | case 'I': 178 | case 'f': 179 | case 'F': 180 | amx_Push(t->amx, t->params_c[--c_idx]); 181 | break; 182 | case 'p': 183 | case 'P': 184 | amx_Push(t->amx, t->playerid); 185 | case 's': 186 | case 'S': 187 | amx_PushString(t->amx, &tmp, NULL, t->params_s[--s_idx], NULL, NULL); 188 | if (amx_addr == -1) { 189 | amx_addr = tmp; 190 | } 191 | break; 192 | case 't': 193 | case 'T': 194 | amx_Push(t->amx, t->id); 195 | break; 196 | } 197 | } 198 | } 199 | amx_Exec(t->amx, &ret, t->funcidx); 200 | if (amx_addr != -1) { 201 | amx_Release(t->amx, amx_addr); 202 | } 203 | return (int)ret; 204 | } 205 | -------------------------------------------------------------------------------- /src/timers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #include 29 | #include 30 | 31 | #define HAVE_STDINT_H 32 | #include "sdk/amx/amx.h" 33 | #include "sdk/amx/amx2.h" 34 | 35 | struct timer 36 | { 37 | AMX *amx; 38 | int id, playerid, funcidx, interval, repeat; 39 | unsigned long long next; 40 | char *func, *format; 41 | std::vector > params_a; 42 | std::vector params_c; 43 | std::vector params_s; 44 | }; 45 | 46 | extern std::map timers; 47 | 48 | extern int CreateTimer(AMX *amx, cell playerid, cell funcname, cell interval, cell delay, cell repeat, cell format, cell *params); 49 | extern bool TimerExists(int id); 50 | extern void DestroyTimer(struct timer *&t); 51 | extern int ExecuteTimer(struct timer *t); 52 | -------------------------------------------------------------------------------- /timerfix.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-2014, Dan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | /** 27 | * 1.8 28 | * Supported parameters: 29 | * a, A = arrays (must be followed by an integer - array's szie); 30 | * b, B = boolean; c, C = character; d, D, i, I = integer; 31 | * s, S = string; p, P = player's ID, t, T = timer's ID 32 | * 33 | */ 34 | 35 | #if defined _timerfix_included 36 | #endinput 37 | #endif 38 | #define _timerfix_included 39 | #pragma library timerfix 40 | 41 | /** 42 | * Same KillTimer is used for all types of timer. 43 | */ 44 | #define KillTimer_ KillTimer 45 | 46 | /** 47 | * Improved GetTickCount (more accurate). 48 | * Current time in miliseconds. 49 | */ 50 | //native GetTickCount(); 51 | 52 | /** 53 | * Checks if a timer is still alive. 54 | * The ID of the timer. 55 | * `true` if the timer is valid or `false` otherwise. 56 | */ 57 | native IsValidTimer(timerid); 58 | 59 | /** 60 | * Gets the number of active timers. 61 | * The number of active timers. 62 | */ 63 | native GetActiveTimers(); 64 | 65 | /** 66 | * Kills specified timer owned by player. 67 | * The ID of the timer. 68 | */ 69 | native KillPlayerTimer(timerid) = KillTimer; 70 | 71 | /** 72 | * Kills all timers a player owns. 73 | * The player that owns the timers. 74 | */ 75 | native KillPlayerTimers(playerid); 76 | 77 | /** 78 | * Basic SetTimer. 79 | * Name of the public function to call. 80 | * Interval in milliseconds. 81 | * Whether this timer will repeat or will execute only one time. 82 | * The ID of the timer. 83 | */ 84 | //native SetTimer(const func[], interval, repeating); 85 | 86 | /** 87 | * Basic SetTimerEx. 88 | * Name of the public function to call. 89 | * Interval in milliseconds. 90 | * Whether this timer will repeat or will execute only one time. 91 | * Special format indicating the types of values the timer will pass. 92 | * The ID of the timer. 93 | */ 94 | //native SetTimerEx(const func[], interval, repeating, const format[], {Float,_}:...); 95 | 96 | /** 97 | * An improved version of SetTimer. 98 | * Name of the public function to call. 99 | * Interval in milliseconds. 100 | * Time after this timer should be called for the first time. 101 | * How many times it should repeat before it's killed (-1 for unlimited). 102 | * The ID of the timer. 103 | */ 104 | native SetTimer_(const func[], interval, delay, count); 105 | 106 | /** 107 | * An improved version of SetTimerEx. 108 | * Name of the public function to call. 109 | * Interval in milliseconds. 110 | * Time after this timer should be called for the first time. 111 | * How many times it should repeat before it's killed (-1 for unlimited). 112 | * Special format indicating the types of values the timer will pass. 113 | * The ID of the timer. 114 | */ 115 | native SetTimerEx_(const func[], interval, delay, count,const format[], {Float, _}:...); 116 | 117 | /** 118 | * Basic SetPlayerTimer. 119 | * The player that owns the timer. 120 | * Name of the public function to call. 121 | * Interval in milliseconds. 122 | * Whether this timer will repeat or will execute only one time. 123 | * The ID of the timer. 124 | */ 125 | native SetPlayerTimer(playerid,const func[], interval, repeating); 126 | 127 | /** 128 | * Basic SetPlayerTimerEx. 129 | * The player that owns the timer. 130 | * Name of the public function to call. 131 | * Interval in milliseconds. 132 | * Whether this timer will repeat or will execute only one time. 133 | * Special format indicating the types of values the timer will pass. 134 | * The ID of the timer. 135 | */ 136 | native SetPlayerTimerEx(playerid,const func[], interval, repeating, const format[], {Float,_}:...); 137 | 138 | /** 139 | * An improved version of SetPlayerTimer. 140 | * The player that owns the timer. 141 | * Name of the public function to call. 142 | * Interval in milliseconds. 143 | * Time after this timer should be called for the first time. 144 | * How many times it should repeat before it's killed (-1 for unlimited). 145 | * The ID of the timer. 146 | */ 147 | native SetPlayerTimer_(playerid, const func[], interval, delay, count); 148 | 149 | /** 150 | * An improved version of SetPlayerTimerEx. 151 | * The player that owns the timer. 152 | * Name of the public function to call. 153 | * Interval in milliseconds. 154 | * Time after this timer should be called for the first time. 155 | * How many times it should repeat before it's killed (-1 for unlimited). 156 | * Special format indicating the types of values the timer will pass. 157 | * The ID of the timer. 158 | */ 159 | native SetPlayerTimerEx_(playerid, const func[], interval, delay, count, const format[], {Float, _}:...); 160 | 161 | /** 162 | * Gets the name of the function that is called. 163 | * The ID of the timer. 164 | * The name of the function. 165 | * Maximum length of the returned function name. 166 | */ 167 | native GetTimerFunctionName(timerid, const func[], maxlength = sizeof(func)); 168 | 169 | /** 170 | * Sets the interval of a timer. 171 | * The ID of the timer. 172 | * The new interval. 173 | */ 174 | native SetTimerInterval(timerid, interval); 175 | 176 | /** 177 | * Sets the time remaining before this timer is called again. 178 | * The ID of the timer. 179 | * The new interval. 180 | */ 181 | native SetTimerIntervalLeft(timerid, interval); 182 | 183 | /** 184 | * Gets the interval of a timer. 185 | * The ID of the timer. 186 | * 0 for invalid timers or the interval (in miliseconds). 187 | */ 188 | native GetTimerInterval(timerid); 189 | 190 | /** 191 | * Gets the time remaining before this timer is called again. 192 | * The ID of the timer. 193 | * 0 for invalid timers or the time (in miliseconds) until the execution. 194 | */ 195 | native GetTimerIntervalLeft(timerid); 196 | 197 | /** 198 | * Sets the delay of a timer. 199 | * The ID of the timer. 200 | * The new delay. 201 | */ 202 | native SetTimerDelay(timerid, delay); 203 | 204 | /** 205 | * Sets the count of a timer. 206 | * The ID of the timer. 207 | * The new count. 208 | */ 209 | native SetTimerCount(timerid, count); 210 | 211 | /** 212 | * Gets the number of remaining calls of this timer. 213 | * The ID of the timer. 214 | * -1 for infinite timers, 0 for invalid ones and positive values for the others. 215 | */ 216 | native GetTimerCallsLeft(timerid); 217 | 218 | // Kills a player's timers on disconnect. 219 | public OnPlayerDisconnect(playerid, reason) { 220 | KillPlayerTimers(playerid); 221 | #if defined TIMERFIX_OnPlayerDisconnect 222 | return TIMERFIX_OnPlayerDisconnect(playerid, reason); 223 | #else 224 | return 1; 225 | #endif 226 | } 227 | #if defined _ALS_OnPlayerDisconnect 228 | #undef OnPlayerDisconnect 229 | #else 230 | #define _ALS_OnPlayerDisconnect 231 | #endif 232 | #define OnPlayerDisconnect TIMERFIX_OnPlayerDisconnect 233 | #if defined TIMERFIX_OnPlayerDisconnect 234 | forward TIMERFIX_OnPlayerDisconnect(playerid, reason); 235 | #endif 236 | --------------------------------------------------------------------------------