├── .github └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── CHANGES.md ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── docker ├── Dockerfile ├── build.sh └── docker-entrypoint.sh ├── pawn.json ├── src ├── CMakeLists.txt ├── callbacks.cpp ├── cell.cpp ├── cell.h ├── chunk-streamer.cpp ├── chunk-streamer.h ├── common.h ├── core.cpp ├── core.h ├── data.cpp ├── data.h ├── grid.cpp ├── grid.h ├── identifier.cpp ├── identifier.h ├── item.cpp ├── item.h ├── main.cpp ├── main.h ├── manipulation.h ├── manipulation │ ├── CMakeLists.txt │ ├── array.cpp │ ├── array.h │ ├── float.cpp │ ├── float.h │ ├── int.cpp │ └── int.h ├── natives.h ├── natives │ ├── CMakeLists.txt │ ├── actors.cpp │ ├── areas.cpp │ ├── checkpoints.cpp │ ├── deprecated.cpp │ ├── extended.cpp │ ├── manipulation.cpp │ ├── map-icons.cpp │ ├── miscellaneous.cpp │ ├── objects.cpp │ ├── pickups.cpp │ ├── race-checkpoints.cpp │ ├── settings.cpp │ ├── text-labels.cpp │ └── updates.cpp ├── player.cpp ├── player.h ├── sampgdk.c ├── sampgdk.h ├── streamer.cpp ├── streamer.h ├── utility.h └── utility │ ├── CMakeLists.txt │ ├── amx.cpp │ ├── amx.h │ ├── geometry.cpp │ ├── geometry.h │ ├── misc.cpp │ └── misc.h ├── streamer.def ├── streamer.inc └── streamer.rc /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - 'master' 8 | pull_request: 9 | branches: 10 | - '*' 11 | - '*/*' 12 | - '**' 13 | 14 | jobs: 15 | build-windows-release: 16 | runs-on: windows-2019 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | submodules: recursive 21 | 22 | - name: Declare github variables 23 | id: vars 24 | shell: bash 25 | run: | 26 | echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 27 | echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" 28 | 29 | - name: Setup Python 30 | uses: actions/setup-python@v2 31 | 32 | - name: Install CMake 33 | uses: lukka/get-cmake@v3.19.0 34 | 35 | - name: Generate build files 36 | run: mkdir build && cd build && cmake .. -G "Visual Studio 16 2019" -A Win32 37 | 38 | - name: Build 39 | run: | 40 | cd build 41 | cmake --build . --config Release 42 | 43 | - name: Get current time 44 | uses: josStorer/get-current-time@v2 45 | id: current-time 46 | with: 47 | format: YYYYMMDD 48 | 49 | - name: Upload artifacts 50 | uses: actions/upload-artifact@v4 51 | with: 52 | name: streamer-win-release-${{ steps.current-time.outputs.formattedTime }}-${{ steps.vars.outputs.sha_short }} 53 | path: build/bin/Release 54 | build-windows-debug: 55 | runs-on: windows-2019 56 | steps: 57 | - uses: actions/checkout@v4 58 | with: 59 | submodules: recursive 60 | 61 | - name: Declare github variables 62 | id: vars 63 | shell: bash 64 | run: | 65 | echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 66 | echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" 67 | 68 | - name: Setup Python 69 | uses: actions/setup-python@v2 70 | 71 | - name: Install CMake 72 | uses: lukka/get-cmake@v3.19.0 73 | 74 | - name: Generate build files 75 | run: mkdir build && cd build && cmake .. -G "Visual Studio 16 2019" -A Win32 76 | 77 | - name: Build 78 | run: | 79 | cd build 80 | cmake --build . --config Debug 81 | 82 | - name: Get current time 83 | uses: josStorer/get-current-time@v2 84 | id: current-time 85 | with: 86 | format: YYYYMMDD 87 | 88 | - name: Upload artifacts 89 | uses: actions/upload-artifact@v4 90 | with: 91 | name: streamer-win-debug-${{ steps.current-time.outputs.formattedTime }}-${{ steps.vars.outputs.sha_short }} 92 | path: build/bin/Debug 93 | build-linux: 94 | runs-on: ubuntu-latest 95 | 96 | strategy: 97 | matrix: 98 | config: [Debug, Release] 99 | 100 | steps: 101 | - uses: actions/checkout@v4 102 | with: 103 | submodules: recursive 104 | 105 | - name: Declare github variables 106 | id: vars 107 | shell: bash 108 | run: | 109 | echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 110 | echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" 111 | 112 | - name: Build 113 | run: | 114 | cd docker 115 | CONFIG=${{ matrix.config == 'Debug' && 'Debug' || 'MinSizeRel' }} ./build.sh 116 | 117 | - name: Get current time 118 | uses: josStorer/get-current-time@v2 119 | id: current-time 120 | with: 121 | format: YYYYMMDD 122 | 123 | - name: Upload artifacts 124 | uses: actions/upload-artifact@v4 125 | with: 126 | name: streamer-linux-${{ matrix.config == 'Debug' && 'debug' || 'release' }}-${{ steps.current-time.outputs.formattedTime }}-${{ steps.vars.outputs.sha_short }} 127 | path: docker/build/bin 128 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | build/ 18 | 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opendb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | *.VC.db 87 | *.VC.VC.opendb 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | *.sap 94 | 95 | # TFS 2012 Local Workspace 96 | $tf/ 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | *.DotSettings.user 105 | 106 | # JustCode is a .NET coding add-in 107 | .JustCode 108 | 109 | # TeamCity is a build add-in 110 | _TeamCity* 111 | 112 | # DotCover is a Code Coverage Tool 113 | *.dotCover 114 | 115 | # NCrunch 116 | _NCrunch_* 117 | .*crunch*.local.xml 118 | nCrunchTemp_* 119 | 120 | # MightyMoose 121 | *.mm.* 122 | AutoTest.Net/ 123 | 124 | # Web workbench (sass) 125 | .sass-cache/ 126 | 127 | # Installshield output folder 128 | [Ee]xpress/ 129 | 130 | # DocProject is a documentation generator add-in 131 | DocProject/buildhelp/ 132 | DocProject/Help/*.HxT 133 | DocProject/Help/*.HxC 134 | DocProject/Help/*.hhc 135 | DocProject/Help/*.hhk 136 | DocProject/Help/*.hhp 137 | DocProject/Help/Html2 138 | DocProject/Help/html 139 | 140 | # Click-Once directory 141 | publish/ 142 | 143 | # Publish Web Output 144 | *.[Pp]ublish.xml 145 | *.azurePubxml 146 | # TODO: Comment the next line if you want to checkin your web deploy settings 147 | # but database connection strings (with potential passwords) will be unencrypted 148 | #*.pubxml 149 | *.publishproj 150 | 151 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 152 | # checkin your Azure Web App publish settings, but sensitive information contained 153 | # in these scripts will be unencrypted 154 | PublishScripts/ 155 | 156 | # NuGet Packages 157 | *.nupkg 158 | # The packages folder can be ignored because of Package Restore 159 | **/packages/* 160 | # except build/, which is used as an MSBuild target. 161 | !**/packages/build/ 162 | # Uncomment if necessary however generally it will be regenerated when needed 163 | #!**/packages/repositories.config 164 | # NuGet v3's project.json files produces more ignoreable files 165 | *.nuget.props 166 | *.nuget.targets 167 | 168 | # Microsoft Azure Build Output 169 | csx/ 170 | *.build.csdef 171 | 172 | # Microsoft Azure Emulator 173 | ecf/ 174 | rcf/ 175 | 176 | # Windows Store app package directories and files 177 | AppPackages/ 178 | BundleArtifacts/ 179 | Package.StoreAssociation.xml 180 | _pkginfo.txt 181 | 182 | # Visual Studio cache files 183 | # files ending in .cache can be ignored 184 | *.[Cc]ache 185 | # but keep track of directories ending in .cache 186 | !*.[Cc]ache/ 187 | 188 | # Others 189 | ClientBin/ 190 | ~$* 191 | *~ 192 | *.dbmdl 193 | *.dbproj.schemaview 194 | *.jfm 195 | *.pfx 196 | *.publishsettings 197 | node_modules/ 198 | orleans.codegen.cs 199 | 200 | # Since there are multiple workflows, uncomment next line to ignore bower_components 201 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 202 | #bower_components/ 203 | 204 | # RIA/Silverlight projects 205 | Generated_Code/ 206 | 207 | # Backup & report files from converting an old project file 208 | # to a newer Visual Studio version. Backup files are not needed, 209 | # because we have git ;-) 210 | _UpgradeReport_Files/ 211 | Backup*/ 212 | UpgradeLog*.XML 213 | UpgradeLog*.htm 214 | 215 | # SQL Server files 216 | *.mdf 217 | *.ldf 218 | 219 | # Business Intelligence projects 220 | *.rdl.data 221 | *.bim.layout 222 | *.bim_*.settings 223 | 224 | # Microsoft Fakes 225 | FakesAssemblies/ 226 | 227 | # GhostDoc plugin setting file 228 | *.GhostDoc.xml 229 | 230 | # Node.js Tools for Visual Studio 231 | .ntvs_analysis.dat 232 | 233 | # Visual Studio 6 build log 234 | *.plg 235 | 236 | # Visual Studio 6 workspace options file 237 | *.opt 238 | 239 | # Visual Studio LightSwitch build output 240 | **/*.HTMLClient/GeneratedArtifacts 241 | **/*.DesktopClient/GeneratedArtifacts 242 | **/*.DesktopClient/ModelManifest.xml 243 | **/*.Server/GeneratedArtifacts 244 | **/*.Server/ModelManifest.xml 245 | _Pvt_Extensions 246 | 247 | # Paket dependency manager 248 | .paket/paket.exe 249 | paket-files/ 250 | 251 | # FAKE - F# Make 252 | .fake/ 253 | 254 | # JetBrains Rider 255 | .idea/ 256 | *.sln.iml 257 | 258 | # CodeRush 259 | .cr/ 260 | 261 | # Python Tools for Visual Studio (PTVS) 262 | __pycache__/ 263 | *.pyc 264 | 265 | /server/src/Networking/Legacy/CMakeFiles/*.stamp 266 | *.depend 267 | *.stamp 268 | *.list 269 | *.rule 270 | *.filters 271 | *.vcxproj 272 | *.cmake 273 | *.bin 274 | /Win32-Debug 275 | /includes/fmat 276 | /includes/gmock 277 | /includes/gtest 278 | /includes/logger 279 | /includes/pawn 280 | /includes/raknet 281 | /includes/server 282 | /includes/tinydir 283 | /includes/utils 284 | *.sln 285 | *.tlog 286 | /open.mp/Win32-Debug/temp/gtest/gtest.idb 287 | /open.mp/Win32-Debug 288 | /CMakeFiles 289 | *.pc 290 | /CMakeCache.txt 291 | *.amx 292 | *.i 293 | .vscode/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/cmake-modules"] 2 | path = lib/cmake-modules 3 | url = git@github.com:AmyrAhmady/samp-cmake-modules.git 4 | [submodule "lib/eigen"] 5 | path = lib/eigen 6 | url = git@github.com:eigenteam/eigen-git-mirror.git 7 | [submodule "lib/samp-plugin-sdk"] 8 | path = lib/samp-plugin-sdk 9 | url = git@github.com:AmyrAhmady/samp-plugin-sdk.git 10 | [submodule "lib/boost"] 11 | path = lib/boost 12 | url = git@github.com:scipy/boost-headers-only.git 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(streamer) 3 | 4 | set(PLUGIN_VERSION "2.9.6") 5 | set(CMAKE_CXX_STANDARD 17) 6 | 7 | if (MSVC) 8 | add_definitions("/MP") 9 | endif() 10 | 11 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") 12 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/lib/cmake-modules") 13 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/lib/eigen/cmake") 14 | 15 | set(SAMP_SDK_ROOT "${PROJECT_SOURCE_DIR}/lib/samp-plugin-sdk") 16 | find_package(SAMPSDK REQUIRED) 17 | include_directories(${SAMPSDK_DIR}) 18 | include_directories(${SAMPSDK_DIR}/amx) 19 | 20 | include_directories(${PROJECT_SOURCE_DIR}/lib/boost) 21 | 22 | if(EIGEN3_INCLUDE_DIR) 23 | file(TO_CMAKE_PATH ${EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | list(APPEND CMAKE_MODULE_PATH "${EIGEN3_INCLUDE_DIR}/cmake") 25 | else() 26 | set(EIGEN3_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/eigen") 27 | endif() 28 | 29 | find_package(Eigen3 3.3.4 REQUIRED) 30 | include_directories(${EIGEN3_INCLUDE_DIR}) 31 | 32 | set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY True) 33 | set(CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY True) 34 | 35 | add_subdirectory(src) 36 | 37 | set(CPACK_PACKAGE_VERSION ${PLUGIN_VERSION}) 38 | 39 | if(COMMIT_ID) 40 | string(TIMESTAMP CURRENT_DATE "%Y%m%d") 41 | set(PACKAGE_FILE_NAME streamer-${PLUGIN_VERSION}-${CURRENT_DATE}-${COMMIT_ID}) 42 | else() 43 | set(PACKAGE_FILE_NAME streamer-${PLUGIN_VERSION}) 44 | endif() 45 | 46 | set(CPACK_OUTPUT_FILE_PREFIX package/${PACKAGE_FILE_NAME}) 47 | 48 | if(WIN32) 49 | set(CPACK_PACKAGE_FILE_NAME ${PACKAGE_FILE_NAME}-win32) 50 | set(CPACK_GENERATOR ZIP) 51 | else() 52 | set(CPACK_PACKAGE_FILE_NAME ${PACKAGE_FILE_NAME}-linux) 53 | set(CPACK_GENERATOR TGZ) 54 | endif() 55 | 56 | if(CPACK_OUTPUT_FILE_POSTFIX) 57 | string(TOLOWER "${CPACK_OUTPUT_FILE_POSTFIX}" CPACK_OUTPUT_FILE_POSTFIX) 58 | set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}-${CPACK_OUTPUT_FILE_POSTFIX}) 59 | endif() 60 | 61 | include(CPack) 62 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SA-MP Streamer Plugin 2 | [![GitHub Release](https://img.shields.io/github/release/samp-incognito/samp-streamer-plugin.svg)](https://github.com/samp-incognito/samp-streamer-plugin/releases/latest) [![Build Status](https://github.com/samp-incognito/samp-streamer-plugin/actions/workflows/build.yml/badge.svg)](https://github.com/samp-incognito/samp-streamer-plugin/actions/workflows/build.yml) 3 | 4 | This plugin streams objects, pickups, checkpoints, race checkpoints, map icons, 3D text labels, and actors at user-defined server ticks. Basic area detection is also included. Because it is written entirely in C++, much of the overhead from PAWN is avoided. This streamer, as a result, is quite a bit faster than any other implementation currently available in PAWN. 5 | 6 | ## Documentation 7 | 8 | Documentation can be found on the [wiki](https://github.com/samp-incognito/samp-streamer-plugin/wiki). 9 | 10 | ## Download 11 | 12 | The latest binaries for Windows and Linux can be found on the [releases page](https://github.com/samp-incognito/samp-streamer-plugin/releases). 13 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | RUN \ 3 | dpkg --add-architecture i386 && \ 4 | apt-get update && \ 5 | apt-get install -y \ 6 | gpg \ 7 | wget \ 8 | && \ 9 | wget -O- https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | \ 10 | gpg --dearmor - | \ 11 | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null && \ 12 | echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | \ 13 | tee /etc/apt/sources.list.d/kitware.list >/dev/null && \ 14 | apt-get update && \ 15 | apt-get install -y \ 16 | cmake \ 17 | ninja-build \ 18 | g++-multilib \ 19 | libstdc++6:i386 \ 20 | libc6:i386 \ 21 | && \ 22 | useradd -m user 23 | 24 | USER user 25 | 26 | ENV PATH=~/.local/bin:${PATH} 27 | 28 | COPY docker-entrypoint.sh / 29 | CMD /docker-entrypoint.sh 30 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Available configs: Debug, RelWithDebInfo, [Release] 4 | [[ -z "$CONFIG" ]] \ 5 | && config=Release \ 6 | || config="$CONFIG" 7 | 8 | docker build \ 9 | -t streamer-omp/build:ubuntu-18.04 ./ \ 10 | || exit 1 11 | 12 | folders=('build') 13 | for folder in "${folders[@]}"; do 14 | if [[ ! -d "./${folder}" ]]; then 15 | mkdir ${folder} 16 | fi 17 | sudo chown -R 1000:1000 ${folder} || exit 1 18 | done 19 | 20 | docker run \ 21 | --rm \ 22 | -t \ 23 | -w /code \ 24 | -v $PWD/..:/code \ 25 | -v $PWD/build:/code/build \ 26 | -e CONFIG=${config} \ 27 | streamer-omp/build:ubuntu-18.04 28 | -------------------------------------------------------------------------------- /docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | [ -z $CONFIG ] && config=Release || config="$CONFIG" 3 | 4 | cmake \ 5 | -S . \ 6 | -B build \ 7 | -G Ninja \ 8 | -DCMAKE_BUILD_TYPE=$config \ 9 | && 10 | cmake \ 11 | --build build \ 12 | --config $config \ 13 | --parallel $(nproc) 14 | -------------------------------------------------------------------------------- /pawn.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": "samp-incognito", 3 | "repo": "samp-streamer-plugin", 4 | "resources": [ 5 | { 6 | "name": "^samp-streamer-plugin-(.*).zip$", 7 | "platform": "linux", 8 | "archive": true, 9 | "includes": ["pawno/include"], 10 | "plugins": ["plugins/streamer.so"] 11 | }, 12 | { 13 | "name": "^samp-streamer-plugin-(.*).zip$", 14 | "platform": "windows", 15 | "archive": true, 16 | "includes": ["pawno/include"], 17 | "plugins": ["plugins/streamer.dll"] 18 | } 19 | ], 20 | "runtime": { 21 | "plugins": ["samp-incognito/samp-streamer-plugin"] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(AMXConfig) 2 | include(AddSAMPPlugin) 3 | 4 | set(PLUGIN_SOURCES ${SAMPSDK_DIR}/amxplugin.cpp) 5 | 6 | add_subdirectory(manipulation) 7 | add_subdirectory(natives) 8 | add_subdirectory(utility) 9 | 10 | list(APPEND PLUGIN_SOURCES 11 | callbacks.cpp 12 | cell.cpp 13 | chunk-streamer.cpp 14 | core.cpp 15 | data.cpp 16 | grid.cpp 17 | identifier.cpp 18 | item.cpp 19 | main.cpp 20 | player.cpp 21 | sampgdk.c 22 | streamer.cpp 23 | ) 24 | 25 | if(WIN32) 26 | list(APPEND PLUGIN_SOURCES 27 | ${PROJECT_SOURCE_DIR}/streamer.def 28 | ${PROJECT_SOURCE_DIR}/streamer.rc 29 | ) 30 | endif() 31 | 32 | add_samp_plugin(${PROJECT_NAME} ${PLUGIN_SOURCES}) 33 | 34 | if(WIN32) 35 | add_definitions(-DNOMINMAX) 36 | else() 37 | set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-strict-aliasing") 38 | set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " -lrt") 39 | endif() 40 | 41 | add_definitions(-DSAMPGDK_AMALGAMATION -DSAMPGDK_CPP_WRAPPERS -D_SILENCE_CXX17_NEGATORS_DEPRECATION_WARNING -D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING) 42 | 43 | set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 44 | target_link_libraries(${PROJECT_NAME}) 45 | 46 | install(TARGETS ${PROJECT_NAME} DESTINATION bin) 47 | -------------------------------------------------------------------------------- /src/callbacks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "core.h" 20 | 21 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerConnect(int playerid) 22 | { 23 | if (playerid >= 0 && playerid < MAX_PLAYERS) 24 | { 25 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 26 | if (p == core->getData()->players.end()) 27 | { 28 | Player player(playerid); 29 | core->getData()->players.insert(std::make_pair(playerid, player)); 30 | } 31 | } 32 | return true; 33 | } 34 | 35 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerDisconnect(int playerid, int reason) 36 | { 37 | core->getData()->players.erase(playerid); 38 | return true; 39 | } 40 | 41 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerSpawn(int playerid) 42 | { 43 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 44 | if (p != core->getData()->players.end()) 45 | { 46 | p->second.requestingClass = false; 47 | } 48 | return true; 49 | } 50 | 51 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerRequestClass(int playerid, int classid) 52 | { 53 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 54 | if (p != core->getData()->players.end()) 55 | { 56 | p->second.requestingClass = true; 57 | } 58 | return true; 59 | } 60 | 61 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerEnterCheckpoint(int playerid) 62 | { 63 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 64 | if (p != core->getData()->players.end()) 65 | { 66 | if (p->second.activeCheckpoint != p->second.visibleCheckpoint) 67 | { 68 | int checkpointid = p->second.visibleCheckpoint; 69 | p->second.activeCheckpoint = checkpointid; 70 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 71 | { 72 | int amxIndex = 0; 73 | if (!amx_FindPublic(*a, "OnPlayerEnterDynamicCP", &amxIndex)) 74 | { 75 | amx_Push(*a, static_cast(checkpointid)); 76 | amx_Push(*a, static_cast(playerid)); 77 | amx_Exec(*a, NULL, amxIndex); 78 | } 79 | } 80 | } 81 | } 82 | return true; 83 | } 84 | 85 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerLeaveCheckpoint(int playerid) 86 | { 87 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 88 | if (p != core->getData()->players.end()) 89 | { 90 | if (p->second.activeCheckpoint == p->second.visibleCheckpoint) 91 | { 92 | int checkpointid = p->second.activeCheckpoint; 93 | p->second.activeCheckpoint = 0; 94 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 95 | { 96 | int amxIndex = 0; 97 | if (!amx_FindPublic(*a, "OnPlayerLeaveDynamicCP", &amxIndex)) 98 | { 99 | amx_Push(*a, static_cast(checkpointid)); 100 | amx_Push(*a, static_cast(playerid)); 101 | amx_Exec(*a, NULL, amxIndex); 102 | } 103 | } 104 | } 105 | } 106 | return true; 107 | } 108 | 109 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerEnterRaceCheckpoint(int playerid) 110 | { 111 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 112 | if (p != core->getData()->players.end()) 113 | { 114 | if (p->second.activeRaceCheckpoint != p->second.visibleRaceCheckpoint) 115 | { 116 | int checkpointid = p->second.visibleRaceCheckpoint; 117 | p->second.activeRaceCheckpoint = checkpointid; 118 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 119 | { 120 | int amxIndex = 0; 121 | if (!amx_FindPublic(*a, "OnPlayerEnterDynamicRaceCP", &amxIndex)) 122 | { 123 | amx_Push(*a, static_cast(checkpointid)); 124 | amx_Push(*a, static_cast(playerid)); 125 | amx_Exec(*a, NULL, amxIndex); 126 | } 127 | } 128 | } 129 | } 130 | return true; 131 | } 132 | 133 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerLeaveRaceCheckpoint(int playerid) 134 | { 135 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 136 | if (p != core->getData()->players.end()) 137 | { 138 | if (p->second.activeRaceCheckpoint == p->second.visibleRaceCheckpoint) 139 | { 140 | int checkpointid = p->second.activeRaceCheckpoint; 141 | p->second.activeRaceCheckpoint = 0; 142 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 143 | { 144 | int amxIndex = 0; 145 | if (!amx_FindPublic(*a, "OnPlayerLeaveDynamicRaceCP", &amxIndex)) 146 | { 147 | amx_Push(*a, static_cast(checkpointid)); 148 | amx_Push(*a, static_cast(playerid)); 149 | amx_Exec(*a, NULL, amxIndex); 150 | } 151 | } 152 | } 153 | } 154 | return true; 155 | } 156 | 157 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerPickUpPickup(int playerid, int pickupid) 158 | { 159 | for (std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalPickups.begin(); i != core->getData()->internalPickups.end(); ++i) 160 | { 161 | if (i->second == pickupid) 162 | { 163 | int dynPickupId = i->first.first; 164 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 165 | { 166 | int amxIndex = 0; 167 | if (!amx_FindPublic(*a, "OnPlayerPickUpDynamicPickup", &amxIndex)) 168 | { 169 | amx_Push(*a, static_cast(dynPickupId)); 170 | amx_Push(*a, static_cast(playerid)); 171 | amx_Exec(*a, NULL, amxIndex); 172 | } 173 | } 174 | break; 175 | } 176 | } 177 | return true; 178 | } 179 | 180 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerEditObject(int playerid, bool playerobject, int objectid, int response, float fX, float fY, float fZ, float fRotX, float fRotY, float fRotZ) 181 | { 182 | if (playerobject) 183 | { 184 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 185 | if (p != core->getData()->players.end()) 186 | { 187 | for (std::unordered_map::iterator i = p->second.internalObjects.begin(); i != p->second.internalObjects.end(); ++i) 188 | { 189 | if (i->second == objectid) 190 | { 191 | int dynObjectId = i->first; 192 | if (response == EDIT_RESPONSE_CANCEL || response == EDIT_RESPONSE_FINAL) 193 | { 194 | std::unordered_map::iterator o = core->getData()->objects.find(dynObjectId); 195 | if (o != core->getData()->objects.end()) 196 | { 197 | if (o->second->comparableStreamDistance < STREAMER_STATIC_DISTANCE_CUTOFF && o->second->originalComparableStreamDistance > STREAMER_STATIC_DISTANCE_CUTOFF) 198 | { 199 | o->second->comparableStreamDistance = o->second->originalComparableStreamDistance; 200 | o->second->originalComparableStreamDistance = -1.0f; 201 | } 202 | } 203 | } 204 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 205 | { 206 | int amxIndex = 0; 207 | cell amxRetVal = 0; 208 | if (!amx_FindPublic(*a, "OnPlayerEditDynamicObject", &amxIndex)) 209 | { 210 | amx_Push(*a, amx_ftoc(fRotZ)); 211 | amx_Push(*a, amx_ftoc(fRotY)); 212 | amx_Push(*a, amx_ftoc(fRotX)); 213 | amx_Push(*a, amx_ftoc(fZ)); 214 | amx_Push(*a, amx_ftoc(fY)); 215 | amx_Push(*a, amx_ftoc(fX)); 216 | amx_Push(*a, static_cast(response)); 217 | amx_Push(*a, static_cast(dynObjectId)); 218 | amx_Push(*a, static_cast(playerid)); 219 | amx_Exec(*a, &amxRetVal, amxIndex); 220 | if (amxRetVal) 221 | { 222 | break; 223 | } 224 | } 225 | } 226 | return true; 227 | } 228 | } 229 | } 230 | } 231 | return false; 232 | } 233 | 234 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerSelectObject(int playerid, int type, int objectid, int modelid, float x, float y, float z) 235 | { 236 | if (type == SELECT_OBJECT_PLAYER_OBJECT) 237 | { 238 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 239 | if (p != core->getData()->players.end()) 240 | { 241 | for (std::unordered_map::iterator i = p->second.internalObjects.begin(); i != p->second.internalObjects.end(); ++i) 242 | { 243 | if (i->second == objectid) 244 | { 245 | int dynObjectId = i->first; 246 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 247 | { 248 | int amxIndex = 0; 249 | cell amxRetVal = 0; 250 | if (!amx_FindPublic(*a, "OnPlayerSelectDynamicObject", &amxIndex)) 251 | { 252 | amx_Push(*a, amx_ftoc(z)); 253 | amx_Push(*a, amx_ftoc(y)); 254 | amx_Push(*a, amx_ftoc(x)); 255 | amx_Push(*a, static_cast(modelid)); 256 | amx_Push(*a, static_cast(dynObjectId)); 257 | amx_Push(*a, static_cast(playerid)); 258 | amx_Exec(*a, &amxRetVal, amxIndex); 259 | if (amxRetVal) 260 | { 261 | break; 262 | } 263 | } 264 | } 265 | return true; 266 | } 267 | } 268 | } 269 | } 270 | return false; 271 | } 272 | 273 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerWeaponShot(int playerid, int weaponid, int hittype, int hitid, float x, float y, float z) 274 | { 275 | bool retVal = true; 276 | if (hittype == BULLET_HIT_TYPE_PLAYER_OBJECT) 277 | { 278 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 279 | if (p != core->getData()->players.end()) 280 | { 281 | for (std::unordered_map::iterator i = p->second.internalObjects.begin(); i != p->second.internalObjects.end(); ++i) 282 | { 283 | if (i->second == hitid) 284 | { 285 | int objectid = i->first; 286 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 287 | { 288 | int amxIndex = 0; 289 | cell amxRetVal = 0; 290 | if (!amx_FindPublic(*a, "OnPlayerShootDynamicObject", &amxIndex)) 291 | { 292 | amx_Push(*a, amx_ftoc(z)); 293 | amx_Push(*a, amx_ftoc(y)); 294 | amx_Push(*a, amx_ftoc(x)); 295 | amx_Push(*a, static_cast(objectid)); 296 | amx_Push(*a, static_cast(weaponid)); 297 | amx_Push(*a, static_cast(playerid)); 298 | amx_Exec(*a, &amxRetVal, amxIndex); 299 | if (!amxRetVal) 300 | { 301 | retVal = false; 302 | } 303 | } 304 | } 305 | break; 306 | } 307 | } 308 | } 309 | } 310 | return retVal; 311 | } 312 | 313 | PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerGiveDamageActor(int playerid, int actorid, float amount, int weaponid, int bodypart) 314 | { 315 | for (std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalActors.begin(); i != core->getData()->internalActors.end(); ++i) 316 | { 317 | if (i->second == actorid) 318 | { 319 | int dynActorId = i->first.first; 320 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 321 | { 322 | int amxIndex = 0; 323 | cell amxRetVal = 0; 324 | if (!amx_FindPublic(*a, "OnPlayerGiveDamageDynamicActor", &amxIndex)) 325 | { 326 | amx_Push(*a, static_cast(bodypart)); 327 | amx_Push(*a, static_cast(weaponid)); 328 | amx_Push(*a, amx_ftoc(amount)); 329 | amx_Push(*a, static_cast(dynActorId)); 330 | amx_Push(*a, static_cast(playerid)); 331 | amx_Exec(*a, &amxRetVal, amxIndex); 332 | if (amxRetVal) 333 | { 334 | break; 335 | } 336 | } 337 | } 338 | return true; 339 | } 340 | } 341 | return false; 342 | } 343 | 344 | PLUGIN_EXPORT bool PLUGIN_CALL OnActorStreamIn(int actorid, int forplayerid) 345 | { 346 | for (std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalActors.begin(); i != core->getData()->internalActors.end(); ++i) 347 | { 348 | if (i->second == actorid) 349 | { 350 | int dynActorId = i->first.first; 351 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 352 | { 353 | int amxIndex = 0; 354 | if (!amx_FindPublic(*a, "OnDynamicActorStreamIn", &amxIndex)) 355 | { 356 | amx_Push(*a, static_cast(forplayerid)); 357 | amx_Push(*a, static_cast(dynActorId)); 358 | amx_Exec(*a, NULL, amxIndex); 359 | } 360 | } 361 | break; 362 | } 363 | } 364 | return true; 365 | } 366 | 367 | PLUGIN_EXPORT bool PLUGIN_CALL OnActorStreamOut(int actorid, int forplayerid) 368 | { 369 | for (std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalActors.begin(); i != core->getData()->internalActors.end(); ++i) 370 | { 371 | if (i->second == actorid) 372 | { 373 | int dynActorId = i->first.first; 374 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 375 | { 376 | int amxIndex = 0; 377 | if (!amx_FindPublic(*a, "OnDynamicActorStreamOut", &amxIndex)) 378 | { 379 | amx_Push(*a, static_cast(forplayerid)); 380 | amx_Push(*a, static_cast(dynActorId)); 381 | amx_Exec(*a, NULL, amxIndex); 382 | } 383 | } 384 | break; 385 | } 386 | } 387 | return true; 388 | } 389 | -------------------------------------------------------------------------------- /src/cell.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "cell.h" 20 | 21 | Cell::Cell() : references(0) {} 22 | Cell::Cell(CellId passedCellId) : cellId(passedCellId), references(0) {} 23 | -------------------------------------------------------------------------------- /src/cell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CELL_H 18 | #define CELL_H 19 | 20 | #include "item.h" 21 | 22 | class Cell 23 | { 24 | public: 25 | Cell(); 26 | Cell(CellId cellId); 27 | 28 | CellId cellId; 29 | int references; 30 | 31 | std::unordered_map actors; 32 | std::unordered_map areas; 33 | std::unordered_map checkpoints; 34 | std::unordered_map mapIcons; 35 | std::unordered_map objects; 36 | std::unordered_map pickups; 37 | std::unordered_map raceCheckpoints; 38 | std::unordered_map textLabels; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/chunk-streamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CHUNK_STREAMER_H 18 | #define CHUNK_STREAMER_H 19 | 20 | #include "cell.h" 21 | #include "player.h" 22 | #include "streamer.h" 23 | 24 | #include 25 | 26 | class ChunkStreamer : public Streamer 27 | { 28 | public: 29 | ChunkStreamer(); 30 | 31 | inline bool getChunkStreamingEnabled() 32 | { 33 | return chunkStreamingEnabled; 34 | } 35 | 36 | inline void setChunkStreamingEnabled(bool enabled) 37 | { 38 | chunkStreamingEnabled = enabled; 39 | } 40 | 41 | void performPlayerChunkUpdate(Player &player, bool automatic); 42 | 43 | void discoverMapIcons(Player &player, const std::vector &cells); 44 | void discoverObjects(Player &player, const std::vector &cells); 45 | void discoverTextLabels(Player &player, const std::vector &cells); 46 | 47 | std::size_t getChunkSize(int type); 48 | bool setChunkSize(int type, std::size_t value); 49 | private: 50 | void streamMapIcons(Player &player, bool automatic); 51 | void streamObjects(Player &player, bool automatic); 52 | void streamTextLabels(Player &player, bool automatic); 53 | 54 | std::size_t chunkSize[STREAMER_MAX_TYPES]; 55 | bool chunkStreamingEnabled; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef COMMON_H 18 | #define COMMON_H 19 | 20 | #define INVALID_PICKUP_ID (-1) 21 | #define INVALID_STREAMER_ID (0) 22 | 23 | #define STREAMER_MAX_TYPES (8) 24 | 25 | #define STREAMER_TYPE_OBJECT (0) 26 | #define STREAMER_TYPE_PICKUP (1) 27 | #define STREAMER_TYPE_CP (2) 28 | #define STREAMER_TYPE_RACE_CP (3) 29 | #define STREAMER_TYPE_MAP_ICON (4) 30 | #define STREAMER_TYPE_3D_TEXT_LABEL (5) 31 | #define STREAMER_TYPE_AREA (6) 32 | #define STREAMER_TYPE_ACTOR (7) 33 | 34 | #define STREAMER_MAX_AREA_TYPES (6) 35 | 36 | #define STREAMER_AREA_TYPE_CIRCLE (0) 37 | #define STREAMER_AREA_TYPE_CYLINDER (1) 38 | #define STREAMER_AREA_TYPE_SPHERE (2) 39 | #define STREAMER_AREA_TYPE_RECTANGLE (3) 40 | #define STREAMER_AREA_TYPE_CUBOID (4) 41 | #define STREAMER_AREA_TYPE_POLYGON (5) 42 | 43 | #define STREAMER_MAX_OBJECT_TYPES (3) 44 | 45 | #define STREAMER_OBJECT_TYPE_GLOBAL (0) 46 | #define STREAMER_OBJECT_TYPE_PLAYER (1) 47 | #define STREAMER_OBJECT_TYPE_DYNAMIC (2) 48 | 49 | #define STREAMER_STATIC_DISTANCE_CUTOFF (0.0f) 50 | 51 | class Cell; 52 | class Data; 53 | class Events; 54 | class Grid; 55 | class Identifier; 56 | struct Player; 57 | class Streamer; 58 | 59 | typedef std::pair CellId; 60 | typedef std::shared_ptr SharedCell; 61 | 62 | typedef boost::geometry::model::box Box2d; 63 | typedef boost::geometry::model::box Box3d; 64 | typedef boost::geometry::model::polygon Polygon2d; 65 | 66 | namespace Item 67 | { 68 | struct Actor; 69 | struct Area; 70 | struct Checkpoint; 71 | struct MapIcon; 72 | struct Object; 73 | struct Pickup; 74 | struct RaceCheckpoint; 75 | struct TextLabel; 76 | 77 | typedef std::shared_ptr SharedActor; 78 | typedef std::shared_ptr SharedArea; 79 | typedef std::shared_ptr SharedCheckpoint; 80 | typedef std::shared_ptr SharedMapIcon; 81 | typedef std::shared_ptr SharedObject; 82 | typedef std::shared_ptr SharedPickup; 83 | typedef std::shared_ptr SharedRaceCheckpoint; 84 | typedef std::shared_ptr SharedTextLabel; 85 | 86 | template 87 | struct Hash 88 | { 89 | std::size_t operator()(std::tuple const &t) const 90 | { 91 | std::size_t seed = 0; 92 | boost::hash_combine(seed, std::get<0>(t)); 93 | boost::hash_combine(seed, std::get<1>(t)); 94 | return seed; 95 | } 96 | }; 97 | 98 | struct PairCompare 99 | { 100 | bool operator()(std::pair const &a, std::pair const &b) const 101 | { 102 | if (a.first != b.first) 103 | { 104 | return a.first > b.first; 105 | } 106 | return a.second < b.second; 107 | } 108 | }; 109 | 110 | template 111 | struct LeftTupleCompare 112 | { 113 | bool operator()(std::tuple const &a, std::tuple const &b) const 114 | { 115 | if (std::get<0>(a) != std::get<0>(b)) 116 | { 117 | return std::get<0>(a) > std::get<0>(b); 118 | } 119 | return std::get<1>(a) < std::get<1>(b); 120 | } 121 | }; 122 | 123 | template 124 | struct RightTupleCompare 125 | { 126 | bool operator()(std::tuple const &a, std::tuple const &b) const 127 | { 128 | return std::get<0>(a) == std::get<0>(b) && std::get<1>(a) == std::get<1>(b); 129 | } 130 | }; 131 | 132 | template 133 | struct Bimap 134 | { 135 | typedef boost::bimap, LeftTupleCompare >, boost::bimaps::unordered_set_of, Hash, RightTupleCompare > > Type; 136 | }; 137 | } 138 | 139 | namespace boost { namespace geometry { namespace traits { 140 | template 141 | struct tag > 142 | { 143 | typedef point_tag type; 144 | }; 145 | 146 | template 147 | struct coordinate_type > 148 | { 149 | typedef _Scalar type; 150 | }; 151 | 152 | template 153 | struct coordinate_system > 154 | { 155 | typedef cs::cartesian type; 156 | }; 157 | 158 | template 159 | struct dimension > : boost::mpl::int_<_Rows> {}; 160 | 161 | template 162 | struct access, Dimension> 163 | { 164 | static inline _Scalar get(Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> const &matrix) 165 | { 166 | return matrix[Dimension]; 167 | } 168 | 169 | static inline void set(Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> &matrix, _Scalar const &value) 170 | { 171 | matrix[Dimension] = value; 172 | } 173 | }; 174 | }}} 175 | 176 | struct pair_hash 177 | { 178 | template 179 | std::size_t operator () (std::pair const& pair) const 180 | { 181 | std::size_t h1 = std::hash()(pair.first); 182 | std::size_t h2 = std::hash()(pair.second); 183 | 184 | return h1 ^ h2; 185 | } 186 | }; 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /src/core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "core.h" 20 | 21 | std::unique_ptr core; 22 | 23 | Core::Core() 24 | { 25 | data.reset(new Data); 26 | grid.reset(new Grid); 27 | chunkStreamer.reset(new ChunkStreamer); 28 | streamer.reset(new Streamer); 29 | } 30 | -------------------------------------------------------------------------------- /src/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CORE_H 18 | #define CORE_H 19 | 20 | #include "chunk-streamer.h" 21 | #include "data.h" 22 | #include "grid.h" 23 | #include "streamer.h" 24 | 25 | class Core 26 | { 27 | public: 28 | Core(); 29 | 30 | inline Data *getData() 31 | { 32 | return data.get(); 33 | } 34 | 35 | inline Grid *getGrid() 36 | { 37 | return grid.get(); 38 | } 39 | 40 | inline ChunkStreamer *getChunkStreamer() 41 | { 42 | return chunkStreamer.get(); 43 | } 44 | 45 | inline Streamer *getStreamer() 46 | { 47 | return streamer.get(); 48 | } 49 | private: 50 | std::unique_ptr data; 51 | std::unique_ptr grid; 52 | 53 | std::unique_ptr chunkStreamer; 54 | std::unique_ptr streamer; 55 | }; 56 | 57 | extern std::unique_ptr core; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/data.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "data.h" 20 | 21 | Data::Data() 22 | { 23 | errorCallbackEnabled = false; 24 | globalChunkTickRate[STREAMER_TYPE_OBJECT] = 1; 25 | globalChunkTickRate[STREAMER_TYPE_MAP_ICON] = 1; 26 | globalChunkTickRate[STREAMER_TYPE_3D_TEXT_LABEL] = 1; 27 | globalMaxItems[STREAMER_TYPE_OBJECT] = std::numeric_limits::max(); 28 | globalMaxItems[STREAMER_TYPE_PICKUP] = std::numeric_limits::max(); 29 | globalMaxItems[STREAMER_TYPE_CP] = std::numeric_limits::max(); 30 | globalMaxItems[STREAMER_TYPE_RACE_CP] = std::numeric_limits::max(); 31 | globalMaxItems[STREAMER_TYPE_MAP_ICON] = std::numeric_limits::max(); 32 | globalMaxItems[STREAMER_TYPE_3D_TEXT_LABEL] = std::numeric_limits::max(); 33 | globalMaxItems[STREAMER_TYPE_AREA] = std::numeric_limits::max(); 34 | globalMaxItems[STREAMER_TYPE_ACTOR] = std::numeric_limits::max(); 35 | globalMaxVisibleItems[STREAMER_TYPE_OBJECT] = 500; 36 | globalMaxVisibleItems[STREAMER_TYPE_PICKUP] = 4096; 37 | globalMaxVisibleItems[STREAMER_TYPE_MAP_ICON] = 100; 38 | globalMaxVisibleItems[STREAMER_TYPE_3D_TEXT_LABEL] = 1024; 39 | globalMaxVisibleItems[STREAMER_TYPE_ACTOR] = 1000; 40 | globalRadiusMultipliers[STREAMER_TYPE_OBJECT] = 1.0f; 41 | globalRadiusMultipliers[STREAMER_TYPE_PICKUP] = 1.0f; 42 | globalRadiusMultipliers[STREAMER_TYPE_CP] = 1.0f; 43 | globalRadiusMultipliers[STREAMER_TYPE_RACE_CP] = 1.0f; 44 | globalRadiusMultipliers[STREAMER_TYPE_MAP_ICON] = 1.0f; 45 | globalRadiusMultipliers[STREAMER_TYPE_3D_TEXT_LABEL] = 1.0f; 46 | globalRadiusMultipliers[STREAMER_TYPE_AREA] = 1.0f; 47 | globalRadiusMultipliers[STREAMER_TYPE_ACTOR] = 1.0f; 48 | static const int defaultTypePriority[] = 49 | { 50 | STREAMER_TYPE_AREA, 51 | STREAMER_TYPE_OBJECT, 52 | STREAMER_TYPE_CP, 53 | STREAMER_TYPE_RACE_CP, 54 | STREAMER_TYPE_MAP_ICON, 55 | STREAMER_TYPE_3D_TEXT_LABEL, 56 | STREAMER_TYPE_PICKUP, 57 | STREAMER_TYPE_ACTOR 58 | }; 59 | for (std::size_t i = 0; i < sizeof(defaultTypePriority) / sizeof(const int); ++i) 60 | { 61 | typePriority.push_back(defaultTypePriority[i]); 62 | } 63 | } 64 | 65 | std::size_t Data::getGlobalChunkTickRate(int type) 66 | { 67 | if (type >= 0 && type < STREAMER_MAX_TYPES) 68 | { 69 | return globalChunkTickRate[type]; 70 | } 71 | return 0; 72 | } 73 | 74 | bool Data::setGlobalChunkTickRate(int type, std::size_t value) 75 | { 76 | if (type >= 0 && type < STREAMER_MAX_TYPES) 77 | { 78 | globalChunkTickRate[type] = value; 79 | return true; 80 | } 81 | return false; 82 | } 83 | 84 | std::size_t Data::getGlobalMaxItems(int type) 85 | { 86 | if (type >= 0 && type < STREAMER_MAX_TYPES) 87 | { 88 | return globalMaxItems[type]; 89 | } 90 | return 0; 91 | } 92 | 93 | bool Data::setGlobalMaxItems(int type, std::size_t value) 94 | { 95 | if (type >= 0 && type < STREAMER_MAX_TYPES) 96 | { 97 | globalMaxItems[type] = value; 98 | return true; 99 | } 100 | return false; 101 | } 102 | 103 | std::size_t Data::getGlobalMaxVisibleItems(int type) 104 | { 105 | switch (type) 106 | { 107 | case STREAMER_TYPE_OBJECT: 108 | { 109 | return globalMaxVisibleItems[STREAMER_TYPE_OBJECT]; 110 | } 111 | case STREAMER_TYPE_PICKUP: 112 | { 113 | return globalMaxVisibleItems[STREAMER_TYPE_PICKUP]; 114 | } 115 | case STREAMER_TYPE_MAP_ICON: 116 | { 117 | return globalMaxVisibleItems[STREAMER_TYPE_MAP_ICON]; 118 | } 119 | case STREAMER_TYPE_3D_TEXT_LABEL: 120 | { 121 | return globalMaxVisibleItems[STREAMER_TYPE_3D_TEXT_LABEL]; 122 | } 123 | case STREAMER_TYPE_ACTOR: 124 | { 125 | return globalMaxVisibleItems[STREAMER_TYPE_ACTOR]; 126 | } 127 | } 128 | return 0; 129 | } 130 | 131 | bool Data::setGlobalMaxVisibleItems(int type, std::size_t value) 132 | { 133 | switch (type) 134 | { 135 | case STREAMER_TYPE_OBJECT: 136 | { 137 | globalMaxVisibleItems[STREAMER_TYPE_OBJECT] = value; 138 | return true; 139 | } 140 | case STREAMER_TYPE_PICKUP: 141 | { 142 | globalMaxVisibleItems[STREAMER_TYPE_PICKUP] = value; 143 | return true; 144 | } 145 | case STREAMER_TYPE_MAP_ICON: 146 | { 147 | globalMaxVisibleItems[STREAMER_TYPE_MAP_ICON] = value; 148 | return true; 149 | } 150 | case STREAMER_TYPE_3D_TEXT_LABEL: 151 | { 152 | globalMaxVisibleItems[STREAMER_TYPE_3D_TEXT_LABEL] = value; 153 | return true; 154 | } 155 | case STREAMER_TYPE_ACTOR: 156 | { 157 | globalMaxVisibleItems[STREAMER_TYPE_ACTOR] = value; 158 | return true; 159 | } 160 | } 161 | return false; 162 | } 163 | 164 | float Data::getGlobalRadiusMultiplier(int type) 165 | { 166 | if (type >= 0 && type < STREAMER_MAX_TYPES) 167 | { 168 | return globalRadiusMultipliers[type]; 169 | } 170 | return 0; 171 | } 172 | 173 | bool Data::setGlobalRadiusMultiplier(int type, float value) 174 | { 175 | if (type >= 0 && type < STREAMER_MAX_TYPES) 176 | { 177 | globalRadiusMultipliers[type] = value; 178 | return true; 179 | } 180 | return false; 181 | } 182 | -------------------------------------------------------------------------------- /src/data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DATA_H 18 | #define DATA_H 19 | 20 | #include "player.h" 21 | 22 | class Data 23 | { 24 | public: 25 | Data(); 26 | 27 | std::size_t getGlobalChunkTickRate(int type); 28 | bool setGlobalChunkTickRate(int type, std::size_t value); 29 | 30 | std::size_t getGlobalMaxItems(int type); 31 | bool setGlobalMaxItems(int type, std::size_t value); 32 | 33 | std::size_t getGlobalMaxVisibleItems(int type); 34 | bool setGlobalMaxVisibleItems(int type, std::size_t value); 35 | 36 | float getGlobalRadiusMultiplier(int type); 37 | bool setGlobalRadiusMultiplier(int type, float value); 38 | 39 | bool errorCallbackEnabled; 40 | 41 | std::set interfaces; 42 | std::set amxUnloadDestroyItems; 43 | 44 | std::vector destroyedActors; 45 | 46 | std::unordered_map, Item::SharedActor, pair_hash> discoveredActors; 47 | std::unordered_map, Item::SharedPickup, pair_hash> discoveredPickups; 48 | 49 | std::unordered_map, int, pair_hash> internalActors; 50 | std::unordered_map, int, pair_hash> internalPickups; 51 | 52 | std::unordered_map actors; 53 | std::unordered_map areas; 54 | std::unordered_map checkpoints; 55 | std::unordered_map mapIcons; 56 | std::unordered_map objects; 57 | std::unordered_map pickups; 58 | std::unordered_map raceCheckpoints; 59 | std::unordered_map textLabels; 60 | 61 | std::unordered_map players; 62 | 63 | std::vector typePriority; 64 | private: 65 | std::size_t globalChunkTickRate[STREAMER_MAX_TYPES]; 66 | std::size_t globalMaxItems[STREAMER_MAX_TYPES]; 67 | std::size_t globalMaxVisibleItems[STREAMER_MAX_TYPES]; 68 | float globalRadiusMultipliers[STREAMER_MAX_TYPES]; 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/grid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef GRID_H 18 | #define GRID_H 19 | 20 | #include "cell.h" 21 | 22 | class Grid 23 | { 24 | public: 25 | Grid(); 26 | 27 | void addActor(const Item::SharedActor &actor); 28 | void addArea(const Item::SharedArea &area); 29 | void addCheckpoint(const Item::SharedCheckpoint &checkpoint); 30 | void addMapIcon(const Item::SharedMapIcon &mapIcon); 31 | void addObject(const Item::SharedObject &object); 32 | void addPickup(const Item::SharedPickup &pickup); 33 | void addRaceCheckpoint(const Item::SharedRaceCheckpoint &raceCheckpoint); 34 | void addTextLabel(const Item::SharedTextLabel &textLabel); 35 | 36 | inline float getCellSize() 37 | { 38 | return cellSize; 39 | } 40 | 41 | inline float getCellDistance() 42 | { 43 | return cellDistance; 44 | } 45 | 46 | inline void setCellSize(float size) 47 | { 48 | cellSize = size; 49 | } 50 | 51 | inline void setCellDistance(float distance) 52 | { 53 | cellDistance = distance; 54 | comparableCellDistance = distance * distance; 55 | } 56 | 57 | void rebuildGrid(); 58 | 59 | void removeActor(const Item::SharedActor &actor, bool reassign = false); 60 | void removeArea(const Item::SharedArea &area, bool reassign = false); 61 | void removeCheckpoint(const Item::SharedCheckpoint &checkpoint, bool reassign = false); 62 | void removeMapIcon(const Item::SharedMapIcon &mapIcon, bool reassign = false); 63 | void removeObject(const Item::SharedObject &object, bool reassign = false); 64 | void removePickup(const Item::SharedPickup &pickup, bool reassign = false); 65 | void removeRaceCheckpoint(const Item::SharedRaceCheckpoint &raceCheckpoint, bool reassign = false); 66 | void removeTextLabel(const Item::SharedTextLabel &textLabel, bool reassign = false); 67 | 68 | void findAllCellsForPlayer(Player &player, std::vector &playerCells); 69 | void findMinimalCellsForPlayer(Player &player, std::vector &playerCells); 70 | void findMinimalCellsForPoint(const Eigen::Vector2f &point, std::vector &pointCells); 71 | void findMinimalCellsForPoint(const Eigen::Vector2f &point, std::vector &pointCells, float range); 72 | private: 73 | float cellDistance; 74 | float cellSize; 75 | float comparableCellDistance; 76 | SharedCell globalCell; 77 | 78 | std::unordered_map cells; 79 | Eigen::Matrix translationMatrix; 80 | 81 | inline void calculateTranslationMatrix() 82 | { 83 | translationMatrix << 0.0f, 0.0f, cellSize, cellSize, cellSize * -1.0f, 0.0f, cellSize * -1.0f, cellSize, cellSize * -1.0f, 84 | 0.0f, cellSize, 0.0f, cellSize, 0.0f, cellSize * -1.0f, cellSize, cellSize * -1.0f, cellSize * -1.0f; 85 | } 86 | 87 | inline void eraseCellIfEmpty(const SharedCell &passedCell) 88 | { 89 | if (passedCell->areas.empty() && passedCell->checkpoints.empty() && passedCell->mapIcons.empty() && passedCell->objects.empty() && passedCell->pickups.empty() && passedCell->raceCheckpoints.empty() && passedCell->textLabels.empty() && passedCell->actors.empty()) 90 | { 91 | cells.erase(passedCell->cellId); 92 | } 93 | } 94 | 95 | CellId getCellId(const Eigen::Vector2f &position, bool insert = true); 96 | void processDiscoveredCellsForPlayer(Player &player, std::vector &playerCells, const std::unordered_set &discoveredCells); 97 | }; 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/identifier.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "identifier.h" 20 | 21 | Identifier::Identifier() 22 | { 23 | highestId = 0; 24 | } 25 | 26 | int Identifier::get() 27 | { 28 | int id = 0; 29 | if (!removedIds.empty()) 30 | { 31 | id = removedIds.top(); 32 | removedIds.pop(); 33 | } 34 | else 35 | { 36 | id = ++highestId; 37 | } 38 | return id; 39 | } 40 | 41 | void Identifier::remove(int id, std::size_t remaining) 42 | { 43 | if (remaining > 1) 44 | { 45 | removedIds.push(id); 46 | } 47 | else 48 | { 49 | reset(); 50 | } 51 | } 52 | 53 | void Identifier::reset() 54 | { 55 | highestId = 0; 56 | removedIds = std::priority_queue, std::greater >(); 57 | } 58 | -------------------------------------------------------------------------------- /src/identifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef IDENTIFIER_H 18 | #define IDENTIFIER_H 19 | 20 | class Identifier 21 | { 22 | public: 23 | Identifier(); 24 | 25 | int get(); 26 | void remove(int id, std::size_t remaining); 27 | void reset(); 28 | private: 29 | int highestId; 30 | 31 | std::priority_queue, std::greater > removedIds; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/item.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "item.h" 20 | #include "identifier.h" 21 | 22 | Identifier Item::Area::identifier; 23 | Identifier Item::Checkpoint::identifier; 24 | Identifier Item::MapIcon::identifier; 25 | Identifier Item::Object::identifier; 26 | Identifier Item::Pickup::identifier; 27 | Identifier Item::RaceCheckpoint::identifier; 28 | Identifier Item::TextLabel::identifier; 29 | Identifier Item::Actor::identifier; 30 | 31 | Item::Area::Area() : references(0) {} 32 | Item::Area::Attach::Attach() : references(0) {} 33 | Item::Checkpoint::Checkpoint() : references(0) {} 34 | Item::MapIcon::MapIcon() : references(0) {} 35 | Item::Object::Object() : references(0) {} 36 | Item::Object::Attach::Attach() : references(0) {} 37 | Item::Object::Material::Main::Main() : references(0) {} 38 | Item::Object::Material::Text::Text() : references(0) {} 39 | Item::Object::Move::Move() : references(0) {} 40 | Item::Pickup::Pickup() : references(0) {} 41 | Item::RaceCheckpoint::RaceCheckpoint() : references(0) {} 42 | Item::TextLabel::TextLabel() : references(0) {} 43 | Item::TextLabel::Attach::Attach() : references(0) {} 44 | Item::Actor::Actor() : references(0) {} 45 | Item::Actor::Anim::Anim() : references(0) {} 46 | -------------------------------------------------------------------------------- /src/item.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef ITEM_H 18 | #define ITEM_H 19 | 20 | #include "cell.h" 21 | #include "identifier.h" 22 | 23 | namespace Item 24 | { 25 | struct Actor 26 | { 27 | Actor(); 28 | 29 | int actorId; 30 | AMX *amx; 31 | SharedCell cell; 32 | float comparableStreamDistance; 33 | float health; 34 | bool inverseAreaChecking; 35 | bool invulnerable; 36 | int modelId; 37 | float originalComparableStreamDistance; 38 | Eigen::Vector3f position; 39 | Eigen::Vector3f positionOffset; 40 | int priority; 41 | int references; 42 | float rotation; 43 | float streamDistance; 44 | 45 | struct Anim 46 | { 47 | Anim(); 48 | 49 | float delta; 50 | bool freeze; 51 | std::string lib; 52 | bool loop; 53 | bool lockx; 54 | bool locky; 55 | std::string name; 56 | int references; 57 | int time; 58 | }; 59 | 60 | std::shared_ptr anim; 61 | 62 | std::unordered_set areas; 63 | std::vector extras; 64 | std::unordered_map > extraExtras; 65 | std::unordered_set interiors; 66 | std::bitset players; 67 | std::unordered_set worlds; 68 | 69 | static Identifier identifier; 70 | 71 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 72 | }; 73 | 74 | struct Area 75 | { 76 | Area(); 77 | 78 | AMX *amx; 79 | int areaId; 80 | SharedCell cell; 81 | float comparableSize; 82 | Eigen::Vector2f height; 83 | int priority; 84 | int references; 85 | float size; 86 | bool spectateMode; 87 | int type; 88 | 89 | std::variant position; 90 | 91 | struct Attach 92 | { 93 | Attach(); 94 | 95 | Eigen::Vector2f height; 96 | std::tuple object; 97 | int player; 98 | std::variant position; 99 | Eigen::Vector3f positionOffset; 100 | int references; 101 | int vehicle; 102 | 103 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 104 | }; 105 | 106 | std::shared_ptr attach; 107 | 108 | std::unordered_set areas; 109 | std::vector extras; 110 | std::unordered_map > extraExtras; 111 | std::unordered_set interiors; 112 | std::bitset players; 113 | std::unordered_set worlds; 114 | 115 | static Identifier identifier; 116 | 117 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 118 | }; 119 | 120 | struct Checkpoint 121 | { 122 | Checkpoint(); 123 | 124 | AMX *amx; 125 | SharedCell cell; 126 | int checkpointId; 127 | float comparableStreamDistance; 128 | bool inverseAreaChecking; 129 | float originalComparableStreamDistance; 130 | Eigen::Vector3f position; 131 | Eigen::Vector3f positionOffset; 132 | int priority; 133 | int references; 134 | float size; 135 | bool streamCallbacks; 136 | float streamDistance; 137 | 138 | std::unordered_set areas; 139 | std::vector extras; 140 | std::unordered_map > extraExtras; 141 | std::unordered_set interiors; 142 | std::bitset players; 143 | std::unordered_set worlds; 144 | 145 | static Identifier identifier; 146 | 147 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 148 | }; 149 | 150 | struct MapIcon 151 | { 152 | MapIcon(); 153 | 154 | AMX *amx; 155 | SharedCell cell; 156 | int color; 157 | float comparableStreamDistance; 158 | bool inverseAreaChecking; 159 | int mapIconId; 160 | float originalComparableStreamDistance; 161 | Eigen::Vector3f position; 162 | Eigen::Vector3f positionOffset; 163 | int priority; 164 | int references; 165 | bool streamCallbacks; 166 | float streamDistance; 167 | int style; 168 | int type; 169 | 170 | std::unordered_set areas; 171 | std::vector extras; 172 | std::unordered_map > extraExtras; 173 | std::unordered_set interiors; 174 | std::bitset players; 175 | std::unordered_set worlds; 176 | 177 | static Identifier identifier; 178 | 179 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 180 | }; 181 | 182 | struct Object 183 | { 184 | Object(); 185 | 186 | AMX *amx; 187 | SharedCell cell; 188 | float comparableStreamDistance; 189 | float drawDistance; 190 | bool inverseAreaChecking; 191 | int modelId; 192 | bool noCameraCollision; 193 | int objectId; 194 | float originalComparableStreamDistance; 195 | Eigen::Vector3f position; 196 | Eigen::Vector3f positionOffset; 197 | int priority; 198 | int references; 199 | Eigen::Vector3f rotation; 200 | bool streamCallbacks; 201 | float streamDistance; 202 | 203 | struct Attach 204 | { 205 | Attach(); 206 | 207 | int object; 208 | int player; 209 | Eigen::Vector3f position; 210 | Eigen::Vector3f positionOffset; 211 | int references; 212 | Eigen::Vector3f rotation; 213 | bool syncRotation; 214 | int vehicle; 215 | 216 | std::unordered_set worlds; 217 | 218 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 219 | }; 220 | 221 | std::shared_ptr attach; 222 | 223 | struct Material 224 | { 225 | struct Main 226 | { 227 | Main(); 228 | 229 | int materialColor; 230 | int modelId; 231 | int references; 232 | std::string textureName; 233 | std::string txdFileName; 234 | }; 235 | 236 | std::shared_ptr
main; 237 | 238 | struct Text 239 | { 240 | Text(); 241 | 242 | int backColor; 243 | bool bold; 244 | int fontColor; 245 | std::string fontFace; 246 | int fontSize; 247 | int references; 248 | int materialSize; 249 | std::string materialText; 250 | int textAlignment; 251 | }; 252 | 253 | std::shared_ptr text; 254 | }; 255 | 256 | std::unordered_map materials; 257 | 258 | struct Move 259 | { 260 | Move(); 261 | 262 | int duration; 263 | std::tuple position; 264 | int references; 265 | std::tuple rotation; 266 | float speed; 267 | std::chrono::steady_clock::time_point time; 268 | 269 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 270 | }; 271 | 272 | std::shared_ptr move; 273 | 274 | std::unordered_set areas; 275 | std::vector extras; 276 | std::unordered_map > extraExtras; 277 | std::unordered_set interiors; 278 | std::bitset players; 279 | std::unordered_set worlds; 280 | 281 | static Identifier identifier; 282 | 283 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 284 | }; 285 | 286 | struct Pickup 287 | { 288 | Pickup(); 289 | 290 | AMX *amx; 291 | SharedCell cell; 292 | float comparableStreamDistance; 293 | bool inverseAreaChecking; 294 | int modelId; 295 | float originalComparableStreamDistance; 296 | int pickupId; 297 | Eigen::Vector3f position; 298 | Eigen::Vector3f positionOffset; 299 | int priority; 300 | int references; 301 | bool streamCallbacks; 302 | float streamDistance; 303 | int type; 304 | 305 | std::unordered_set areas; 306 | std::vector extras; 307 | std::unordered_map > extraExtras; 308 | std::unordered_set interiors; 309 | std::bitset players; 310 | std::unordered_set worlds; 311 | 312 | static Identifier identifier; 313 | 314 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 315 | }; 316 | 317 | struct RaceCheckpoint 318 | { 319 | RaceCheckpoint(); 320 | 321 | AMX *amx; 322 | SharedCell cell; 323 | float comparableStreamDistance; 324 | bool inverseAreaChecking; 325 | Eigen::Vector3f next; 326 | float originalComparableStreamDistance; 327 | Eigen::Vector3f position; 328 | Eigen::Vector3f positionOffset; 329 | int priority; 330 | int raceCheckpointId; 331 | int references; 332 | float size; 333 | bool streamCallbacks; 334 | float streamDistance; 335 | int type; 336 | 337 | std::unordered_set areas; 338 | std::vector extras; 339 | std::unordered_map > extraExtras; 340 | std::unordered_set interiors; 341 | std::bitset players; 342 | std::unordered_set worlds; 343 | 344 | static Identifier identifier; 345 | 346 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 347 | }; 348 | 349 | struct TextLabel 350 | { 351 | TextLabel(); 352 | 353 | AMX *amx; 354 | SharedCell cell; 355 | int color; 356 | float comparableStreamDistance; 357 | float drawDistance; 358 | bool inverseAreaChecking; 359 | float originalComparableStreamDistance; 360 | Eigen::Vector3f position; 361 | Eigen::Vector3f positionOffset; 362 | int priority; 363 | int references; 364 | bool streamCallbacks; 365 | float streamDistance; 366 | bool testLOS; 367 | std::string text; 368 | int textLabelId; 369 | 370 | struct Attach 371 | { 372 | Attach(); 373 | 374 | int player; 375 | Eigen::Vector3f position; 376 | int references; 377 | int vehicle; 378 | 379 | std::unordered_set worlds; 380 | 381 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 382 | }; 383 | 384 | std::shared_ptr attach; 385 | 386 | std::unordered_set areas; 387 | std::vector extras; 388 | std::unordered_map > extraExtras; 389 | std::unordered_set interiors; 390 | std::bitset players; 391 | std::unordered_set worlds; 392 | 393 | static Identifier identifier; 394 | 395 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 396 | }; 397 | } 398 | 399 | #endif 400 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MAIN_H 18 | #define MAIN_H 19 | 20 | #define INCLUDE_FILE_VERSION (0x296) 21 | #define PLUGIN_VERSION "2.9.6" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include "common.h" 51 | #include "sampgdk.h" 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/manipulation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MANIPULATION_H 18 | #define MANIPULATION_H 19 | 20 | namespace Manipulation 21 | { 22 | enum 23 | { 24 | AreaId, 25 | AttachedObject, 26 | AttachedPlayer, 27 | AttachedVehicle, 28 | AttachOffsetX, 29 | AttachOffsetY, 30 | AttachOffsetZ, 31 | AttachRX, 32 | AttachRY, 33 | AttachRZ, 34 | AttachX, 35 | AttachY, 36 | AttachZ, 37 | Color, 38 | DrawDistance, 39 | ExtraId, 40 | Health, 41 | InteriorId, 42 | Invulnerable, 43 | MaxX, 44 | MaxY, 45 | MaxZ, 46 | MinX, 47 | MinY, 48 | MinZ, 49 | ModelId, 50 | MoveRX, 51 | MoveRY, 52 | MoveRZ, 53 | MoveSpeed, 54 | MoveX, 55 | MoveY, 56 | MoveZ, 57 | NextX, 58 | NextY, 59 | NextZ, 60 | PlayerId, 61 | Priority, 62 | Rotation, 63 | RX, 64 | RY, 65 | RZ, 66 | Size, 67 | StreamDistance, 68 | Style, 69 | SyncRotation, 70 | TestLOS, 71 | Type, 72 | WorldId, 73 | X, 74 | Y, 75 | Z 76 | }; 77 | 78 | enum 79 | { 80 | InvalidData, 81 | InvalidId, 82 | InvalidType 83 | }; 84 | } 85 | 86 | #include "manipulation/array.h" 87 | #include "manipulation/float.h" 88 | #include "manipulation/int.h" 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/manipulation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND PLUGIN_SOURCES 2 | ${CMAKE_CURRENT_SOURCE_DIR}/array.cpp 3 | ${CMAKE_CURRENT_SOURCE_DIR}/float.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/int.cpp 5 | ) 6 | 7 | set(PLUGIN_SOURCES "${PLUGIN_SOURCES}" PARENT_SCOPE) 8 | -------------------------------------------------------------------------------- /src/manipulation/array.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MANIPULATION_ARRAY_H 18 | #define MANIPULATION_ARRAY_H 19 | 20 | #include "../manipulation.h" 21 | #include "../utility.h" 22 | 23 | namespace Manipulation 24 | { 25 | int getArrayData(AMX *amx, cell *params); 26 | int setArrayData(AMX *amx, cell *params); 27 | int isInArrayData(AMX *amx, cell *params); 28 | int appendArrayData(AMX *amx, cell *params); 29 | int removeArrayData(AMX *amx, cell *params); 30 | int getArrayDataLength(AMX *amx, cell *params); 31 | 32 | template 33 | int getArrayDataForItem(T &container, AMX *amx, int id, int data, cell output, cell size, int &error) 34 | { 35 | typename T::iterator i = container.find(id); 36 | if (i != container.end()) 37 | { 38 | switch (data) 39 | { 40 | case AreaId: 41 | { 42 | return Utility::convertContainerToArray(amx, output, size, i->second->areas) != 0; 43 | } 44 | case ExtraId: 45 | { 46 | return Utility::convertContainerToArray(amx, output, size, i->second->extras) != 0; 47 | } 48 | case InteriorId: 49 | { 50 | return Utility::convertContainerToArray(amx, output, size, i->second->interiors) != 0; 51 | } 52 | case PlayerId: 53 | { 54 | return Utility::convertContainerToArray(amx, output, size, i->second->players) != 0; 55 | } 56 | case WorldId: 57 | { 58 | return Utility::convertContainerToArray(amx, output, size, i->second->worlds) != 0; 59 | } 60 | default: 61 | { 62 | if (data & 0x40000000) 63 | { 64 | std::unordered_map >::iterator p = i->second->extraExtras.find(data & ~0xC0000000); 65 | if (p != i->second->extraExtras.end()) 66 | { 67 | return Utility::convertContainerToArray(amx, output, size, p->second) != 0; 68 | } 69 | } 70 | error = InvalidData; 71 | break; 72 | } 73 | } 74 | } 75 | else 76 | { 77 | error = InvalidId; 78 | } 79 | return 0; 80 | } 81 | 82 | template 83 | int setArrayDataForItem(T &container, AMX *amx, int id, int data, cell input, cell size, int &error) 84 | { 85 | typename T::iterator i = container.find(id); 86 | if (i != container.end()) 87 | { 88 | switch (data) 89 | { 90 | case AreaId: 91 | { 92 | return Utility::convertArrayToContainer(amx, input, size, i->second->areas) != 0; 93 | } 94 | case ExtraId: 95 | { 96 | return Utility::convertArrayToContainer(amx, input, size, i->second->extras) != 0; 97 | } 98 | case InteriorId: 99 | { 100 | return Utility::convertArrayToContainer(amx, input, size, i->second->interiors) != 0; 101 | } 102 | case PlayerId: 103 | { 104 | return Utility::convertArrayToContainer(amx, input, size, i->second->players) != 0; 105 | } 106 | case WorldId: 107 | { 108 | return Utility::convertArrayToContainer(amx, input, size, i->second->worlds) != 0; 109 | } 110 | default: 111 | { 112 | if (data & 0x40000000) 113 | { 114 | i->second->extraExtras[data & ~0xC0000000] = std::vector(); 115 | return Utility::convertArrayToContainer(amx, input, size, i->second->extraExtras[data & ~0xC0000000]) != 0; 116 | } 117 | error = InvalidData; 118 | return 0; 119 | } 120 | } 121 | } 122 | error = InvalidId; 123 | return 0; 124 | } 125 | 126 | template 127 | int isInArrayDataForItem(T &container, int id, int data, int value, int &error) 128 | { 129 | typename T::iterator i = container.find(id); 130 | if (i != container.end()) 131 | { 132 | switch (data) 133 | { 134 | case AreaId: 135 | { 136 | return Utility::isInContainer(i->second->areas, value) != 0; 137 | } 138 | case ExtraId: 139 | { 140 | return Utility::isInContainer(i->second->extras, value) != 0; 141 | } 142 | case InteriorId: 143 | { 144 | return Utility::isInContainer(i->second->interiors, value) != 0; 145 | } 146 | case PlayerId: 147 | { 148 | return Utility::isInContainer(i->second->players, value) != 0; 149 | } 150 | case WorldId: 151 | { 152 | return Utility::isInContainer(i->second->worlds, value) != 0; 153 | } 154 | default: 155 | { 156 | if (data & 0x40000000) 157 | { 158 | std::unordered_map >::iterator p = i->second->extraExtras.find(data & ~0xC0000000); 159 | if (p != i->second->extraExtras.end()) 160 | { 161 | return Utility::isInContainer(p->second, value) != 0; 162 | } 163 | } 164 | error = InvalidData; 165 | break; 166 | } 167 | } 168 | } 169 | else 170 | { 171 | error = InvalidId; 172 | } 173 | return 0; 174 | } 175 | 176 | template 177 | int appendArrayDataForItem(T &container, int id, int data, int value, int &error) 178 | { 179 | typename T::iterator i = container.find(id); 180 | if (i != container.end()) 181 | { 182 | switch (data) 183 | { 184 | case AreaId: 185 | { 186 | return Utility::addToContainer(i->second->areas, value) != 0; 187 | } 188 | case ExtraId: 189 | { 190 | return Utility::addToContainer(i->second->extras, value) != 0; 191 | } 192 | case InteriorId: 193 | { 194 | return Utility::addToContainer(i->second->interiors, value) != 0; 195 | } 196 | case PlayerId: 197 | { 198 | return Utility::addToContainer(i->second->players, value) != 0; 199 | } 200 | case WorldId: 201 | { 202 | return Utility::addToContainer(i->second->worlds, value) != 0; 203 | } 204 | default: 205 | { 206 | if (data & 0x40000000) 207 | { 208 | std::unordered_map >::iterator p = i->second->extraExtras.find(data & ~0xC0000000); 209 | if (p != i->second->extraExtras.end()) 210 | { 211 | return Utility::addToContainer(p->second, value) != 0; 212 | } 213 | } 214 | error = InvalidData; 215 | break; 216 | } 217 | } 218 | } 219 | else 220 | { 221 | error = InvalidId; 222 | } 223 | return 0; 224 | } 225 | 226 | template 227 | int removeArrayDataForItem(T &container, int id, int data, int value, int &error) 228 | { 229 | typename T::iterator i = container.find(id); 230 | if (i != container.end()) 231 | { 232 | switch (data) 233 | { 234 | case AreaId: 235 | { 236 | return Utility::removeFromContainer(i->second->areas, value) != 0; 237 | } 238 | case ExtraId: 239 | { 240 | return Utility::removeFromContainer(i->second->extras, value) != 0; 241 | } 242 | case InteriorId: 243 | { 244 | return Utility::removeFromContainer(i->second->interiors, value) != 0; 245 | } 246 | case PlayerId: 247 | { 248 | return Utility::removeFromContainer(i->second->players, value) != 0; 249 | } 250 | case WorldId: 251 | { 252 | return Utility::removeFromContainer(i->second->worlds, value) != 0; 253 | } 254 | default: 255 | { 256 | if (data & 0x40000000) 257 | { 258 | std::unordered_map >::iterator p = i->second->extraExtras.find(data & ~0xC0000000); 259 | if (p != i->second->extraExtras.end()) 260 | { 261 | return Utility::removeFromContainer(p->second, value) != 0; 262 | } 263 | } 264 | error = InvalidData; 265 | break; 266 | } 267 | } 268 | } 269 | else 270 | { 271 | error = InvalidId; 272 | } 273 | return 0; 274 | } 275 | 276 | template 277 | int getArrayDataLengthForItem(T &container, int id, int data, int &error) 278 | { 279 | typename T::iterator i = container.find(id); 280 | if (i != container.end()) 281 | { 282 | switch (data) 283 | { 284 | case AreaId: 285 | { 286 | int size = static_cast(i->second->areas.size()); 287 | return size ? size : -1; 288 | } 289 | case ExtraId: 290 | { 291 | return static_cast(i->second->extras.size()); 292 | } 293 | case InteriorId: 294 | { 295 | int size = static_cast(i->second->interiors.size()); 296 | return size ? size : -1; 297 | } 298 | case PlayerId: 299 | { 300 | return static_cast(i->second->players.count()); 301 | } 302 | case WorldId: 303 | { 304 | int size = static_cast(i->second->worlds.size()); 305 | return size ? size : -1; 306 | } 307 | default: 308 | { 309 | if (data & 0x40000000) 310 | { 311 | std::unordered_map >::iterator p = i->second->extraExtras.find(data & ~0xC0000000); 312 | if (p != i->second->extraExtras.end()) 313 | { 314 | int size = static_cast(p->second.size()); 315 | return size ? size : -1; 316 | } 317 | } 318 | error = InvalidData; 319 | break; 320 | } 321 | } 322 | } 323 | else 324 | { 325 | error = InvalidId; 326 | } 327 | return 0; 328 | } 329 | } 330 | 331 | #endif 332 | -------------------------------------------------------------------------------- /src/manipulation/float.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MANIPULATION_FLOAT_H 18 | #define MANIPULATION_FLOAT_H 19 | 20 | #include "../manipulation.h" 21 | 22 | namespace Manipulation 23 | { 24 | int getFloatData(AMX *amx, cell *params); 25 | int setFloatData(AMX *amx, cell *params); 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/manipulation/int.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MANIPULATION_INT_H 18 | #define MANIPULATION_INT_H 19 | 20 | #include "../manipulation.h" 21 | 22 | namespace Manipulation 23 | { 24 | int getIntData(AMX *amx, cell *params); 25 | int setIntData(AMX *amx, cell *params); 26 | int removeIntData(AMX *amx, cell *params); 27 | int hasIntData(AMX *amx, cell *params); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/natives.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef NATIVES_H 18 | #define NATIVES_H 19 | 20 | #include "utility.h" 21 | 22 | #define CHECK_PARAMS(n) \ 23 | if (params[0] != (n * 4)) \ 24 | { \ 25 | Utility::logError("%s: Expecting %d parameter(s), but found %d.", __func__, n, params[0] / sizeof(cell)); \ 26 | return 0; \ 27 | } 28 | 29 | namespace Natives 30 | { 31 | // Settings 32 | cell AMX_NATIVE_CALL Streamer_GetTickRate(AMX *amx, cell *params); 33 | cell AMX_NATIVE_CALL Streamer_SetTickRate(AMX *amx, cell *params); 34 | cell AMX_NATIVE_CALL Streamer_GetPlayerTickRate(AMX *amx, cell *params); 35 | cell AMX_NATIVE_CALL Streamer_SetPlayerTickRate(AMX *amx, cell *params); 36 | cell AMX_NATIVE_CALL Streamer_ToggleChunkStream(AMX *amx, cell *params); 37 | cell AMX_NATIVE_CALL Streamer_IsToggleChunkStream(AMX *amx, cell *params); 38 | cell AMX_NATIVE_CALL Streamer_GetChunkTickRate(AMX *amx, cell *params); 39 | cell AMX_NATIVE_CALL Streamer_SetChunkTickRate(AMX *amx, cell *params); 40 | cell AMX_NATIVE_CALL Streamer_GetChunkSize(AMX *amx, cell *params); 41 | cell AMX_NATIVE_CALL Streamer_SetChunkSize(AMX *amx, cell *params); 42 | cell AMX_NATIVE_CALL Streamer_GetMaxItems(AMX *amx, cell *params); 43 | cell AMX_NATIVE_CALL Streamer_SetMaxItems(AMX *amx, cell *params); 44 | cell AMX_NATIVE_CALL Streamer_GetVisibleItems(AMX *amx, cell *params); 45 | cell AMX_NATIVE_CALL Streamer_SetVisibleItems(AMX *amx, cell *params); 46 | cell AMX_NATIVE_CALL Streamer_GetRadiusMultiplier(AMX *amx, cell *params); 47 | cell AMX_NATIVE_CALL Streamer_SetRadiusMultiplier(AMX *amx, cell *params); 48 | cell AMX_NATIVE_CALL Streamer_GetTypePriority(AMX *amx, cell *params); 49 | cell AMX_NATIVE_CALL Streamer_SetTypePriority(AMX *amx, cell *params); 50 | cell AMX_NATIVE_CALL Streamer_GetCellDistance(AMX *amx, cell *params); 51 | cell AMX_NATIVE_CALL Streamer_SetCellDistance(AMX *amx, cell *params); 52 | cell AMX_NATIVE_CALL Streamer_GetCellSize(AMX *amx, cell *params); 53 | cell AMX_NATIVE_CALL Streamer_SetCellSize(AMX *amx, cell *params); 54 | cell AMX_NATIVE_CALL Streamer_ToggleItemStatic(AMX *amx, cell *params); 55 | cell AMX_NATIVE_CALL Streamer_IsToggleItemStatic(AMX *amx, cell *params); 56 | cell AMX_NATIVE_CALL Streamer_ToggleItemInvAreas(AMX *amx, cell *params); 57 | cell AMX_NATIVE_CALL Streamer_IsToggleItemInvAreas(AMX *amx, cell *params); 58 | cell AMX_NATIVE_CALL Streamer_ToggleItemCallbacks(AMX *amx, cell *params); 59 | cell AMX_NATIVE_CALL Streamer_IsToggleItemCallbacks(AMX *amx, cell *params); 60 | cell AMX_NATIVE_CALL Streamer_ToggleErrorCallback(AMX *amx, cell *params); 61 | cell AMX_NATIVE_CALL Streamer_IsToggleErrorCallback(AMX *amx, cell *params); 62 | cell AMX_NATIVE_CALL Streamer_AmxUnloadDestroyItems(AMX *amx, cell *params); 63 | // Updates 64 | cell AMX_NATIVE_CALL Streamer_ProcessActiveItems(AMX *amx, cell *params); 65 | cell AMX_NATIVE_CALL Streamer_ToggleIdleUpdate(AMX *amx, cell *params); 66 | cell AMX_NATIVE_CALL Streamer_IsToggleIdleUpdate(AMX *amx, cell *params); 67 | cell AMX_NATIVE_CALL Streamer_ToggleCameraUpdate(AMX *amx, cell *params); 68 | cell AMX_NATIVE_CALL Streamer_IsToggleCameraUpdate(AMX *amx, cell *params); 69 | cell AMX_NATIVE_CALL Streamer_ToggleItemUpdate(AMX *amx, cell *params); 70 | cell AMX_NATIVE_CALL Streamer_IsToggleItemUpdate(AMX *amx, cell *params); 71 | cell AMX_NATIVE_CALL Streamer_GetLastUpdateTime(AMX *amx, cell *params); 72 | cell AMX_NATIVE_CALL Streamer_Update(AMX *amx, cell *params); 73 | cell AMX_NATIVE_CALL Streamer_UpdateEx(AMX *amx, cell *params); 74 | // Data Manipulation 75 | cell AMX_NATIVE_CALL Streamer_GetFloatData(AMX *amx, cell *params); 76 | cell AMX_NATIVE_CALL Streamer_SetFloatData(AMX *amx, cell *params); 77 | cell AMX_NATIVE_CALL Streamer_GetIntData(AMX *amx, cell *params); 78 | cell AMX_NATIVE_CALL Streamer_SetIntData(AMX *amx, cell *params); 79 | cell AMX_NATIVE_CALL Streamer_RemoveIntData(AMX *amx, cell *params); 80 | cell AMX_NATIVE_CALL Streamer_HasIntData(AMX *amx, cell *params); 81 | cell AMX_NATIVE_CALL Streamer_GetArrayData(AMX *amx, cell *params); 82 | cell AMX_NATIVE_CALL Streamer_SetArrayData(AMX *amx, cell *params); 83 | cell AMX_NATIVE_CALL Streamer_IsInArrayData(AMX *amx, cell *params); 84 | cell AMX_NATIVE_CALL Streamer_AppendArrayData(AMX *amx, cell *params); 85 | cell AMX_NATIVE_CALL Streamer_RemoveArrayData(AMX *amx, cell *params); 86 | cell AMX_NATIVE_CALL Streamer_GetArrayDataLength(AMX *amx, cell *params); 87 | cell AMX_NATIVE_CALL Streamer_GetUpperBound(AMX *amx, cell *params); 88 | // Miscellaneous 89 | cell AMX_NATIVE_CALL Streamer_GetDistanceToItem(AMX *amx, cell *params); 90 | cell AMX_NATIVE_CALL Streamer_ToggleItem(AMX *amx, cell *params); 91 | cell AMX_NATIVE_CALL Streamer_IsToggleItem(AMX *amx, cell *params); 92 | cell AMX_NATIVE_CALL Streamer_ToggleAllItems(AMX *amx, cell *params); 93 | cell AMX_NATIVE_CALL Streamer_GetItemInternalID(AMX *amx, cell *params); 94 | cell AMX_NATIVE_CALL Streamer_GetItemStreamerID(AMX *amx, cell *params); 95 | cell AMX_NATIVE_CALL Streamer_IsItemVisible(AMX *amx, cell *params); 96 | cell AMX_NATIVE_CALL Streamer_DestroyAllVisibleItems(AMX *amx, cell *params); 97 | cell AMX_NATIVE_CALL Streamer_CountVisibleItems(AMX *amx, cell *params); 98 | cell AMX_NATIVE_CALL Streamer_DestroyAllItems(AMX *amx, cell *params); 99 | cell AMX_NATIVE_CALL Streamer_CountItems(AMX *amx, cell *params); 100 | cell AMX_NATIVE_CALL Streamer_GetNearbyItems(AMX *amx, cell *params); 101 | cell AMX_NATIVE_CALL Streamer_GetAllVisibleItems(AMX *amx, cell *params); 102 | cell AMX_NATIVE_CALL Streamer_GetItemPos(AMX *amx, cell *params); 103 | cell AMX_NATIVE_CALL Streamer_SetItemPos(AMX *amx, cell *params); 104 | cell AMX_NATIVE_CALL Streamer_GetItemOffset(AMX *amx, cell *params); 105 | cell AMX_NATIVE_CALL Streamer_SetItemOffset(AMX *amx, cell *params); 106 | // Objects 107 | cell AMX_NATIVE_CALL CreateDynamicObject(AMX *amx, cell *params); 108 | cell AMX_NATIVE_CALL DestroyDynamicObject(AMX *amx, cell *params); 109 | cell AMX_NATIVE_CALL IsValidDynamicObject(AMX *amx, cell *params); 110 | cell AMX_NATIVE_CALL GetDynamicObjectPos(AMX *amx, cell *params); 111 | cell AMX_NATIVE_CALL SetDynamicObjectPos(AMX *amx, cell *params); 112 | cell AMX_NATIVE_CALL GetDynamicObjectRot(AMX *amx, cell *params); 113 | cell AMX_NATIVE_CALL SetDynamicObjectRot(AMX *amx, cell *params); 114 | cell AMX_NATIVE_CALL GetDynamicObjectNoCameraCol(AMX *amx, cell *params); 115 | cell AMX_NATIVE_CALL SetDynamicObjectNoCameraCol(AMX *amx, cell *params); 116 | cell AMX_NATIVE_CALL MoveDynamicObject(AMX *amx, cell *params); 117 | cell AMX_NATIVE_CALL StopDynamicObject(AMX *amx, cell *params); 118 | cell AMX_NATIVE_CALL IsDynamicObjectMoving(AMX *amx, cell *params); 119 | cell AMX_NATIVE_CALL AttachCameraToDynamicObject(AMX *amx, cell *params); 120 | cell AMX_NATIVE_CALL AttachDynamicObjectToObject(AMX *amx, cell *params); 121 | cell AMX_NATIVE_CALL AttachDynamicObjectToPlayer(AMX *amx, cell *params); 122 | cell AMX_NATIVE_CALL AttachDynamicObjectToVehicle(AMX *amx, cell *params); 123 | cell AMX_NATIVE_CALL EditDynamicObject(AMX *amx, cell *params); 124 | cell AMX_NATIVE_CALL IsDynamicObjectMaterialUsed(AMX *amx, cell *params); 125 | cell AMX_NATIVE_CALL RemoveDynamicObjectMaterial(AMX *amx, cell *params); 126 | cell AMX_NATIVE_CALL GetDynamicObjectMaterial(AMX *amx, cell *params); 127 | cell AMX_NATIVE_CALL SetDynamicObjectMaterial(AMX *amx, cell *params); 128 | cell AMX_NATIVE_CALL IsDynamicObjectMaterialTextUsed(AMX *amx, cell *params); 129 | cell AMX_NATIVE_CALL RemoveDynamicObjectMaterialText(AMX *amx, cell *params); 130 | cell AMX_NATIVE_CALL GetDynamicObjectMaterialText(AMX *amx, cell *params); 131 | cell AMX_NATIVE_CALL SetDynamicObjectMaterialText(AMX *amx, cell *params); 132 | cell AMX_NATIVE_CALL GetPlayerCameraTargetDynObject(AMX *amx, cell *params); 133 | // Pickups 134 | cell AMX_NATIVE_CALL CreateDynamicPickup(AMX *amx, cell *params); 135 | cell AMX_NATIVE_CALL DestroyDynamicPickup(AMX *amx, cell *params); 136 | cell AMX_NATIVE_CALL IsValidDynamicPickup(AMX *amx, cell *params); 137 | // Checkpoints 138 | cell AMX_NATIVE_CALL CreateDynamicCP(AMX *amx, cell *params); 139 | cell AMX_NATIVE_CALL IsValidDynamicCP(AMX *amx, cell *params); 140 | cell AMX_NATIVE_CALL DestroyDynamicCP(AMX *amx, cell *params); 141 | cell AMX_NATIVE_CALL IsPlayerInDynamicCP(AMX *amx, cell *params); 142 | cell AMX_NATIVE_CALL GetPlayerVisibleDynamicCP(AMX *amx, cell *params); 143 | // Race Checkpoints 144 | cell AMX_NATIVE_CALL CreateDynamicRaceCP(AMX *amx, cell *params); 145 | cell AMX_NATIVE_CALL DestroyDynamicRaceCP(AMX *amx, cell *params); 146 | cell AMX_NATIVE_CALL IsValidDynamicRaceCP(AMX *amx, cell *params); 147 | cell AMX_NATIVE_CALL IsPlayerInDynamicRaceCP(AMX *amx, cell *params); 148 | cell AMX_NATIVE_CALL GetPlayerVisibleDynamicRaceCP(AMX *amx, cell *params); 149 | // Map Icons 150 | cell AMX_NATIVE_CALL CreateDynamicMapIcon(AMX *amx, cell *params); 151 | cell AMX_NATIVE_CALL DestroyDynamicMapIcon(AMX *amx, cell *params); 152 | cell AMX_NATIVE_CALL IsValidDynamicMapIcon(AMX *amx, cell *params); 153 | // 3D Text Labels 154 | cell AMX_NATIVE_CALL CreateDynamic3DTextLabel(AMX *amx, cell *params); 155 | cell AMX_NATIVE_CALL DestroyDynamic3DTextLabel(AMX *amx, cell *params); 156 | cell AMX_NATIVE_CALL IsValidDynamic3DTextLabel(AMX *amx, cell *params); 157 | cell AMX_NATIVE_CALL GetDynamic3DTextLabelText(AMX *amx, cell *params); 158 | cell AMX_NATIVE_CALL UpdateDynamic3DTextLabelText(AMX *amx, cell *params); 159 | // Areas 160 | cell AMX_NATIVE_CALL CreateDynamicCircle(AMX *amx, cell *params); 161 | cell AMX_NATIVE_CALL CreateDynamicCylinder(AMX *amx, cell *params); 162 | cell AMX_NATIVE_CALL CreateDynamicSphere(AMX *amx, cell *params); 163 | cell AMX_NATIVE_CALL CreateDynamicRectangle(AMX *amx, cell *params); 164 | cell AMX_NATIVE_CALL CreateDynamicCuboid(AMX *amx, cell *params); 165 | cell AMX_NATIVE_CALL CreateDynamicPolygon(AMX *amx, cell *params); 166 | cell AMX_NATIVE_CALL DestroyDynamicArea(AMX *amx, cell *params); 167 | cell AMX_NATIVE_CALL IsValidDynamicArea(AMX *amx, cell *params); 168 | cell AMX_NATIVE_CALL GetDynamicAreaType(AMX *amx, cell *params); 169 | cell AMX_NATIVE_CALL GetDynamicPolygonPoints(AMX *amx, cell *params); 170 | cell AMX_NATIVE_CALL GetDynamicPolygonNumberPoints(AMX *amx, cell *params); 171 | cell AMX_NATIVE_CALL IsPlayerInDynamicArea(AMX *amx, cell *params); 172 | cell AMX_NATIVE_CALL IsPlayerInAnyDynamicArea(AMX *amx, cell *params); 173 | cell AMX_NATIVE_CALL IsAnyPlayerInDynamicArea(AMX *amx, cell *params); 174 | cell AMX_NATIVE_CALL IsAnyPlayerInAnyDynamicArea(AMX *amx, cell *params); 175 | cell AMX_NATIVE_CALL GetPlayerDynamicAreas(AMX *amx, cell *params); 176 | cell AMX_NATIVE_CALL GetPlayerNumberDynamicAreas(AMX *amx, cell *params); 177 | cell AMX_NATIVE_CALL IsPointInDynamicArea(AMX *amx, cell *params); 178 | cell AMX_NATIVE_CALL IsPointInAnyDynamicArea(AMX *amx, cell *params); 179 | cell AMX_NATIVE_CALL IsLineInDynamicArea(AMX *amx, cell *params); 180 | cell AMX_NATIVE_CALL IsLineInAnyDynamicArea(AMX *amx, cell *params); 181 | cell AMX_NATIVE_CALL GetDynamicAreasForPoint(AMX *amx, cell *params); 182 | cell AMX_NATIVE_CALL GetNumberDynamicAreasForPoint(AMX *amx, cell *params); 183 | cell AMX_NATIVE_CALL GetDynamicAreasForLine(AMX *amx, cell *params); 184 | cell AMX_NATIVE_CALL GetNumberDynamicAreasForLine(AMX *amx, cell *params); 185 | cell AMX_NATIVE_CALL AttachDynamicAreaToObject(AMX *amx, cell *params); 186 | cell AMX_NATIVE_CALL AttachDynamicAreaToPlayer(AMX *amx, cell *params); 187 | cell AMX_NATIVE_CALL AttachDynamicAreaToVehicle(AMX *amx, cell *params); 188 | cell AMX_NATIVE_CALL ToggleDynAreaSpectateMode(AMX *amx, cell *params); 189 | cell AMX_NATIVE_CALL IsToggleDynAreaSpectateMode(AMX *amx, cell *params); 190 | // Actors 191 | cell AMX_NATIVE_CALL CreateDynamicActor(AMX *amx, cell *params); 192 | cell AMX_NATIVE_CALL DestroyDynamicActor(AMX *amx, cell *params); 193 | cell AMX_NATIVE_CALL IsValidDynamicActor(AMX *amx, cell *params); 194 | cell AMX_NATIVE_CALL IsDynamicActorStreamedIn(AMX *amx, cell *params); 195 | cell AMX_NATIVE_CALL GetDynamicActorVirtualWorld(AMX *amx, cell *params); 196 | cell AMX_NATIVE_CALL SetDynamicActorVirtualWorld(AMX *amx, cell *params); 197 | cell AMX_NATIVE_CALL GetDynamicActorAnimation(AMX *amx, cell *params); 198 | cell AMX_NATIVE_CALL ApplyDynamicActorAnimation(AMX *amx, cell *params); 199 | cell AMX_NATIVE_CALL ClearDynamicActorAnimations(AMX *amx, cell *params); 200 | cell AMX_NATIVE_CALL GetDynamicActorFacingAngle(AMX *amx, cell *params); 201 | cell AMX_NATIVE_CALL SetDynamicActorFacingAngle(AMX *amx, cell *params); 202 | cell AMX_NATIVE_CALL GetDynamicActorPos(AMX *amx, cell *params); 203 | cell AMX_NATIVE_CALL SetDynamicActorPos(AMX *amx, cell *params); 204 | cell AMX_NATIVE_CALL GetDynamicActorHealth(AMX *amx, cell *params); 205 | cell AMX_NATIVE_CALL SetDynamicActorHealth(AMX *amx, cell *params); 206 | cell AMX_NATIVE_CALL SetDynamicActorInvulnerable(AMX *amx, cell *params); 207 | cell AMX_NATIVE_CALL IsDynamicActorInvulnerable(AMX *amx, cell *params); 208 | cell AMX_NATIVE_CALL GetPlayerTargetDynamicActor(AMX *amx, cell *params); 209 | cell AMX_NATIVE_CALL GetPlayerCameraTargetDynActor(AMX *amx, cell *params); 210 | // Extended 211 | cell AMX_NATIVE_CALL CreateDynamicObjectEx(AMX *amx, cell *params); 212 | cell AMX_NATIVE_CALL CreateDynamicPickupEx(AMX *amx, cell *params); 213 | cell AMX_NATIVE_CALL CreateDynamicCPEx(AMX *amx, cell *params); 214 | cell AMX_NATIVE_CALL CreateDynamicRaceCPEx(AMX *amx, cell *params); 215 | cell AMX_NATIVE_CALL CreateDynamicMapIconEx(AMX *amx, cell *params); 216 | cell AMX_NATIVE_CALL CreateDynamic3DTextLabelEx(AMX *amx, cell *params); 217 | cell AMX_NATIVE_CALL CreateDynamicCircleEx(AMX *amx, cell *params); 218 | cell AMX_NATIVE_CALL CreateDynamicCylinderEx(AMX *amx, cell *params); 219 | cell AMX_NATIVE_CALL CreateDynamicSphereEx(AMX *amx, cell *params); 220 | cell AMX_NATIVE_CALL CreateDynamicRectangleEx(AMX *amx, cell *params); 221 | cell AMX_NATIVE_CALL CreateDynamicCuboidEx(AMX *amx, cell *params); 222 | cell AMX_NATIVE_CALL CreateDynamicPolygonEx(AMX *amx, cell *params); 223 | cell AMX_NATIVE_CALL CreateDynamicActorEx(AMX *amx, cell *params); 224 | // Deprecated 225 | cell AMX_NATIVE_CALL Streamer_CallbackHook(AMX *amx, cell *params); 226 | cell AMX_NATIVE_CALL DestroyAllDynamicObjects(AMX *amx, cell *params); 227 | cell AMX_NATIVE_CALL CountDynamicObjects(AMX *amx, cell *params); 228 | cell AMX_NATIVE_CALL DestroyAllDynamicPickups(AMX *amx, cell *params); 229 | cell AMX_NATIVE_CALL CountDynamicPickups(AMX *amx, cell *params); 230 | cell AMX_NATIVE_CALL DestroyAllDynamicCPs(AMX *amx, cell *params); 231 | cell AMX_NATIVE_CALL CountDynamicCPs(AMX *amx, cell *params); 232 | cell AMX_NATIVE_CALL DestroyAllDynamicRaceCPs(AMX *amx, cell *params); 233 | cell AMX_NATIVE_CALL CountDynamicRaceCPs(AMX *amx, cell *params); 234 | cell AMX_NATIVE_CALL DestroyAllDynamicMapIcons(AMX *amx, cell *params); 235 | cell AMX_NATIVE_CALL CountDynamicMapIcons(AMX *amx, cell *params); 236 | cell AMX_NATIVE_CALL DestroyAllDynamic3DTextLabels(AMX *amx, cell *params); 237 | cell AMX_NATIVE_CALL CountDynamic3DTextLabels(AMX *amx, cell *params); 238 | cell AMX_NATIVE_CALL DestroyAllDynamicAreas(AMX *amx, cell *params); 239 | cell AMX_NATIVE_CALL CountDynamicAreas(AMX *amx, cell *params); 240 | cell AMX_NATIVE_CALL TogglePlayerDynamicCP(AMX *amx, cell *params); 241 | cell AMX_NATIVE_CALL TogglePlayerAllDynamicCPs(AMX *amx, cell *params); 242 | cell AMX_NATIVE_CALL TogglePlayerDynamicRaceCP(AMX *amx, cell *params); 243 | cell AMX_NATIVE_CALL TogglePlayerAllDynamicRaceCPs(AMX *amx, cell *params); 244 | cell AMX_NATIVE_CALL TogglePlayerDynamicArea(AMX *amx, cell *params); 245 | cell AMX_NATIVE_CALL TogglePlayerAllDynamicAreas(AMX *amx, cell *params); 246 | } 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /src/natives/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND PLUGIN_SOURCES 2 | ${CMAKE_CURRENT_SOURCE_DIR}/actors.cpp 3 | ${CMAKE_CURRENT_SOURCE_DIR}/areas.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/checkpoints.cpp 5 | ${CMAKE_CURRENT_SOURCE_DIR}/deprecated.cpp 6 | ${CMAKE_CURRENT_SOURCE_DIR}/extended.cpp 7 | ${CMAKE_CURRENT_SOURCE_DIR}/manipulation.cpp 8 | ${CMAKE_CURRENT_SOURCE_DIR}/map-icons.cpp 9 | ${CMAKE_CURRENT_SOURCE_DIR}/miscellaneous.cpp 10 | ${CMAKE_CURRENT_SOURCE_DIR}/objects.cpp 11 | ${CMAKE_CURRENT_SOURCE_DIR}/pickups.cpp 12 | ${CMAKE_CURRENT_SOURCE_DIR}/race-checkpoints.cpp 13 | ${CMAKE_CURRENT_SOURCE_DIR}/settings.cpp 14 | ${CMAKE_CURRENT_SOURCE_DIR}/text-labels.cpp 15 | ${CMAKE_CURRENT_SOURCE_DIR}/updates.cpp 16 | ) 17 | 18 | set(PLUGIN_SOURCES "${PLUGIN_SOURCES}" PARENT_SCOPE) 19 | -------------------------------------------------------------------------------- /src/natives/checkpoints.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../utility.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::CreateDynamicCP(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(10); 26 | if (core->getData()->getGlobalMaxItems(STREAMER_TYPE_CP) == core->getData()->checkpoints.size()) 27 | { 28 | return INVALID_STREAMER_ID; 29 | } 30 | int checkpointId = Item::Checkpoint::identifier.get(); 31 | Item::SharedCheckpoint checkpoint(new Item::Checkpoint); 32 | checkpoint->amx = amx; 33 | checkpoint->checkpointId = checkpointId; 34 | checkpoint->inverseAreaChecking = false; 35 | checkpoint->originalComparableStreamDistance = -1.0f; 36 | checkpoint->positionOffset = Eigen::Vector3f::Zero(); 37 | checkpoint->streamCallbacks = false; 38 | checkpoint->position = Eigen::Vector3f(amx_ctof(params[1]), amx_ctof(params[2]), amx_ctof(params[3])); 39 | checkpoint->size = amx_ctof(params[4]); 40 | Utility::addToContainer(checkpoint->worlds, static_cast(params[5])); 41 | Utility::addToContainer(checkpoint->interiors, static_cast(params[6])); 42 | Utility::addToContainer(checkpoint->players, static_cast(params[7])); 43 | checkpoint->comparableStreamDistance = amx_ctof(params[8]) < STREAMER_STATIC_DISTANCE_CUTOFF ? amx_ctof(params[8]) : amx_ctof(params[8]) * amx_ctof(params[8]); 44 | checkpoint->streamDistance = amx_ctof(params[8]); 45 | Utility::addToContainer(checkpoint->areas, static_cast(params[9])); 46 | checkpoint->priority = static_cast(params[10]); 47 | core->getGrid()->addCheckpoint(checkpoint); 48 | core->getData()->checkpoints.insert(std::make_pair(checkpointId, checkpoint)); 49 | return static_cast(checkpointId); 50 | } 51 | 52 | cell AMX_NATIVE_CALL Natives::DestroyDynamicCP(AMX *amx, cell *params) 53 | { 54 | CHECK_PARAMS(1); 55 | std::unordered_map::iterator c = core->getData()->checkpoints.find(static_cast(params[1])); 56 | if (c != core->getData()->checkpoints.end()) 57 | { 58 | Utility::destroyCheckpoint(c); 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | cell AMX_NATIVE_CALL Natives::IsValidDynamicCP(AMX *amx, cell *params) 65 | { 66 | CHECK_PARAMS(1); 67 | std::unordered_map::iterator c = core->getData()->checkpoints.find(static_cast(params[1])); 68 | if (c != core->getData()->checkpoints.end()) 69 | { 70 | return 1; 71 | } 72 | return 0; 73 | } 74 | 75 | cell AMX_NATIVE_CALL Natives::IsPlayerInDynamicCP(AMX *amx, cell *params) 76 | { 77 | CHECK_PARAMS(2); 78 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 79 | if (p != core->getData()->players.end()) 80 | { 81 | if (p->second.activeCheckpoint == static_cast(params[2])) 82 | { 83 | return 1; 84 | } 85 | } 86 | return 0; 87 | } 88 | 89 | cell AMX_NATIVE_CALL Natives::GetPlayerVisibleDynamicCP(AMX *amx, cell *params) 90 | { 91 | CHECK_PARAMS(1); 92 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 93 | if (p != core->getData()->players.end()) 94 | { 95 | return p->second.visibleCheckpoint; 96 | } 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /src/natives/deprecated.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | 22 | cell AMX_NATIVE_CALL Natives::Streamer_CallbackHook(AMX *amx, cell *params) 23 | { 24 | return 0; 25 | } 26 | 27 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicObjects(AMX *amx, cell *params) 28 | { 29 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_OBJECT, 1 }; 30 | return Natives::Streamer_DestroyAllItems(amx, newParams); 31 | } 32 | 33 | cell AMX_NATIVE_CALL Natives::CountDynamicObjects(AMX *amx, cell *params) 34 | { 35 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_OBJECT, 1 }; 36 | return Natives::Streamer_CountItems(amx, newParams); 37 | } 38 | 39 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicPickups(AMX *amx, cell *params) 40 | { 41 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_PICKUP, 1 }; 42 | return Natives::Streamer_DestroyAllItems(amx, newParams); 43 | } 44 | 45 | cell AMX_NATIVE_CALL Natives::CountDynamicPickups(AMX *amx, cell *params) 46 | { 47 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_PICKUP, 1 }; 48 | return Natives::Streamer_CountItems(amx, newParams); 49 | } 50 | 51 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicCPs(AMX *amx, cell *params) 52 | { 53 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_CP, 1 }; 54 | return Natives::Streamer_DestroyAllItems(amx, newParams); 55 | } 56 | 57 | cell AMX_NATIVE_CALL Natives::CountDynamicCPs(AMX *amx, cell *params) 58 | { 59 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_CP, 1 }; 60 | return Natives::Streamer_CountItems(amx, newParams); 61 | } 62 | 63 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicRaceCPs(AMX *amx, cell *params) 64 | { 65 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_RACE_CP, 1 }; 66 | return Natives::Streamer_DestroyAllItems(amx, newParams); 67 | } 68 | 69 | cell AMX_NATIVE_CALL Natives::CountDynamicRaceCPs(AMX *amx, cell *params) 70 | { 71 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_RACE_CP, 1 }; 72 | return Natives::Streamer_CountItems(amx, newParams); 73 | } 74 | 75 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicMapIcons(AMX *amx, cell *params) 76 | { 77 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_MAP_ICON, 1 }; 78 | return Natives::Streamer_DestroyAllItems(amx, newParams); 79 | } 80 | 81 | cell AMX_NATIVE_CALL Natives::CountDynamicMapIcons(AMX *amx, cell *params) 82 | { 83 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_MAP_ICON, 1 }; 84 | return Natives::Streamer_CountItems(amx, newParams); 85 | } 86 | 87 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamic3DTextLabels(AMX *amx, cell *params) 88 | { 89 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_3D_TEXT_LABEL, 1 }; 90 | return Natives::Streamer_DestroyAllItems(amx, newParams); 91 | } 92 | 93 | cell AMX_NATIVE_CALL Natives::CountDynamic3DTextLabels(AMX *amx, cell *params) 94 | { 95 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_3D_TEXT_LABEL, 1 }; 96 | return Natives::Streamer_CountItems(amx, newParams); 97 | } 98 | 99 | cell AMX_NATIVE_CALL Natives::DestroyAllDynamicAreas(AMX *amx, cell *params) 100 | { 101 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_AREA, 1 }; 102 | return Natives::Streamer_DestroyAllItems(amx, newParams); 103 | } 104 | 105 | cell AMX_NATIVE_CALL Natives::CountDynamicAreas(AMX *amx, cell *params) 106 | { 107 | cell newParams[3] = { sizeof(cell) * 2, STREAMER_TYPE_AREA, 1 }; 108 | return Natives::Streamer_CountItems(amx, newParams); 109 | } 110 | 111 | cell AMX_NATIVE_CALL Natives::TogglePlayerDynamicCP(AMX *amx, cell *params) 112 | { 113 | cell newParams[5] = { sizeof(cell) * 4, params[1], STREAMER_TYPE_CP, params[2], params[3] }; 114 | return Natives::Streamer_ToggleItem(amx, newParams); 115 | } 116 | 117 | cell AMX_NATIVE_CALL Natives::TogglePlayerAllDynamicCPs(AMX *amx, cell *params) 118 | { 119 | cell newParams[6] = { sizeof(cell) * 5, params[1], STREAMER_TYPE_CP, params[2], params[3], params[4] }; 120 | return Natives::Streamer_ToggleAllItems(amx, newParams); 121 | } 122 | 123 | cell AMX_NATIVE_CALL Natives::TogglePlayerDynamicRaceCP(AMX *amx, cell *params) 124 | { 125 | cell newParams[5] = { sizeof(cell) * 4, params[1], STREAMER_TYPE_RACE_CP, params[2], params[3] }; 126 | return Natives::Streamer_ToggleItem(amx, newParams); 127 | } 128 | 129 | cell AMX_NATIVE_CALL Natives::TogglePlayerAllDynamicRaceCPs(AMX *amx, cell *params) 130 | { 131 | cell newParams[6] = { sizeof(cell) * 5, params[1], STREAMER_TYPE_RACE_CP, params[2], params[3], params[4] }; 132 | return Natives::Streamer_ToggleAllItems(amx, newParams); 133 | } 134 | 135 | cell AMX_NATIVE_CALL Natives::TogglePlayerDynamicArea(AMX *amx, cell *params) 136 | { 137 | cell newParams[5] = { sizeof(cell) * 4, params[1], STREAMER_TYPE_AREA, params[2], params[3] }; 138 | return Natives::Streamer_ToggleItem(amx, newParams); 139 | } 140 | 141 | cell AMX_NATIVE_CALL Natives::TogglePlayerAllDynamicAreas(AMX *amx, cell *params) 142 | { 143 | cell newParams[6] = { sizeof(cell) * 5, params[1], STREAMER_TYPE_AREA, params[2], params[3], params[4] }; 144 | return Natives::Streamer_ToggleAllItems(amx, newParams); 145 | } 146 | -------------------------------------------------------------------------------- /src/natives/manipulation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../manipulation.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::Streamer_GetFloatData(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(4); 26 | return static_cast(Manipulation::getFloatData(amx, params)); 27 | } 28 | 29 | cell AMX_NATIVE_CALL Natives::Streamer_SetFloatData(AMX *amx, cell *params) 30 | { 31 | CHECK_PARAMS(4); 32 | return static_cast(Manipulation::setFloatData(amx, params)); 33 | } 34 | 35 | cell AMX_NATIVE_CALL Natives::Streamer_GetIntData(AMX *amx, cell *params) 36 | { 37 | CHECK_PARAMS(3); 38 | return static_cast(Manipulation::getIntData(amx, params)); 39 | } 40 | 41 | cell AMX_NATIVE_CALL Natives::Streamer_SetIntData(AMX *amx, cell *params) 42 | { 43 | CHECK_PARAMS(4); 44 | return static_cast(Manipulation::setIntData(amx, params)); 45 | } 46 | 47 | cell AMX_NATIVE_CALL Natives::Streamer_RemoveIntData(AMX *amx, cell *params) 48 | { 49 | CHECK_PARAMS(3); 50 | return static_cast(Manipulation::removeIntData(amx, params)); 51 | } 52 | 53 | cell AMX_NATIVE_CALL Natives::Streamer_HasIntData(AMX *amx, cell *params) 54 | { 55 | CHECK_PARAMS(3); 56 | return static_cast(Manipulation::hasIntData(amx, params)); 57 | } 58 | 59 | cell AMX_NATIVE_CALL Natives::Streamer_GetArrayData(AMX *amx, cell *params) 60 | { 61 | CHECK_PARAMS(5); 62 | return static_cast(Manipulation::getArrayData(amx, params)); 63 | } 64 | 65 | cell AMX_NATIVE_CALL Natives::Streamer_SetArrayData(AMX *amx, cell *params) 66 | { 67 | CHECK_PARAMS(5); 68 | return static_cast(Manipulation::setArrayData(amx, params)); 69 | } 70 | 71 | cell AMX_NATIVE_CALL Natives::Streamer_IsInArrayData(AMX *amx, cell *params) 72 | { 73 | CHECK_PARAMS(4); 74 | return static_cast(Manipulation::isInArrayData(amx, params)); 75 | } 76 | 77 | cell AMX_NATIVE_CALL Natives::Streamer_AppendArrayData(AMX *amx, cell *params) 78 | { 79 | CHECK_PARAMS(4); 80 | return static_cast(Manipulation::appendArrayData(amx, params)); 81 | } 82 | 83 | cell AMX_NATIVE_CALL Natives::Streamer_RemoveArrayData(AMX *amx, cell *params) 84 | { 85 | CHECK_PARAMS(4); 86 | return static_cast(Manipulation::removeArrayData(amx, params)); 87 | } 88 | 89 | cell AMX_NATIVE_CALL Natives::Streamer_GetArrayDataLength(AMX *amx, cell *params) 90 | { 91 | CHECK_PARAMS(3); 92 | return static_cast(Manipulation::getArrayDataLength(amx, params)); 93 | } 94 | 95 | cell AMX_NATIVE_CALL Natives::Streamer_GetUpperBound(AMX *amx, cell *params) 96 | { 97 | CHECK_PARAMS(1); 98 | switch (static_cast(params[1])) 99 | { 100 | case STREAMER_TYPE_OBJECT: 101 | { 102 | int objectId = 0; 103 | for (std::unordered_map::iterator o = core->getData()->objects.begin(); o != core->getData()->objects.end(); ++o) 104 | { 105 | if (o->first > objectId) 106 | { 107 | objectId = o->first; 108 | } 109 | } 110 | return static_cast(objectId + 1); 111 | } 112 | case STREAMER_TYPE_PICKUP: 113 | { 114 | int pickupId = 0; 115 | for (std::unordered_map::iterator p = core->getData()->pickups.begin(); p != core->getData()->pickups.end(); ++p) 116 | { 117 | if (p->first > pickupId) 118 | { 119 | pickupId = p->first; 120 | } 121 | } 122 | return static_cast(pickupId + 1); 123 | } 124 | case STREAMER_TYPE_CP: 125 | { 126 | int checkpointId = 0; 127 | for (std::unordered_map::iterator c = core->getData()->checkpoints.begin(); c != core->getData()->checkpoints.end(); ++c) 128 | { 129 | if (c->first > checkpointId) 130 | { 131 | checkpointId = c->first; 132 | } 133 | } 134 | return static_cast(checkpointId + 1); 135 | } 136 | case STREAMER_TYPE_RACE_CP: 137 | { 138 | int raceCheckpointId = 0; 139 | for (std::unordered_map::iterator r = core->getData()->raceCheckpoints.begin(); r != core->getData()->raceCheckpoints.end(); ++r) 140 | { 141 | if (r->first > raceCheckpointId) 142 | { 143 | raceCheckpointId = r->first; 144 | } 145 | } 146 | return static_cast(raceCheckpointId + 1); 147 | } 148 | case STREAMER_TYPE_MAP_ICON: 149 | { 150 | int mapIconId = 0; 151 | for (std::unordered_map::iterator m = core->getData()->mapIcons.begin(); m != core->getData()->mapIcons.end(); ++m) 152 | { 153 | if (m->first > mapIconId) 154 | { 155 | mapIconId = m->first; 156 | } 157 | } 158 | return static_cast(mapIconId + 1); 159 | } 160 | case STREAMER_TYPE_3D_TEXT_LABEL: 161 | { 162 | int textLabelId = 0; 163 | for (std::unordered_map::iterator t = core->getData()->textLabels.begin(); t != core->getData()->textLabels.end(); ++t) 164 | { 165 | if (t->first > textLabelId) 166 | { 167 | textLabelId = t->first; 168 | } 169 | } 170 | return static_cast(textLabelId + 1); 171 | } 172 | case STREAMER_TYPE_AREA: 173 | { 174 | int areaId = 0; 175 | for (std::unordered_map::iterator a = core->getData()->areas.begin(); a != core->getData()->areas.end(); ++a) 176 | { 177 | if (a->first > areaId) 178 | { 179 | areaId = a->first; 180 | } 181 | } 182 | return static_cast(areaId + 1); 183 | } 184 | case STREAMER_TYPE_ACTOR: 185 | { 186 | int actorId = 0; 187 | for (std::unordered_map::iterator a = core->getData()->actors.begin(); a != core->getData()->actors.end(); ++a) 188 | { 189 | if (a->first > actorId) 190 | { 191 | actorId = a->first; 192 | } 193 | } 194 | return static_cast(actorId + 1); 195 | } 196 | default: 197 | { 198 | Utility::logError("Streamer_GetUpperBound: Invalid type specified."); 199 | return 0; 200 | } 201 | } 202 | return 0; 203 | } 204 | -------------------------------------------------------------------------------- /src/natives/map-icons.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../utility.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::CreateDynamicMapIcon(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(12); 26 | if (core->getData()->getGlobalMaxItems(STREAMER_TYPE_MAP_ICON) == core->getData()->mapIcons.size()) 27 | { 28 | return INVALID_STREAMER_ID; 29 | } 30 | int mapIconId = Item::MapIcon::identifier.get(); 31 | Item::SharedMapIcon mapIcon(new Item::MapIcon); 32 | mapIcon->amx = amx; 33 | mapIcon->mapIconId = mapIconId; 34 | mapIcon->inverseAreaChecking = false; 35 | mapIcon->originalComparableStreamDistance = -1.0f; 36 | mapIcon->positionOffset = Eigen::Vector3f::Zero(); 37 | mapIcon->streamCallbacks = false; 38 | mapIcon->position = Eigen::Vector3f(amx_ctof(params[1]), amx_ctof(params[2]), amx_ctof(params[3])); 39 | mapIcon->type = static_cast(params[4]); 40 | mapIcon->color = static_cast(params[5]); 41 | Utility::addToContainer(mapIcon->worlds, static_cast(params[6])); 42 | Utility::addToContainer(mapIcon->interiors, static_cast(params[7])); 43 | Utility::addToContainer(mapIcon->players, static_cast(params[8])); 44 | mapIcon->comparableStreamDistance = amx_ctof(params[9]) < STREAMER_STATIC_DISTANCE_CUTOFF ? amx_ctof(params[9]) : amx_ctof(params[9]) * amx_ctof(params[9]); 45 | mapIcon->streamDistance = amx_ctof(params[9]); 46 | mapIcon->style = static_cast(params[10]); 47 | Utility::addToContainer(mapIcon->areas, static_cast(params[11])); 48 | mapIcon->priority = static_cast(params[12]); 49 | core->getGrid()->addMapIcon(mapIcon); 50 | core->getData()->mapIcons.insert(std::make_pair(mapIconId, mapIcon)); 51 | return static_cast(mapIconId); 52 | } 53 | 54 | cell AMX_NATIVE_CALL Natives::DestroyDynamicMapIcon(AMX *amx, cell *params) 55 | { 56 | CHECK_PARAMS(1); 57 | std::unordered_map::iterator m = core->getData()->mapIcons.find(static_cast(params[1])); 58 | if (m != core->getData()->mapIcons.end()) 59 | { 60 | Utility::destroyMapIcon(m); 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | cell AMX_NATIVE_CALL Natives::IsValidDynamicMapIcon(AMX *amx, cell *params) 67 | { 68 | CHECK_PARAMS(1); 69 | std::unordered_map::iterator m = core->getData()->mapIcons.find(static_cast(params[1])); 70 | if (m != core->getData()->mapIcons.end()) 71 | { 72 | return 1; 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/natives/pickups.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../utility.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::CreateDynamicPickup(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(11); 26 | if (core->getData()->getGlobalMaxItems(STREAMER_TYPE_PICKUP) == core->getData()->pickups.size()) 27 | { 28 | return INVALID_STREAMER_ID; 29 | } 30 | int pickupId = Item::Pickup::identifier.get(); 31 | Item::SharedPickup pickup(new Item::Pickup); 32 | pickup->amx = amx; 33 | pickup->pickupId = pickupId; 34 | pickup->inverseAreaChecking = false; 35 | pickup->originalComparableStreamDistance = -1.0f; 36 | pickup->positionOffset = Eigen::Vector3f::Zero(); 37 | pickup->streamCallbacks = false; 38 | pickup->modelId = static_cast(params[1]); 39 | pickup->type = static_cast(params[2]); 40 | pickup->position = Eigen::Vector3f(amx_ctof(params[3]), amx_ctof(params[4]), amx_ctof(params[5])); 41 | Utility::addToContainer(pickup->worlds, static_cast(params[6])); 42 | if (pickup->worlds.empty()) 43 | { 44 | pickup->worlds.insert(-1); 45 | } 46 | Utility::addToContainer(pickup->interiors, static_cast(params[7])); 47 | Utility::addToContainer(pickup->players, static_cast(params[8])); 48 | pickup->comparableStreamDistance = amx_ctof(params[9]) < STREAMER_STATIC_DISTANCE_CUTOFF ? amx_ctof(params[9]) : amx_ctof(params[9]) * amx_ctof(params[9]); 49 | pickup->streamDistance = amx_ctof(params[9]); 50 | Utility::addToContainer(pickup->areas, static_cast(params[10])); 51 | pickup->priority = static_cast(params[11]); 52 | core->getGrid()->addPickup(pickup); 53 | core->getData()->pickups.insert(std::make_pair(pickupId, pickup)); 54 | return static_cast(pickupId); 55 | } 56 | 57 | cell AMX_NATIVE_CALL Natives::DestroyDynamicPickup(AMX *amx, cell *params) 58 | { 59 | CHECK_PARAMS(1); 60 | std::unordered_map::iterator p = core->getData()->pickups.find(static_cast(params[1])); 61 | if (p != core->getData()->pickups.end()) 62 | { 63 | Utility::destroyPickup(p); 64 | return 1; 65 | } 66 | return 0; 67 | } 68 | 69 | cell AMX_NATIVE_CALL Natives::IsValidDynamicPickup(AMX *amx, cell *params) 70 | { 71 | CHECK_PARAMS(1); 72 | std::unordered_map::iterator p = core->getData()->pickups.find(static_cast(params[1])); 73 | if (p != core->getData()->pickups.end()) 74 | { 75 | return 1; 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /src/natives/race-checkpoints.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../utility.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::CreateDynamicRaceCP(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(14); 26 | if (core->getData()->getGlobalMaxItems(STREAMER_TYPE_RACE_CP) == core->getData()->raceCheckpoints.size()) 27 | { 28 | return INVALID_STREAMER_ID; 29 | } 30 | int raceCheckpointId = Item::RaceCheckpoint::identifier.get(); 31 | Item::SharedRaceCheckpoint raceCheckpoint(new Item::RaceCheckpoint); 32 | raceCheckpoint->amx = amx; 33 | raceCheckpoint->raceCheckpointId = raceCheckpointId; 34 | raceCheckpoint->inverseAreaChecking = false; 35 | raceCheckpoint->originalComparableStreamDistance = -1.0f; 36 | raceCheckpoint->positionOffset = Eigen::Vector3f::Zero(); 37 | raceCheckpoint->streamCallbacks = false; 38 | raceCheckpoint->type = static_cast(params[1]); 39 | raceCheckpoint->position = Eigen::Vector3f(amx_ctof(params[2]), amx_ctof(params[3]), amx_ctof(params[4])); 40 | raceCheckpoint->next = Eigen::Vector3f(amx_ctof(params[5]), amx_ctof(params[6]), amx_ctof(params[7])); 41 | raceCheckpoint->size = amx_ctof(params[8]); 42 | Utility::addToContainer(raceCheckpoint->worlds, static_cast(params[9])); 43 | Utility::addToContainer(raceCheckpoint->interiors, static_cast(params[10])); 44 | Utility::addToContainer(raceCheckpoint->players, static_cast(params[11])); 45 | raceCheckpoint->comparableStreamDistance = amx_ctof(params[12]) < STREAMER_STATIC_DISTANCE_CUTOFF ? amx_ctof(params[12]) : amx_ctof(params[12]) * amx_ctof(params[12]); 46 | raceCheckpoint->streamDistance = amx_ctof(params[12]); 47 | Utility::addToContainer(raceCheckpoint->areas, static_cast(params[13])); 48 | raceCheckpoint->priority = static_cast(params[14]); 49 | core->getGrid()->addRaceCheckpoint(raceCheckpoint); 50 | core->getData()->raceCheckpoints.insert(std::make_pair(raceCheckpointId, raceCheckpoint)); 51 | return static_cast(raceCheckpointId); 52 | } 53 | 54 | cell AMX_NATIVE_CALL Natives::DestroyDynamicRaceCP(AMX *amx, cell *params) 55 | { 56 | CHECK_PARAMS(1); 57 | std::unordered_map::iterator r = core->getData()->raceCheckpoints.find(static_cast(params[1])); 58 | if (r != core->getData()->raceCheckpoints.end()) 59 | { 60 | Utility::destroyRaceCheckpoint(r); 61 | return 1; 62 | } 63 | return 0; 64 | } 65 | 66 | cell AMX_NATIVE_CALL Natives::IsValidDynamicRaceCP(AMX *amx, cell *params) 67 | { 68 | CHECK_PARAMS(1); 69 | std::unordered_map::iterator r = core->getData()->raceCheckpoints.find(static_cast(params[1])); 70 | if (r != core->getData()->raceCheckpoints.end()) 71 | { 72 | return 1; 73 | } 74 | return 0; 75 | } 76 | 77 | cell AMX_NATIVE_CALL Natives::IsPlayerInDynamicRaceCP(AMX *amx, cell *params) 78 | { 79 | CHECK_PARAMS(2); 80 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 81 | if (p != core->getData()->players.end()) 82 | { 83 | if (p->second.activeRaceCheckpoint == static_cast(params[2])) 84 | { 85 | return 1; 86 | } 87 | } 88 | return 0; 89 | } 90 | 91 | cell AMX_NATIVE_CALL Natives::GetPlayerVisibleDynamicRaceCP(AMX *amx, cell *params) 92 | { 93 | CHECK_PARAMS(1); 94 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 95 | if (p != core->getData()->players.end()) 96 | { 97 | return p->second.visibleRaceCheckpoint; 98 | } 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /src/natives/text-labels.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | #include "../utility.h" 22 | 23 | cell AMX_NATIVE_CALL Natives::CreateDynamic3DTextLabel(AMX *amx, cell *params) 24 | { 25 | CHECK_PARAMS(15); 26 | if (core->getData()->getGlobalMaxItems(STREAMER_TYPE_3D_TEXT_LABEL) == core->getData()->textLabels.size()) 27 | { 28 | return INVALID_STREAMER_ID; 29 | } 30 | int textLabelId = Item::TextLabel::identifier.get(); 31 | Item::SharedTextLabel textLabel(new Item::TextLabel); 32 | textLabel->amx = amx; 33 | textLabel->textLabelId = textLabelId; 34 | textLabel->inverseAreaChecking = false; 35 | textLabel->originalComparableStreamDistance = -1.0f; 36 | textLabel->positionOffset = Eigen::Vector3f::Zero(); 37 | textLabel->streamCallbacks = false; 38 | textLabel->text = Utility::convertNativeStringToString(amx, params[1]); 39 | textLabel->color = static_cast(params[2]); 40 | textLabel->position = Eigen::Vector3f(amx_ctof(params[3]), amx_ctof(params[4]), amx_ctof(params[5])); 41 | textLabel->drawDistance = amx_ctof(params[6]); 42 | if (static_cast(params[7]) != INVALID_PLAYER_ID || static_cast(params[8]) != INVALID_VEHICLE_ID) 43 | { 44 | textLabel->attach = std::make_shared(); 45 | textLabel->attach->player = static_cast(params[7]); 46 | textLabel->attach->vehicle = static_cast(params[8]); 47 | if (textLabel->position.cwiseAbs().maxCoeff() > 50.0f) 48 | { 49 | textLabel->position.setZero(); 50 | } 51 | core->getStreamer()->attachedTextLabels.insert(textLabel); 52 | } 53 | textLabel->testLOS = static_cast(params[9]) != 0; 54 | Utility::addToContainer(textLabel->worlds, static_cast(params[10])); 55 | Utility::addToContainer(textLabel->interiors, static_cast(params[11])); 56 | Utility::addToContainer(textLabel->players, static_cast(params[12])); 57 | textLabel->comparableStreamDistance = amx_ctof(params[13]) < STREAMER_STATIC_DISTANCE_CUTOFF ? amx_ctof(params[13]) : amx_ctof(params[13]) * amx_ctof(params[13]); 58 | textLabel->streamDistance = amx_ctof(params[13]); 59 | Utility::addToContainer(textLabel->areas, static_cast(params[14])); 60 | textLabel->priority = static_cast(params[15]); 61 | core->getGrid()->addTextLabel(textLabel); 62 | core->getData()->textLabels.insert(std::make_pair(textLabelId, textLabel)); 63 | return static_cast(textLabelId); 64 | } 65 | 66 | cell AMX_NATIVE_CALL Natives::DestroyDynamic3DTextLabel(AMX *amx, cell *params) 67 | { 68 | CHECK_PARAMS(1); 69 | std::unordered_map::iterator t = core->getData()->textLabels.find(static_cast(params[1])); 70 | if (t != core->getData()->textLabels.end()) 71 | { 72 | Utility::destroyTextLabel(t); 73 | return 1; 74 | } 75 | return 0; 76 | } 77 | 78 | cell AMX_NATIVE_CALL Natives::IsValidDynamic3DTextLabel(AMX *amx, cell *params) 79 | { 80 | CHECK_PARAMS(1); 81 | std::unordered_map::iterator t = core->getData()->textLabels.find(static_cast(params[1])); 82 | if (t != core->getData()->textLabels.end()) 83 | { 84 | return 1; 85 | } 86 | return 0; 87 | } 88 | 89 | cell AMX_NATIVE_CALL Natives::GetDynamic3DTextLabelText(AMX *amx, cell *params) 90 | { 91 | CHECK_PARAMS(3); 92 | std::unordered_map::iterator t = core->getData()->textLabels.find(static_cast(params[1])); 93 | if (t != core->getData()->textLabels.end()) 94 | { 95 | cell *text = NULL; 96 | amx_GetAddr(amx, params[2], &text); 97 | amx_SetString(text, t->second->text.c_str(), 0, 0, static_cast(params[3])); 98 | return 1; 99 | } 100 | return 0; 101 | } 102 | 103 | cell AMX_NATIVE_CALL Natives::UpdateDynamic3DTextLabelText(AMX *amx, cell *params) 104 | { 105 | CHECK_PARAMS(3); 106 | std::unordered_map::iterator t = core->getData()->textLabels.find(static_cast(params[1])); 107 | if (t != core->getData()->textLabels.end()) 108 | { 109 | t->second->color = static_cast(params[2]); 110 | t->second->text = Utility::convertNativeStringToString(amx, params[3]); 111 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 112 | { 113 | std::unordered_map::iterator i = p->second.internalTextLabels.find(t->first); 114 | if (i != p->second.internalTextLabels.end()) 115 | { 116 | sampgdk::UpdatePlayer3DTextLabelText(p->first, i->second, t->second->color, t->second->text.c_str()); 117 | } 118 | } 119 | return 1; 120 | } 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /src/natives/updates.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "../natives.h" 20 | #include "../core.h" 21 | 22 | cell AMX_NATIVE_CALL Natives::Streamer_ProcessActiveItems(AMX *amx, cell *params) 23 | { 24 | core->getStreamer()->processActiveItems(); 25 | return 1; 26 | } 27 | 28 | cell AMX_NATIVE_CALL Natives::Streamer_ToggleIdleUpdate(AMX *amx, cell *params) 29 | { 30 | CHECK_PARAMS(2); 31 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 32 | if (p != core->getData()->players.end()) 33 | { 34 | p->second.updateWhenIdle = static_cast(params[2]) != 0; 35 | return 1; 36 | } 37 | return 0; 38 | } 39 | 40 | cell AMX_NATIVE_CALL Natives::Streamer_IsToggleIdleUpdate(AMX *amx, cell *params) 41 | { 42 | CHECK_PARAMS(1); 43 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 44 | if (p != core->getData()->players.end()) 45 | { 46 | return static_cast(p->second.updateWhenIdle != 0); 47 | } 48 | return 0; 49 | } 50 | 51 | cell AMX_NATIVE_CALL Natives::Streamer_ToggleCameraUpdate(AMX *amx, cell *params) 52 | { 53 | CHECK_PARAMS(2); 54 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 55 | if (p != core->getData()->players.end()) 56 | { 57 | p->second.updateUsingCameraPosition = static_cast(params[2]) != 0; 58 | return 1; 59 | } 60 | return 0; 61 | } 62 | 63 | cell AMX_NATIVE_CALL Natives::Streamer_IsToggleCameraUpdate(AMX *amx, cell *params) 64 | { 65 | CHECK_PARAMS(1); 66 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 67 | if (p != core->getData()->players.end()) 68 | { 69 | return static_cast(p->second.updateUsingCameraPosition != 0); 70 | } 71 | return 0; 72 | } 73 | 74 | cell AMX_NATIVE_CALL Natives::Streamer_ToggleItemUpdate(AMX *amx, cell *params) 75 | { 76 | CHECK_PARAMS(3); 77 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 78 | if (p != core->getData()->players.end()) 79 | { 80 | if (static_cast(params[2]) >= 0 && static_cast(params[2]) < STREAMER_MAX_TYPES) 81 | { 82 | p->second.enabledItems.set(static_cast(params[2]), params[3] != 0); 83 | return 1; 84 | } 85 | } 86 | return 0; 87 | } 88 | 89 | cell AMX_NATIVE_CALL Natives::Streamer_IsToggleItemUpdate(AMX *amx, cell *params) 90 | { 91 | CHECK_PARAMS(2); 92 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 93 | if (p != core->getData()->players.end()) 94 | { 95 | if (static_cast(params[2]) >= 0 && static_cast(params[2]) < STREAMER_MAX_TYPES) 96 | { 97 | return static_cast(p->second.enabledItems.test(params[2]) != 0); 98 | } 99 | } 100 | return 0; 101 | } 102 | 103 | cell AMX_NATIVE_CALL Natives::Streamer_GetLastUpdateTime(AMX *amx, cell *params) 104 | { 105 | CHECK_PARAMS(1); 106 | Utility::storeFloatInNative(amx, params[1], core->getStreamer()->getLastUpdateTime()); 107 | return 1; 108 | } 109 | 110 | cell AMX_NATIVE_CALL Natives::Streamer_Update(AMX *amx, cell *params) 111 | { 112 | CHECK_PARAMS(2); 113 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 114 | if (p != core->getData()->players.end()) 115 | { 116 | p->second.interiorId = sampgdk::GetPlayerInterior(p->first); 117 | p->second.worldId = sampgdk::GetPlayerVirtualWorld(p->first); 118 | sampgdk::GetPlayerPos(p->first, &p->second.position[0], &p->second.position[1], &p->second.position[2]); 119 | core->getStreamer()->startManualUpdate(p->second, static_cast(params[2])); 120 | return 1; 121 | } 122 | return 0; 123 | } 124 | 125 | cell AMX_NATIVE_CALL Natives::Streamer_UpdateEx(AMX *amx, cell *params) 126 | { 127 | CHECK_PARAMS(9); 128 | std::unordered_map::iterator p = core->getData()->players.find(static_cast(params[1])); 129 | if (p != core->getData()->players.end()) 130 | { 131 | p->second.position = Eigen::Vector3f(amx_ctof(params[2]), amx_ctof(params[3]), amx_ctof(params[4])); 132 | if (static_cast(params[5]) >= 0) 133 | { 134 | p->second.worldId = static_cast(params[5]); 135 | } 136 | else 137 | { 138 | p->second.worldId = sampgdk::GetPlayerVirtualWorld(p->first); 139 | } 140 | if (static_cast(params[6]) >= 0) 141 | { 142 | p->second.interiorId = static_cast(params[6]); 143 | } 144 | else 145 | { 146 | p->second.interiorId = sampgdk::GetPlayerInterior(p->first); 147 | } 148 | if (static_cast(params[8]) >= 0) 149 | { 150 | sampgdk::SetPlayerPos(p->first, p->second.position[0], p->second.position[1], p->second.position[2]); 151 | if (static_cast(params[9])) 152 | { 153 | sampgdk::TogglePlayerControllable(p->first, false); 154 | } 155 | p->second.delayedUpdate = true; 156 | p->second.delayedUpdateType = static_cast(params[7]); 157 | p->second.delayedUpdateTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(static_cast(params[8])); 158 | p->second.delayedUpdateFreeze = static_cast(params[9]) != 0; 159 | } 160 | core->getStreamer()->startManualUpdate(p->second, static_cast(params[7])); 161 | return 1; 162 | } 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /src/player.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "main.h" 18 | 19 | #include "player.h" 20 | #include "core.h" 21 | 22 | Player::Player(int id) 23 | { 24 | activeCheckpoint = 0; 25 | activeRaceCheckpoint = 0; 26 | chunkTickCount[STREAMER_TYPE_OBJECT] = 0; 27 | chunkTickCount[STREAMER_TYPE_MAP_ICON] = 0; 28 | chunkTickCount[STREAMER_TYPE_3D_TEXT_LABEL] = 0; 29 | chunkTickRate[STREAMER_TYPE_OBJECT] = 1; 30 | chunkTickRate[STREAMER_TYPE_MAP_ICON] = 1; 31 | chunkTickRate[STREAMER_TYPE_3D_TEXT_LABEL] = 1; 32 | currentVisibleObjects = core->getData()->getGlobalMaxVisibleItems(STREAMER_TYPE_OBJECT); 33 | currentVisibleTextLabels = core->getData()->getGlobalMaxVisibleItems(STREAMER_TYPE_3D_TEXT_LABEL); 34 | delayedCheckpoint = 0; 35 | delayedRaceCheckpoint = 0; 36 | delayedUpdate = false; 37 | delayedUpdateType = 0; 38 | if (!sampgdk::IsPlayerNPC(id)) 39 | { 40 | enabledItems.set(); 41 | } 42 | interiorId = 0; 43 | maxVisibleMapIcons = core->getData()->getGlobalMaxVisibleItems(STREAMER_TYPE_MAP_ICON); 44 | maxVisibleObjects = core->getData()->getGlobalMaxVisibleItems(STREAMER_TYPE_OBJECT); 45 | maxVisibleTextLabels = core->getData()->getGlobalMaxVisibleItems(STREAMER_TYPE_3D_TEXT_LABEL); 46 | playerId = id; 47 | position.setZero(); 48 | radiusMultipliers[STREAMER_TYPE_OBJECT] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_OBJECT); 49 | radiusMultipliers[STREAMER_TYPE_PICKUP] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_PICKUP); 50 | radiusMultipliers[STREAMER_TYPE_CP] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_CP); 51 | radiusMultipliers[STREAMER_TYPE_RACE_CP] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_RACE_CP); 52 | radiusMultipliers[STREAMER_TYPE_MAP_ICON] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_MAP_ICON); 53 | radiusMultipliers[STREAMER_TYPE_3D_TEXT_LABEL] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_3D_TEXT_LABEL); 54 | radiusMultipliers[STREAMER_TYPE_AREA] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_AREA); 55 | radiusMultipliers[STREAMER_TYPE_ACTOR] = core->getData()->getGlobalRadiusMultiplier(STREAMER_TYPE_ACTOR); 56 | requestingClass = false; 57 | tickCount = 0; 58 | tickRate = 50; 59 | updateUsingCameraPosition = false; 60 | updateWhenIdle = false; 61 | visibleCell = std::make_shared(); 62 | visibleCheckpoint = 0; 63 | visibleRaceCheckpoint = 0; 64 | worldId = 0; 65 | } 66 | -------------------------------------------------------------------------------- /src/player.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PLAYER_H 18 | #define PLAYER_H 19 | 20 | #include "cell.h" 21 | #include "identifier.h" 22 | 23 | struct Player 24 | { 25 | Player(int id); 26 | 27 | int activeCheckpoint; 28 | int activeRaceCheckpoint; 29 | std::size_t chunkTickCount[STREAMER_MAX_TYPES]; 30 | std::size_t chunkTickRate[STREAMER_MAX_TYPES]; 31 | std::size_t currentVisibleObjects; 32 | std::size_t currentVisibleTextLabels; 33 | int delayedCheckpoint; 34 | int delayedRaceCheckpoint; 35 | bool delayedUpdate; 36 | bool delayedUpdateFreeze; 37 | std::chrono::steady_clock::time_point delayedUpdateTime; 38 | int delayedUpdateType; 39 | int interiorId; 40 | std::size_t maxVisibleMapIcons; 41 | std::size_t maxVisibleObjects; 42 | std::size_t maxVisibleTextLabels; 43 | int playerId; 44 | Eigen::Vector3f position; 45 | float radiusMultipliers[STREAMER_MAX_TYPES]; 46 | int references; 47 | bool requestingClass; 48 | std::size_t tickCount; 49 | std::size_t tickRate; 50 | bool updateUsingCameraPosition; 51 | bool updateWhenIdle; 52 | SharedCell visibleCell; 53 | int visibleCheckpoint; 54 | int visibleRaceCheckpoint; 55 | int worldId; 56 | 57 | std::bitset enabledItems; 58 | std::bitset processingChunks; 59 | 60 | Item::Bimap::Type discoveredMapIcons; 61 | Item::Bimap::Type discoveredObjects; 62 | Item::Bimap::Type discoveredTextLabels; 63 | 64 | Item::Bimap::Type existingMapIcons; 65 | Item::Bimap::Type existingObjects; 66 | Item::Bimap::Type existingTextLabels; 67 | 68 | std::unordered_set internalAreas; 69 | std::unordered_map internalMapIcons; 70 | std::unordered_map internalObjects; 71 | std::unordered_map internalTextLabels; 72 | 73 | std::unordered_set removedMapIcons; 74 | std::unordered_set removedObjects; 75 | std::unordered_set removedTextLabels; 76 | 77 | Identifier mapIconIdentifier; 78 | 79 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/streamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef STREAMER_H 18 | #define STREAMER_H 19 | 20 | #include "cell.h" 21 | #include "item.h" 22 | #include "player.h" 23 | #include "utility.h" 24 | 25 | class Streamer 26 | { 27 | public: 28 | Streamer(); 29 | 30 | inline float getLastUpdateTime() 31 | { 32 | return lastUpdateTime; 33 | } 34 | 35 | inline std::size_t getTickRate() 36 | { 37 | return tickRate; 38 | } 39 | 40 | inline bool setTickRate(std::size_t value) 41 | { 42 | if (value > 0) 43 | { 44 | tickRate = value; 45 | return true; 46 | } 47 | return false; 48 | } 49 | 50 | void startAutomaticUpdate(); 51 | void startManualUpdate(Player &player, int type); 52 | 53 | bool processPlayerArea(Player &player, const Item::SharedArea &a, const int state); 54 | 55 | void processActiveItems(); 56 | 57 | std::unordered_set attachedAreas; 58 | std::unordered_set attachedObjects; 59 | std::unordered_set attachedTextLabels; 60 | std::unordered_set movingObjects; 61 | private: 62 | void calculateAverageElapsedTime(); 63 | 64 | void executeCallbacks(); 65 | 66 | void performPlayerUpdate(Player &player, bool automatic); 67 | 68 | void discoverActors(Player &player, const std::vector &cells); 69 | void streamActors(); 70 | 71 | void processAreas(Player &player, const std::vector &cells); 72 | void processCheckpoints(Player &player, const std::vector &cells); 73 | void processRaceCheckpoints(Player &player, const std::vector &cells); 74 | void processMapIcons(Player &player, const std::vector &cells); 75 | void processObjects(Player &player, const std::vector &cells); 76 | 77 | void discoverPickups(Player &player, const std::vector &cells); 78 | void streamPickups(); 79 | 80 | void processTextLabels(Player &player, const std::vector &cells); 81 | 82 | void processMovingObjects(); 83 | void processAttachedAreas(); 84 | void processAttachedObjects(); 85 | void processAttachedTextLabels(); 86 | 87 | std::size_t tickCount; 88 | std::size_t tickRate; 89 | 90 | float averageElapsedTime; 91 | float lastUpdateTime; 92 | 93 | std::tuple velocityBoundaries; 94 | 95 | std::multimap > areaEnterCallbacks; 96 | std::multimap > areaLeaveCallbacks; 97 | 98 | std::vector objectMoveCallbacks; 99 | protected: 100 | std::vector > streamInCallbacks; 101 | std::vector > streamOutCallbacks; 102 | 103 | template 104 | inline bool doesPlayerSatisfyConditions(const std::bitset &a, const T &b, const std::unordered_set &c, const T &d, const std::unordered_set &e, const T &f) 105 | { 106 | return (a[b] && (c.empty() || c.find(d) != c.end()) && (e.empty() || e.find(f) != e.end())); 107 | } 108 | 109 | template 110 | inline bool doesPlayerSatisfyConditions(const std::bitset &a, const T &b, const std::unordered_set &c, const T &d, const std::unordered_set &e, const T &f, const std::unordered_set &g, const std::unordered_set &h, bool i) 111 | { 112 | return (a[b] && (c.empty() || c.find(d) != c.end()) && (e.empty() || e.find(f) != e.end()) && (g.empty() || i ? !Utility::isContainerWithinContainer(g, h) : Utility::isContainerWithinContainer(g, h))); 113 | } 114 | }; 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UTILITY_H 18 | #define UTILITY_H 19 | 20 | #include "utility/amx.h" 21 | #include "utility/geometry.h" 22 | #include "utility/misc.h" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/utility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND PLUGIN_SOURCES 2 | ${CMAKE_CURRENT_SOURCE_DIR}/amx.cpp 3 | ${CMAKE_CURRENT_SOURCE_DIR}/geometry.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/misc.cpp 5 | ) 6 | 7 | set(PLUGIN_SOURCES "${PLUGIN_SOURCES}" PARENT_SCOPE) 8 | -------------------------------------------------------------------------------- /src/utility/amx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "amx.h" 20 | #include "../core.h" 21 | 22 | using namespace Utility; 23 | 24 | cell AMX_NATIVE_CALL Utility::hookedNative(AMX *amx, cell *params) 25 | { 26 | return 1; 27 | } 28 | 29 | int Utility::checkInterfaceAndRegisterNatives(AMX *amx, AMX_NATIVE_INFO *amxNativeList) 30 | { 31 | AMX_HEADER *amxHeader = reinterpret_cast(amx->base); 32 | AMX_FUNCSTUBNT *amxNativeTable = reinterpret_cast(amx->base + amxHeader->natives); 33 | int amxRegisterResult = amx_Register(amx, amxNativeList, -1); 34 | bool foundNatives = false; 35 | bool hookedNatives = false; 36 | int numberOfNatives = 0; 37 | amx_NumNatives(amx, &numberOfNatives); 38 | for (int i = 0; i < numberOfNatives; ++i) 39 | { 40 | char *name = reinterpret_cast(amx->base + amxNativeTable[i].nameofs); 41 | if (std::string(name).find("Streamer_") != std::string::npos) 42 | { 43 | foundNatives = true; 44 | if (!amxNativeTable[i].address) 45 | { 46 | amxNativeTable[i].address = reinterpret_cast(hookedNative); 47 | hookedNatives = true; 48 | } 49 | } 50 | } 51 | if (foundNatives) 52 | { 53 | cell amxAddr = 0; 54 | int includeFileVersion = 0; 55 | if (!amx_FindPubVar(amx, "Streamer_IncludeFileVersion", &amxAddr)) 56 | { 57 | cell *amxPhysAddr = NULL; 58 | if (!amx_GetAddr(amx, amxAddr, &amxPhysAddr)) 59 | { 60 | includeFileVersion = static_cast(*amxPhysAddr); 61 | } 62 | } 63 | std::ostringstream includeFileVersionStream, pluginVersionStream; 64 | if (includeFileVersion <= 0) 65 | { 66 | includeFileVersionStream << "unknown version"; 67 | } 68 | else 69 | { 70 | includeFileVersionStream << std::hex << std::showbase << includeFileVersion; 71 | pluginVersionStream << std::hex << std::showbase << INCLUDE_FILE_VERSION; 72 | std::istringstream(includeFileVersionStream.str().substr(0, pluginVersionStream.str().length())) >> std::hex >> includeFileVersion; 73 | } 74 | if (includeFileVersion < INCLUDE_FILE_VERSION) 75 | { 76 | Utility::logError("The include file version (%s) for this script is older than the plugin version (%#x). The script might need to be recompiled with the latest include file.", includeFileVersionStream.str().c_str(), INCLUDE_FILE_VERSION); 77 | } 78 | else if (includeFileVersion > INCLUDE_FILE_VERSION) 79 | { 80 | Utility::logError("The plugin version (%#x) is older than the include file version (%s) for this script. The plugin might need to be updated to the latest version.", INCLUDE_FILE_VERSION, includeFileVersionStream.str().c_str()); 81 | } 82 | } 83 | if (hookedNatives) 84 | { 85 | amxRegisterResult = amx_Register(amx, amxNativeList, -1); 86 | } 87 | return amxRegisterResult; 88 | } 89 | 90 | void Utility::destroyAllItemsInInterface(AMX *amx) 91 | { 92 | std::unordered_map::iterator o = core->getData()->objects.begin(); 93 | while (o != core->getData()->objects.end()) 94 | { 95 | if (o->second->amx == amx) 96 | { 97 | o = destroyObject(o); 98 | } 99 | else 100 | { 101 | ++o; 102 | } 103 | } 104 | std::unordered_map::iterator p = core->getData()->pickups.begin(); 105 | while (p != core->getData()->pickups.end()) 106 | { 107 | if (p->second->amx == amx) 108 | { 109 | p = destroyPickup(p); 110 | } 111 | else 112 | { 113 | ++p; 114 | } 115 | } 116 | std::unordered_map::iterator c = core->getData()->checkpoints.begin(); 117 | while (c != core->getData()->checkpoints.end()) 118 | { 119 | if (c->second->amx == amx) 120 | { 121 | c = destroyCheckpoint(c); 122 | } 123 | else 124 | { 125 | ++c; 126 | } 127 | } 128 | std::unordered_map::iterator r = core->getData()->raceCheckpoints.begin(); 129 | while (r != core->getData()->raceCheckpoints.end()) 130 | { 131 | if (r->second->amx == amx) 132 | { 133 | r = destroyRaceCheckpoint(r); 134 | } 135 | else 136 | { 137 | ++r; 138 | } 139 | } 140 | std::unordered_map::iterator m = core->getData()->mapIcons.begin(); 141 | while (m != core->getData()->mapIcons.end()) 142 | { 143 | if (m->second->amx == amx) 144 | { 145 | m = destroyMapIcon(m); 146 | } 147 | else 148 | { 149 | ++m; 150 | } 151 | } 152 | std::unordered_map::iterator t = core->getData()->textLabels.begin(); 153 | while (t != core->getData()->textLabels.end()) 154 | { 155 | if (t->second->amx == amx) 156 | { 157 | t = destroyTextLabel(t); 158 | } 159 | else 160 | { 161 | ++t; 162 | } 163 | } 164 | Utility::executeFinalAreaCallbacksForAllAreas(amx, false); 165 | std::unordered_map::iterator a = core->getData()->areas.begin(); 166 | while (a != core->getData()->areas.end()) 167 | { 168 | if (a->second->amx == amx) 169 | { 170 | a = destroyArea(a); 171 | } 172 | else 173 | { 174 | ++a; 175 | } 176 | } 177 | std::unordered_map::iterator b = core->getData()->actors.begin(); 178 | while (b != core->getData()->actors.end()) 179 | { 180 | if (b->second->amx == amx) 181 | { 182 | b = destroyActor(b); 183 | } 184 | else 185 | { 186 | ++b; 187 | } 188 | } 189 | } 190 | 191 | void Utility::executeFinalAreaCallbacks(int areaid) 192 | { 193 | std::vector > callbacks; 194 | std::unordered_map::iterator a = core->getData()->areas.find(areaid); 195 | if (a != core->getData()->areas.end()) 196 | { 197 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 198 | { 199 | std::unordered_set::iterator i = p->second.internalAreas.find(a->first); 200 | if (i != p->second.internalAreas.end()) 201 | { 202 | callbacks.push_back(std::make_tuple(a->first, p->first)); 203 | } 204 | } 205 | } 206 | for (std::vector >::const_iterator c = callbacks.begin(); c != callbacks.end(); ++c) 207 | { 208 | for (std::set::iterator amx = core->getData()->interfaces.begin(); amx != core->getData()->interfaces.end(); ++amx) 209 | { 210 | int amxIndex = 0; 211 | if (!amx_FindPublic(*amx, "OnPlayerLeaveDynamicArea", &amxIndex)) 212 | { 213 | amx_Push(*amx, static_cast(std::get<0>(*c))); 214 | amx_Push(*amx, static_cast(std::get<1>(*c))); 215 | amx_Exec(*amx, NULL, amxIndex); 216 | } 217 | } 218 | } 219 | } 220 | 221 | void Utility::executeFinalAreaCallbacksForAllAreas(AMX *amx, bool ignoreInterface) 222 | { 223 | std::vector > callbacks; 224 | for (std::unordered_map::iterator a = core->getData()->areas.begin(); a != core->getData()->areas.end(); ++a) 225 | { 226 | if (ignoreInterface || a->second->amx == amx) 227 | { 228 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 229 | { 230 | std::unordered_set::iterator i = p->second.internalAreas.find(a->first); 231 | if (i != p->second.internalAreas.end()) 232 | { 233 | callbacks.push_back(std::make_tuple(a->first, p->first)); 234 | } 235 | } 236 | } 237 | } 238 | for (std::vector >::const_iterator c = callbacks.begin(); c != callbacks.end(); ++c) 239 | { 240 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 241 | { 242 | int amxIndex = 0; 243 | if (!amx_FindPublic(*a, "OnPlayerLeaveDynamicArea", &amxIndex)) 244 | { 245 | amx_Push(*a, static_cast(std::get<0>(*c))); 246 | amx_Push(*a, static_cast(std::get<1>(*c))); 247 | amx_Exec(*a, NULL, amxIndex); 248 | } 249 | } 250 | } 251 | } 252 | 253 | void Utility::logError(const char *format, ...) 254 | { 255 | va_list args; 256 | va_start(args, format); 257 | char buffer[MAX_BUFFER]; 258 | vsnprintf(buffer, sizeof(buffer), format, args); 259 | buffer[sizeof(buffer) - 1] = '\0'; 260 | va_end(args); 261 | if (core->getData()->errorCallbackEnabled) 262 | { 263 | for (std::set::iterator a = core->getData()->interfaces.begin(); a != core->getData()->interfaces.end(); ++a) 264 | { 265 | cell amxAddress = 0; 266 | int amxIndex = 0; 267 | if (!amx_FindPublic(*a, "Streamer_OnPluginError", &amxIndex)) 268 | { 269 | amx_PushString(*a, &amxAddress, NULL, buffer, 0, 0); 270 | amx_Exec(*a, NULL, amxIndex); 271 | amx_Release(*a, amxAddress); 272 | } 273 | } 274 | } 275 | else 276 | { 277 | static std::string lastErrorMessage; 278 | if (lastErrorMessage != buffer) 279 | { 280 | sampgdk::logprintf("*** Streamer Plugin: %s", buffer); 281 | } 282 | lastErrorMessage = buffer; 283 | } 284 | } 285 | 286 | void Utility::convertArrayToPolygon(AMX *amx, cell input, cell size, Polygon2d &polygon) 287 | { 288 | cell *array = NULL; 289 | std::vector points; 290 | amx_GetAddr(amx, input, &array); 291 | for (std::size_t i = 0; i < static_cast(size); i += 2) 292 | { 293 | points.push_back(Eigen::Vector2f(amx_ctof(array[i]), amx_ctof(array[i + 1]))); 294 | } 295 | boost::geometry::assign_points(polygon, points); 296 | boost::geometry::correct(polygon); 297 | } 298 | 299 | bool Utility::convertPolygonToArray(AMX *amx, cell output, cell size, Polygon2d &polygon) 300 | { 301 | cell *array = NULL; 302 | std::size_t i = 0; 303 | amx_GetAddr(amx, output, &array); 304 | for (std::vector::iterator p = polygon.outer().begin(); p != polygon.outer().end(); ++p) 305 | { 306 | if ((i + 1) >= static_cast(size)) 307 | { 308 | return false; 309 | } 310 | array[i++] = amx_ftoc(p->data()[0]); 311 | array[i++] = amx_ftoc(p->data()[1]); 312 | } 313 | return true; 314 | } 315 | 316 | std::string Utility::convertNativeStringToString(AMX *amx, cell input) 317 | { 318 | char *string = NULL; 319 | amx_StrParam(amx, input, string); 320 | return string ? string : ""; 321 | } 322 | 323 | void Utility::convertStringToNativeString(AMX *amx, cell output, cell size, std::string string) 324 | { 325 | cell *address = NULL; 326 | amx_GetAddr(amx, output, &address); 327 | amx_SetString(address, string.c_str(), 0, 0, static_cast(size)); 328 | } 329 | 330 | void Utility::storeFloatInNative(AMX *amx, cell output, float value) 331 | { 332 | cell *address; 333 | amx_GetAddr(amx, output, &address); 334 | *address = amx_ftoc(value); 335 | } 336 | 337 | void Utility::storeIntegerInNative(AMX *amx, cell output, int value) 338 | { 339 | cell *address; 340 | amx_GetAddr(amx, output, &address); 341 | *address = value; 342 | } 343 | -------------------------------------------------------------------------------- /src/utility/amx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UTILITY_AMX_H 18 | #define UTILITY_AMX_H 19 | 20 | #include "misc.h" 21 | #include "../item.h" 22 | 23 | #define MAX_BUFFER (1024) 24 | 25 | namespace Utility 26 | { 27 | cell AMX_NATIVE_CALL hookedNative(AMX *amx, cell *params); 28 | 29 | int checkInterfaceAndRegisterNatives(AMX *amx, AMX_NATIVE_INFO *amxNativeList); 30 | void destroyAllItemsInInterface(AMX *amx); 31 | void executeFinalAreaCallbacks(int areaid); 32 | void executeFinalAreaCallbacksForAllAreas(AMX *amx, bool ignoreInterface); 33 | void logError(const char *format, ...); 34 | 35 | template 36 | bool convertArrayToContainer(AMX *amx, cell input, cell size, std::vector &container) 37 | { 38 | cell *array = NULL; 39 | amx_GetAddr(amx, input, &array); 40 | container.clear(); 41 | for (std::size_t i = 0; i < static_cast(size); ++i) 42 | { 43 | if (!addToContainer(container, static_cast(array[i]))) 44 | { 45 | return false; 46 | } 47 | } 48 | return true; 49 | } 50 | 51 | template 52 | bool convertArrayToContainer(AMX *amx, cell input, cell size, std::unordered_set &container) 53 | { 54 | cell *array = NULL; 55 | amx_GetAddr(amx, input, &array); 56 | container.clear(); 57 | for (std::size_t i = 0; i < static_cast(size); ++i) 58 | { 59 | if (!addToContainer(container, static_cast(array[i]))) 60 | { 61 | return false; 62 | } 63 | } 64 | return true; 65 | } 66 | 67 | template 68 | bool convertArrayToContainer(AMX *amx, cell input, cell size, std::bitset &container) 69 | { 70 | cell *array = NULL; 71 | amx_GetAddr(amx, input, &array); 72 | container.reset(); 73 | for (std::size_t i = 0; i < static_cast(size); ++i) 74 | { 75 | if (!addToContainer(container, static_cast(array[i]))) 76 | { 77 | return false; 78 | } 79 | } 80 | return true; 81 | } 82 | 83 | template 84 | bool convertContainerToArray(AMX *amx, cell output, cell size, const std::vector &container) 85 | { 86 | cell *array = NULL; 87 | std::size_t i = 0; 88 | amx_GetAddr(amx, output, &array); 89 | for (typename std::vector::const_iterator c = container.begin(); c != container.end(); ++c) 90 | { 91 | if (i == static_cast(size)) 92 | { 93 | return false; 94 | } 95 | array[i++] = static_cast(*c); 96 | } 97 | return true; 98 | } 99 | 100 | template 101 | bool convertContainerToArray(AMX *amx, cell output, cell size, const std::unordered_set &container) 102 | { 103 | cell *array = NULL; 104 | std::size_t i = 0; 105 | amx_GetAddr(amx, output, &array); 106 | for (typename std::unordered_set::const_iterator c = container.begin(); c != container.end(); ++c) 107 | { 108 | if (i == static_cast(size)) 109 | { 110 | return false; 111 | } 112 | array[i++] = static_cast(*c); 113 | } 114 | return true; 115 | } 116 | 117 | template 118 | bool convertContainerToArray(AMX *amx, cell output, cell size, const std::bitset &container) 119 | { 120 | cell *array = NULL; 121 | std::size_t i = 0; 122 | amx_GetAddr(amx, output, &array); 123 | for (std::size_t c = 0; c < N; ++c) 124 | { 125 | if (i == static_cast(size)) 126 | { 127 | return false; 128 | } 129 | if (container[c]) 130 | { 131 | array[i++] = static_cast(c); 132 | } 133 | } 134 | return true; 135 | } 136 | 137 | void convertArrayToPolygon(AMX *amx, cell input, cell size, Polygon2d &polygon); 138 | bool convertPolygonToArray(AMX *amx, cell output, cell size, Polygon2d &polygon); 139 | std::string convertNativeStringToString(AMX *amx, cell input); 140 | void convertStringToNativeString(AMX *amx, cell output, cell size, std::string string); 141 | void storeFloatInNative(AMX *amx, cell output, float number); 142 | void storeIntegerInNative(AMX *amx, cell output, int number); 143 | } 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /src/utility/geometry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "geometry.h" 20 | #include "../core.h" 21 | 22 | using namespace Utility; 23 | 24 | bool Utility::doesLineSegmentIntersectArea(const Eigen::Vector3f &lineSegmentStart, const Eigen::Vector3f &lineSegmentEnd, const Item::SharedArea &area) 25 | { 26 | Eigen::Vector2f height = Eigen::Vector2f::Zero(); 27 | std::variant position; 28 | if (area->attach) 29 | { 30 | height = area->height; 31 | position = area->attach->position; 32 | } 33 | else 34 | { 35 | height = area->height; 36 | position = area->position; 37 | } 38 | switch (area->type) 39 | { 40 | case STREAMER_AREA_TYPE_CIRCLE: 41 | { 42 | return doesLineSegmentIntersectCircleOrSphere(Eigen::Vector2f(lineSegmentStart[0], lineSegmentStart[1]), Eigen::Vector2f(lineSegmentEnd[0], lineSegmentEnd[1]), std::get(position), area->comparableSize); 43 | } 44 | case STREAMER_AREA_TYPE_CYLINDER: 45 | { 46 | Box2d box2d = Box2d(Eigen::Vector2f(std::get(position)[0] - area->size, std::get(position)[1] - area->size), Eigen::Vector2f(std::get(position)[0] + area->size, std::get(position)[1] + area->size)); 47 | Box3d box3d = Box3d(Eigen::Vector3f(box2d.min_corner()[0], box2d.min_corner()[1], height[0]), Eigen::Vector3f(box2d.max_corner()[0], box2d.max_corner()[1], height[1])); 48 | return doesLineSegmentIntersectBox(lineSegmentStart, lineSegmentEnd, box3d); 49 | } 50 | case STREAMER_AREA_TYPE_SPHERE: 51 | { 52 | return doesLineSegmentIntersectCircleOrSphere(lineSegmentStart, lineSegmentEnd, std::get(position), area->comparableSize); 53 | } 54 | case STREAMER_AREA_TYPE_RECTANGLE: 55 | { 56 | return doesLineSegmentIntersectBox(Eigen::Vector2f(lineSegmentStart[0], lineSegmentStart[1]), Eigen::Vector2f(lineSegmentEnd[0], lineSegmentEnd[1]), std::get(position)); 57 | } 58 | case STREAMER_AREA_TYPE_CUBOID: 59 | { 60 | return doesLineSegmentIntersectBox(lineSegmentStart, lineSegmentEnd, std::get(position)); 61 | } 62 | case STREAMER_AREA_TYPE_POLYGON: 63 | { 64 | Box2d box2d = boost::geometry::return_envelope(std::get(position)); 65 | Box3d box3d = Box3d(Eigen::Vector3f(box2d.min_corner()[0], box2d.min_corner()[1], height[0]), Eigen::Vector3f(box2d.max_corner()[0], box2d.max_corner()[1], height[1])); 66 | return doesLineSegmentIntersectBox(lineSegmentStart, lineSegmentEnd, box3d); 67 | } 68 | } 69 | return false; 70 | } 71 | 72 | bool Utility::isPointInArea(const Eigen::Vector3f &point, const Item::SharedArea &area) 73 | { 74 | Eigen::Vector2f height = Eigen::Vector2f::Zero(); 75 | std::variant position; 76 | if (area->attach) 77 | { 78 | height = area->attach->height; 79 | position = area->attach->position; 80 | } 81 | else 82 | { 83 | height = area->height; 84 | position = area->position; 85 | } 86 | switch (area->type) 87 | { 88 | case STREAMER_AREA_TYPE_CIRCLE: 89 | { 90 | return boost::geometry::comparable_distance(Eigen::Vector2f(point[0], point[1]), std::get(position)) < area->comparableSize; 91 | } 92 | case STREAMER_AREA_TYPE_CYLINDER: 93 | { 94 | if ((almostEquals(point[2], height[0]) || (point[2] > height[0])) && (almostEquals(point[2], height[1]) || (point[2] < height[1]))) 95 | { 96 | return boost::geometry::comparable_distance(Eigen::Vector2f(point[0], point[1]), std::get(position)) < area->comparableSize; 97 | } 98 | return false; 99 | } 100 | case STREAMER_AREA_TYPE_SPHERE: 101 | { 102 | return boost::geometry::comparable_distance(point, std::get(position)) < area->comparableSize; 103 | } 104 | case STREAMER_AREA_TYPE_RECTANGLE: 105 | { 106 | return boost::geometry::covered_by(Eigen::Vector2f(point[0], point[1]), std::get(position)); 107 | } 108 | case STREAMER_AREA_TYPE_CUBOID: 109 | { 110 | return boost::geometry::covered_by(point, std::get(position)); 111 | } 112 | case STREAMER_AREA_TYPE_POLYGON: 113 | { 114 | if ((almostEquals(point[2], height[0]) || (point[2] > height[0])) && (almostEquals(point[2], height[1]) || (point[2] < height[1]))) 115 | { 116 | return boost::geometry::covered_by(Eigen::Vector2f(point[0], point[1]), std::get(position)); 117 | } 118 | return false; 119 | } 120 | } 121 | return false; 122 | } 123 | 124 | void Utility::constructAttachedArea(const Item::SharedArea &area, const std::variant &orientation, const Eigen::Vector3f location) 125 | { 126 | if (area->attach) 127 | { 128 | Eigen::Vector3f position = location; 129 | if (!area->attach->positionOffset.isZero()) 130 | { 131 | Utility::projectPoint(area->attach->positionOffset, orientation, position); 132 | } 133 | switch (area->type) 134 | { 135 | case STREAMER_AREA_TYPE_CIRCLE: 136 | { 137 | area->attach->position = Eigen::Vector2f(position[0], position[1]); 138 | break; 139 | } 140 | case STREAMER_AREA_TYPE_CYLINDER: 141 | { 142 | area->attach->height = Eigen::Vector2f(position[2] + area->height[0], position[2] + area->height[1]); 143 | area->attach->position = Eigen::Vector2f(position[0], position[1]); 144 | break; 145 | } 146 | case STREAMER_AREA_TYPE_SPHERE: 147 | { 148 | area->attach->position = position; 149 | break; 150 | } 151 | case STREAMER_AREA_TYPE_RECTANGLE: 152 | { 153 | std::get(area->attach->position).min_corner() = Eigen::Vector2f(position[0], position[1]) + std::get(area->position).min_corner(); 154 | std::get(area->attach->position).max_corner() = Eigen::Vector2f(position[0], position[1]) + std::get(area->position).max_corner(); 155 | boost::geometry::correct(std::get(area->attach->position)); 156 | break; 157 | } 158 | case STREAMER_AREA_TYPE_CUBOID: 159 | { 160 | std::get(area->attach->position).min_corner() = position + std::get(area->position).min_corner(); 161 | std::get(area->attach->position).max_corner() = position + std::get(area->position).max_corner(); 162 | boost::geometry::correct(std::get(area->attach->position)); 163 | break; 164 | } 165 | case STREAMER_AREA_TYPE_POLYGON: 166 | { 167 | area->attach->height = Eigen::Vector2f(position[2] + area->height[0], position[2] + area->height[1]); 168 | std::vector points; 169 | for (std::vector::iterator p = std::get(area->position).outer().begin(); p != std::get(area->position).outer().end(); ++p) 170 | { 171 | points.push_back(Eigen::Vector2f(position[0], position[1]) + Eigen::Vector2f(p->data()[0], p->data()[1])); 172 | } 173 | boost::geometry::assign_points(std::get(area->attach->position), points); 174 | boost::geometry::correct(std::get(area->attach->position)); 175 | break; 176 | } 177 | } 178 | } 179 | } 180 | 181 | void Utility::projectPoint(const Eigen::Vector3f &point, const std::variant &orientation, Eigen::Vector3f &position) 182 | { 183 | switch (orientation.index()) 184 | { 185 | case 0: 186 | { 187 | projectPoint(point, std::get(orientation), position); 188 | break; 189 | } 190 | case 1: 191 | { 192 | projectPoint(point, std::get(orientation), position); 193 | break; 194 | } 195 | case 2: 196 | { 197 | projectPoint(point, std::get(orientation), position); 198 | break; 199 | } 200 | } 201 | } 202 | 203 | void Utility::projectPoint(const Eigen::Vector3f &point, const float &heading, Eigen::Vector3f &position) 204 | { 205 | float angle = (std::atan2(point[0], point[1]) * (180.0f / (std::atan(1.0f) * 4.0f))) - heading, distance = std::sqrt((point[0] * point[0]) + (point[1] * point[1])); 206 | position[0] += distance * std::sin(angle * ((std::atan(1.0f) * 4.0f) / 180.0f)); 207 | position[1] += distance * std::cos(angle * ((std::atan(1.0f) * 4.0f) / 180.0f)); 208 | position[2] += point[2]; 209 | } 210 | 211 | void Utility::projectPoint(const Eigen::Vector3f &point, const Eigen::Vector3f &rotation, Eigen::Vector3f &position) 212 | { 213 | Eigen::Vector3f rotRad = rotation * ((std::atan(1.0f) * 4.0f) / 180.0f), rotCos(std::cos(rotRad[0]), std::cos(rotRad[1]), std::cos(rotRad[2])), rotSin(std::sin(rotRad[0]), std::sin(rotRad[1]), std::sin(rotRad[2])); 214 | position[0] += (point[0] * rotCos[1] * rotCos[2]) - (point[0] * rotSin[0] * rotSin[1] * rotSin[2]) - (point[1] * rotCos[0] * rotSin[2]) + (point[2] * rotSin[1] * rotCos[2]) + (point[2] * rotSin[0] * rotCos[1] * rotSin[2]); 215 | position[1] += (point[0] * rotCos[1] * rotSin[2]) + (point[0] * rotSin[0] * rotSin[1] * rotCos[2]) + (point[1] * rotCos[0] * rotCos[2]) + (point[2] * rotSin[1] * rotSin[2]) - (point[2] * rotSin[0] * rotCos[1] * rotCos[2]); 216 | position[2] += -(point[0] * rotCos[0] * rotSin[1]) + (point[1] * rotSin[0]) + (point[2] * rotCos[0] * rotCos[1]); 217 | } 218 | 219 | void Utility::projectPoint(const Eigen::Vector3f &point, const Eigen::Vector4f &quaternion, Eigen::Vector3f &position) 220 | { 221 | Eigen::Matrix3f matrix = Eigen::Matrix3f::Zero(); 222 | matrix(0, 0) = 1 - 2 * ((quaternion[1] * quaternion[1]) + (quaternion[2] * quaternion[2])); 223 | matrix(0, 1) = 2 * ((quaternion[0] * quaternion[1]) - (quaternion[2] * quaternion[3])); 224 | matrix(0, 2) = 2 * ((quaternion[0] * quaternion[2]) + (quaternion[1] * quaternion[3])); 225 | matrix(1, 0) = 2 * ((quaternion[0] * quaternion[1]) + (quaternion[2] * quaternion[3])); 226 | matrix(1, 1) = 1 - 2 * ((quaternion[0] * quaternion[0]) + (quaternion[2] * quaternion[2])); 227 | matrix(1, 2) = 2 * ((quaternion[1] * quaternion[2]) - (quaternion[0] * quaternion[3])); 228 | matrix(2, 0) = 2 * ((quaternion[0] * quaternion[2]) - (quaternion[1] * quaternion[3])); 229 | matrix(2, 1) = 2 * ((quaternion[1] * quaternion[2]) + (quaternion[0] * quaternion[3])); 230 | matrix(2, 2) = 1 - 2 * ((quaternion[0] * quaternion[0]) + (quaternion[1] * quaternion[1])); 231 | position[0] += (point[2] * matrix(2, 0)) + (point[1] * matrix(2, 1)) + (point[0] * matrix(2, 2)); 232 | position[1] += -((point[2] * matrix(1, 0)) + (point[1] * matrix(1, 1)) + (point[0] * matrix(1, 2))); 233 | position[2] += (point[2] * matrix(0, 0)) + (point[1] * matrix(0, 1)) + (point[0] * matrix(0, 2)); 234 | } 235 | -------------------------------------------------------------------------------- /src/utility/geometry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UTILITY_GEOMETRY_H 18 | #define UTILITY_GEOMETRY_H 19 | 20 | #include "misc.h" 21 | #include "../item.h" 22 | 23 | namespace Utility 24 | { 25 | bool doesLineSegmentIntersectArea(const Eigen::Vector3f &lineSegmentStart, const Eigen::Vector3f &lineSegmentEnd, const Item::SharedArea &area); 26 | bool isPointInArea(const Eigen::Vector3f &point, const Item::SharedArea &area); 27 | 28 | void constructAttachedArea(const Item::SharedArea &area, const std::variant &orientation, const Eigen::Vector3f location); 29 | 30 | void projectPoint(const Eigen::Vector3f &point, const std::variant &orientation, Eigen::Vector3f &position); 31 | void projectPoint(const Eigen::Vector3f &point, const float &heading, Eigen::Vector3f &position); 32 | void projectPoint(const Eigen::Vector3f &point, const Eigen::Vector3f &rotation, Eigen::Vector3f &position); 33 | void projectPoint(const Eigen::Vector3f &point, const Eigen::Vector4f &quaternion, Eigen::Vector3f &position); 34 | 35 | template 36 | bool doesLineSegmentIntersectBox(const T1 &lineSegmentStart, const T1 &lineSegmentEnd, const T2 &box) 37 | { 38 | boost::geometry::model::segment lineSegment = boost::geometry::model::segment(lineSegmentStart, lineSegmentEnd); 39 | return boost::geometry::intersects(lineSegment, box); 40 | } 41 | 42 | template 43 | bool doesLineSegmentIntersectCircleOrSphere(const T &lineSegmentStart, const T &lineSegmentEnd, const T ¢er, float squaredRadius) 44 | { 45 | boost::geometry::model::segment lineSegment = boost::geometry::model::segment(lineSegmentStart, lineSegmentEnd); 46 | float comparableDistance = static_cast(boost::geometry::comparable_distance(lineSegment, center)); 47 | return comparableDistance < squaredRadius || almostEquals(comparableDistance, squaredRadius); 48 | } 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/utility/misc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../main.h" 18 | 19 | #include "misc.h" 20 | #include "../core.h" 21 | 22 | using namespace Utility; 23 | 24 | std::unordered_map::iterator Utility::destroyActor(std::unordered_map::iterator a) 25 | { 26 | Item::Actor::identifier.remove(a->first, core->getData()->actors.size()); 27 | for (std::unordered_set::const_iterator w = a->second->worlds.begin(); w != a->second->worlds.end(); ++w) 28 | { 29 | std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalActors.find(std::make_pair(a->first, *w)); 30 | if (i != core->getData()->internalActors.end()) 31 | { 32 | core->getData()->destroyedActors.push_back(i->second); 33 | core->getData()->internalActors.erase(i); 34 | } 35 | std::unordered_map, Item::SharedActor, pair_hash>::iterator d = core->getData()->discoveredActors.find(std::make_pair(a->first, *w)); 36 | if (d != core->getData()->discoveredActors.end()) 37 | { 38 | core->getData()->discoveredActors.erase(d); 39 | } 40 | } 41 | core->getGrid()->removeActor(a->second); 42 | return core->getData()->actors.erase(a); 43 | } 44 | 45 | std::unordered_map::iterator Utility::destroyArea(std::unordered_map::iterator a) 46 | { 47 | Item::Area::identifier.remove(a->first, core->getData()->areas.size()); 48 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 49 | { 50 | p->second.internalAreas.erase(a->first); 51 | p->second.visibleCell->areas.erase(a->first); 52 | } 53 | core->getGrid()->removeArea(a->second); 54 | return core->getData()->areas.erase(a); 55 | } 56 | 57 | std::unordered_map::iterator Utility::destroyCheckpoint(std::unordered_map::iterator c) 58 | { 59 | Item::Checkpoint::identifier.remove(c->first, core->getData()->checkpoints.size()); 60 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 61 | { 62 | if (p->second.visibleCheckpoint == c->first) 63 | { 64 | sampgdk::DisablePlayerCheckpoint(p->first); 65 | p->second.activeCheckpoint = 0; 66 | p->second.visibleCheckpoint = 0; 67 | } 68 | p->second.visibleCell->checkpoints.erase(c->first); 69 | } 70 | core->getGrid()->removeCheckpoint(c->second); 71 | return core->getData()->checkpoints.erase(c); 72 | } 73 | 74 | std::unordered_map::iterator Utility::destroyMapIcon(std::unordered_map::iterator m) 75 | { 76 | Item::MapIcon::identifier.remove(m->first, core->getData()->mapIcons.size()); 77 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 78 | { 79 | Item::Bimap::Type::right_iterator d = p->second.discoveredMapIcons.right.find(std::make_tuple(m->first, m->second)); 80 | if (d != p->second.discoveredMapIcons.right.end()) 81 | { 82 | p->second.discoveredMapIcons.right.erase(d); 83 | } 84 | Item::Bimap::Type::right_iterator e = p->second.existingMapIcons.right.find(std::make_tuple(m->first, m->second)); 85 | if (e != p->second.existingMapIcons.right.end()) 86 | { 87 | p->second.existingMapIcons.right.erase(e); 88 | } 89 | std::unordered_map::iterator i = p->second.internalMapIcons.find(m->first); 90 | if (i != p->second.internalMapIcons.end()) 91 | { 92 | sampgdk::RemovePlayerMapIcon(p->first, i->second); 93 | p->second.mapIconIdentifier.remove(i->second, p->second.internalMapIcons.size()); 94 | p->second.internalMapIcons.erase(i); 95 | } 96 | std::unordered_set::iterator r = p->second.removedMapIcons.find(m->first); 97 | if (r != p->second.removedMapIcons.end()) 98 | { 99 | p->second.removedMapIcons.erase(r); 100 | } 101 | p->second.visibleCell->mapIcons.erase(m->first); 102 | } 103 | core->getGrid()->removeMapIcon(m->second); 104 | return core->getData()->mapIcons.erase(m); 105 | } 106 | 107 | std::unordered_map::iterator Utility::destroyObject(std::unordered_map::iterator o) 108 | { 109 | Item::Object::identifier.remove(o->first, core->getData()->objects.size()); 110 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 111 | { 112 | Item::Bimap::Type::right_iterator d = p->second.discoveredObjects.right.find(std::make_tuple(o->first, o->second)); 113 | if (d != p->second.discoveredObjects.right.end()) 114 | { 115 | p->second.discoveredObjects.right.erase(d); 116 | } 117 | Item::Bimap::Type::right_iterator e = p->second.existingObjects.right.find(std::make_tuple(o->first, o->second)); 118 | if (e != p->second.existingObjects.right.end()) 119 | { 120 | p->second.existingObjects.right.erase(e); 121 | } 122 | std::unordered_map::iterator i = p->second.internalObjects.find(o->first); 123 | if (i != p->second.internalObjects.end()) 124 | { 125 | sampgdk::DestroyPlayerObject(p->first, i->second); 126 | p->second.internalObjects.erase(i); 127 | } 128 | std::unordered_set::iterator r = p->second.removedObjects.find(o->first); 129 | if (r != p->second.removedObjects.end()) 130 | { 131 | p->second.removedObjects.erase(r); 132 | } 133 | p->second.visibleCell->objects.erase(o->first); 134 | } 135 | core->getGrid()->removeObject(o->second); 136 | return core->getData()->objects.erase(o); 137 | } 138 | 139 | std::unordered_map::iterator Utility::destroyPickup(std::unordered_map::iterator p) 140 | { 141 | Item::Pickup::identifier.remove(p->first, core->getData()->pickups.size()); 142 | for (std::unordered_set::const_iterator w = p->second->worlds.begin(); w != p->second->worlds.end(); ++w) 143 | { 144 | std::unordered_map, int, pair_hash>::iterator i = core->getData()->internalPickups.find(std::make_pair(p->first, *w)); 145 | if (i != core->getData()->internalPickups.end()) 146 | { 147 | sampgdk::DestroyPickup(i->second); 148 | core->getData()->internalPickups.erase(i); 149 | } 150 | std::unordered_map, Item::SharedPickup, pair_hash>::iterator d = core->getData()->discoveredPickups.find(std::make_pair(p->first, *w)); 151 | if (d != core->getData()->discoveredPickups.end()) 152 | { 153 | core->getData()->discoveredPickups.erase(d); 154 | } 155 | } 156 | core->getGrid()->removePickup(p->second); 157 | return core->getData()->pickups.erase(p); 158 | } 159 | 160 | std::unordered_map::iterator Utility::destroyRaceCheckpoint(std::unordered_map::iterator r) 161 | { 162 | Item::RaceCheckpoint::identifier.remove(r->first, core->getData()->raceCheckpoints.size()); 163 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 164 | { 165 | if (p->second.visibleRaceCheckpoint == r->first) 166 | { 167 | sampgdk::DisablePlayerRaceCheckpoint(p->first); 168 | p->second.activeRaceCheckpoint = 0; 169 | p->second.visibleRaceCheckpoint = 0; 170 | } 171 | p->second.visibleCell->raceCheckpoints.erase(r->first); 172 | } 173 | core->getGrid()->removeRaceCheckpoint(r->second); 174 | return core->getData()->raceCheckpoints.erase(r); 175 | } 176 | 177 | std::unordered_map::iterator Utility::destroyTextLabel(std::unordered_map::iterator t) 178 | { 179 | Item::TextLabel::identifier.remove(t->first, core->getData()->textLabels.size()); 180 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 181 | { 182 | Item::Bimap::Type::right_iterator d = p->second.discoveredTextLabels.right.find(std::make_tuple(t->first, t->second)); 183 | if (d != p->second.discoveredTextLabels.right.end()) 184 | { 185 | p->second.discoveredTextLabels.right.erase(d); 186 | } 187 | Item::Bimap::Type::right_iterator e = p->second.existingTextLabels.right.find(std::make_tuple(t->first, t->second)); 188 | if (e != p->second.existingTextLabels.right.end()) 189 | { 190 | p->second.existingTextLabels.right.erase(e); 191 | } 192 | std::unordered_map::iterator i = p->second.internalTextLabels.find(t->first); 193 | if (i != p->second.internalTextLabels.end()) 194 | { 195 | sampgdk::DeletePlayer3DTextLabel(p->first, i->second); 196 | p->second.internalTextLabels.erase(i); 197 | } 198 | std::unordered_set::iterator r = p->second.removedTextLabels.find(t->first); 199 | if (r != p->second.removedTextLabels.end()) 200 | { 201 | p->second.removedTextLabels.erase(r); 202 | } 203 | p->second.visibleCell->textLabels.erase(t->first); 204 | } 205 | core->getGrid()->removeTextLabel(t->second); 206 | return core->getData()->textLabels.erase(t); 207 | } 208 | 209 | std::size_t Utility::getChunkTickRate(int type, int playerid) 210 | { 211 | if (playerid >= 0 && playerid < MAX_PLAYERS) 212 | { 213 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 214 | if (p != core->getData()->players.end()) 215 | { 216 | switch (type) 217 | { 218 | case STREAMER_TYPE_OBJECT: 219 | { 220 | return p->second.chunkTickRate[STREAMER_TYPE_OBJECT]; 221 | } 222 | case STREAMER_TYPE_MAP_ICON: 223 | { 224 | return p->second.chunkTickRate[STREAMER_TYPE_MAP_ICON]; 225 | } 226 | case STREAMER_TYPE_3D_TEXT_LABEL: 227 | { 228 | return p->second.chunkTickRate[STREAMER_TYPE_3D_TEXT_LABEL]; 229 | } 230 | } 231 | } 232 | } 233 | return core->getData()->getGlobalChunkTickRate(type); 234 | } 235 | 236 | bool Utility::setChunkTickRate(int type, std::size_t value, int playerid) 237 | { 238 | if (playerid >= 0 && playerid < MAX_PLAYERS) 239 | { 240 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 241 | if (p != core->getData()->players.end()) 242 | { 243 | switch (type) 244 | { 245 | case STREAMER_TYPE_OBJECT: 246 | { 247 | p->second.chunkTickRate[STREAMER_TYPE_OBJECT] = value; 248 | return true; 249 | } 250 | case STREAMER_TYPE_MAP_ICON: 251 | { 252 | p->second.chunkTickRate[STREAMER_TYPE_MAP_ICON] = value; 253 | return true; 254 | } 255 | case STREAMER_TYPE_3D_TEXT_LABEL: 256 | { 257 | p->second.chunkTickRate[STREAMER_TYPE_3D_TEXT_LABEL] = value; 258 | return true; 259 | } 260 | } 261 | } 262 | } 263 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 264 | { 265 | switch (type) 266 | { 267 | case STREAMER_TYPE_OBJECT: 268 | { 269 | p->second.chunkTickRate[STREAMER_TYPE_OBJECT] = value; 270 | break; 271 | } 272 | case STREAMER_TYPE_MAP_ICON: 273 | { 274 | p->second.chunkTickRate[STREAMER_TYPE_MAP_ICON] = value; 275 | break; 276 | } 277 | case STREAMER_TYPE_3D_TEXT_LABEL: 278 | { 279 | p->second.chunkTickRate[STREAMER_TYPE_3D_TEXT_LABEL] = value; 280 | break; 281 | } 282 | } 283 | } 284 | return core->getData()->setGlobalChunkTickRate(type, value); 285 | } 286 | 287 | std::size_t Utility::getMaxVisibleItems(int type, int playerid) 288 | { 289 | if (playerid >= 0 && playerid < MAX_PLAYERS) 290 | { 291 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 292 | if (p != core->getData()->players.end()) 293 | { 294 | switch (type) 295 | { 296 | case STREAMER_TYPE_OBJECT: 297 | { 298 | return p->second.maxVisibleObjects; 299 | } 300 | case STREAMER_TYPE_MAP_ICON: 301 | { 302 | return p->second.maxVisibleMapIcons; 303 | } 304 | case STREAMER_TYPE_3D_TEXT_LABEL: 305 | { 306 | return p->second.maxVisibleTextLabels; 307 | } 308 | } 309 | } 310 | } 311 | return core->getData()->getGlobalMaxVisibleItems(type); 312 | } 313 | 314 | bool Utility::setMaxVisibleItems(int type, std::size_t value, int playerid) 315 | { 316 | if (playerid >= 0 && playerid < MAX_PLAYERS) 317 | { 318 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 319 | if (p != core->getData()->players.end()) 320 | { 321 | switch (type) 322 | { 323 | case STREAMER_TYPE_OBJECT: 324 | { 325 | p->second.maxVisibleObjects = value; 326 | return true; 327 | } 328 | case STREAMER_TYPE_MAP_ICON: 329 | { 330 | p->second.maxVisibleMapIcons = value; 331 | return true; 332 | } 333 | case STREAMER_TYPE_3D_TEXT_LABEL: 334 | { 335 | p->second.maxVisibleTextLabels = value; 336 | return true; 337 | } 338 | } 339 | } 340 | } 341 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 342 | { 343 | switch (type) 344 | { 345 | case STREAMER_TYPE_OBJECT: 346 | { 347 | p->second.maxVisibleObjects = value; 348 | break; 349 | } 350 | case STREAMER_TYPE_MAP_ICON: 351 | { 352 | p->second.maxVisibleMapIcons = value; 353 | break; 354 | } 355 | case STREAMER_TYPE_3D_TEXT_LABEL: 356 | { 357 | p->second.maxVisibleTextLabels = value; 358 | break; 359 | } 360 | } 361 | } 362 | return core->getData()->setGlobalMaxVisibleItems(type, value); 363 | } 364 | 365 | float Utility::getRadiusMultiplier(int type, int playerid) 366 | { 367 | if (type >= 0 && type < STREAMER_MAX_TYPES) 368 | { 369 | if (playerid >= 0 && playerid < MAX_PLAYERS) 370 | { 371 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 372 | if (p != core->getData()->players.end()) 373 | { 374 | return p->second.radiusMultipliers[type]; 375 | } 376 | } 377 | } 378 | return core->getData()->getGlobalRadiusMultiplier(type); 379 | } 380 | 381 | bool Utility::setRadiusMultiplier(int type, float value, int playerid) 382 | { 383 | if (type >= 0 && type < STREAMER_MAX_TYPES) 384 | { 385 | if (playerid >= 0 && playerid < MAX_PLAYERS) 386 | { 387 | std::unordered_map::iterator p = core->getData()->players.find(playerid); 388 | if (p != core->getData()->players.end()) 389 | { 390 | p->second.radiusMultipliers[type] = value; 391 | return true; 392 | } 393 | } 394 | for (std::unordered_map::iterator p = core->getData()->players.begin(); p != core->getData()->players.end(); ++p) 395 | { 396 | p->second.radiusMultipliers[type] = value; 397 | } 398 | } 399 | return core->getData()->setGlobalRadiusMultiplier(type, value); 400 | } 401 | 402 | void Utility::processPendingDestroyedActors() 403 | { 404 | if (!core->getData()->destroyedActors.empty()) 405 | { 406 | std::vector::iterator a = core->getData()->destroyedActors.begin(); 407 | while (a != core->getData()->destroyedActors.end()) 408 | { 409 | if (sampgdk::IsValidActor(*a)) 410 | { 411 | sampgdk::DestroyActor(*a); 412 | } 413 | a = core->getData()->destroyedActors.erase(a); 414 | } 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /src/utility/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Incognito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UTILITY_MISC_H 18 | #define UTILITY_MISC_H 19 | 20 | #include "../item.h" 21 | 22 | namespace Utility 23 | { 24 | std::unordered_map::iterator destroyActor(std::unordered_map::iterator a); 25 | std::unordered_map::iterator destroyArea(std::unordered_map::iterator a); 26 | std::unordered_map::iterator destroyCheckpoint(std::unordered_map::iterator c); 27 | std::unordered_map::iterator destroyMapIcon(std::unordered_map::iterator m); 28 | std::unordered_map::iterator destroyObject(std::unordered_map::iterator o); 29 | std::unordered_map::iterator destroyPickup(std::unordered_map::iterator p); 30 | std::unordered_map::iterator destroyRaceCheckpoint(std::unordered_map::iterator r); 31 | std::unordered_map::iterator destroyTextLabel(std::unordered_map::iterator t); 32 | 33 | std::size_t getChunkTickRate(int type, int playerid); 34 | bool setChunkTickRate(int type, std::size_t value, int playerid); 35 | 36 | std::size_t getMaxVisibleItems(int type, int playerid); 37 | bool setMaxVisibleItems(int type, std::size_t value, int playerid); 38 | 39 | float getRadiusMultiplier(int type, int playerid); 40 | bool setRadiusMultiplier(int type, float value, int playerid); 41 | 42 | void processPendingDestroyedActors(); 43 | 44 | template 45 | inline bool almostEquals(T a, T b) 46 | { 47 | return std::fabs(a - b) < std::numeric_limits::epsilon(); 48 | } 49 | 50 | template 51 | inline bool addToContainer(std::vector &container, T value) 52 | { 53 | container.push_back(value); 54 | return true; 55 | } 56 | 57 | template 58 | inline bool addToContainer(std::unordered_set &container, T value) 59 | { 60 | if (value >= 0) 61 | { 62 | container.insert(value); 63 | return true; 64 | } 65 | else 66 | { 67 | container.clear(); 68 | } 69 | return false; 70 | } 71 | 72 | template 73 | inline bool addToContainer(std::bitset &container, T value) 74 | { 75 | if (value < 0) 76 | { 77 | container.set(); 78 | } 79 | else if (static_cast(value) >= N) 80 | { 81 | container.reset(); 82 | } 83 | else 84 | { 85 | container.set(static_cast(value)); 86 | return true; 87 | } 88 | return false; 89 | } 90 | 91 | template 92 | inline int getFirstValueInContainer(const std::vector &container) 93 | { 94 | if (!container.empty()) 95 | { 96 | return container.front(); 97 | } 98 | return 0; 99 | } 100 | 101 | template 102 | inline int getFirstValueInContainer(const std::unordered_set &container) 103 | { 104 | const auto& i = container.begin(); 105 | if (i != container.end()) 106 | { 107 | return *i; 108 | } 109 | return -1; 110 | } 111 | 112 | template 113 | inline int getFirstValueInContainer(const std::bitset &container) 114 | { 115 | if (container.any()) 116 | { 117 | if (container.all()) 118 | { 119 | return -1; 120 | } 121 | for (std::size_t i = 0; i < N; ++i) 122 | { 123 | if (container.test(i)) 124 | { 125 | return i; 126 | } 127 | } 128 | } 129 | return INVALID_PLAYER_ID; 130 | } 131 | 132 | template 133 | inline bool setFirstValueInContainer(std::vector &container, T value) 134 | { 135 | container.clear(); 136 | return addToContainer(container, value); 137 | } 138 | 139 | template 140 | inline bool setFirstValueInContainer(std::unordered_set &container, T value) 141 | { 142 | container.clear(); 143 | return addToContainer(container, value); 144 | } 145 | 146 | template 147 | inline bool setFirstValueInContainer(std::bitset &container, T value) 148 | { 149 | container.reset(); 150 | return addToContainer(container, value); 151 | } 152 | 153 | template 154 | inline bool isInContainer(const std::vector &container, const T value) 155 | { 156 | if (std::find(container.begin(), container.end(), value) != container.end()) 157 | { 158 | return true; 159 | } 160 | return false; 161 | } 162 | 163 | template 164 | inline bool isInContainer(const std::unordered_set &container, const T value) 165 | { 166 | if (value >= 0) 167 | { 168 | if (container.find(value) != container.end()) 169 | { 170 | return true; 171 | } 172 | } 173 | else 174 | { 175 | if (container.empty()) 176 | { 177 | return true; 178 | } 179 | } 180 | return false; 181 | } 182 | 183 | template 184 | inline bool isInContainer(const std::bitset &container, const T value) 185 | { 186 | if (value >= 0 && static_cast(value) < N) 187 | { 188 | if (container[static_cast(value)]) 189 | { 190 | return true; 191 | } 192 | } 193 | else 194 | { 195 | if (container.count() == N) 196 | { 197 | return true; 198 | } 199 | } 200 | return false; 201 | } 202 | 203 | template 204 | inline bool isContainerWithinContainer(const std::unordered_set &mainContainer, const std::unordered_set &overlappingContainer) 205 | { 206 | for (typename std::unordered_set::const_iterator o = overlappingContainer.begin(); o != overlappingContainer.end(); ++o) 207 | { 208 | if (mainContainer.find(*o) != mainContainer.end()) 209 | { 210 | return true; 211 | } 212 | } 213 | return false; 214 | } 215 | 216 | template 217 | inline bool removeFromContainer(std::vector &container, T value) 218 | { 219 | typename std::vector::iterator i = std::find(container.begin(), container.end(), value); 220 | if (i != container.end()) 221 | { 222 | container.erase(i); 223 | return true; 224 | } 225 | return false; 226 | } 227 | 228 | template 229 | inline bool removeFromContainer(std::unordered_set &container, T value) 230 | { 231 | if (value >= 0) 232 | { 233 | container.erase(value); 234 | return true; 235 | } 236 | else 237 | { 238 | container.clear(); 239 | } 240 | return false; 241 | } 242 | 243 | template 244 | inline bool removeFromContainer(std::bitset &container, T value) 245 | { 246 | if (value >= 0 && static_cast(value) < N) 247 | { 248 | container.reset(static_cast(value)); 249 | return true; 250 | } 251 | else 252 | { 253 | container.reset(); 254 | } 255 | return false; 256 | } 257 | } 258 | 259 | #endif 260 | -------------------------------------------------------------------------------- /streamer.def: -------------------------------------------------------------------------------- 1 | LIBRARY "streamer" 2 | 3 | EXPORTS 4 | Supports 5 | Load 6 | Unload 7 | AmxLoad 8 | AmxUnload 9 | ProcessTick 10 | OnPlayerConnect 11 | OnPlayerDisconnect 12 | OnPlayerSpawn 13 | OnPlayerRequestClass 14 | OnPlayerEnterCheckpoint 15 | OnPlayerLeaveCheckpoint 16 | OnPlayerEnterRaceCheckpoint 17 | OnPlayerLeaveRaceCheckpoint 18 | OnPlayerPickUpPickup 19 | OnPlayerEditObject 20 | OnPlayerSelectObject 21 | OnPlayerWeaponShot 22 | OnPlayerGiveDamageActor 23 | OnActorStreamIn 24 | OnActorStreamOut 25 | -------------------------------------------------------------------------------- /streamer.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 4 | 1 VERSIONINFO 5 | FILEVERSION 2,9,5,0 6 | { 7 | BLOCK "StringFileInfo" 8 | { 9 | BLOCK "04090025" 10 | { 11 | VALUE "FileDescription", "SA-MP Streamer Plugin" 12 | VALUE "LegalCopyright", "Copyright � 2017 Incognito" 13 | VALUE "OriginalFilename", "streamer.dll" 14 | VALUE "ProductName", "SA-MP Streamer Plugin" 15 | VALUE "ProductVersion", "v2.9.6" 16 | } 17 | } 18 | BLOCK "VarFileInfo" 19 | { 20 | VALUE "Translation", 1033, 37 21 | } 22 | } 23 | --------------------------------------------------------------------------------