link errors
This commit is contained in:
parent
40370e266b
commit
6f95b55aa4
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -37,3 +37,7 @@
|
|||||||
[submodule "deps/minhook"]
|
[submodule "deps/minhook"]
|
||||||
path = deps/minhook
|
path = deps/minhook
|
||||||
url = https://github.com/TsudaKageyu/minhook.git
|
url = https://github.com/TsudaKageyu/minhook.git
|
||||||
|
[submodule "deps/gsc-tool"]
|
||||||
|
path = deps/gsc-tool
|
||||||
|
url = https://github.com/xensik/gsc-tool.git
|
||||||
|
branch = xlabs
|
||||||
|
28
deps/extra/gsc-tool/interface.cpp
vendored
Normal file
28
deps/extra/gsc-tool/interface.cpp
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdafx.hpp>
|
||||||
|
#include <xsk/iw5.hpp>
|
||||||
|
#include "interface.hpp"
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
std::unique_ptr<xsk::gsc::compiler> compiler()
|
||||||
|
{
|
||||||
|
auto compiler = std::make_unique<xsk::gsc::iw5::compiler>();
|
||||||
|
compiler->mode(xsk::gsc::build::prod);
|
||||||
|
return compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::decompiler> decompiler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::iw5::decompiler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::assembler> assembler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::iw5::assembler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::disassembler> disassembler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::iw5::disassembler>();
|
||||||
|
}
|
||||||
|
}
|
9
deps/extra/gsc-tool/interface.hpp
vendored
Normal file
9
deps/extra/gsc-tool/interface.hpp
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
std::unique_ptr<xsk::gsc::compiler> compiler();
|
||||||
|
std::unique_ptr<xsk::gsc::decompiler> decompiler();
|
||||||
|
std::unique_ptr<xsk::gsc::assembler> assembler();
|
||||||
|
std::unique_ptr<xsk::gsc::disassembler> disassembler();
|
||||||
|
}
|
1
deps/gsc-tool
vendored
Submodule
1
deps/gsc-tool
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 7d374025b7675bada64c247ebe9378dd335a33da
|
65
deps/premake/gsc-tool.lua
vendored
Normal file
65
deps/premake/gsc-tool.lua
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
gsc_tool = {
|
||||||
|
source = path.join(dependencies.basePath, "gsc-tool/src"),
|
||||||
|
}
|
||||||
|
|
||||||
|
function gsc_tool.import()
|
||||||
|
links { "xsk-gsc-iw5", "xsk-gsc-utils" }
|
||||||
|
gsc_tool.includes()
|
||||||
|
end
|
||||||
|
|
||||||
|
function gsc_tool.includes()
|
||||||
|
includedirs {
|
||||||
|
path.join(gsc_tool.source, "iw5"),
|
||||||
|
path.join(gsc_tool.source, "utils"),
|
||||||
|
path.join(dependencies.basePath, "extra/gsc-tool"),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function gsc_tool.project()
|
||||||
|
project "xsk-gsc-utils"
|
||||||
|
kind "StaticLib"
|
||||||
|
language "C++"
|
||||||
|
|
||||||
|
pchheader "stdafx.hpp"
|
||||||
|
pchsource (path.join(gsc_tool.source, "utils/stdafx.cpp"))
|
||||||
|
|
||||||
|
files {
|
||||||
|
path.join(gsc_tool.source, "utils/**.hpp"),
|
||||||
|
path.join(gsc_tool.source, "utils/**.cpp"),
|
||||||
|
}
|
||||||
|
|
||||||
|
includedirs {
|
||||||
|
path.join(gsc_tool.source, "utils"),
|
||||||
|
gsc_tool.source,
|
||||||
|
}
|
||||||
|
|
||||||
|
zlib.includes()
|
||||||
|
|
||||||
|
project "xsk-gsc-iw5"
|
||||||
|
kind "StaticLib"
|
||||||
|
|
||||||
|
language "C++"
|
||||||
|
cppdialect "C++20"
|
||||||
|
|
||||||
|
filter "toolset:msc*"
|
||||||
|
buildoptions "/bigobj"
|
||||||
|
buildoptions "/Zc:__cplusplus"
|
||||||
|
filter {}
|
||||||
|
|
||||||
|
pchheader "stdafx.hpp"
|
||||||
|
pchsource (path.join(gsc_tool.source, "iw5/stdafx.cpp"))
|
||||||
|
|
||||||
|
files {
|
||||||
|
path.join(gsc_tool.source, "iw5/**.hpp"),
|
||||||
|
path.join(gsc_tool.source, "iw5/**.cpp"),
|
||||||
|
path.join(dependencies.basePath, "extra/gsc-tool/interface.cpp"),
|
||||||
|
}
|
||||||
|
|
||||||
|
includedirs {
|
||||||
|
path.join(gsc_tool.source, "iw5"),
|
||||||
|
gsc_tool.source,
|
||||||
|
path.join(dependencies.basePath, "extra/gsc-tool"),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(dependencies, gsc_tool)
|
@ -12,6 +12,7 @@ namespace game
|
|||||||
Com_Filter_t Com_Filter;
|
Com_Filter_t Com_Filter;
|
||||||
|
|
||||||
DB_LoadXAssets_t DB_LoadXAssets;
|
DB_LoadXAssets_t DB_LoadXAssets;
|
||||||
|
DB_FindXAssetHeader_t DB_FindXAssetHeader;
|
||||||
|
|
||||||
Dvar_RegisterBool_t Dvar_RegisterBool;
|
Dvar_RegisterBool_t Dvar_RegisterBool;
|
||||||
Dvar_RegisterString_t Dvar_RegisterString;
|
Dvar_RegisterString_t Dvar_RegisterString;
|
||||||
@ -92,9 +93,6 @@ namespace game
|
|||||||
scrVarPub_t* scr_VarPub;
|
scrVarPub_t* scr_VarPub;
|
||||||
scrVmPub_t* scr_VmPub;
|
scrVmPub_t* scr_VmPub;
|
||||||
|
|
||||||
scr_call_t* scr_instanceFunctions;
|
|
||||||
scr_call_t* scr_globalFunctions;
|
|
||||||
|
|
||||||
unsigned int* levelEntityId;
|
unsigned int* levelEntityId;
|
||||||
|
|
||||||
int* g_script_error_level;
|
int* g_script_error_level;
|
||||||
@ -412,16 +410,6 @@ namespace game
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
scr_call_t Scr_GetFunc(const unsigned int index)
|
|
||||||
{
|
|
||||||
if (index > 0x1C7)
|
|
||||||
{
|
|
||||||
return scr_instanceFunctions[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return scr_globalFunctions[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int string_value,
|
__declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int string_value,
|
||||||
unsigned int paramcount)
|
unsigned int paramcount)
|
||||||
{
|
{
|
||||||
@ -543,6 +531,50 @@ namespace game
|
|||||||
return SL_GetStringOfSize(str, user, std::strlen(str) + 1, 7);
|
return SL_GetStringOfSize(str, user, std::strlen(str) + 1, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int sl_get_canonical_string(const char* str)
|
||||||
|
{
|
||||||
|
static DWORD func = SELECT_VALUE(0x610750, 0x56B040, 0x0);
|
||||||
|
unsigned int result{};
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
mov edi, str
|
||||||
|
call func
|
||||||
|
mov result, eax
|
||||||
|
popad
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int sl_get_canonical_dedicated(const char* str)
|
||||||
|
{
|
||||||
|
static DWORD func = 0x4F1620;
|
||||||
|
unsigned int result{};
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
mov esi, str
|
||||||
|
call func
|
||||||
|
mov result, eax
|
||||||
|
popad
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int SL_GetCanonicalString(const char* str)
|
||||||
|
{
|
||||||
|
if (!is_dedi())
|
||||||
|
{
|
||||||
|
return sl_get_canonical_string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sl_get_canonical_dedicated(str);
|
||||||
|
}
|
||||||
|
|
||||||
__declspec(naked) void sv_send_client_game_state_mp(mp::client_t* /*client*/)
|
__declspec(naked) void sv_send_client_game_state_mp(mp::client_t* /*client*/)
|
||||||
{
|
{
|
||||||
static DWORD func = 0x570FC0;
|
static DWORD func = 0x570FC0;
|
||||||
@ -989,6 +1021,7 @@ namespace game
|
|||||||
native::Com_Filter = native::Com_Filter_t(SELECT_VALUE(0x44EFF0, 0x5B7C30, 0x0));
|
native::Com_Filter = native::Com_Filter_t(SELECT_VALUE(0x44EFF0, 0x5B7C30, 0x0));
|
||||||
|
|
||||||
native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770));
|
native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770));
|
||||||
|
native::DB_FindXAssetHeader = native::DB_FindXAssetHeader_t(SELECT_VALUE(0x4FF000, 0x4CA620, 0x44E7A0));
|
||||||
|
|
||||||
native::Dvar_RegisterBool = native::Dvar_RegisterBool_t(SELECT_VALUE(0x4914D0, 0x5BE9F0, 0x0));
|
native::Dvar_RegisterBool = native::Dvar_RegisterBool_t(SELECT_VALUE(0x4914D0, 0x5BE9F0, 0x0));
|
||||||
native::Dvar_RegisterString = native::Dvar_RegisterString_t(SELECT_VALUE(0x5197F0, 0x5BEC90, 0x0));
|
native::Dvar_RegisterString = native::Dvar_RegisterString_t(SELECT_VALUE(0x5197F0, 0x5BEC90, 0x0));
|
||||||
@ -1084,12 +1117,6 @@ namespace game
|
|||||||
native::scr_VarPub = reinterpret_cast<native::scrVarPub_t*>(SELECT_VALUE(0x0, 0x208E188, 0x1CD8720));
|
native::scr_VarPub = reinterpret_cast<native::scrVarPub_t*>(SELECT_VALUE(0x0, 0x208E188, 0x1CD8720));
|
||||||
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
|
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
|
||||||
|
|
||||||
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x184CDB0, 0x1D4F258,
|
|
||||||
0x1BF59C8));
|
|
||||||
native::scr_globalFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x186C68C, 0x1D6EB34,
|
|
||||||
0x1C152A4
|
|
||||||
));
|
|
||||||
|
|
||||||
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
||||||
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ namespace game
|
|||||||
typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync);
|
typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync);
|
||||||
extern DB_LoadXAssets_t DB_LoadXAssets;
|
extern DB_LoadXAssets_t DB_LoadXAssets;
|
||||||
|
|
||||||
|
typedef XAssetHeader (*DB_FindXAssetHeader_t)(XAssetType type, const char* name, int allowCreateDefault);
|
||||||
|
extern DB_FindXAssetHeader_t DB_FindXAssetHeader;
|
||||||
|
|
||||||
typedef const dvar_t* (*Dvar_RegisterBool_t)(const char* dvarName, bool value,
|
typedef const dvar_t* (*Dvar_RegisterBool_t)(const char* dvarName, bool value,
|
||||||
unsigned __int16 flags, const char* description);
|
unsigned __int16 flags, const char* description);
|
||||||
extern Dvar_RegisterBool_t Dvar_RegisterBool;
|
extern Dvar_RegisterBool_t Dvar_RegisterBool;
|
||||||
@ -171,9 +174,6 @@ namespace game
|
|||||||
extern scrVarPub_t* scr_VarPub;
|
extern scrVarPub_t* scr_VarPub;
|
||||||
extern scrVmPub_t* scr_VmPub;
|
extern scrVmPub_t* scr_VmPub;
|
||||||
|
|
||||||
extern scr_call_t* scr_instanceFunctions;
|
|
||||||
extern scr_call_t* scr_globalFunctions;
|
|
||||||
|
|
||||||
extern unsigned int* levelEntityId;
|
extern unsigned int* levelEntityId;
|
||||||
|
|
||||||
extern int* g_script_error_level;
|
extern int* g_script_error_level;
|
||||||
@ -272,7 +272,6 @@ namespace game
|
|||||||
const float* Scr_AllocVector(const float* v);
|
const float* Scr_AllocVector(const float* v);
|
||||||
void Scr_ClearOutParams();
|
void Scr_ClearOutParams();
|
||||||
scr_entref_t Scr_GetEntityIdRef(unsigned int id);
|
scr_entref_t Scr_GetEntityIdRef(unsigned int id);
|
||||||
scr_call_t Scr_GetFunc(unsigned int index);
|
|
||||||
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount);
|
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount);
|
||||||
int Scr_SetObjectField(unsigned int classnum, int entnum, int offset);
|
int Scr_SetObjectField(unsigned int classnum, int entnum, int offset);
|
||||||
void Scr_AddString(const char* value);
|
void Scr_AddString(const char* value);
|
||||||
@ -280,6 +279,7 @@ namespace game
|
|||||||
|
|
||||||
const char* SL_ConvertToString(unsigned int stringValue);
|
const char* SL_ConvertToString(unsigned int stringValue);
|
||||||
unsigned int SL_GetString(const char* str, unsigned int user);
|
unsigned int SL_GetString(const char* str, unsigned int user);
|
||||||
|
unsigned int SL_GetCanonicalString(const char* str);
|
||||||
|
|
||||||
void SV_SendClientGameState(mp::client_t* client);
|
void SV_SendClientGameState(mp::client_t* client);
|
||||||
int SV_IsTestClient(int clientNum);
|
int SV_IsTestClient(int clientNum);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
#include "game/game.hpp"
|
|
||||||
#include "functions.hpp"
|
#include "functions.hpp"
|
||||||
#include "stack_isolation.hpp"
|
#include "stack_isolation.hpp"
|
||||||
#include "safe_executer.hpp"
|
#include "safe_executer.hpp"
|
||||||
@ -111,7 +112,7 @@ namespace game::scripting
|
|||||||
chaiscript::Boxed_Value executer::call(const std::string& function, const unsigned int entity_id,
|
chaiscript::Boxed_Value executer::call(const std::string& function, const unsigned int entity_id,
|
||||||
std::vector<chaiscript::Boxed_Value> arguments) const
|
std::vector<chaiscript::Boxed_Value> arguments) const
|
||||||
{
|
{
|
||||||
const auto function_index = find_function_index(function, entity_id == 0);
|
const auto function_index = ::scripting::find_function_index(function, entity_id == 0);
|
||||||
if (function_index < 0)
|
if (function_index < 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("No function found for name '" + function + "'");
|
throw std::runtime_error("No function found for name '" + function + "'");
|
||||||
@ -121,7 +122,7 @@ namespace game::scripting
|
|||||||
? native::Scr_GetEntityIdRef(entity_id)
|
? native::Scr_GetEntityIdRef(entity_id)
|
||||||
: native::scr_entref_t{~0u};
|
: native::scr_entref_t{~0u};
|
||||||
|
|
||||||
const auto function_ptr = native::Scr_GetFunc(function_index);
|
const auto function_ptr = ::scripting::get_function_by_index(function_index);
|
||||||
|
|
||||||
stack_isolation _;
|
stack_isolation _;
|
||||||
|
|
||||||
@ -142,34 +143,8 @@ namespace game::scripting
|
|||||||
return this->context_->get_parameters()->get_return_value();
|
return this->context_->get_parameters()->get_return_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
int executer::find_function_index(const std::string& function, const bool prefer_global)
|
bool executer::function_exists(const std::string& function, bool prefer_global)
|
||||||
{
|
{
|
||||||
const auto target = utils::string::to_lower(function);
|
return ::scripting::find_function_index(function, prefer_global) >= 0;
|
||||||
|
|
||||||
const auto primary_map = prefer_global
|
|
||||||
? &global_function_map
|
|
||||||
: &instance_function_map;
|
|
||||||
const auto secondary_map = !prefer_global
|
|
||||||
? &global_function_map
|
|
||||||
: &instance_function_map;
|
|
||||||
|
|
||||||
auto function_entry = primary_map->find(target);
|
|
||||||
if (function_entry != primary_map->end())
|
|
||||||
{
|
|
||||||
return function_entry->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
function_entry = secondary_map->find(target);
|
|
||||||
if (function_entry != secondary_map->end())
|
|
||||||
{
|
|
||||||
return function_entry->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool executer::function_exists(const std::string& function, const bool prefer_global)
|
|
||||||
{
|
|
||||||
return find_function_index(function, prefer_global) >= 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,5 @@ namespace game::scripting
|
|||||||
std::unordered_map<unsigned int, std::unordered_map<std::string, chaiscript::Boxed_Value>> entity_fields_;
|
std::unordered_map<unsigned int, std::unordered_map<std::string, chaiscript::Boxed_Value>> entity_fields_;
|
||||||
|
|
||||||
int get_field_id(int classnum, const std::string& field) const;
|
int get_field_id(int classnum, const std::string& field) const;
|
||||||
|
|
||||||
static int find_function_index(const std::string& function, bool prefer_global);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,748 +1,93 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "functions.hpp"
|
#include "functions.hpp"
|
||||||
|
|
||||||
namespace game::scripting
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
|
#include <xsk/gsc/types.hpp>
|
||||||
|
#include <xsk/resolver.hpp>
|
||||||
|
|
||||||
|
namespace scripting
|
||||||
{
|
{
|
||||||
std::map<std::string, int> instance_function_map =
|
int find_function_index(const std::string& name, const bool prefer_global)
|
||||||
{
|
{
|
||||||
{"getviewmodel", 33457},
|
const auto target = utils::string::to_lower(name);
|
||||||
{"fragbuttonpressed", 33458},
|
auto first = xsk::gsc::iw5::resolver::function_id;
|
||||||
{"secondaryoffhandbuttonpressed", 33459},
|
auto second = xsk::gsc::iw5::resolver::method_id;
|
||||||
{"getcurrentweaponclipammo", 33460},
|
if (!prefer_global)
|
||||||
{"setvelocity", 33461},
|
|
||||||
{"getplayerviewheight", 33462},
|
|
||||||
{"enablemousesteer", 33545},
|
|
||||||
{"getnormalizedmovement", 33463},
|
|
||||||
{"getnormalizedcameramovement", 33486},
|
|
||||||
{"giveweapon", 33487},
|
|
||||||
{"takeweapon", 33488},
|
|
||||||
{"takeallweapons", 33489},
|
|
||||||
{"getcurrentweapon", 33490},
|
|
||||||
{"getcurrentprimaryweapon", 33491},
|
|
||||||
{"getcurrentoffhand", 33492},
|
|
||||||
{"hasweapon", 33493},
|
|
||||||
{"switchtoweapon", 33494},
|
|
||||||
{"switchtoweaponimmediate", 33495},
|
|
||||||
{"switchtooffhand", 33496},
|
|
||||||
{"givestartammo", 33522},
|
|
||||||
{"givemaxammo", 33523},
|
|
||||||
{"getfractionstartammo", 33524},
|
|
||||||
{"getfractionmaxammo", 33525},
|
|
||||||
{"isdualwielding", 33526},
|
|
||||||
{"isreloading", 33527},
|
|
||||||
{"isswitchingweapon", 33528},
|
|
||||||
{"setorigin", 33529},
|
|
||||||
{"getvelocity", 33530},
|
|
||||||
{"setplayerangles", 33531},
|
|
||||||
{"getplayerangles", 33532},
|
|
||||||
{"usebuttonpressed", 33533},
|
|
||||||
{"attackbuttonpressed", 33534},
|
|
||||||
{"adsbuttonpressed", 33535},
|
|
||||||
{"meleebuttonpressed", 33536},
|
|
||||||
{"playerads", 33537},
|
|
||||||
{"isonground", 33538},
|
|
||||||
{"isusingturret", 33539},
|
|
||||||
{"setviewmodel", 33540},
|
|
||||||
{"setoffhandprimaryclass", 33541},
|
|
||||||
{"getoffhandprimaryclass", 33542},
|
|
||||||
{"setoffhandsecondaryclass", 33497},
|
|
||||||
{"getoffhandsecondaryclass", 33498},
|
|
||||||
{"beginlocationselection", 33499},
|
|
||||||
{"endlocationselection", 33500},
|
|
||||||
{"disableweapons", 33501},
|
|
||||||
{"enableweapons", 33502},
|
|
||||||
{"disableoffhandweapons", 33503},
|
|
||||||
{"enableoffhandweapons", 33504},
|
|
||||||
{"disableweaponswitch", 33505},
|
|
||||||
{"enableweaponswitch", 33506},
|
|
||||||
{"openpopupmenu", 33507},
|
|
||||||
{"openpopupmenunomouse", 33508},
|
|
||||||
{"closepopupmenu", 33509},
|
|
||||||
{"openmenu", 33510},
|
|
||||||
{"closemenu", 33511},
|
|
||||||
{"freezecontrols", 33513},
|
|
||||||
{"disableusability", 33514},
|
|
||||||
{"enableusability", 33515},
|
|
||||||
{"setwhizbyspreads", 33516},
|
|
||||||
{"setwhizbyradii", 33517},
|
|
||||||
{"setreverb", 33518},
|
|
||||||
{"deactivatereverb", 33519},
|
|
||||||
{"setvolmod", 33520},
|
|
||||||
{"setchannelvolume", 33521},
|
|
||||||
{"setchannelvolumes", 33464},
|
|
||||||
{"deactivatechannelvolumes", 33465},
|
|
||||||
{"playlocalsound", 33466},
|
|
||||||
{"stoplocalsound", 33467},
|
|
||||||
{"setweaponammoclip", 33468},
|
|
||||||
{"setweaponammostock", 33469},
|
|
||||||
{"getweaponammoclip", 33470},
|
|
||||||
{"getweaponammostock", 33471},
|
|
||||||
{"anyammoforweaponmodes", 33472},
|
|
||||||
{"setclientdvar", 33473},
|
|
||||||
{"setclientdvars", 33474},
|
|
||||||
{"allowads", 33475},
|
|
||||||
{"allowjump", 33476},
|
|
||||||
{"allowsprint", 33477},
|
|
||||||
{"setspreadoverride", 33478},
|
|
||||||
{"resetspreadoverride", 33479},
|
|
||||||
{"setaimspreadmovementscale", 33480},
|
|
||||||
{"setactionslot", 33481},
|
|
||||||
{"setviewkickscale", 33482},
|
|
||||||
{"getviewkickscale", 33483},
|
|
||||||
{"getweaponslistall", 33484},
|
|
||||||
{"getweaponslistprimaries", 33485},
|
|
||||||
{"getweaponslistoffhands", 33430},
|
|
||||||
{"getweaponslistitems", 33431},
|
|
||||||
{"getweaponslistexclusives", 33432},
|
|
||||||
{"getweaponslist", 33433},
|
|
||||||
{"canplayerplacesentry", 33434},
|
|
||||||
{"canplayerplacetank", 33435},
|
|
||||||
{"visionsetnakedforplayer", 33436},
|
|
||||||
{"visionsetnightforplayer", 33437},
|
|
||||||
{"visionsetmissilecamforplayer", 33438},
|
|
||||||
{"visionsetthermalforplayer", 33439},
|
|
||||||
{"visionsetpainforplayer", 33440},
|
|
||||||
{"setblurforplayer", 33441},
|
|
||||||
{"getplayerweaponmodel", 33442},
|
|
||||||
{"getplayerknifemodel", 33443},
|
|
||||||
{"updateplayermodelwithweapons", 33444},
|
|
||||||
{"notifyonplayercommand", 33445},
|
|
||||||
{"canmantle", 33446},
|
|
||||||
{"forcemantle", 33447},
|
|
||||||
{"ismantling", 33448},
|
|
||||||
{"playfx", 33449},
|
|
||||||
{"recoilscaleon", 33450},
|
|
||||||
{"recoilscaleoff", 33451},
|
|
||||||
{"weaponlockstart", 33452},
|
|
||||||
{"weaponlockfinalize", 33453},
|
|
||||||
{"weaponlockfree", 33454},
|
|
||||||
{"weaponlocktargettooclose", 33455},
|
|
||||||
{"weaponlocknoclearance", 33390},
|
|
||||||
{"visionsyncwithplayer", 33391},
|
|
||||||
{"showhudsplash", 33392},
|
|
||||||
{"setperk", 33393},
|
|
||||||
{"hasperk", 33394},
|
|
||||||
{"clearperks", 33395},
|
|
||||||
{"unsetperk", 33396},
|
|
||||||
{"noclip", 33397},
|
|
||||||
{"ufo", 33398},
|
|
||||||
|
|
||||||
// playercmd #2
|
|
||||||
{"pingplayer", 33308},
|
|
||||||
{"buttonpressed", 33309},
|
|
||||||
{"sayall", 33310},
|
|
||||||
{"sayteam", 33311},
|
|
||||||
{"showscoreboard", 33312},
|
|
||||||
{"setspawnweapon", 33313},
|
|
||||||
{"dropitem", 33314},
|
|
||||||
{"dropscavengerbag", 33315},
|
|
||||||
{"finishplayerdamage", 33340},
|
|
||||||
{"suicide", 33341},
|
|
||||||
{"closeingamemenu", 33342},
|
|
||||||
{"iprintln", 33343},
|
|
||||||
{"iprintlnbold", 33344},
|
|
||||||
{"spawn", 33345},
|
|
||||||
{"setentertime", 33346},
|
|
||||||
{"cloneplayer", 33347},
|
|
||||||
{"istalking", 33348},
|
|
||||||
{"allowspectateteam", 33349},
|
|
||||||
{"getguid", 33350},
|
|
||||||
{"getxuid", 33382},
|
|
||||||
{"ishost", 33383},
|
|
||||||
{"getspectatingplayer", 33384},
|
|
||||||
{"predictstreampos", 33385},
|
|
||||||
{"updatescores", 33386},
|
|
||||||
{"updatedmscores", 33387},
|
|
||||||
{"setrank", 33388},
|
|
||||||
{"setcardtitle", 33389},
|
|
||||||
{"setcardicon", 33420},
|
|
||||||
{"setcardnameplate", 33421},
|
|
||||||
{"setcarddisplayslot", 33422},
|
|
||||||
{"regweaponforfxremoval", 33423},
|
|
||||||
{"laststandrevive", 33424},
|
|
||||||
{"setspectatedefaults", 33425},
|
|
||||||
{"getthirdpersoncrosshairoffset", 33426},
|
|
||||||
{"disableweaponpickup", 33427},
|
|
||||||
{"enableweaponpickup", 33428},
|
|
||||||
|
|
||||||
// HECmd
|
|
||||||
{"settext", 32950},
|
|
||||||
{"clearalltextafterhudelem", 32951},
|
|
||||||
{"setshader", 32952},
|
|
||||||
{"settargetent", 32953},
|
|
||||||
{"cleartargetent", 32954},
|
|
||||||
{"settimer", 32955},
|
|
||||||
{"settimerup", 32956},
|
|
||||||
{"settimerstatic", 32957},
|
|
||||||
{"settenthstimer", 32958},
|
|
||||||
{"settenthstimerup", 32959},
|
|
||||||
{"settenthstimerstatic", 32960},
|
|
||||||
{"setclock", 32961},
|
|
||||||
{"setclockup", 32962},
|
|
||||||
{"setvalue", 32963},
|
|
||||||
{"setwaypoint", 32964},
|
|
||||||
{"rotatingicon", 32965},
|
|
||||||
{"secondaryarrow", 32891},
|
|
||||||
{"setwaypointiconoffscreenonly", 32892},
|
|
||||||
{"fadeovertime", 32893},
|
|
||||||
{"scaleovertime", 32894},
|
|
||||||
{"moveovertime", 32895},
|
|
||||||
{"reset", 32896},
|
|
||||||
{"destroy", 32897},
|
|
||||||
{"setpulsefx", 32898},
|
|
||||||
{"setplayernamestring", 32899},
|
|
||||||
{"fadeovertime2", 33547},
|
|
||||||
{"scaleovertime2", 33548},
|
|
||||||
{"changefontscaleovertime", 32900},
|
|
||||||
|
|
||||||
// ScrCmd
|
|
||||||
{"attach", 32791},
|
|
||||||
{"attachshieldmodel", 32792},
|
|
||||||
{"detach", 32804},
|
|
||||||
{"detachshieldmodel", 32805},
|
|
||||||
{"moveshieldmodel", 32806},
|
|
||||||
{"detachall", 32807},
|
|
||||||
{"getattachsize", 32808},
|
|
||||||
{"getattachmodelname", 32809},
|
|
||||||
{"getattachtagname", 32810},
|
|
||||||
{"getattachignorecollision", 32835},
|
|
||||||
{"hidepart", 32836},
|
|
||||||
{"allinstances", 32837},
|
|
||||||
{"hideallparts", 32838},
|
|
||||||
{"showpart", 32839},
|
|
||||||
{"showallparts", 32840},
|
|
||||||
{"linkto", 32841},
|
|
||||||
{"linktoblendtotag", 32842},
|
|
||||||
{"unlink", 32843},
|
|
||||||
{"islinked", 32867},
|
|
||||||
{"enablelinkto", 32868},
|
|
||||||
{"playerlinkto", 32885},
|
|
||||||
{"playerlinktodelta", 32886},
|
|
||||||
{"playerlinkweaponviewtodelta", 32887},
|
|
||||||
{"playerlinktoabsolute", 32888},
|
|
||||||
{"playerlinktoblend", 32889},
|
|
||||||
{"playerlinkedoffsetenable", 32890},
|
|
||||||
{"playerlinkedoffsetdisable", 32916},
|
|
||||||
{"playerlinkedsetviewznear", 32917},
|
|
||||||
{"playerlinkedsetusebaseangleforviewclamp", 32918},
|
|
||||||
{"lerpviewangleclamp", 32919},
|
|
||||||
{"setviewangleresistance", 32920},
|
|
||||||
{"geteye", 32921},
|
|
||||||
{"istouching", 32922},
|
|
||||||
{"stoploopsound", 32923},
|
|
||||||
{"stopsounds", 32924},
|
|
||||||
{"playrumbleonentity", 32925},
|
|
||||||
{"playrumblelooponentity", 32926},
|
|
||||||
{"stoprumble", 32927},
|
|
||||||
{"delete", 32928},
|
|
||||||
{"setmodel", 32929},
|
|
||||||
{"laseron", 32930},
|
|
||||||
{"laseroff", 32931},
|
|
||||||
{"laseraltviewon", 32932},
|
|
||||||
{"laseraltviewoff", 32933},
|
|
||||||
{"thermalvisionon", 32934},
|
|
||||||
{"thermalvisionoff", 32935},
|
|
||||||
{"thermaldrawenable", 32803},
|
|
||||||
{"thermaldrawdisable", 32768},
|
|
||||||
{"thermalvisionfofoverlayon", 32936},
|
|
||||||
{"thermalvisionfofoverlayoff", 32937},
|
|
||||||
{"autospotoverlayon", 32938},
|
|
||||||
{"autospotoverlayoff", 32939},
|
|
||||||
{"setcontents", 32940},
|
|
||||||
{"makeusable", 32941},
|
|
||||||
{"makeunusable", 32942},
|
|
||||||
{"setcursorhint", 32966},
|
|
||||||
{"sethintstring", 32967},
|
|
||||||
{"forceusehinton", 32968},
|
|
||||||
{"forceusehintoff", 32969},
|
|
||||||
{"makesoft", 32970},
|
|
||||||
{"makehard", 32971},
|
|
||||||
{"willneverchange", 32972},
|
|
||||||
{"startfiring", 32973},
|
|
||||||
{"stopfiring", 32974},
|
|
||||||
{"isfiringturret", 32975},
|
|
||||||
{"startbarrelspin", 32976},
|
|
||||||
{"stopbarrelspin", 32977},
|
|
||||||
{"getbarrelspinrate", 32978},
|
|
||||||
{"remotecontrolturret", 32979},
|
|
||||||
{"remotecontrolturretoff", 32980},
|
|
||||||
{"shootturret", 32981},
|
|
||||||
{"getturretowner", 32982},
|
|
||||||
{"setsentryowner", 33006},
|
|
||||||
{"setsentrycarrier", 33007},
|
|
||||||
{"setturretminimapvisible", 33008},
|
|
||||||
{"settargetentity", 33009},
|
|
||||||
{"snaptotargetentity", 33010},
|
|
||||||
{"cleartargetentity", 33011},
|
|
||||||
{"getturrettarget", 33012},
|
|
||||||
{"setplayerspread", 33013},
|
|
||||||
{"setaispread", 33014},
|
|
||||||
{"setsuppressiontime", 33015},
|
|
||||||
{"setconvergencetime", 33049},
|
|
||||||
{"setconvergenceheightpercent", 33050},
|
|
||||||
{"setturretteam", 33051},
|
|
||||||
{"maketurretsolid", 33052},
|
|
||||||
{"maketurretoperable", 33053},
|
|
||||||
{"maketurretinoperable", 33054},
|
|
||||||
{"setturretaccuracy", 33082},
|
|
||||||
{"setrightarc", 33083},
|
|
||||||
{"setleftarc", 33084},
|
|
||||||
{"settoparc", 33085},
|
|
||||||
{"setbottomarc", 33086},
|
|
||||||
{"setautorotationdelay", 33087},
|
|
||||||
{"setdefaultdroppitch", 33088},
|
|
||||||
{"restoredefaultdroppitch", 33089},
|
|
||||||
{"turretfiredisable", 33090},
|
|
||||||
{"turretfireenable", 33121},
|
|
||||||
{"setturretmodechangewait", 33122},
|
|
||||||
{"usetriggerrequirelookat", 33123},
|
|
||||||
{"getstance", 33124},
|
|
||||||
{"setstance", 33125},
|
|
||||||
{"itemweaponsetammo", 33126},
|
|
||||||
{"getammocount", 33127},
|
|
||||||
{"gettagorigin", 33128},
|
|
||||||
{"gettagangles", 33129},
|
|
||||||
{"shellshock", 33130},
|
|
||||||
{"stunplayer", 33131},
|
|
||||||
{"stopshellshock", 33132},
|
|
||||||
{"fadeoutshellshock", 33133},
|
|
||||||
{"setdepthoffield", 33134},
|
|
||||||
{"setviewmodeldepthoffield", 33135},
|
|
||||||
{"setmotionblurmovescale", 33136},
|
|
||||||
{"setmotionblurturnscale", 33168},
|
|
||||||
{"setmotionblurzoomscale", 33169},
|
|
||||||
{"viewkick", 33170},
|
|
||||||
{"localtoworldcoords", 33171},
|
|
||||||
{"getentitynumber", 33172},
|
|
||||||
{"getentityvelocity", 33173},
|
|
||||||
{"enablegrenadetouchdamage", 33174},
|
|
||||||
{"disablegrenadetouchdamage", 33175},
|
|
||||||
{"enableaimassist", 33176},
|
|
||||||
{"disableaimassist", 33207},
|
|
||||||
{"radiusdamage", 33208},
|
|
||||||
{"detonate", 33209},
|
|
||||||
{"damageconetrace", 33210},
|
|
||||||
{"sightconetrace", 33211},
|
|
||||||
{"settargetent", 33212},
|
|
||||||
{"settargetpos", 33213},
|
|
||||||
{"cleartarget", 33214},
|
|
||||||
{"setflightmodedirect", 33215},
|
|
||||||
{"setflightmodetop", 33216},
|
|
||||||
{"getlightintensity", 33217},
|
|
||||||
{"setlightintensity", 33218},
|
|
||||||
{"isragdoll", 33219},
|
|
||||||
{"setmovespeedscale", 33220},
|
|
||||||
{"cameralinkto", 33221},
|
|
||||||
{"cameraunlink", 33222},
|
|
||||||
{"controlslinkto", 33251},
|
|
||||||
{"controlsunlink", 33252},
|
|
||||||
{"makevehiclesolidcapsule", 33253},
|
|
||||||
{"makevehiclesolidsphere", 33254},
|
|
||||||
{"remotecontrolvehicle", 33256},
|
|
||||||
{"remotecontrolvehicleoff", 33257},
|
|
||||||
{"isfiringvehicleturret", 33258},
|
|
||||||
{"drivevehicleandcontrolturret", 33259},
|
|
||||||
{"drivevehicleandcontrolturretoff", 33260},
|
|
||||||
{"getplayersetting", 33261},
|
|
||||||
{"getlocalplayerprofiledata", 33262},
|
|
||||||
{"setlocalplayerprofiledata", 33263},
|
|
||||||
{"remotecamerasoundscapeon", 33264},
|
|
||||||
{"remotecamerasoundscapeoff", 33265},
|
|
||||||
{"radarjamon", 33266},
|
|
||||||
{"radarjamoff", 33267},
|
|
||||||
{"setmotiontrackervisible", 33268},
|
|
||||||
{"getmotiontrackervisible", 33269},
|
|
||||||
{"circle", 33270},
|
|
||||||
{"getpointinbounds", 33271},
|
|
||||||
{"transfermarkstonewscriptmodel", 33272},
|
|
||||||
{"setwatersheeting", 33273},
|
|
||||||
{"setweaponhudiconoverride", 33274},
|
|
||||||
{"getweaponhudiconoverride", 33275},
|
|
||||||
{"setempjammed", 33276},
|
|
||||||
{"playersetexpfog", 33277},
|
|
||||||
{"isitemunlocked", 33278},
|
|
||||||
{"getplayerdata", 33279},
|
|
||||||
{"setplayerdata", 33306},
|
|
||||||
|
|
||||||
// Vehicle stuff
|
|
||||||
{"teleport", 0x824C},
|
|
||||||
{"attachpath", 0x824D},
|
|
||||||
{"getattachpos", 0x824E},
|
|
||||||
{"startpath", 0x824F},
|
|
||||||
{"setswitchnode", 0x8250},
|
|
||||||
{"setwaitspeed", 0x8251},
|
|
||||||
{"finishdamage", 0x8252},
|
|
||||||
{"setspeed", 0x8253},
|
|
||||||
{"setspeedimmediate", 0x8254},
|
|
||||||
{"setwaitspeed", 0x8251},
|
|
||||||
|
|
||||||
{"setlookatent", 0x8237},
|
|
||||||
{"clearlookatent", 0x8238},
|
|
||||||
|
|
||||||
{"setvehgoalpos", 33325},
|
|
||||||
{"setturningability", 33381},
|
|
||||||
|
|
||||||
// some entity (script_model) stuff
|
|
||||||
{"moveto", 33399},
|
|
||||||
{"movex", 33400},
|
|
||||||
{"movey", 33401},
|
|
||||||
{"movez", 33402},
|
|
||||||
{"movegravity", 33403},
|
|
||||||
{"moveslide", 33404},
|
|
||||||
{"stopmoveslide", 33405},
|
|
||||||
{"rotateto", 33406},
|
|
||||||
{"rotatepitch", 33407},
|
|
||||||
{"rotateyaw", 33408},
|
|
||||||
{"rotateroll", 33409},
|
|
||||||
{"addpitch", 33410},
|
|
||||||
{"addyaw", 33411},
|
|
||||||
{"addroll", 33412},
|
|
||||||
{"vibrate", 33413},
|
|
||||||
{"rotatevelocity", 33414},
|
|
||||||
{"solid", 33415},
|
|
||||||
{"notsolid", 33416},
|
|
||||||
{"setcandamage", 33417},
|
|
||||||
{"setcanradiusdamage", 33418},
|
|
||||||
{"physicslaunchclient", 33419},
|
|
||||||
{"physicslaunchserver", 33351},
|
|
||||||
{"physicslaunchserveritem", 33352},
|
|
||||||
{"clonebrushmodeltoscriptmodel", 33353},
|
|
||||||
{"scriptmodelplayanim", 33354},
|
|
||||||
{"scriptmodelclearanim", 33355},
|
|
||||||
|
|
||||||
// varied ent/player script commands
|
|
||||||
{"getorigin", 32910},
|
|
||||||
{"useby", 32914},
|
|
||||||
{"playsound", 32915},
|
|
||||||
{"playsoundasmaster", 32878},
|
|
||||||
{"playsoundtoteam", 32771},
|
|
||||||
{"playsoundtoplayer", 32772},
|
|
||||||
{"playloopsound", 32879},
|
|
||||||
{"getnormalhealth", 32884},
|
|
||||||
{"setnormalhealth", 32844},
|
|
||||||
{"show", 32847},
|
|
||||||
{"hide", 32848},
|
|
||||||
{"playerhide", 32773},
|
|
||||||
{"showtoplayer", 32774},
|
|
||||||
{"enableplayeruse", 32775},
|
|
||||||
{"disableplayeruse", 32776},
|
|
||||||
{"setscriptmoverkillcam", 33546},
|
|
||||||
{"makescrambler", 32777},
|
|
||||||
{"makeportableradar", 32778},
|
|
||||||
{"maketrophysystem", 32779},
|
|
||||||
{"setmode", 32864},
|
|
||||||
{"getmode", 32865},
|
|
||||||
{"placespawnpoint", 32780},
|
|
||||||
{"setteamfortrigger", 32781},
|
|
||||||
{"clientclaimtrigger", 32782},
|
|
||||||
{"clientreleasetrigger", 32783},
|
|
||||||
{"releaseclaimedtrigger", 32784},
|
|
||||||
{"isusingonlinedataoffline", 32785},
|
|
||||||
{"getrestedtime", 32786},
|
|
||||||
{"sendleaderboards", 32787},
|
|
||||||
{"logstring", 32800},
|
|
||||||
{"isonladder", 32788},
|
|
||||||
{"startragdoll", 32798},
|
|
||||||
{"getcorpseanim", 32789},
|
|
||||||
{"playerforcedeathanim", 32790},
|
|
||||||
{"startac130", 33543},
|
|
||||||
{"stopac130", 33544},
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<std::string, int> global_function_map =
|
|
||||||
{
|
{
|
||||||
// global stuff #1
|
std::swap(first, second);
|
||||||
{"iprintln", 362},
|
}
|
||||||
{"iprintlnbold", 363},
|
|
||||||
{"logstring", 364},
|
const auto first_res = first(target);
|
||||||
{"getent", 365},
|
if (first_res)
|
||||||
{"getentarray", 366},
|
{
|
||||||
{"spawnplane", 367},
|
return first_res;
|
||||||
{"spawnstruct", 368},
|
}
|
||||||
{"spawnhelicopter", 369},
|
|
||||||
{"isalive", 370},
|
const auto second_res = second(target);
|
||||||
{"isspawner", 371},
|
if (second_res)
|
||||||
{"createattractorent", 372},
|
{
|
||||||
{"createattractororigin", 373},
|
return second_res;
|
||||||
{"createrepulsorent", 374},
|
}
|
||||||
{"createrepulsororigin", 375},
|
|
||||||
{"deleteattractor", 376},
|
return -1;
|
||||||
{"playsoundatpos", 377},
|
}
|
||||||
{"newhudelem", 378},
|
|
||||||
{"newclienthudelem", 379},
|
std::uint32_t parse_token_id(const std::string& name)
|
||||||
{"newteamhudelem", 380},
|
{
|
||||||
{"resettimeout", 381},
|
if (name.starts_with("_ID"))
|
||||||
{"precachefxteamthermal", 382},
|
{
|
||||||
{"isplayer", 383},
|
return static_cast<std::uint32_t>(std::strtol(name.substr(3).data(), nullptr, 10));
|
||||||
{"isplayernumber", 384},
|
}
|
||||||
{"setsunlight", 57},
|
|
||||||
{"resetsunlight", 58},
|
return 0;
|
||||||
{"setwinningplayer", 385},
|
}
|
||||||
{"setwinningteam", 311},
|
|
||||||
{"announcement", 312},
|
std::string find_token(std::uint32_t id)
|
||||||
{"clientannouncement", 313},
|
{
|
||||||
{"getteamscore", 314},
|
return xsk::gsc::iw5::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||||
{"setteamscore", 315},
|
}
|
||||||
{"setclientnamemode", 316},
|
|
||||||
{"updateclientnames", 317},
|
std::string find_token_single(std::uint32_t id)
|
||||||
{"getteamplayersalive", 318},
|
{
|
||||||
{"logprint", 319},
|
return xsk::gsc::iw5::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||||
{"worldentnumber", 320},
|
}
|
||||||
{"obituary", 321},
|
|
||||||
{"positionwouldtelefrag", 322},
|
unsigned int find_token_id(const std::string& name)
|
||||||
{"canspawn", 323},
|
{
|
||||||
{"getstarttime", 324},
|
const auto id = xsk::gsc::iw5::resolver::token_id(name);
|
||||||
{"precachestatusicon", 325},
|
if (id)
|
||||||
{"precacheminimapicon", 327},
|
{
|
||||||
{"precachempanim", 328},
|
return id;
|
||||||
{"restart", 329},
|
}
|
||||||
{"exitlevel", 330},
|
|
||||||
{"addtestclient", 331},
|
const auto parsed_id = parse_token_id(name);
|
||||||
{"makedvarserverinfo", 332},
|
if (parsed_id)
|
||||||
{"setarchive", 333},
|
{
|
||||||
{"allclientsprint", 334},
|
return parsed_id;
|
||||||
{"clientprint", 335},
|
}
|
||||||
{"mapexists", 336},
|
|
||||||
{"isvalidgametype", 337},
|
return game::native::SL_GetCanonicalString(name.data());
|
||||||
{"matchend", 338},
|
}
|
||||||
{"setplayerteamrank", 339},
|
|
||||||
{"endparty", 340},
|
game::native::scr_call_t get_function_by_index(const std::uint32_t index)
|
||||||
{"setteamradar", 341},
|
{
|
||||||
{"getteamradar", 342},
|
static const auto function_table = SELECT_VALUE(0x186C68C, 0x1D6EB34, 0x1C152A4);
|
||||||
{"setteamradarstrength", 343},
|
static const auto method_table = SELECT_VALUE(0x184CDB0, 0x1D4F258, 0x1BF59C8);
|
||||||
{"getteamradarstrength", 344},
|
|
||||||
{"getuavstrengthmin", 345},
|
if (index < 0x1C7)
|
||||||
{"getuavstrengthmax", 262},
|
{
|
||||||
{"getuavstrengthlevelneutral", 263},
|
return reinterpret_cast<game::native::scr_call_t*>(function_table)[index - 1];
|
||||||
{"getuavstrengthlevelshowenemyfastsweep", 264},
|
}
|
||||||
{"getuavstrengthlevelshowenemydirectional", 265},
|
|
||||||
{"blockteamradar", 266},
|
return reinterpret_cast<game::native::scr_call_t*>(method_table)[index];
|
||||||
{"unblockteamradar", 267},
|
}
|
||||||
{"isteamradarblocked", 268},
|
|
||||||
{"getassignedteam", 269},
|
game::native::scr_call_t find_function(const std::string& name, const bool prefer_global)
|
||||||
{"setmatchdata", 270},
|
{
|
||||||
{"getmatchdata", 271},
|
const auto index = find_function_index(name, prefer_global);
|
||||||
{"sendmatchdata", 272},
|
if (index < 0) return nullptr;
|
||||||
{"clearmatchdata", 273},
|
|
||||||
{"setmatchdatadef", 274},
|
return get_function_by_index(index);
|
||||||
{"setmatchclientip", 275},
|
}
|
||||||
{"setmatchdataid", 276},
|
|
||||||
{"setclientmatchdata", 277},
|
|
||||||
{"getclientmatchdata", 278},
|
|
||||||
{"setclientmatchdatadef", 279},
|
|
||||||
{"sendclientmatchdata", 280},
|
|
||||||
{"getbuildversion", 281},
|
|
||||||
{"getbuildnumber", 282},
|
|
||||||
{"getsystemtime", 283},
|
|
||||||
{"getmatchrulesdata", 284},
|
|
||||||
{"isusingmatchrulesdata", 285},
|
|
||||||
{"kick", 286},
|
|
||||||
{"issplitscreen", 287},
|
|
||||||
{"setmapcenter", 288},
|
|
||||||
{"setgameendtime", 289},
|
|
||||||
{"visionsetnaked", 290},
|
|
||||||
{"visionsetnight", 291},
|
|
||||||
{"visionsetmissilecam", 292},
|
|
||||||
{"visionsetthermal", 217},
|
|
||||||
{"visionsetpain", 218},
|
|
||||||
{"endlobby", 219},
|
|
||||||
{"ambience", 220},
|
|
||||||
{"getmapcustom", 221},
|
|
||||||
{"updateskill", 222},
|
|
||||||
{"spawnsighttrace", 223},
|
|
||||||
|
|
||||||
// global stuff #2
|
|
||||||
{"setprintchannel", 14},
|
|
||||||
{"print", 15},
|
|
||||||
{"println", 16},
|
|
||||||
{"print3d", 17},
|
|
||||||
{"line", 18},
|
|
||||||
{"spawnturret", 19},
|
|
||||||
{"canspawnturret", 20},
|
|
||||||
{"assert", 21},
|
|
||||||
{"assertex", 38},
|
|
||||||
{"assertmsg", 39},
|
|
||||||
{"isdefined", 40},
|
|
||||||
{"isstring", 41},
|
|
||||||
{"setdvar", 42},
|
|
||||||
{"setdynamicdvar", 43},
|
|
||||||
{"setdvarifuninitialized", 44},
|
|
||||||
{"setdevdvar", 45},
|
|
||||||
{"setdevdvarifuninitialized", 46},
|
|
||||||
{"getdvar", 47},
|
|
||||||
{"getdvarint", 48},
|
|
||||||
{"getdvarfloat", 49},
|
|
||||||
{"getdvarvector", 50},
|
|
||||||
{"gettime", 51},
|
|
||||||
{"getentbynum", 52},
|
|
||||||
{"getweaponmodel", 53},
|
|
||||||
{"getweaponhidetags", 81},
|
|
||||||
{"getanimlength", 82},
|
|
||||||
{"animhasnotetrack", 83},
|
|
||||||
{"getnotetracktimes", 84},
|
|
||||||
{"spawn", 85},
|
|
||||||
{"spawnloopsound", 86},
|
|
||||||
{"bullettrace", 87},
|
|
||||||
{"bullettracepassed", 88},
|
|
||||||
{"sighttracepassed", 116},
|
|
||||||
{"physicstrace", 117},
|
|
||||||
{"physicstracenormal", 118},
|
|
||||||
{"playerphysicstrace", 119},
|
|
||||||
{"getgroundposition", 120},
|
|
||||||
{"getmovedelta", 121},
|
|
||||||
{"getangledelta", 122},
|
|
||||||
{"getnorthyaw", 123},
|
|
||||||
{"setnorthyaw", 150},
|
|
||||||
{"setslowmotion", 151},
|
|
||||||
{"randomint", 152},
|
|
||||||
{"randomfloat", 153},
|
|
||||||
{"randomintrange", 154},
|
|
||||||
{"randomfloatrange", 155},
|
|
||||||
{"sin", 156},
|
|
||||||
{"cos", 157},
|
|
||||||
{"tan", 158},
|
|
||||||
{"asin", 159},
|
|
||||||
{"acos", 160},
|
|
||||||
{"atan", 161},
|
|
||||||
{"int", 162},
|
|
||||||
{"float", 163},
|
|
||||||
{"abs", 164},
|
|
||||||
{"min", 165},
|
|
||||||
{"max", 198},
|
|
||||||
{"floor", 199},
|
|
||||||
{"ceil", 200},
|
|
||||||
{"exp", 201},
|
|
||||||
{"log", 202},
|
|
||||||
{"sqrt", 203},
|
|
||||||
{"squared", 204},
|
|
||||||
{"clamp", 205},
|
|
||||||
{"angleclamp", 206},
|
|
||||||
{"angleclamp180", 207},
|
|
||||||
{"vectorfromlinetopoint", 208},
|
|
||||||
{"pointonsegmentnearesttopoint", 209},
|
|
||||||
{"distance", 210},
|
|
||||||
{"distance2d", 211},
|
|
||||||
{"distancesquared", 212},
|
|
||||||
{"length", 213},
|
|
||||||
{"lengthsquared", 214},
|
|
||||||
{"closer", 215},
|
|
||||||
{"vectordot", 216},
|
|
||||||
{"vectornormalize", 246},
|
|
||||||
{"vectortoangles", 247},
|
|
||||||
{"vectortoyaw", 248},
|
|
||||||
{"vectorlerp", 249},
|
|
||||||
{"anglestoup", 250},
|
|
||||||
{"anglestoright", 251},
|
|
||||||
{"anglestoforward", 252},
|
|
||||||
{"combineangles", 253},
|
|
||||||
{"transformmove", 254},
|
|
||||||
{"issubstr", 255},
|
|
||||||
{"isendstr", 256},
|
|
||||||
{"getsubstr", 257},
|
|
||||||
{"tolower", 258},
|
|
||||||
{"strtok", 259},
|
|
||||||
{"stricmp", 260},
|
|
||||||
{"ambientplay", 261},
|
|
||||||
{"ambientstop", 293},
|
|
||||||
{"precachemodel", 294},
|
|
||||||
{"precacheshellshock", 295},
|
|
||||||
{"precacheitem", 296},
|
|
||||||
{"precacheshader", 297},
|
|
||||||
{"precachestring", 298},
|
|
||||||
{"precachemenu", 299},
|
|
||||||
{"precacherumble", 300},
|
|
||||||
{"precachelocationselector", 301},
|
|
||||||
{"precacheleaderboards", 302},
|
|
||||||
{"precacheheadicon", 326},
|
|
||||||
{"loadfx", 303},
|
|
||||||
{"playfx", 304},
|
|
||||||
{"playfxontag", 305},
|
|
||||||
{"stopfxontag", 306},
|
|
||||||
{"playloopedfx", 307},
|
|
||||||
{"spawnfx", 308},
|
|
||||||
{"triggerfx", 309},
|
|
||||||
{"playfxontagforclients", 310},
|
|
||||||
{"physicsexplosionsphere", 346},
|
|
||||||
{"physicsexplosioncylinder", 347},
|
|
||||||
{"physicsjolt", 348},
|
|
||||||
{"physicsjitter", 349},
|
|
||||||
{"setexpfog", 350},
|
|
||||||
{"isexplosivedamagemod", 351},
|
|
||||||
{"radiusdamage", 352},
|
|
||||||
{"setplayerignoreradiusdamage", 353},
|
|
||||||
{"glassradiusdamage", 354},
|
|
||||||
{"earthquake", 355},
|
|
||||||
{"getnumparts", 356},
|
|
||||||
{"getpartname", 386},
|
|
||||||
{"weaponfiretime", 387},
|
|
||||||
{"weaponclipsize", 388},
|
|
||||||
{"weaponisauto", 389},
|
|
||||||
{"weaponissemiauto", 390},
|
|
||||||
{"weaponisboltaction", 391},
|
|
||||||
{"weaponinheritsperks", 392},
|
|
||||||
{"weaponburstcount", 393},
|
|
||||||
{"weapontype", 394},
|
|
||||||
{"weaponclass", 395},
|
|
||||||
{"weaponinventorytype", 437},
|
|
||||||
{"weaponstartammo", 438},
|
|
||||||
{"weaponmaxammo", 439},
|
|
||||||
{"weaponaltweaponname", 440},
|
|
||||||
{"isweaponcliponly", 441},
|
|
||||||
{"isweapondetonationtimed", 442},
|
|
||||||
{"weaponhasthermalscope", 443},
|
|
||||||
{"getvehiclenode", 444},
|
|
||||||
{"getvehiclenodearray", 445},
|
|
||||||
{"getallvehiclenodes", 446},
|
|
||||||
{"getnumvehicles", 447},
|
|
||||||
{"precachevehicle", 448},
|
|
||||||
{"spawnvehicle", 449},
|
|
||||||
{"getarray", 450},
|
|
||||||
{"getspawnerarray", 408},
|
|
||||||
{"playrumbleonposition", 409},
|
|
||||||
{"playrumblelooponposition", 410},
|
|
||||||
{"stopallrumbles", 411},
|
|
||||||
{"soundexists", 412},
|
|
||||||
{"openfile", 413},
|
|
||||||
{"closefile", 414},
|
|
||||||
{"fprintln", 415},
|
|
||||||
{"fprintfields", 416},
|
|
||||||
{"freadln", 417},
|
|
||||||
{"fgetarg", 418},
|
|
||||||
{"setminimap", 419},
|
|
||||||
{"setthermalbodymaterial", 420},
|
|
||||||
{"getarraykeys", 421},
|
|
||||||
{"getfirstarraykey", 422},
|
|
||||||
{"getnextarraykey", 396},
|
|
||||||
{"sortbydistance", 397},
|
|
||||||
{"tablelookup", 398},
|
|
||||||
{"tablelookupbyrow", 399},
|
|
||||||
{"tablelookupistring", 400},
|
|
||||||
{"tablelookupistringbyrow", 401},
|
|
||||||
{"tablelookuprownum", 402},
|
|
||||||
{"getmissileowner", 403},
|
|
||||||
{"magicbullet", 404},
|
|
||||||
{"getweaponflashtagname", 405},
|
|
||||||
{"averagepoint", 406},
|
|
||||||
{"averagenormal", 407},
|
|
||||||
{"getglass", 423},
|
|
||||||
{"getglassarray", 424},
|
|
||||||
{"getglassorigin", 425},
|
|
||||||
{"isglassdestroyed", 426},
|
|
||||||
{"destroyglass", 427},
|
|
||||||
{"deleteglass", 428},
|
|
||||||
{"getentchannelscount", 429},
|
|
||||||
|
|
||||||
// objective
|
|
||||||
{"objective_add", 431},
|
|
||||||
{"objective_delete", 432},
|
|
||||||
{"objective_state", 433},
|
|
||||||
{"objective_icon", 434},
|
|
||||||
{"objective_position", 435},
|
|
||||||
{"objective_current", 436},
|
|
||||||
{"objective_onentity", 357},
|
|
||||||
{"objective_team", 358},
|
|
||||||
{"objective_player", 359},
|
|
||||||
{"objective_playerteam", 360},
|
|
||||||
{"objective_playerenemyteam", 361},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
namespace game::scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
extern std::map<std::string, int> instance_function_map;
|
std::string find_token(std::uint32_t id);
|
||||||
extern std::map<std::string, int> global_function_map;
|
std::string find_token_single(std::uint32_t id);
|
||||||
|
unsigned int find_token_id(const std::string& name);
|
||||||
|
|
||||||
|
int find_function_index(const std::string& name, bool prefer_global);
|
||||||
|
game::native::scr_call_t get_function_by_index(std::uint32_t index);
|
||||||
|
game::native::scr_call_t find_function(const std::string& name, bool prefer_global);
|
||||||
}
|
}
|
||||||
|
@ -374,6 +374,27 @@ namespace game
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
enum XAssetType
|
||||||
|
{
|
||||||
|
ASSET_TYPE_SCRIPTFILE = 0x27,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScriptFile
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
int compressedLen;
|
||||||
|
int len;
|
||||||
|
int bytecodeLen;
|
||||||
|
const char* buffer;
|
||||||
|
unsigned char* bytecode;
|
||||||
|
};
|
||||||
|
|
||||||
|
union XAssetHeader
|
||||||
|
{
|
||||||
|
void* data;
|
||||||
|
ScriptFile* scriptfile;
|
||||||
|
};
|
||||||
|
|
||||||
enum errorParm_t
|
enum errorParm_t
|
||||||
{
|
{
|
||||||
ERR_FATAL = 0x0,
|
ERR_FATAL = 0x0,
|
||||||
|
128
src/module/gsc/script_error.cpp
Normal file
128
src/module/gsc/script_error.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include <loader/module_loader.hpp>
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
|
#include "script_error.hpp"
|
||||||
|
|
||||||
|
#include "module/scripting.hpp"
|
||||||
|
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
|
using namespace utils::string;
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
utils::hook::detour scr_emit_function_hook;
|
||||||
|
|
||||||
|
unsigned int current_filename = 0;
|
||||||
|
|
||||||
|
std::string unknown_function_error;
|
||||||
|
|
||||||
|
void scr_emit_function_stub(unsigned int filename, unsigned int thread_name, char* code_pos)
|
||||||
|
{
|
||||||
|
current_filename = filename;
|
||||||
|
scr_emit_function_hook.invoke<void>(filename, thread_name, code_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_filename_name()
|
||||||
|
{
|
||||||
|
const auto filename_str = game::native::SL_ConvertToString(current_filename);
|
||||||
|
const auto id = std::strtol(filename_str, nullptr, 10);
|
||||||
|
if (!id)
|
||||||
|
{
|
||||||
|
return filename_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scripting::get_token(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_unknown_function_error(const char* code_pos)
|
||||||
|
{
|
||||||
|
const auto function = find_function(code_pos);
|
||||||
|
if (function.has_value())
|
||||||
|
{
|
||||||
|
const auto& pos = function.value();
|
||||||
|
unknown_function_error = std::format(
|
||||||
|
"while processing function '{}' in script '{}':\nunknown script '{}'", pos.first, pos.second, scripting::current_file
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unknown_function_error = std::format("unknown script '{}'", scripting::current_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_unknown_function_error(unsigned int thread_name)
|
||||||
|
{
|
||||||
|
const auto filename = get_filename_name();
|
||||||
|
const auto name = scripting::get_token(thread_name);
|
||||||
|
|
||||||
|
unknown_function_error = std::format(
|
||||||
|
"while processing script '{}':\nunknown function '{}::{}'", scripting::current_file, filename, name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void compile_error_stub(const char* code_pos, [[maybe_unused]] const char* msg)
|
||||||
|
{
|
||||||
|
get_unknown_function_error(code_pos);
|
||||||
|
game::native::Com_Error(game::native::ERR_DROP, "script link error\n%s", unknown_function_error.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int find_variable_stub(unsigned int parent_id, unsigned int thread_name)
|
||||||
|
{
|
||||||
|
const auto res = utils::hook::invoke<unsigned int>(SELECT_VALUE(0x4C4E70, 0x5651F0, 0x0), parent_id, thread_name);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
get_unknown_function_error(thread_name);
|
||||||
|
game::native::Com_Error(game::native::ERR_DROP, "script link error\n%s", unknown_function_error.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::pair<std::string, std::string>> find_function(const char* pos)
|
||||||
|
{
|
||||||
|
for (const auto& file : scripting::script_function_table_sort)
|
||||||
|
{
|
||||||
|
for (auto i = file.second.begin(); i != file.second.end() && std::next(i) != file.second.end(); ++i)
|
||||||
|
{
|
||||||
|
const auto next = std::next(i);
|
||||||
|
if (pos >= i->second && pos < next->second)
|
||||||
|
{
|
||||||
|
return {std::make_pair(i->first, file.first)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
class error final : public module
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void post_load() override
|
||||||
|
{
|
||||||
|
if (game::is_dedi())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scr_emit_function_hook.create(SELECT_VALUE(0x40DCB0, 0x561400, 0x0), &scr_emit_function_stub);
|
||||||
|
|
||||||
|
utils::hook(SELECT_VALUE(0x60DABA, 0x5615FA, 0x0), &compile_error_stub, HOOK_CALL).install()->quick();
|
||||||
|
utils::hook(SELECT_VALUE(0x60DAD1, 0x561611, 0x0), &compile_error_stub, HOOK_CALL).install()->quick();
|
||||||
|
utils::hook(SELECT_VALUE(0x40DCFA, 0x56144A, 0x0), &find_variable_stub, HOOK_CALL).install()->quick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pre_destroy() override
|
||||||
|
{
|
||||||
|
scr_emit_function_hook.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_MODULE(gsc::error)
|
6
src/module/gsc/script_error.hpp
Normal file
6
src/module/gsc/script_error.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
std::optional<std::pair<std::string, std::string>> find_function(const char* pos);
|
||||||
|
}
|
12
src/module/gsc/script_loading.cpp
Normal file
12
src/module/gsc/script_loading.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
|
#include "script_loading.hpp"
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
game::native::ScriptFile* find_script(game::native::XAssetType type, const char* name, int allow_create_default)
|
||||||
|
{
|
||||||
|
return game::native::DB_FindXAssetHeader(type, name, allow_create_default).scriptfile;
|
||||||
|
}
|
||||||
|
}
|
6
src/module/gsc/script_loading.hpp
Normal file
6
src/module/gsc/script_loading.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
game::native::ScriptFile* find_script(game::native::XAssetType type, const char* name, int allow_create_default);
|
||||||
|
}
|
@ -4,9 +4,103 @@
|
|||||||
#include <utils/io.hpp>
|
#include <utils/io.hpp>
|
||||||
|
|
||||||
#include "game/scripting/context.hpp"
|
#include "game/scripting/context.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "game/scripting/functions.hpp"
|
||||||
|
|
||||||
class scripting final : public module
|
#include "scheduler.hpp"
|
||||||
|
#include "scripting.hpp"
|
||||||
|
|
||||||
|
#include "gsc/script_loading.hpp"
|
||||||
|
|
||||||
|
namespace scripting
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
|
||||||
|
std::unordered_map<std::string, std::vector<std::pair<std::string, const char*>>> script_function_table_sort;
|
||||||
|
std::unordered_map<const char*, std::pair<std::string, std::string>> script_function_table_rev;
|
||||||
|
|
||||||
|
std::string current_file;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::uint32_t current_file_id = 0;
|
||||||
|
std::string current_script_file;
|
||||||
|
|
||||||
|
std::string get_token(unsigned int id)
|
||||||
|
{
|
||||||
|
return find_token(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_function_sort(unsigned int id, const char* pos)
|
||||||
|
{
|
||||||
|
std::string filename = current_file;
|
||||||
|
if (current_file_id)
|
||||||
|
{
|
||||||
|
filename = get_token(current_file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!script_function_table_sort.contains(filename))
|
||||||
|
{
|
||||||
|
auto* script = gsc::find_script(game::native::ASSET_TYPE_SCRIPTFILE, current_script_file.data(), false);
|
||||||
|
if (script)
|
||||||
|
{
|
||||||
|
const auto* end = &script->bytecode[script->bytecodeLen];
|
||||||
|
script_function_table_sort[filename].emplace_back("__end__", reinterpret_cast<const char*>(end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto name = scripting::get_token(id);
|
||||||
|
auto& itr = script_function_table_sort[filename];
|
||||||
|
itr.insert(itr.end() - 1, { name, pos });
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_function(const std::string& file, unsigned int id, const char* pos)
|
||||||
|
{
|
||||||
|
const auto name = get_token(id);
|
||||||
|
script_function_table[file][name] = pos;
|
||||||
|
script_function_table_rev[pos] = { file, name };
|
||||||
|
}
|
||||||
|
|
||||||
|
void scr_set_thread_position(unsigned int thread_name, const char* code_pos)
|
||||||
|
{
|
||||||
|
add_function_sort(thread_name, code_pos);
|
||||||
|
|
||||||
|
if (current_file_id)
|
||||||
|
{
|
||||||
|
const auto name = get_token(current_file_id);
|
||||||
|
add_function(name, thread_name, code_pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add_function(current_file, thread_name, code_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::hook::invoke<void>(SELECT_VALUE(0x4845F0, 0x5616D0, 0x0), thread_name, code_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_script(const char* filename)
|
||||||
|
{
|
||||||
|
current_script_file = filename;
|
||||||
|
|
||||||
|
const auto file_id = std::strtol(filename, nullptr, 10);
|
||||||
|
if (file_id)
|
||||||
|
{
|
||||||
|
current_file_id = file_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_file_id = 0;
|
||||||
|
current_file = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::hook::invoke<void>(SELECT_VALUE(0x446850, 0x56B130, 0x0), filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_token(unsigned int id)
|
||||||
|
{
|
||||||
|
return find_token(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
class scripting_class final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
@ -34,6 +128,11 @@ public:
|
|||||||
|
|
||||||
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::is_dedi()) return;
|
||||||
|
|
||||||
|
utils::hook(SELECT_VALUE(0x44690A, 0x56B1EA, 0x0), &scr_set_thread_position, HOOK_CALL).install()->quick();
|
||||||
|
utils::hook(SELECT_VALUE(0x4232A8, 0x561748, 0x0), &process_script, HOOK_CALL).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
@ -90,7 +189,7 @@ private:
|
|||||||
this->scripts_.clear();
|
this->scripts_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_frame()
|
void run_frame() const
|
||||||
{
|
{
|
||||||
for (const auto& script : this->scripts_)
|
for (const auto& script : this->scripts_)
|
||||||
{
|
{
|
||||||
@ -98,7 +197,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch(game::scripting::event* event)
|
void dispatch(game::scripting::event* event) const
|
||||||
{
|
{
|
||||||
for (const auto& script : this->scripts_)
|
for (const auto& script : this->scripts_)
|
||||||
{
|
{
|
||||||
@ -123,13 +222,13 @@ private:
|
|||||||
|
|
||||||
static void start_execution_stub()
|
static void start_execution_stub()
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->start_execution();
|
module_loader::get<scripting_class>()->start_execution();
|
||||||
static_cast<void(*)()>(start_hook_.get_original())();
|
static_cast<void(*)()>(start_hook_.get_original())();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_execution_stub()
|
static void stop_execution_stub()
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->stop_execution();
|
module_loader::get<scripting_class>()->stop_execution();
|
||||||
static_cast<void(*)()>(stop_hook_.get_original())();
|
static_cast<void(*)()>(stop_hook_.get_original())();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,14 +243,12 @@ private:
|
|||||||
|
|
||||||
if (e.name == "touch") return; // Skip that for now
|
if (e.name == "touch") return; // Skip that for now
|
||||||
|
|
||||||
//printf("%X: %s\n", e.entity_id, e.name.data());
|
|
||||||
|
|
||||||
for (auto* value = stack; value->type != game::native::SCRIPT_END; --value)
|
for (auto* value = stack; value->type != game::native::SCRIPT_END; --value)
|
||||||
{
|
{
|
||||||
e.arguments.emplace_back(*value);
|
e.arguments.emplace_back(*value);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_loader::get<scripting>()->dispatch(&e);
|
module_loader::get<scripting_class>()->dispatch(&e);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@ -163,12 +260,15 @@ private:
|
|||||||
|
|
||||||
static int frame_stub(const int a1, const int a2)
|
static int frame_stub(const int a1, const int a2)
|
||||||
{
|
{
|
||||||
module_loader::get<scripting>()->run_frame();
|
module_loader::get<scripting_class>()->run_frame();
|
||||||
return game::native::G_RunFrame(a1, a2);
|
return game::native::G_RunFrame(a1, a2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
utils::hook scripting::start_hook_;
|
utils::hook scripting_class::start_hook_;
|
||||||
utils::hook scripting::stop_hook_;
|
utils::hook scripting_class::stop_hook_;
|
||||||
|
}
|
||||||
|
|
||||||
REGISTER_MODULE(scripting)
|
|
||||||
|
|
||||||
|
REGISTER_MODULE(scripting::scripting_class)
|
||||||
|
12
src/module/scripting.hpp
Normal file
12
src/module/scripting.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace scripting
|
||||||
|
{
|
||||||
|
extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
|
||||||
|
extern std::unordered_map<std::string, std::vector<std::pair<std::string, const char*>>> script_function_table_sort;
|
||||||
|
extern std::unordered_map<const char*, std::pair<std::string, std::string>> script_function_table_rev;
|
||||||
|
|
||||||
|
extern std::string current_file;
|
||||||
|
|
||||||
|
std::string get_token(unsigned int id);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user