fix: hot join join issue for dedis & dangling pointer in script
This commit is contained in:
parent
20992d9a3b
commit
7de1ffbe9d
@ -94,9 +94,9 @@ namespace bots
|
|||||||
}
|
}
|
||||||
|
|
||||||
int format_bot_string(char* buffer, [[maybe_unused]] const char* format, const char* name, const char* xuid,
|
int format_bot_string(char* buffer, [[maybe_unused]] const char* format, const char* name, const char* xuid,
|
||||||
const char* xnaddr, int protocol, int net_field_chk, const char* session_mode, int qport)
|
const char* xnaddr, int protocol, int net_field_chk, const char* session_mode, int qport)
|
||||||
{
|
{
|
||||||
const auto find_name = [](const std::string& needle) -> const char*
|
const auto find_clan_name = [](const std::string& needle) -> const char*
|
||||||
{
|
{
|
||||||
for (const auto& entry : get_bot_names())
|
for (const auto& entry : get_bot_names())
|
||||||
{
|
{
|
||||||
@ -109,7 +109,8 @@ namespace bots
|
|||||||
return "3arc";
|
return "3arc";
|
||||||
};
|
};
|
||||||
|
|
||||||
return sprintf_s(buffer, 1024, bot_format_string, name, find_name(name), xuid, xnaddr, protocol, net_field_chk, session_mode, qport);
|
return sprintf_s(buffer, 1024, bot_format_string, name, find_clan_name(name),
|
||||||
|
xuid, xnaddr, protocol, net_field_chk, session_mode, qport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#include "auth.hpp"
|
#include "auth.hpp"
|
||||||
|
|
||||||
#include "steam/steam.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "scheduler.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ namespace dedicated_patches
|
|||||||
{
|
{
|
||||||
utils::hook::detour spawn_server_hook;
|
utils::hook::detour spawn_server_hook;
|
||||||
|
|
||||||
void scr_are_textures_loaded_stub([[maybe_unused]] game::scriptInstance_t inst)
|
void scr_are_textures_loaded_stub()
|
||||||
{
|
{
|
||||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
|
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,6 @@ namespace getinfo
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
int Com_SessionMode_GetGameMode()
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<int*>(game::select(0x1568ED7F4, 0x14948DB04)) << 14 >> 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_assigned_team()
|
int get_assigned_team()
|
||||||
{
|
{
|
||||||
return (rand() % 2) + 1;
|
return (rand() % 2) + 1;
|
||||||
@ -112,7 +104,7 @@ namespace getinfo
|
|||||||
info.set("protocol", std::to_string(PROTOCOL));
|
info.set("protocol", std::to_string(PROTOCOL));
|
||||||
info.set("sub_protocol", std::to_string(SUB_PROTOCOL));
|
info.set("sub_protocol", std::to_string(SUB_PROTOCOL));
|
||||||
info.set("playmode", std::to_string(game::Com_SessionMode_GetMode()));
|
info.set("playmode", std::to_string(game::Com_SessionMode_GetMode()));
|
||||||
info.set("gamemode", std::to_string(Com_SessionMode_GetGameMode()));
|
info.set("gamemode", std::to_string(game::Com_SessionMode_GetGameMode()));
|
||||||
info.set("sv_running", std::to_string(game::is_server_running()));
|
info.set("sv_running", std::to_string(game::is_server_running()));
|
||||||
info.set("dedicated", game::is_server() ? "1" : "0");
|
info.set("dedicated", game::is_server() ? "1" : "0");
|
||||||
info.set("hc", std::to_string(game::Com_GametypeSettings_GetUInt("hardcoremode", false)));
|
info.set("hc", std::to_string(game::Com_GametypeSettings_GetUInt("hardcoremode", false)));
|
||||||
|
@ -54,7 +54,7 @@ namespace party
|
|||||||
{
|
{
|
||||||
const auto local_client = *reinterpret_cast<DWORD*>(0x14342155C_g);
|
const auto local_client = *reinterpret_cast<DWORD*>(0x14342155C_g);
|
||||||
const auto current_mode = game::Com_SessionMode_GetMode();
|
const auto current_mode = game::Com_SessionMode_GetMode();
|
||||||
game::Com_SwitchMode(local_client, current_mode, mode, 6);
|
game::Com_SwitchMode(local_client, static_cast<game::eModes>(current_mode), mode, 6);
|
||||||
}, scheduler::main);
|
}, scheduler::main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
#include <game/game.hpp>
|
#include <game/game.hpp>
|
||||||
|
#include <game/utils.hpp>
|
||||||
#include "network.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
@ -11,21 +10,10 @@ namespace patches
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
utils::hook::detour sv_execute_client_messages_hook;
|
const game::dvar_t* lobby_min_players;
|
||||||
|
|
||||||
void sv_execute_client_messages_stub(game::client_s* client, game::msg_t* msg)
|
void script_errors_stub([[maybe_unused]] const char* file, [[maybe_unused]] int line,
|
||||||
{
|
[[maybe_unused]] unsigned int code, const char* fmt, ...)
|
||||||
if ((client->reliableSequence - client->reliableAcknowledge) < 0)
|
|
||||||
{
|
|
||||||
client->reliableAcknowledge = client->reliableSequence;
|
|
||||||
network::send(client->address, "error", "EXE_LOSTRELIABLECOMMANDS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sv_execute_client_messages_hook.invoke<void>(client, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void script_errors_stub(const char* file, int line, unsigned int code, const char* fmt, ...)
|
|
||||||
{
|
{
|
||||||
char buffer[0x1000];
|
char buffer[0x1000];
|
||||||
|
|
||||||
@ -38,6 +26,30 @@ namespace patches
|
|||||||
|
|
||||||
game::Com_Error(game::ERROR_SCRIPT_DROP, "%s", buffer);
|
game::Com_Error(game::ERROR_SCRIPT_DROP, "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scr_get_num_expected_players()
|
||||||
|
{
|
||||||
|
const auto mode = game::Com_SessionMode_GetMode();
|
||||||
|
if (mode == game::MODE_ZOMBIES || mode == game::MODE_CAMPAIGN)
|
||||||
|
{
|
||||||
|
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, lobby_min_players->current.value.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto num_expected_players = std::max(1, game::LobbyHost_GetClientCount(game::LOBBY_TYPE_GAME, game::LOBBY_CLIENT_TYPE_ALL));
|
||||||
|
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, num_expected_players);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sv_execute_client_messages_stub(game::client_s* client, game::msg_t* msg)
|
||||||
|
{
|
||||||
|
if ((client->reliableSequence - client->reliableAcknowledge) < 0)
|
||||||
|
{
|
||||||
|
client->reliableAcknowledge = client->reliableSequence;
|
||||||
|
game::SV_DropClient(client, "EXE_LOSTRELIABLECOMMANDS", true, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
game::SV_ExecuteClientMessage(client, msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct component final : generic_component
|
struct component final : generic_component
|
||||||
@ -53,13 +65,16 @@ namespace patches
|
|||||||
// don't make script errors fatal error
|
// don't make script errors fatal error
|
||||||
utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub);
|
utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub);
|
||||||
|
|
||||||
// Change 4 character name limit to 3 characters
|
// change 4 character name limit to 3 characters
|
||||||
utils::hook::set<uint8_t>(game::select(0x14224DA53, 0x140531143), 3);
|
utils::hook::set<uint8_t>(game::select(0x14224DA53, 0x140531143), 3);
|
||||||
utils::hook::set<uint8_t>(game::select(0x14224DBB4, 0x1405312A8), 3);
|
utils::hook::set<uint8_t>(game::select(0x14224DBB4, 0x1405312A8), 3);
|
||||||
utils::hook::set<uint8_t>(game::select(0x14224DF8C, 0x1405316DC), 3);
|
utils::hook::set<uint8_t>(game::select(0x14224DF8C, 0x1405316DC), 3);
|
||||||
|
|
||||||
// make sure client's reliableAck are not negative
|
// make sure reliableAck is not negative or too big
|
||||||
sv_execute_client_messages_hook.create(game::select(0x14224A460, 0x14052F840), sv_execute_client_messages_stub);
|
utils::hook::call(game::select(0x14225489C, 0x140537C4C), sv_execute_client_messages_stub);
|
||||||
|
|
||||||
|
lobby_min_players = game::register_dvar_int("lobby_min_players", 1, 1, 8, game::DVAR_NONE, "");
|
||||||
|
utils::hook::jump(game::select(0x141A7BCF0, 0x1402CB900), scr_get_num_expected_players, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace scheduler
|
|||||||
};
|
};
|
||||||
|
|
||||||
volatile bool kill = false;
|
volatile bool kill = false;
|
||||||
std::thread thread;
|
std::thread async_thread;
|
||||||
task_pipeline pipelines[pipeline::count];
|
task_pipeline pipelines[pipeline::count];
|
||||||
|
|
||||||
utils::hook::detour r_end_frame_hook;
|
utils::hook::detour r_end_frame_hook;
|
||||||
@ -153,7 +153,7 @@ namespace scheduler
|
|||||||
{
|
{
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
thread = utils::thread::create_named_thread("Async Scheduler", []()
|
async_thread = utils::thread::create_named_thread("Async Scheduler", []()
|
||||||
{
|
{
|
||||||
while (!kill)
|
while (!kill)
|
||||||
{
|
{
|
||||||
@ -180,9 +180,9 @@ namespace scheduler
|
|||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
kill = true;
|
kill = true;
|
||||||
if (thread.joinable())
|
if (async_thread.joinable())
|
||||||
{
|
{
|
||||||
thread.join();
|
async_thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,12 +30,12 @@ namespace scheduler
|
|||||||
|
|
||||||
void execute(const pipeline type);
|
void execute(const pipeline type);
|
||||||
|
|
||||||
void schedule(const std::function<bool()>& callback, pipeline type = pipeline::async,
|
void schedule(const std::function<bool()>& callback, pipeline type,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
void loop(const std::function<void()>& callback, pipeline type = pipeline::async,
|
void loop(const std::function<void()>& callback, pipeline type,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
void once(const std::function<void()>& callback, pipeline type = pipeline::async,
|
void once(const std::function<void()>& callback, pipeline type,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
void on_game_initialized(const std::function<void()>& callback, pipeline type = pipeline::async,
|
void on_game_initialized(const std::function<void()>& callback, pipeline type,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace script
|
|||||||
{
|
{
|
||||||
constexpr size_t GSC_MAGIC = 0x1C000A0D43534780;
|
constexpr size_t GSC_MAGIC = 0x1C000A0D43534780;
|
||||||
|
|
||||||
utils::hook::detour db_findxassetheader_hook;
|
utils::hook::detour db_find_x_asset_header_hook;
|
||||||
utils::hook::detour gscr_get_bgb_remaining_hook;
|
utils::hook::detour gscr_get_bgb_remaining_hook;
|
||||||
|
|
||||||
std::unordered_map<std::string, game::RawFile*> loaded_scripts;
|
std::unordered_map<std::string, game::RawFile*> loaded_scripts;
|
||||||
@ -33,7 +33,6 @@ namespace script
|
|||||||
void load_script(std::string& name, const std::string& data)
|
void load_script(std::string& name, const std::string& data)
|
||||||
{
|
{
|
||||||
auto& allocator = *utils::memory::get_allocator();
|
auto& allocator = *utils::memory::get_allocator();
|
||||||
const auto* file_string = allocator.duplicate_string(data);
|
|
||||||
|
|
||||||
const auto appdata_path = (game::get_appdata_path() / "data/").generic_string();
|
const auto appdata_path = (game::get_appdata_path() / "data/").generic_string();
|
||||||
const auto host_path = (utils::nt::library{}.get_folder() / "boiii/").generic_string();
|
const auto host_path = (utils::nt::library{}.get_folder() / "boiii/").generic_string();
|
||||||
@ -50,12 +49,12 @@ namespace script
|
|||||||
name.erase(i, host_path.length());
|
name.erase(i, host_path.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* rawfile = allocator.allocate<game::RawFile>();
|
auto* raw_file = allocator.allocate<game::RawFile>();
|
||||||
rawfile->name = name.c_str();
|
raw_file->name = allocator.duplicate_string(name);
|
||||||
rawfile->buffer = file_string;
|
raw_file->buffer = allocator.duplicate_string(data);
|
||||||
rawfile->len = static_cast<int>(data.length());
|
raw_file->len = static_cast<int>(data.length());
|
||||||
|
|
||||||
loaded_scripts[name] = rawfile;
|
loaded_scripts[name] = raw_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_scripts_folder(const std::string& script_dir)
|
void load_scripts_folder(const std::string& script_dir)
|
||||||
@ -94,11 +93,11 @@ namespace script
|
|||||||
load_scripts_folder((host.get_folder() / "boiii/scripts").string());
|
load_scripts_folder((host.get_folder() / "boiii/scripts").string());
|
||||||
}
|
}
|
||||||
|
|
||||||
game::RawFile* db_findxassetheader_stub(const game::XAssetType type, const char* name,
|
game::RawFile* db_find_x_asset_header_stub(const game::XAssetType type, const char* name,
|
||||||
const bool error_if_missing,
|
const bool error_if_missing,
|
||||||
const int wait_time)
|
const int wait_time)
|
||||||
{
|
{
|
||||||
auto* asset_header = db_findxassetheader_hook.invoke<game::RawFile*>(
|
auto* asset_header = db_find_x_asset_header_hook.invoke<game::RawFile*>(
|
||||||
type, name, error_if_missing, wait_time);
|
type, name, error_if_missing, wait_time);
|
||||||
|
|
||||||
if (type != game::ASSET_TYPE_SCRIPTPARSETREE)
|
if (type != game::ASSET_TYPE_SCRIPTPARSETREE)
|
||||||
@ -134,10 +133,10 @@ namespace script
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scheduler::once(load_scripts, scheduler::pipeline::renderer);
|
scheduler::once(load_scripts, scheduler::pipeline::main);
|
||||||
}
|
}
|
||||||
|
|
||||||
db_findxassetheader_hook.create(game::select(0x141420ED0, 0x1401D5FB0), db_findxassetheader_stub);
|
db_find_x_asset_header_hook.create(game::select(0x141420ED0, 0x1401D5FB0), db_find_x_asset_header_stub);
|
||||||
gscr_get_bgb_remaining_hook.create(game::select(0x141A8CAB0, 0x1402D2310), gscr_get_bgb_remaining_stub);
|
gscr_get_bgb_remaining_hook.create(game::select(0x141A8CAB0, 0x1402D2310), gscr_get_bgb_remaining_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -890,7 +890,7 @@ namespace game
|
|||||||
|
|
||||||
enum LobbyType
|
enum LobbyType
|
||||||
{
|
{
|
||||||
LOBBY_TYPE_INVALID = 0xFFFFFFFF,
|
LOBBY_TYPE_INVALID = -1,
|
||||||
LOBBY_TYPE_PRIVATE = 0x0,
|
LOBBY_TYPE_PRIVATE = 0x0,
|
||||||
LOBBY_TYPE_GAME = 0x1,
|
LOBBY_TYPE_GAME = 0x1,
|
||||||
LOBBY_TYPE_TRANSITION = 0x2,
|
LOBBY_TYPE_TRANSITION = 0x2,
|
||||||
@ -900,6 +900,14 @@ namespace game
|
|||||||
LOBBY_TYPE_AUTO = 0x3,
|
LOBBY_TYPE_AUTO = 0x3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum LobbyClientType
|
||||||
|
{
|
||||||
|
LOBBY_CLIENT_TYPE_INVALID = -1,
|
||||||
|
LOBBY_CLIENT_TYPE_ALL = 0x0,
|
||||||
|
LOBBY_CLIENT_TYPE_LOCAL = 0x1,
|
||||||
|
LOBBY_CLIENT_TYPE_REMOTE = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
enum LobbyNetworkMode
|
enum LobbyNetworkMode
|
||||||
{
|
{
|
||||||
LOBBY_NETWORKMODE_INVALID = 0xFFFFFFFF,
|
LOBBY_NETWORKMODE_INVALID = 0xFFFFFFFF,
|
||||||
@ -1600,7 +1608,6 @@ namespace game
|
|||||||
char __pad6[171432];
|
char __pad6[171432];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
static_assert(sizeof(client_s) == 0xE5110);
|
static_assert(sizeof(client_s) == 0xE5110);
|
||||||
|
|
||||||
@ -1637,14 +1644,23 @@ namespace game
|
|||||||
struct EntityState
|
struct EntityState
|
||||||
{
|
{
|
||||||
int number;
|
int number;
|
||||||
};
|
}; // Incomplete
|
||||||
|
|
||||||
struct gentity_s
|
struct gentity_s
|
||||||
{
|
{
|
||||||
EntityState s;
|
EntityState s;
|
||||||
unsigned char __pad0[0x24C];
|
unsigned char __pad0[0x24C];
|
||||||
gclient_s* client;
|
gclient_s* client;
|
||||||
unsigned char __pad1[0x2A0];
|
unsigned char __pad1[0x17C];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int notifyString;
|
||||||
|
unsigned int index;
|
||||||
|
unsigned char stoppable;
|
||||||
|
int basetime;
|
||||||
|
int duration;
|
||||||
|
} snd_wait;
|
||||||
|
unsigned char __pad2[0x110];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
eModes Com_SessionMode_GetMode()
|
|
||||||
{
|
|
||||||
return eModes(*reinterpret_cast<uint32_t*>(game::select(0x1568ED7F4, 0x14948DB04)) << 28 >> 28);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool I_islower(int c)
|
bool I_islower(int c)
|
||||||
{
|
{
|
||||||
return c >= 'a' && c <= 'z';
|
return c >= 'a' && c <= 'z';
|
||||||
|
@ -25,6 +25,8 @@ namespace game
|
|||||||
WEAK symbol<void(int channel, unsigned int label, const char* fmt, ...)> Com_Printf{0x142148F60, 0x140505630};
|
WEAK symbol<void(int channel, unsigned int label, const char* fmt, ...)> Com_Printf{0x142148F60, 0x140505630};
|
||||||
WEAK symbol<void(const char* file, int line, int code, const char* fmt, ...)> Com_Error_{0x1420F8170, 0x140501470};
|
WEAK symbol<void(const char* file, int line, int code, const char* fmt, ...)> Com_Error_{0x1420F8170, 0x140501470};
|
||||||
WEAK symbol<bool(eModes mode)> Com_SessionMode_IsMode{0x1420F7370};
|
WEAK symbol<bool(eModes mode)> Com_SessionMode_IsMode{0x1420F7370};
|
||||||
|
WEAK symbol<int()> Com_SessionMode_GetMode{0x1420F6D30 , 0x1405002D0};
|
||||||
|
WEAK symbol<int()> Com_SessionMode_GetGameMode{0x1420F68B0, 0x1404FFE50};
|
||||||
WEAK symbol<void(eNetworkModes networkMode)> Com_SessionMode_SetNetworkMode{0x1420F75B0, 0x140500B80};
|
WEAK symbol<void(eNetworkModes networkMode)> Com_SessionMode_SetNetworkMode{0x1420F75B0, 0x140500B80};
|
||||||
WEAK symbol<eGameModes(eGameModes gameMode)> Com_SessionMode_SetGameMode{0x1420F7570, 0x140500B40};
|
WEAK symbol<eGameModes(eGameModes gameMode)> Com_SessionMode_SetGameMode{0x1420F7570, 0x140500B40};
|
||||||
WEAK symbol<eModes(eModes mode)> Com_SessionMode_SetMode{0x1420F7570};
|
WEAK symbol<eModes(eModes mode)> Com_SessionMode_SetMode{0x1420F7570};
|
||||||
@ -131,7 +133,7 @@ namespace game
|
|||||||
};
|
};
|
||||||
WEAK symbol<dvar_t*(dvarStrHash_t hash, const char* dvarName, int value, int min, int max, unsigned int flags,
|
WEAK symbol<dvar_t*(dvarStrHash_t hash, const char* dvarName, int value, int min, int max, unsigned int flags,
|
||||||
const char* description)> Dvar_RegisterInt{
|
const char* description)> Dvar_RegisterInt{
|
||||||
0x0, 0x14057B7B0
|
0x1422D0AE0, 0x14057B7B0
|
||||||
};
|
};
|
||||||
WEAK symbol<dvar_t*(dvarStrHash_t hash, const char* dvarName, float value, float min, float max, unsigned int flags,
|
WEAK symbol<dvar_t*(dvarStrHash_t hash, const char* dvarName, float value, float min, float max, unsigned int flags,
|
||||||
const char* description)> Dvar_RegisterFloat{
|
const char* description)> Dvar_RegisterFloat{
|
||||||
@ -204,10 +206,20 @@ namespace game
|
|||||||
};
|
};
|
||||||
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x1420EF130, 0x1404FA6C0};
|
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x1420EF130, 0x1404FA6C0};
|
||||||
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x1420EF0E0, 0x1404FA670};
|
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x1420EF0E0, 0x1404FA670};
|
||||||
|
WEAK symbol<void(void* client, msg_t* msg)> SV_ExecuteClientMessage{0x14224A460, 0x14052F840};
|
||||||
|
|
||||||
|
WEAK symbol<void(void* drop, const char* reason, bool tellThem, bool removeFromLobby)> SV_DropClient{
|
||||||
|
0x14224A050, 0x14052F430
|
||||||
|
};
|
||||||
|
|
||||||
// FS
|
// FS
|
||||||
WEAK symbol<char*(int bytes)> FS_AllocMem{0x1422AC9F0, 0x14056C340};
|
WEAK symbol<char*(int bytes)> FS_AllocMem{0x1422AC9F0, 0x14056C340};
|
||||||
|
|
||||||
|
// Lobby
|
||||||
|
WEAK symbol<int(LobbyType lobbyType, LobbyClientType clientType)> LobbyHost_GetClientCount{
|
||||||
|
0x141ED8AC0, 0x14048A360
|
||||||
|
};
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
WEAK symbol<const char*(char* str)> I_CleanStr{0x1422E9050, 0x140580E80};
|
WEAK symbol<const char*(char* str)> I_CleanStr{0x1422E9050, 0x140580E80};
|
||||||
WEAK symbol<void(char* dest, size_t destsize, const char* src)> I_strcpy{
|
WEAK symbol<void(char* dest, size_t destsize, const char* src)> I_strcpy{
|
||||||
@ -261,8 +273,6 @@ namespace game
|
|||||||
constexpr auto CMD_MAX_NESTING = 8;
|
constexpr auto CMD_MAX_NESTING = 8;
|
||||||
|
|
||||||
// Re-implementations
|
// Re-implementations
|
||||||
eModes Com_SessionMode_GetMode();
|
|
||||||
|
|
||||||
bool I_islower(int c);
|
bool I_islower(int c);
|
||||||
bool I_isupper(int c);
|
bool I_isupper(int c);
|
||||||
|
|
||||||
|
@ -136,11 +136,10 @@ namespace game
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* dvar_to_change = dvar;
|
auto* dvar_to_change = dvar;
|
||||||
|
|
||||||
if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR)
|
if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR)
|
||||||
{
|
{
|
||||||
const auto mode = Com_SessionMode_GetMode();
|
const auto mode = Com_SessionMode_GetMode();
|
||||||
dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, mode);
|
dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, static_cast<eModes>(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
dvar_to_change->flags |= flags;
|
dvar_to_change->flags |= flags;
|
||||||
@ -156,11 +155,10 @@ namespace game
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* dvar_to_change = dvar;
|
auto* dvar_to_change = dvar;
|
||||||
|
|
||||||
if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR)
|
if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR)
|
||||||
{
|
{
|
||||||
const auto mode = Com_SessionMode_GetMode();
|
const auto mode = Com_SessionMode_GetMode();
|
||||||
dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, mode);
|
dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, static_cast<eModes>(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
dvar_to_change->flags = flags;
|
dvar_to_change->flags = flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user