2019-09-24 10:30:08 +02:00
|
|
|
#include <std_include.hpp>
|
|
|
|
#include "game.hpp"
|
|
|
|
|
|
|
|
namespace game
|
|
|
|
{
|
|
|
|
namespace native
|
|
|
|
{
|
|
|
|
Cmd_AddCommand_t Cmd_AddCommand;
|
|
|
|
|
2022-03-10 19:50:36 +00:00
|
|
|
Cmd_RemoveCommand_t Cmd_RemoveCommand;
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
Com_Error_t Com_Error;
|
|
|
|
|
|
|
|
DB_LoadXAssets_t DB_LoadXAssets;
|
|
|
|
|
2022-03-11 20:43:11 +00:00
|
|
|
Dvar_RegisterBool_t Dvar_RegisterBool;
|
|
|
|
|
2022-03-14 23:54:41 +00:00
|
|
|
Dvar_RegisterFloat_t Dvar_RegisterFloat;
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
Dvar_SetIntByName_t Dvar_SetIntByName;
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
|
|
|
|
|
|
|
G_RunFrame_t G_RunFrame;
|
|
|
|
|
|
|
|
MSG_ReadData_t MSG_ReadData;
|
|
|
|
|
|
|
|
MT_AllocIndex_t MT_AllocIndex;
|
|
|
|
|
|
|
|
RemoveRefToValue_t RemoveRefToValue;
|
|
|
|
|
|
|
|
SL_GetStringOfSize_t SL_GetStringOfSize;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
Scr_AddEntityNum_t Scr_AddEntityNum;
|
|
|
|
|
|
|
|
Scr_Notify_t Scr_Notify;
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
Sys_ShowConsole_t Sys_ShowConsole;
|
|
|
|
|
|
|
|
VM_Notify_t VM_Notify;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
BG_NetDataChecksum_t BG_NetDataChecksum;
|
|
|
|
|
|
|
|
LiveStorage_GetPersistentDataDefVersion_t LiveStorage_GetPersistentDataDefVersion;
|
|
|
|
|
|
|
|
LiveStorage_GetPersistentDataDefFormatChecksum_t LiveStorage_GetPersistentDataDefFormatChecksum;
|
|
|
|
|
|
|
|
SV_DirectConnect_t SV_DirectConnect;
|
|
|
|
|
|
|
|
SV_ClientEnterWorld_t SV_ClientEnterWorld;
|
|
|
|
|
|
|
|
SV_Cmd_TokenizeString_t SV_Cmd_TokenizeString;
|
|
|
|
|
|
|
|
SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString;
|
|
|
|
|
2022-03-10 19:50:36 +00:00
|
|
|
SV_GameSendServerCommand_t SV_GameSendServerCommand;
|
|
|
|
|
|
|
|
SV_SendServerCommand_t SV_SendServerCommand;
|
|
|
|
|
2022-03-10 12:32:22 +00:00
|
|
|
XUIDToString_t XUIDToString;
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
SEH_LocalizeTextMessage_t SEH_LocalizeTextMessage;
|
|
|
|
|
2022-03-11 20:43:11 +00:00
|
|
|
PM_WeaponUseAmmo_t PM_WeaponUseAmmo;
|
|
|
|
|
2022-03-15 10:10:15 +00:00
|
|
|
CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace;
|
|
|
|
|
2022-03-15 14:48:19 +00:00
|
|
|
Weapon_RocketLauncher_Fire_t Weapon_RocketLauncher_Fire;
|
|
|
|
|
|
|
|
PM_playerTrace_t PM_playerTrace;
|
|
|
|
|
|
|
|
PM_trace_t PM_trace;
|
|
|
|
|
2022-03-14 23:54:41 +00:00
|
|
|
Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand;
|
|
|
|
|
2022-03-15 15:41:51 +00:00
|
|
|
Com_Quit_f_t Com_Quit_f;
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
decltype(longjmp)* _longjmp;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
CmdArgs* sv_cmd_args;
|
|
|
|
CmdArgs* cmd_args;
|
2019-09-24 10:30:08 +02:00
|
|
|
|
|
|
|
short* scrVarGlob;
|
|
|
|
char** scrMemTreePub;
|
|
|
|
char* scrMemTreeGlob;
|
|
|
|
|
|
|
|
scrVmPub_t* scr_VmPub;
|
|
|
|
|
|
|
|
scr_call_t* scr_instanceFunctions;
|
|
|
|
scr_call_t* scr_globalFunctions;
|
|
|
|
|
|
|
|
unsigned int* levelEntityId;
|
|
|
|
|
|
|
|
int* g_script_error_level;
|
|
|
|
jmp_buf* g_script_error;
|
|
|
|
|
|
|
|
scr_classStruct_t* g_classMap;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
int* svs_clientCount;
|
|
|
|
|
2022-03-10 19:50:36 +00:00
|
|
|
gentity_s* g_entities;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
namespace mp
|
|
|
|
{
|
|
|
|
client_t* svs_clients;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace dedi
|
|
|
|
{
|
|
|
|
client_t* svs_clients;
|
|
|
|
}
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
namespace sp
|
|
|
|
{
|
|
|
|
sp::gentity_s* g_entities;
|
|
|
|
}
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
void AddRefToValue(VariableValue* value)
|
|
|
|
{
|
|
|
|
if (value->type == SCRIPT_OBJECT)
|
|
|
|
{
|
|
|
|
++scrVarGlob[4 * value->u.entityId];
|
|
|
|
}
|
|
|
|
else if ((value->type & ~1) == SCRIPT_STRING)
|
|
|
|
{
|
|
|
|
static const auto size = is_sp() ? 16 : 12;
|
|
|
|
const auto ref_count = reinterpret_cast<unsigned volatile *>(*scrMemTreePub + size * value
|
|
|
|
->u.stringValue);
|
|
|
|
InterlockedIncrement(ref_count);
|
|
|
|
}
|
|
|
|
else if (value->type == SCRIPT_VECTOR)
|
|
|
|
{
|
|
|
|
if (!*PBYTE(value->u.vectorValue - 1))
|
|
|
|
{
|
|
|
|
++*PWORD(value->u.vectorValue - 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) unsigned int conbuf_append_text_dedicated(const char* message)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x53C790;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov ecx, message
|
|
|
|
call func
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Conbuf_AppendText(const char* message)
|
|
|
|
{
|
2019-09-24 11:46:47 +02:00
|
|
|
if (is_dedi())
|
2019-09-24 10:30:08 +02:00
|
|
|
{
|
|
|
|
conbuf_append_text_dedicated(message);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(const char*)>(SELECT_VALUE(0x4C84E0, 0x5CF610, 0))(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) unsigned int find_variable_dedicated(unsigned int parentId, unsigned int name)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x4E7ED0;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, name
|
|
|
|
mov ecx, parentId
|
|
|
|
call func
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int FindVariable(const unsigned int parentId, const unsigned int name)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
return find_variable_dedicated(parentId, name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return reinterpret_cast<unsigned int(*)(unsigned int, unsigned int)> //
|
|
|
|
(SELECT_VALUE(0x4C4E70, 0x5651F0, 0x0))(parentId, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) VariableValue get_entity_field_value_dedicated(unsigned int classnum, int entnum, int _offset)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x4F1400;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push _offset
|
|
|
|
push entnum
|
|
|
|
mov ecx, classnum
|
|
|
|
call func
|
|
|
|
add esp, 8h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VariableValue GetEntityFieldValue(const unsigned int classnum, const int entnum, const int offset)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
return get_entity_field_value_dedicated(classnum, entnum, offset);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return reinterpret_cast<VariableValue(*)(unsigned int, int, int)> //
|
|
|
|
(SELECT_VALUE(0x530E30, 0x56AF20, 0x0))(classnum, entnum, offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void* MT_Alloc(const int numBytes, const int type)
|
|
|
|
{
|
|
|
|
return scrMemTreeGlob + 12 * size_t(MT_AllocIndex(numBytes, type));
|
|
|
|
}
|
|
|
|
|
2022-03-10 12:32:22 +00:00
|
|
|
__declspec(naked) dvar_t* dvar_find_malleable_var(const char* dvarName)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x531320;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov edi, dvarName
|
|
|
|
call func
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dvar_t* Dvar_FindVar(const char* dvarName)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
return dvar_find_malleable_var(dvarName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return reinterpret_cast<dvar_t*(*)(const char*)>
|
|
|
|
(SELECT_VALUE(0x539550, 0x5BDCC0, 0x0))(dvarName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
const float* Scr_AllocVector(const float* v)
|
|
|
|
{
|
|
|
|
const auto mem = static_cast<DWORD*>(MT_Alloc(16, 2));
|
|
|
|
*mem = 0;
|
|
|
|
|
|
|
|
const auto array = reinterpret_cast<float*>(mem + 1);
|
|
|
|
array[0] = v[0];
|
|
|
|
array[1] = v[1];
|
|
|
|
array[2] = v[2];
|
|
|
|
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scr_ClearOutParams()
|
|
|
|
{
|
|
|
|
const auto num_params = scr_VmPub->outparamcount;
|
|
|
|
for (unsigned int i = num_params; i > 0; --i)
|
|
|
|
{
|
|
|
|
const auto value = scr_VmPub->top[i - 1];
|
|
|
|
RemoveRefToValue(value.type, value.u);
|
|
|
|
}
|
|
|
|
|
|
|
|
scr_VmPub->top -= num_params;
|
|
|
|
}
|
|
|
|
|
|
|
|
scr_entref_t Scr_GetEntityIdRef(const unsigned int id)
|
|
|
|
{
|
|
|
|
static auto class_array = reinterpret_cast<DWORD*>(SELECT_VALUE(0x19AFC84, 0x1E72184, 0x1D3C804));
|
|
|
|
static auto ent_array = reinterpret_cast<WORD*>(SELECT_VALUE(0x19AFC82, 0x1E72182, 0x1D3C802));
|
|
|
|
|
|
|
|
scr_entref_t result{};
|
|
|
|
result.raw.classnum = static_cast<unsigned short>(class_array[2 * id]) >> 8;
|
|
|
|
result.raw.entnum = ent_array[4 * id];
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
scr_call_t Scr_GetFunc(const unsigned int index)
|
|
|
|
{
|
|
|
|
if (index > 0x1C7)
|
|
|
|
{
|
|
|
|
return scr_instanceFunctions[index];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return scr_globalFunctions[index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int stringValue,
|
|
|
|
unsigned int paramcount)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x56B5E0;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, paramcount
|
|
|
|
push stringValue
|
|
|
|
push id
|
|
|
|
call func
|
|
|
|
add esp, 8h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void scr_notify_id_singleplayer(unsigned int id, unsigned int stringValue,
|
|
|
|
unsigned int paramcount)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x610980;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, paramcount
|
|
|
|
push stringValue
|
|
|
|
push id
|
|
|
|
call func
|
|
|
|
add esp, 8h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount)
|
|
|
|
{
|
|
|
|
if (is_mp())
|
|
|
|
{
|
|
|
|
return scr_notify_id_multiplayer(id, stringValue, paramcount);
|
|
|
|
}
|
|
|
|
else if (is_sp())
|
|
|
|
{
|
|
|
|
return scr_notify_id_singleplayer(id, stringValue, paramcount);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-24 11:46:47 +02:00
|
|
|
return reinterpret_cast<void(*)(unsigned int, unsigned int, unsigned int)>(0x4EFAA0)(
|
|
|
|
id, stringValue, paramcount);
|
2019-09-24 10:30:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) int scr_set_object_field_dedicated(unsigned int classnum, int entnum, int _offset)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x4B15C0;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov ecx, _offset
|
|
|
|
mov eax, entnum
|
|
|
|
push classnum
|
|
|
|
call func
|
|
|
|
add esp, 4h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Scr_SetObjectField(const unsigned int classnum, const int entnum, const int offset)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
return scr_set_object_field_dedicated(classnum, entnum, offset);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return reinterpret_cast<int(*)(unsigned int, int, int)> //
|
|
|
|
(SELECT_VALUE(0x42CAD0, 0x52BCC0, 0x0))(classnum, entnum, offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 12:32:22 +00:00
|
|
|
__declspec(naked) void scr_add_string_dedi(const char* value)
|
2022-03-10 01:12:16 +00:00
|
|
|
{
|
|
|
|
static DWORD func = 0x4F1010;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov edi, value
|
|
|
|
call func
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scr_AddString(const char* value)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
scr_add_string_dedi(value);
|
|
|
|
}
|
|
|
|
else if (is_mp())
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(const char*)>
|
|
|
|
(0x56AC00)(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
const char* SL_ConvertToString(const unsigned int stringValue)
|
|
|
|
{
|
|
|
|
if (!stringValue) return nullptr;
|
|
|
|
|
|
|
|
static const auto size = is_sp() ? 16 : 12;
|
|
|
|
return *scrMemTreePub + size * stringValue + 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int SL_GetString(const char* str, const unsigned int user)
|
|
|
|
{
|
|
|
|
return SL_GetStringOfSize(str, user, strlen(str) + 1, 7);
|
|
|
|
}
|
2022-03-10 01:12:16 +00:00
|
|
|
|
2022-03-10 13:54:10 +00:00
|
|
|
__declspec(naked) void sv_send_client_game_state_mp(mp::client_t* /*client*/)
|
2022-03-10 01:12:16 +00:00
|
|
|
{
|
2022-03-10 15:11:26 +00:00
|
|
|
static DWORD func = 0x570FC0;
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
__asm
|
|
|
|
{
|
2022-03-10 13:54:10 +00:00
|
|
|
pushad
|
|
|
|
|
|
|
|
mov esi, [esp + 0x20 + 0x4]
|
2022-03-10 15:11:26 +00:00
|
|
|
call func
|
2022-03-10 13:54:10 +00:00
|
|
|
|
|
|
|
popad
|
2022-03-10 19:50:36 +00:00
|
|
|
retn
|
2022-03-10 01:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SV_SendClientGameState(mp::client_t* client)
|
|
|
|
{
|
|
|
|
if (is_mp())
|
|
|
|
{
|
|
|
|
sv_send_client_game_state_mp(client);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int SV_IsTestClient(int clientNum)
|
|
|
|
{
|
|
|
|
assert(clientNum < *svs_clientCount);
|
|
|
|
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
return dedi::svs_clients[clientNum].bIsTestClient;
|
|
|
|
}
|
|
|
|
else if (is_mp())
|
|
|
|
{
|
|
|
|
return mp::svs_clients[clientNum].bIsTestClient;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SV_DropClient(mp::client_t* drop, const char* reason, bool tellThem)
|
|
|
|
{
|
|
|
|
if (is_mp())
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(mp::client_t*, const char*, bool)>
|
|
|
|
(0x570980)(drop, reason, tellThem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sv_drop_all_bots_mp()
|
|
|
|
{
|
|
|
|
for (auto i = 0; i < *svs_clientCount; i++)
|
|
|
|
{
|
|
|
|
if (mp::svs_clients[i].header.state != CS_FREE
|
|
|
|
&& mp::svs_clients[i].header.netchan.remoteAddress.type == NA_BOT)
|
|
|
|
{
|
2022-03-10 12:32:22 +00:00
|
|
|
SV_DropClient(&mp::svs_clients[i], "EXE_TIMEDOUT", true);
|
2022-03-10 01:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SV_DropAllBots()
|
|
|
|
{
|
|
|
|
if (is_mp())
|
|
|
|
{
|
|
|
|
sv_drop_all_bots_mp();
|
|
|
|
}
|
|
|
|
}
|
2022-03-10 12:32:22 +00:00
|
|
|
|
2022-03-10 19:50:36 +00:00
|
|
|
__declspec(naked) void client_command_dedi(int clientNum)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x47EA40;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov edi, clientNum
|
|
|
|
call func
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClientCommand(int clientNum)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
client_command_dedi(clientNum);
|
|
|
|
}
|
|
|
|
else if (is_mp())
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(int)>(0x502CB0)(clientNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 12:32:22 +00:00
|
|
|
int GetProtocolVersion()
|
|
|
|
{
|
|
|
|
return 0x507C;
|
|
|
|
}
|
2022-03-10 13:54:10 +00:00
|
|
|
|
|
|
|
void NetAdr_SetType(netadr_s* addr, netadrtype_t type)
|
|
|
|
{
|
|
|
|
addr->type = type;
|
|
|
|
}
|
2022-03-10 19:50:36 +00:00
|
|
|
|
|
|
|
__declspec(naked) void cbuf_add_text_dedi(LocalClientNum_t localClientNum, const char* text)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x4CB5D0;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, text
|
|
|
|
push localClientNum
|
|
|
|
call func
|
|
|
|
add esp, 4h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Cbuf_AddText(LocalClientNum_t localClientNum, const char* text)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
cbuf_add_text_dedi(localClientNum, text);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(LocalClientNum_t, const char*)>
|
|
|
|
(SELECT_VALUE(0x457C90, 0x545680, 0x0))(localClientNum, text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void teleport_player_dedi(gentity_s* player, float* origin, float* angles)
|
|
|
|
{
|
|
|
|
static DWORD func = 0x48B840;
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, player
|
|
|
|
mov ecx, origin
|
|
|
|
push angles
|
|
|
|
call func
|
|
|
|
add esp, 4h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TeleportPlayer(gentity_s* player, float* origin, float* angles)
|
|
|
|
{
|
|
|
|
if (is_dedi())
|
|
|
|
{
|
|
|
|
teleport_player_dedi(player, origin, angles);
|
|
|
|
}
|
|
|
|
else if (is_mp())
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(gentity_s*, float*, float*)>
|
|
|
|
(0x50D840)(player, origin, angles);
|
|
|
|
}
|
|
|
|
}
|
2022-03-11 14:30:00 +00:00
|
|
|
|
2022-03-11 16:06:14 +00:00
|
|
|
// SP takes one extra argument, all possible values are undocumented
|
|
|
|
void CG_GameMessage(LocalClientNum_t localClientNum, const char* msg, int flags)
|
2022-03-11 14:30:00 +00:00
|
|
|
{
|
|
|
|
if (is_mp())
|
|
|
|
{
|
|
|
|
reinterpret_cast<void(*)(LocalClientNum_t, const char*)>(0x456DC0)(localClientNum, msg);
|
|
|
|
}
|
|
|
|
else if (is_sp())
|
|
|
|
{
|
2022-03-11 16:06:14 +00:00
|
|
|
reinterpret_cast<void(*)(LocalClientNum_t, const char*, int)>(0x4228A0)(localClientNum, msg, flags);
|
2022-03-11 14:30:00 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-24 10:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
launcher::mode mode = launcher::mode::none;
|
|
|
|
|
|
|
|
launcher::mode get_mode()
|
|
|
|
{
|
2019-09-24 11:46:47 +02:00
|
|
|
if (mode == launcher::mode::none)
|
2019-09-24 10:30:08 +02:00
|
|
|
{
|
|
|
|
throw std::runtime_error("Launcher mode not valid. Something must be wrong.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_mp()
|
|
|
|
{
|
|
|
|
return get_mode() == launcher::mode::multiplayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_sp()
|
|
|
|
{
|
|
|
|
return get_mode() == launcher::mode::singleplayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_dedi()
|
|
|
|
{
|
|
|
|
return get_mode() == launcher::mode::server;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initialize(const launcher::mode _mode)
|
|
|
|
{
|
|
|
|
mode = _mode;
|
|
|
|
|
|
|
|
native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0, 0));
|
|
|
|
|
2022-03-10 19:50:36 +00:00
|
|
|
native::Cmd_RemoveCommand = native::Cmd_RemoveCommand_t(SELECT_VALUE(0x443A30, 0x545E20, 0x4CC060));
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450, 0x4D93F0));
|
|
|
|
|
|
|
|
native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770));
|
|
|
|
|
2022-03-11 20:43:11 +00:00
|
|
|
native::Dvar_RegisterBool = native::Dvar_RegisterBool_t(SELECT_VALUE(0x4914D0, 0x5BE9F0, 0x0));
|
|
|
|
|
2022-03-14 23:54:41 +00:00
|
|
|
native::Dvar_RegisterFloat = native::Dvar_RegisterFloat_t(SELECT_VALUE(0x4F9CC0, 0x5BEA80, 0x0));
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::Dvar_SetIntByName = native::Dvar_SetIntByName_t(SELECT_VALUE(0x5396B0, 0x5BF560, 0x0));
|
|
|
|
|
2019-09-24 11:46:47 +02:00
|
|
|
native::Dvar_SetFromStringByName = native::Dvar_SetFromStringByName_t(
|
|
|
|
SELECT_VALUE(0x4DD090, 0x5BF740, 0x518DF0));
|
2019-09-24 10:30:08 +02:00
|
|
|
|
|
|
|
native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60));
|
|
|
|
|
|
|
|
native::MSG_ReadData = native::MSG_ReadData_t(SELECT_VALUE(0, 0x5592A0, 0));
|
|
|
|
|
|
|
|
native::MT_AllocIndex = native::MT_AllocIndex_t(SELECT_VALUE(0x4B9610, 0x562080, 0x4E6C30));
|
|
|
|
|
|
|
|
native::RemoveRefToValue = native::RemoveRefToValue_t(SELECT_VALUE(0x477EA0, 0x565730, 0x4E8A40));
|
|
|
|
|
|
|
|
native::SL_GetStringOfSize = native::SL_GetStringOfSize_t(SELECT_VALUE(0x4E13F0, 0x564650, 0x4E7490));
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
native::Scr_AddEntityNum = native::Scr_AddEntityNum_t(SELECT_VALUE(0x0, 0x56ABC0, 0x4EA2F0));
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::Scr_Notify = native::Scr_Notify_t(SELECT_VALUE(0x4895B0, 0x52B190, 0x0));
|
2022-03-10 01:12:16 +00:00
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0));
|
|
|
|
|
|
|
|
native::VM_Notify = native::VM_Notify_t(SELECT_VALUE(0x610200, 0x569720, 0x4EF450));
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
native::BG_NetDataChecksum = native::BG_NetDataChecksum_t(SELECT_VALUE(0x0, 0x41BB20, 0x0));
|
|
|
|
|
|
|
|
native::LiveStorage_GetPersistentDataDefVersion = native::LiveStorage_GetPersistentDataDefVersion_t(
|
|
|
|
SELECT_VALUE(0x0, 0x548D60, 0x4D0390));
|
|
|
|
|
|
|
|
native::LiveStorage_GetPersistentDataDefFormatChecksum = native::LiveStorage_GetPersistentDataDefFormatChecksum_t(
|
|
|
|
SELECT_VALUE(0x0, 0x548D80, 0x4D03D0));
|
|
|
|
|
|
|
|
native::SV_DirectConnect = native::SV_DirectConnect_t(SELECT_VALUE(0x0, 0x572750, 0x4F74C0));
|
|
|
|
|
|
|
|
native::SV_ClientEnterWorld = native::SV_ClientEnterWorld_t(SELECT_VALUE(0x0, 0x571100, 0x0));
|
|
|
|
|
|
|
|
native::SV_Cmd_TokenizeString = native::SV_Cmd_TokenizeString_t(SELECT_VALUE(0x0, 0x545D40, 0x0));
|
|
|
|
|
|
|
|
native::SV_Cmd_EndTokenizedString = native::SV_Cmd_EndTokenizedString_t(SELECT_VALUE(0x0, 0x545D70, 0x0));
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::SV_GameSendServerCommand = native::SV_GameSendServerCommand_t(SELECT_VALUE(0x402130, 0x573220, 0x0));
|
2022-03-10 19:50:36 +00:00
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::SV_SendServerCommand = native::SV_SendServerCommand_t(SELECT_VALUE(0x4F6990, 0x575DE0, 0x4FD5A0));
|
2022-03-10 19:50:36 +00:00
|
|
|
|
2022-03-10 12:32:22 +00:00
|
|
|
native::XUIDToString = native::XUIDToString_t(SELECT_VALUE(0x4FAA30, 0x55CC20, 0x0));
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::SEH_LocalizeTextMessage = native::SEH_LocalizeTextMessage_t(
|
|
|
|
SELECT_VALUE(0x41EA20, 0x57E240, 0x0));
|
2022-03-11 20:43:11 +00:00
|
|
|
|
|
|
|
native::PM_WeaponUseAmmo = native::PM_WeaponUseAmmo_t(SELECT_VALUE(0x463F80, 0x42E930, 0x0));
|
2022-03-11 14:30:00 +00:00
|
|
|
|
2022-03-15 10:10:15 +00:00
|
|
|
native::CM_TransformedCapsuleTrace = native::CM_TransformedCapsuleTrace_t(
|
|
|
|
SELECT_VALUE(0x4F9B80, 0x541340, 0x0));
|
|
|
|
|
2022-03-15 14:48:19 +00:00
|
|
|
native::Weapon_RocketLauncher_Fire = native::Weapon_RocketLauncher_Fire_t(
|
|
|
|
SELECT_VALUE(0x48C920, 0x5305D0, 0x0));
|
|
|
|
|
|
|
|
native::PM_playerTrace = native::PM_playerTrace_t(SELECT_VALUE(0x4CE600, 0x421F00, 0x0));
|
|
|
|
|
|
|
|
native::PM_trace = native::PM_trace_t(SELECT_VALUE(0x544BF0, 0x41CEB0, 0x0));
|
|
|
|
|
2022-03-14 23:54:41 +00:00
|
|
|
native::Cmd_ExecuteSingleCommand = native::Cmd_ExecuteSingleCommand_t(
|
|
|
|
SELECT_VALUE(0x4D6960, 0x5462B0, 0x4CC360));
|
|
|
|
|
2022-03-15 15:41:51 +00:00
|
|
|
native::Com_Quit_f = native::Com_Quit_f_t(SELECT_VALUE(0x4F48B0, 0x5556B0, 0x4D95B0));
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
native::_longjmp = reinterpret_cast<decltype(longjmp)*>(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558));
|
|
|
|
|
2022-03-11 14:30:00 +00:00
|
|
|
native::sv_cmd_args = reinterpret_cast<native::CmdArgs*>(SELECT_VALUE(0x1757218, 0x1CAA998, 0x1B5E7D8));
|
2022-03-10 01:12:16 +00:00
|
|
|
native::cmd_args = reinterpret_cast<native::CmdArgs*>(SELECT_VALUE(0x1750750, 0x1C978D0, 0x1B455F8));
|
2019-09-24 10:30:08 +02:00
|
|
|
|
|
|
|
native::scrVarGlob = reinterpret_cast<short*>(SELECT_VALUE(0x19AFC80, 0x1E72180, 0x1D3C800));
|
|
|
|
native::scrMemTreePub = reinterpret_cast<char**>(SELECT_VALUE(0x196FB00, 0x1E32000, 0x1C152A4));
|
|
|
|
native::scrMemTreeGlob = reinterpret_cast<char*>(SELECT_VALUE(0x186DA00, 0x1D6FF00, 0x1C16600));
|
|
|
|
|
|
|
|
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
|
|
|
|
|
2019-09-24 11:46:47 +02:00
|
|
|
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
|
|
|
|
));
|
2019-09-24 10:30:08 +02:00
|
|
|
|
|
|
|
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_classMap = reinterpret_cast<native::scr_classStruct_t*>(SELECT_VALUE(0x92D140, 0x8B4300, 0x7C0408));
|
|
|
|
|
2022-03-10 01:12:16 +00:00
|
|
|
native::svs_clientCount = reinterpret_cast<int*>(SELECT_VALUE(0x0, 0x4B5CF8C, 0x4A12E8C));
|
|
|
|
|
2019-09-24 10:30:08 +02:00
|
|
|
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
2022-03-10 01:12:16 +00:00
|
|
|
|
|
|
|
native::mp::svs_clients = reinterpret_cast<native::mp::client_t*>(0x4B5CF90);
|
|
|
|
native::dedi::svs_clients = reinterpret_cast<native::dedi::client_t*>(0x4A12E90);
|
2022-03-10 19:50:36 +00:00
|
|
|
|
|
|
|
native::g_entities = reinterpret_cast<native::gentity_s*>(SELECT_VALUE(0, 0x1A66E28, 0x191B900));
|
2022-03-11 14:30:00 +00:00
|
|
|
native::sp::g_entities = reinterpret_cast<native::sp::gentity_s*>(0x1197AD8);
|
2019-09-24 10:30:08 +02:00
|
|
|
}
|
|
|
|
}
|