Compare commits
1 Commits
master
...
struct_suf
Author | SHA1 | Date | |
---|---|---|---|
|
d0003da606 |
2
deps/GSL
vendored
2
deps/GSL
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3325bbd33d24d1f8f5a0f69e782c92ad5a39a68e
|
Subproject commit f1a494cfd2ce55fe88b5134eab985f5852667b8d
|
2
deps/WinToast
vendored
2
deps/WinToast
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a78ce469b456c06103b3b30d4bd37e7bb80da30c
|
Subproject commit 821c4818ade1aa4da56ac753285c159ce26fd597
|
2
deps/asmjit
vendored
2
deps/asmjit
vendored
@ -1 +1 @@
|
|||||||
Subproject commit e8c8e2e48a1a38154c8e8864eb3bc61db80a1e31
|
Subproject commit bfa0bf690c2e90cc0844f2f012efa41b916bde7e
|
2
deps/gsc-tool
vendored
2
deps/gsc-tool
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 2d9781ce0ce9e8551eaf040d7761fd986f33cfdc
|
Subproject commit b8e30e6334aa33ea731caf8d0700a9e6c7794c09
|
2
deps/libtomcrypt
vendored
2
deps/libtomcrypt
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a6b9aff7aab857fe1b491710a5c5b9e2be49cb08
|
Subproject commit 7e863d21429f94ed6a720e24499a12a3f852bb31
|
2
deps/libtommath
vendored
2
deps/libtommath
vendored
@ -1 +1 @@
|
|||||||
Subproject commit e823b0c34cea291bdb94d672731e1c1f08525557
|
Subproject commit 8314bde5e5c8e5d9331460130a9d1066e324f091
|
2
deps/minhook
vendored
2
deps/minhook
vendored
@ -1 +1 @@
|
|||||||
Subproject commit c3fcafdc10146beb5919319d0683e44e3c30d537
|
Subproject commit f5485b8454544c2f034c78f8f127c1d03dea3636
|
2
deps/rapidjson
vendored
2
deps/rapidjson
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 24b5e7a8b27f42fa16b96fc70aade9106cf7102f
|
Subproject commit 6089180ecb704cb2b136777798fa1be303618975
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5a82f71ed1dfc0bec044d9702463dbdf84ea3b71
|
Subproject commit 9f0f2d4f9f1f28be7e16d8bf3b4e9d4ada70aa9f
|
@ -268,7 +268,7 @@ filter "configurations:Release"
|
|||||||
buildoptions {"/GL"}
|
buildoptions {"/GL"}
|
||||||
linkoptions {"/IGNORE:4702", "/LTCG"}
|
linkoptions {"/IGNORE:4702", "/LTCG"}
|
||||||
defines {"NDEBUG"}
|
defines {"NDEBUG"}
|
||||||
fatalwarnings {"All"}
|
flags {"FatalCompileWarnings"}
|
||||||
filter {}
|
filter {}
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include <loader/component_loader.hpp>
|
|
||||||
#include "game/game.hpp"
|
|
||||||
|
|
||||||
#include <utils/memory.hpp>
|
|
||||||
|
|
||||||
namespace asset_restrict
|
|
||||||
{
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void reallocate_asset_pool(game::XAssetType type, const int size)
|
|
||||||
{
|
|
||||||
const auto asset_size = game::DB_GetXAssetTypeSize(type);
|
|
||||||
const auto new_size = size * game::g_poolSize[type];
|
|
||||||
|
|
||||||
const auto new_allocation_size = static_cast<std::size_t>(new_size * asset_size);
|
|
||||||
|
|
||||||
const game::XAssetHeader pool_entry = { .data = utils::memory::allocate(new_allocation_size) };
|
|
||||||
game::DB_XAssetPool[type] = pool_entry.data;
|
|
||||||
game::g_poolSize[type] = new_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class component final : public component_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
reallocate_asset_pool(game::ASSET_TYPE_XANIMPARTS, 2);
|
|
||||||
reallocate_asset_pool(game::ASSET_TYPE_ATTACHMENT, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_COMPONENT(asset_restrict::component)
|
|
@ -1,61 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include "loader/component_loader.hpp"
|
|
||||||
#include "game/game.hpp"
|
|
||||||
|
|
||||||
#include "component/console.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
|
||||||
|
|
||||||
namespace weapons
|
|
||||||
{
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void g_setup_level_weapon_def_stub()
|
|
||||||
{
|
|
||||||
game::G_SetupLevelWeaponDef();
|
|
||||||
|
|
||||||
// The count on most maps is well below 200
|
|
||||||
std::array<game::WeaponCompleteDef*, 256> weapons{};
|
|
||||||
const auto count = game::DB_GetAllXAssetOfType_FastFile(game::ASSET_TYPE_WEAPON, (void**)weapons.data(), static_cast<int>(weapons.max_size()));
|
|
||||||
|
|
||||||
std::sort(weapons.begin(), weapons.begin() + count, [](game::WeaponCompleteDef* weapon1, game::WeaponCompleteDef* weapon2)
|
|
||||||
{
|
|
||||||
assert(weapon1->szInternalName);
|
|
||||||
assert(weapon2->szInternalName);
|
|
||||||
|
|
||||||
return std::strcmp(weapon1->szInternalName, weapon2->szInternalName) < 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
console::info("Found %i weapons to precache\n", count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (auto i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
console::info("Precaching weapon \"%s\"\n", weapons[i]->szInternalName);
|
|
||||||
#endif
|
|
||||||
(void)game::G_GetWeaponForName(weapons[i]->szInternalName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class component final : public component_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
if (game::environment::is_sp()) return;
|
|
||||||
|
|
||||||
// Kill Scr_PrecacheItem (We are going to do this from code)
|
|
||||||
utils::hook::nop(0x1403BDB10, 4);
|
|
||||||
utils::hook::set<std::uint8_t>(0x1403BDB10, 0xC3);
|
|
||||||
|
|
||||||
// Load weapons from the DB
|
|
||||||
utils::hook::call(0x14039F382, g_setup_level_weapon_def_stub);
|
|
||||||
utils::hook::call(0x1403AE31A, g_setup_level_weapon_def_stub);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_COMPONENT(weapons::component)
|
|
@ -8,13 +8,11 @@
|
|||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "network.hpp"
|
#include "network.hpp"
|
||||||
|
|
||||||
#include <utils/cryptography.hpp>
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/info_string.hpp>
|
|
||||||
#include <utils/io.hpp>
|
|
||||||
#include <utils/properties.hpp>
|
|
||||||
#include <utils/smbios.hpp>
|
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
#include <utils/smbios.hpp>
|
||||||
|
#include <utils/info_string.hpp>
|
||||||
|
#include <utils/cryptography.hpp>
|
||||||
|
|
||||||
namespace auth
|
namespace auth
|
||||||
{
|
{
|
||||||
@ -33,21 +31,13 @@ namespace auth
|
|||||||
|
|
||||||
std::string get_hw_profile_guid()
|
std::string get_hw_profile_guid()
|
||||||
{
|
{
|
||||||
auto hw_profile_path = (utils::properties::get_appdata_path() / "iw6-guid.dat").generic_string();
|
|
||||||
if (utils::io::file_exists(hw_profile_path))
|
|
||||||
{
|
|
||||||
// Migration
|
|
||||||
utils::io::remove_file(hw_profile_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
HW_PROFILE_INFO info;
|
HW_PROFILE_INFO info;
|
||||||
if (!GetCurrentHwProfileA(&info))
|
if (!GetCurrentHwProfileA(&info))
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hw_profile_info = std::string{ info.szHwProfileGuid, sizeof(info.szHwProfileGuid) };
|
return std::string{ info.szHwProfileGuid, sizeof(info.szHwProfileGuid) };
|
||||||
return hw_profile_info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_protected_data()
|
std::string get_protected_data()
|
||||||
@ -62,7 +52,7 @@ namespace auth
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto size = std::min<DWORD>(data_out.cbData, 52);
|
const auto size = std::min(data_out.cbData, 52ul);
|
||||||
std::string result{ reinterpret_cast<char*>(data_out.pbData), size };
|
std::string result{ reinterpret_cast<char*>(data_out.pbData), size };
|
||||||
LocalFree(data_out.pbData);
|
LocalFree(data_out.pbData);
|
||||||
|
|
||||||
@ -86,80 +76,17 @@ namespace auth
|
|||||||
return entropy;
|
return entropy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_key(utils::cryptography::ecc::key& key)
|
utils::cryptography::ecc::key& get_key()
|
||||||
{
|
{
|
||||||
std::string data{};
|
static auto key = utils::cryptography::ecc::generate_key(512, get_key_entropy());
|
||||||
|
|
||||||
auto key_path = (utils::properties::get_appdata_path() / "iw6-private.key").generic_string();
|
|
||||||
if (!utils::io::read_file(key_path, &data))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
key.deserialize(data);
|
|
||||||
if (!key.is_valid())
|
|
||||||
{
|
|
||||||
console::error("Loaded key is invalid!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
utils::cryptography::ecc::key generate_key()
|
|
||||||
{
|
|
||||||
auto key = utils::cryptography::ecc::generate_key(512, get_key_entropy());
|
|
||||||
if (!key.is_valid())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to generate cryptographic key!");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto key_path = (utils::properties::get_appdata_path() / "iw6-private.key").generic_string();
|
|
||||||
if (!utils::io::write_file(key_path, key.serialize()))
|
|
||||||
{
|
|
||||||
console::error("Failed to write cryptographic key!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
console::info("Generated cryptographic key: %llX\n", key.get_hash());
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::cryptography::ecc::key load_or_generate_key()
|
int send_connect_data_stub(game::netsrc_t sock, game::netadr_t* adr, const char* format, const int len)
|
||||||
{
|
|
||||||
utils::cryptography::ecc::key key{};
|
|
||||||
if (load_key(key))
|
|
||||||
{
|
|
||||||
console::info("Loaded cryptographic key: %llX\n", key.get_hash());
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return generate_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
utils::cryptography::ecc::key get_key_internal()
|
|
||||||
{
|
|
||||||
auto key = load_or_generate_key();
|
|
||||||
|
|
||||||
auto key_path = (utils::properties::get_appdata_path() / "iw6-public.key").generic_string();
|
|
||||||
if (!utils::io::write_file(key_path, key.get_public_key()))
|
|
||||||
{
|
|
||||||
console::error("Failed to write public key!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
const utils::cryptography::ecc::key& get_key()
|
|
||||||
{
|
|
||||||
static auto key = get_key_internal();
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
int send_connect_data_stub(game::netsrc_t sock, game::netadr_s* adr, const char* format, const int len)
|
|
||||||
{
|
{
|
||||||
std::string connect_string(format, len);
|
std::string connect_string(format, len);
|
||||||
game::SV_Cmd_TokenizeString(connect_string.data());
|
game::SV_Cmd_TokenizeString(connect_string.data());
|
||||||
const auto _0 = gsl::finally([]()
|
const auto _ = gsl::finally([]()
|
||||||
{
|
{
|
||||||
game::SV_Cmd_EndTokenizedString();
|
game::SV_Cmd_EndTokenizedString();
|
||||||
});
|
});
|
||||||
@ -182,14 +109,14 @@ namespace auth
|
|||||||
|
|
||||||
proto::network::connect_info info;
|
proto::network::connect_info info;
|
||||||
info.set_publickey(get_key().get_public_key());
|
info.set_publickey(get_key().get_public_key());
|
||||||
info.set_signature(utils::cryptography::ecc::sign_message(get_key(), challenge));
|
info.set_signature(sign_message(get_key(), challenge));
|
||||||
info.set_infostring(connect_string);
|
info.set_infostring(connect_string);
|
||||||
|
|
||||||
network::send(*adr, "connect", info.SerializeAsString());
|
network::send(*adr, "connect", info.SerializeAsString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void direct_connect(game::netadr_s* from, game::msg_t* msg)
|
void direct_connect(game::netadr_t* from, game::msg_t* msg)
|
||||||
{
|
{
|
||||||
const auto offset = sizeof("connect") + 4;
|
const auto offset = sizeof("connect") + 4;
|
||||||
|
|
||||||
@ -223,14 +150,14 @@ namespace auth
|
|||||||
utils::cryptography::ecc::key key;
|
utils::cryptography::ecc::key key;
|
||||||
key.set(info.publickey());
|
key.set(info.publickey());
|
||||||
|
|
||||||
const auto xuid = std::strtoull(steam_id.data(), nullptr, 16);
|
const auto xuid = strtoull(steam_id.data(), nullptr, 16);
|
||||||
if (xuid != key.get_hash())
|
if (xuid != key.get_hash())
|
||||||
{
|
{
|
||||||
network::send(*from, "error", "XUID doesn't match the certificate!", '\n');
|
network::send(*from, "error", "XUID doesn't match the certificate!", '\n');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key.is_valid() || !utils::cryptography::ecc::verify_message(key, challenge, info.signature()))
|
if (!key.is_valid() || !verify_message(key, challenge, info.signature()))
|
||||||
{
|
{
|
||||||
network::send(*from, "error", "Challenge signature was invalid!", '\n');
|
network::send(*from, "error", "Challenge signature was invalid!", '\n');
|
||||||
return;
|
return;
|
||||||
@ -290,7 +217,7 @@ namespace auth
|
|||||||
utils::hook::call(0x1402C4F8E, send_connect_data_stub);
|
utils::hook::call(0x1402C4F8E, send_connect_data_stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
command::add("guid", []() -> void
|
command::add("guid", []
|
||||||
{
|
{
|
||||||
console::info("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits);
|
console::info("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits);
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,9 @@ namespace binding
|
|||||||
|
|
||||||
if (value && value < 100)
|
if (value && value < 100)
|
||||||
{
|
{
|
||||||
const auto len = game::Com_sprintf(&buffer[bytes_used], (buffer_size_align - bytes_used), "bind %s \"%s\"\n", key_button, game::command_whitelist[value]);
|
const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used),
|
||||||
|
"bind %s \"%s\"\n", key_button, game::command_whitelist[value]);
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
return bytes_used;
|
return bytes_used;
|
||||||
@ -38,7 +40,9 @@ namespace binding
|
|||||||
value -= 100;
|
value -= 100;
|
||||||
if (static_cast<size_t>(value) < custom_binds.size() && !custom_binds[value].empty())
|
if (static_cast<size_t>(value) < custom_binds.size() && !custom_binds[value].empty())
|
||||||
{
|
{
|
||||||
const auto len = game::Com_sprintf(&buffer[bytes_used], (buffer_size_align - bytes_used), "bind %s \"%s\"\n", key_button, custom_binds[value].data());
|
const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used),
|
||||||
|
"bind %s \"%s\"\n", key_button, custom_binds[value].data());
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
return bytes_used;
|
return bytes_used;
|
||||||
|
@ -144,7 +144,7 @@ namespace bots
|
|||||||
{
|
{
|
||||||
bot_names_received = false;
|
bot_names_received = false;
|
||||||
|
|
||||||
game::netadr_s master{};
|
game::netadr_t master{};
|
||||||
if (server_list::get_master_server(master))
|
if (server_list::get_master_server(master))
|
||||||
{
|
{
|
||||||
console::info("Getting bots...\n");
|
console::info("Getting bots...\n");
|
||||||
@ -198,9 +198,9 @@ namespace bots
|
|||||||
parse_bot_names_from_file();
|
parse_bot_names_from_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
network::on("getbotsResponse", [](const game::netadr_s& target, const std::string& data)
|
network::on("getbotsResponse", [](const game::netadr_t& target, const std::string& data)
|
||||||
{
|
{
|
||||||
game::netadr_s master{};
|
game::netadr_t master{};
|
||||||
if (server_list::get_master_server(master) && !bot_names_received && target == master)
|
if (server_list::get_master_server(master) && !bot_names_received && target == master)
|
||||||
{
|
{
|
||||||
bot_names = utils::string::split(data, '\n');
|
bot_names = utils::string::split(data, '\n');
|
||||||
|
@ -76,16 +76,7 @@ namespace colors
|
|||||||
|
|
||||||
void com_clean_name_stub(const char* in, char* out, const int out_size)
|
void com_clean_name_stub(const char* in, char* out, const int out_size)
|
||||||
{
|
{
|
||||||
// Check that the name is at least 3 char without colors
|
strncpy_s(out, out_size, in, _TRUNCATE);
|
||||||
char name[16]{};
|
|
||||||
|
|
||||||
game::I_strncpyz(out, in, std::min<int>(out_size, sizeof(name)));
|
|
||||||
|
|
||||||
utils::string::strip(out, name, std::strlen(out) + 1);
|
|
||||||
if (std::strlen(name) < 3)
|
|
||||||
{
|
|
||||||
game::I_strncpyz(out, "UnnamedPlayer", std::min<int>(out_size, sizeof(name)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* i_clean_str_stub(char* string)
|
char* i_clean_str_stub(char* string)
|
||||||
@ -95,31 +86,18 @@ namespace colors
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cl_get_client_name_and_clan_tag_stub(const int local_client_num, const int index, char* name_buf, const int name_size, char* clan_tag_buf, int clan_tag_size)
|
size_t get_client_name_stub(const int local_client_num, const int index, char* buf, const int size,
|
||||||
|
const size_t unk, const size_t unk2)
|
||||||
{
|
{
|
||||||
// CL_GetClientNameAndClanTag -> CL_GetClientNameAndClanTagColorize
|
// CL_GetClientName (CL_GetClientNameAndClantag?)
|
||||||
const auto result = utils::hook::invoke<int>(0x1402CF790, local_client_num, index, name_buf, name_size, clan_tag_buf, clan_tag_size);
|
const auto result = reinterpret_cast<size_t(*)(int, int, char*, int, size_t, size_t)>(0x1402CF790)(
|
||||||
|
local_client_num, index, buf, size, unk, unk2);
|
||||||
|
|
||||||
utils::string::strip(name_buf, name_buf, name_size);
|
utils::string::strip(buf, buf, size);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int com_sprintf_stub(char* dest, int size, const char* fmt, const char* name)
|
|
||||||
{
|
|
||||||
const auto len = game::Com_sprintf(dest, size, fmt, name);
|
|
||||||
if (len < 0)
|
|
||||||
{
|
|
||||||
game::I_strncpyz(dest, "UnnamedAgent", size);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should inherit the name of the owner (a player) which already passed the length check in Com_CleanName
|
|
||||||
utils::string::strip(dest, dest, len + 1);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rb_lookup_color_stub(const char index, DWORD* color)
|
void rb_lookup_color_stub(const char index, DWORD* color)
|
||||||
{
|
{
|
||||||
*color = RGB(255, 255, 255);
|
*color = RGB(255, 255, 255);
|
||||||
@ -160,15 +138,10 @@ namespace colors
|
|||||||
if (!game::environment::is_sp())
|
if (!game::environment::is_sp())
|
||||||
{
|
{
|
||||||
// allows colored name in-game
|
// allows colored name in-game
|
||||||
utils::hook::call(0x1403881CF, com_clean_name_stub);
|
utils::hook::jump(0x1404F5FC0, com_clean_name_stub);
|
||||||
utils::hook::call(0x140388224, com_clean_name_stub);
|
|
||||||
|
|
||||||
// don't apply colors to overhead names
|
// don't apply colors to overhead names
|
||||||
utils::hook::call(0x14025CE79, cl_get_client_name_and_clan_tag_stub);
|
utils::hook::call(0x14025CE79, get_client_name_stub);
|
||||||
|
|
||||||
// don't apply colors to overhead names of agents (like dogs or juggernauts)
|
|
||||||
// hook Com_sprintf in CL_GetAgentName
|
|
||||||
utils::hook::call(0x1402CF760, com_sprintf_stub);
|
|
||||||
|
|
||||||
// patch I_CleanStr
|
// patch I_CleanStr
|
||||||
utils::hook::jump(0x1404F63C0, i_clean_str_stub);
|
utils::hook::jump(0x1404F63C0, i_clean_str_stub);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
#include "game/engine/sv_game.hpp"
|
|
||||||
|
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
@ -195,7 +194,7 @@ namespace command
|
|||||||
|
|
||||||
void add_raw(const char* name, void (*callback)())
|
void add_raw(const char* name, void (*callback)())
|
||||||
{
|
{
|
||||||
game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate<game::cmd_function_s>());
|
game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate<game::cmd_function_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const char* name, const std::function<void(const params&)>& callback)
|
void add(const char* name, const std::function<void(const params&)>& callback)
|
||||||
@ -233,10 +232,7 @@ namespace command
|
|||||||
|
|
||||||
void execute(std::string command, const bool sync)
|
void execute(std::string command, const bool sync)
|
||||||
{
|
{
|
||||||
if (!command.ends_with('\n'))
|
command += "\n";
|
||||||
{
|
|
||||||
command += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sync)
|
if (sync)
|
||||||
{
|
{
|
||||||
@ -322,7 +318,7 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
console::info("================================ COMMAND DUMP =====================================\n");
|
console::info("================================ COMMAND DUMP =====================================\n");
|
||||||
game::cmd_function_s* cmd = *game::cmd_functions;
|
game::cmd_function_t* cmd = *game::cmd_functions;
|
||||||
auto i = 0;
|
auto i = 0;
|
||||||
while (cmd)
|
while (cmd)
|
||||||
{
|
{
|
||||||
@ -460,7 +456,10 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
game::sp::g_entities[0].flags ^= game::FL_GODMODE;
|
game::sp::g_entities[0].flags ^= game::FL_GODMODE;
|
||||||
game::CG_GameMessage(0, utils::string::va("godmode %s", game::sp::g_entities[0].flags & game::FL_GODMODE ? "^2on" : "^1off"));
|
game::CG_GameMessage(0, utils::string::va("godmode %s",
|
||||||
|
game::sp::g_entities[0].flags & game::FL_GODMODE
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add("notarget", []
|
add("notarget", []
|
||||||
@ -471,7 +470,10 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
game::sp::g_entities[0].flags ^= game::FL_NOTARGET;
|
game::sp::g_entities[0].flags ^= game::FL_NOTARGET;
|
||||||
game::CG_GameMessage(0, utils::string::va("notarget %s", game::sp::g_entities[0].flags & game::FL_NOTARGET ? "^2on" : "^1off"));
|
game::CG_GameMessage(0, utils::string::va("notarget %s",
|
||||||
|
game::sp::g_entities[0].flags & game::FL_NOTARGET
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add("noclip", []
|
add("noclip", []
|
||||||
@ -482,7 +484,10 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
game::sp::g_entities[0].client->flags ^= 1;
|
game::sp::g_entities[0].client->flags ^= 1;
|
||||||
game::CG_GameMessage(0, utils::string::va("noclip %s", game::sp::g_entities[0].client->flags & 1 ? "^2on" : "^1off"));
|
game::CG_GameMessage(0, utils::string::va("noclip %s",
|
||||||
|
game::sp::g_entities[0].client->flags & 1
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add("ufo", []
|
add("ufo", []
|
||||||
@ -493,7 +498,10 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
game::sp::g_entities[0].client->flags ^= 2;
|
game::sp::g_entities[0].client->flags ^= 2;
|
||||||
game::CG_GameMessage(0, utils::string::va("ufo %s", game::sp::g_entities[0].client->flags & 2 ? "^2on" : "^1off"));
|
game::CG_GameMessage(0, utils::string::va("ufo %s",
|
||||||
|
game::sp::g_entities[0].client->flags & 2
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add("give", [](const params& params)
|
add("give", [](const params& params)
|
||||||
@ -545,65 +553,78 @@ namespace command
|
|||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::mp::g_entities[client_num].flags ^= game::FL_GODMODE;
|
game::mp::g_entities[client_num].flags ^= game::FL_GODMODE;
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, utils::string::va("f \"godmode %s\"", game::mp::g_entities[client_num].flags & game::FL_GODMODE ? "^2on" : "^1off"));
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
|
utils::string::va("f \"godmode %s\"",
|
||||||
|
game::mp::g_entities[client_num].flags & game::FL_GODMODE
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add_sv("notarget", [](const int client_num, const params_sv&)
|
add_sv("notarget", [](const int client_num, const params_sv&)
|
||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::mp::g_entities[client_num].flags ^= game::FL_NOTARGET;
|
game::mp::g_entities[client_num].flags ^= game::FL_NOTARGET;
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
utils::string::va("f \"notarget %s\"", game::mp::g_entities[client_num].flags & game::FL_NOTARGET ? "^2on" : "^1off"));
|
utils::string::va("f \"notarget %s\"",
|
||||||
|
game::mp::g_entities[client_num].flags & game::FL_NOTARGET
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add_sv("noclip", [](const int client_num, const params_sv&)
|
add_sv("noclip", [](const int client_num, const params_sv&)
|
||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::mp::g_entities[client_num].client->flags ^= 1;
|
game::mp::g_entities[client_num].client->flags ^= 1;
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
utils::string::va("f \"noclip %s\"", game::mp::g_entities[client_num].client->flags & 1 ? "^2on" : "^1off"));
|
utils::string::va("f \"noclip %s\"",
|
||||||
|
game::mp::g_entities[client_num].client->flags & 1
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add_sv("ufo", [](const int client_num, const params_sv&)
|
add_sv("ufo", [](const int client_num, const params_sv&)
|
||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::mp::g_entities[client_num].client->flags ^= 2;
|
game::mp::g_entities[client_num].client->flags ^= 2;
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
utils::string::va("f \"ufo %s\"", game::mp::g_entities[client_num].client->flags & 2 ? "^2on" : "^1off"));
|
utils::string::va("f \"ufo %s\"",
|
||||||
|
game::mp::g_entities[client_num].client->flags & 2
|
||||||
|
? "^2on"
|
||||||
|
: "^1off"));
|
||||||
});
|
});
|
||||||
|
|
||||||
add_sv("setviewpos", [](const int client_num, const params_sv& params)
|
add_sv("setviewpos", [](const int client_num, const params_sv& params)
|
||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size() < 4)
|
if (params.size() < 4)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
"f \"You did not specify the correct number of coordinates\"");
|
"f \"You did not specify the correct number of coordinates\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,14 +637,14 @@ namespace command
|
|||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size() < 4)
|
if (params.size() < 4)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
|
game::SV_GameSendServerCommand(client_num, 1,
|
||||||
"f \"You did not specify the correct number of coordinates\"");
|
"f \"You did not specify the correct number of coordinates\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,13 +657,13 @@ namespace command
|
|||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size() < 2)
|
if (params.size() < 2)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,13 +680,13 @@ namespace command
|
|||||||
{
|
{
|
||||||
if (!dvars::sv_cheats->current.enabled)
|
if (!dvars::sv_cheats->current.enabled)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size() < 2)
|
if (params.size() < 2)
|
||||||
{
|
{
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\"");
|
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +84,15 @@ namespace console
|
|||||||
|
|
||||||
void print_stub(const char* fmt, ...)
|
void print_stub(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
char buffer[4096]{};
|
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
[[maybe_unused]] const auto len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
print_message(buffer);
|
char buffer[4096]{};
|
||||||
|
const auto res = vsnprintf_s(buffer, _TRUNCATE, fmt, ap);
|
||||||
|
(void)res;
|
||||||
|
print_message(buffer);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_text(const char* text)
|
void append_text(const char* text)
|
||||||
|
@ -110,7 +110,7 @@ namespace dedicated
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::netadr_s target{};
|
game::netadr_t target{};
|
||||||
if (server_list::get_master_server(target))
|
if (server_list::get_master_server(target))
|
||||||
{
|
{
|
||||||
network::send(target, "heartbeat", "IW6");
|
network::send(target, "heartbeat", "IW6");
|
||||||
@ -198,6 +198,25 @@ namespace dedicated
|
|||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sys_error_stub(const char* msg, ...)
|
||||||
|
{
|
||||||
|
char buffer[2048]{};
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
|
||||||
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
scheduler::once([]()
|
||||||
|
{
|
||||||
|
command::execute("map_rotate");
|
||||||
|
}, scheduler::pipeline::main, 3s);
|
||||||
|
|
||||||
|
game::Com_Error(game::ERR_DROP, "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void add_commands()
|
void add_commands()
|
||||||
{
|
{
|
||||||
command::add("map", [](const command::params& params)
|
command::add("map", [](const command::params& params)
|
||||||
@ -345,6 +364,9 @@ namespace dedicated
|
|||||||
utils::hook::nop(0x1404F8BE1, 2); // ^
|
utils::hook::nop(0x1404F8BE1, 2); // ^
|
||||||
utils::hook::set<uint8_t>(0x140328660, 0xC3); // Disable image pak file loading
|
utils::hook::set<uint8_t>(0x140328660, 0xC3); // Disable image pak file loading
|
||||||
|
|
||||||
|
// Stop crashing from sys_errors
|
||||||
|
utils::hook::jump(0x1404FF510, sys_error_stub);
|
||||||
|
|
||||||
// Reduce min required memory
|
// Reduce min required memory
|
||||||
utils::hook::set<uint64_t>(0x1404FA6BD, 0x80000000);
|
utils::hook::set<uint64_t>(0x1404FA6BD, 0x80000000);
|
||||||
utils::hook::set<uint64_t>(0x1404FA76F, 0x80000000);
|
utils::hook::set<uint64_t>(0x1404FA76F, 0x80000000);
|
||||||
|
@ -25,28 +25,28 @@ namespace dedicated_info
|
|||||||
|
|
||||||
scheduler::loop([]()
|
scheduler::loop([]()
|
||||||
{
|
{
|
||||||
const auto* sv_running = game::Dvar_FindVar("sv_running");
|
auto* sv_running = game::Dvar_FindVar("sv_running");
|
||||||
if (!sv_running || !sv_running->current.enabled)
|
if (!sv_running || !sv_running->current.enabled)
|
||||||
{
|
{
|
||||||
console::set_title("iw6-mod Dedicated Server");
|
console::set_title("iw6-mod Dedicated Server");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* sv_hostname = game::Dvar_FindVar("sv_hostname");
|
auto* const sv_hostname = game::Dvar_FindVar("sv_hostname");
|
||||||
const auto* sv_maxclients = game::Dvar_FindVar("sv_maxclients");
|
auto* const sv_maxclients = game::Dvar_FindVar("sv_maxclients");
|
||||||
const auto* mapname = game::Dvar_FindVar("mapname");
|
auto* const mapname = game::Dvar_FindVar("mapname");
|
||||||
|
|
||||||
auto client_count = 0;
|
auto client_count = 0;
|
||||||
auto bot_count = 0;
|
auto bot_count = 0;
|
||||||
|
|
||||||
for (auto i = 0; i < sv_maxclients->current.integer; ++i)
|
for (auto i = 0; i < sv_maxclients->current.integer; i++)
|
||||||
{
|
{
|
||||||
auto* client = &game::mp::svs_clients[i];
|
auto* client = &game::mp::svs_clients[i];
|
||||||
auto* self = &game::mp::g_entities[i];
|
auto* self = &game::mp::g_entities[i];
|
||||||
|
|
||||||
if (client->header.state > game::CS_FREE && self && self->client)
|
if (client->header.state > game::CS_FREE && self && self->client)
|
||||||
{
|
{
|
||||||
++client_count;
|
client_count++;
|
||||||
if (game::SV_BotIsBot(i))
|
if (game::SV_BotIsBot(i))
|
||||||
{
|
{
|
||||||
++bot_count;
|
++bot_count;
|
||||||
@ -56,7 +56,8 @@ namespace dedicated_info
|
|||||||
|
|
||||||
std::string cleaned_hostname = sv_hostname->current.string;
|
std::string cleaned_hostname = sv_hostname->current.string;
|
||||||
|
|
||||||
utils::string::strip(sv_hostname->current.string, cleaned_hostname.data(), cleaned_hostname.size() + 1);
|
utils::string::strip(sv_hostname->current.string, cleaned_hostname.data(),
|
||||||
|
cleaned_hostname.size() + 1);
|
||||||
|
|
||||||
console::set_title(utils::string::va("%s on %s [%d/%d] (%d)", cleaned_hostname.data(),
|
console::set_title(utils::string::va("%s on %s [%d/%d] (%d)", cleaned_hostname.data(),
|
||||||
mapname->current.string, client_count,
|
mapname->current.string, client_count,
|
||||||
|
@ -222,7 +222,7 @@ namespace demonware
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
|
|
||||||
vsnprintf(buffer, sizeof(buffer), msg, ap);
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
printf("%s: %s\n", function, buffer);
|
printf("%s: %s\n", function, buffer);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
@ -71,7 +71,7 @@ namespace discord
|
|||||||
discord_presence.state = host_name;
|
discord_presence.state = host_name;
|
||||||
discord_presence.partyMax = party::server_client_count();
|
discord_presence.partyMax = party::server_client_count();
|
||||||
|
|
||||||
std::hash<game::netadr_s> hash_fn;
|
std::hash<game::netadr_t> hash_fn;
|
||||||
static const auto nonce = utils::cryptography::random::get_integer();
|
static const auto nonce = utils::cryptography::random::get_integer();
|
||||||
|
|
||||||
const auto& address = party::get_target();
|
const auto& address = party::get_target();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
#include "game/engine/sv_game.hpp"
|
|
||||||
|
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
|
|
||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace dvar_cheats
|
namespace dvar_cheats
|
||||||
{
|
{
|
||||||
void apply_sv_cheats(const game::dvar_t* dvar, const game::DvarSetSource source, game::DvarValue* value)
|
void apply_sv_cheats(const game::dvar_t* dvar, const game::DvarSetSource source, game::dvar_value* value)
|
||||||
{
|
{
|
||||||
if (dvar && dvar->name == "sv_cheats"s)
|
if (dvar && dvar->name == "sv_cheats"s)
|
||||||
{
|
{
|
||||||
@ -110,7 +110,7 @@ namespace dvar_cheats
|
|||||||
a.jmp(0x1404F0D74);
|
a.jmp(0x1404F0D74);
|
||||||
});
|
});
|
||||||
|
|
||||||
void cg_set_client_dvar_from_server(const int local_client_num, game::mp::cg_s* cg, const char* dvar_id, const char* value)
|
void cg_set_client_dvar_from_server(const int local_client_num, game::mp::cg_t* cg, const char* dvar_id, const char* value)
|
||||||
{
|
{
|
||||||
if (dvar_id == "cg_fov"s || dvar_id == "com_maxfps"s)
|
if (dvar_id == "cg_fov"s || dvar_id == "com_maxfps"s)
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@ namespace dvar_cheats
|
|||||||
const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack
|
const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack
|
||||||
const auto* command = utils::string::va("q %s \"%s\"", dvar, value);
|
const auto* command = utils::string::va("q %s \"%s\"", dvar, value);
|
||||||
|
|
||||||
game::engine::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command);
|
game::SV_GameSendServerCommand(entity_num, 1, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a)
|
const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a)
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
|
#include "fastfiles.hpp"
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "fastfiles.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/io.hpp>
|
|
||||||
#include <utils/memory.hpp>
|
#include <utils/memory.hpp>
|
||||||
#include <utils/string.hpp>
|
#include <utils/io.hpp>
|
||||||
|
|
||||||
namespace fastfiles
|
namespace fastfiles
|
||||||
{
|
{
|
||||||
@ -22,7 +22,7 @@ namespace fastfiles
|
|||||||
void db_try_load_x_file_internal(const char* zone_name, const int zone_flags, const int is_base_map)
|
void db_try_load_x_file_internal(const char* zone_name, const int zone_flags, const int is_base_map)
|
||||||
{
|
{
|
||||||
console::info("Loading fastfile %s\n", zone_name);
|
console::info("Loading fastfile %s\n", zone_name);
|
||||||
db_try_load_x_file_internal_hook.invoke<void>(zone_name, zone_flags, is_base_map);
|
return db_try_load_x_file_internal_hook.invoke<void>(zone_name, zone_flags, is_base_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_gsc_script(const std::string& name, game::XAssetHeader header)
|
void dump_gsc_script(const std::string& name, game::XAssetHeader header)
|
||||||
@ -32,12 +32,6 @@ namespace fastfiles
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto out_name = std::format("gsc_dump/{}.gscbin", name);
|
|
||||||
if (utils::io::file_exists(out_name))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
buffer.append(header.scriptfile->name, std::strlen(header.scriptfile->name) + 1);
|
buffer.append(header.scriptfile->name, std::strlen(header.scriptfile->name) + 1);
|
||||||
buffer.append(reinterpret_cast<char*>(&header.scriptfile->compressedLen), 4);
|
buffer.append(reinterpret_cast<char*>(&header.scriptfile->compressedLen), 4);
|
||||||
@ -46,38 +40,12 @@ namespace fastfiles
|
|||||||
buffer.append(header.scriptfile->buffer, header.scriptfile->compressedLen);
|
buffer.append(header.scriptfile->buffer, header.scriptfile->compressedLen);
|
||||||
buffer.append(reinterpret_cast<char*>(header.scriptfile->bytecode), header.scriptfile->bytecodeLen);
|
buffer.append(reinterpret_cast<char*>(header.scriptfile->bytecode), header.scriptfile->bytecodeLen);
|
||||||
|
|
||||||
|
const auto out_name = std::format("gsc_dump/{}.gscbin", name);
|
||||||
utils::io::write_file(out_name, buffer);
|
utils::io::write_file(out_name, buffer);
|
||||||
|
|
||||||
console::info("Dumped %s\n", out_name.c_str());
|
console::info("Dumped %s\n", out_name.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_csv_table(const std::string& name, game::XAssetHeader header)
|
|
||||||
{
|
|
||||||
if (!dvars::g_dump_string_tables->current.enabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto out_name = std::format("csv_dump/{}.csv", name);
|
|
||||||
if (utils::io::file_exists(out_name))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string buffer;
|
|
||||||
|
|
||||||
for (auto row = 0; row < header.stringTable->rowCount; row++)
|
|
||||||
{
|
|
||||||
for (auto column = 0; column < header.stringTable->columnCount; column++)
|
|
||||||
{
|
|
||||||
const auto* string = header.stringTable->values[(row * header.stringTable->columnCount) + column].string;
|
|
||||||
buffer.append(utils::string::va("%s%s", string ? string : "", (column == header.stringTable->columnCount - 1) ? "\n" : ","));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
utils::io::write_file(out_name, buffer);
|
|
||||||
console::info("Dumped %s\n", out_name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
game::XAssetHeader db_find_x_asset_header_stub(game::XAssetType type, const char* name, int allow_create_default)
|
game::XAssetHeader db_find_x_asset_header_stub(game::XAssetType type, const char* name, int allow_create_default)
|
||||||
{
|
{
|
||||||
@ -90,11 +58,6 @@ namespace fastfiles
|
|||||||
dump_gsc_script(name, result);
|
dump_gsc_script(name, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == game::ASSET_TYPE_STRINGTABLE)
|
|
||||||
{
|
|
||||||
dump_csv_table(name, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (diff > 100)
|
if (diff > 100)
|
||||||
{
|
{
|
||||||
console::print(
|
console::print(
|
||||||
@ -147,11 +110,26 @@ namespace fastfiles
|
|||||||
|
|
||||||
db_find_x_asset_header_hook.create(game::DB_FindXAssetHeader, db_find_x_asset_header_stub);
|
db_find_x_asset_header_hook.create(game::DB_FindXAssetHeader, db_find_x_asset_header_stub);
|
||||||
dvars::g_dump_scripts = game::Dvar_RegisterBool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts to binary format");
|
dvars::g_dump_scripts = game::Dvar_RegisterBool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts to binary format");
|
||||||
dvars::g_dump_string_tables = game::Dvar_RegisterBool("g_dumpStringTables", false, game::DVAR_FLAG_NONE, "Dump CSV files");
|
|
||||||
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1402752DF, 0x140156350), p_mem_free_stub);
|
utils::hook::call(SELECT_VALUE(0x1402752DF, 0x140156350), p_mem_free_stub);
|
||||||
utils::hook::call(SELECT_VALUE(0x140276004, 0x140324259), p_mem_free_stub);
|
utils::hook::call(SELECT_VALUE(0x140276004, 0x140324259), p_mem_free_stub);
|
||||||
|
|
||||||
|
command::add("loadzone", [](const command::params& params)
|
||||||
|
{
|
||||||
|
if (params.size() < 2)
|
||||||
|
{
|
||||||
|
console::info("usage: loadzone <zone>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
game::XZoneInfo info;
|
||||||
|
info.name = params.get(1);
|
||||||
|
info.allocFlags = 1;
|
||||||
|
info.freeFlags = 0;
|
||||||
|
|
||||||
|
game::DB_LoadXAssets(&info, 1, game::DBSyncMode::DB_LOAD_SYNC);
|
||||||
|
});
|
||||||
|
|
||||||
command::add("materiallist", [](const command::params& params)
|
command::add("materiallist", [](const command::params& params)
|
||||||
{
|
{
|
||||||
game::DB_EnumXAssets_FastFile(game::ASSET_TYPE_MATERIAL, [](const game::XAssetHeader header, void*)
|
game::DB_EnumXAssets_FastFile(game::ASSET_TYPE_MATERIAL, [](const game::XAssetHeader header, void*)
|
||||||
@ -166,10 +144,6 @@ namespace fastfiles
|
|||||||
if (!game::environment::is_sp())
|
if (!game::environment::is_sp())
|
||||||
{
|
{
|
||||||
reallocate_asset_pool(game::ASSET_TYPE_WEAPON, 320);
|
reallocate_asset_pool(game::ASSET_TYPE_WEAPON, 320);
|
||||||
|
|
||||||
// Allow loading of unsigned fastfiles
|
|
||||||
utils::hook::set<uint8_t>(0x1402FBF23, 0xEB); // DB_LoadXFile
|
|
||||||
utils::hook::nop(0x1402FC445, 2); // DB_SetFileLoadCompressor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -83,22 +83,15 @@ namespace filesystem
|
|||||||
|
|
||||||
void startup()
|
void startup()
|
||||||
{
|
{
|
||||||
const auto base = std::filesystem::current_path();
|
register_path("iw6");
|
||||||
|
|
||||||
register_path(base / "iw6");
|
|
||||||
register_path(get_binary_directory() + "\\data");
|
register_path(get_binary_directory() + "\\data");
|
||||||
|
|
||||||
if (get_binary_directory() != base)
|
|
||||||
{
|
|
||||||
register_path(base / "data");
|
|
||||||
}
|
|
||||||
|
|
||||||
// game's search paths
|
// game's search paths
|
||||||
register_path(base / "devraw");
|
register_path("devraw");
|
||||||
register_path(base / "devraw_shared");
|
register_path("devraw_shared");
|
||||||
register_path(base / "raw_shared");
|
register_path("raw_shared");
|
||||||
register_path(base / "raw");
|
register_path("raw");
|
||||||
register_path(base / "main");
|
register_path("main");
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_for_startup()
|
void check_for_startup()
|
||||||
|
@ -63,7 +63,7 @@ namespace game_console
|
|||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
game::I_strncpyz(con.buffer, "", sizeof(con.buffer));
|
strncpy_s(con.buffer, "", sizeof(con.buffer));
|
||||||
con.cursor = 0;
|
con.cursor = 0;
|
||||||
|
|
||||||
fixed_input = "";
|
fixed_input = "";
|
||||||
@ -249,7 +249,7 @@ namespace game_console
|
|||||||
dvars::con_inputDvarInactiveValueColor->current.vector, offset);
|
dvars::con_inputDvarInactiveValueColor->current.vector, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::I_strncpyz(con.globals.auto_complete_choice, matches[0].data(), sizeof(con.globals.auto_complete_choice));
|
strncpy_s(con.globals.auto_complete_choice, matches[0].data(), sizeof(con.globals.auto_complete_choice));
|
||||||
con.globals.may_auto_complete = true;
|
con.globals.may_auto_complete = true;
|
||||||
}
|
}
|
||||||
else if (matches.size() > 1)
|
else if (matches.size() > 1)
|
||||||
@ -274,7 +274,7 @@ namespace game_console
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game::I_strncpyz(con.globals.auto_complete_choice, matches[0].data(), sizeof(con.globals.auto_complete_choice));
|
strncpy_s(con.globals.auto_complete_choice, matches[0].data(), sizeof(con.globals.auto_complete_choice));
|
||||||
con.globals.may_auto_complete = true;
|
con.globals.may_auto_complete = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,11 +364,11 @@ namespace game_console
|
|||||||
|
|
||||||
void print_internal(const char* fmt, ...)
|
void print_internal(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
char va_buffer[1024]{};
|
char va_buffer[0x200] = { 0 };
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(va_buffer, sizeof(va_buffer), fmt, ap);
|
vsprintf_s(va_buffer, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
const auto formatted = std::string(va_buffer);
|
const auto formatted = std::string(va_buffer);
|
||||||
@ -424,7 +424,7 @@ namespace game_console
|
|||||||
con.buffer[1] = '\0';
|
con.buffer[1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
game::I_strncat(con.buffer, sizeof(con.buffer), con.globals.auto_complete_choice);
|
strncat_s(con.buffer, con.globals.auto_complete_choice, 64);
|
||||||
con.cursor = static_cast<int>(std::string(con.buffer).length());
|
con.cursor = static_cast<int>(std::string(con.buffer).length());
|
||||||
|
|
||||||
if (con.cursor != 254)
|
if (con.cursor != 254)
|
||||||
@ -549,7 +549,7 @@ namespace game_console
|
|||||||
|
|
||||||
if (history_index != -1)
|
if (history_index != -1)
|
||||||
{
|
{
|
||||||
game::I_strncpyz(con.buffer, history.at(history_index).c_str(), sizeof(con.buffer));
|
strncpy_s(con.buffer, history.at(history_index).c_str(), sizeof(con.buffer));
|
||||||
con.cursor = static_cast<int>(strlen(con.buffer));
|
con.cursor = static_cast<int>(strlen(con.buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,7 +564,7 @@ namespace game_console
|
|||||||
|
|
||||||
if (history_index != -1)
|
if (history_index != -1)
|
||||||
{
|
{
|
||||||
game::I_strncpyz(con.buffer, history.at(history_index).c_str(), sizeof(con.buffer));
|
strncpy_s(con.buffer, history.at(history_index).c_str(), sizeof(con.buffer));
|
||||||
con.cursor = static_cast<int>(strlen(con.buffer));
|
con.cursor = static_cast<int>(strlen(con.buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,7 +674,7 @@ namespace game_console
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game::cmd_function_s* cmd = (*game::cmd_functions);
|
game::cmd_function_t* cmd = (*game::cmd_functions);
|
||||||
while (cmd)
|
while (cmd)
|
||||||
{
|
{
|
||||||
if (cmd->name)
|
if (cmd->name)
|
||||||
@ -721,7 +721,7 @@ namespace game_console
|
|||||||
con.output_visible = false;
|
con.output_visible = false;
|
||||||
con.display_line_offset = 0;
|
con.display_line_offset = 0;
|
||||||
con.line_count = 0;
|
con.line_count = 0;
|
||||||
game::I_strncpyz(con.buffer, "", sizeof(con.buffer));
|
strncpy_s(con.buffer, "", sizeof(con.buffer));
|
||||||
|
|
||||||
con.globals.x = 0.0f;
|
con.globals.x = 0.0f;
|
||||||
con.globals.y = 0.0f;
|
con.globals.y = 0.0f;
|
||||||
@ -729,7 +729,7 @@ namespace game_console
|
|||||||
con.globals.font_height = 0.0f;
|
con.globals.font_height = 0.0f;
|
||||||
con.globals.may_auto_complete = false;
|
con.globals.may_auto_complete = false;
|
||||||
con.globals.info_line_count = 0;
|
con.globals.info_line_count = 0;
|
||||||
game::I_strncpyz(con.globals.auto_complete_choice, "", sizeof(con.globals.auto_complete_choice));
|
strncpy_s(con.globals.auto_complete_choice, "", sizeof(con.globals.auto_complete_choice));
|
||||||
|
|
||||||
// add clear command
|
// add clear command
|
||||||
command::add("clear", [&]()
|
command::add("clear", [&]()
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
#include "console.hpp"
|
|
||||||
#include "game_log.hpp"
|
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
#include "scripting.hpp"
|
#include "scripting.hpp"
|
||||||
|
#include "console.hpp"
|
||||||
|
#include "game_log.hpp"
|
||||||
|
|
||||||
|
#include "gsc/script_extension.hpp"
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/io.hpp>
|
#include <utils/io.hpp>
|
||||||
@ -21,7 +23,7 @@ namespace game_log
|
|||||||
char buf[1024]{};
|
char buf[1024]{};
|
||||||
std::size_t out_chars = 0;
|
std::size_t out_chars = 0;
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < game::Scr_GetNumParam(); ++i)
|
for (auto i = 0u; i < game::Scr_GetNumParam(); ++i)
|
||||||
{
|
{
|
||||||
const auto* value = game::Scr_GetString(i);
|
const auto* value = game::Scr_GetString(i);
|
||||||
const auto len = std::strlen(value);
|
const auto len = std::strlen(value);
|
||||||
@ -32,7 +34,7 @@ namespace game_log
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::I_strncat(buf, sizeof(buf), value);
|
strncat_s(buf, value, _TRUNCATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_log_printf("%s", buf);
|
g_log_printf("%s", buf);
|
||||||
@ -47,15 +49,22 @@ namespace game_log
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[1024]{};
|
char buffer[0x400]{};
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
|
||||||
|
vsprintf_s(buffer, fmt, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
const auto time = *game::level_time / 1000;
|
const auto time = *game::level_time / 1000;
|
||||||
utils::io::write_file(log, utils::string::va("%3i:%i%i %s", time / 60, time % 60 / 10, time % 60 % 10, buffer), true);
|
utils::io::write_file(log, utils::string::va("%3i:%i%i %s",
|
||||||
|
time / 60,
|
||||||
|
time % 60 / 10,
|
||||||
|
time % 60 % 10,
|
||||||
|
buffer
|
||||||
|
), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -93,14 +102,9 @@ namespace game_log
|
|||||||
g_log_printf("InitGame\n");
|
g_log_printf("InitGame\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
scripting::on_shutdown([](const int clear_scripts, const int post_shutdown) -> void
|
scripting::on_shutdown([](int free_scripts)
|
||||||
{
|
{
|
||||||
if (post_shutdown)
|
console::info("==== ShutdownGame (%d) ====\n", free_scripts);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console::info("==== ShutdownGame (%d) ====\n", clear_scripts);
|
|
||||||
|
|
||||||
g_log_printf("ShutdownGame:\n");
|
g_log_printf("ShutdownGame:\n");
|
||||||
g_log_printf("------------------------------------------------------------\n");
|
g_log_printf("------------------------------------------------------------\n");
|
||||||
|
@ -133,7 +133,7 @@ namespace gameplay
|
|||||||
return jump_height;
|
return jump_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jump_apply_slowdown_stub(game::mp::playerState_s* ps)
|
void jump_apply_slowdown_stub(game::mp::playerState_t* ps)
|
||||||
{
|
{
|
||||||
assert(ps->pm_flags & game::PMF_JUMPING);
|
assert(ps->pm_flags & game::PMF_JUMPING);
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ namespace gameplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float jump_get_slowdown_friction(game::mp::playerState_s* ps)
|
float jump_get_slowdown_friction(game::mp::playerState_t* ps)
|
||||||
{
|
{
|
||||||
assert(ps->pm_flags & game::PMF_JUMPING);
|
assert(ps->pm_flags & game::PMF_JUMPING);
|
||||||
assert(ps->pm_time <= game::JUMP_LAND_SLOWDOWN_TIME);
|
assert(ps->pm_time <= game::JUMP_LAND_SLOWDOWN_TIME);
|
||||||
@ -181,7 +181,7 @@ namespace gameplay
|
|||||||
return 2.5f;
|
return 2.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float jump_reduce_friction_stub(game::mp::playerState_s* ps)
|
float jump_reduce_friction_stub(game::mp::playerState_t* ps)
|
||||||
{
|
{
|
||||||
float control;
|
float control;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ namespace gameplay
|
|||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
float jump_get_land_factor(game::mp::playerState_s* ps)
|
float jump_get_land_factor(game::mp::playerState_t* ps)
|
||||||
{
|
{
|
||||||
assert(ps->pm_flags & game::PMF_JUMPING);
|
assert(ps->pm_flags & game::PMF_JUMPING);
|
||||||
assert(ps->pm_time <= game::JUMP_LAND_SLOWDOWN_TIME);
|
assert(ps->pm_time <= game::JUMP_LAND_SLOWDOWN_TIME);
|
||||||
@ -219,9 +219,9 @@ namespace gameplay
|
|||||||
|
|
||||||
void jump_start_stub(game::pmove_t* pm, game::pml_t* pml, float height)
|
void jump_start_stub(game::pmove_t* pm, game::pml_t* pml, float height)
|
||||||
{
|
{
|
||||||
static_assert(offsetof(game::mp::playerState_s, groundEntityNum) == 0x70);
|
static_assert(offsetof(game::mp::playerState_t, groundEntityNum) == 0x70);
|
||||||
static_assert(offsetof(game::mp::playerState_s, pm_time) == 0x8);
|
static_assert(offsetof(game::mp::playerState_t, pm_time) == 0x8);
|
||||||
static_assert(offsetof(game::mp::playerState_s, sprintState.sprintButtonUpRequired) == 0x240);
|
static_assert(offsetof(game::mp::playerState_t, sprintState.sprintButtonUpRequired) == 0x240);
|
||||||
static_assert(offsetof(game::pml_t, frametime) == 0x24);
|
static_assert(offsetof(game::pml_t, frametime) == 0x24);
|
||||||
static_assert(offsetof(game::pml_t, walking) == 0x2C);
|
static_assert(offsetof(game::pml_t, walking) == 0x2C);
|
||||||
static_assert(offsetof(game::pml_t, groundPlane) == 0x30);
|
static_assert(offsetof(game::pml_t, groundPlane) == 0x30);
|
||||||
@ -229,9 +229,9 @@ namespace gameplay
|
|||||||
|
|
||||||
float factor;
|
float factor;
|
||||||
float velocity_sqrd;
|
float velocity_sqrd;
|
||||||
game::mp::playerState_s* ps;
|
game::mp::playerState_t* ps;
|
||||||
|
|
||||||
ps = static_cast<game::mp::playerState_s*>(pm->ps);
|
ps = static_cast<game::mp::playerState_t*>(pm->ps);
|
||||||
|
|
||||||
assert(ps);
|
assert(ps);
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ namespace gameplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_weapon_use_ammo_stub(game::playerState_s* ps, game::Weapon weapon,
|
void pm_weapon_use_ammo_stub(game::playerState_t* ps, game::Weapon weapon,
|
||||||
bool is_alternate, int amount, game::PlayerHandIndex hand)
|
bool is_alternate, int amount, game::PlayerHandIndex hand)
|
||||||
{
|
{
|
||||||
if (!dvars::player_sustainAmmo->current.enabled)
|
if (!dvars::player_sustainAmmo->current.enabled)
|
||||||
@ -304,10 +304,10 @@ namespace gameplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game::mp::gentity_s* weapon_rocket_launcher_fire_stub(game::mp::gentity_s* ent, game::Weapon weapon, float spread, game::weaponParms* wp,
|
game::mp::gentity_t* weapon_rocket_launcher_fire_stub(game::mp::gentity_t* ent, game::Weapon weapon, float spread, game::weaponParms* wp,
|
||||||
const float* gun_vel, game::mp::missileFireParms* fire_parms, bool magic_bullet)
|
const float* gun_vel, game::mp::missileFireParms* fire_parms, bool magic_bullet)
|
||||||
{
|
{
|
||||||
auto* result = utils::hook::invoke<game::mp::gentity_s*>(0x1403DB8A0, ent, weapon, spread, wp, gun_vel, fire_parms, magic_bullet);
|
auto* result = utils::hook::invoke<game::mp::gentity_t*>(0x1403DB8A0, ent, weapon, spread, wp, gun_vel, fire_parms, magic_bullet);
|
||||||
|
|
||||||
if (ent->client != nullptr && wp->weapDef->inventoryType != game::WEAPINVENTORY_EXCLUSIVE)
|
if (ent->client != nullptr && wp->weapDef->inventoryType != game::WEAPINVENTORY_EXCLUSIVE)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +113,7 @@ namespace gsc
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int scr_get_object(unsigned int index)
|
unsigned int scr_get_object(unsigned int index)
|
||||||
@ -283,23 +284,28 @@ namespace gsc
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
scr_emit_function_hook.create(SELECT_VALUE(0x1403D3350, 0x14042E150), &scr_emit_function_stub);
|
if (game::environment::is_sp())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403D32E4, 0x14042E0E4), compile_error_stub); // LinkFile
|
scr_emit_function_hook.create(0x14042E150, &scr_emit_function_stub);
|
||||||
utils::hook::call(SELECT_VALUE(0x1403D3338, 0x14042E138), compile_error_stub); // LinkFile
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403D342A, 0x14042E22B), find_variable_stub); // Scr_EmitFunction
|
utils::hook::call(0x14042E0E4, compile_error_stub); // LinkFile
|
||||||
|
utils::hook::call(0x14042E138, compile_error_stub); // LinkFile
|
||||||
|
utils::hook::call(0x14042E22B, find_variable_stub); // Scr_EmitFunction
|
||||||
|
|
||||||
// Restore basic error messages to scr functions
|
// Restore basic error messages to scr functions
|
||||||
utils::hook::jump(game::Scr_GetObject, scr_get_object);
|
utils::hook::jump(0x140438ED0, scr_get_object);
|
||||||
utils::hook::jump(game::Scr_GetConstString, scr_get_const_string);
|
utils::hook::jump(0x140438AD0, scr_get_const_string);
|
||||||
utils::hook::jump(game::Scr_GetConstIString, scr_get_const_istring);
|
utils::hook::jump(0x1404388B0, scr_get_const_istring);
|
||||||
utils::hook::jump(game::Scr_GetVector, scr_get_vector);
|
utils::hook::jump(0x1404393D0, scr_get_vector);
|
||||||
utils::hook::jump(game::Scr_GetInt, scr_get_int);
|
utils::hook::jump(0x140438E10, scr_get_int);
|
||||||
utils::hook::jump(game::Scr_GetFloat, scr_get_float);
|
utils::hook::jump(0x140438D60, scr_get_float);
|
||||||
|
|
||||||
utils::hook::jump(SELECT_VALUE(0x1403DE150, 0x1404390B0), scr_get_pointer_type);
|
utils::hook::jump(0x1404390B0, scr_get_pointer_type);
|
||||||
utils::hook::jump(SELECT_VALUE(0x1403DE320, 0x140439280), scr_get_type);
|
utils::hook::jump(0x140439280, scr_get_type);
|
||||||
utils::hook::jump(SELECT_VALUE(0x1403DE390, 0x1404392F0), scr_get_type_name);
|
utils::hook::jump(0x1404392F0, scr_get_type_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
|
@ -37,60 +37,9 @@ namespace gsc
|
|||||||
bool force_error_print = false;
|
bool force_error_print = false;
|
||||||
std::optional<std::string> gsc_error_msg;
|
std::optional<std::string> gsc_error_msg;
|
||||||
|
|
||||||
std::vector<devmap_entry> devmap_entries{};
|
|
||||||
|
|
||||||
std::optional<devmap_entry> get_devmap_entry(const std::uint8_t* codepos)
|
|
||||||
{
|
|
||||||
const auto itr = std::ranges::find_if(devmap_entries, [codepos](const devmap_entry& entry) -> bool
|
|
||||||
{
|
|
||||||
return codepos >= entry.bytecode && codepos < entry.bytecode + entry.size;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (itr != devmap_entries.end())
|
|
||||||
{
|
|
||||||
return *itr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::pair<std::uint16_t, std::uint16_t>> get_line_and_col_for_codepos(const std::uint8_t* codepos)
|
|
||||||
{
|
|
||||||
const auto entry = get_devmap_entry(codepos);
|
|
||||||
|
|
||||||
if (!entry.has_value())
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::pair<std::uint16_t, std::uint16_t>> best_line_info{};
|
|
||||||
std::uint32_t best_codepos = 0;
|
|
||||||
|
|
||||||
assert(codepos >= entry->bytecode);
|
|
||||||
const std::uint32_t codepos_offset = static_cast<std::uint32_t>(codepos - entry->bytecode);
|
|
||||||
|
|
||||||
for (const auto& instruction : entry->devmap)
|
|
||||||
{
|
|
||||||
if (instruction.codepos > codepos_offset)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best_line_info.has_value() && codepos_offset - instruction.codepos > codepos_offset - best_codepos)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
best_line_info = { { instruction.line, instruction.col } };
|
|
||||||
best_codepos = instruction.codepos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return best_line_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int scr_get_function_stub(const char** p_name, int* type)
|
unsigned int scr_get_function_stub(const char** p_name, int* type)
|
||||||
{
|
{
|
||||||
const auto result = game::Scr_GetFunction(p_name, type);
|
const auto result = utils::hook::invoke<unsigned int>(0x1403CD9F0, p_name, type);
|
||||||
|
|
||||||
for (const auto& [name, func] : functions)
|
for (const auto& [name, func] : functions)
|
||||||
{
|
{
|
||||||
@ -171,36 +120,27 @@ namespace gsc
|
|||||||
const auto pos = frame == game::scr_VmPub->function_frame ? game::scr_function_stack->pos : frame->fs.pos;
|
const auto pos = frame == game::scr_VmPub->function_frame ? game::scr_function_stack->pos : frame->fs.pos;
|
||||||
const auto function = find_function(frame->fs.pos);
|
const auto function = find_function(frame->fs.pos);
|
||||||
|
|
||||||
const char* location;
|
|
||||||
if (function.has_value())
|
if (function.has_value())
|
||||||
{
|
{
|
||||||
location = utils::string::va("function \"%s\" in file \"%s\"", function.value().first.data(), function.value().second.data());
|
console::warn("\tat function \"%s\" in file \"%s.gsc\"\n", function.value().first.data(), function.value().second.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
location = utils::string::va("unknown location %p", pos);
|
console::warn("\tat unknown location %p\n", pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto line_info = get_line_and_col_for_codepos(reinterpret_cast<const std::uint8_t*>(pos));
|
|
||||||
if (line_info.has_value())
|
|
||||||
{
|
|
||||||
location = utils::string::va("%s line \"%d\" column \"%d\"", location, line_info->first, line_info->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
console::warn("\tat %s\n", location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_error_stub(const unsigned __int64 mark_pos)
|
void vm_error_stub(int mark_pos)
|
||||||
{
|
{
|
||||||
if (!dvars::com_developer_script->current.enabled && !force_error_print)
|
if (!dvars::com_developer_script->current.enabled && !force_error_print)
|
||||||
{
|
{
|
||||||
game::LargeLocalResetToMark(mark_pos);
|
utils::hook::invoke<void>(0x1404E4D00, mark_pos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console::warn("******* script runtime error ********\n");
|
console::warn("******* script runtime error ********\n");
|
||||||
const auto opcode_id = *reinterpret_cast<std::uint8_t*>(SELECT_VALUE(0x1455BE740, 0x144D57840));
|
const auto opcode_id = *reinterpret_cast<std::uint8_t*>(0x144D57840);
|
||||||
|
|
||||||
const std::string error = gsc_error_msg.has_value() ? std::format(": {}", gsc_error_msg.value()) : std::string();
|
const std::string error = gsc_error_msg.has_value() ? std::format(": {}", gsc_error_msg.value()) : std::string();
|
||||||
|
|
||||||
@ -226,7 +166,7 @@ namespace gsc
|
|||||||
|
|
||||||
print_callstack();
|
print_callstack();
|
||||||
console::warn("************************************\n");
|
console::warn("************************************\n");
|
||||||
game::LargeLocalResetToMark(mark_pos);
|
utils::hook::invoke<void>(0x1404E4D00, mark_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inc_in_param()
|
void inc_in_param()
|
||||||
@ -288,22 +228,6 @@ namespace gsc
|
|||||||
scr_error(utils::string::va("Assert fail: %s", game::Scr_GetString(0)));
|
scr_error(utils::string::va("Assert fail: %s", game::Scr_GetString(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void scr_cmd_is_dedicated_server()
|
|
||||||
{
|
|
||||||
game::Scr_AddInt(game::environment::is_dedi());
|
|
||||||
}
|
|
||||||
|
|
||||||
void scr_bot_auto_connect_enabled()
|
|
||||||
{
|
|
||||||
if (game::environment::is_dedi() && dvars::sv_botsAutoJoin->current.enabled)
|
|
||||||
{
|
|
||||||
game::Scr_AddInt(1); // 2 seems to be unused (incomplete GSC/game mode)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
game::Scr_AddInt(game::BG_BotsConnectType());
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* get_code_pos(const int index)
|
const char* get_code_pos(const int index)
|
||||||
{
|
{
|
||||||
if (static_cast<unsigned int>(index) >= game::scr_VmPub->outparamcount)
|
if (static_cast<unsigned int>(index) >= game::scr_VmPub->outparamcount)
|
||||||
@ -324,22 +248,6 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_devmap_entry(std::uint8_t* codepos, std::size_t size, const std::string& name, xsk::gsc::buffer devmap_buf)
|
|
||||||
{
|
|
||||||
std::vector<dev_map_instruction> devmap{};
|
|
||||||
const auto* devmap_ptr = reinterpret_cast<const dev_map*>(devmap_buf.data);
|
|
||||||
|
|
||||||
devmap.resize(devmap_ptr->num_instructions);
|
|
||||||
std::memcpy(devmap.data(), devmap_ptr->instructions, sizeof(dev_map_instruction) * devmap_ptr->num_instructions);
|
|
||||||
|
|
||||||
devmap_entries.emplace_back(codepos, size, name, std::move(devmap));
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_devmap()
|
|
||||||
{
|
|
||||||
devmap_entries.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_function(const std::string& name, game::BuiltinFunction function)
|
void add_function(const std::string& name, game::BuiltinFunction function)
|
||||||
{
|
{
|
||||||
++function_id_start;
|
++function_id_start;
|
||||||
@ -363,18 +271,27 @@ namespace gsc
|
|||||||
utils::hook::set<game::BuiltinFunction>(SELECT_VALUE(0x14086F468, 0x1409E6CE8), scr_print);
|
utils::hook::set<game::BuiltinFunction>(SELECT_VALUE(0x14086F468, 0x1409E6CE8), scr_print);
|
||||||
utils::hook::set<game::BuiltinFunction>(SELECT_VALUE(0x14086F480, 0x1409E6D00), scr_print_ln);
|
utils::hook::set<game::BuiltinFunction>(SELECT_VALUE(0x14086F480, 0x1409E6D00), scr_print_ln);
|
||||||
|
|
||||||
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403D353B + 1, 0x14042E33B + 1), 0x1000); // Scr_RegisterFunction
|
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403D353C, 0x14042E33C), 0x1000); // Scr_RegisterFunction
|
||||||
|
|
||||||
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403D3542 + 4, 0x14042E342 + 4), RVA(&func_table)); // Scr_RegisterFunction
|
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403D3542 + 4, 0x14042E342 + 4), RVA(&func_table)); // Scr_RegisterFunction
|
||||||
// utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403E0BDD + 3, 0x14043BBBE + 3), RVA(&func_table)); // VM_Execute_0
|
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x1403E0BDD + 3, 0x14043BBBE + 3), RVA(&func_table)); // VM_Execute_0
|
||||||
utils::hook::inject(SELECT_VALUE(0x1403D38E4 + 3, 0x14042E734 + 3), &func_table); // Scr_BeginLoadScripts
|
utils::hook::inject(SELECT_VALUE(0x1403D38E4 + 3, 0x14042E734 + 3), &func_table); // Scr_BeginLoadScripts
|
||||||
|
|
||||||
utils::hook::nop(SELECT_VALUE(0x1403E0BDD + 5, 0x14043BBBE + 5), 2);
|
if (game::environment::is_sp())
|
||||||
utils::hook::call(SELECT_VALUE(0x1403E0BDD, 0x14043BBBE), vm_call_builtin_function);
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403D391F, 0x14042E76F), scr_get_function_stub);
|
utils::hook::nop(0x14043BBBE + 5, 2);
|
||||||
|
utils::hook::call(0x14043BBBE, vm_call_builtin_function);
|
||||||
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403E1ED0, 0x14043CEB1), vm_error_stub);
|
utils::hook::call(0x14043CEB1, vm_error_stub);
|
||||||
|
|
||||||
|
utils::hook::call(0x14042E76F, scr_get_function_stub);
|
||||||
|
|
||||||
|
utils::hook::set<game::BuiltinFunction>(0x1409E6E38, assert_ex_cmd);
|
||||||
|
utils::hook::set<game::BuiltinFunction>(0x1409E6E50, assert_msg_cmd);
|
||||||
|
utils::hook::set<game::BuiltinFunction>(0x1409E6E20, assert_cmd);
|
||||||
|
|
||||||
add_function("replacefunc", []
|
add_function("replacefunc", []
|
||||||
{
|
{
|
||||||
@ -392,19 +309,10 @@ namespace gsc
|
|||||||
command::execute(cmd);
|
command::execute(cmd);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
add_function("isdedicated", []
|
||||||
{
|
{
|
||||||
return;
|
game::Scr_AddInt(game::environment::is_dedi());
|
||||||
}
|
});
|
||||||
|
|
||||||
utils::hook::set<game::BuiltinFunction>(0x1409E6E38, assert_ex_cmd);
|
|
||||||
utils::hook::set<game::BuiltinFunction>(0x1409E6E50, assert_msg_cmd);
|
|
||||||
utils::hook::set<game::BuiltinFunction>(0x1409E6E20, assert_cmd);
|
|
||||||
|
|
||||||
utils::hook::set<game::BuiltinFunction>(0x1409E94D0, scr_cmd_is_dedicated_server);
|
|
||||||
|
|
||||||
dvars::sv_botsAutoJoin = game::Dvar_RegisterBool("sv_botsAutoJoin", false, game::DVAR_FLAG_NONE, "");
|
|
||||||
utils::hook::set<game::BuiltinFunction>(0x1409E92F0, scr_bot_auto_connect_enabled);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <xsk/gsc/engine/iw6_pc.hpp>
|
|
||||||
|
|
||||||
namespace gsc
|
namespace gsc
|
||||||
{
|
{
|
||||||
extern void* func_table[0x1000];
|
extern void* func_table[0x1000];
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
struct dev_map_instruction
|
|
||||||
{
|
|
||||||
std::uint32_t codepos;
|
|
||||||
std::uint16_t line;
|
|
||||||
std::uint16_t col;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dev_map
|
|
||||||
{
|
|
||||||
std::uint32_t num_instructions;
|
|
||||||
dev_map_instruction instructions[1];
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
struct devmap_entry
|
|
||||||
{
|
|
||||||
const std::uint8_t* bytecode;
|
|
||||||
std::size_t size;
|
|
||||||
std::string script_name;
|
|
||||||
std::vector<dev_map_instruction> devmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
void add_devmap_entry(std::uint8_t*, std::size_t, const std::string&, xsk::gsc::buffer);
|
|
||||||
void clear_devmap();
|
|
||||||
|
|
||||||
void add_function(const std::string& name, game::BuiltinFunction function);
|
void add_function(const std::string& name, game::BuiltinFunction function);
|
||||||
|
|
||||||
void scr_error(const char* error);
|
void scr_error(const char* error);
|
||||||
|
@ -3,16 +3,15 @@
|
|||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
#include <utils/compression.hpp>
|
|
||||||
#include <utils/hook.hpp>
|
|
||||||
#include <utils/io.hpp>
|
#include <utils/io.hpp>
|
||||||
|
#include <utils/hook.hpp>
|
||||||
#include <utils/memory.hpp>
|
#include <utils/memory.hpp>
|
||||||
|
#include <utils/compression.hpp>
|
||||||
|
|
||||||
#include "component/console.hpp"
|
|
||||||
#include "component/filesystem.hpp"
|
#include "component/filesystem.hpp"
|
||||||
|
#include "component/console.hpp"
|
||||||
#include "component/scripting.hpp"
|
#include "component/scripting.hpp"
|
||||||
|
|
||||||
#include "script_extension.hpp"
|
|
||||||
#include "script_loading.hpp"
|
#include "script_loading.hpp"
|
||||||
|
|
||||||
namespace gsc
|
namespace gsc
|
||||||
@ -33,7 +32,6 @@ namespace gsc
|
|||||||
init_handles.clear();
|
init_handles.clear();
|
||||||
loaded_scripts.clear();
|
loaded_scripts.clear();
|
||||||
script_allocator.clear();
|
script_allocator.clear();
|
||||||
clear_devmap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_raw_script_file(const std::string& name, std::string* data)
|
bool read_raw_script_file(const std::string& name, std::string* data)
|
||||||
@ -116,12 +114,6 @@ namespace gsc
|
|||||||
|
|
||||||
loaded_scripts[real_name] = script_file_ptr;
|
loaded_scripts[real_name] = script_file_ptr;
|
||||||
|
|
||||||
const auto devmap = std::get<2>(output_script);
|
|
||||||
if (devmap.size > 0 && (gsc_ctx->build() & xsk::gsc::build::dev_maps) != xsk::gsc::build::prod)
|
|
||||||
{
|
|
||||||
add_devmap_entry(script_file_ptr->bytecode, byte_code_size, real_name, devmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return script_file_ptr;
|
return script_file_ptr;
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
@ -188,9 +180,13 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_scripts_from_folder(const std::filesystem::path& root_dir, const std::filesystem::path& script_dir)
|
void load_scripts(const std::filesystem::path& root_dir)
|
||||||
{
|
{
|
||||||
console::info("Scanning directory '%s' for custom GSC scripts...\n", script_dir.generic_string().data());
|
const std::filesystem::path script_dir = root_dir / "scripts";
|
||||||
|
if (!utils::io::directory_exists(script_dir.generic_string()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto scripts = utils::io::list_files(script_dir.generic_string());
|
const auto scripts = utils::io::list_files(script_dir.generic_string());
|
||||||
for (const auto& script : scripts)
|
for (const auto& script : scripts)
|
||||||
@ -208,44 +204,6 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_scripts(const std::filesystem::path& root_dir)
|
|
||||||
{
|
|
||||||
const auto load = [&root_dir](const std::filesystem::path& folder) -> void
|
|
||||||
{
|
|
||||||
const std::filesystem::path script_dir = root_dir / folder;
|
|
||||||
if (utils::io::directory_exists(script_dir.generic_string()))
|
|
||||||
{
|
|
||||||
load_scripts_from_folder(root_dir, script_dir);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::filesystem::path base_dir = "scripts";
|
|
||||||
|
|
||||||
load(base_dir);
|
|
||||||
|
|
||||||
const auto* map_name = game::Dvar_FindVar("mapname");
|
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
|
||||||
{
|
|
||||||
const std::filesystem::path game_folder = "sp";
|
|
||||||
|
|
||||||
load(base_dir / game_folder);
|
|
||||||
|
|
||||||
load(base_dir / game_folder / map_name->current.string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const std::filesystem::path game_folder = "mp";
|
|
||||||
|
|
||||||
load(base_dir / game_folder);
|
|
||||||
|
|
||||||
load(base_dir / game_folder / map_name->current.string);
|
|
||||||
|
|
||||||
const auto* game_type = game::Dvar_FindVar("g_gametype");
|
|
||||||
load(base_dir / game_folder / game_type->current.string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int db_is_x_asset_default(game::XAssetType type, const char* name)
|
int db_is_x_asset_default(game::XAssetType type, const char* name)
|
||||||
{
|
{
|
||||||
if (loaded_scripts.contains(name))
|
if (loaded_scripts.contains(name))
|
||||||
@ -260,22 +218,12 @@ namespace gsc
|
|||||||
{
|
{
|
||||||
utils::hook::invoke<void>(0x1403CCB10);
|
utils::hook::invoke<void>(0x1403CCB10);
|
||||||
|
|
||||||
for (const auto& path : filesystem::get_search_paths())
|
clear();
|
||||||
{
|
|
||||||
load_scripts(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int g_scr_load_script_and_label_stub(game::ScriptFunctions* functions)
|
|
||||||
{
|
|
||||||
const auto result = utils::hook::invoke<int>(0x140349790, functions);
|
|
||||||
|
|
||||||
for (const auto& path : filesystem::get_search_paths())
|
for (const auto& path : filesystem::get_search_paths())
|
||||||
{
|
{
|
||||||
load_scripts(path);
|
load_scripts(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void db_get_raw_buffer_stub(const game::RawFile* rawfile, char* buf, const int size)
|
void db_get_raw_buffer_stub(const game::RawFile* rawfile, char* buf, const int size)
|
||||||
@ -302,26 +250,7 @@ namespace gsc
|
|||||||
utils::hook::invoke<void>(0x1403D2CA0);
|
utils::hook::invoke<void>(0x1403D2CA0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scr_load_level_singleplayer_stub()
|
void scr_load_level_stub()
|
||||||
{
|
|
||||||
for (auto& function_handle : main_handles)
|
|
||||||
{
|
|
||||||
console::info("Executing '%s::main'\n", function_handle.first.data());
|
|
||||||
const auto thread = game::Scr_ExecThread(static_cast<int>(function_handle.second), 0);
|
|
||||||
game::RemoveRefToObject(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
utils::hook::invoke<void>(0x1403401B0);
|
|
||||||
|
|
||||||
for (auto& function_handle : init_handles)
|
|
||||||
{
|
|
||||||
console::info("Executing '%s::init'\n", function_handle.first.data());
|
|
||||||
const auto thread = game::Scr_ExecThread(static_cast<int>(function_handle.second), 0);
|
|
||||||
game::RemoveRefToObject(thread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scr_load_level_multiplayer_stub()
|
|
||||||
{
|
{
|
||||||
utils::hook::invoke<void>(0x1403CDC60);
|
utils::hook::invoke<void>(0x1403CDC60);
|
||||||
|
|
||||||
@ -403,7 +332,7 @@ namespace gsc
|
|||||||
public:
|
public:
|
||||||
loading()
|
loading()
|
||||||
{
|
{
|
||||||
gsc_ctx = std::make_unique<xsk::gsc::iw6_pc::context>(xsk::gsc::instance::server);
|
gsc_ctx = std::make_unique<xsk::gsc::iw6_pc::context>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
@ -416,35 +345,31 @@ namespace gsc
|
|||||||
utils::hook::call(SELECT_VALUE(0x14032D1E0, 0x1403CCED9), scr_begin_load_scripts_stub); // GScr_LoadScripts
|
utils::hook::call(SELECT_VALUE(0x14032D1E0, 0x1403CCED9), scr_begin_load_scripts_stub); // GScr_LoadScripts
|
||||||
utils::hook::call(SELECT_VALUE(0x14032D345, 0x1403CD08D), scr_end_load_scripts_stub); // GScr_LoadScripts
|
utils::hook::call(SELECT_VALUE(0x14032D345, 0x1403CD08D), scr_end_load_scripts_stub); // GScr_LoadScripts
|
||||||
|
|
||||||
// ProcessScript
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403DC887, 0x1404378D7), find_script);
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403DC897, 0x1404378E7), db_is_x_asset_default);
|
|
||||||
|
|
||||||
dvars::com_developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
|
dvars::com_developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
|
||||||
|
|
||||||
scripting::on_shutdown([](const int clear_scripts, const int post_shutdown) -> void
|
if (game::environment::is_sp())
|
||||||
{
|
{
|
||||||
if (clear_scripts && post_shutdown)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessScript
|
||||||
|
utils::hook::call(0x1404378D7, find_script);
|
||||||
|
utils::hook::call(0x1404378E7, db_is_x_asset_default);
|
||||||
|
|
||||||
|
// GScr_LoadScripts
|
||||||
|
utils::hook::call(0x1403CD009, gscr_load_game_type_script_stub);
|
||||||
|
|
||||||
|
// Exec script handles
|
||||||
|
utils::hook::call(0x14039F64E, g_load_structs_stub);
|
||||||
|
utils::hook::call(0x14039F653, scr_load_level_stub);
|
||||||
|
|
||||||
|
scripting::on_shutdown([](int free_scripts)
|
||||||
|
{
|
||||||
|
if (free_scripts)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
|
||||||
{
|
|
||||||
utils::hook::call(0x14034996F, g_scr_load_script_and_label_stub);
|
|
||||||
|
|
||||||
utils::hook::call(0x140316591, scr_load_level_singleplayer_stub);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// GScr_LoadScripts
|
|
||||||
utils::hook::call(0x1403CD009, gscr_load_game_type_script_stub);
|
|
||||||
|
|
||||||
// Exec script handles
|
|
||||||
utils::hook::call(0x14039F64E, g_load_structs_stub);
|
|
||||||
utils::hook::call(0x14039F653, scr_load_level_multiplayer_stub);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,43 @@ namespace logger
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
utils::hook::detour com_error_hook;
|
||||||
|
|
||||||
const game::dvar_t* logger_dev = nullptr;
|
const game::dvar_t* logger_dev = nullptr;
|
||||||
|
|
||||||
|
void print_com_error(int, const char* msg, ...)
|
||||||
|
{
|
||||||
|
char buffer[2048]{};
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
console::error("%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_error_stub(const int error, const char* msg, ...)
|
||||||
|
{
|
||||||
|
char buffer[2048]{};
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
console::error("Error: %s\n", buffer);
|
||||||
|
|
||||||
|
com_error_hook.invoke<void>(error, "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void print_warning(const char* msg, ...)
|
void print_warning(const char* msg, ...)
|
||||||
{
|
{
|
||||||
char buffer[2048]{};
|
char buffer[2048]{};
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
vsnprintf(buffer, sizeof(buffer), msg, ap);
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
console::warn("%s", buffer);
|
console::warn("%s", buffer);
|
||||||
@ -30,7 +58,7 @@ namespace logger
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
vsnprintf(buffer, sizeof(buffer), msg, ap);
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
console::info("%s", buffer);
|
console::info("%s", buffer);
|
||||||
@ -47,7 +75,7 @@ namespace logger
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
vsnprintf(buffer, sizeof(buffer), msg, ap);
|
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
console::info("%s", buffer);
|
console::info("%s", buffer);
|
||||||
@ -113,6 +141,13 @@ namespace logger
|
|||||||
sub_1401DAA40();
|
sub_1401DAA40();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!game::environment::is_sp())
|
||||||
|
{
|
||||||
|
utils::hook::call(0x140501AE3, print_com_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
com_error_hook.create(game::Com_Error, com_error_stub);
|
||||||
|
|
||||||
// Make havok script's print function actually print
|
// Make havok script's print function actually print
|
||||||
utils::hook::jump(SELECT_VALUE(0x1406283A4, 0x140732184), print);
|
utils::hook::jump(SELECT_VALUE(0x1406283A4, 0x140732184), print);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace map_rotation
|
|||||||
console::error("%s: %s contains invalid data!\n", ex.what(), sv_map_rotation->name);
|
console::error("%s: %s contains invalid data!\n", ex.what(), sv_map_rotation->name);
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
console::info("dedicated_rotation size after parsing is '%llu'\n", dedicated_rotation.get_entries_size());
|
console::info("dedicated_rotation size after parsing is '%llu'", dedicated_rotation.get_entries_size());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,234 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include "loader/component_loader.hpp"
|
|
||||||
#include "game/game.hpp"
|
|
||||||
#include "game/dvars.hpp"
|
|
||||||
|
|
||||||
#include "command.hpp"
|
|
||||||
#include "console.hpp"
|
|
||||||
#include "mods.hpp"
|
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
|
||||||
#include <utils/string.hpp>
|
|
||||||
|
|
||||||
namespace mods
|
|
||||||
{
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
utils::hook::detour sys_create_file_hook;
|
|
||||||
|
|
||||||
void db_build_os_path_from_source(const char* zone_name, game::FF_DIR source, int size, char* filename)
|
|
||||||
{
|
|
||||||
char user_map[MAX_PATH]{};
|
|
||||||
|
|
||||||
switch (source)
|
|
||||||
{
|
|
||||||
case game::FFD_DEFAULT:
|
|
||||||
(void)game::Com_sprintf(filename, size, "%s\\%s.ff", std::filesystem::current_path().string().c_str(), zone_name);
|
|
||||||
break;
|
|
||||||
case game::FFD_MOD_DIR:
|
|
||||||
assert(mods::is_using_mods());
|
|
||||||
|
|
||||||
(void)game::Com_sprintf(filename, size, "%s\\%s\\%s.ff", std::filesystem::current_path().string().c_str(), (*dvars::fs_gameDirVar)->current.string, zone_name);
|
|
||||||
break;
|
|
||||||
case game::FFD_USER_MAP:
|
|
||||||
game::I_strncpyz(user_map, zone_name, sizeof(user_map));
|
|
||||||
|
|
||||||
(void)game::Com_sprintf(filename, size, "%s\\%s\\%s\\%s.ff", std::filesystem::current_path().string().c_str(), "usermaps", user_map, zone_name);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false && "inconceivable");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game::Sys_File sys_create_file_stub(const char* dir, const char* filename)
|
|
||||||
{
|
|
||||||
auto result = sys_create_file_hook.invoke<game::Sys_File>(dir, filename);
|
|
||||||
|
|
||||||
if (result.handle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_using_mods())
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .ff extension was added previously
|
|
||||||
if (!std::strcmp(filename, "mod.ff") && mods::db_mod_file_exists())
|
|
||||||
{
|
|
||||||
char file_path[MAX_PATH]{};
|
|
||||||
db_build_os_path_from_source("mod", game::FFD_MOD_DIR, sizeof(file_path), file_path);
|
|
||||||
result.handle = game::Sys_OpenFileReliable(file_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void db_load_x_assets_stub(game::XZoneInfo* zone_info, unsigned int zone_count, game::DBSyncMode sync_mode)
|
|
||||||
{
|
|
||||||
std::vector<game::XZoneInfo> zones(zone_info, zone_info + zone_count);
|
|
||||||
|
|
||||||
if (db_mod_file_exists())
|
|
||||||
{
|
|
||||||
zones.emplace_back("mod", game::DB_ZONE_COMMON | game::DB_ZONE_CUSTOM, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
game::DB_LoadXAssets(zones.data(), static_cast<unsigned int>(zones.size()), sync_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto skip_extra_zones_stub = utils::hook::assemble([](utils::hook::assembler& a)
|
|
||||||
{
|
|
||||||
const auto skip = a.newLabel();
|
|
||||||
const auto original = a.newLabel();
|
|
||||||
|
|
||||||
a.pushad64();
|
|
||||||
a.test(ebp, game::DB_ZONE_CUSTOM); // allocFlags
|
|
||||||
a.jnz(skip);
|
|
||||||
|
|
||||||
a.bind(original);
|
|
||||||
a.popad64();
|
|
||||||
a.mov(rdx, 0x140835F28);
|
|
||||||
a.mov(rcx, rsi);
|
|
||||||
a.call_aligned(strcmp);
|
|
||||||
a.jmp(0x1403217C0);
|
|
||||||
|
|
||||||
a.bind(skip);
|
|
||||||
a.popad64();
|
|
||||||
a.mov(r15d, 0x80);
|
|
||||||
a.not_(r15d);
|
|
||||||
a.and_(ebp, r15d);
|
|
||||||
a.jmp(0x1403217F6);
|
|
||||||
});
|
|
||||||
|
|
||||||
bool fs_game_dir_domain_func(game::dvar_t* dvar, game::DvarValue new_value)
|
|
||||||
{
|
|
||||||
if (*new_value.string == '\0')
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game::I_strnicmp(new_value.string, "mods", 4) != 0)
|
|
||||||
{
|
|
||||||
game::LiveStorage_StatsWriteNotNeeded(game::CONTROLLER_INDEX_0);
|
|
||||||
console::error("ERROR: Invalid server value '%s' for '%s'\n", new_value.string, dvar->name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (5 < std::strlen(new_value.string) && (new_value.string[4] == '\\' || new_value.string[4] == '/'))
|
|
||||||
{
|
|
||||||
const auto* s1 = std::strstr(new_value.string, "..");
|
|
||||||
const auto* s2 = std::strstr(new_value.string, "::");
|
|
||||||
if (s1 == nullptr && s2 == nullptr)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
game::LiveStorage_StatsWriteNotNeeded(game::CONTROLLER_INDEX_0);
|
|
||||||
console::error("ERROR: Invalid server value '%s' for '%s'\n", new_value.string, dvar->name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid path specified
|
|
||||||
game::LiveStorage_StatsWriteNotNeeded(game::CONTROLLER_INDEX_0);
|
|
||||||
console::error("ERROR: Invalid server value '%s' for '%s'\n", new_value.string, dvar->name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_using_mods()
|
|
||||||
{
|
|
||||||
return (*dvars::fs_gameDirVar) && *(*dvars::fs_gameDirVar)->current.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool db_mod_file_exists()
|
|
||||||
{
|
|
||||||
if (!*(*dvars::fs_gameDirVar)->current.string)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char filename[MAX_PATH]{};
|
|
||||||
db_build_os_path_from_source("mod", game::FFD_MOD_DIR, sizeof(filename), filename);
|
|
||||||
|
|
||||||
if (auto zone_file = game::Sys_OpenFileReliable(filename); zone_file != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
::CloseHandle(zone_file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
class component final : public component_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static_assert(sizeof(game::Sys_File) == 8);
|
|
||||||
|
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
dvars::fs_gameDirVar = reinterpret_cast<game::dvar_t**>(SELECT_VALUE(0x145856D38, 0x147876000));
|
|
||||||
|
|
||||||
// Remove DVAR_INIT from fs_game
|
|
||||||
utils::hook::set<std::uint32_t>(SELECT_VALUE(0x14041C085 + 2, 0x1404DDA45 + 2), SELECT_VALUE(game::DVAR_FLAG_NONE, game::DVAR_FLAG_SERVERINFO));
|
|
||||||
|
|
||||||
utils::hook::inject(SELECT_VALUE(0x14041C097 + 3, 0x1404DDA57 + 3), &fs_game_dir_domain_func);
|
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't load eng_ + patch_ with loadzone
|
|
||||||
utils::hook::nop(0x1403217B1, 15);
|
|
||||||
utils::hook::jump(0x1403217B1, skip_extra_zones_stub, true);
|
|
||||||
|
|
||||||
// Add custom zone paths
|
|
||||||
sys_create_file_hook.create(game::Sys_CreateFile, sys_create_file_stub);
|
|
||||||
|
|
||||||
// Load mod.ff
|
|
||||||
utils::hook::call(0x1405E7113, db_load_x_assets_stub); // R_LoadGraphicsAssets According to myself but I don't remember where I got it from
|
|
||||||
|
|
||||||
command::add("loadmod", [](const command::params& params) -> void
|
|
||||||
{
|
|
||||||
if (params.size() != 2)
|
|
||||||
{
|
|
||||||
console::info("USAGE: %s \"mods/<mod name>\"", params.get(0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string mod_name = utils::string::to_lower(params.get(1));
|
|
||||||
|
|
||||||
if (!mod_name.empty() && !mod_name.starts_with("mods/"))
|
|
||||||
{
|
|
||||||
mod_name = "mods/" + mod_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change fs_game if needed
|
|
||||||
if (mod_name != (*dvars::fs_gameDirVar)->current.string)
|
|
||||||
{
|
|
||||||
game::Dvar_SetString((*dvars::fs_gameDirVar), mod_name.c_str());
|
|
||||||
command::execute("vid_restart\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
command::add("unloadmod", [](const command::params& params) -> void
|
|
||||||
{
|
|
||||||
if (*dvars::fs_gameDirVar == nullptr || *(*dvars::fs_gameDirVar)->current.string == '\0')
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
game::Dvar_SetString(*dvars::fs_gameDirVar, "");
|
|
||||||
command::execute("vid_restart\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: without a way to monitor all the ways fs_game can be changed there is no way to detect when we
|
|
||||||
// should unregister the path from the internal filesystem we use
|
|
||||||
// HINT: It could be done in fs_game_dir_domain_func, but I haven't tested if that's the best place to monitor for changes and register/unregister the mods folder
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_COMPONENT(mods::component)
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace mods
|
|
||||||
{
|
|
||||||
bool is_using_mods();
|
|
||||||
bool db_mod_file_exists();
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ namespace network
|
|||||||
return callbacks;
|
return callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_command(game::netadr_s* address, const char* command, game::msg_t* message)
|
bool handle_command(game::netadr_t* address, const char* command, game::msg_t* message)
|
||||||
{
|
{
|
||||||
const auto cmd_string = utils::string::to_lower(command);
|
const auto cmd_string = utils::string::to_lower(command);
|
||||||
auto& callbacks = get_callbacks();
|
auto& callbacks = get_callbacks();
|
||||||
@ -61,7 +61,7 @@ namespace network
|
|||||||
a.jmp(0x1402C64EE);
|
a.jmp(0x1402C64EE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_compare_base_address(const game::netadr_s* a1, const game::netadr_s* a2)
|
int net_compare_base_address(const game::netadr_t* a1, const game::netadr_t* a2)
|
||||||
{
|
{
|
||||||
if (a1->type == a2->type)
|
if (a1->type == a2->type)
|
||||||
{
|
{
|
||||||
@ -83,12 +83,12 @@ namespace network
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_compare_address(const game::netadr_s* a1, const game::netadr_s* a2)
|
int net_compare_address(const game::netadr_t* a1, const game::netadr_t* a2)
|
||||||
{
|
{
|
||||||
return net_compare_base_address(a1, a2) && a1->port == a2->port;
|
return net_compare_base_address(a1, a2) && a1->port == a2->port;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reconnect_migrated_client(game::mp::client_t*, game::netadr_s* from, const int, const int, const char*, const char*, bool)
|
void reconnect_migrated_client(game::mp::client_t*, game::netadr_t* from, const int, const int, const char*, const char*, bool)
|
||||||
{
|
{
|
||||||
// This happens when a client tries to rejoin after being recently disconnected, OR by a duplicated guid
|
// This happens when a client tries to rejoin after being recently disconnected, OR by a duplicated guid
|
||||||
// We don't want this to do anything. It decides to crash seemingly randomly
|
// We don't want this to do anything. It decides to crash seemingly randomly
|
||||||
@ -107,14 +107,14 @@ namespace network
|
|||||||
get_callbacks()[utils::string::to_lower(command)] = callback;
|
get_callbacks()[utils::string::to_lower(command)] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dw_send_to_stub(const int size, const char* src, game::netadr_s* addr)
|
int dw_send_to_stub(const int size, const char* src, game::netadr_t* addr)
|
||||||
{
|
{
|
||||||
sockaddr s = {};
|
sockaddr s = {};
|
||||||
game::NetadrToSockadr(addr, &s);
|
game::NetadrToSockadr(addr, &s);
|
||||||
return sendto(*game::query_socket, src, size, 0, &s, 16) >= 0;
|
return sendto(*game::query_socket, src, size, 0, &s, 16) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(const game::netadr_s& address, const std::string& command, const std::string& data, const char separator)
|
void send(const game::netadr_t& address, const std::string& command, const std::string& data, const char separator)
|
||||||
{
|
{
|
||||||
std::string packet = "\xFF\xFF\xFF\xFF";
|
std::string packet = "\xFF\xFF\xFF\xFF";
|
||||||
packet.append(command);
|
packet.append(command);
|
||||||
@ -124,7 +124,7 @@ namespace network
|
|||||||
send_data(address, packet);
|
send_data(address, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_data(const game::netadr_s& address, const std::string& data)
|
void send_data(const game::netadr_t& address, const std::string& data)
|
||||||
{
|
{
|
||||||
if (address.type == game::NA_LOOPBACK)
|
if (address.type == game::NA_LOOPBACK)
|
||||||
{
|
{
|
||||||
@ -136,12 +136,12 @@ namespace network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool are_addresses_equal(const game::netadr_s& a, const game::netadr_s& b)
|
bool are_addresses_equal(const game::netadr_t& a, const game::netadr_t& b)
|
||||||
{
|
{
|
||||||
return net_compare_address(&a, &b);
|
return net_compare_address(&a, &b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* net_adr_to_string(const game::netadr_s& a)
|
const char* net_adr_to_string(const game::netadr_t& a)
|
||||||
{
|
{
|
||||||
if (a.type == game::NA_LOOPBACK)
|
if (a.type == game::NA_LOOPBACK)
|
||||||
{
|
{
|
||||||
@ -286,7 +286,7 @@ namespace network
|
|||||||
if (!game::environment::is_dedi())
|
if (!game::environment::is_dedi())
|
||||||
{
|
{
|
||||||
// we need this on the client for RCon
|
// we need this on the client for RCon
|
||||||
on("print", [](const game::netadr_s& address, const std::string& message)
|
on("print", [](const game::netadr_t& address, const std::string& message)
|
||||||
{
|
{
|
||||||
if (address != party::get_target())
|
if (address != party::get_target())
|
||||||
{
|
{
|
||||||
|
@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
namespace network
|
namespace network
|
||||||
{
|
{
|
||||||
using callback = std::function<void(const game::netadr_s&, const std::string&)>;
|
using callback = std::function<void(const game::netadr_t&, const std::string&)>;
|
||||||
|
|
||||||
void on(const std::string& command, const callback& callback);
|
void on(const std::string& command, const callback& callback);
|
||||||
void send(const game::netadr_s& address, const std::string& command, const std::string& data = {}, char separator = ' ');
|
void send(const game::netadr_t& address, const std::string& command, const std::string& data = {}, char separator = ' ');
|
||||||
void send_data(const game::netadr_s& address, const std::string& data);
|
void send_data(const game::netadr_t& address, const std::string& data);
|
||||||
|
|
||||||
bool are_addresses_equal(const game::netadr_s& a, const game::netadr_s& b);
|
bool are_addresses_equal(const game::netadr_t& a, const game::netadr_t& b);
|
||||||
|
|
||||||
const char* net_adr_to_string(const game::netadr_s& a);
|
const char* net_adr_to_string(const game::netadr_t& a);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const game::netadr_s& a, const game::netadr_s& b)
|
inline bool operator==(const game::netadr_t& a, const game::netadr_t& b)
|
||||||
{
|
{
|
||||||
return network::are_addresses_equal(a, b); //
|
return network::are_addresses_equal(a, b); //
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const game::netadr_s& a, const game::netadr_s& b)
|
inline bool operator!=(const game::netadr_t& a, const game::netadr_t& b)
|
||||||
{
|
{
|
||||||
return !(a == b); //
|
return !(a == b); //
|
||||||
}
|
}
|
||||||
@ -26,20 +26,20 @@ inline bool operator!=(const game::netadr_s& a, const game::netadr_s& b)
|
|||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct equal_to<game::netadr_s>
|
struct equal_to<game::netadr_t>
|
||||||
{
|
{
|
||||||
using result_type = bool;
|
using result_type = bool;
|
||||||
|
|
||||||
bool operator()(const game::netadr_s& lhs, const game::netadr_s& rhs) const
|
bool operator()(const game::netadr_t& lhs, const game::netadr_t& rhs) const
|
||||||
{
|
{
|
||||||
return network::are_addresses_equal(lhs, rhs);
|
return network::are_addresses_equal(lhs, rhs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct hash<game::netadr_s>
|
struct hash<game::netadr_t>
|
||||||
{
|
{
|
||||||
size_t operator()(const game::netadr_s& x) const noexcept
|
size_t operator()(const game::netadr_t& x) const noexcept
|
||||||
{
|
{
|
||||||
return hash<uint32_t>()(*reinterpret_cast<const uint32_t*>(&x.ip[0])) ^ hash<uint16_t>()(x.port);
|
return hash<uint32_t>()(*reinterpret_cast<const uint32_t*>(&x.ip[0])) ^ hash<uint16_t>()(x.port);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ namespace notifies
|
|||||||
a.lea(eax, dword_ptr(r15, -0x17));
|
a.lea(eax, dword_ptr(r15, -0x17));
|
||||||
a.mov(dword_ptr(rbp, 0x60), r15d);
|
a.mov(dword_ptr(rbp, 0x60), r15d);
|
||||||
|
|
||||||
a.jmp(SELECT_VALUE(0x1403DF5B3, 0x14043A593));
|
a.jmp(0x14043A593);
|
||||||
|
|
||||||
a.bind(replace);
|
a.bind(replace);
|
||||||
|
|
||||||
@ -174,22 +174,22 @@ namespace notifies
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
utils::hook::jump(SELECT_VALUE(0x1403DF5A4, 0x14043A584), utils::hook::assemble(vm_execute_stub), true);
|
|
||||||
|
|
||||||
scripting::on_shutdown([](const int clear_scripts, const int post_shutdown) -> void
|
|
||||||
{
|
|
||||||
if (clear_scripts && post_shutdown)
|
|
||||||
{
|
|
||||||
vm_execute_hooks.clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
if (game::environment::is_sp())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::hook::call(0x1404724DD, client_command_stub);
|
utils::hook::call(0x1404724DD, client_command_stub);
|
||||||
|
|
||||||
|
utils::hook::jump(0x14043A584, utils::hook::assemble(vm_execute_stub), true);
|
||||||
|
|
||||||
|
scripting::on_shutdown([](const bool free_scripts)
|
||||||
|
{
|
||||||
|
if (free_scripts)
|
||||||
|
{
|
||||||
|
vm_execute_hooks.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
#include "game/engine/sv_game.hpp"
|
|
||||||
|
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
@ -27,7 +26,7 @@ namespace party
|
|||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
game::netadr_s host{};
|
game::netadr_t host{};
|
||||||
std::string challenge{};
|
std::string challenge{};
|
||||||
bool hostDefined{false};
|
bool hostDefined{false};
|
||||||
} connect_state;
|
} connect_state;
|
||||||
@ -38,7 +37,7 @@ namespace party
|
|||||||
|
|
||||||
int sv_maxclients;
|
int sv_maxclients;
|
||||||
|
|
||||||
void connect_to_party(const game::netadr_s& target, const std::string& mapname, const std::string& gametype)
|
void connect_to_party(const game::netadr_t& target, const std::string& mapname, const std::string& gametype)
|
||||||
{
|
{
|
||||||
if (game::environment::is_sp())
|
if (game::environment::is_sp())
|
||||||
{
|
{
|
||||||
@ -59,7 +58,7 @@ namespace party
|
|||||||
|
|
||||||
// CL_ConnectFromParty
|
// CL_ConnectFromParty
|
||||||
char session_info[0x100] = {};
|
char session_info[0x100] = {};
|
||||||
reinterpret_cast<void(*)(int, char*, const game::netadr_s*, const char*, const char*)>(0x1402C5700)(
|
reinterpret_cast<void(*)(int, char*, const game::netadr_t*, const char*, const char*)>(0x1402C5700)(
|
||||||
0, session_info, &target, mapname.data(), gametype.data());
|
0, session_info, &target, mapname.data(), gametype.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,26 +81,6 @@ namespace party
|
|||||||
a.mov(ecx, 2);
|
a.mov(ecx, 2);
|
||||||
a.jmp(0x1402C617D);
|
a.jmp(0x1402C617D);
|
||||||
});
|
});
|
||||||
|
|
||||||
utils::info_string get_info()
|
|
||||||
{
|
|
||||||
utils::info_string info;
|
|
||||||
|
|
||||||
info.set("gamename", "IW6");
|
|
||||||
info.set("hostname", dvars::get_string("sv_hostname"));
|
|
||||||
info.set("gametype", dvars::get_string("g_gametype"));
|
|
||||||
info.set("sv_motd", dvars::get_string("sv_motd"));
|
|
||||||
info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits));
|
|
||||||
info.set("mapname", dvars::get_string("mapname"));
|
|
||||||
info.set("isPrivate", dvars::get_string("g_password").empty() ? "0" : "1");
|
|
||||||
info.set("clients", std::to_string(get_client_count()));
|
|
||||||
info.set("bots", std::to_string(get_bot_count()));
|
|
||||||
info.set("sv_maxclients", std::to_string(*game::mp::svs_clientCount));
|
|
||||||
info.set("protocol", std::to_string(PROTOCOL));
|
|
||||||
info.set("shortversion", SHORTVERSION);
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void switch_gamemode_if_necessary(const std::string& gametype)
|
void switch_gamemode_if_necessary(const std::string& gametype)
|
||||||
@ -167,7 +146,7 @@ namespace party
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::netadr_s& get_target()
|
game::netadr_t& get_target()
|
||||||
{
|
{
|
||||||
return connect_state.host;
|
return connect_state.host;
|
||||||
}
|
}
|
||||||
@ -181,25 +160,22 @@ namespace party
|
|||||||
{
|
{
|
||||||
for (auto i = 0; !name.empty() && i < *game::mp::svs_clientCount; ++i)
|
for (auto i = 0; !name.empty() && i < *game::mp::svs_clientCount; ++i)
|
||||||
{
|
{
|
||||||
if (!game::mp::g_entities[i].client)
|
if (game::mp::g_entities[i].client)
|
||||||
{
|
{
|
||||||
continue;
|
char client_name[16] = {0};
|
||||||
}
|
strncpy_s(client_name, game::mp::g_entities[i].client->sess.cs.name, sizeof(client_name));
|
||||||
|
game::I_CleanStr(client_name);
|
||||||
|
|
||||||
char client_name[16]{};
|
if (client_name == name)
|
||||||
game::I_strncpyz(client_name, game::mp::g_entities[i].client->sess.cs.name, sizeof(client_name));
|
{
|
||||||
game::I_CleanStr(client_name);
|
return i;
|
||||||
|
}
|
||||||
if (client_name == name)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(const game::netadr_s& target)
|
void connect(const game::netadr_t& target)
|
||||||
{
|
{
|
||||||
if (game::environment::is_sp())
|
if (game::environment::is_sp())
|
||||||
{
|
{
|
||||||
@ -276,7 +252,7 @@ namespace party
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::netadr_s target{};
|
game::netadr_t target{};
|
||||||
if (game::NET_StringToAdr(params[1], &target))
|
if (game::NET_StringToAdr(params[1], &target))
|
||||||
{
|
{
|
||||||
connect(target);
|
connect(target);
|
||||||
@ -384,7 +360,7 @@ namespace party
|
|||||||
const auto message = params.join(2);
|
const auto message = params.join(2);
|
||||||
const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string;
|
const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string;
|
||||||
|
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data()));
|
game::SV_GameSendServerCommand(client_num, 0, utils::string::va("%c \"%s: %s\"", 84, name, message.data()));
|
||||||
console::info("%s -> %i: %s\n", name, client_num, message.data());
|
console::info("%s -> %i: %s\n", name, client_num, message.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -398,7 +374,7 @@ namespace party
|
|||||||
const auto client_num = atoi(params.get(1));
|
const auto client_num = atoi(params.get(1));
|
||||||
const auto message = params.join(2);
|
const auto message = params.join(2);
|
||||||
|
|
||||||
game::engine::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data()));
|
game::SV_GameSendServerCommand(client_num, 0, utils::string::va("%c \"%s\"", 84, message.data()));
|
||||||
console::info("%i: %s\n", client_num, message.data());
|
console::info("%i: %s\n", client_num, message.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -412,7 +388,7 @@ namespace party
|
|||||||
const auto message = params.join(1);
|
const auto message = params.join(1);
|
||||||
const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string;
|
const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string;
|
||||||
|
|
||||||
game::engine::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data()));
|
game::SV_GameSendServerCommand(-1, 0, utils::string::va("%c \"%s: %s\"", 84, name, message.data()));
|
||||||
console::info("%s: %s\n", name, message.data());
|
console::info("%s: %s\n", name, message.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -425,67 +401,36 @@ namespace party
|
|||||||
|
|
||||||
const auto message = params.join(1);
|
const auto message = params.join(1);
|
||||||
|
|
||||||
game::engine::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s\"", 84, message.data()));
|
game::SV_GameSendServerCommand(-1, 0, utils::string::va("%c \"%s\"", 84, message.data()));
|
||||||
console::info("%s\n", message.data());
|
console::info("%s\n", message.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
network::on("getInfo", [](const game::netadr_s& target, const std::string& data)
|
network::on("getInfo", [](const game::netadr_t& target, const std::string& data)
|
||||||
{
|
{
|
||||||
utils::info_string info = get_info();
|
utils::info_string info;
|
||||||
info.set("challenge", data);
|
info.set("challenge", data);
|
||||||
|
info.set("gamename", "IW6");
|
||||||
|
info.set("hostname", dvars::get_string("sv_hostname"));
|
||||||
|
info.set("gametype", dvars::get_string("g_gametype"));
|
||||||
|
info.set("sv_motd", dvars::get_string("sv_motd"));
|
||||||
|
info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits));
|
||||||
|
info.set("mapname", dvars::get_string("mapname"));
|
||||||
|
info.set("isPrivate", dvars::get_string("g_password").empty() ? "0" : "1");
|
||||||
|
info.set("clients", std::to_string(get_client_count()));
|
||||||
|
info.set("bots", std::to_string(get_bot_count()));
|
||||||
|
info.set("sv_maxclients", std::to_string(*game::mp::svs_clientCount));
|
||||||
|
info.set("protocol", std::to_string(PROTOCOL));
|
||||||
|
info.set("shortversion", SHORTVERSION);
|
||||||
|
|
||||||
network::send(target, "infoResponse", info.build(), '\n');
|
network::send(target, "infoResponse", info.build(), '\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
network::on("getStatus", [](const game::netadr_s& target, const std::string& data)
|
|
||||||
{
|
|
||||||
std::string player_list;
|
|
||||||
|
|
||||||
utils::info_string info = get_info();
|
|
||||||
info.set("challenge", data);
|
|
||||||
|
|
||||||
const auto* sv_running = game::Dvar_FindVar("sv_running");
|
|
||||||
if (!sv_running || !sv_running->current.enabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i = 0; i < game::Dvar_FindVar("sv_maxclients")->current.integer; ++i)
|
|
||||||
{
|
|
||||||
auto* client = &game::mp::svs_clients[i];
|
|
||||||
auto* self = &game::mp::g_entities[i];
|
|
||||||
|
|
||||||
if (client->header.state < game::CS_ACTIVE)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self || !self->client)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game::SV_BotIsBot(i))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto score = game::G_GetClientScore(i);
|
|
||||||
const auto ping = game::mp::svs_clients[i].ping;
|
|
||||||
const std::string name = game::mp::svs_clients[i].name;
|
|
||||||
|
|
||||||
player_list.append(std::format("{} {} \"{}\"\n", score, ping, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
network::send(target, "statusResponse", info.build() + "\n"s + player_list + "\n"s, '\n');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (game::environment::is_dedi())
|
if (game::environment::is_dedi())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::on("infoResponse", [](const game::netadr_s& target, const std::string& data)
|
network::on("infoResponse", [](const game::netadr_t& target, const std::string& data)
|
||||||
{
|
{
|
||||||
const utils::info_string info(data);
|
const utils::info_string info(data);
|
||||||
server_list::handle_info_response(target, info);
|
server_list::handle_info_response(target, info);
|
||||||
|
@ -7,7 +7,7 @@ namespace party
|
|||||||
|
|
||||||
void reset_connect_state();
|
void reset_connect_state();
|
||||||
|
|
||||||
void connect(const game::netadr_s& target);
|
void connect(const game::netadr_t& target);
|
||||||
void map_restart();
|
void map_restart();
|
||||||
|
|
||||||
[[nodiscard]] int server_client_count();
|
[[nodiscard]] int server_client_count();
|
||||||
@ -15,5 +15,5 @@ namespace party
|
|||||||
[[nodiscard]] int get_client_count();
|
[[nodiscard]] int get_client_count();
|
||||||
[[nodiscard]] int get_bot_count();
|
[[nodiscard]] int get_bot_count();
|
||||||
|
|
||||||
[[nodiscard]] game::netadr_s& get_target();
|
[[nodiscard]] game::netadr_t& get_target();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
#include "game/engine/sv_game.hpp"
|
|
||||||
|
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
@ -73,10 +72,8 @@ namespace patches
|
|||||||
if (exec_params.size() == 2)
|
if (exec_params.size() == 2)
|
||||||
{
|
{
|
||||||
std::string file_name = exec_params.get(1);
|
std::string file_name = exec_params.get(1);
|
||||||
if (!file_name.ends_with(".cfg"))
|
if (file_name.find(".cfg") == std::string::npos)
|
||||||
{
|
|
||||||
file_name.append(".cfg");
|
file_name.append(".cfg");
|
||||||
}
|
|
||||||
|
|
||||||
const auto file = filesystem::file(file_name);
|
const auto file = filesystem::file(file_name);
|
||||||
if (file.exists())
|
if (file.exists())
|
||||||
@ -153,7 +150,7 @@ namespace patches
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::Font_s* get_chat_font_handle()
|
game::Font_t* get_chat_font_handle()
|
||||||
{
|
{
|
||||||
return game::R_RegisterFont("fonts/bigFont");
|
return game::R_RegisterFont("fonts/bigFont");
|
||||||
}
|
}
|
||||||
@ -190,7 +187,7 @@ namespace patches
|
|||||||
}
|
}
|
||||||
|
|
||||||
utils::hook::detour cmd_lui_notify_server_hook;
|
utils::hook::detour cmd_lui_notify_server_hook;
|
||||||
void cmd_lui_notify_server_stub(game::mp::gentity_s* ent)
|
void cmd_lui_notify_server_stub(game::mp::gentity_t* ent)
|
||||||
{
|
{
|
||||||
command::params_sv params{};
|
command::params_sv params{};
|
||||||
const auto menu_id = atoi(params.get(1));
|
const auto menu_id = atoi(params.get(1));
|
||||||
@ -293,12 +290,6 @@ namespace patches
|
|||||||
|
|
||||||
static void patch_mp()
|
static void patch_mp()
|
||||||
{
|
{
|
||||||
// Bypass Arxan function
|
|
||||||
utils::hook::nop(0x1404758C0, 16);
|
|
||||||
utils::hook::jump(0x1404758C0, game::engine::SV_GameSendServerCommand, true);
|
|
||||||
|
|
||||||
utils::hook::call(0x140477399, game::engine::SV_SendServerCommand);
|
|
||||||
|
|
||||||
// Register dvars
|
// Register dvars
|
||||||
com_register_dvars_hook.create(0x140413A90, &com_register_dvars_stub);
|
com_register_dvars_hook.create(0x140413A90, &com_register_dvars_stub);
|
||||||
|
|
||||||
@ -335,10 +326,6 @@ namespace patches
|
|||||||
dvars::override::register_int("igs_s1", 1, 0, 1, 0);
|
dvars::override::register_int("igs_s1", 1, 0, 1, 0);
|
||||||
dvars::override::register_int("igs_crossgame", 1, 0, 1, 0);
|
dvars::override::register_int("igs_crossgame", 1, 0, 1, 0);
|
||||||
|
|
||||||
// Required by UI scripts. Missing when joining a dedi and causes crashes
|
|
||||||
game::Dvar_RegisterInt("scr_gun_winlimit", 1, 0, 10, game::DVAR_FLAG_REPLICATED, "Win limit for Gun Game");
|
|
||||||
game::Dvar_RegisterInt("scr_gun_scorelimit", 18, 1, 1000, game::DVAR_FLAG_REPLICATED, "Score limit for Gun Game");
|
|
||||||
|
|
||||||
// Patch game chat on resolutions higher than 1080p to use the right font
|
// Patch game chat on resolutions higher than 1080p to use the right font
|
||||||
utils::hook::call(0x14025C825, get_chat_font_handle);
|
utils::hook::call(0x14025C825, get_chat_font_handle);
|
||||||
utils::hook::call(0x1402BC42F, get_chat_font_handle);
|
utils::hook::call(0x1402BC42F, get_chat_font_handle);
|
||||||
@ -370,9 +357,6 @@ namespace patches
|
|||||||
utils::hook::nop(0x1403A1A0F, 1);
|
utils::hook::nop(0x1403A1A0F, 1);
|
||||||
// ^^
|
// ^^
|
||||||
utils::hook::nop(0x1403A072F, 5); // LiveStorage_RecordMovementInMatchdata
|
utils::hook::nop(0x1403A072F, 5); // LiveStorage_RecordMovementInMatchdata
|
||||||
|
|
||||||
// Disable Com_Error in NET_SendPacket
|
|
||||||
utils::hook::nop(0x140501AE3, 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_sp()
|
static void patch_sp()
|
||||||
|
@ -14,11 +14,11 @@ namespace rcon
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool is_redirecting_ = false;
|
bool is_redirecting_ = false;
|
||||||
game::netadr_s redirect_target_ = {};
|
game::netadr_t redirect_target_ = {};
|
||||||
std::string redirect_buffer = {};
|
std::string redirect_buffer = {};
|
||||||
std::recursive_mutex redirect_lock;
|
std::recursive_mutex redirect_lock;
|
||||||
|
|
||||||
void setup_redirect(const game::netadr_s& target)
|
void setup_redirect(const game::netadr_t& target)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> $(redirect_lock);
|
std::lock_guard<std::recursive_mutex> $(redirect_lock);
|
||||||
|
|
||||||
@ -53,25 +53,23 @@ namespace rcon
|
|||||||
const auto client = &game::mp::svs_clients[i];
|
const auto client = &game::mp::svs_clients[i];
|
||||||
auto self = &game::mp::g_entities[i];
|
auto self = &game::mp::g_entities[i];
|
||||||
|
|
||||||
if (client->header.state == game::CS_FREE || !self || !self->client)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char clean_name[32]{};
|
char clean_name[32]{};
|
||||||
game::I_strncpyz(clean_name, self->client->sess.cs.name, sizeof(clean_name));
|
strncpy_s(clean_name, self->client->sess.cs.name, sizeof(clean_name));
|
||||||
game::I_CleanStr(clean_name);
|
game::I_CleanStr(clean_name);
|
||||||
|
|
||||||
buffer.append(utils::string::va("%3i %5i %3s %s %32s %16s %21s %5i\n",
|
if (client->header.state > game::CS_FREE && self && self->client)
|
||||||
i,
|
{
|
||||||
self->client->sess.scores.score,
|
buffer.append(utils::string::va("%3i %5i %3s %s %32s %16s %21s %5i\n",
|
||||||
game::SV_BotIsBot(i) ? "Yes" : "No",
|
i,
|
||||||
(client->header.state == game::CS_RECONNECTING) ? "CNCT" : (client->header.state == game::CS_ZOMBIE) ? "ZMBI" : utils::string::va("%4i", client->ping),
|
self->client->sess.scores.score,
|
||||||
game::SV_GetGuid(i),
|
game::SV_BotIsBot(i) ? "Yes" : "No",
|
||||||
clean_name,
|
(client->header.state == game::CS_RECONNECTING) ? "CNCT" : (client->header.state == game::CS_ZOMBIE) ? "ZMBI" : utils::string::va("%4i", client->ping),
|
||||||
network::net_adr_to_string(client->header.netchan.remoteAddress),
|
game::SV_GetGuid(i),
|
||||||
client->header.netchan.remoteAddress.port)
|
clean_name,
|
||||||
);
|
network::net_adr_to_string(client->header.netchan.remoteAddress),
|
||||||
|
client->header.netchan.remoteAddress.port)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -94,7 +92,7 @@ namespace rcon
|
|||||||
|
|
||||||
if (*reinterpret_cast<std::int32_t*>(0x1419E1AE0) >= 5) //clientUIActive.connectionState >= CA_CONNECTED
|
if (*reinterpret_cast<std::int32_t*>(0x1419E1AE0) >= 5) //clientUIActive.connectionState >= CA_CONNECTED
|
||||||
{
|
{
|
||||||
const auto target = *reinterpret_cast<game::netadr_s*>(0x141CB535C);
|
const auto target = *reinterpret_cast<game::netadr_t*>(0x141CB535C);
|
||||||
const auto buffer = password + " " + data;
|
const auto buffer = password + " " + data;
|
||||||
network::send(target, "rcon", buffer);
|
network::send(target, "rcon", buffer);
|
||||||
}
|
}
|
||||||
@ -172,7 +170,7 @@ namespace rcon
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
network::on("rcon", [](const game::netadr_s& addr, const std::string& data)
|
network::on("rcon", [](const game::netadr_t& addr, const std::string& data)
|
||||||
{
|
{
|
||||||
const auto pos = data.find_first_of(" ");
|
const auto pos = data.find_first_of(" ");
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
|
@ -34,7 +34,7 @@ namespace scripting
|
|||||||
|
|
||||||
std::unordered_map<unsigned int, std::string> canonical_string_table;
|
std::unordered_map<unsigned int, std::string> canonical_string_table;
|
||||||
|
|
||||||
std::vector<std::function<void(int, int)>> shutdown_callbacks;
|
std::vector<std::function<void(int)>> shutdown_callbacks;
|
||||||
std::vector<std::function<void()>> init_callbacks;
|
std::vector<std::function<void()>> init_callbacks;
|
||||||
|
|
||||||
void scr_load_level_stub()
|
void scr_load_level_stub()
|
||||||
@ -47,9 +47,9 @@ namespace scripting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_shutdown_game_stub(const int clear_scripts)
|
void g_shutdown_game_stub(const int free_scripts)
|
||||||
{
|
{
|
||||||
if (clear_scripts)
|
if (free_scripts)
|
||||||
{
|
{
|
||||||
script_function_table_sort.clear();
|
script_function_table_sort.clear();
|
||||||
script_function_table.clear();
|
script_function_table.clear();
|
||||||
@ -59,15 +59,10 @@ namespace scripting
|
|||||||
|
|
||||||
for (const auto& callback : shutdown_callbacks)
|
for (const auto& callback : shutdown_callbacks)
|
||||||
{
|
{
|
||||||
callback(clear_scripts ,false);
|
callback(free_scripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_shutdown_game_hook.invoke<void>(clear_scripts);
|
return g_shutdown_game_hook.invoke<void>(free_scripts);
|
||||||
|
|
||||||
for (const auto& callback : shutdown_callbacks)
|
|
||||||
{
|
|
||||||
callback(clear_scripts, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_script_stub(const char* filename)
|
void process_script_stub(const char* filename)
|
||||||
@ -170,7 +165,7 @@ namespace scripting
|
|||||||
return find_token(id);
|
return find_token(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_shutdown(const std::function<void(int, int)>& callback)
|
void on_shutdown(const std::function<void(int)>& callback)
|
||||||
{
|
{
|
||||||
shutdown_callbacks.push_back(callback);
|
shutdown_callbacks.push_back(callback);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace scripting
|
|||||||
|
|
||||||
extern std::string current_file;
|
extern std::string current_file;
|
||||||
|
|
||||||
void on_shutdown(const std::function<void(int, int)>& callback);
|
void on_shutdown(const std::function<void(int)>& callback);
|
||||||
void on_init(const std::function<void()>& callback);
|
void on_init(const std::function<void()>& callback);
|
||||||
|
|
||||||
std::optional<std::string> get_canonical_string(unsigned int id);
|
std::optional<std::string> get_canonical_string(unsigned int id);
|
||||||
|
@ -10,8 +10,6 @@ namespace security
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
utils::hook::detour ui_replace_directive_hook;
|
|
||||||
|
|
||||||
void set_cached_playerdata_stub(const int localclient, const int index1, const int index2)
|
void set_cached_playerdata_stub(const int localclient, const int index1, const int index2)
|
||||||
{
|
{
|
||||||
if (index1 >= 0 && index1 < 18 && index2 >= 0 && index2 < 42)
|
if (index1 >= 0 && index1 < 18 && index2 >= 0 && index2 < 42)
|
||||||
@ -32,71 +30,6 @@ namespace security
|
|||||||
|
|
||||||
utils::hook::invoke<void>(0x140472500, client, msg);
|
utils::hook::invoke<void>(0x140472500, client, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_replace_directive_stub(const int local_client_num, const char* src_string, char* dst_string, const int dst_buffer_size)
|
|
||||||
{
|
|
||||||
assert(src_string);
|
|
||||||
if (!src_string)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(dst_string);
|
|
||||||
if (!dst_string)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(dst_buffer_size > 0);
|
|
||||||
if (dst_buffer_size <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::size_t MAX_HUDELEM_TEXT_LEN = 0x100;
|
|
||||||
if (std::strlen(src_string) > MAX_HUDELEM_TEXT_LEN)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_replace_directive_hook.invoke<void>(local_client_num, src_string, dst_string, dst_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hud_elem_set_enum_string_stub(char* string, const char* format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
const auto len = vsnprintf(string, 0x800, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
string[0x800 - 1] = '\0';
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sv_add_bot_stub(char* string, const char* format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
const auto len = vsnprintf(string, 0x400, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
string[0x400 - 1] = '\0';
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sv_add_test_client_stub(char* string, const char* format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
const auto len = vsnprintf(string, 0x400, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
string[0x400 - 1] = '\0';
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -104,22 +37,13 @@ namespace security
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
// sprinf
|
|
||||||
utils::hook::call(SELECT_VALUE(0x140310D0F, 0x140399B0F), hud_elem_set_enum_string_stub);
|
|
||||||
|
|
||||||
if (game::environment::is_sp()) return;
|
if (game::environment::is_sp()) return;
|
||||||
|
|
||||||
// Patch vulnerability in PlayerCards_SetCachedPlayerData
|
// Patch vulnerability in PlayerCards_SetCachedPlayerData
|
||||||
utils::hook::call(0x140287C5C, set_cached_playerdata_stub);
|
utils::hook::call(0x140287C5C, set_cached_playerdata_stub);
|
||||||
|
|
||||||
// sprinf
|
|
||||||
utils::hook::call(0x140470A88, sv_add_bot_stub);
|
|
||||||
utils::hook::call(0x140470F68, sv_add_test_client_stub);
|
|
||||||
|
|
||||||
// It is possible to make the server hang if left unchecked
|
// It is possible to make the server hang if left unchecked
|
||||||
utils::hook::call(0x14047A29A, sv_execute_client_message_stub);
|
utils::hook::call(0x14047A29A, sv_execute_client_message_stub);
|
||||||
|
|
||||||
ui_replace_directive_hook.create(0x1404D8A00, ui_replace_directive_stub);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -33,14 +33,14 @@ namespace server_list
|
|||||||
std::string map_name;
|
std::string map_name;
|
||||||
std::string game_type;
|
std::string game_type;
|
||||||
char in_game;
|
char in_game;
|
||||||
game::netadr_s address;
|
game::netadr_t address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
game::netadr_s address{};
|
game::netadr_t address{};
|
||||||
volatile bool requesting = false;
|
volatile bool requesting = false;
|
||||||
std::unordered_map<game::netadr_s, int> queued_servers{};
|
std::unordered_map<game::netadr_t, int> queued_servers{};
|
||||||
} master_state;
|
} master_state;
|
||||||
|
|
||||||
volatile bool update_server_list = false;
|
volatile bool update_server_list = false;
|
||||||
@ -307,12 +307,12 @@ namespace server_list
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_master_server(game::netadr_s& address)
|
bool get_master_server(game::netadr_t& address)
|
||||||
{
|
{
|
||||||
return game::NET_StringToAdr("server.alterware.dev:20810", &address);
|
return game::NET_StringToAdr("server.alterware.dev:20810", &address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_info_response(const game::netadr_s& address, const utils::info_string& info)
|
void handle_info_response(const game::netadr_t& address, const utils::info_string& info)
|
||||||
{
|
{
|
||||||
int start_time{};
|
int start_time{};
|
||||||
const auto now = game::Sys_Milliseconds();
|
const auto now = game::Sys_Milliseconds();
|
||||||
@ -436,7 +436,7 @@ namespace server_list
|
|||||||
|
|
||||||
scheduler::loop(do_frame_work, scheduler::pipeline::main);
|
scheduler::loop(do_frame_work, scheduler::pipeline::main);
|
||||||
|
|
||||||
network::on("getServersResponse", [](const game::netadr_s& target, const std::string& data)
|
network::on("getServersResponse", [](const game::netadr_t& target, const std::string& data)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> _(mutex);
|
std::lock_guard<std::mutex> _(mutex);
|
||||||
@ -469,7 +469,7 @@ namespace server_list
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::netadr_s address{};
|
game::netadr_t address{};
|
||||||
address.type = game::NA_IP;
|
address.type = game::NA_IP;
|
||||||
address.localNetID = game::NS_CLIENT1;
|
address.localNetID = game::NS_CLIENT1;
|
||||||
std::memcpy(&address.ip[0], data.data() + i + 0, 4);
|
std::memcpy(&address.ip[0], data.data() + i + 0, 4);
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
namespace server_list
|
namespace server_list
|
||||||
{
|
{
|
||||||
bool get_master_server(game::netadr_s& address);
|
bool get_master_server(game::netadr_t& address);
|
||||||
void handle_info_response(const game::netadr_s& address, const utils::info_string& info);
|
void handle_info_response(const game::netadr_t& address, const utils::info_string& info);
|
||||||
|
|
||||||
bool sl_key_event(int key, int down);
|
bool sl_key_event(int key, int down);
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,6 @@ namespace steam_proxy
|
|||||||
ownership_state state_;
|
ownership_state state_;
|
||||||
|
|
||||||
utils::binary_resource runner_file(RUNNER, "runner.exe");
|
utils::binary_resource runner_file(RUNNER, "runner.exe");
|
||||||
|
|
||||||
bool is_disabled() { return true; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -35,7 +33,7 @@ namespace steam_proxy
|
|||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (game::environment::is_dedi() || is_disabled())
|
if (game::environment::is_dedi())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -195,27 +195,6 @@ namespace ui_scripting
|
|||||||
setup_functions();
|
setup_functions();
|
||||||
|
|
||||||
lua["print"] = function(reinterpret_cast<game::hks::lua_function>(0x14017B120)); // hks::base_print
|
lua["print"] = function(reinterpret_cast<game::hks::lua_function>(0x14017B120)); // hks::base_print
|
||||||
|
|
||||||
lua["directoryexists"] = [](const std::string& string)
|
|
||||||
{
|
|
||||||
return utils::io::directory_exists(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
lua["listfiles"] = [](const std::string& string)
|
|
||||||
{
|
|
||||||
return utils::io::list_files(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
lua["directoryisempty"] = [](const std::string& string)
|
|
||||||
{
|
|
||||||
return utils::io::directory_is_empty(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
lua["fileexists"] = [](const std::string& string)
|
|
||||||
{
|
|
||||||
return utils::io::file_exists(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
lua["table"]["unpack"] = lua["unpack"];
|
lua["table"]["unpack"] = lua["unpack"];
|
||||||
lua["luiglobals"] = lua;
|
lua["luiglobals"] = lua;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace demonware
|
|||||||
uint64_t file_id;
|
uint64_t file_id;
|
||||||
uint32_t create_time;
|
uint32_t create_time;
|
||||||
uint32_t modified_time;
|
uint32_t modified_time;
|
||||||
bool visibility;
|
bool priv;
|
||||||
uint64_t owner_id;
|
uint64_t owner_id;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
uint32_t file_size;
|
uint32_t file_size;
|
||||||
@ -41,7 +41,7 @@ namespace demonware
|
|||||||
buffer->write_uint64(this->file_id);
|
buffer->write_uint64(this->file_id);
|
||||||
buffer->write_uint32(this->create_time);
|
buffer->write_uint32(this->create_time);
|
||||||
buffer->write_uint32(this->modified_time);
|
buffer->write_uint32(this->modified_time);
|
||||||
buffer->write_bool(this->visibility);
|
buffer->write_bool(this->priv);
|
||||||
buffer->write_uint64(this->owner_id);
|
buffer->write_uint64(this->owner_id);
|
||||||
buffer->write_string(this->filename);
|
buffer->write_string(this->filename);
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ namespace demonware
|
|||||||
buffer->read_uint64(&this->file_id);
|
buffer->read_uint64(&this->file_id);
|
||||||
buffer->read_uint32(&this->create_time);
|
buffer->read_uint32(&this->create_time);
|
||||||
buffer->read_uint32(&this->modified_time);
|
buffer->read_uint32(&this->modified_time);
|
||||||
buffer->read_bool(&this->visibility);
|
buffer->read_bool(&this->priv);
|
||||||
buffer->read_uint64(&this->owner_id);
|
buffer->read_uint64(&this->owner_id);
|
||||||
buffer->read_string(&this->filename);
|
buffer->read_string(&this->filename);
|
||||||
}
|
}
|
||||||
|
@ -10,35 +10,19 @@ namespace demonware
|
|||||||
this->register_service(4, &bdGroup::get_groups);
|
this->register_service(4, &bdGroup::get_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdGroup::set_groups(i_server* server, byte_buffer* buffer)
|
void bdGroup::set_groups(i_server* server, byte_buffer* /*buffer*/) const
|
||||||
{
|
{
|
||||||
uint32_t entries_count{};
|
//uint32_t groupCount;
|
||||||
buffer->read_array_header(game::BD_BB_UNSIGNED_INTEGER32_TYPE, &entries_count);
|
// TODO: Implement array reading
|
||||||
|
|
||||||
auto reply = server->create_reply(this->get_sub_type());
|
auto reply = server->create_reply(this->get_sub_type());
|
||||||
|
|
||||||
buffer->set_use_data_types(false);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < entries_count; ++i)
|
|
||||||
{
|
|
||||||
uint32_t group_id{};
|
|
||||||
buffer->read_uint32(&group_id);
|
|
||||||
|
|
||||||
if (group_id < ARRAYSIZE(this->groups))
|
|
||||||
{
|
|
||||||
this->groups[group_id] = 999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->set_use_data_types(true);
|
|
||||||
|
|
||||||
reply->send();
|
reply->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdGroup::get_groups(i_server* server, byte_buffer* buffer)
|
void bdGroup::get_groups(i_server* server, byte_buffer* buffer)
|
||||||
{
|
{
|
||||||
uint32_t group_count;
|
uint32_t group_count;
|
||||||
buffer->read_array_header(game::BD_BB_UNSIGNED_INTEGER32_TYPE, &group_count);
|
buffer->read_array_header(8, &group_count);
|
||||||
|
|
||||||
auto reply = server->create_reply(this->get_sub_type());
|
auto reply = server->create_reply(this->get_sub_type());
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ namespace demonware
|
|||||||
bdGroup();
|
bdGroup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_groups(i_server* server, byte_buffer* buffer);
|
void set_groups(i_server* server, byte_buffer* buffer) const;
|
||||||
void get_groups(i_server* server, byte_buffer* buffer);
|
void get_groups(i_server* server, byte_buffer* buffer);
|
||||||
|
|
||||||
uint32_t groups[512]{};
|
uint32_t groups[512]{};
|
||||||
|
@ -119,11 +119,11 @@ namespace demonware
|
|||||||
|
|
||||||
void bdStorage::set_legacy_user_file(i_server* server, byte_buffer* buffer) const
|
void bdStorage::set_legacy_user_file(i_server* server, byte_buffer* buffer) const
|
||||||
{
|
{
|
||||||
bool visibility;
|
bool priv;
|
||||||
std::string filename, data;
|
std::string filename, data;
|
||||||
|
|
||||||
buffer->read_string(&filename);
|
buffer->read_string(&filename);
|
||||||
buffer->read_bool(&visibility);
|
buffer->read_bool(&priv);
|
||||||
buffer->read_blob(&data);
|
buffer->read_blob(&data);
|
||||||
|
|
||||||
const auto id = *reinterpret_cast<const uint64_t*>(utils::cryptography::sha1::compute(filename).data());
|
const auto id = *reinterpret_cast<const uint64_t*>(utils::cryptography::sha1::compute(filename).data());
|
||||||
@ -139,11 +139,11 @@ namespace demonware
|
|||||||
|
|
||||||
info->file_id = id;
|
info->file_id = id;
|
||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->create_time = static_cast<uint32_t>(std::time(nullptr));
|
info->create_time = uint32_t(time(nullptr));
|
||||||
info->modified_time = info->create_time;
|
info->modified_time = info->create_time;
|
||||||
info->file_size = static_cast<uint32_t>(data.size());
|
info->file_size = uint32_t(data.size());
|
||||||
info->owner_id = 0;
|
info->owner_id = 0;
|
||||||
info->visibility = visibility;
|
info->priv = priv;
|
||||||
|
|
||||||
auto reply = server->create_reply(this->get_sub_type());
|
auto reply = server->create_reply(this->get_sub_type());
|
||||||
reply->add(info);
|
reply->add(info);
|
||||||
@ -170,11 +170,11 @@ namespace demonware
|
|||||||
|
|
||||||
info->file_id = id;
|
info->file_id = id;
|
||||||
info->filename = "<>";
|
info->filename = "<>";
|
||||||
info->create_time = static_cast<uint32_t>(std::time(nullptr));
|
info->create_time = uint32_t(time(nullptr));
|
||||||
info->modified_time = info->create_time;
|
info->modified_time = info->create_time;
|
||||||
info->file_size = static_cast<uint32_t>(data.size());
|
info->file_size = uint32_t(data.size());
|
||||||
info->owner_id = 0;
|
info->owner_id = 0;
|
||||||
info->visibility = false;
|
info->priv = false;
|
||||||
|
|
||||||
auto reply = server->create_reply(this->get_sub_type());
|
auto reply = server->create_reply(this->get_sub_type());
|
||||||
reply->add(info);
|
reply->add(info);
|
||||||
@ -207,12 +207,12 @@ namespace demonware
|
|||||||
|
|
||||||
void bdStorage::list_legacy_user_files(i_server* server, byte_buffer* buffer) const
|
void bdStorage::list_legacy_user_files(i_server* server, byte_buffer* buffer) const
|
||||||
{
|
{
|
||||||
uint64_t owner;
|
uint64_t unk;
|
||||||
uint32_t date;
|
uint32_t date;
|
||||||
uint16_t num_results, offset;
|
uint16_t num_results, offset;
|
||||||
std::string filename, data;
|
std::string filename, data;
|
||||||
|
|
||||||
buffer->read_uint64(&owner);
|
buffer->read_uint64(&unk);
|
||||||
buffer->read_uint32(&date);
|
buffer->read_uint32(&date);
|
||||||
buffer->read_uint16(&num_results);
|
buffer->read_uint16(&num_results);
|
||||||
buffer->read_uint16(&offset);
|
buffer->read_uint16(&offset);
|
||||||
@ -229,9 +229,9 @@ namespace demonware
|
|||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->create_time = 0;
|
info->create_time = 0;
|
||||||
info->modified_time = info->create_time;
|
info->modified_time = info->create_time;
|
||||||
info->file_size = static_cast<uint32_t>(data.size());
|
info->file_size = uint32_t(data.size());
|
||||||
info->owner_id = owner;
|
info->owner_id = 0;
|
||||||
info->visibility = false;
|
info->priv = false;
|
||||||
|
|
||||||
reply->add(info);
|
reply->add(info);
|
||||||
}
|
}
|
||||||
@ -260,9 +260,9 @@ namespace demonware
|
|||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->create_time = 0;
|
info->create_time = 0;
|
||||||
info->modified_time = info->create_time;
|
info->modified_time = info->create_time;
|
||||||
info->file_size = static_cast<uint32_t>(data.size());
|
info->file_size = uint32_t(data.size());
|
||||||
info->owner_id = 0;
|
info->owner_id = 0;
|
||||||
info->visibility = false;
|
info->priv = false;
|
||||||
|
|
||||||
reply->add(info);
|
reply->add(info);
|
||||||
}
|
}
|
||||||
@ -312,13 +312,13 @@ namespace demonware
|
|||||||
|
|
||||||
void bdStorage::set_user_file(i_server* server, byte_buffer* buffer) const
|
void bdStorage::set_user_file(i_server* server, byte_buffer* buffer) const
|
||||||
{
|
{
|
||||||
bool visibility;
|
bool priv;
|
||||||
uint64_t owner;
|
uint64_t owner;
|
||||||
std::string game, filename, data;
|
std::string game, filename, data;
|
||||||
|
|
||||||
buffer->read_string(&game);
|
buffer->read_string(&game);
|
||||||
buffer->read_string(&filename);
|
buffer->read_string(&filename);
|
||||||
buffer->read_bool(&visibility);
|
buffer->read_bool(&priv);
|
||||||
buffer->read_blob(&data);
|
buffer->read_blob(&data);
|
||||||
buffer->read_uint64(&owner);
|
buffer->read_uint64(&owner);
|
||||||
|
|
||||||
@ -329,11 +329,11 @@ namespace demonware
|
|||||||
|
|
||||||
info->file_id = *reinterpret_cast<const uint64_t*>(utils::cryptography::sha1::compute(filename).data());
|
info->file_id = *reinterpret_cast<const uint64_t*>(utils::cryptography::sha1::compute(filename).data());
|
||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->create_time = static_cast<uint32_t>(std::time(nullptr));
|
info->create_time = uint32_t(time(nullptr));
|
||||||
info->modified_time = info->create_time;
|
info->modified_time = info->create_time;
|
||||||
info->file_size = static_cast<uint32_t>(data.size());
|
info->file_size = uint32_t(data.size());
|
||||||
info->owner_id = owner;
|
info->owner_id = owner;
|
||||||
info->visibility = visibility;
|
info->priv = priv;
|
||||||
|
|
||||||
auto reply = server->create_reply(this->get_sub_type());
|
auto reply = server->create_reply(this->get_sub_type());
|
||||||
reply->add(info);
|
reply->add(info);
|
||||||
|
@ -16,7 +16,6 @@ namespace dvars
|
|||||||
game::dvar_t* con_inputCmdMatchColor = nullptr;
|
game::dvar_t* con_inputCmdMatchColor = nullptr;
|
||||||
|
|
||||||
game::dvar_t* sv_cheats = nullptr;
|
game::dvar_t* sv_cheats = nullptr;
|
||||||
game::dvar_t* sv_botsAutoJoin = nullptr;
|
|
||||||
|
|
||||||
game::dvar_t* g_playerEjection = nullptr;
|
game::dvar_t* g_playerEjection = nullptr;
|
||||||
game::dvar_t* g_playerCollision = nullptr;
|
game::dvar_t* g_playerCollision = nullptr;
|
||||||
@ -25,7 +24,6 @@ namespace dvars
|
|||||||
game::dvar_t* g_rocketPushbackScale = nullptr;
|
game::dvar_t* g_rocketPushbackScale = nullptr;
|
||||||
game::dvar_t* g_enableElevators = nullptr;
|
game::dvar_t* g_enableElevators = nullptr;
|
||||||
game::dvar_t* g_dump_scripts = nullptr;
|
game::dvar_t* g_dump_scripts = nullptr;
|
||||||
game::dvar_t* g_dump_string_tables = nullptr;
|
|
||||||
game::dvar_t* g_log = nullptr;
|
game::dvar_t* g_log = nullptr;
|
||||||
|
|
||||||
game::dvar_t* bg_surfacePenetration = nullptr;
|
game::dvar_t* bg_surfacePenetration = nullptr;
|
||||||
@ -48,9 +46,7 @@ namespace dvars
|
|||||||
game::dvar_t* cg_legacyCrashHandling = nullptr;
|
game::dvar_t* cg_legacyCrashHandling = nullptr;
|
||||||
|
|
||||||
game::dvar_t* com_developer_script = nullptr;
|
game::dvar_t* com_developer_script = nullptr;
|
||||||
game::dvar_t** com_developer = nullptr;
|
game::dvar_t** com_developer;
|
||||||
|
|
||||||
game::dvar_t** fs_gameDirVar = nullptr;
|
|
||||||
|
|
||||||
std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain)
|
std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,6 @@ namespace dvars
|
|||||||
extern game::dvar_t* con_inputCmdMatchColor;
|
extern game::dvar_t* con_inputCmdMatchColor;
|
||||||
|
|
||||||
extern game::dvar_t* sv_cheats;
|
extern game::dvar_t* sv_cheats;
|
||||||
extern game::dvar_t* sv_botsAutoJoin;
|
|
||||||
|
|
||||||
extern game::dvar_t* g_playerCollision;
|
extern game::dvar_t* g_playerCollision;
|
||||||
extern game::dvar_t* g_playerEjection;
|
extern game::dvar_t* g_playerEjection;
|
||||||
@ -24,7 +23,6 @@ namespace dvars
|
|||||||
extern game::dvar_t* g_rocketPushbackScale;
|
extern game::dvar_t* g_rocketPushbackScale;
|
||||||
extern game::dvar_t* g_enableElevators;
|
extern game::dvar_t* g_enableElevators;
|
||||||
extern game::dvar_t* g_dump_scripts;
|
extern game::dvar_t* g_dump_scripts;
|
||||||
extern game::dvar_t* g_dump_string_tables;
|
|
||||||
extern game::dvar_t* g_log;
|
extern game::dvar_t* g_log;
|
||||||
|
|
||||||
extern game::dvar_t* bg_surfacePenetration;
|
extern game::dvar_t* bg_surfacePenetration;
|
||||||
@ -49,8 +47,6 @@ namespace dvars
|
|||||||
extern game::dvar_t* com_developer_script;
|
extern game::dvar_t* com_developer_script;
|
||||||
extern game::dvar_t** com_developer;
|
extern game::dvar_t** com_developer;
|
||||||
|
|
||||||
extern game::dvar_t** fs_gameDirVar;
|
|
||||||
|
|
||||||
std::string dvar_get_vector_domain(int components, const game::dvar_limits& domain);
|
std::string dvar_get_vector_domain(int components, const game::dvar_limits& domain);
|
||||||
std::string dvar_get_domain(game::dvar_type type, const game::dvar_limits& domain);
|
std::string dvar_get_domain(game::dvar_type type, const game::dvar_limits& domain);
|
||||||
}
|
}
|
||||||
|
@ -1,206 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include <game/game.hpp>
|
|
||||||
|
|
||||||
#include "sv_game.hpp"
|
|
||||||
|
|
||||||
#include <component/console.hpp>
|
|
||||||
|
|
||||||
#include <utils/string.hpp>
|
|
||||||
|
|
||||||
namespace game::engine
|
|
||||||
{
|
|
||||||
char* SV_ExpandNewlines(char* in)
|
|
||||||
{
|
|
||||||
static char string[1024];
|
|
||||||
|
|
||||||
unsigned int l = 0;
|
|
||||||
while (*in && l < sizeof(string) - 3)
|
|
||||||
{
|
|
||||||
if (*in == '\n')
|
|
||||||
{
|
|
||||||
string[l++] = '\\';
|
|
||||||
string[l++] = 'n';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (*in != '\x14' && *in != '\x15')
|
|
||||||
{
|
|
||||||
string[l++] = *in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++in;
|
|
||||||
}
|
|
||||||
|
|
||||||
string[l] = '\0';
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_CullIgnorableServerCommands(mp::client_t* client)
|
|
||||||
{
|
|
||||||
int to = client->reliableSent + 1;
|
|
||||||
for (int from = to; from <= client->reliableSequence; ++from)
|
|
||||||
{
|
|
||||||
int from_index = from & 0x7F;
|
|
||||||
assert(client->netBuf.reliableCommandInfo[from_index].time >= 0);
|
|
||||||
if (client->netBuf.reliableCommandInfo[from_index].type)
|
|
||||||
{
|
|
||||||
int to_index = to & 0x7F;
|
|
||||||
if (to_index != from_index)
|
|
||||||
{
|
|
||||||
client->netBuf.reliableCommandInfo[to_index] = client->netBuf.reliableCommandInfo[from_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
++to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client->reliableSequence = to - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_DelayDropClient(mp::client_t* drop, const char* reason)
|
|
||||||
{
|
|
||||||
assert(drop);
|
|
||||||
assert(reason);
|
|
||||||
assert(drop->header.state != CS_FREE);
|
|
||||||
if (drop->header.state == CS_ZOMBIE)
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
console::info("(drop->dropReason) = %s", drop->dropReason);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (!drop->dropReason)
|
|
||||||
{
|
|
||||||
drop->dropReason = reason;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_AddServerCommand(mp::client_t* client, svscmd_type type, const char* cmd)
|
|
||||||
{
|
|
||||||
static_assert(offsetof(mp::client_t, netBuf.reliableCommandInfo[0].cmd) == 0xC44);
|
|
||||||
|
|
||||||
if (client->testClient == TC_BOT)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->reliableSequence - client->reliableAcknowledge < 64 && client->header.state == CS_ACTIVE || (SV_CullIgnorableServerCommands(client), type))
|
|
||||||
{
|
|
||||||
int len = static_cast<int>(std::strlen(cmd)) + 1;
|
|
||||||
int to = SV_CanReplaceServerCommand(client, reinterpret_cast<const unsigned char*>(cmd), len);
|
|
||||||
if (to < 0)
|
|
||||||
{
|
|
||||||
++client->reliableSequence;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int from = to + 1;
|
|
||||||
while (from <= client->reliableSequence)
|
|
||||||
{
|
|
||||||
client->netBuf.reliableCommandInfo[to & 0x7F] = client->netBuf.reliableCommandInfo[from & 0x7F];
|
|
||||||
++from;
|
|
||||||
++to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->reliableSequence - client->reliableAcknowledge == 129)
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
console::info("===== pending server commands =====\n");
|
|
||||||
int i = 0;
|
|
||||||
for (i = client->reliableAcknowledge + 1; i <= client->reliableSequence; ++i)
|
|
||||||
{
|
|
||||||
console::info("cmd %5d: %8d: %s\n", i, client->netBuf.reliableCommandInfo[i & 0x7F].time, client->netBuf.reliableCommandInfo[i & 0x7F].cmd);
|
|
||||||
}
|
|
||||||
console::info("cmd %5d: %8d: %s\n", i, *game::mp::serverTime, cmd);
|
|
||||||
#endif
|
|
||||||
NET_OutOfBandPrint(NS_SERVER, &client->header.netchan.remoteAddress, "disconnect");
|
|
||||||
SV_DelayDropClient(client, "EXE_SERVERCOMMANDOVERFLOW");
|
|
||||||
type = SV_CMD_RELIABLE;
|
|
||||||
cmd = utils::string::va("%c \"EXE_SERVERCOMMANDOVERFLOW\"", 'r');
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = client->reliableSequence & 0x7F;
|
|
||||||
MSG_WriteReliableCommandToBuffer(cmd, client->netBuf.reliableCommandInfo[index].cmd, sizeof(client->netBuf.reliableCommandInfo[index].cmd));
|
|
||||||
client->netBuf.reliableCommandInfo[index].time = *game::mp::serverTime;
|
|
||||||
client->netBuf.reliableCommandInfo[index].type = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_SendServerCommand(mp::client_t* cl, svscmd_type type, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
mp::client_t* client;
|
|
||||||
int j, len;
|
|
||||||
va_list va;
|
|
||||||
|
|
||||||
const auto server_command_buf_large = std::make_unique<char[]>(0x20000);
|
|
||||||
|
|
||||||
va_start(va, fmt);
|
|
||||||
len = vsnprintf(server_command_buf_large.get(), 0x20000, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
assert(len >= 0);
|
|
||||||
|
|
||||||
if (cl)
|
|
||||||
{
|
|
||||||
SV_AddServerCommand(cl, type, server_command_buf_large.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (environment::is_dedi() && !std::strncmp(server_command_buf_large.get(), "print", 5))
|
|
||||||
{
|
|
||||||
console::info("broadcast: %s\n", SV_ExpandNewlines(server_command_buf_large.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto* sv_maxclients = Dvar_FindVar("sv_maxclients");
|
|
||||||
for (j = 0, client = mp::svs_clients; j < sv_maxclients->current.integer; j++, client++)
|
|
||||||
{
|
|
||||||
if (client->header.state < CS_CLIENTLOADING)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SV_AddServerCommand(client, type, server_command_buf_large.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text)
|
|
||||||
{
|
|
||||||
[[maybe_unused]] const auto* sv_maxclients = Dvar_FindVar("sv_maxclients");
|
|
||||||
|
|
||||||
if (clientNum == -1)
|
|
||||||
{
|
|
||||||
SV_SendServerCommand(nullptr, type, "%s", text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(sv_maxclients->current.integer >= 1 && sv_maxclients->current.integer <= 18);
|
|
||||||
assert(static_cast<unsigned>(clientNum) < sv_maxclients->current.unsignedInt);
|
|
||||||
SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_ReconnectClients(int savepersist)
|
|
||||||
{
|
|
||||||
const auto* sv_maxclients = Dvar_FindVar("sv_maxclients");
|
|
||||||
for (int i = 0; i < sv_maxclients->current.integer; ++i)
|
|
||||||
{
|
|
||||||
mp::client_t* client = &mp::svs_clients[i];
|
|
||||||
if (client->header.state < CS_CONNECTED)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SV_AddServerCommand(client, SV_CMD_RELIABLE, utils::string::va("%c", savepersist != 0 ? 107 : 118));
|
|
||||||
const char* denied = ClientConnect(i, client->scriptId);
|
|
||||||
if (denied)
|
|
||||||
{
|
|
||||||
SV_DropClient(client, denied, true);
|
|
||||||
console::info("SV_MapRestart_f: dropped client %i - denied!\n", i);
|
|
||||||
}
|
|
||||||
else if (client->header.state == CS_ACTIVE)
|
|
||||||
{
|
|
||||||
SV_ClientEnterWorld(client, &client->lastUsercmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace game::engine
|
|
||||||
{
|
|
||||||
void SV_SendServerCommand(mp::client_t* cl, svscmd_type type, const char* fmt, ...);
|
|
||||||
void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text);
|
|
||||||
void SV_ReconnectClients(int savepersist);
|
|
||||||
}
|
|
@ -25,13 +25,6 @@ namespace game
|
|||||||
return sv_cmd_args->argv[sv_cmd_args->nesting][index];
|
return sv_cmd_args->argv[sv_cmd_args->nesting][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE Sys_OpenFileReliable(const char* filename)
|
|
||||||
{
|
|
||||||
return ::CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, nullptr,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace environment
|
namespace environment
|
||||||
{
|
{
|
||||||
launcher::mode mode = launcher::mode::none;
|
launcher::mode mode = launcher::mode::none;
|
||||||
|
@ -63,8 +63,6 @@ namespace game
|
|||||||
[[nodiscard]] int SV_Cmd_Argc();
|
[[nodiscard]] int SV_Cmd_Argc();
|
||||||
[[nodiscard]] const char* SV_Cmd_Argv(int index);
|
[[nodiscard]] const char* SV_Cmd_Argv(int index);
|
||||||
|
|
||||||
[[nodiscard]] HANDLE Sys_OpenFileReliable(const char* filename);
|
|
||||||
|
|
||||||
[[nodiscard]] bool is_headless();
|
[[nodiscard]] bool is_headless();
|
||||||
void show_error(const std::string& text, const std::string& title = "Error");
|
void show_error(const std::string& text, const std::string& title = "Error");
|
||||||
|
|
||||||
|
@ -10,14 +10,6 @@ namespace game
|
|||||||
typedef vec_t vec3_t[3];
|
typedef vec_t vec3_t[3];
|
||||||
typedef vec_t vec4_t[4];
|
typedef vec_t vec4_t[4];
|
||||||
|
|
||||||
enum ControllerIndex_t
|
|
||||||
{
|
|
||||||
INVALID_CONTROLLER_PORT = -1,
|
|
||||||
CONTROLLER_INDEX_0 = 0x0,
|
|
||||||
CONTROLLER_INDEX_FIRST = 0x0,
|
|
||||||
CONTROLLER_INDEX_COUNT = 0x1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FL_GODMODE = 0x1,
|
FL_GODMODE = 0x1,
|
||||||
@ -55,12 +47,6 @@ namespace game
|
|||||||
PMF_UNK3 = 0x4000,
|
PMF_UNK3 = 0x4000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum svscmd_type
|
|
||||||
{
|
|
||||||
SV_CMD_CAN_IGNORE,
|
|
||||||
SV_CMD_RELIABLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum XAssetType
|
enum XAssetType
|
||||||
{
|
{
|
||||||
ASSET_TYPE_PHYSPRESET = 0x0,
|
ASSET_TYPE_PHYSPRESET = 0x0,
|
||||||
@ -141,19 +127,6 @@ namespace game
|
|||||||
DB_LOAD_SYNC_SKIP_ALWAYS_LOADED = 0x5,
|
DB_LOAD_SYNC_SKIP_ALWAYS_LOADED = 0x5,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DB_ZONE_COMMON = 0x1,
|
|
||||||
DB_ZONE_UI = 0x2,
|
|
||||||
DB_ZONE_GAME = 0x4,
|
|
||||||
DB_ZONE_LOAD = 0x8,
|
|
||||||
DB_ZONE_DEV = 0x10,
|
|
||||||
DB_ZONE_BASEMAP = 0x20,
|
|
||||||
DB_ZONE_TRANSIENT_POOL = 0x40,
|
|
||||||
DB_ZONE_TRANSIENT_MASK = 0x40,
|
|
||||||
DB_ZONE_CUSTOM = 0x80,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
THREAD_CONTEXT_MAIN = 0x0,
|
THREAD_CONTEXT_MAIN = 0x0,
|
||||||
@ -208,7 +181,7 @@ namespace game
|
|||||||
|
|
||||||
static_assert(sizeof(db_internal_state) == 0x20);
|
static_assert(sizeof(db_internal_state) == 0x20);
|
||||||
|
|
||||||
struct db_z_stream_s
|
struct db_z_stream_t
|
||||||
{
|
{
|
||||||
unsigned char* next_in;
|
unsigned char* next_in;
|
||||||
unsigned int avail_in;
|
unsigned int avail_in;
|
||||||
@ -243,7 +216,7 @@ namespace game
|
|||||||
unsigned char* start_in;
|
unsigned char* start_in;
|
||||||
_OVERLAPPED overlapped;
|
_OVERLAPPED overlapped;
|
||||||
unsigned int readError;
|
unsigned int readError;
|
||||||
db_z_stream_s stream;
|
db_z_stream_t stream;
|
||||||
int readingResident;
|
int readingResident;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -649,33 +622,6 @@ namespace game
|
|||||||
BD_MAX_ERROR_CODE = 0x27E2,
|
BD_MAX_ERROR_CODE = 0x27E2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bdBitBufferDataType
|
|
||||||
{
|
|
||||||
BD_BB_NO_TYPE = 0x0,
|
|
||||||
BD_BB_BOOL_TYPE = 0x1,
|
|
||||||
BD_BB_SIGNED_CHAR8_TYPE = 0x2,
|
|
||||||
BD_BB_UNSIGNED_CHAR8_TYPE = 0x3,
|
|
||||||
BD_BB_WCHAR16_TYPE = 0x4,
|
|
||||||
BD_BB_SIGNED_INTEGER16_TYPE = 0x5,
|
|
||||||
BD_BB_UNSIGNED_INTEGER16_TYPE = 0x6,
|
|
||||||
BD_BB_SIGNED_INTEGER32_TYPE = 0x7,
|
|
||||||
BD_BB_UNSIGNED_INTEGER32_TYPE = 0x8,
|
|
||||||
BD_BB_SIGNED_INTEGER64_TYPE = 0x9,
|
|
||||||
BD_BB_UNSIGNED_INTEGER64_TYPE = 0xA,
|
|
||||||
BD_BB_RANGED_SIGNED_INTEGER32_TYPE = 0xB,
|
|
||||||
BD_BB_RANGED_UNSIGNED_INTEGER32_TYPE = 0xC,
|
|
||||||
BD_BB_FLOAT32_TYPE = 0xD,
|
|
||||||
BD_BB_FLOAT64_TYPE = 0xE,
|
|
||||||
BD_BB_RANGED_FLOAT32_TYPE = 0xF,
|
|
||||||
BD_BB_SIGNED_CHAR8_STRING_TYPE = 0x10,
|
|
||||||
BD_BB_UNSIGNED_CHAR8_STRING_TYPE = 0x11,
|
|
||||||
BD_BB_MBSTRING_TYPE = 0x12,
|
|
||||||
BD_BB_BLOB_TYPE = 0x13,
|
|
||||||
BD_BB_NAN_TYPE = 0x14,
|
|
||||||
BD_BB_FULL_TYPE = 0x15,
|
|
||||||
BD_BB_MAX_TYPE = 0x20,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bdNATType : uint8_t
|
enum bdNATType : uint8_t
|
||||||
{
|
{
|
||||||
BD_NAT_UNKNOWN = 0x0,
|
BD_NAT_UNKNOWN = 0x0,
|
||||||
@ -990,27 +936,6 @@ namespace game
|
|||||||
LOOKUP_ERROR_COUNT = 0x5,
|
LOOKUP_ERROR_COUNT = 0x5,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComStreamSyncModel
|
|
||||||
{
|
|
||||||
unsigned __int16 modelIndex;
|
|
||||||
unsigned __int8 alternateIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(ComStreamSyncModel) == 4);
|
|
||||||
|
|
||||||
struct ComStreamedSyncModelList
|
|
||||||
{
|
|
||||||
unsigned int modelCount;
|
|
||||||
ComStreamSyncModel models[18];
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(ComStreamedSyncModelList) == 0x4C);
|
|
||||||
|
|
||||||
struct ComStreamedSyncSwapBuffer
|
|
||||||
{
|
|
||||||
ComStreamedSyncModelList modelLists[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StructuredDataEnumEntry
|
struct StructuredDataEnumEntry
|
||||||
{
|
{
|
||||||
unsigned int name;
|
unsigned int name;
|
||||||
@ -1139,7 +1064,7 @@ namespace game
|
|||||||
float t1;
|
float t1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Font_s
|
struct Font_t
|
||||||
{
|
{
|
||||||
const char* fontName;
|
const char* fontName;
|
||||||
int pixelHeight;
|
int pixelHeight;
|
||||||
@ -1181,9 +1106,6 @@ namespace game
|
|||||||
DVAR_FLAG_LATCHED = 0x2,
|
DVAR_FLAG_LATCHED = 0x2,
|
||||||
DVAR_FLAG_CHEAT = 0x4,
|
DVAR_FLAG_CHEAT = 0x4,
|
||||||
DVAR_FLAG_REPLICATED = 0x8,
|
DVAR_FLAG_REPLICATED = 0x8,
|
||||||
DVAR_FLAG_INTERNAL = 0x80,
|
|
||||||
DVAR_FLAG_EXTERNAL = 0x100,
|
|
||||||
DVAR_FLAG_SERVERINFO = 0x400,
|
|
||||||
DVAR_FLAG_WRITE = 0x800,
|
DVAR_FLAG_WRITE = 0x800,
|
||||||
DVAR_FLAG_READ = 0x2000,
|
DVAR_FLAG_READ = 0x2000,
|
||||||
};
|
};
|
||||||
@ -1202,7 +1124,7 @@ namespace game
|
|||||||
rgb = 9 // Color without alpha
|
rgb = 9 // Color without alpha
|
||||||
};
|
};
|
||||||
|
|
||||||
union DvarValue
|
union dvar_value
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled;
|
||||||
int integer;
|
int integer;
|
||||||
@ -1245,9 +1167,9 @@ namespace game
|
|||||||
unsigned int flags; //08
|
unsigned int flags; //08
|
||||||
dvar_type type; //0C
|
dvar_type type; //0C
|
||||||
bool modified; //0D
|
bool modified; //0D
|
||||||
DvarValue current; //10
|
dvar_value current; //10
|
||||||
DvarValue latched;
|
dvar_value latched;
|
||||||
DvarValue reset;
|
dvar_value reset;
|
||||||
dvar_limits domain;
|
dvar_limits domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1260,9 +1182,9 @@ namespace game
|
|||||||
const char** argv[8];
|
const char** argv[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmd_function_s
|
struct cmd_function_t
|
||||||
{
|
{
|
||||||
cmd_function_s* next;
|
cmd_function_t* next;
|
||||||
const char* name;
|
const char* name;
|
||||||
void (__cdecl* function)();
|
void (__cdecl* function)();
|
||||||
};
|
};
|
||||||
@ -1313,7 +1235,7 @@ namespace game
|
|||||||
WEAPON_HAND_DEFAULT = 0x0,
|
WEAPON_HAND_DEFAULT = 0x0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct usercmd_s
|
struct usercmd_t
|
||||||
{
|
{
|
||||||
int serverTime;
|
int serverTime;
|
||||||
unsigned int buttons;
|
unsigned int buttons;
|
||||||
@ -1389,7 +1311,7 @@ namespace game
|
|||||||
bool hybridScope;
|
bool hybridScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compressedAnimData_s
|
struct compressedAnimData_t
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
int animRate;
|
int animRate;
|
||||||
@ -1408,7 +1330,7 @@ namespace game
|
|||||||
int flags;
|
int flags;
|
||||||
int startTime;
|
int startTime;
|
||||||
float startPosition[3];
|
float startPosition[3];
|
||||||
compressedAnimData_s compressedAnimData;
|
compressedAnimData_t compressedAnimData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SlideState
|
struct SlideState
|
||||||
@ -1417,7 +1339,7 @@ namespace game
|
|||||||
int noFricTime;
|
int noFricTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SprintState_s
|
struct SprintState_t
|
||||||
{
|
{
|
||||||
int sprintButtonUpRequired;
|
int sprintButtonUpRequired;
|
||||||
int sprintDelay;
|
int sprintDelay;
|
||||||
@ -1476,7 +1398,7 @@ namespace game
|
|||||||
NS_INVALID_NETSRC = 0x4,
|
NS_INVALID_NETSRC = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netadr_s
|
struct netadr_t
|
||||||
{
|
{
|
||||||
netadrtype_t type;
|
netadrtype_t type;
|
||||||
unsigned char ip[4];
|
unsigned char ip[4];
|
||||||
@ -1541,7 +1463,7 @@ namespace game
|
|||||||
unsigned int rgba;
|
unsigned int rgba;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hudelem_s
|
struct hudelem_t
|
||||||
{
|
{
|
||||||
he_type_t type;
|
he_type_t type;
|
||||||
float x;
|
float x;
|
||||||
@ -1587,9 +1509,9 @@ namespace game
|
|||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_hudelem_s
|
struct game_hudelem_t
|
||||||
{
|
{
|
||||||
hudelem_s elem;
|
hudelem_t elem;
|
||||||
int clientNum;
|
int clientNum;
|
||||||
int team;
|
int team;
|
||||||
int archived;
|
int archived;
|
||||||
@ -1631,13 +1553,6 @@ namespace game
|
|||||||
VAR_TOTAL_COUNT = 0x1B,
|
VAR_TOTAL_COUNT = 0x1B,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScriptFunctions
|
|
||||||
{
|
|
||||||
int maxSize;
|
|
||||||
int count;
|
|
||||||
int* address;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VariableStackBuffer
|
struct VariableStackBuffer
|
||||||
{
|
{
|
||||||
const char* pos;
|
const char* pos;
|
||||||
@ -1994,12 +1909,6 @@ namespace game
|
|||||||
const char* buffer;
|
const char* buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WeaponCompleteDef
|
|
||||||
{
|
|
||||||
const char* szInternalName;
|
|
||||||
WeaponDef* weapDef;
|
|
||||||
};
|
|
||||||
|
|
||||||
union XAssetHeader
|
union XAssetHeader
|
||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
@ -2030,21 +1939,21 @@ namespace game
|
|||||||
FxWorld *fxWorld;
|
FxWorld *fxWorld;
|
||||||
GfxWorld *gfxWorld;
|
GfxWorld *gfxWorld;
|
||||||
GfxLightDef *lightDef;*/
|
GfxLightDef *lightDef;*/
|
||||||
Font_s* font;
|
Font_t* font;
|
||||||
/*MenuList *menuList;
|
/*MenuList *menuList;
|
||||||
menuDef_t *menu;
|
menuDef_t *menu;
|
||||||
AnimationClass *animClass;
|
AnimationClass *animClass;
|
||||||
LocalizeEntry *localize;
|
LocalizeEntry *localize;
|
||||||
WeaponAttachment *attachment;*/
|
WeaponAttachment *attachment;
|
||||||
WeaponCompleteDef* weapon;
|
WeaponCompleteDef *weapon;
|
||||||
/*SndDriverGlobals *sndDriverGlobals;
|
SndDriverGlobals *sndDriverGlobals;
|
||||||
FxEffectDef *fx;
|
FxEffectDef *fx;
|
||||||
FxImpactTable *impactFx;
|
FxImpactTable *impactFx;
|
||||||
SurfaceFxTable *surfaceFx;*/
|
SurfaceFxTable *surfaceFx;*/
|
||||||
RawFile* rawfile;
|
RawFile* rawfile;
|
||||||
ScriptFile* scriptfile;
|
ScriptFile* scriptfile;
|
||||||
StringTable* stringTable;
|
/*StringTable *stringTable;
|
||||||
/*LeaderboardDef *leaderboardDef;
|
LeaderboardDef *leaderboardDef;
|
||||||
StructuredDataDefSet *structuredDataDefSet;
|
StructuredDataDefSet *structuredDataDefSet;
|
||||||
TracerDef *tracerDef;
|
TracerDef *tracerDef;
|
||||||
VehicleDef *vehDef;
|
VehicleDef *vehDef;
|
||||||
@ -2106,36 +2015,24 @@ namespace game
|
|||||||
const void* weapCompleteDef;
|
const void* weapCompleteDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FF_DIR
|
|
||||||
{
|
|
||||||
FFD_DEFAULT = 0x0,
|
|
||||||
FFD_MOD_DIR = 0x1,
|
|
||||||
FFD_USER_MAP = 0x2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sys_File
|
|
||||||
{
|
|
||||||
HANDLE handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace sp
|
namespace sp
|
||||||
{
|
{
|
||||||
// very shit structures for the moment cuz i cba mapping the whole thing out right now...
|
// very shit structures for the moment cuz i cba mapping the whole thing out right now...
|
||||||
struct gclient_s
|
struct gclient_t
|
||||||
{
|
{
|
||||||
char __0x00[0xB6DC];
|
char __0x00[0xB6DC];
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gentity_s
|
struct gentity_t
|
||||||
{
|
{
|
||||||
char __0x00[0x110];
|
char __0x00[0x110];
|
||||||
gclient_s* client;
|
gclient_t* client;
|
||||||
char __0x118[0x4C];
|
char __0x118[0x4C];
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct playerState_s
|
struct playerState_t
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2152,7 +2049,7 @@ namespace game
|
|||||||
namespace mp
|
namespace mp
|
||||||
{
|
{
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
struct playerState_s
|
struct playerState_t
|
||||||
{
|
{
|
||||||
int commandTime;
|
int commandTime;
|
||||||
int pm_type;
|
int pm_type;
|
||||||
@ -2204,7 +2101,7 @@ namespace game
|
|||||||
vec3_t viewangles;
|
vec3_t viewangles;
|
||||||
char _0x190[0xAC];
|
char _0x190[0xAC];
|
||||||
int locationSelectionInfo;
|
int locationSelectionInfo;
|
||||||
SprintState_s sprintState;
|
SprintState_t sprintState;
|
||||||
float holdBreathScale;
|
float holdBreathScale;
|
||||||
int holdBreathTimer;
|
int holdBreathTimer;
|
||||||
float moveSpeedScaleMultiplier;
|
float moveSpeedScaleMultiplier;
|
||||||
@ -2282,7 +2179,7 @@ namespace game
|
|||||||
TEAM_NUM_TEAMS = 0x4,
|
TEAM_NUM_TEAMS = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clientState_s
|
struct clientState_t
|
||||||
{
|
{
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
team_t team;
|
team_t team;
|
||||||
@ -2306,21 +2203,21 @@ namespace game
|
|||||||
int killCamEntity;
|
int killCamEntity;
|
||||||
int isInKillcam;
|
int isInKillcam;
|
||||||
char __0x332C[0x14];
|
char __0x332C[0x14];
|
||||||
usercmd_s cmd;
|
usercmd_t cmd;
|
||||||
usercmd_s oldcmd;
|
usercmd_t oldcmd;
|
||||||
int localClient;
|
int localClient;
|
||||||
char __0x33C4[0x24];
|
char __0x33C4[0x24];
|
||||||
float moveSpeedScaleMultiplier;
|
float moveSpeedScaleMultiplier;
|
||||||
int viewmodelIndex;
|
int viewmodelIndex;
|
||||||
int noSpectate;
|
int noSpectate;
|
||||||
clientState_s cs;
|
clientState_t cs;
|
||||||
ScoreInfo scores;
|
ScoreInfo scores;
|
||||||
char __pad[0x1B0];
|
char __pad[0x1B0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gclient_s
|
struct gclient_t
|
||||||
{
|
{
|
||||||
playerState_s ps;
|
playerState_t ps;
|
||||||
clientSession_t sess;
|
clientSession_t sess;
|
||||||
int flags;
|
int flags;
|
||||||
int spectatorClient;
|
int spectatorClient;
|
||||||
@ -2369,11 +2266,11 @@ namespace game
|
|||||||
char _0x14C[0xC];
|
char _0x14C[0xC];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gentity_s
|
struct gentity_t
|
||||||
{
|
{
|
||||||
EntityState s;
|
EntityState s;
|
||||||
EntityShared r;
|
EntityShared r;
|
||||||
gclient_s* client;
|
gclient_t* client;
|
||||||
char _0x170[0x50];
|
char _0x170[0x50];
|
||||||
int flags;
|
int flags;
|
||||||
char _0x1C4[0x18];
|
char _0x1C4[0x18];
|
||||||
@ -2382,7 +2279,7 @@ namespace game
|
|||||||
char _0x1E4[0x10C];
|
char _0x1E4[0x10C];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snapshot_s
|
struct snapshot_t
|
||||||
{
|
{
|
||||||
char _0x0[0x3C78];
|
char _0x0[0x3C78];
|
||||||
int ping;
|
int ping;
|
||||||
@ -2391,12 +2288,12 @@ namespace game
|
|||||||
int numClients;
|
int numClients;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cg_s
|
struct cg_t
|
||||||
{
|
{
|
||||||
playerState_s ps;
|
playerState_t ps;
|
||||||
char _0x3324[0x64];
|
char _0x3324[0x64];
|
||||||
snapshot_s* snap;
|
snapshot_t* snap;
|
||||||
snapshot_s* nextSnap; // theres alot after this cba rn
|
snapshot_t* nextSnap; // theres alot after this cba rn
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netProfilePacket_t
|
struct netProfilePacket_t
|
||||||
@ -2431,7 +2328,7 @@ namespace game
|
|||||||
netsrc_t sock;
|
netsrc_t sock;
|
||||||
int dropped;
|
int dropped;
|
||||||
int incomingSequence;
|
int incomingSequence;
|
||||||
netadr_s remoteAddress;
|
netadr_t remoteAddress;
|
||||||
int fragmentSequence;
|
int fragmentSequence;
|
||||||
int fragmentLength;
|
int fragmentLength;
|
||||||
char* fragmentBuffer;
|
char* fragmentBuffer;
|
||||||
@ -2471,24 +2368,6 @@ namespace game
|
|||||||
int isInKillcam;
|
int isInKillcam;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct svscmd_info_t
|
|
||||||
{
|
|
||||||
int time;
|
|
||||||
int type;
|
|
||||||
char cmd[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(svscmd_info_t) == 0x408);
|
|
||||||
|
|
||||||
struct client_net_buffers_t
|
|
||||||
{
|
|
||||||
svscmd_info_t reliableCommandInfo[128];
|
|
||||||
char netchanOutgoingBuffer[131072];
|
|
||||||
char netchanIncomingBuffer[2048];
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(client_net_buffers_t) == 0x40C00);
|
|
||||||
|
|
||||||
struct client_t
|
struct client_t
|
||||||
{
|
{
|
||||||
clientHeader_t header;
|
clientHeader_t header;
|
||||||
@ -2498,18 +2377,8 @@ namespace game
|
|||||||
int reliableAcknowledge;
|
int reliableAcknowledge;
|
||||||
int reliableSent;
|
int reliableSent;
|
||||||
int messageAcknowledge;
|
int messageAcknowledge;
|
||||||
int largeCommandSequence;
|
char _0xC30[0x41238];
|
||||||
int gamestateMessageNum;
|
gentity_t* gentity;
|
||||||
int challenge;
|
|
||||||
client_net_buffers_t netBuf;
|
|
||||||
int cumulThinkTime;
|
|
||||||
int beginCmdIndex;
|
|
||||||
int currCmdIndex;
|
|
||||||
usercmd_s lastUsercmd;
|
|
||||||
usercmd_s cmds[8];
|
|
||||||
int lastClientCommand;
|
|
||||||
char lastClientCommandString[1024];
|
|
||||||
gentity_s* gentity;
|
|
||||||
char name[16];
|
char name[16];
|
||||||
int lastPacketTime;
|
int lastPacketTime;
|
||||||
int lastConnectTime;
|
int lastConnectTime;
|
||||||
@ -2542,7 +2411,7 @@ namespace game
|
|||||||
|
|
||||||
struct missileFireParms
|
struct missileFireParms
|
||||||
{
|
{
|
||||||
gentity_s* target;
|
gentity_t* target;
|
||||||
float targetPosOrOffset[3];
|
float targetPosOrOffset[3];
|
||||||
float autoDetonateTime;
|
float autoDetonateTime;
|
||||||
bool lockon;
|
bool lockon;
|
||||||
@ -2554,10 +2423,10 @@ namespace game
|
|||||||
|
|
||||||
static_assert(sizeof(mp::client_t) == 0x83570);
|
static_assert(sizeof(mp::client_t) == 0x83570);
|
||||||
|
|
||||||
union playerState_s
|
union playerState_t
|
||||||
{
|
{
|
||||||
sp::playerState_s* sp;
|
sp::playerState_t* sp;
|
||||||
mp::playerState_s* mp;
|
mp::playerState_t* mp;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GfxDrawSceneMethod
|
enum GfxDrawSceneMethod
|
||||||
@ -2588,7 +2457,7 @@ namespace game
|
|||||||
TECHNIQUE_NONE = 0x137,
|
TECHNIQUE_NONE = 0x137,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GfxDrawMethod_s
|
struct GfxDrawMethod_t
|
||||||
{
|
{
|
||||||
int drawScene;
|
int drawScene;
|
||||||
int baseTechType;
|
int baseTechType;
|
||||||
@ -2640,8 +2509,8 @@ namespace game
|
|||||||
struct pmove_t
|
struct pmove_t
|
||||||
{
|
{
|
||||||
void* ps;
|
void* ps;
|
||||||
usercmd_s cmd;
|
usercmd_t cmd;
|
||||||
usercmd_s oldcmd;
|
usercmd_t oldcmd;
|
||||||
int tracemask;
|
int tracemask;
|
||||||
int numtouch;
|
int numtouch;
|
||||||
int touchents[32];
|
int touchents[32];
|
||||||
|
@ -8,19 +8,17 @@ namespace game
|
|||||||
* Functions
|
* Functions
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
WEAK symbol<void(unsigned int id)> AddRefToObject{0x1403D7A10, 0x1404326D0};
|
WEAK symbol<void(unsigned int id)> AddRefToObject{0, 0x1404326D0};
|
||||||
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x1403D7740, 0x1404326E0};
|
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x1403D7740, 0x1404326E0};
|
||||||
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0, 0x1404329B0};
|
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0, 0x1404329B0};
|
||||||
WEAK symbol<ObjectVariableValue*(unsigned int* index)> AllocVariable{0x1403D7A70, 0x140432A10};
|
WEAK symbol<ObjectVariableValue*(unsigned int* index)> AllocVariable{0x1403D7A70, 0x140432A10};
|
||||||
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x1403D90F0, 0x1404340C0};
|
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x1403D90F0, 0x1404340C0};
|
||||||
WEAK symbol<void(unsigned int id)> RemoveRefToObject{0x1403D8FE0, 0x140433FB0};
|
WEAK symbol<void(unsigned int id)> RemoveRefToObject{0, 0x140433FB0};
|
||||||
WEAK symbol<void(unsigned int parentId, unsigned int index)> RemoveVariableValue{0x1403D91C0, 0x140434190};
|
WEAK symbol<void(unsigned int parentId, unsigned int index)> RemoveVariableValue{0x1403D91C0, 0x140434190};
|
||||||
|
|
||||||
WEAK symbol<void(void*, void*)> AimAssist_AddToTargetList{0, 0x140139D80};
|
WEAK symbol<void(void*, void*)> AimAssist_AddToTargetList{0, 0x140139D80};
|
||||||
|
|
||||||
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0, 0x140239370};
|
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0, 0x140239370};
|
||||||
WEAK symbol<void()> BG_ClearWeaponDef{0x0, 0x140238D20};
|
|
||||||
WEAK symbol<bool()> BG_BotsConnectType{0x0, 0x140217080};
|
|
||||||
|
|
||||||
WEAK symbol<void()> Com_Frame_Try_Block_Function{0x1403BC980, 0x1404131A0};
|
WEAK symbol<void()> Com_Frame_Try_Block_Function{0x1403BC980, 0x1404131A0};
|
||||||
WEAK symbol<const char*(char const**)> Com_Parse{0x1404313E0, 0x1404F50E0};
|
WEAK symbol<const char*(char const**)> Com_Parse{0x1404313E0, 0x1404F50E0};
|
||||||
@ -30,8 +28,6 @@ namespace game
|
|||||||
WEAK symbol<void(float, float, int)> Com_SetSlowMotion{0, 0x1404158C0};
|
WEAK symbol<void(float, float, int)> Com_SetSlowMotion{0, 0x1404158C0};
|
||||||
WEAK symbol<void(const char* text_in)> Com_TokenizeString{0x1403B4150, 0x1403F7CC0};
|
WEAK symbol<void(const char* text_in)> Com_TokenizeString{0x1403B4150, 0x1403F7CC0};
|
||||||
WEAK symbol<void()> Com_EndTokenizeString{0x1403B37C0, 0x1403F7330};
|
WEAK symbol<void()> Com_EndTokenizeString{0x1403B37C0, 0x1403F7330};
|
||||||
WEAK symbol<void()> Com_StreamSync_UpdateLaunchData{0x0, 0x140411B50};
|
|
||||||
WEAK symbol<int(char* dest, int size, const char* fmt, ...)> Com_sprintf{0x140432310, 0x1404F6260};
|
|
||||||
|
|
||||||
WEAK symbol<void(const char* message)> Conbuf_AppendText{0x14043DDE0, 0x1405028C0};
|
WEAK symbol<void(const char* message)> Conbuf_AppendText{0x14043DDE0, 0x1405028C0};
|
||||||
|
|
||||||
@ -43,9 +39,9 @@ namespace game
|
|||||||
WEAK symbol<bool()> CL_IsCgameInitialized{0x140234DA0, 0x1402B9A70};
|
WEAK symbol<bool()> CL_IsCgameInitialized{0x140234DA0, 0x1402B9A70};
|
||||||
|
|
||||||
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x1401F2E20, 0x140271320};
|
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x1401F2E20, 0x140271320};
|
||||||
WEAK symbol<void(int localClientNum, mp::cg_s* cg, const char* dvar, const char* value)> CG_SetClientDvarFromServer{0x0, 0x14028A2C0};
|
WEAK symbol<void(int localClientNum, mp::cg_t* cg, const char* dvar, const char* value)> CG_SetClientDvarFromServer{0x0, 0x14028A2C0};
|
||||||
|
|
||||||
WEAK symbol<void(const char* cmdName, void (), cmd_function_s* allocedCmd)> Cmd_AddCommandInternal{0x1403B3570, 0x1403F7070};
|
WEAK symbol<void(const char* cmdName, void (), cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x1403B3570, 0x1403F7070};
|
||||||
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x1403B3B10, 0x1403F7680};
|
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x1403B3B10, 0x1403F7680};
|
||||||
|
|
||||||
WEAK symbol<void (XAssetType type, void (__cdecl *func)(XAssetHeader, void*), void* inData, bool includeOverride)> DB_EnumXAssets_FastFile{0x140271F50, 0x14031EF90};
|
WEAK symbol<void (XAssetType type, void (__cdecl *func)(XAssetHeader, void*), void* inData, bool includeOverride)> DB_EnumXAssets_FastFile{0x140271F50, 0x14031EF90};
|
||||||
@ -58,12 +54,11 @@ namespace game
|
|||||||
WEAK symbol<XAssetHeader(XAssetType type, const char* name, int allowCreateDefault)> DB_FindXAssetHeader{0x140272300, 0x14031F3A0};
|
WEAK symbol<XAssetHeader(XAssetType type, const char* name, int allowCreateDefault)> DB_FindXAssetHeader{0x140272300, 0x14031F3A0};
|
||||||
WEAK symbol<int(XAssetType type, const char* name)> DB_XAssetExists{0x140276200, 0x1403245E0};
|
WEAK symbol<int(XAssetType type, const char* name)> DB_XAssetExists{0x140276200, 0x1403245E0};
|
||||||
WEAK symbol<int(XAssetType type, const char* name)> DB_IsXAssetDefault{0x140273480 , 0x1403204D0};
|
WEAK symbol<int(XAssetType type, const char* name)> DB_IsXAssetDefault{0x140273480 , 0x1403204D0};
|
||||||
WEAK symbol<int(const RawFile* rawfile)> DB_GetRawFileLen{0x140272E80, 0x14031FF80};
|
WEAK symbol<int(const RawFile* rawfile)> DB_GetRawFileLen{0x0140272E80, 0x14031FF80};
|
||||||
WEAK symbol<void(const RawFile* rawfile, char* buf, int size)> DB_GetRawBuffer{0x140272D50, 0x14031FE50};
|
WEAK symbol<void(const RawFile* rawfile, char* buf, int size)> DB_GetRawBuffer{0x140272D50, 0x14031FE50};
|
||||||
WEAK symbol<int(const char* zoneName)> DB_IsLocalized{0x140273210, 0x140320360};
|
WEAK symbol<int(const char* zoneName)> DB_IsLocalized{0x140273210, 0x140320360};
|
||||||
WEAK symbol<int(XAssetType type, void** assets, int maxCount)> DB_GetAllXAssetOfType_FastFile{0x0, 0x14031FC00};
|
|
||||||
|
|
||||||
WEAK symbol<void*(unsigned int size, unsigned int alignment, unsigned int type, PMem_Source source)> PMem_AllocFromSource_NoDebug{0x140430B80, 0x1404F46C0};
|
WEAK symbol<void*(unsigned int size, unsigned int alignment, unsigned int type, PMem_Source source)> PMem_AllocFromSource_NoDebug{0x0140430B80, 0x001404F46C0};
|
||||||
WEAK symbol<void(const char* name, PMem_Direction allocDir)> PMem_Free{0x140430EC0 , 0x1404F4A30};
|
WEAK symbol<void(const char* name, PMem_Direction allocDir)> PMem_Free{0x140430EC0 , 0x1404F4A30};
|
||||||
|
|
||||||
WEAK symbol<void*(unsigned int size)> Hunk_AllocateTempMemoryHighInternal{0x140423C70, 0x1404E4E20};
|
WEAK symbol<void*(unsigned int size)> Hunk_AllocateTempMemoryHighInternal{0x140423C70, 0x1404E4E20};
|
||||||
@ -90,7 +85,7 @@ namespace game
|
|||||||
WEAK symbol<void(const dvar_t* dvar, const char* string)> Dvar_SetString{0x14042D6E0, 0x1404F08E0};
|
WEAK symbol<void(const dvar_t* dvar, const char* string)> Dvar_SetString{0x14042D6E0, 0x1404F08E0};
|
||||||
WEAK symbol<void(const char*, const char*, DvarSetSource)> Dvar_SetFromStringByNameFromSource{0x14042D000, 0x1404F00B0};
|
WEAK symbol<void(const char*, const char*, DvarSetSource)> Dvar_SetFromStringByNameFromSource{0x14042D000, 0x1404F00B0};
|
||||||
WEAK symbol<void()> Dvar_Sort{0x14042DEF0, 0x1404F1210};
|
WEAK symbol<void()> Dvar_Sort{0x14042DEF0, 0x1404F1210};
|
||||||
WEAK symbol<const char*(dvar_t* dvar, DvarValue value)> Dvar_ValueToString{0x14042E710, 0x1404F1A30};
|
WEAK symbol<const char*(dvar_t* dvar, dvar_value value)> Dvar_ValueToString{0x14042E710, 0x1404F1A30};
|
||||||
|
|
||||||
WEAK symbol<long long (const char* qpath, char** buffer)> FS_ReadFile{0x14041D0B0, 0x1404DE900};
|
WEAK symbol<long long (const char* qpath, char** buffer)> FS_ReadFile{0x14041D0B0, 0x1404DE900};
|
||||||
WEAK symbol<void(void* buffer)> FS_FreeFile{0x14041D0A0, 0x1404DE8F0};
|
WEAK symbol<void(void* buffer)> FS_FreeFile{0x14041D0A0, 0x1404DE8F0};
|
||||||
@ -99,31 +94,27 @@ namespace game
|
|||||||
WEAK symbol<void(const char *path, const char *dir)> FS_AddLocalizedGameDirectory{0x14041A2F0, 0x1404DC760};
|
WEAK symbol<void(const char *path, const char *dir)> FS_AddLocalizedGameDirectory{0x14041A2F0, 0x1404DC760};
|
||||||
|
|
||||||
WEAK symbol<Weapon(const char* pickupName, int model)> G_FindItem{0x140462490, 0x14021B7E0};
|
WEAK symbol<Weapon(const char* pickupName, int model)> G_FindItem{0x140462490, 0x14021B7E0};
|
||||||
WEAK symbol<int(playerState_s* ps, Weapon weapon, int dualWield, int startInAltMode, int usedBefore)> G_GivePlayerWeapon{0x140359E20, 0x1403DA5E0};
|
WEAK symbol<int(playerState_t* ps, Weapon weapon, int dualWield, int startInAltMode, int usedBefore)> G_GivePlayerWeapon{0x140359E20, 0x1403DA5E0};
|
||||||
WEAK symbol<Weapon(const char* name)> G_GetWeaponForName{0x140359890, 0x1403DA060};
|
WEAK symbol<Weapon(const char* name)> G_GetWeaponForName{0x140359890, 0x1403DA060};
|
||||||
WEAK symbol<void()> G_SetupLevelWeaponDef{0x0, 0x1403DA910};
|
|
||||||
WEAK symbol<void()> G_Glass_Update{0x14030E680, 0x140397450};
|
WEAK symbol<void()> G_Glass_Update{0x14030E680, 0x140397450};
|
||||||
WEAK symbol<void (playerState_s* ps, Weapon weapon, int hadWeapon)> G_InitializeAmmo{0x140311F00, 0x14039AEA0};
|
WEAK symbol<void (playerState_t* ps, Weapon weapon, int hadWeapon)> G_InitializeAmmo{0x140311F00, 0x14039AEA0};
|
||||||
WEAK symbol<void(int clientNum, Weapon weapon)> G_SelectWeapon{0x14035A200, 0x1403DA880};
|
WEAK symbol<void(int clientNum, Weapon weapon)> G_SelectWeapon{0x14035A200, 0x1403DA880};
|
||||||
WEAK symbol<int(playerState_s* ps, Weapon weapon)> G_TakePlayerWeapon{0x14035A350, 0x1403DA9C0};
|
WEAK symbol<int(playerState_t* ps, Weapon weapon)> G_TakePlayerWeapon{0x14035A350, 0x1403DA9C0};
|
||||||
WEAK symbol<unsigned int (const char* name, /*ConfigString*/ unsigned int start, unsigned int max, int create,
|
WEAK symbol<unsigned int (const char* name, /*ConfigString*/ unsigned int start, unsigned int max, int create,
|
||||||
const char* errormsg)> G_FindConfigstringIndex{0x0, 0x140161F90};
|
const char* errormsg)> G_FindConfigstringIndex{0x0, 0x140161F90};
|
||||||
WEAK symbol<int(int server_time)> G_RunFrame{0x0, 0x1403A05E0};
|
WEAK symbol<int(int server_time)> G_RunFrame{0x0, 0x1403A05E0};
|
||||||
WEAK symbol<int(int clientNun)> G_GetClientScore{0x0, 0x14039EF60};
|
|
||||||
|
|
||||||
WEAK symbol<game_hudelem_s*(int clientNum, int teamNum)> HudElem_Alloc{0x0, 0x1403997E0};
|
WEAK symbol<game_hudelem_t*(int clientNum, int teamNum)> HudElem_Alloc{0x0, 0x1403997E0};
|
||||||
|
|
||||||
WEAK symbol<char*(char* string)> I_CleanStr{0x140432460, 0x1404F63C0};
|
WEAK symbol<char*(char* string)> I_CleanStr{0x140432460, 0x1404F63C0};
|
||||||
WEAK symbol<void(char* dest, const char* src, int destsize)> I_strncpyz{0x140432810, 0x1404F67A0};
|
|
||||||
WEAK symbol<void(char* dest, int size, const char* src)> I_strncat{0x140432740, 0x1404F66D0};
|
|
||||||
|
|
||||||
WEAK symbol<char*(GfxImage* image, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipCount,
|
WEAK symbol<char*(GfxImage* image, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipCount,
|
||||||
uint32_t imageFlags, DXGI_FORMAT imageFormat, const char* name, const void* initData)> Image_Setup{0x140517910, 0x1405E4380};
|
uint32_t imageFlags, DXGI_FORMAT imageFormat, const char* name, const void* initData)>
|
||||||
|
Image_Setup{0x140517910, 0x1405E4380};
|
||||||
|
|
||||||
WEAK symbol<const char*(int, int, int)> Key_KeynumToString{0x14023D9A0, 0x1402C40E0};
|
WEAK symbol<const char*(int, int, int)> Key_KeynumToString{0x14023D9A0, 0x1402C40E0};
|
||||||
|
|
||||||
WEAK symbol<unsigned int (int)> Live_SyncOnlineDataFlags{0, 0x1405ABF70};
|
WEAK symbol<unsigned int (int)> Live_SyncOnlineDataFlags{0, 0x1405ABF70};
|
||||||
WEAK symbol<void(int localControllerIndex)> LiveStorage_StatsWriteNotNeeded{0x1403BA420, 0x140409120};
|
|
||||||
|
|
||||||
WEAK symbol<bool(int controllerIndex, unsigned int name, int value, StatsGroup statsGroup)> LiveStorage_PlayerDataSetIntByName{0x1403B8C20, 0x140404730};
|
WEAK symbol<bool(int controllerIndex, unsigned int name, int value, StatsGroup statsGroup)> LiveStorage_PlayerDataSetIntByName{0x1403B8C20, 0x140404730};
|
||||||
WEAK symbol<bool(std::uint8_t* persistentData, const char* lookupString, int value, std::uint8_t* modifiedFlags, StatsGroup statsGroup)> LiveStorage_PlayerDataSetReservedInt{0x1403B8D00, 0x140404820};
|
WEAK symbol<bool(std::uint8_t* persistentData, const char* lookupString, int value, std::uint8_t* modifiedFlags, StatsGroup statsGroup)> LiveStorage_PlayerDataSetReservedInt{0x1403B8D00, 0x140404820};
|
||||||
@ -141,9 +132,8 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<StructuredDataDef*(const char* filename, unsigned int maxSize)>StructuredDataDef_GetAsset{0, 0x1404E6560};
|
WEAK symbol<StructuredDataDef*(const char* filename, unsigned int maxSize)>StructuredDataDef_GetAsset{0, 0x1404E6560};
|
||||||
WEAK symbol<StringTable*(const char* fileName, const StringTable** tablePtr)>StringTable_GetAsset{0, 0x1404E6170};
|
WEAK symbol<StringTable*(const char* fileName, const StringTable** tablePtr)>StringTable_GetAsset{0, 0x1404E6170};
|
||||||
WEAK symbol<const char*(const StringTable* table, int row, int column)> StringTable_GetColumnValueForRow{0, 0x1404E61A0};
|
WEAK symbol<const char*(const StringTable* table, const int row, const int column)> StringTable_GetColumnValueForRow{0, 0x1404E61A0};
|
||||||
WEAK symbol<int(const StringTable* table, int comparisonColumn, const char* value)> StringTable_LookupRowNumForValue{0, 0x1404E6260};
|
WEAK symbol<int(const StringTable* table, const int comparisonColumn, const char* value)> StringTable_LookupRowNumForValue{0, 0x1404E6260};
|
||||||
WEAK symbol<int(const char* string)> StringTable_HashString{0x1404259A0, 0x1404E6320};
|
|
||||||
|
|
||||||
WEAK symbol<void(int localClientNum, const char* menuName, int isPopup, int isModal, unsigned int isExclusive)> LUI_OpenMenu{0x1403FD460, 0x1404B3610};
|
WEAK symbol<void(int localClientNum, const char* menuName, int isPopup, int isModal, unsigned int isExclusive)> LUI_OpenMenu{0x1403FD460, 0x1404B3610};
|
||||||
// Made up name, replaced by ScopedCriticalSection on Black Ops 3
|
// Made up name, replaced by ScopedCriticalSection on Black Ops 3
|
||||||
@ -154,18 +144,18 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<Material*(const char* material)> Material_RegisterHandle{0x140523D90, 0x1405F0E20};
|
WEAK symbol<Material*(const char* material)> Material_RegisterHandle{0x140523D90, 0x1405F0E20};
|
||||||
|
|
||||||
WEAK symbol<void(netsrc_t, netadr_s*, const char*)> NET_OutOfBandPrint{0, 0x14041D5C0};
|
WEAK symbol<void(netsrc_t, netadr_t*, const char*)> NET_OutOfBandPrint{0, 0x14041D5C0};
|
||||||
WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_s* to)> NET_SendLoopPacket{0, 0x14041D780};
|
WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_t* to)> NET_SendLoopPacket{0, 0x14041D780};
|
||||||
WEAK symbol<bool(const char* s, netadr_s* a)> NET_StringToAdr{0, 0x14041D870};
|
WEAK symbol<bool(const char* s, netadr_t* a)> NET_StringToAdr{0, 0x14041D870};
|
||||||
WEAK symbol<void(netadr_s*, sockaddr*)> NetadrToSockadr{0, 0x1404E53D0};
|
WEAK symbol<void(netadr_t*, sockaddr*)> NetadrToSockadr{0, 0x1404E53D0};
|
||||||
|
|
||||||
WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1,
|
WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1,
|
||||||
float* color, Material* material)> R_AddCmdDrawStretchPic{0x140234460, 0x140600BE0};
|
float* color, Material* material)> R_AddCmdDrawStretchPic{0x140234460, 0x140600BE0};
|
||||||
WEAK symbol<void(const char*, int, Font_s*, float, float, float, float, float, float*, int)> R_AddCmdDrawText{0x140533E40, 0x140601070};
|
WEAK symbol<void(const char*, int, Font_t*, float, float, float, float, float, float*, int)> R_AddCmdDrawText{0x140533E40, 0x140601070};
|
||||||
WEAK symbol<void(const char*, int, Font_s*, float, float, float, float, float, const float*, int, int, char)> R_AddCmdDrawTextWithCursor{0x140534170, 0x1406013A0};
|
WEAK symbol<void(const char*, int, Font_t*, float, float, float, float, float, const float*, int, int, char)> R_AddCmdDrawTextWithCursor{0x140534170, 0x1406013A0};
|
||||||
WEAK symbol<Font_s*(const char* font)> R_RegisterFont{0x1405130B0, 0x1405DFAC0};
|
WEAK symbol<Font_t*(const char* font)> R_RegisterFont{0x1405130B0, 0x1405DFAC0};
|
||||||
WEAK symbol<void()> R_SyncRenderThread{0x140535AF0, 0x140602D30};
|
WEAK symbol<void()> R_SyncRenderThread{0x140535AF0, 0x140602D30};
|
||||||
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{0x140513390, 0x1405DFDB0};
|
WEAK symbol<int(const char* text, int maxChars, Font_t* font)> R_TextWidth{0x140513390, 0x1405DFDB0};
|
||||||
|
|
||||||
WEAK symbol<ScreenPlacement*()> ScrPlace_GetViewPlacement{0x14024D150, 0x1402F6D40};
|
WEAK symbol<ScreenPlacement*()> ScrPlace_GetViewPlacement{0x14024D150, 0x1402F6D40};
|
||||||
|
|
||||||
@ -173,17 +163,13 @@ namespace game
|
|||||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x1403D84F0, 0x1404334A0};
|
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x1403D84F0, 0x1404334A0};
|
||||||
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0, 0x1404333A0};
|
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0, 0x1404333A0};
|
||||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int id)> GetVariableName{0x1403D8E90, 0x140433E60};
|
WEAK symbol<unsigned int(unsigned int parentId, unsigned int id)> GetVariableName{0x1403D8E90, 0x140433E60};
|
||||||
WEAK symbol<void(VariableValue* result, unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x1403DC810, 0x140437860};
|
WEAK symbol<void (VariableValue* result, unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x1403DC810, 0x140437860};
|
||||||
WEAK symbol<const float*(const float* v)> Scr_AllocVector{0x1403D9AF0, 0x140434A10};
|
WEAK symbol<const float*(const float* v)> Scr_AllocVector{0x1403D9AF0, 0x140434A10};
|
||||||
WEAK symbol<const char*(unsigned int index)> Scr_GetString{0x1403DE200, 0x140439160};
|
WEAK symbol<const char*(unsigned int index)> Scr_GetString{0, 0x140439160};
|
||||||
WEAK symbol<unsigned int(unsigned int index)> Scr_GetConstString{0x1403DDAC0, 0x140438AD0};
|
|
||||||
WEAK symbol<unsigned int(unsigned int index)> Scr_GetConstIString{0x1403DD8A0, 0x1404388B0};
|
|
||||||
WEAK symbol<void(int value)> Scr_AddInt{0x0, 0x140437E70};
|
WEAK symbol<void(int value)> Scr_AddInt{0x0, 0x140437E70};
|
||||||
WEAK symbol<void(const char* value)> Scr_AddString{0x0, 0x1404381D0};
|
WEAK symbol<void(const char* value)> Scr_AddString{0x0, 0x1404381D0};
|
||||||
WEAK symbol<int(unsigned int index)> Scr_GetInt{0x1403DDEB0, 0x140438E10};
|
WEAK symbol<int(unsigned int index)> Scr_GetInt{0x0, 0x140438E10};
|
||||||
WEAK symbol<float(unsigned int index)> Scr_GetFloat{0x1403DDD50, 0x140438D60};
|
WEAK symbol<float(unsigned int index)> Scr_GetFloat{0, 0x140438D60};
|
||||||
WEAK symbol<void(unsigned int index, float* vectorValue)> Scr_GetVector{0x1403DE470, 0x1404393D0};
|
|
||||||
WEAK symbol<unsigned int(unsigned int index)> Scr_GetObject{0x1403DDF70, 0x140438ED0};
|
|
||||||
WEAK symbol<unsigned int()> Scr_GetNumParam{0x1403DDF60, 0x140438EC0};
|
WEAK symbol<unsigned int()> Scr_GetNumParam{0x1403DDF60, 0x140438EC0};
|
||||||
WEAK symbol<void()> Scr_ClearOutParams{0x1403DD500, 0x140438600};
|
WEAK symbol<void()> Scr_ClearOutParams{0x1403DD500, 0x140438600};
|
||||||
WEAK symbol<scr_entref_t(unsigned int entId)> Scr_GetEntityIdRef{0x1403DBDC0, 0x140436E10};
|
WEAK symbol<scr_entref_t(unsigned int entId)> Scr_GetEntityIdRef{0x1403DBDC0, 0x140436E10};
|
||||||
@ -192,16 +178,15 @@ namespace game
|
|||||||
WEAK symbol<void(unsigned int id, unsigned int stringValue, unsigned int paramcount)> Scr_NotifyId{0x1403DE730, 0x140439700};
|
WEAK symbol<void(unsigned int id, unsigned int stringValue, unsigned int paramcount)> Scr_NotifyId{0x1403DE730, 0x140439700};
|
||||||
WEAK symbol<void(unsigned int stringValue, unsigned int paramcount)> Scr_NotifyLevel{0x0, 0x1404397D0};
|
WEAK symbol<void(unsigned int stringValue, unsigned int paramcount)> Scr_NotifyLevel{0x0, 0x1404397D0};
|
||||||
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> Scr_GetEntityId{0x0, 0x140436D60};
|
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> Scr_GetEntityId{0x0, 0x140436D60};
|
||||||
WEAK symbol<bool(VariableValue* value)> Scr_CastString{0x1403D9BA0, 0x140434AC0};
|
WEAK symbol<bool(VariableValue* value)> Scr_CastString{0x0, 0x140434AC0};
|
||||||
|
|
||||||
WEAK symbol<unsigned __int16(int handle, unsigned int paramcount)> Scr_ExecThread{0x1403DD600, 0x1404386E0};
|
WEAK symbol<unsigned __int16(int handle, unsigned int paramcount)> Scr_ExecThread{0x1403DD600, 0x1404386E0};
|
||||||
WEAK symbol<unsigned int(const char* name)> Scr_LoadScript{0x1403D3C50, 0x14042EAA0};
|
WEAK symbol<unsigned int(const char* name)> Scr_LoadScript{0x1403D3C50, 0x14042EAA0};
|
||||||
WEAK symbol<unsigned int(const char* script, unsigned int name)> Scr_GetFunctionHandle{0x1403D3AD0 , 0x14042E920};
|
WEAK symbol<unsigned int(const char* script, unsigned int name)> Scr_GetFunctionHandle{0x1403D3AD0 , 0x14042E920};
|
||||||
WEAK symbol<unsigned int(void* func, int type, unsigned int name)> Scr_RegisterFunction{0x1403D3530, 0x14042E330};
|
WEAK symbol<unsigned int(void* func, int type, unsigned int name)> Scr_RegisterFunction{0x1403D3530, 0x14042E330};
|
||||||
WEAK symbol<unsigned int(const char** pName, int* type)> Scr_GetFunction{0x14034A950, 0x1403CD9F0};
|
WEAK symbol<void()> Scr_ErrorInternal{0x0, 0x140438660};
|
||||||
WEAK symbol<void()> Scr_ErrorInternal{0x1403DD580 , 0x140438660};
|
|
||||||
|
|
||||||
WEAK symbol<int(unsigned int)> GetObjectType{0x1403D8D30, 0x140433CF0};
|
WEAK symbol<int(unsigned int)> GetObjectType{0x0, 0x140433CF0};
|
||||||
|
|
||||||
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0, 0x14043A280};
|
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0, 0x14043A280};
|
||||||
|
|
||||||
@ -218,33 +203,29 @@ namespace game
|
|||||||
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0, 0x1403F8110};
|
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0, 0x1403F8110};
|
||||||
WEAK symbol<void()> SV_MatchEnd{0x0, 0x14047A090};
|
WEAK symbol<void()> SV_MatchEnd{0x0, 0x14047A090};
|
||||||
|
|
||||||
WEAK symbol<void(netadr_s* from)> SV_DirectConnect{0, 0x140471390};
|
WEAK symbol<void(netadr_t* from)> SV_DirectConnect{0, 0x140471390};
|
||||||
|
WEAK symbol<void(int, int, const char*)> SV_GameSendServerCommand{0x140490F40, 0x1404758C0};
|
||||||
WEAK symbol<bool()> SV_Loaded{0x140491820, 0x1404770C0};
|
WEAK symbol<bool()> SV_Loaded{0x140491820, 0x1404770C0};
|
||||||
WEAK symbol<void(int localClientNum, const char* map, bool mapIsPreloaded)> SV_StartMap{0, 0x140470170};
|
WEAK symbol<void(int localClientNum, const char* map, bool mapIsPreloaded)> SV_StartMap{0, 0x140470170};
|
||||||
WEAK symbol<void(int localClientNum, const char* map, bool mapIsPreloaded, bool migrate)> SV_StartMapForParty{0, 0x1404702F0};
|
WEAK symbol<void(int localClientNum, const char* map, bool mapIsPreloaded, bool migrate)> SV_StartMapForParty{0, 0x1404702F0};
|
||||||
WEAK symbol<void(mp::client_t* cl, int isReconnectingClient)> SV_StreamSync_ClientConnect{0x0, 0x140488080};
|
|
||||||
WEAK symbol<const char*(int clientNum, unsigned __int16 scriptPersId)> ClientConnect{0x0, 0x140387630};
|
|
||||||
WEAK symbol<void(mp::client_t* client, usercmd_s* cmd)> SV_ClientEnterWorld{0x0, 0x1404710F0};
|
|
||||||
WEAK symbol<void(mp::client_t* drop, const char* reason, bool tellThem)> SV_DropClient{0x0, 0x140472110};
|
|
||||||
|
|
||||||
WEAK symbol<mp::gentity_s*(const char*, unsigned int, unsigned int, unsigned int)> SV_AddBot{0, 0x140470920};
|
WEAK symbol<mp::gentity_t*(const char*, unsigned int, unsigned int, unsigned int)> SV_AddBot{0, 0x140470920};
|
||||||
WEAK symbol<bool(int clientNum)> SV_BotIsBot{0, 0x140461340};
|
WEAK symbol<bool(int clientNum)> SV_BotIsBot{0, 0x140461340};
|
||||||
WEAK symbol<const char*()> SV_BotGetRandomName{0, 0x140460B80};
|
WEAK symbol<const char*()> SV_BotGetRandomName{0, 0x140460B80};
|
||||||
WEAK symbol<void(mp::gentity_s*)> SV_SpawnTestClient{0, 0x1404740A0};
|
WEAK symbol<void(mp::gentity_t*)> SV_SpawnTestClient{0, 0x1404740A0};
|
||||||
|
|
||||||
WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0, 0x140472430};
|
WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0, 0x140472430};
|
||||||
WEAK symbol<void()> SV_FastRestart{0x14048B890, 0x14046F440};
|
WEAK symbol<void()> SV_FastRestart{0x14048B890, 0x14046F440};
|
||||||
WEAK symbol<playerState_s*(int num)> SV_GetPlayerstateForClientNum{0x140490F80, 0x140475A10};
|
WEAK symbol<playerState_t*(int num)> SV_GetPlayerstateForClientNum{0x140490F80, 0x140475A10};
|
||||||
WEAK symbol<const char*(int clientNum)> SV_GetGuid{0, 0x140475990};
|
WEAK symbol<const char*(int clientNum)> SV_GetGuid{0, 0x140475990};
|
||||||
WEAK symbol<void(int clientNum, const char* reason)> SV_KickClientNum{0, 0x14046F730};
|
WEAK symbol<void(int clientNum, const char* reason)> SV_KickClientNum{0, 0x14046F730};
|
||||||
WEAK symbol<void(int index, const char* string)> SV_SetConfigstring{0, 0x140477450};
|
WEAK symbol<void(int index, const char* string)> SV_SetConfigstring{0, 0x140477450};
|
||||||
WEAK symbol<int(mp::client_t* client, const unsigned char* cmd, int cmdSize)> SV_CanReplaceServerCommand{0x0, 0x140478F00};
|
|
||||||
|
|
||||||
WEAK symbol<void(const char* error, ...)> Sys_Error{0x14043AC20, 0x1404FF510};
|
WEAK symbol<void(const char* error, ...)> Sys_Error{0x14043AC20, 0x1404FF510};
|
||||||
WEAK symbol<bool()> Sys_IsDatabaseReady2{0x1403C2D40, 0x140423920};
|
WEAK symbol<bool()> Sys_IsDatabaseReady2{0x1403C2D40, 0x140423920};
|
||||||
WEAK symbol<int()> Sys_Milliseconds{0x14043D2A0, 0x140501CA0};
|
WEAK symbol<int()> Sys_Milliseconds{0x14043D2A0, 0x140501CA0};
|
||||||
WEAK symbol<void()> Sys_ShowConsole{0x14043E650, 0x140503130};
|
WEAK symbol<void()> Sys_ShowConsole{0x14043E650, 0x140503130};
|
||||||
WEAK symbol<bool(int, void const*, const netadr_s*)> Sys_SendPacket{0x14043D000, 0x140501A00};
|
WEAK symbol<bool(int, void const*, const netadr_t*)> Sys_SendPacket{0x14043D000, 0x140501A00};
|
||||||
WEAK symbol<void*(int valueIndex)> Sys_GetValue{0x1403C2C30, 0x1404237D0};
|
WEAK symbol<void*(int valueIndex)> Sys_GetValue{0x1403C2C30, 0x1404237D0};
|
||||||
WEAK symbol<bool()> Sys_IsMainThread{0x1478FC470, 0x140423950};
|
WEAK symbol<bool()> Sys_IsMainThread{0x1478FC470, 0x140423950};
|
||||||
WEAK symbol<HANDLE(Sys_Folder folder, const char* baseFilename)> Sys_CreateFile{0x140434B10, 0x1404F8FD0};
|
WEAK symbol<HANDLE(Sys_Folder folder, const char* baseFilename)> Sys_CreateFile{0x140434B10, 0x1404F8FD0};
|
||||||
@ -255,7 +236,6 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<const char*(const char*)> UI_LocalizeMapname{0, 0x1404B96D0};
|
WEAK symbol<const char*(const char*)> UI_LocalizeMapname{0, 0x1404B96D0};
|
||||||
WEAK symbol<const char*(const char*)> UI_LocalizeGametype{0, 0x1404B90F0};
|
WEAK symbol<const char*(const char*)> UI_LocalizeGametype{0, 0x1404B90F0};
|
||||||
WEAK symbol<void(int localClientNum, const char* srcString, char* dstString, int dstBufferSize)> UI_ReplaceDirective{0x0, 0x1404D8A00};
|
|
||||||
|
|
||||||
WEAK symbol<DWOnlineStatus(int)> dwGetLogOnStatus{0, 0x140589490};
|
WEAK symbol<DWOnlineStatus(int)> dwGetLogOnStatus{0, 0x140589490};
|
||||||
|
|
||||||
@ -266,12 +246,6 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<void(void* ps)> Jump_ClearState{0x0, 0x140213120};
|
WEAK symbol<void(void* ps)> Jump_ClearState{0x0, 0x140213120};
|
||||||
|
|
||||||
WEAK symbol<void(const char* pszCommand, char* pszBuffer, int iBufferSize)> MSG_WriteReliableCommandToBuffer{0x0, 0x1404232B0};
|
|
||||||
|
|
||||||
WEAK symbol<void(unsigned __int64 markPos)> LargeLocalResetToMark{0x140423B50, 0x1404E4D00};
|
|
||||||
|
|
||||||
WEAK symbol<int(const char* s0, const char* s1, int n)> I_strnicmp{0x140432840, 0x1404F67D0};
|
|
||||||
|
|
||||||
WEAK symbol<void*(jmp_buf* Buf, int Value)> longjmp{0x14062E030, 0x140738060};
|
WEAK symbol<void*(jmp_buf* Buf, int Value)> longjmp{0x14062E030, 0x140738060};
|
||||||
WEAK symbol<int (jmp_buf* Buf)> _setjmp{0x14062F030, 0x140739060};
|
WEAK symbol<int (jmp_buf* Buf)> _setjmp{0x14062F030, 0x140739060};
|
||||||
|
|
||||||
@ -283,7 +257,7 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<CmdArgs> cmd_args{0x144CE7F70, 0x144518480};
|
WEAK symbol<CmdArgs> cmd_args{0x144CE7F70, 0x144518480};
|
||||||
WEAK symbol<CmdArgs> sv_cmd_args{0x144CE8020, 0x144518530};
|
WEAK symbol<CmdArgs> sv_cmd_args{0x144CE8020, 0x144518530};
|
||||||
WEAK symbol<cmd_function_s*> cmd_functions{0x144CE80C8, 0x1445185D8};
|
WEAK symbol<cmd_function_t*> cmd_functions{0x144CE80C8, 0x1445185D8};
|
||||||
|
|
||||||
WEAK symbol<int> dvarCount{0x1458CBA3C, 0x1478EADF4};
|
WEAK symbol<int> dvarCount{0x1458CBA3C, 0x1478EADF4};
|
||||||
WEAK symbol<dvar_t*> sortedDvars{0x1458CBA60, 0x1478EAE10};
|
WEAK symbol<dvar_t*> sortedDvars{0x1458CBA60, 0x1478EAE10};
|
||||||
@ -326,20 +300,20 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<DWORD> threadIds{0x144DE6640, 0x1446B4960};
|
WEAK symbol<DWORD> threadIds{0x144DE6640, 0x1446B4960};
|
||||||
|
|
||||||
WEAK symbol<GfxDrawMethod_s> gfxDrawMethod{0x145F525A8, 0x1480350D8};
|
WEAK symbol<GfxDrawMethod_t> gfxDrawMethod{0x145F525A8, 0x1480350D8};
|
||||||
|
|
||||||
namespace sp
|
namespace sp
|
||||||
{
|
{
|
||||||
WEAK symbol<gentity_s> g_entities{0x143C91600, 0};
|
WEAK symbol<gentity_t> g_entities{0x143C91600, 0};
|
||||||
|
|
||||||
WEAK symbol<XZone> g_zones_0{0x1434892D8, 0};
|
WEAK symbol<XZone> g_zones_0{0x1434892D8, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace mp
|
namespace mp
|
||||||
{
|
{
|
||||||
WEAK symbol<cg_s> cgArray{0, 0x14176EC00};
|
WEAK symbol<cg_t> cgArray{0, 0x14176EC00};
|
||||||
|
|
||||||
WEAK symbol<gentity_s> g_entities{0, 0x14427A0E0};
|
WEAK symbol<gentity_t> g_entities{0, 0x14427A0E0};
|
||||||
|
|
||||||
WEAK symbol<int> svs_clientCount{0, 0x14647B28C};
|
WEAK symbol<int> svs_clientCount{0, 0x14647B28C};
|
||||||
WEAK symbol<client_t> svs_clients{0, 0x14647B290};
|
WEAK symbol<client_t> svs_clients{0, 0x14647B290};
|
||||||
@ -350,8 +324,6 @@ namespace game
|
|||||||
WEAK symbol<int> serverTime{0, 0x14647B280};
|
WEAK symbol<int> serverTime{0, 0x14647B280};
|
||||||
|
|
||||||
WEAK symbol<XZone> g_zones_0{0, 0x143A46498};
|
WEAK symbol<XZone> g_zones_0{0, 0x143A46498};
|
||||||
|
|
||||||
WEAK symbol<int> s_launchDataAvailable{0x0, 0x1445CE354};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace hks
|
namespace hks
|
||||||
|
@ -64,7 +64,9 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info)
|
|||||||
&exception_information, nullptr, nullptr))
|
&exception_information, nullptr, nullptr))
|
||||||
{
|
{
|
||||||
char buf[4096]{};
|
char buf[4096]{};
|
||||||
sprintf_s(buf, "An exception 0x%08X occurred at location 0x%p\n", exception_info->ExceptionRecord->ExceptionCode, exception_info->ExceptionRecord->ExceptionAddress);
|
sprintf_s(buf, "An exception 0x%08X occurred at location 0x%p\n",
|
||||||
|
exception_info->ExceptionRecord->ExceptionCode,
|
||||||
|
exception_info->ExceptionRecord->ExceptionAddress);
|
||||||
game::show_error(buf);
|
game::show_error(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,7 @@
|
|||||||
#define BINARY_PAYLOAD_SIZE 0x0B500000
|
#define BINARY_PAYLOAD_SIZE 0x0B500000
|
||||||
|
|
||||||
// Decide whether to load the game as lib or to inject it
|
// Decide whether to load the game as lib or to inject it
|
||||||
#if 1
|
|
||||||
#define INJECT_HOST_AS_LIB
|
#define INJECT_HOST_AS_LIB
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4100)
|
#pragma warning(disable: 4100)
|
||||||
@ -55,7 +53,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
#include "properties.hpp"
|
|
||||||
|
|
||||||
#include <gsl/gsl>
|
|
||||||
|
|
||||||
#include <ShlObj.h>
|
|
||||||
|
|
||||||
namespace utils::properties
|
|
||||||
{
|
|
||||||
std::filesystem::path get_appdata_path()
|
|
||||||
{
|
|
||||||
PWSTR path;
|
|
||||||
if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path)))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to read APPDATA path!");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto _ = gsl::finally([&path]
|
|
||||||
{
|
|
||||||
CoTaskMemFree(path);
|
|
||||||
});
|
|
||||||
|
|
||||||
static auto appdata = std::filesystem::path(path) / "alterware";
|
|
||||||
return appdata;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace utils::properties
|
|
||||||
{
|
|
||||||
std::filesystem::path get_appdata_path();
|
|
||||||
}
|
|
@ -115,13 +115,13 @@ namespace utils::string
|
|||||||
|
|
||||||
void strip(const char* in, char* out, size_t max)
|
void strip(const char* in, char* out, size_t max)
|
||||||
{
|
{
|
||||||
if (!in || !out || !max) return;
|
if (!in || !out) return;
|
||||||
|
|
||||||
max--;
|
max--;
|
||||||
auto current = 0u;
|
auto current = 0u;
|
||||||
while (*in != 0 && current < max)
|
while (*in != 0 && current < max)
|
||||||
{
|
{
|
||||||
const auto color_index = (static_cast<size_t>(*(in + 1) - 48)) >= 0xC ? 7 : (*(in + 1) - 48);
|
const auto color_index = (*(in + 1) - 48) >= 0xC ? 7 : (*(in + 1) - 48);
|
||||||
|
|
||||||
if (*in == '^' && (color_index != 7 || *(in + 1) == '7'))
|
if (*in == '^' && (color_index != 7 || *(in + 1) == '7'))
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace utils::string
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
const int res = vsnprintf(entry->buffer, entry->size, format, ap);
|
const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
|
||||||
if (res > 0) break; // Success
|
if (res > 0) break; // Success
|
||||||
if (res == 0) return nullptr; // Error
|
if (res == 0) return nullptr; // Error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user