filesystem: reverse properly a lot of stuff
This commit is contained in:
parent
cec72268b0
commit
395e27bbe4
@ -8,10 +8,14 @@ namespace dvars
|
||||
|
||||
const game::native::dvar_t** sv_maxclients;
|
||||
|
||||
const game::native::dvar_t** loc_language;
|
||||
|
||||
void initialize()
|
||||
{
|
||||
com_sv_running = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x1769F50, 0x1CEF588));
|
||||
|
||||
sv_maxclients = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x0, 0x21223C0));
|
||||
|
||||
loc_language = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x1BF6938, 0x58D5A90));
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,7 @@ namespace dvars
|
||||
|
||||
extern const game::native::dvar_t** sv_maxclients;
|
||||
|
||||
extern const game::native::dvar_t** loc_language;
|
||||
|
||||
void initialize();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ namespace game
|
||||
{
|
||||
namespace native
|
||||
{
|
||||
Cmd_AddCommand_t Cmd_AddCommand;
|
||||
Cmd_AddCommandInternal_t Cmd_AddCommandInternal;
|
||||
Cmd_RemoveCommand_t Cmd_RemoveCommand;
|
||||
|
||||
Cbuf_AddText_t Cbuf_AddText;
|
||||
@ -63,6 +63,8 @@ namespace game
|
||||
Sys_Error_t Sys_Error;
|
||||
Sys_Milliseconds_t Sys_Milliseconds;
|
||||
Sys_Sleep_t Sys_Sleep;
|
||||
Sys_FreeFileList_t Sys_FreeFileList;
|
||||
Sys_MessageBox_t Sys_MessageBox;
|
||||
|
||||
PMem_AllocFromSource_NoDebug_t PMem_AllocFromSource_NoDebug;
|
||||
|
||||
@ -86,6 +88,7 @@ namespace game
|
||||
XUIDToString_t XUIDToString;
|
||||
|
||||
SEH_LocalizeTextMessage_t SEH_LocalizeTextMessage;
|
||||
SEH_GetLanguageName_t SEH_GetLanguageName;
|
||||
|
||||
CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace;
|
||||
|
||||
@ -103,11 +106,17 @@ namespace game
|
||||
|
||||
FS_Printf_t FS_Printf;
|
||||
FS_ReadFile_t FS_ReadFile;
|
||||
FS_CreatePath_t FS_CreatePath;
|
||||
FS_HandleForFile_t FS_HandleForFile;
|
||||
FS_FCloseFile_t FS_FCloseFile;
|
||||
FS_ListFilteredFiles_t FS_ListFilteredFiles;
|
||||
|
||||
player_die_t player_die;
|
||||
|
||||
LargeLocalResetToMark_t LargeLocalResetToMark;
|
||||
|
||||
Win_LocalizeRef_t Win_LocalizeRef;
|
||||
|
||||
decltype(longjmp)* _longjmp;
|
||||
|
||||
CmdArgs* sv_cmd_args;
|
||||
@ -143,6 +152,9 @@ namespace game
|
||||
searchpath_s** fs_searchpaths;
|
||||
char* fs_gamedir;
|
||||
fileHandleData_t* fsh;
|
||||
int* fs_numServerIwds;
|
||||
int* fs_serverIwds;
|
||||
int* fs_iwdFileCount;
|
||||
int* com_fileAccessed;
|
||||
|
||||
// DS does not have MJPEG thread
|
||||
@ -186,6 +198,23 @@ namespace game
|
||||
gclient_s* g_clients;
|
||||
}
|
||||
|
||||
int Cmd_Argc()
|
||||
{
|
||||
assert(cmd_args->nesting < CMD_MAX_NESTING);
|
||||
return cmd_args->argc[cmd_args->nesting];
|
||||
}
|
||||
|
||||
const char* Cmd_Argv(int argIndex)
|
||||
{
|
||||
assert(cmd_args->nesting < CMD_MAX_NESTING);
|
||||
assert(argIndex >= 0);
|
||||
if (argIndex < cmd_args->argc[cmd_args->nesting])
|
||||
{
|
||||
return cmd_args->argv[cmd_args->nesting][argIndex];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void AddRefToValue(VariableValue* value)
|
||||
{
|
||||
if (value->type == VAR_POINTER)
|
||||
@ -524,9 +553,16 @@ namespace game
|
||||
InterlockedDecrement(&critSect->readCount);
|
||||
}
|
||||
|
||||
void FS_FCloseFile(int h)
|
||||
void Sys_OutOfMemErrorInternal(const char* filename, int line)
|
||||
{
|
||||
reinterpret_cast<void(*)(int)>(SELECT_VALUE(0x415160, 0x5AF170))(h);
|
||||
Sys_EnterCriticalSection(CRITSECT_FATAL_ERROR);
|
||||
|
||||
printf("Out of memory: filename \'%s\', line %d\n", filename, line);
|
||||
const auto* title = Win_LocalizeRef("WIN_OUT_OF_MEM_TITLE");
|
||||
const auto* body = Win_LocalizeRef("WIN_OUT_OF_MEM_BODY");
|
||||
|
||||
Sys_MessageBox(body, title, MB_ICONERROR, 0);
|
||||
std::exit(-1);
|
||||
}
|
||||
|
||||
bool FS_Initialized()
|
||||
@ -534,11 +570,6 @@ namespace game
|
||||
return (*fs_searchpaths != nullptr);
|
||||
}
|
||||
|
||||
int FS_HandleForFile(FsThread thread)
|
||||
{
|
||||
return reinterpret_cast<int(*)(FsThread)>(SELECT_VALUE(0x46B1C0, 0x5AEE50))(thread);
|
||||
}
|
||||
|
||||
int fs_fopen_file_read_for_thread_singleplayer(const char* filename, int* file, FsThread thread)
|
||||
{
|
||||
static DWORD func = 0x627F20;
|
||||
@ -593,11 +624,6 @@ namespace game
|
||||
return fs_fopen_file_read_for_thread_multiplayer(filename, file, thread);
|
||||
}
|
||||
|
||||
int FS_CreatePath(char* OSPath)
|
||||
{
|
||||
return reinterpret_cast<int(*)(char*)>(SELECT_VALUE(0x4F5AB0, 0x5AF060))(OSPath);
|
||||
}
|
||||
|
||||
void FS_CheckFileSystemStarted()
|
||||
{
|
||||
assert(*fs_searchpaths);
|
||||
@ -634,6 +660,34 @@ namespace game
|
||||
Sys_UnlockRead(db_hashCritSect);
|
||||
return asset_entry != nullptr;
|
||||
}
|
||||
|
||||
int SEH_GetCurrentLanguage()
|
||||
{
|
||||
return (*dvars::loc_language)->current.integer;
|
||||
}
|
||||
|
||||
void* Z_Malloc(std::size_t size)
|
||||
{
|
||||
void* buf = std::malloc(size);
|
||||
if (buf)
|
||||
{
|
||||
std::memset(buf, 0, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
printf("Failed to Z_Malloc %u bytes\n", size);
|
||||
Sys_OutOfMemError();
|
||||
}
|
||||
|
||||
bool I_islower(int c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
bool I_isupper(int c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
}
|
||||
|
||||
launcher::mode mode = launcher::mode::none;
|
||||
@ -664,7 +718,7 @@ namespace game
|
||||
|
||||
dvars::initialize();
|
||||
|
||||
native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0));
|
||||
native::Cmd_AddCommandInternal = native::Cmd_AddCommandInternal_t(SELECT_VALUE(0x558820, 0x545DF0));
|
||||
native::Cmd_RemoveCommand = native::Cmd_RemoveCommand_t(SELECT_VALUE(0x443A30, 0x545E20));
|
||||
|
||||
native::Cbuf_AddText = native::Cbuf_AddText_t(SELECT_VALUE(0x457C90, 0x545680));
|
||||
@ -722,6 +776,8 @@ namespace game
|
||||
native::Sys_Error = native::Sys_Error_t(SELECT_VALUE(0x490D90, 0x5CC3B0));
|
||||
native::Sys_Milliseconds = native::Sys_Milliseconds_t(SELECT_VALUE(0x4A1610, 0x5CE740));
|
||||
native::Sys_Sleep = native::Sys_Sleep_t(SELECT_VALUE(0x438600, 0x55F460));
|
||||
native::Sys_FreeFileList = native::Sys_FreeFileList_t(SELECT_VALUE(0x486380, 0x5C4F90));
|
||||
native::Sys_MessageBox = native::Sys_MessageBox_t(SELECT_VALUE(0x4664D0, 0x5CD180));
|
||||
|
||||
native::PMem_AllocFromSource_NoDebug = native::PMem_AllocFromSource_NoDebug_t(SELECT_VALUE(0x449E50, 0x5C15C0));
|
||||
|
||||
@ -753,6 +809,7 @@ namespace game
|
||||
native::XUIDToString = native::XUIDToString_t(SELECT_VALUE(0x4FAA30, 0x55CC20));
|
||||
|
||||
native::SEH_LocalizeTextMessage = native::SEH_LocalizeTextMessage_t(SELECT_VALUE(0x41EA20, 0x57E240));
|
||||
native::SEH_GetLanguageName = native::SEH_GetLanguageName_t(SELECT_VALUE(0x533650, 0x57E5A0));
|
||||
|
||||
native::CM_TransformedCapsuleTrace = native::CM_TransformedCapsuleTrace_t(SELECT_VALUE(0x4F9B80, 0x541340));
|
||||
|
||||
@ -770,11 +827,17 @@ namespace game
|
||||
|
||||
native::FS_Printf = native::FS_Printf_t(SELECT_VALUE(0x421E90, 0x5AF7C0));
|
||||
native::FS_ReadFile = native::FS_ReadFile_t(SELECT_VALUE(0x4D8DF0, 0x5B1FB0));
|
||||
native::FS_CreatePath = native::FS_CreatePath_t(SELECT_VALUE(0x4F5AB0, 0x5AF060));
|
||||
native::FS_HandleForFile = native::FS_HandleForFile_t(SELECT_VALUE(0x46B1C0, 0x5AEE50));
|
||||
native::FS_FCloseFile = native::FS_FCloseFile_t(SELECT_VALUE(0x415160, 0x5AF170));
|
||||
native::FS_ListFilteredFiles = native::FS_ListFilteredFiles_t(SELECT_VALUE(0x41D910, 0x5AFF10));
|
||||
|
||||
native::player_die = native::player_die_t(SELECT_VALUE(0x0, 0x503460));
|
||||
|
||||
native::LargeLocalResetToMark = native::LargeLocalResetToMark_t(SELECT_VALUE(0x524350, 0x5B7150));
|
||||
|
||||
native::Win_LocalizeRef = native::Win_LocalizeRef_t(SELECT_VALUE(0x49D7E0, 0x5CBE90));
|
||||
|
||||
native::_longjmp = reinterpret_cast<decltype(longjmp)*>(SELECT_VALUE(0x73AC20, 0x7363BC));
|
||||
|
||||
native::sv_cmd_args = reinterpret_cast<native::CmdArgs*>(SELECT_VALUE(0x1757218, 0x1CAA998));
|
||||
@ -817,9 +880,12 @@ namespace game
|
||||
native::fs_searchpaths = reinterpret_cast<native::searchpath_s**>(SELECT_VALUE(0x1C2FE78, 0x59BA858));
|
||||
native::fs_gamedir = reinterpret_cast<char*>(SELECT_VALUE(0x1C2B220, 0x59A98F8));
|
||||
native::fsh = reinterpret_cast<native::fileHandleData_t*>(SELECT_VALUE(0x1C2B540, 0x59B5F20));
|
||||
native::fs_numServerIwds = reinterpret_cast<int*>(SELECT_VALUE(0x1C2FE84, 0x59BA864));
|
||||
native::fs_serverIwds = reinterpret_cast<int*>(SELECT_VALUE(0x0, 0x59AAB18));
|
||||
native::fs_iwdFileCount = reinterpret_cast<int*>(SELECT_VALUE(0x1C2fE7C, 0x59BA85C));
|
||||
native::com_fileAccessed = reinterpret_cast<int*>(SELECT_VALUE(0x1C2B328, 0x59A9A04));
|
||||
|
||||
native::threadId = reinterpret_cast<unsigned(*)[native::THREAD_CONTEXT_COUNT]>(SELECT_VALUE(0x18576C8, 0x1D6E448));
|
||||
native::threadId = reinterpret_cast<unsigned int(*)[native::THREAD_CONTEXT_COUNT]>(SELECT_VALUE(0x18576C8, 0x1D6E448));
|
||||
|
||||
native::initialized_0 = reinterpret_cast<int*>(SELECT_VALUE(0x1CE1CA0, 0x5AA3058));
|
||||
native::sys_timeBase = reinterpret_cast<int*>(SELECT_VALUE(0x1CE1C98, 0x5AA3050));
|
||||
|
@ -11,8 +11,8 @@ namespace game
|
||||
{
|
||||
namespace native
|
||||
{
|
||||
typedef void (*Cmd_AddCommand_t)(const char* cmdName, void (*function)(), cmd_function_t* allocedCmd);
|
||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||
typedef void (*Cmd_AddCommandInternal_t)(const char* cmdName, void (*function)(), cmd_function_s* allocedCmd);
|
||||
extern Cmd_AddCommandInternal_t Cmd_AddCommandInternal;
|
||||
|
||||
typedef void (*Cmd_RemoveCommand_t)(const char* cmdName);
|
||||
extern Cmd_RemoveCommand_t Cmd_RemoveCommand;
|
||||
@ -137,6 +137,12 @@ namespace game
|
||||
typedef void (*Sys_Sleep_t)(int msec);
|
||||
extern Sys_Sleep_t Sys_Sleep;
|
||||
|
||||
typedef void (*Sys_FreeFileList_t)(char** list);
|
||||
extern Sys_FreeFileList_t Sys_FreeFileList;
|
||||
|
||||
typedef int (*Sys_MessageBox_t)(const char* lpText, const char* lpCaption, unsigned int uType, int defaultValue);
|
||||
extern Sys_MessageBox_t Sys_MessageBox;
|
||||
|
||||
typedef void* (*PMem_AllocFromSource_NoDebug_t)(unsigned int size, unsigned int alignment, unsigned int type, int source);
|
||||
extern PMem_AllocFromSource_NoDebug_t PMem_AllocFromSource_NoDebug;
|
||||
|
||||
@ -182,6 +188,9 @@ namespace game
|
||||
typedef char* (*SEH_LocalizeTextMessage_t)(const char* pszInputBuffer, const char* pszMessageType, msgLocErrType_t errType);
|
||||
extern SEH_LocalizeTextMessage_t SEH_LocalizeTextMessage;
|
||||
|
||||
typedef const char* (*SEH_GetLanguageName_t)(int iLanguage);
|
||||
extern SEH_GetLanguageName_t SEH_GetLanguageName;
|
||||
|
||||
typedef void (*CM_TransformedCapsuleTrace_t)(trace_t* results, const float* start, const float* end,
|
||||
const Bounds* bounds, const Bounds* capsule, int contents,
|
||||
const float* origin, const float* angles);
|
||||
@ -216,12 +225,27 @@ namespace game
|
||||
typedef int (*FS_ReadFile_t)(const char* qpath, char** buffer);
|
||||
extern FS_ReadFile_t FS_ReadFile;
|
||||
|
||||
typedef int (*FS_CreatePath_t)(char* OSPath);
|
||||
extern FS_CreatePath_t FS_CreatePath;
|
||||
|
||||
typedef int (*FS_HandleForFile_t)(FsThread thread);
|
||||
extern FS_HandleForFile_t FS_HandleForFile;
|
||||
|
||||
typedef void (*FS_FCloseFile_t)(int h);
|
||||
extern FS_FCloseFile_t FS_FCloseFile;
|
||||
|
||||
typedef char** (*FS_ListFilteredFiles_t)(searchpath_s* searchPath, const char* path, const char* extension, const char* filter, FsListBehavior_e behavior, int* numfiles, int allocTrackType);
|
||||
extern FS_ListFilteredFiles_t FS_ListFilteredFiles;
|
||||
|
||||
typedef void (*player_die_t)(gentity_s* self, const gentity_s* inflictor, gentity_s* attacker, int damage, int meansOfDeath, const Weapon* iWeapon, bool isAlternate, const float* vDir, const hitLocation_t hitLoc, int psTimeOffset);
|
||||
extern player_die_t player_die;
|
||||
|
||||
typedef void (*LargeLocalResetToMark_t)(int markPos);
|
||||
extern LargeLocalResetToMark_t LargeLocalResetToMark;
|
||||
|
||||
typedef const char* (*Win_LocalizeRef_t)(const char* ref);
|
||||
extern Win_LocalizeRef_t Win_LocalizeRer;
|
||||
|
||||
extern decltype(longjmp)* _longjmp;
|
||||
|
||||
constexpr auto CMD_MAX_NESTING = 8;
|
||||
@ -261,6 +285,9 @@ namespace game
|
||||
extern searchpath_s** fs_searchpaths;
|
||||
extern char* fs_gamedir;
|
||||
extern fileHandleData_t* fsh;
|
||||
extern int* fs_numServerIwds;
|
||||
extern int* fs_serverIwds;
|
||||
extern int* fs_iwdFileCount;
|
||||
extern int* com_fileAccessed;
|
||||
|
||||
extern unsigned int(*threadId)[THREAD_CONTEXT_COUNT];
|
||||
@ -322,6 +349,9 @@ namespace game
|
||||
extern gclient_s* g_clients;
|
||||
}
|
||||
|
||||
int Cmd_Argc();
|
||||
const char* Cmd_Argv(int argIndex);
|
||||
|
||||
void AddRefToValue(VariableValue* value);
|
||||
|
||||
void* MT_Alloc(int numBytes, int type);
|
||||
@ -361,16 +391,23 @@ namespace game
|
||||
bool Sys_IsStreamThread();
|
||||
bool Sys_IsRenderThread();
|
||||
bool Sys_IsServerThread();
|
||||
void Sys_LockRead(FastCriticalSection* critSect);
|
||||
void Sys_UnlockRead(FastCriticalSection* critSect);
|
||||
void Sys_OutOfMemErrorInternal(const char* filename, int line);
|
||||
|
||||
void FS_FCloseFile(int h);
|
||||
bool FS_Initialized();
|
||||
int FS_HandleForFile(FsThread thread);
|
||||
int FS_FOpenFileReadForThread(const char* filename, int* file, FsThread thread);
|
||||
int FS_CreatePath(char* OSPath);
|
||||
void FS_CheckFileSystemStarted();
|
||||
|
||||
XAssetEntry* DB_FindXAssetEntry(XAssetType type, const char* name);
|
||||
int DB_XAssetExists(XAssetType type, const char* name);
|
||||
|
||||
int SEH_GetCurrentLanguage();
|
||||
|
||||
void* Z_Malloc(std::size_t size);
|
||||
|
||||
bool I_islower(int c);
|
||||
bool I_isupper(int c);
|
||||
}
|
||||
|
||||
bool is_mp();
|
||||
@ -378,3 +415,5 @@ namespace game
|
||||
|
||||
void initialize(launcher::mode mode);
|
||||
}
|
||||
|
||||
#define Sys_OutOfMemError() game::native::Sys_OutOfMemErrorInternal(__FILE__, __LINE__)
|
||||
|
@ -483,9 +483,15 @@ namespace game
|
||||
PMEM_SOURCE_SCRIPT,
|
||||
};
|
||||
|
||||
struct cmd_function_t
|
||||
enum FsListBehavior_e
|
||||
{
|
||||
cmd_function_t* next;
|
||||
FS_LIST_PURE_ONLY,
|
||||
FS_LIST_ALL,
|
||||
};
|
||||
|
||||
struct cmd_function_s
|
||||
{
|
||||
cmd_function_s* next;
|
||||
const char* name;
|
||||
const char* autoCompleteDir;
|
||||
const char* autoCompleteExt;
|
||||
@ -1289,6 +1295,7 @@ namespace game
|
||||
enum CriticalSection
|
||||
{
|
||||
CRITSECT_CONSOLE = 0x0,
|
||||
CRITSECT_FATAL_ERROR = 0x12,
|
||||
CRITSECT_CBUF = 0x1F,
|
||||
CRITSECT_COUNT = 0x27,
|
||||
};
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include <std_include.hpp>
|
||||
#include <loader/module_loader.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#include "game/game.hpp"
|
||||
|
||||
class ceg final : public module
|
||||
#include "ceg.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
|
||||
void ceg::post_load()
|
||||
{
|
||||
public:
|
||||
void post_load() override
|
||||
{
|
||||
// Only SP has CEG
|
||||
// CEG in MP has accidentally been removed due to CVE-2018-10718
|
||||
if (!game::is_sp()) return;
|
||||
@ -18,7 +18,7 @@ public:
|
||||
signature.add({
|
||||
"\x56\xE8\x00\x00\x00\x00\x8B\xF0\xE8\x00\x00\x00\x00\x50\x56\xE8", "xx????xxx????xxx", [](char* address)
|
||||
{
|
||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||
utils::hook::set<std::uint32_t>(address, 0xC301B0);
|
||||
}
|
||||
});
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
signature.add({
|
||||
"\x55\x8B\xEC\x80\x7D\x08\x00\x75\x55", "xxxxxx?xx", [](char* address)
|
||||
{
|
||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||
utils::hook::set<std::uint32_t>(address, 0xC301B0);
|
||||
}
|
||||
});
|
||||
|
||||
@ -34,7 +34,7 @@ public:
|
||||
signature.add({
|
||||
"\x55\x8B\xEC\x83\xEC\x18\x53\x56\x57\xE8\x00\x00\x00\x00", "xxxxxxxxxx????", [](char* address)
|
||||
{
|
||||
utils::hook::set<BYTE>(address, 0xC3);
|
||||
utils::hook::set<std::uint8_t>(address, 0xC3);
|
||||
}
|
||||
});
|
||||
|
||||
@ -42,7 +42,7 @@ public:
|
||||
signature.add({
|
||||
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\x53\x56\x57\x8B\x3D", "xxxxx??xxxxxxx", [](char* address)
|
||||
{
|
||||
utils::hook::set<DWORD>(address, 0xC301B0);
|
||||
utils::hook::set<std::uint32_t>(address, 0xC301B0);
|
||||
}
|
||||
});
|
||||
|
||||
@ -51,7 +51,7 @@ public:
|
||||
"\x55\x8B\xEC\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x64\xFF\x35\x00\x00\x00\x00\x64\x89\x25\x00\x00\x00\x00\xE8",
|
||||
"xxxx????x????xxx????xxx????x", [](char* address)
|
||||
{
|
||||
utils::hook::set<BYTE>(address, 0xC3);
|
||||
utils::hook::set<std::uint8_t>(address, 0xC3);
|
||||
}
|
||||
});
|
||||
|
||||
@ -67,8 +67,8 @@ public:
|
||||
|
||||
// hkcr guid check 2
|
||||
signature.add({
|
||||
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06", "xxxxx????x????xxxx", [
|
||||
](char* address)
|
||||
"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0\x75\x06",
|
||||
"xxxxx????x????xxxx", [](char* address)
|
||||
{
|
||||
utils::hook::nop(address + 0x9, 5); // Call
|
||||
utils::hook::nop(address + 0x10, 2); // Jump
|
||||
@ -78,8 +78,8 @@ public:
|
||||
signature.process();
|
||||
|
||||
// Checks on startup
|
||||
utils::hook::set<DWORD>(0x402ED0, 0xC301B0);
|
||||
utils::hook::set<DWORD>(0x4b9280, 0xC301B0);
|
||||
utils::hook::set<std::uint32_t>(0x402ED0, 0xC301B0);
|
||||
utils::hook::set<std::uint32_t>(0x4b9280, 0xC301B0);
|
||||
|
||||
// Function fixup
|
||||
utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick();
|
||||
@ -88,8 +88,7 @@ public:
|
||||
utils::hook(0x493B81, 0x493BFC, HOOK_JUMP).install()->quick();
|
||||
|
||||
// CEG uninitialization
|
||||
utils::hook::set<BYTE>(0x527110, 0xC3);
|
||||
}
|
||||
};
|
||||
utils::hook::set<std::uint8_t>(0x527110, 0xC3);
|
||||
}
|
||||
|
||||
REGISTER_MODULE(ceg)
|
||||
|
7
src/module/ceg.hpp
Normal file
7
src/module/ceg.hpp
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
class ceg final : public module
|
||||
{
|
||||
public:
|
||||
void post_load() override;
|
||||
};
|
@ -85,7 +85,7 @@ std::string command::params_sv::join(const int index) const
|
||||
|
||||
void command::add_raw(const char* name, void (*callback)())
|
||||
{
|
||||
game::native::Cmd_AddCommand(name, callback, allocator.allocate<game::native::cmd_function_t>());
|
||||
game::native::Cmd_AddCommandInternal(name, callback, allocator.allocate<game::native::cmd_function_s>());
|
||||
}
|
||||
|
||||
void command::add(const char* name, const std::function<void(const params&)>& callback)
|
||||
|
@ -64,3 +64,9 @@ private:
|
||||
|
||||
static void add_sp_commands();
|
||||
};
|
||||
|
||||
#define Cmd_AddCommand(cmd_name, function) \
|
||||
{ \
|
||||
static game::native::cmd_function_s function##_VAR; \
|
||||
game::native::Cmd_AddCommandInternal(cmd_name, function, &function##_VAR); \
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ std::string console::format(va_list* ap, const char* message)
|
||||
const auto count = vsnprintf_s(buffer, _TRUNCATE, message, *ap);
|
||||
|
||||
if (count < 0) return {};
|
||||
return {buffer, static_cast<size_t>(count)};
|
||||
return {buffer, static_cast<std::size_t>(count)};
|
||||
}
|
||||
|
||||
REGISTER_MODULE(console)
|
||||
|
@ -4,29 +4,33 @@
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#include "command.hpp"
|
||||
#include "file_system.hpp"
|
||||
#include "log_file.hpp"
|
||||
|
||||
static utils::hook::detour sys_default_install_path_hook;
|
||||
|
||||
static const game::native::dvar_t** fs_homepath;
|
||||
static const game::native::dvar_t** fs_debug;
|
||||
|
||||
static FILE* file_for_handle(const int f)
|
||||
namespace
|
||||
{
|
||||
utils::hook::detour sys_default_install_path_hook;
|
||||
|
||||
const game::native::dvar_t** fs_homepath;
|
||||
const game::native::dvar_t** fs_debug;
|
||||
const game::native::dvar_t** fs_ignoreLocalized;
|
||||
|
||||
FILE* file_for_handle(const int f)
|
||||
{
|
||||
assert(!game::native::fsh[f].zipFile);
|
||||
assert(game::native::fsh[f].handleFiles.file.o);
|
||||
|
||||
return game::native::fsh[f].handleFiles.file.o;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int file_write(const void* ptr, const unsigned int len, FILE* stream)
|
||||
{
|
||||
unsigned int file_write(const void* ptr, const unsigned int len, FILE* stream)
|
||||
{
|
||||
return std::fwrite(ptr, sizeof(char), len, stream);
|
||||
}
|
||||
}
|
||||
|
||||
static FILE* file_open_append_text(const char* filename)
|
||||
{
|
||||
FILE* file_open_append_text(const char* filename)
|
||||
{
|
||||
errno = 0;
|
||||
auto* file = std::fopen(filename, "at");
|
||||
if (file)
|
||||
@ -36,10 +40,10 @@ static FILE* file_open_append_text(const char* filename)
|
||||
|
||||
log_file::info("Couldn't open file: %s %s\n", filename, std::strerror(errno));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static FILE* file_open_write_binary(const char* filename)
|
||||
{
|
||||
FILE* file_open_write_binary(const char* filename)
|
||||
{
|
||||
errno = 0;
|
||||
auto* file = std::fopen(filename, "wb");
|
||||
if (file)
|
||||
@ -49,10 +53,10 @@ static FILE* file_open_write_binary(const char* filename)
|
||||
|
||||
log_file::info("Couldn't open file: %s %s\n", filename, std::strerror(errno));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_separators(char* path)
|
||||
{
|
||||
void replace_separators(char* path)
|
||||
{
|
||||
char* src, * dst;
|
||||
|
||||
bool was_sep = false;
|
||||
@ -74,10 +78,10 @@ static void replace_separators(char* path)
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void build_os_path_for_thread(const char* base, const char* game, const char* qpath, char* ospath, game::native::FsThread thread)
|
||||
{
|
||||
void build_os_path_for_thread(const char* base, const char* game, const char* qpath, char* ospath, game::native::FsThread thread)
|
||||
{
|
||||
assert(base);
|
||||
assert(qpath);
|
||||
assert(ospath);
|
||||
@ -113,10 +117,10 @@ static void build_os_path_for_thread(const char* base, const char* game, const c
|
||||
|
||||
std::memcpy(ospath + len_base + 2 + len_game, qpath, len_qpath + 1);
|
||||
replace_separators(ospath);
|
||||
}
|
||||
}
|
||||
|
||||
static game::native::FsThread get_current_thread()
|
||||
{
|
||||
game::native::FsThread get_current_thread()
|
||||
{
|
||||
if (game::native::Sys_IsMainThread())
|
||||
{
|
||||
return game::native::FS_THREAD_MAIN;
|
||||
@ -138,15 +142,15 @@ static game::native::FsThread get_current_thread()
|
||||
return game::native::FS_THREAD_SERVER;
|
||||
}
|
||||
return game::native::FS_THREAD_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_for_file_current_thread()
|
||||
{
|
||||
int handle_for_file_current_thread()
|
||||
{
|
||||
return game::native::FS_HandleForFile(get_current_thread());
|
||||
}
|
||||
}
|
||||
|
||||
static int open_file_append(const char* filename)
|
||||
{
|
||||
int open_file_append(const char* filename)
|
||||
{
|
||||
char ospath[game::native::MAX_OSPATH]{};
|
||||
|
||||
game::native::FS_CheckFileSystemStarted();
|
||||
@ -181,10 +185,10 @@ static int open_file_append(const char* filename)
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_handle_and_open_file(const char* filename, const char* ospath, game::native::FsThread thread)
|
||||
{
|
||||
int get_handle_and_open_file(const char* filename, const char* ospath, game::native::FsThread thread)
|
||||
{
|
||||
auto* fp = file_open_write_binary(ospath);
|
||||
if (!fp)
|
||||
{
|
||||
@ -199,10 +203,10 @@ static int get_handle_and_open_file(const char* filename, const char* ospath, ga
|
||||
game::native::fsh[f].handleSync = 0;
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
static int open_file_write_to_dir_for_thread(const char* filename, const char* dir, const char* osbasepath, game::native::FsThread thread)
|
||||
{
|
||||
int open_file_write_to_dir_for_thread(const char* filename, const char* dir, const char* osbasepath, game::native::FsThread thread)
|
||||
{
|
||||
char ospath[game::native::MAX_OSPATH]{};
|
||||
|
||||
game::native::FS_CheckFileSystemStarted();
|
||||
@ -221,17 +225,319 @@ static int open_file_write_to_dir_for_thread(const char* filename, const char* d
|
||||
}
|
||||
|
||||
return get_handle_and_open_file(filename, ospath, thread);
|
||||
}
|
||||
}
|
||||
|
||||
static int open_file_write(const char* filename)
|
||||
{
|
||||
int open_file_write(const char* filename)
|
||||
{
|
||||
return open_file_write_to_dir_for_thread(filename, game::native::fs_gamedir, "", game::native::FS_THREAD_MAIN);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* sys_default_install_path_stub()
|
||||
{
|
||||
void convert_path(char* s)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
if (*s == '\\' || *s == ':')
|
||||
{
|
||||
*s = '/';
|
||||
}
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
int path_cmp(const char* s1, const char* s2)
|
||||
{
|
||||
int c1;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = *s1++;
|
||||
int c2 = *s2++;
|
||||
|
||||
if (game::native::I_islower(c1))
|
||||
{
|
||||
c1 -= ('a' - 'A');
|
||||
}
|
||||
if (game::native::I_islower(c2))
|
||||
{
|
||||
c2 -= ('a' - 'A');
|
||||
}
|
||||
if (c1 == '\\' || c1 == ':')
|
||||
{
|
||||
c1 = '/';
|
||||
}
|
||||
if (c2 == '\\' || c2 == ':')
|
||||
{
|
||||
c2 = '/';
|
||||
}
|
||||
|
||||
if (c1 < c2)
|
||||
{
|
||||
return -1; // strings not equal
|
||||
}
|
||||
|
||||
if (c1 > c2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
} while (c1);
|
||||
|
||||
return 0; // strings are equal
|
||||
}
|
||||
|
||||
void sort_file_list(char** filelist, int numfiles)
|
||||
{
|
||||
int j;
|
||||
|
||||
const char** sortedlist = static_cast<const char**>(game::native::Z_Malloc((numfiles * sizeof(*sortedlist)) + 4));
|
||||
sortedlist[0] = nullptr;
|
||||
auto numsortedfiles = 0;
|
||||
for (auto i = 0; i < numfiles; ++i)
|
||||
{
|
||||
for (j = 0; j < numsortedfiles; j++)
|
||||
{
|
||||
if (path_cmp(filelist[i], sortedlist[j]) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto k = numsortedfiles; k > j; --k)
|
||||
{
|
||||
sortedlist[k] = sortedlist[k - 1];
|
||||
}
|
||||
sortedlist[j] = filelist[i];
|
||||
++numsortedfiles;
|
||||
}
|
||||
|
||||
std::memcpy(filelist, sortedlist, numfiles * sizeof(*filelist));
|
||||
std::free(sortedlist);
|
||||
}
|
||||
|
||||
int use_search_path(game::native::searchpath_s* pSearch)
|
||||
{
|
||||
if (pSearch->bLocalized && (*fs_ignoreLocalized)->current.enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pSearch->bLocalized && pSearch->language != game::native::SEH_GetCurrentLanguage())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iwd_is_pure(game::native::iwd_t* iwd)
|
||||
{
|
||||
if (*game::native::fs_numServerIwds)
|
||||
{
|
||||
for (auto i = 0; i < *game::native::fs_numServerIwds; ++i)
|
||||
{
|
||||
if (iwd->checksum == game::native::fs_serverIwds[i])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char** list_files(const char* path, const char* extension, game::native::FsListBehavior_e behavior, int* numfiles, int allocTrackType)
|
||||
{
|
||||
return game::native::FS_ListFilteredFiles(*game::native::fs_searchpaths, path, extension, nullptr, behavior, numfiles, allocTrackType);
|
||||
}
|
||||
|
||||
void display_path(bool b_language_cull)
|
||||
{
|
||||
auto i_language = game::native::SEH_GetCurrentLanguage();
|
||||
const auto* psz_language_name = game::native::SEH_GetLanguageName(i_language);
|
||||
log_file::info("Current language: %s\n", psz_language_name);
|
||||
if ((*fs_ignoreLocalized)->current.enabled)
|
||||
{
|
||||
log_file::info(" localized assets are being ignored\n");
|
||||
}
|
||||
|
||||
log_file::info("Current search path:\n");
|
||||
for (auto* s = *game::native::fs_searchpaths; s; s = s->next)
|
||||
{
|
||||
if (b_language_cull && !use_search_path(s))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->iwd)
|
||||
{
|
||||
log_file::info("%s (%i files)\n", s->iwd->iwdFilename, s->iwd->numfiles);
|
||||
if (s->bLocalized)
|
||||
{
|
||||
log_file::info(" localized assets iwd file for %s\n", game::native::SEH_GetLanguageName(s->language));
|
||||
}
|
||||
|
||||
if (*game::native::fs_numServerIwds)
|
||||
{
|
||||
if (iwd_is_pure(s->iwd))
|
||||
{
|
||||
log_file::info(" on the pure list\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_file::info(" not on the pure list\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_file::info("%s/%s\n", s->dir->path, s->dir->gamedir);
|
||||
if (s->bLocalized)
|
||||
{
|
||||
log_file::info(" localized assets game folder for %s\n", game::native::SEH_GetLanguageName(s->language));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_file::info("\nFile Handles:\n");
|
||||
for (int i = 1; i < 64; ++i)
|
||||
{
|
||||
if (game::native::fsh[i].handleFiles.file.o)
|
||||
{
|
||||
log_file::info("handle %i: %s\n", i, game::native::fsh[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool touch_file(const char* name)
|
||||
{
|
||||
*game::native::com_fileAccessed = 1;
|
||||
auto ret = game::native::FS_FOpenFileReadForThread(name, nullptr, game::native::FS_THREAD_MAIN);
|
||||
return ret != -1;
|
||||
}
|
||||
|
||||
void path_f()
|
||||
{
|
||||
display_path(true);
|
||||
}
|
||||
|
||||
void full_path_f()
|
||||
{
|
||||
display_path(false);
|
||||
}
|
||||
|
||||
void dir_f()
|
||||
{
|
||||
const char* path;
|
||||
const char* extension;
|
||||
int ndirs;
|
||||
|
||||
if (game::native::Cmd_Argc() < 2 || game::native::Cmd_Argc() > 3)
|
||||
{
|
||||
log_file::info("usage: dir <directory> [extension]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (game::native::Cmd_Argc() == 2)
|
||||
{
|
||||
path = game::native::Cmd_Argv(1);
|
||||
extension = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = game::native::Cmd_Argv(1);
|
||||
extension = game::native::Cmd_Argv(2);
|
||||
}
|
||||
|
||||
log_file::info("Directory of %s %s\n", path, extension);
|
||||
log_file::info("---------------\n");
|
||||
|
||||
auto** dirnames = list_files(path, extension, game::native::FS_LIST_PURE_ONLY, &ndirs, 3);
|
||||
|
||||
for (int i = 0; i < ndirs; ++i)
|
||||
{
|
||||
log_file::info("%s\n", dirnames[i]);
|
||||
}
|
||||
|
||||
game::native::Sys_FreeFileList(dirnames);
|
||||
}
|
||||
|
||||
void new_dir_f()
|
||||
{
|
||||
int ndirs;
|
||||
|
||||
if (game::native::Cmd_Argc() < 2)
|
||||
{
|
||||
log_file::info("usage: fdir <filter>\n");
|
||||
log_file::info("example: fdir *q3dm*.bsp\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* filter = game::native::Cmd_Argv(1);
|
||||
|
||||
log_file::info("---------------\n");
|
||||
|
||||
auto** dirnames = game::native::FS_ListFilteredFiles(*game::native::fs_searchpaths, "", "", filter, game::native::FS_LIST_PURE_ONLY, &ndirs, 3);
|
||||
sort_file_list(dirnames, ndirs);
|
||||
|
||||
for (auto i = 0; i < ndirs; ++i)
|
||||
{
|
||||
convert_path(dirnames[i]);
|
||||
log_file::info("%s\n", dirnames[i]);
|
||||
}
|
||||
log_file::info("%d files listed\n", ndirs);
|
||||
game::native::Sys_FreeFileList(dirnames);
|
||||
}
|
||||
|
||||
void touch_file_f()
|
||||
{
|
||||
if (game::native::Cmd_Argc() != 2)
|
||||
{
|
||||
log_file::info("Usage: touchFile <file>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
touch_file(game::native::Cmd_Argv(1));
|
||||
}
|
||||
|
||||
void add_commands()
|
||||
{
|
||||
Cmd_AddCommand("path", path_f);
|
||||
Cmd_AddCommand("fullpath", full_path_f);
|
||||
Cmd_AddCommand("dir", dir_f);
|
||||
Cmd_AddCommand("fdir", new_dir_f);
|
||||
Cmd_AddCommand("touchFile", touch_file_f);
|
||||
}
|
||||
|
||||
void fs_startup_stub(char* game_name)
|
||||
{
|
||||
log_file::info("----- FS_Startup -----\n");
|
||||
|
||||
utils::hook::invoke<void>(0x5B1070, game_name);
|
||||
|
||||
add_commands();
|
||||
display_path(true);
|
||||
|
||||
log_file::info("----------------------\n");
|
||||
log_file::info("%d files in iwd files\n", *game::native::fs_iwdFileCount);
|
||||
}
|
||||
|
||||
void fs_shutdown_stub(int closemfp)
|
||||
{
|
||||
utils::hook::invoke<void>(0x5B0D30, closemfp);
|
||||
|
||||
game::native::Cmd_RemoveCommand("path");
|
||||
game::native::Cmd_RemoveCommand("fullpath");
|
||||
game::native::Cmd_RemoveCommand("dir");
|
||||
game::native::Cmd_RemoveCommand("fdir");
|
||||
game::native::Cmd_RemoveCommand("touchFile");
|
||||
}
|
||||
|
||||
const char* sys_default_install_path_stub()
|
||||
{
|
||||
static auto current_path = std::filesystem::current_path().string();
|
||||
return current_path.data();
|
||||
}
|
||||
}
|
||||
|
||||
int file_system::open_file_by_mode(const char* qpath, int* f, game::native::fsMode_t mode)
|
||||
@ -329,6 +635,16 @@ void file_system::post_load()
|
||||
{
|
||||
fs_homepath = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x1C2B538, 0x59ADD18));
|
||||
fs_debug = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x1C2B32C, 0x59A9A08));
|
||||
fs_ignoreLocalized = reinterpret_cast<const game::native::dvar_t**>(SELECT_VALUE(0x1C2B21C, 0x59A99F8));
|
||||
|
||||
if (game::is_mp())
|
||||
{
|
||||
utils::hook(0x5B20AA, fs_startup_stub, HOOK_CALL).install()->quick(); // FS_InitFilesystem
|
||||
utils::hook(0x5B2148, fs_startup_stub, HOOK_CALL).install()->quick(); // FS_Restart
|
||||
|
||||
utils::hook(0x5557CC, fs_shutdown_stub, HOOK_CALL).install()->quick(); // Com_Quit_f
|
||||
utils::hook(0x5B2115, fs_shutdown_stub, HOOK_CALL).install()->quick(); // FS_Restart
|
||||
}
|
||||
|
||||
// Make open-iw5 work outside of the game directory
|
||||
sys_default_install_path_hook.create(SELECT_VALUE(0x487E50, 0x5C4A80), &sys_default_install_path_stub);
|
||||
|
Loading…
Reference in New Issue
Block a user