mirror of
				https://github.com/fedddddd/iw5-gsc-utils.git
				synced 2025-10-31 01:26:57 +00:00 
			
		
		
		
	Compare commits
	
		
			90 Commits
		
	
	
		
			v1.2.4
			...
			dependabot
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5f45acb202 | ||
|  | 1061c08829 | ||
|  | c75cf561f7 | ||
|  | 3ea6050498 | ||
|  | 1551d7f1fd | ||
|  | bf1d649bc1 | ||
|  | 71727a5197 | ||
|  | 530cd10466 | ||
|  | 978e251df8 | ||
|  | cb96052638 | ||
|  | 9b217b20e3 | ||
|  | 136a723187 | ||
|  | ad27dcb098 | ||
|  | 96acf0718e | ||
|  | 72f936e82a | ||
|  | 9a11ac82b3 | ||
|  | 8f36c271fd | ||
|  | e952b8a0f7 | ||
|  | f6d78fd815 | ||
|  | cadcca22f9 | ||
|  | c04a0a0d8c | ||
|  | 61706336ce | ||
|  | eb08109392 | ||
|  | b23cb2014b | ||
|  | 4d979bf659 | ||
|  | 206d06dc7d | ||
|  | 4d8af4bd45 | ||
|  | 46ab288488 | ||
|  | dd8c1ff71e | ||
|  | ed1ac62153 | ||
|  | 7f7fd016cf | ||
|  | 6c093888b5 | ||
|  | 1440760aa5 | ||
|  | 105c11a8b2 | ||
|  | 795f8ac162 | ||
|  | 6dd4d2651a | ||
|  | b2f030f349 | ||
|  | 2690eeeece | ||
|  | 098bd21008 | ||
|  | 2f474e979f | ||
|  | 2ab4da0ad9 | ||
|  | 28c5594094 | ||
|  | 6525bbb8bf | ||
|  | 1a9e3dfb15 | ||
|  | c62f1995e7 | ||
|  | 883e38ae58 | ||
|  | 1b2d4dbc46 | ||
|  | 7dfb35233e | ||
|  | d842022056 | ||
|  | 0a8ebc3058 | ||
|  | 8ccae5ddec | ||
|  | cfb143f0fd | ||
|  | 0281b5bef6 | ||
|  | 70a91b271d | ||
|  | a7576ea765 | ||
|  | 3a492f51d9 | ||
|  | d4ba37cde5 | ||
|  | 2ded4c6a2a | ||
|  | 24b3a9369e | ||
|  | 1d94fdd88d | ||
|  | 0af6b1cb13 | ||
|  | d72c6f7057 | ||
|  | 39b9e7e352 | ||
|  | 36fefa6bb5 | ||
|  | 4ffdb331b4 | ||
|  | 7b995b3348 | ||
|  | 14d0f401fb | ||
|  | df23604b1e | ||
|  | e2960bc895 | ||
| db90d361a9 | |||
| 6ec0c5e23c | |||
| c84d681a3a | |||
| 62d1c8671b | |||
| 877adfa4b6 | |||
| 12fd44d0da | |||
|  | 12562eb8fd | ||
| 286481cbcd | |||
|  | e9a877bd74 | ||
|  | 3060df1f05 | ||
|  | aa1ae8c574 | ||
| ccd8176c25 | |||
| c230a1d916 | |||
| 2785a60dc0 | |||
|  | 1b65bda323 | ||
|  | 9ca07aca55 | ||
|  | 10b45027d0 | ||
| d5c0063fee | |||
|  | 31920b0692 | ||
|  | 89e4edc00b | ||
|  | 379a21ff7e | 
							
								
								
									
										7
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | version: 2 | ||||||
|  | updates: | ||||||
|  | - package-ecosystem: gitsubmodule | ||||||
|  |   directory: "/" | ||||||
|  |   schedule: | ||||||
|  |     interval: daily | ||||||
|  |   open-pull-requests-limit: 10 | ||||||
							
								
								
									
										45
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | name: Build | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - "*" | ||||||
|  |   pull_request: | ||||||
|  |     branches: | ||||||
|  |       - "*" | ||||||
|  |     types: [opened, synchronize, reopened] | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     name: Build binaries | ||||||
|  |     runs-on: windows-2022 | ||||||
|  |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         configuration: | ||||||
|  |           - Debug | ||||||
|  |           - Release | ||||||
|  |     steps: | ||||||
|  |       - name: Check out files | ||||||
|  |         uses: actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           submodules: true | ||||||
|  |           fetch-depth: 0 | ||||||
|  |           lfs: false | ||||||
|  |  | ||||||
|  |       - name: Add msbuild to PATH | ||||||
|  |         uses: microsoft/setup-msbuild@v1.1.3 | ||||||
|  |  | ||||||
|  |       - name: Generate project files | ||||||
|  |         run: tools/premake5 vs2022 | ||||||
|  |  | ||||||
|  |       - name: Set up problem matching | ||||||
|  |         uses: ammaraskar/msvc-problem-matcher@master | ||||||
|  |  | ||||||
|  |       - name: Build ${{matrix.configuration}} binaries | ||||||
|  |         run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:PlatformTarget=x86 build/iw5-gsc-utils.sln | ||||||
|  |  | ||||||
|  |       - name: Upload ${{matrix.configuration}} binaries | ||||||
|  |         uses: actions/upload-artifact@v3.1.0 | ||||||
|  |         with: | ||||||
|  |           name: ${{matrix.configuration}} binaries | ||||||
|  |           path: | | ||||||
|  |             build/bin/${{matrix.configuration}}/iw5-gsc-utils.dll | ||||||
							
								
								
									
										13
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -4,12 +4,13 @@ | |||||||
| [submodule "deps/GSL"] | [submodule "deps/GSL"] | ||||||
| 	path = deps/GSL | 	path = deps/GSL | ||||||
| 	url = https://github.com/microsoft/GSL.git | 	url = https://github.com/microsoft/GSL.git | ||||||
| [submodule "deps/sol2"] |  | ||||||
| 	path = deps/sol2 |  | ||||||
| 	url = https://github.com/ThePhD/sol2.git |  | ||||||
| [submodule "deps/lua"] |  | ||||||
| 	path = deps/lua |  | ||||||
| 	url = https://github.com/lua/lua.git |  | ||||||
| [submodule "deps/json"] | [submodule "deps/json"] | ||||||
| 	path = deps/json | 	path = deps/json | ||||||
| 	url = https://github.com/nlohmann/json.git | 	url = https://github.com/nlohmann/json.git | ||||||
|  | 	branch = develop | ||||||
|  | [submodule "deps/gsc-tool"] | ||||||
|  | 	path = deps/gsc-tool | ||||||
|  | 	url = https://github.com/xensik/gsc-tool.git | ||||||
|  | [submodule "deps/zlib"] | ||||||
|  | 	path = deps/zlib | ||||||
|  | 	url = https://github.com/madler/zlib.git | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								deps/GSL
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								deps/GSL
									
									
									
									
										vendored
									
									
								
							 Submodule deps/GSL updated: c31a9ad5e8...b39e7e4b09
									
								
							
							
								
								
									
										1
									
								
								deps/gsc-tool
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								deps/gsc-tool
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule deps/gsc-tool added at 0e6238a6ab
									
								
							
							
								
								
									
										2
									
								
								deps/json
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								deps/json
									
									
									
									
										vendored
									
									
								
							 Submodule deps/json updated: e10a3fac8a...0457de21cf
									
								
							
							
								
								
									
										2
									
								
								deps/minhook
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								deps/minhook
									
									
									
									
										vendored
									
									
								
							 Submodule deps/minhook updated: 423d1e45af...1cc46107ee
									
								
							
							
								
								
									
										62
									
								
								deps/premake/gsc-tool.lua
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								deps/premake/gsc-tool.lua
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | gsc_tool = { | ||||||
|  | 	source = path.join(dependencies.basePath, "gsc-tool"), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function gsc_tool.import() | ||||||
|  | 	links { "xsk-gsc-iw5-pc", "xsk-gsc-utils" } | ||||||
|  | 	gsc_tool.includes() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function gsc_tool.includes() | ||||||
|  | 	includedirs { | ||||||
|  | 		path.join(gsc_tool.source, "include"), | ||||||
|  | 	} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function gsc_tool.project() | ||||||
|  | 	project "xsk-gsc-utils" | ||||||
|  | 		kind "StaticLib" | ||||||
|  | 		language "C++" | ||||||
|  |  | ||||||
|  | 		files { | ||||||
|  | 			path.join(gsc_tool.source, "include/xsk/utils/*.hpp"), | ||||||
|  | 			path.join(gsc_tool.source, "src/utils/*.cpp"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		includedirs { | ||||||
|  | 			path.join(gsc_tool.source, "include"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		zlib.includes() | ||||||
|  |  | ||||||
|  | 	project "xsk-gsc-iw5-pc" | ||||||
|  | 		kind "StaticLib" | ||||||
|  | 		language "C++" | ||||||
|  |  | ||||||
|  | 		filter "action:vs*" | ||||||
|  | 			buildoptions "/Zc:__cplusplus" | ||||||
|  | 		filter {} | ||||||
|  |  | ||||||
|  | 		files { | ||||||
|  | 			path.join(gsc_tool.source, "include/xsk/stdinc.hpp"), | ||||||
|  |  | ||||||
|  | 			path.join(gsc_tool.source, "include/xsk/gsc/engine/iw5_pc.hpp"), | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/engine/iw5_pc.cpp"), | ||||||
|  |  | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/engine/iw5_pc_code.cpp"), | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/engine/iw5_pc_func.cpp"), | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/engine/iw5_pc_meth.cpp"), | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/engine/iw5_pc_token.cpp"), | ||||||
|  |  | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/*.cpp"), | ||||||
|  |  | ||||||
|  | 			path.join(gsc_tool.source, "src/gsc/common/*.cpp"), | ||||||
|  | 			path.join(gsc_tool.source, "include/xsk/gsc/common/*.hpp"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		includedirs { | ||||||
|  | 			path.join(gsc_tool.source, "include"), | ||||||
|  | 		} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | table.insert(dependencies, gsc_tool) | ||||||
							
								
								
									
										39
									
								
								deps/premake/zlib.lua
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								deps/premake/zlib.lua
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | zlib = { | ||||||
|  | 	source = path.join(dependencies.basePath, "zlib"), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function zlib.import() | ||||||
|  | 	links { "zlib" } | ||||||
|  | 	zlib.includes() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function zlib.includes() | ||||||
|  | 	includedirs { | ||||||
|  | 		zlib.source | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	defines { | ||||||
|  | 		"ZLIB_CONST", | ||||||
|  | 	} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function zlib.project() | ||||||
|  | 	project "zlib" | ||||||
|  | 		language "C" | ||||||
|  |  | ||||||
|  | 		zlib.includes() | ||||||
|  |  | ||||||
|  | 		files { | ||||||
|  | 			path.join(zlib.source, "*.h"), | ||||||
|  | 			path.join(zlib.source, "*.c"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		defines { | ||||||
|  | 			"_CRT_SECURE_NO_DEPRECATE", | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		warnings "Off" | ||||||
|  | 		kind "StaticLib" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | table.insert(dependencies, zlib) | ||||||
							
								
								
									
										1
									
								
								deps/zlib
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								deps/zlib
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule deps/zlib added at 5c42a230b7
									
								
							| @@ -1,2 +1,3 @@ | |||||||
| @echo off | @echo off | ||||||
| tools\windows\premake5.exe vs2019 | call git submodule update --init --recursive | ||||||
|  | tools\premake5.exe vs2022 | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								premake5.lua
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								premake5.lua
									
									
									
									
									
								
							| @@ -36,12 +36,19 @@ workspace "iw5-gsc-utils" | |||||||
| 	targetdir "%{wks.location}/bin/%{cfg.buildcfg}" | 	targetdir "%{wks.location}/bin/%{cfg.buildcfg}" | ||||||
| 	targetname "%{prj.name}" | 	targetname "%{prj.name}" | ||||||
|  |  | ||||||
|  | 	configurations { "Debug", "Release", } | ||||||
|  |  | ||||||
| 	language "C++" | 	language "C++" | ||||||
|  | 	cppdialect "C++20" | ||||||
|  |  | ||||||
| 	architecture "x86" | 	architecture "x86" | ||||||
|  |  | ||||||
| 	buildoptions "/std:c++latest" |  | ||||||
| 	systemversion "latest" | 	systemversion "latest" | ||||||
|  | 	symbols "On" | ||||||
|  | 	staticruntime "On" | ||||||
|  | 	editandcontinue "Off" | ||||||
|  | 	warnings "Extra" | ||||||
|  | 	characterset "ASCII" | ||||||
|  |  | ||||||
| 	flags | 	flags | ||||||
| 	{ | 	{ | ||||||
| @@ -49,19 +56,15 @@ workspace "iw5-gsc-utils" | |||||||
| 		"MultiProcessorCompile", | 		"MultiProcessorCompile", | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	configurations { "Debug", "Release", } | 	filter "configurations:Release" | ||||||
|  |  | ||||||
| 	symbols "On" |  | ||||||
| 	 |  | ||||||
| 	configuration "Release" |  | ||||||
| 		optimize "Full" | 		optimize "Full" | ||||||
| 		defines { "NDEBUG" } | 		defines { "NDEBUG" } | ||||||
| 	configuration{} | 	filter {} | ||||||
|  |  | ||||||
| 	configuration "Debug" | 	filter "configurations:Debug" | ||||||
| 		optimize "Debug" | 		optimize "Debug" | ||||||
| 		defines { "DEBUG", "_DEBUG" } | 		defines { "DEBUG", "_DEBUG" } | ||||||
| 	configuration {} | 	filter {} | ||||||
|  |  | ||||||
| 	startproject "iw5-gsc-utils" | 	startproject "iw5-gsc-utils" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ namespace command | |||||||
| 			if (i > index) result.append(" "); | 			if (i > index) result.append(" "); | ||||||
| 			result.append(this->get(i)); | 			result.append(this->get(i)); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -96,7 +97,6 @@ namespace command | |||||||
| 	public: | 	public: | ||||||
| 		void post_unpack() override | 		void post_unpack() override | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,13 +21,13 @@ namespace gsc | |||||||
| 	{ | 	{ | ||||||
| 		std::string method_name(unsigned int id) | 		std::string method_name(unsigned int id) | ||||||
| 		{ | 		{ | ||||||
| 			const auto map = *game::plutonium::method_map_rev; | 			const auto& map = (*game::plutonium::gsc_ctx)->meth_map(); | ||||||
|  |  | ||||||
| 			for (const auto& function : map) | 			for (const auto& function : map) | ||||||
| 			{ | 			{ | ||||||
| 				if (function.second == id) | 				if (function.second == id) | ||||||
| 				{ | 				{ | ||||||
| 					return function.first; | 					return function.first.data(); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -36,13 +36,13 @@ namespace gsc | |||||||
|  |  | ||||||
| 		std::string function_name(unsigned int id) | 		std::string function_name(unsigned int id) | ||||||
| 		{ | 		{ | ||||||
| 			const auto map = *game::plutonium::function_map_rev; | 			const auto& map = (*game::plutonium::gsc_ctx)->func_map(); | ||||||
|  |  | ||||||
| 			for (const auto& function : map) | 			for (const auto& function : map) | ||||||
| 			{ | 			{ | ||||||
| 				if (function.second == id) | 				if (function.second == id) | ||||||
| 				{ | 				{ | ||||||
| 					return function.first; | 					return function.first.data(); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -53,8 +53,6 @@ namespace gsc | |||||||
| 		{ | 		{ | ||||||
| 			std::vector<scripting::script_value> args; | 			std::vector<scripting::script_value> args; | ||||||
|  |  | ||||||
| 			const auto top = game::scr_VmPub->top; |  | ||||||
|  |  | ||||||
| 			for (auto i = 0; i < game::scr_VmPub->outparamcount; i++) | 			for (auto i = 0; i < game::scr_VmPub->outparamcount; i++) | ||||||
| 			{ | 			{ | ||||||
| 				const auto value = game::scr_VmPub->top[-i]; | 				const auto value = game::scr_VmPub->top[-i]; | ||||||
| @@ -194,7 +192,7 @@ namespace gsc | |||||||
| 				return scr_get_object_field_hook.invoke<void>(classnum, entnum, offset); | 				return scr_get_object_field_hook.invoke<void>(classnum, entnum, offset); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			const auto field = custom_fields[classnum][offset]; | 			const auto& field = custom_fields[classnum][offset]; | ||||||
|  |  | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| @@ -219,7 +217,7 @@ namespace gsc | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			const auto args = get_arguments(); | 			const auto args = get_arguments(); | ||||||
| 			const auto field = custom_fields[classnum][offset]; | 			const auto& field = custom_fields[classnum][offset]; | ||||||
|  |  | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| @@ -250,10 +248,21 @@ namespace gsc | |||||||
| 	{ | 	{ | ||||||
| 		void add(const std::string& name, const script_function& func) | 		void add(const std::string& name, const script_function& func) | ||||||
| 		{ | 		{ | ||||||
| 			const auto index = function_map_start++; | 			auto index = 0u; | ||||||
|  | 			auto& ctx = (*game::plutonium::gsc_ctx); | ||||||
| 			 | 			 | ||||||
| 			functions[index] = func; | 			if (ctx->func_exists(name)) | ||||||
| 			(*game::plutonium::function_map_rev)[name] = index; | 			{ | ||||||
|  | 				printf("[iw5-gsc-utils] Warning: function '%s' already defined\n", name.data()); | ||||||
|  | 				index = ctx->func_id(name); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				index = function_map_start++; | ||||||
|  | 				ctx->func_add(name, index); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			functions.insert(std::make_pair(index, func)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -261,10 +270,21 @@ namespace gsc | |||||||
| 	{ | 	{ | ||||||
| 		void add(const std::string& name, const script_method& func) | 		void add(const std::string& name, const script_method& func) | ||||||
| 		{ | 		{ | ||||||
| 			const auto index = method_map_start++; | 			auto index = 0u; | ||||||
|  | 			auto& ctx = (*game::plutonium::gsc_ctx); | ||||||
|  |  | ||||||
| 			methods[index] = func; | 			if (ctx->meth_exists(name)) | ||||||
| 			(*game::plutonium::method_map_rev)[name] = index; | 			{ | ||||||
|  | 				printf("[iw5-gsc-utils] Warning: method '%s' already defined\n", name.data()); | ||||||
|  | 				index = ctx->meth_id(name); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				index = method_map_start++; | ||||||
|  | 				ctx->meth_add(name, index); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			methods.insert(std::make_pair(index, func)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -274,16 +294,13 @@ namespace gsc | |||||||
| 			const std::function<scripting::script_value(unsigned int entnum)>& getter, | 			const std::function<scripting::script_value(unsigned int entnum)>& getter, | ||||||
| 			const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter) | 			const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter) | ||||||
| 		{ | 		{ | ||||||
| 			const auto token_id = token_map_start++; |  | ||||||
| 			const auto offset = field_offset_start++; | 			const auto offset = field_offset_start++; | ||||||
|  |  | ||||||
| 			custom_fields[classnum][offset] = {name, getter, setter}; | 			custom_fields[classnum][offset] = {name, getter, setter}; | ||||||
| 			(*game::plutonium::token_map_rev)[name] = token_id; |  | ||||||
|  |  | ||||||
| 			post_load_callbacks.push_back([classnum, name, token_id, offset]() | 			post_load_callbacks.push_back([=]() | ||||||
| 			{ | 			{ | ||||||
| 				const auto name_str = game::SL_GetString(name.data(), 0); | 				const auto name_str = game::SL_GetString(name.data(), 0); | ||||||
| 				game::Scr_AddClassField(classnum, name_str, token_id, offset); | 				game::Scr_AddClassField(classnum, name_str, game::SL_GetCanonicalString(name.data()), offset); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -322,7 +339,7 @@ namespace gsc | |||||||
| 			scr_set_object_field_hook.create(0x52BCC0, scr_set_object_field_stub); | 			scr_set_object_field_hook.create(0x52BCC0, scr_set_object_field_stub); | ||||||
| 			scr_post_load_scripts_hook.create(0x628B50, scr_post_load_scripts_stub); | 			scr_post_load_scripts_hook.create(0x628B50, scr_post_load_scripts_stub); | ||||||
|  |  | ||||||
| 			field::add(classid::entity, "flags", | 			field::add(classid::entity, "entityflags", | ||||||
| 				[](unsigned int entnum) -> scripting::script_value | 				[](unsigned int entnum) -> scripting::script_value | ||||||
| 				{ | 				{ | ||||||
| 					const auto entity = &game::g_entities[entnum]; | 					const auto entity = &game::g_entities[entnum]; | ||||||
| @@ -380,6 +397,20 @@ namespace gsc | |||||||
| 				return {}; | 				return {}; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
|  | 			function::add("dropallbots", [](const function_args&) -> scripting::script_value | ||||||
|  | 			{ | ||||||
|  | 				for (auto i = 0; i < *game::svs_clientCount; i++) | ||||||
|  | 				{ | ||||||
|  | 					if (game::svs_clients[i].header.state != game::CS_FREE | ||||||
|  | 						&& game::svs_clients[i].header.netchan.remoteAddress.type == game::NA_BOT) | ||||||
|  | 					{ | ||||||
|  | 						game::SV_GameDropClient(i, "GAME_GET_TO_COVER"); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				return {}; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
| 			method::add("tell", [](const game::scr_entref_t ent, const function_args& args) -> scripting::script_value | 			method::add("tell", [](const game::scr_entref_t ent, const function_args& args) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				if (ent.classnum != 0) | 				if (ent.classnum != 0) | ||||||
| @@ -388,8 +419,13 @@ namespace gsc | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				const auto client = ent.entnum; | 				const auto client = ent.entnum; | ||||||
| 				const auto message = args[0].as<std::string>(); |  | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[client].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto message = args[0].as<std::string>(); | ||||||
| 				game::SV_GameSendServerCommand(client, 0, utils::string::va("%c \"%s\"", 84, message.data())); | 				game::SV_GameSendServerCommand(client, 0, utils::string::va("%c \"%s\"", 84, message.data())); | ||||||
|  |  | ||||||
| 				return {}; | 				return {}; | ||||||
| @@ -402,22 +438,62 @@ namespace gsc | |||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				const auto num = ent.entnum; | 				const auto client = ent.entnum; | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[client].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				const auto toggle = args[0].as<int>(); | 				const auto toggle = args[0].as<int>(); | ||||||
|  | 				auto flags = game::g_entities[client].client->ps.perks[0]; | ||||||
|  |  | ||||||
| 				auto g_client = game::g_entities[num].client; | 				game::g_entities[client].client->ps.perks[0] = toggle | ||||||
| 				auto playerState = &g_client->ps; | 					? flags | 0x4000u : flags & ~0x4000u; | ||||||
| 				auto flags = playerState->perks[0]; |  | ||||||
|  |  | ||||||
| 				playerState->perks[0] = toggle |  | ||||||
| 					? flags | 0x4000u |  | ||||||
| 					: flags & ~0x4000u; |  | ||||||
|  |  | ||||||
| 				return {}; | 				return {}; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
|  | 			method::add("isbot", [](const game::scr_entref_t ent, const function_args&) -> scripting::script_value | ||||||
|  | 			{ | ||||||
|  | 				if (ent.classnum != 0) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Invalid entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto client = ent.entnum; | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[client].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				return game::svs_clients[client].bIsTestClient; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			method::add("arecontrolsfrozen", [](const game::scr_entref_t ent, const function_args&) -> scripting::script_value | ||||||
|  | 			{ | ||||||
|  | 				if (ent.classnum != 0) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Invalid entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto client = ent.entnum; | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[client].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				return {(game::g_entities[client].client->flags & 4) != 0}; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			// let other plugins read the pointers | ||||||
|  | 			post_load_callbacks.push_back([]() | ||||||
|  | 			{ | ||||||
| 				utils::hook::jump(0x56C8EB, call_builtin_stub); | 				utils::hook::jump(0x56C8EB, call_builtin_stub); | ||||||
| 				utils::hook::jump(0x56CBDC, call_builtin_method_stub); | 				utils::hook::jump(0x56CBDC, call_builtin_method_stub); | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,6 +15,12 @@ namespace notifies | |||||||
| 		void client_command_stub(int clientNum) | 		void client_command_stub(int clientNum) | ||||||
| 		{ | 		{ | ||||||
| 			char cmd[1024] = {0}; | 			char cmd[1024] = {0}; | ||||||
|  | 			const auto* entity = &game::g_entities[clientNum]; | ||||||
|  |  | ||||||
|  | 			if (entity->client == nullptr) | ||||||
|  | 			{ | ||||||
|  | 				return; // Client is not fully in game yet | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			game::SV_Cmd_ArgvBuffer(0, cmd, 1024); | 			game::SV_Cmd_ArgvBuffer(0, cmd, 1024); | ||||||
|  |  | ||||||
| @@ -29,7 +35,7 @@ namespace notifies | |||||||
| 					const auto entity_id = game::Scr_GetEntityId(clientNum, 0); | 					const auto entity_id = game::Scr_GetEntityId(clientNum, 0); | ||||||
| 					const auto result = callback(entity_id, {message, cmd == "say_team"s}); | 					const auto result = callback(entity_id, {message, cmd == "say_team"s}); | ||||||
|  |  | ||||||
| 					if (result.is<int>()) | 					if (result.is<int>() && !hidden) | ||||||
| 					{ | 					{ | ||||||
| 						hidden = result.as<int>() == 0; | 						hidden = result.as<int>() == 0; | ||||||
| 					} | 					} | ||||||
|   | |||||||
| @@ -85,7 +85,6 @@ namespace scripting | |||||||
| 				callback(); | 				callback(); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			shutdown_callbacks = {}; |  | ||||||
| 			g_shutdown_game_hook.invoke<void>(free_scripts); | 			g_shutdown_game_hook.invoke<void>(free_scripts); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -96,7 +95,7 @@ namespace scripting | |||||||
| 			const auto file_id = atoi(filename); | 			const auto file_id = atoi(filename); | ||||||
| 			if (file_id) | 			if (file_id) | ||||||
| 			{ | 			{ | ||||||
| 				current_file = scripting::file_list[file_id]; | 				current_file = scripting::find_file(file_id); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			process_script_hook.invoke<void>(filename); | 			process_script_hook.invoke<void>(filename); | ||||||
|   | |||||||
							
								
								
									
										106
									
								
								src/component/signatures.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/component/signatures.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | #include <stdinc.hpp> | ||||||
|  | #include "signatures.hpp" | ||||||
|  | #include <utils/hook.hpp> | ||||||
|  |  | ||||||
|  | namespace signatures | ||||||
|  | { | ||||||
|  | 	size_t load_image_size() | ||||||
|  | 	{ | ||||||
|  | 		MODULEINFO info{}; | ||||||
|  | 		GetModuleInformation(GetCurrentProcess(), | ||||||
|  | 			GetModuleHandle("plutonium-bootstrapper-win32.exe"), &info, sizeof(MODULEINFO)); | ||||||
|  | 		return info.SizeOfImage; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	size_t get_image_size() | ||||||
|  | 	{ | ||||||
|  | 		static const auto image_size = load_image_size(); | ||||||
|  | 		return image_size; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void load_function_tables() | ||||||
|  | 	{ | ||||||
|  | 		static const auto ptr = *reinterpret_cast<size_t*>(0x56CBDC + 0x1) + 0x56CBDC + 0x5; | ||||||
|  | 		static const auto function_table = *reinterpret_cast<size_t*>(0x56C8EB + 0x3); | ||||||
|  | 		static const auto method_table = *reinterpret_cast<size_t*>(ptr + 0xA); | ||||||
|  |  | ||||||
|  | 		game::plutonium::function_table.set(function_table); | ||||||
|  | 		game::plutonium::method_table.set(method_table); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	size_t find_string_ptr(const std::string& string) | ||||||
|  | 	{ | ||||||
|  | 		const char* string_ptr = nullptr; | ||||||
|  | 		std::string mask(string.size(), 'x'); | ||||||
|  | 		const auto base = reinterpret_cast<size_t>(GetModuleHandle("plutonium-bootstrapper-win32.exe")); | ||||||
|  | 		utils::hook::signature signature(base, get_image_size() - base); | ||||||
|  |  | ||||||
|  | 		auto found = false; | ||||||
|  | 		signature.add({ | ||||||
|  | 			string, | ||||||
|  | 			mask, | ||||||
|  | 			[&](char* address) | ||||||
|  | 			{ | ||||||
|  | 				if (found) | ||||||
|  | 				{ | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				found = true; | ||||||
|  | 				string_ptr = address; | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		signature.process(); | ||||||
|  | 		return reinterpret_cast<size_t>(string_ptr); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	size_t find_string_ref(const std::string& string) | ||||||
|  | 	{ | ||||||
|  | 		char bytes[4] = {0}; | ||||||
|  | 		const auto string_ptr = find_string_ptr(string); | ||||||
|  | 		if (!string_ptr) | ||||||
|  | 		{ | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		std::memcpy(bytes, &string_ptr, sizeof(bytes)); | ||||||
|  | 		return find_string_ptr({bytes, 4}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool process_gsc_ctx() | ||||||
|  | 	{ | ||||||
|  | 		const auto string_ref = find_string_ref("in call to builtin %s \"%s\""); | ||||||
|  | 		if (!string_ref) | ||||||
|  | 		{ | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		const auto gsc_ctx_ptr = *reinterpret_cast<size_t*>(string_ref - 0xAD); | ||||||
|  | 		OutputDebugString(utils::string::va("gsc_ctx_ptr: %p\n", gsc_ctx_ptr)); | ||||||
|  | 		game::plutonium::gsc_ctx.set(gsc_ctx_ptr); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool process_printf() | ||||||
|  | 	{ | ||||||
|  | 		const auto string_ref = find_string_ref("A critical exception occured!\n"); | ||||||
|  | 		if (!string_ref) | ||||||
|  | 		{ | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const auto offset = *reinterpret_cast<size_t*>(string_ref + 5); | ||||||
|  | 		const auto printf_ptr = string_ref + 4 + 5 + offset; | ||||||
|  | 		OutputDebugString(utils::string::va("printf_ptr: %p\n", printf_ptr)); | ||||||
|  | 		game::plutonium::printf.set(printf_ptr); | ||||||
|  |  | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool process() | ||||||
|  | 	{ | ||||||
|  | 		load_function_tables(); | ||||||
|  | 		return process_printf() && process_gsc_ctx(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								src/component/signatures.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/component/signatures.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace signatures | ||||||
|  | { | ||||||
|  | 	bool process(); | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								src/component/string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/component/string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | #include <stdinc.hpp> | ||||||
|  | #include "loader/component_loader.hpp" | ||||||
|  |  | ||||||
|  | #include "gsc.hpp" | ||||||
|  |  | ||||||
|  | #include <utils/string.hpp> | ||||||
|  |  | ||||||
|  | namespace string | ||||||
|  | { | ||||||
|  | 	class component final : public component_interface | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		void post_unpack() override | ||||||
|  | 		{ | ||||||
|  | 			gsc::function::add("toupper", [](const gsc::function_args& args) | ||||||
|  | 			{ | ||||||
|  | 				return utils::string::to_upper(args[0].as<std::string>()); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			gsc::function::add("getchar", [](const gsc::function_args& args) | ||||||
|  | 			{ | ||||||
|  | 				auto index = 0; | ||||||
|  | 				if (args.size() > 1) | ||||||
|  | 				{ | ||||||
|  | 					index = args[1].as<int>(); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto string = args[0].as<std::string>(); | ||||||
|  | 				if (index >= static_cast<int>(string.size())) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Char index out of bounds"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				return static_cast<int>(string[index]); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			gsc::function::add("chartostring", [](const gsc::function_args& args) | ||||||
|  | 			{ | ||||||
|  | 				const auto char_ = static_cast<char>(args[0].as<int>()); | ||||||
|  | 				return std::string(1, char_); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | REGISTER_COMPONENT(string::component) | ||||||
| @@ -13,12 +13,17 @@ namespace userinfo | |||||||
| 	{ | 	{ | ||||||
| 		utils::hook::detour sv_getuserinfo_hook; | 		utils::hook::detour sv_getuserinfo_hook; | ||||||
|  |  | ||||||
| 		userinfo_map userinfo_to_map(const std::string& userinfo) | 		userinfo_map userinfo_to_map(std::string userinfo) | ||||||
| 		{ | 		{ | ||||||
| 			userinfo_map map; | 			userinfo_map map{}; | ||||||
| 			const auto args = utils::string::split(userinfo, '\\'); |  | ||||||
|  |  | ||||||
| 			for (auto i = 1; i < args.size() - 1; i += 2) | 			if (userinfo[0] == '\\') | ||||||
|  | 			{ | ||||||
|  | 				userinfo = userinfo.substr(1); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			const auto args = utils::string::split(userinfo, '\\'); | ||||||
|  | 			for (size_t i = 0; !args.empty() && i < (args.size() - 1); i += 2) | ||||||
| 			{ | 			{ | ||||||
| 				map[args[i]] = args[i + 1]; | 				map[args[i]] = args[i + 1]; | ||||||
| 			} | 			} | ||||||
| @@ -28,7 +33,7 @@ namespace userinfo | |||||||
|  |  | ||||||
| 		std::string map_to_userinfo(const userinfo_map& map) | 		std::string map_to_userinfo(const userinfo_map& map) | ||||||
| 		{ | 		{ | ||||||
| 			std::string buffer; | 			std::string buffer{}; | ||||||
|  |  | ||||||
| 			for (const auto& value : map) | 			for (const auto& value : map) | ||||||
| 			{ | 			{ | ||||||
| @@ -43,9 +48,8 @@ namespace userinfo | |||||||
|  |  | ||||||
| 		void sv_getuserinfo_stub(int index, char* buffer, int bufferSize) | 		void sv_getuserinfo_stub(int index, char* buffer, int bufferSize) | ||||||
| 		{ | 		{ | ||||||
| 			char _buffer[1024]; | 			sv_getuserinfo_hook.invoke<void>(index, buffer, bufferSize); | ||||||
| 			sv_getuserinfo_hook.invoke<void>(index, _buffer, 1024); | 			auto map = userinfo_to_map(buffer); | ||||||
| 			auto map = userinfo_to_map(_buffer); |  | ||||||
|  |  | ||||||
| 			if (userinfo_overrides.find(index) == userinfo_overrides.end()) | 			if (userinfo_overrides.find(index) == userinfo_overrides.end()) | ||||||
| 			{ | 			{ | ||||||
| @@ -88,26 +92,36 @@ namespace userinfo | |||||||
|  |  | ||||||
| 			gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | 			gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				const auto name = args[0].as<std::string>(); | 				if (ent.classnum != 0) | ||||||
|  |  | ||||||
| 				if (ent.classnum != 0 || ent.entnum > 17) |  | ||||||
| 				{ | 				{ | ||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[ent.entnum].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto name = args[0].as<std::string>(); | ||||||
|  |  | ||||||
| 				userinfo_overrides[ent.entnum]["name"] = name; | 				userinfo_overrides[ent.entnum]["name"] = name; | ||||||
| 				game::ClientUserinfoChanged(ent.entnum); | 				game::ClientUserinfoChanged(ent.entnum); | ||||||
|  |  | ||||||
| 				return {}; | 				return {}; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | 			gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args&) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				if (ent.classnum != 0 || ent.entnum > 17) | 				if (ent.classnum != 0) | ||||||
| 				{ | 				{ | ||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[ent.entnum].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				userinfo_overrides[ent.entnum].erase("name"); | 				userinfo_overrides[ent.entnum].erase("name"); | ||||||
| 				game::ClientUserinfoChanged(ent.entnum); | 				game::ClientUserinfoChanged(ent.entnum); | ||||||
|  |  | ||||||
| @@ -116,13 +130,18 @@ namespace userinfo | |||||||
|  |  | ||||||
| 			gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | 			gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				const auto name = args[0].as<std::string>(); | 				if (ent.classnum != 0) | ||||||
|  |  | ||||||
| 				if (ent.classnum != 0 || ent.entnum > 17) |  | ||||||
| 				{ | 				{ | ||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[ent.entnum].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				const auto name = args[0].as<std::string>(); | ||||||
|  |  | ||||||
| 				userinfo_overrides[ent.entnum]["clantag"] = name; | 				userinfo_overrides[ent.entnum]["clantag"] = name; | ||||||
| 				userinfo_overrides[ent.entnum]["ec_TagText"] = name; | 				userinfo_overrides[ent.entnum]["ec_TagText"] = name; | ||||||
| 				userinfo_overrides[ent.entnum]["ec_usingTag"] = "1"; | 				userinfo_overrides[ent.entnum]["ec_usingTag"] = "1"; | ||||||
| @@ -131,13 +150,18 @@ namespace userinfo | |||||||
| 				return {}; | 				return {}; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | 			gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args&) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				if (ent.classnum != 0 || ent.entnum > 17) | 				if (ent.classnum != 0) | ||||||
| 				{ | 				{ | ||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[ent.entnum].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				userinfo_overrides[ent.entnum].erase("clantag"); | 				userinfo_overrides[ent.entnum].erase("clantag"); | ||||||
| 				userinfo_overrides[ent.entnum].erase("ec_TagText"); | 				userinfo_overrides[ent.entnum].erase("ec_TagText"); | ||||||
| 				userinfo_overrides[ent.entnum].erase("ec_usingTag"); | 				userinfo_overrides[ent.entnum].erase("ec_usingTag"); | ||||||
| @@ -146,13 +170,18 @@ namespace userinfo | |||||||
| 				return {}; | 				return {}; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value | 			gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args&) -> scripting::script_value | ||||||
| 			{ | 			{ | ||||||
| 				if (ent.classnum != 0 || ent.entnum > 17) | 				if (ent.classnum != 0) | ||||||
| 				{ | 				{ | ||||||
| 					throw std::runtime_error("Invalid entity"); | 					throw std::runtime_error("Invalid entity"); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (game::g_entities[ent.entnum].client == nullptr) | ||||||
|  | 				{ | ||||||
|  | 					throw std::runtime_error("Not a player entity"); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				userinfo_overrides[ent.entnum]["clantag"] = ""; | 				userinfo_overrides[ent.entnum]["clantag"] = ""; | ||||||
| 				userinfo_overrides[ent.entnum]["ec_TagText"] = ""; | 				userinfo_overrides[ent.entnum]["ec_TagText"] = ""; | ||||||
| 				userinfo_overrides[ent.entnum]["ec_usingTag"] = "0"; | 				userinfo_overrides[ent.entnum]["ec_usingTag"] = "0"; | ||||||
|   | |||||||
| @@ -1,22 +1,27 @@ | |||||||
| #include <stdinc.hpp> | #include <stdinc.hpp> | ||||||
| #include "loader/component_loader.hpp" | #include "loader/component_loader.hpp" | ||||||
|  |  | ||||||
| BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) | #include "component/signatures.hpp" | ||||||
|  |  | ||||||
|  | BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) | ||||||
| { | { | ||||||
|     if (ul_reason_for_call == DLL_PROCESS_ATTACH) |     if (ul_reason_for_call == DLL_PROCESS_ATTACH) | ||||||
|     { |     { | ||||||
|         const auto value = *reinterpret_cast<DWORD*>(0x20900000); |         if (!signatures::process()) | ||||||
|         if (value != 0xF0681B6A) |  | ||||||
|         { |         { | ||||||
|             MessageBoxA(NULL, |             MessageBoxA(NULL, | ||||||
|                 "This version of iw5-gsc-utils is outdated.\n" \ |                 "This version of iw5-gsc-utils is outdated.\n" \ | ||||||
|                 "Download the latest dll from here: https://github.com/fedddddd/iw5-gsc-utils/releases" \ |                 "Download the latest dll from here: https://github.com/fedddddd/iw5-gsc-utils/releases", | ||||||
|             , "ERROR", MB_ICONERROR); |                 "ERROR", MB_ICONERROR); | ||||||
|  |  | ||||||
|             return FALSE; |             return FALSE; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (game::plutonium::printf.get() != nullptr) | ||||||
|  |         { | ||||||
|             utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf); |             utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         component_loader::post_unpack(); |         component_loader::post_unpack(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,5 +2,11 @@ | |||||||
|  |  | ||||||
| namespace game | namespace game | ||||||
| { | { | ||||||
|  | 	void SV_GameDropClient(int clientNum, const char* reason) | ||||||
|  | 	{ | ||||||
|  | 		if (clientNum >= 0 && clientNum < sv_maxclients->current.integer) | ||||||
|  | 		{ | ||||||
|  | 			SV_DropClient(&svs_clients[clientNum], reason, true); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,6 +16,11 @@ namespace game | |||||||
| 			return dedi_; | 			return dedi_; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		void set(const size_t dedi) | ||||||
|  | 		{ | ||||||
|  | 			this->dedi_ = reinterpret_cast<T*>(dedi); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		operator T* () const | 		operator T* () const | ||||||
| 		{ | 		{ | ||||||
| 			return this->get(); | 			return this->get(); | ||||||
| @@ -29,6 +34,8 @@ namespace game | |||||||
| 	private: | 	private: | ||||||
| 		T* dedi_; | 		T* dedi_; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	void SV_GameDropClient(int clientNum, const char* reason); | ||||||
| } | } | ||||||
|  |  | ||||||
| #include "symbols.hpp" | #include "symbols.hpp" | ||||||
| @@ -60,13 +60,11 @@ namespace scripting | |||||||
| 	array::array() | 	array::array() | ||||||
| 	{ | 	{ | ||||||
| 		this->id_ = make_array(); | 		this->id_ = make_array(); | ||||||
| 		this->add(); |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	array::array(std::vector<script_value> values) | 	array::array(std::vector<script_value> values) | ||||||
| 	{ | 	{ | ||||||
| 		this->id_ = make_array(); | 		this->id_ = make_array(); | ||||||
| 		this->add(); |  | ||||||
|  |  | ||||||
| 		for (const auto& value : values) | 		for (const auto& value : values) | ||||||
| 		{ | 		{ | ||||||
| @@ -77,7 +75,6 @@ namespace scripting | |||||||
| 	array::array(std::unordered_map<std::string, script_value> values) | 	array::array(std::unordered_map<std::string, script_value> values) | ||||||
| 	{ | 	{ | ||||||
| 		this->id_ = make_array(); | 		this->id_ = make_array(); | ||||||
| 		this->add(); |  | ||||||
|  |  | ||||||
| 		for (const auto& value : values) | 		for (const auto& value : values) | ||||||
| 		{ | 		{ | ||||||
| @@ -266,11 +263,9 @@ namespace scripting | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void array::set(const std::string& key, const script_value& _value) const | 	void array::set(const std::string& key, const script_value& value_) const | ||||||
| 	{ | 	{ | ||||||
| 		const auto value = _value.get_raw(); | 		const auto value = value_.get_raw(); | ||||||
|  |  | ||||||
| 		const auto string_value = game::SL_GetString(key.data(), 0); |  | ||||||
| 		const auto variable_id = this->get_value_id(key); | 		const auto variable_id = this->get_value_id(key); | ||||||
|  |  | ||||||
| 		if (!variable_id) | 		if (!variable_id) | ||||||
| @@ -287,9 +282,9 @@ namespace scripting | |||||||
| 		variable->u.u = value.u; | 		variable->u.u = value.u; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void array::set(const unsigned int index, const script_value& _value) const | 	void array::set(const unsigned int index, const script_value& value_) const | ||||||
| 	{ | 	{ | ||||||
| 		const auto value = _value.get_raw(); | 		const auto value = value_.get_raw(); | ||||||
| 		const auto variable_id = this->get_value_id(index); | 		const auto variable_id = this->get_value_id(index); | ||||||
|  |  | ||||||
| 		if (!variable_id) | 		if (!variable_id) | ||||||
|   | |||||||
| @@ -269,8 +269,6 @@ namespace scripting | |||||||
| 		{ | 		{ | ||||||
| 			return get_custom_field(entity, field); | 			return get_custom_field(entity, field); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return {}; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	unsigned int make_array() | 	unsigned int make_array() | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -7,51 +7,20 @@ namespace scripting | |||||||
| { | { | ||||||
| 	namespace | 	namespace | ||||||
| 	{ | 	{ | ||||||
| 		std::unordered_map<std::string, unsigned> lowercase_map( | 		int find_function_index(const std::string& name, [[maybe_unused]] const bool prefer_global) | ||||||
| 			const std::unordered_map<std::string, unsigned>& old_map) |  | ||||||
| 		{ |  | ||||||
| 			std::unordered_map<std::string, unsigned> new_map{}; |  | ||||||
| 			for (auto& entry : old_map) |  | ||||||
| 			{ |  | ||||||
| 				new_map[utils::string::to_lower(entry.first)] = entry.second; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return new_map; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		const std::unordered_map<std::string, unsigned>& get_methods() |  | ||||||
| 		{ |  | ||||||
| 			static auto methods = lowercase_map(method_map); |  | ||||||
| 			return methods; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		const std::unordered_map<std::string, unsigned>& get_functions() |  | ||||||
| 		{ |  | ||||||
| 			static auto function = lowercase_map(function_map); |  | ||||||
| 			return function; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		int find_function_index(const std::string& name, const bool prefer_global) |  | ||||||
| 		{ | 		{ | ||||||
| 			const auto target = utils::string::to_lower(name); | 			const auto target = utils::string::to_lower(name); | ||||||
|  | 			auto const& first = (*game::plutonium::gsc_ctx)->func_map(); | ||||||
|  | 			auto const& second = (*game::plutonium::gsc_ctx)->meth_map(); | ||||||
|  |  | ||||||
| 			const auto& primary_map = prefer_global | 			if (const auto itr = first.find(name); itr != first.end()) | ||||||
| 				                          ? get_functions() |  | ||||||
| 				                          : get_methods(); |  | ||||||
| 			const auto& secondary_map = !prefer_global |  | ||||||
| 				                            ? get_functions() |  | ||||||
| 				                            : get_methods(); |  | ||||||
|  |  | ||||||
| 			auto function_entry = primary_map.find(target); |  | ||||||
| 			if (function_entry != primary_map.end()) |  | ||||||
| 			{ | 			{ | ||||||
| 				return function_entry->second; | 				return static_cast<int>(itr->second); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			function_entry = secondary_map.find(target); | 			if (const auto itr = second.find(name); itr != second.end()) | ||||||
| 			if (function_entry != secondary_map.end()) |  | ||||||
| 			{ | 			{ | ||||||
| 				return function_entry->second; | 				return static_cast<int>(itr->second); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			return -1; | 			return -1; | ||||||
| @@ -73,33 +42,26 @@ namespace scripting | |||||||
|  |  | ||||||
| 	std::string find_token(unsigned int id) | 	std::string find_token(unsigned int id) | ||||||
| 	{ | 	{ | ||||||
| 		for (const auto& token : token_map) | 		return (*game::plutonium::gsc_ctx)->token_name(id); | ||||||
| 		{ |  | ||||||
| 			if (token.second == id) |  | ||||||
| 			{ |  | ||||||
| 				return token.first; |  | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 		return {}; | 	std::string find_file(unsigned int id) | ||||||
|  | 	{ | ||||||
|  | 		return find_token(id); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	int find_token_id(const std::string& name) | 	int find_token_id(const std::string& name) | ||||||
| 	{ | 	{ | ||||||
| 		const auto result = token_map.find(name); | 		return (*game::plutonium::gsc_ctx)->token_id(name); | ||||||
|  |  | ||||||
| 		if (result != token_map.end()) |  | ||||||
| 		{ |  | ||||||
| 			return result->second; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return -1; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	script_function find_function(const std::string& name, const bool prefer_global) | 	script_function find_function(const std::string& name, const bool prefer_global) | ||||||
| 	{ | 	{ | ||||||
| 		const auto index = find_function_index(name, prefer_global); | 		const auto index = find_function_index(name, prefer_global); | ||||||
| 		if (index < 0) return nullptr; | 		if (index < 0) | ||||||
|  | 		{ | ||||||
|  | 			return nullptr; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		return get_function_by_index(index); | 		return get_function_by_index(index); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -3,14 +3,10 @@ | |||||||
|  |  | ||||||
| namespace scripting | namespace scripting | ||||||
| { | { | ||||||
| 	extern std::unordered_map<std::string, unsigned> method_map; |  | ||||||
| 	extern std::unordered_map<std::string, unsigned> function_map; |  | ||||||
| 	extern std::unordered_map<std::string, unsigned> token_map; |  | ||||||
| 	extern std::unordered_map<unsigned, std::string> file_list; |  | ||||||
|  |  | ||||||
| 	using script_function = void(*)(game::scr_entref_t); | 	using script_function = void(*)(game::scr_entref_t); | ||||||
|  |  | ||||||
| 	script_function find_function(const std::string& name, const bool prefer_global); | 	script_function find_function(const std::string& name, const bool prefer_global); | ||||||
| 	int find_token_id(const std::string& name); | 	int find_token_id(const std::string& name); | ||||||
| 	std::string find_token(unsigned int id); | 	std::string find_token(unsigned int id); | ||||||
|  | 	std::string find_file(unsigned int id); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,20 +26,35 @@ namespace game | |||||||
| 		const char** argv[8]; | 		const char** argv[8]; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	enum netsrc_t | ||||||
|  | 	{ | ||||||
|  | 		NS_CLIENT1 = 0x0, | ||||||
|  | 		NS_CLIENT2 = 0x1, | ||||||
|  | 		NS_CLIENT3 = 0x2, | ||||||
|  | 		NS_CLIENT4 = 0x3, | ||||||
|  | 		NS_MAXCLIENTS = 0x4, | ||||||
|  | 		NS_SERVER = 0x4, | ||||||
|  | 		NS_PACKET = 0x5, | ||||||
|  | 		NS_INVALID_NETSRC = 0x6 | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	struct msg_t | 	struct msg_t | ||||||
| 	{ | 	{ | ||||||
| 		int overflowed; | 		int overflowed; | ||||||
| 		int readOnly; | 		int readOnly; | ||||||
| 		char* data; | 		unsigned char* data; | ||||||
| 		char* splitData; | 		unsigned char* splitData; | ||||||
| 		int maxsize; | 		int maxsize; | ||||||
| 		int cursize; | 		int cursize; | ||||||
| 		int splitSize; | 		int splitSize; | ||||||
| 		int readcount; | 		int readcount; | ||||||
| 		int bit; | 		int bit; | ||||||
| 		int lastEntityRef; | 		int lastEntityRef; | ||||||
|  | 		netsrc_t targetLocalNetID; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert(sizeof(msg_t) == 0x2C); | ||||||
|  |  | ||||||
| 	struct XZoneInfo | 	struct XZoneInfo | ||||||
| 	{ | 	{ | ||||||
| 		const char* name; | 		const char* name; | ||||||
| @@ -327,4 +342,88 @@ namespace game | |||||||
| 		int flags; | 		int flags; | ||||||
| 		char __pad2[0xEC]; | 		char __pad2[0xEC]; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	enum netadrtype_t | ||||||
|  | 	{ | ||||||
|  | 		NA_BOT = 0x0, | ||||||
|  | 		NA_BAD = 0x1, | ||||||
|  | 		NA_LOOPBACK = 0x2, | ||||||
|  | 		NA_BROADCAST = 0x3, | ||||||
|  | 		NA_IP = 0x4 | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct netadr_s | ||||||
|  | 	{ | ||||||
|  | 		netadrtype_t type; | ||||||
|  | 		unsigned char ip[4]; | ||||||
|  | 		unsigned __int16 port; | ||||||
|  | 		unsigned char ipx[10]; | ||||||
|  | 		unsigned int addrHandleIndex; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert(sizeof(netadr_s) == 24); | ||||||
|  |  | ||||||
|  | 	struct netchan_t | ||||||
|  | 	{ | ||||||
|  | 		int outgoingSequence; | ||||||
|  | 		netsrc_t sock; | ||||||
|  | 		int dropped; | ||||||
|  | 		int incomingSequence; | ||||||
|  | 		netadr_s remoteAddress; | ||||||
|  | 		int qport; | ||||||
|  | 		int fragmentSequence; | ||||||
|  | 		int fragmentLength; | ||||||
|  | 		unsigned char* fragmentBuffer; | ||||||
|  | 		int fragmentBufferSize; | ||||||
|  | 		int unsentFragments; | ||||||
|  | 		int unsentFragmentStart; | ||||||
|  | 		int unsentLength; | ||||||
|  | 		unsigned char* unsentBuffer; | ||||||
|  | 		int unsentBufferSize; | ||||||
|  | 		unsigned char __pad0[0x5E0]; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert(sizeof(netchan_t) == 0x630); | ||||||
|  |  | ||||||
|  | 	enum clientState_t | ||||||
|  | 	{ | ||||||
|  | 		CS_FREE = 0, | ||||||
|  | 		CS_ZOMBIE = 1, | ||||||
|  | 		CS_RECONNECTING = 2, | ||||||
|  | 		CS_CONNECTED = 3, | ||||||
|  | 		CS_CLIENTLOADING = 4, | ||||||
|  | 		CS_ACTIVE = 5 | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct clientHeader_t | ||||||
|  | 	{ | ||||||
|  | 		clientState_t state; // 0 | ||||||
|  | 		int sendAsActive; // 4 | ||||||
|  | 		int deltaMessage; // 8 | ||||||
|  | 		int rateDealyed; // 12 | ||||||
|  | 		int hasAckedBaselineData; // 16 | ||||||
|  | 		int hugeSnapshotSent; // 20 | ||||||
|  | 		netchan_t netchan; // 24 | ||||||
|  | 		vec3_t predictedOrigin; | ||||||
|  | 		int predictedOriginServerTime; | ||||||
|  | 		int migrationState; | ||||||
|  | 		vec3_t predictedVehicleOrigin; | ||||||
|  | 		int predictedVehicleServerTime; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert(sizeof(clientHeader_t) == 0x66C); | ||||||
|  |  | ||||||
|  | 	struct client_s | ||||||
|  | 	{ | ||||||
|  | 		clientHeader_t header; | ||||||
|  | 		const char* dropReason; | ||||||
|  | 		char userinfo[1024]; | ||||||
|  | 		char __pad0[0x41242]; | ||||||
|  | 		unsigned __int16 scriptId; // 269490 | ||||||
|  | 		int bIsTestClient; // 269492 | ||||||
|  | 		int serverId; // 269496 | ||||||
|  | 		char __pad1[0x369DC]; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert(sizeof(client_s) == 0x78698); | ||||||
| } | } | ||||||
| @@ -57,6 +57,7 @@ namespace game | |||||||
|  |  | ||||||
| 	WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x573220}; | 	WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x573220}; | ||||||
| 	WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x5459F0}; | 	WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x5459F0}; | ||||||
|  | 	WEAK symbol<void(client_s* drop, const char* reason, bool tellThem)> SV_DropClient{0x570980}; | ||||||
|  |  | ||||||
| 	WEAK symbol<void(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top)> VM_Notify{0x569720}; | 	WEAK symbol<void(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top)> VM_Notify{0x569720}; | ||||||
| 	WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0}; | 	WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0}; | ||||||
| @@ -79,13 +80,15 @@ namespace game | |||||||
| 	WEAK symbol<gentity_s> g_entities{0x1A66E28}; | 	WEAK symbol<gentity_s> g_entities{0x1A66E28}; | ||||||
| 	WEAK symbol<unsigned int> levelEntityId{0x208E1A4}; | 	WEAK symbol<unsigned int> levelEntityId{0x208E1A4}; | ||||||
|  |  | ||||||
|  | 	WEAK symbol<dvar_t> sv_maxclients{0x1BA0E4C}; | ||||||
|  | 	WEAK symbol<int> svs_clientCount{0x4B5CF8C}; | ||||||
|  | 	WEAK symbol<client_s> svs_clients{0x4B5CF90}; | ||||||
|  |  | ||||||
| 	namespace plutonium | 	namespace plutonium | ||||||
| 	{ | 	{ | ||||||
| 		WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x20693038}; | 		WEAK symbol<std::unique_ptr<xsk::gsc::iw5_pc::context>> gsc_ctx{0}; | ||||||
| 		WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x20693058}; | 		WEAK symbol<int(const char* fmt, ...)> printf{0}; | ||||||
| 		WEAK symbol<std::unordered_map<std::string, std::uint16_t>> token_map_rev{0x20693098}; | 		WEAK symbol<void*> function_table{0}; | ||||||
| 		WEAK symbol<int(const char* fmt, ...)> printf{0x208879B0}; | 		WEAK symbol<void*> method_table{0}; | ||||||
| 		WEAK symbol<void*> function_table{0x2068BCF0}; |  | ||||||
| 		WEAK symbol<void*> method_table{0x2068C4C0}; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -8,6 +8,8 @@ | |||||||
| #pragma warning(disable: 4996) | #pragma warning(disable: 4996) | ||||||
| #pragma warning(disable: 26812) | #pragma warning(disable: 26812) | ||||||
|  |  | ||||||
|  | #include <xsk/gsc/engine/iw5_pc.hpp> | ||||||
|  |  | ||||||
| #define DLL_EXPORT extern "C" __declspec(dllexport) | #define DLL_EXPORT extern "C" __declspec(dllexport) | ||||||
| #define WIN32_LEAN_AND_MEAN | #define WIN32_LEAN_AND_MEAN | ||||||
| #include <windows.h> | #include <windows.h> | ||||||
| @@ -28,6 +30,7 @@ | |||||||
| #include <map> | #include <map> | ||||||
| #include <csetjmp> | #include <csetjmp> | ||||||
| #include <atlcomcli.h> | #include <atlcomcli.h> | ||||||
|  | #include <Psapi.h> | ||||||
|  |  | ||||||
| #pragma comment(lib, "urlmon.lib") | #pragma comment(lib, "urlmon.lib") | ||||||
|  |  | ||||||
| @@ -36,6 +39,7 @@ using namespace std::literals; | |||||||
| #include <gsl/gsl> | #include <gsl/gsl> | ||||||
| #include <MinHook.h> | #include <MinHook.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "utils/memory.hpp" | #include "utils/memory.hpp" | ||||||
| #include "utils/string.hpp" | #include "utils/string.hpp" | ||||||
| #include "utils/hook.hpp" | #include "utils/hook.hpp" | ||||||
|   | |||||||
| @@ -4,6 +4,48 @@ | |||||||
|  |  | ||||||
| namespace utils::hook | namespace utils::hook | ||||||
| { | { | ||||||
|  | 	// open-iw5 | ||||||
|  |  | ||||||
|  | 	void signature::process() | ||||||
|  | 	{ | ||||||
|  | 		if (this->signatures_.empty()) return; | ||||||
|  |  | ||||||
|  | 		const auto start = static_cast<char*>(this->start_); | ||||||
|  |  | ||||||
|  | 		const unsigned int sig_count = this->signatures_.size(); | ||||||
|  | 		const auto containers = this->signatures_.data(); | ||||||
|  |  | ||||||
|  | 		for (size_t i = 0; i < this->length_; ++i) | ||||||
|  | 		{ | ||||||
|  | 			const auto address = start + i; | ||||||
|  |  | ||||||
|  | 			for (unsigned int k = 0; k < sig_count; ++k) | ||||||
|  | 			{ | ||||||
|  | 				const auto container = &containers[k]; | ||||||
|  |  | ||||||
|  | 				unsigned int j; | ||||||
|  | 				for (j = 0; j < static_cast<unsigned int>(container->mask.size()); ++j) | ||||||
|  | 				{ | ||||||
|  | 					if (container->mask[j] != '?' && container->signature[j] != address[j]) | ||||||
|  | 					{ | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if (j == container->mask.size()) | ||||||
|  | 				{ | ||||||
|  | 					container->callback(address); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void signature::add(const container& container) | ||||||
|  | 	{ | ||||||
|  | 		signatures_.push_back(container); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	namespace | 	namespace | ||||||
| 	{ | 	{ | ||||||
| 		[[maybe_unused]] class _ | 		[[maybe_unused]] class _ | ||||||
|   | |||||||
| @@ -4,6 +4,37 @@ | |||||||
|  |  | ||||||
| namespace utils::hook | namespace utils::hook | ||||||
| { | { | ||||||
|  | 	class signature final | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		struct container final | ||||||
|  | 		{ | ||||||
|  | 			std::string signature; | ||||||
|  | 			std::string mask; | ||||||
|  | 			std::function<void(char*)> callback; | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		signature(void* start, const size_t length) : start_(start), length_(length) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		signature(const DWORD start, const size_t length) : signature(reinterpret_cast<void*>(start), length) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		signature() : signature(0x400000, 0x800000) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		void process(); | ||||||
|  | 		void add(const container& container); | ||||||
|  |  | ||||||
|  | 	private: | ||||||
|  | 		void* start_; | ||||||
|  | 		size_t length_; | ||||||
|  | 		std::vector<container> signatures_; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	class detour | 	class detour | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
|   | |||||||
| @@ -1,8 +1,14 @@ | |||||||
| #include <stdinc.hpp> | #include <stdinc.hpp> | ||||||
| #include <fstream> | #include <fstream> | ||||||
|  | #include "io.hpp" | ||||||
|  |  | ||||||
| namespace utils::io | namespace utils::io | ||||||
| { | { | ||||||
|  | 	bool remove_file(const std::string& file) | ||||||
|  | 	{ | ||||||
|  | 		return DeleteFileA(file.data()) == TRUE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	bool file_exists(const std::string& file) | 	bool file_exists(const std::string& file) | ||||||
| 	{ | 	{ | ||||||
| 		return std::ifstream(file).good(); | 		return std::ifstream(file).good(); | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| namespace utils::io | namespace utils::io | ||||||
| { | { | ||||||
|  | 	bool remove_file(const std::string& file); | ||||||
| 	bool file_exists(const std::string& file); | 	bool file_exists(const std::string& file); | ||||||
| 	bool write_file(const std::string& file, const std::string& data, bool append = false); | 	bool write_file(const std::string& file, const std::string& data, bool append = false); | ||||||
| 	bool read_file(const std::string& file, std::string* data); | 	bool read_file(const std::string& file, std::string* data); | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								tools/premake5.exe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tools/premake5.exe
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user