complete reverse of dvardump & dvarlist
This commit is contained in:
parent
5ac7a59eba
commit
6424fd291d
@ -9,6 +9,7 @@ namespace game
|
|||||||
Cmd_RemoveCommand_t Cmd_RemoveCommand;
|
Cmd_RemoveCommand_t Cmd_RemoveCommand;
|
||||||
|
|
||||||
Com_Error_t Com_Error;
|
Com_Error_t Com_Error;
|
||||||
|
Com_Filter_t Com_Filter;
|
||||||
|
|
||||||
DB_LoadXAssets_t DB_LoadXAssets;
|
DB_LoadXAssets_t DB_LoadXAssets;
|
||||||
|
|
||||||
@ -19,7 +20,10 @@ namespace game
|
|||||||
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
||||||
Dvar_SetString_t Dvar_SetString;
|
Dvar_SetString_t Dvar_SetString;
|
||||||
|
|
||||||
|
Dvar_ForEach_t Dvar_ForEach;
|
||||||
|
|
||||||
Dvar_DisplayableValue_t Dvar_DisplayableValue;
|
Dvar_DisplayableValue_t Dvar_DisplayableValue;
|
||||||
|
Dvar_DisplayableLatchedValue_t Dvar_DisplayableLatchedValue;
|
||||||
|
|
||||||
G_RunFrame_t G_RunFrame;
|
G_RunFrame_t G_RunFrame;
|
||||||
G_GetWeaponForName_t G_GetWeaponForName;
|
G_GetWeaponForName_t G_GetWeaponForName;
|
||||||
@ -127,6 +131,11 @@ namespace game
|
|||||||
int* dvarCount;
|
int* dvarCount;
|
||||||
dvar_t** sortedDvars;
|
dvar_t** sortedDvars;
|
||||||
|
|
||||||
|
int Vec4Compare(const float* a, const float* b)
|
||||||
|
{
|
||||||
|
return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
|
||||||
|
}
|
||||||
|
|
||||||
namespace mp
|
namespace mp
|
||||||
{
|
{
|
||||||
SV_GetGuid_t SV_GetGuid;
|
SV_GetGuid_t SV_GetGuid;
|
||||||
@ -977,6 +986,7 @@ namespace game
|
|||||||
native::Cmd_RemoveCommand = native::Cmd_RemoveCommand_t(SELECT_VALUE(0x443A30, 0x545E20, 0x4CC060));
|
native::Cmd_RemoveCommand = native::Cmd_RemoveCommand_t(SELECT_VALUE(0x443A30, 0x545E20, 0x4CC060));
|
||||||
|
|
||||||
native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450, 0x4D93F0));
|
native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450, 0x4D93F0));
|
||||||
|
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));
|
||||||
|
|
||||||
@ -988,7 +998,10 @@ namespace game
|
|||||||
SELECT_VALUE(0x4DD090, 0x5BF740, 0x518DF0));
|
SELECT_VALUE(0x4DD090, 0x5BF740, 0x518DF0));
|
||||||
native::Dvar_SetString = native::Dvar_SetString_t(SELECT_VALUE(0x540570, 0x5BF3E0, 0x0));
|
native::Dvar_SetString = native::Dvar_SetString_t(SELECT_VALUE(0x540570, 0x5BF3E0, 0x0));
|
||||||
|
|
||||||
|
native::Dvar_ForEach = native::Dvar_ForEach_t(SELECT_VALUE(0x536720, 0x5BFFB0, 0x0));
|
||||||
|
|
||||||
native::Dvar_DisplayableValue = native::Dvar_DisplayableValue_t(SELECT_VALUE(0x4AB1D0, 0x5BD260, 0x0));
|
native::Dvar_DisplayableValue = native::Dvar_DisplayableValue_t(SELECT_VALUE(0x4AB1D0, 0x5BD260, 0x0));
|
||||||
|
native::Dvar_DisplayableLatchedValue = native::Dvar_DisplayableLatchedValue_t(SELECT_VALUE(0x464F50, 0x5BD290, 0x0));
|
||||||
|
|
||||||
native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60));
|
native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60));
|
||||||
native::G_GetWeaponForName = native::G_GetWeaponForName_t(SELECT_VALUE(0x495E40, 0x531070, 0x0));
|
native::G_GetWeaponForName = native::G_GetWeaponForName_t(SELECT_VALUE(0x495E40, 0x531070, 0x0));
|
||||||
|
@ -20,6 +20,9 @@ namespace game
|
|||||||
typedef void (*Com_Error_t)(errorParm_t code, const char* fmt, ...);
|
typedef void (*Com_Error_t)(errorParm_t code, const char* fmt, ...);
|
||||||
extern Com_Error_t Com_Error;
|
extern Com_Error_t Com_Error;
|
||||||
|
|
||||||
|
typedef bool (*Com_Filter_t)(const char* filter, const char* name, int casesensitive);
|
||||||
|
extern Com_Filter_t Com_Filter;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -40,9 +43,15 @@ namespace game
|
|||||||
typedef void (*Dvar_SetString_t)(const dvar_t* dvar, const char* value);
|
typedef void (*Dvar_SetString_t)(const dvar_t* dvar, const char* value);
|
||||||
extern Dvar_SetString_t Dvar_SetString;
|
extern Dvar_SetString_t Dvar_SetString;
|
||||||
|
|
||||||
|
typedef void (*Dvar_ForEach_t)(void (*callback)(const dvar_t*, void*), void* userData);
|
||||||
|
extern Dvar_ForEach_t Dvar_ForEach;
|
||||||
|
|
||||||
typedef const char* (*Dvar_DisplayableValue_t)(const dvar_t* dvar);
|
typedef const char* (*Dvar_DisplayableValue_t)(const dvar_t* dvar);
|
||||||
extern Dvar_DisplayableValue_t Dvar_DisplayableValue;
|
extern Dvar_DisplayableValue_t Dvar_DisplayableValue;
|
||||||
|
|
||||||
|
typedef const char* (*Dvar_DisplayableLatchedValue_t)(const dvar_t* dvar);
|
||||||
|
extern Dvar_DisplayableLatchedValue_t Dvar_DisplayableLatchedValue;
|
||||||
|
|
||||||
typedef int (*G_RunFrame_t)(int, int);
|
typedef int (*G_RunFrame_t)(int, int);
|
||||||
extern G_RunFrame_t G_RunFrame;
|
extern G_RunFrame_t G_RunFrame;
|
||||||
|
|
||||||
@ -212,6 +221,8 @@ namespace game
|
|||||||
template <typename T, typename R>
|
template <typename T, typename R>
|
||||||
constexpr auto VectorScale(T v, R s, T out) { out[0] = v[0] * s; out[1] = v[1] * s; out[2] = v[2] * s; }
|
constexpr auto VectorScale(T v, R s, T out) { out[0] = v[0] * s; out[1] = v[1] * s; out[2] = v[2] * s; }
|
||||||
|
|
||||||
|
int Vec4Compare(const float* a, const float* b);
|
||||||
|
|
||||||
namespace mp
|
namespace mp
|
||||||
{
|
{
|
||||||
typedef char* (*SV_GetGuid_t)(int clientNum);
|
typedef char* (*SV_GetGuid_t)(int clientNum);
|
||||||
|
@ -611,6 +611,7 @@ namespace game
|
|||||||
DVAR_CODINFO = 1 << 3,
|
DVAR_CODINFO = 1 << 3,
|
||||||
DVAR_SCRIPTINFO = 1 << 4,
|
DVAR_SCRIPTINFO = 1 << 4,
|
||||||
DVAR_SAVED = 1 << 6,
|
DVAR_SAVED = 1 << 6,
|
||||||
|
DVAR_USERINFO = 1 << 9,
|
||||||
DVAR_SERVERINFO = 1 << 10,
|
DVAR_SERVERINFO = 1 << 10,
|
||||||
DVAR_INIT = 1 << 11,
|
DVAR_INIT = 1 << 11,
|
||||||
DVAR_ROM = 1 << 13,
|
DVAR_ROM = 1 << 13,
|
||||||
@ -629,6 +630,8 @@ namespace game
|
|||||||
DVAR_TYPE_STRING = 0x7,
|
DVAR_TYPE_STRING = 0x7,
|
||||||
DVAR_TYPE_COLOR = 0x8,
|
DVAR_TYPE_COLOR = 0x8,
|
||||||
DVAR_TYPE_FLOAT_3_COLOR = 0x9,
|
DVAR_TYPE_FLOAT_3_COLOR = 0x9,
|
||||||
|
|
||||||
|
DVAR_TYPE_COUNT = 0xA
|
||||||
};
|
};
|
||||||
|
|
||||||
union DvarValue
|
union DvarValue
|
||||||
@ -680,10 +683,17 @@ namespace game
|
|||||||
DvarValue latched;
|
DvarValue latched;
|
||||||
DvarValue reset;
|
DvarValue reset;
|
||||||
DvarLimits domain;
|
DvarLimits domain;
|
||||||
bool (__cdecl *domainFunc)(dvar_t*, DvarValue);
|
bool (*domainFunc)(dvar_t*, DvarValue);
|
||||||
dvar_t* hashNext;
|
dvar_t* hashNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DvarDumpInfo
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int channel;
|
||||||
|
const char* match;
|
||||||
|
};
|
||||||
|
|
||||||
struct Bounds
|
struct Bounds
|
||||||
{
|
{
|
||||||
float midPoint[3];
|
float midPoint[3];
|
||||||
|
@ -77,6 +77,10 @@ public:
|
|||||||
|
|
||||||
signature.process();
|
signature.process();
|
||||||
|
|
||||||
|
// Checks on startup
|
||||||
|
utils::hook::set<DWORD>(0x402ED0, 0xC301B0);
|
||||||
|
utils::hook::set<DWORD>(0x4b9280, 0xC301B0);
|
||||||
|
|
||||||
// Function fixup
|
// Function fixup
|
||||||
utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick();
|
utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <utils/io.hpp>
|
#include <utils/io.hpp>
|
||||||
|
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "log_file.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
utils::memory::allocator command::allocator_;
|
utils::memory::allocator command::allocator_;
|
||||||
@ -369,33 +368,6 @@ void command::post_load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
add("quit", game::native::Com_Quit_f);
|
add("quit", game::native::Com_Quit_f);
|
||||||
add("dvarDump", [](const params& params)
|
|
||||||
{
|
|
||||||
if (params.size() < 2)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string file_name = "userraw/";
|
|
||||||
file_name.append(params.get(1));
|
|
||||||
if (!file_name.ends_with(".txt"))
|
|
||||||
{
|
|
||||||
file_name.append(".txt");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i = 0; i < *game::native::dvarCount; ++i)
|
|
||||||
{
|
|
||||||
const auto* dvar = game::native::sortedDvars[i];
|
|
||||||
|
|
||||||
if (dvar)
|
|
||||||
{
|
|
||||||
const auto* line = utils::string::va("%s \"%s\"\r\n", dvar->name, game::native::Dvar_DisplayableValue(dvar));
|
|
||||||
utils::io::write_file(file_name, line, i != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_file::info("%i dvars\n", *game::native::dvarCount);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (game::is_mp())
|
if (game::is_mp())
|
||||||
{
|
{
|
||||||
|
205
src/module/dvar.cpp
Normal file
205
src/module/dvar.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include <loader/module_loader.hpp>
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
|
#include "command.hpp"
|
||||||
|
#include "log_file.hpp"
|
||||||
|
#include "dvar.hpp"
|
||||||
|
|
||||||
|
int dvar::values_equal(unsigned char type, game::native::DvarValue val0, game::native::DvarValue val1)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case game::native::DVAR_TYPE_BOOL:
|
||||||
|
return val0.enabled == val1.enabled;
|
||||||
|
case game::native::DVAR_TYPE_FLOAT:
|
||||||
|
return val0.value == val1.value;
|
||||||
|
case game::native::DVAR_TYPE_FLOAT_2:
|
||||||
|
return val0.vector[0] == val1.vector[0] && val0.vector[1] == val1.vector[1];
|
||||||
|
case game::native::DVAR_TYPE_FLOAT_3:
|
||||||
|
case game::native::DVAR_TYPE_FLOAT_3_COLOR:
|
||||||
|
return val0.vector[0] == val1.vector[0] && val0.vector[1] == val1.vector[1] &&
|
||||||
|
val0.vector[2] == val1.vector[2] && val0.vector[3] == val1.vector[3];
|
||||||
|
case game::native::DVAR_TYPE_FLOAT_4:
|
||||||
|
return game::native::Vec4Compare(val0.vector, val1.vector);
|
||||||
|
case game::native::DVAR_TYPE_INT:
|
||||||
|
return val0.integer == val1.integer;
|
||||||
|
case game::native::DVAR_TYPE_ENUM:
|
||||||
|
return val0.integer == val1.integer;
|
||||||
|
case game::native::DVAR_TYPE_STRING:
|
||||||
|
assert(val0.string);
|
||||||
|
assert(val1.string);
|
||||||
|
return std::strcmp(val0.string, val1.string) == 0;
|
||||||
|
case game::native::DVAR_TYPE_COLOR:
|
||||||
|
return val0.integer == val1.integer;
|
||||||
|
default:
|
||||||
|
assert(0 && "unhandled dvar type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dvar::has_latched_value(const game::native::dvar_t* dvar)
|
||||||
|
{
|
||||||
|
return values_equal(dvar->type, dvar->current, dvar->latched) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::list_single(const game::native::dvar_t* dvar, void* user_data)
|
||||||
|
{
|
||||||
|
if ((user_data != nullptr) && !game::native::Com_Filter(static_cast<const char*>(user_data), dvar->name, 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_SERVERINFO)
|
||||||
|
{
|
||||||
|
log_file::info("S");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_USERINFO)
|
||||||
|
{
|
||||||
|
log_file::info("U");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_ROM)
|
||||||
|
{
|
||||||
|
log_file::info("R");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_INIT)
|
||||||
|
{
|
||||||
|
log_file::info("I");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_ARCHIVE)
|
||||||
|
{
|
||||||
|
log_file::info("A");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_LATCH)
|
||||||
|
{
|
||||||
|
log_file::info("L");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvar->flags & game::native::DVAR_CHEAT)
|
||||||
|
{
|
||||||
|
log_file::info("C");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_file::info(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
log_file::info(" %s \"%s\"\n", dvar->name, game::native::Dvar_DisplayableValue(dvar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::com_dvar_dump_single(const game::native::dvar_t* dvar, void* user_data)
|
||||||
|
{
|
||||||
|
char message[2048];
|
||||||
|
|
||||||
|
auto* dumpInfo = static_cast<game::native::DvarDumpInfo*>(user_data);
|
||||||
|
|
||||||
|
++dumpInfo->count;
|
||||||
|
if (dumpInfo->match && !game::native::Com_Filter(dumpInfo->match, dvar->name, 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_latched_value(dvar))
|
||||||
|
{
|
||||||
|
sprintf_s(message, " %s \"%s\" -- latched \"%s\"\n", dvar->name, game::native::Dvar_DisplayableValue(dvar), game::native::Dvar_DisplayableLatchedValue(dvar));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf_s(message, " %s \"%s\"\n", dvar->name, game::native::Dvar_DisplayableValue(dvar));
|
||||||
|
}
|
||||||
|
|
||||||
|
log_file::info("%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::com_dvar_dump(int channel, const char* match)
|
||||||
|
{
|
||||||
|
game::native::DvarDumpInfo dump_info;
|
||||||
|
char summary[128];
|
||||||
|
|
||||||
|
if (!log_file::com_logfile->current.integer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_file::info("=============================== DVAR DUMP ========================================\n");
|
||||||
|
dump_info.count = 0;
|
||||||
|
dump_info.channel = channel;
|
||||||
|
dump_info.match = match;
|
||||||
|
game::native::Dvar_ForEach(com_dvar_dump_single, &dump_info);
|
||||||
|
sprintf_s(summary, "\n%i total dvars\n%i dvar indexes\n", dump_info.count, *game::native::dvarCount);
|
||||||
|
log_file::info("%s", summary);
|
||||||
|
log_file::info("=============================== END DVAR DUMP =====================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::dump_f(const command::params& params)
|
||||||
|
{
|
||||||
|
const char* match;
|
||||||
|
if (params.size() > 1)
|
||||||
|
{
|
||||||
|
match = params.get(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
match = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
com_dvar_dump(0, match);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::list_f(const command::params& params)
|
||||||
|
{
|
||||||
|
const char* match;
|
||||||
|
if (params.size() > 1)
|
||||||
|
{
|
||||||
|
match = params.get(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
match = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
game::native::Dvar_ForEach(list_single, (void*)match);
|
||||||
|
log_file::info("\n%i total dvars\n", *game::native::dvarCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvar::post_load()
|
||||||
|
{
|
||||||
|
if (game::is_dedi())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command::add("dvardump", dump_f);
|
||||||
|
command::add("dvarlist", list_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_MODULE(dvar)
|
19
src/module/dvar.hpp
Normal file
19
src/module/dvar.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class dvar final : public module
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void post_load() override;
|
||||||
|
|
||||||
|
static int values_equal(unsigned char type, game::native::DvarValue val0, game::native::DvarValue val1);
|
||||||
|
static bool has_latched_value(const game::native::dvar_t* dvar);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void com_dvar_dump_single(const game::native::dvar_t* dvar, void* user_data);
|
||||||
|
static void com_dvar_dump(int channel, const char* match);
|
||||||
|
|
||||||
|
static void list_single(const game::native::dvar_t* dvar, void* user_data);
|
||||||
|
|
||||||
|
static void dump_f(const command::params& params);
|
||||||
|
static void list_f(const command::params& params);
|
||||||
|
};
|
@ -8,13 +8,13 @@ public:
|
|||||||
static void com_log_print_message(const std::string& msg);
|
static void com_log_print_message(const std::string& msg);
|
||||||
static void info(const char* fmt, ...);
|
static void info(const char* fmt, ...);
|
||||||
|
|
||||||
|
static const game::native::dvar_t* com_logfile;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* log_file_name;
|
static const char* log_file_name;
|
||||||
|
|
||||||
static int opening_qconsole;
|
static int opening_qconsole;
|
||||||
static int com_console_log_open_failed;
|
static int com_console_log_open_failed;
|
||||||
|
|
||||||
static const game::native::dvar_t* com_logfile;
|
|
||||||
|
|
||||||
static void com_open_log_file();
|
static void com_open_log_file();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user