Merge branch 'main' of https://github.com/mjkzy/boiii into scripts

This commit is contained in:
m 2023-05-09 03:07:02 -05:00
commit 32f8dbb9f1
13 changed files with 93 additions and 60 deletions

View File

@ -42,7 +42,7 @@ DataSources.LobbyServer = {
SetModelValue(serverModel, "modName", serverInfo.modName) SetModelValue(serverModel, "modName", serverInfo.modName)
SetModelValue(serverModel, "mapName", serverInfo.map) SetModelValue(serverModel, "mapName", serverInfo.map)
SetModelValue(serverModel, "desc", serverInfo.desc) SetModelValue(serverModel, "desc", serverInfo.desc)
-- Changed the client count to be the actual player count -- Change the client count to be the actual player count
local clientCount = serverInfo.playerCount - serverInfo.botCount local clientCount = serverInfo.playerCount - serverInfo.botCount
SetModelValue(serverModel, "clientCount", clientCount) SetModelValue(serverModel, "clientCount", clientCount)
SetModelValue(serverModel, "maxClients", serverInfo.maxPlayers) SetModelValue(serverModel, "maxClients", serverInfo.maxPlayers)
@ -54,7 +54,7 @@ DataSources.LobbyServer = {
SetModelValue(serverModel, "ranked", serverInfo.ranked) SetModelValue(serverModel, "ranked", serverInfo.ranked)
SetModelValue(serverModel, "hardcore", serverInfo.hardcore) SetModelValue(serverModel, "hardcore", serverInfo.hardcore)
SetModelValue(serverModel, "zombies", serverInfo.zombies) SetModelValue(serverModel, "zombies", serverInfo.zombies)
-- Added the bot count -- Add the bot count
SetModelValue(serverModel, "botCount", serverInfo.botCount) SetModelValue(serverModel, "botCount", serverInfo.botCount)
return serverModel return serverModel
else else

2
deps/curl vendored

@ -1 +1 @@
Subproject commit d8df0d6db7441b6e14920a7e16a10e32bdc9c7ae Subproject commit 8e21b1a05f3c0ee098dbcb6c3d84cb61f102a122

View File

@ -85,6 +85,12 @@ namespace chat
a.cmp(dword_ptr(rax, 0x16AE0), 0x0); // game's code a.cmp(dword_ptr(rax, 0x16AE0), 0x0); // game's code
a.jmp(0x14029905B_g); a.jmp(0x14029905B_g);
} }
void cl_handle_chat(char* dest, size_t dest_size, const char* src)
{
game::I_strcpy(dest, dest_size, src);
printf("%s\n", dest);
}
} }
const char* get_client_name(const uint64_t xuid) const char* get_client_name(const uint64_t xuid)
@ -96,7 +102,7 @@ namespace chat
if (xuid < 19 && !game::is_server()) if (xuid < 19 && !game::is_server())
{ {
char buffer[256]; char buffer[256]{};
game::CL_GetClientName(0, static_cast<int>(xuid - 1), buffer, sizeof(buffer), true); game::CL_GetClientName(0, static_cast<int>(xuid - 1), buffer, sizeof(buffer), true);
return utils::string::va("%s\n", buffer); return utils::string::va("%s\n", buffer);
@ -167,6 +173,9 @@ namespace chat
{ {
// Ignore some check that suppresses the chat // Ignore some check that suppresses the chat
utils::hook::nop(0x141DEA9BD_g, 2); utils::hook::nop(0x141DEA9BD_g, 2);
// Add chat history to the in-game console
utils::hook::call(0x141DEAA0F_g, cl_handle_chat); // I_strcpy
} }
} }
}; };

View File

@ -116,8 +116,9 @@ namespace getinfo
info.set("sv_running", std::to_string(game::is_server_running())); info.set("sv_running", std::to_string(game::is_server_running()));
info.set("dedicated", game::is_server() ? "1" : "0"); info.set("dedicated", game::is_server() ? "1" : "0");
info.set("hc", std::to_string(game::Com_GametypeSettings_GetUInt("hardcoremode", false))); info.set("hc", std::to_string(game::Com_GametypeSettings_GetUInt("hardcoremode", false)));
info.set("modName", workshop::get_mod_resized_name(game::get_dvar_string("fs_game"))); info.set("modName", workshop::get_mod_resized_name());
info.set("modId", workshop::get_mod_publisher_id(game::get_dvar_string("fs_game"))); info.set("modId", workshop::get_mod_publisher_id());
info.set("rounds_played", std::to_string(*game::level_rounds_played));
info.set("shortversion", SHORTVERSION); info.set("shortversion", SHORTVERSION);
network::send(target, "infoResponse", info.build(), '\n'); network::send(target, "infoResponse", info.build(), '\n');

View File

@ -79,7 +79,6 @@ namespace script
{ {
if (data.size() >= sizeof(GSC_MAGIC) && !std::memcmp(data.data(), &GSC_MAGIC, sizeof(GSC_MAGIC))) if (data.size() >= sizeof(GSC_MAGIC) && !std::memcmp(data.data(), &GSC_MAGIC, sizeof(GSC_MAGIC)))
{ {
auto base_name = script_file.substr(0, script_file.size() - 4);
print_loading_script(script_file); print_loading_script(script_file);
load_script(script_file, data); load_script(script_file, data);
} }

View File

@ -16,7 +16,7 @@ namespace server_list
{ {
namespace namespace
{ {
utils::hook::detour lua_serverinfo_to_table_hook; utils::hook::detour lua_server_info_to_table_hook;
struct state struct state
{ {
@ -80,14 +80,14 @@ namespace server_list
callback(true, result); callback(true, result);
} }
void lua_serverinfo_to_table_stub(game::hks::lua_State* state, game::ServerInfo serverInfo, int index) void lua_server_info_to_table_stub(game::hks::lua_State* state, game::ServerInfo server_info, int index)
{ {
lua_serverinfo_to_table_hook.invoke(state, serverInfo, index); lua_server_info_to_table_hook.invoke(state, server_info, index);
if (state) if (state)
{ {
auto botCount = atoi(game::Info_ValueForKey(serverInfo.tags, "bots")); const auto bot_count = atoi(game::Info_ValueForKey(server_info.tags, "bots"));
game::Lua_SetTableInt("botCount", botCount, state); game::Lua_SetTableInt("botCount", bot_count, state);
} }
} }
@ -98,13 +98,14 @@ namespace server_list
void write_favorite_servers() void write_favorite_servers()
{ {
favorite_servers.access([&](std::unordered_set<game::netadr_t>& servers) favorite_servers.access([](const std::unordered_set<game::netadr_t>& servers)
{ {
std::string servers_buffer = ""; std::string servers_buffer{};
for (auto itr : servers) for (const auto& itr : servers)
{ {
servers_buffer.append(utils::string::va("%i.%i.%i.%i:%u\n", itr.ipv4.a, itr.ipv4.b, itr.ipv4.c, itr.ipv4.d, itr.port)); servers_buffer.append(utils::string::va("%i.%i.%i.%i:%hu\n", itr.ipv4.a, itr.ipv4.b, itr.ipv4.c, itr.ipv4.d, itr.port));
} }
utils::io::write_file(get_favorite_servers_file_path(), servers_buffer); utils::io::write_file(get_favorite_servers_file_path(), servers_buffer);
}); });
} }
@ -120,11 +121,12 @@ namespace server_list
favorite_servers.access([&path](std::unordered_set<game::netadr_t>& servers) favorite_servers.access([&path](std::unordered_set<game::netadr_t>& servers)
{ {
servers.clear(); servers.clear();
std::string filedata;
if (utils::io::read_file(path, &filedata)) std::string data;
if (utils::io::read_file(path, &data))
{ {
auto srv = utils::string::split(filedata, '\n'); const auto srv = utils::string::split(data, '\n');
for (auto server_address : srv) for (const auto& server_address : srv)
{ {
auto server = network::address_from_string(server_address); auto server = network::address_from_string(server_address);
servers.insert(server); servers.insert(server);
@ -222,7 +224,7 @@ namespace server_list
}); });
}, scheduler::async, 200ms); }, scheduler::async, 200ms);
lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub); lua_server_info_to_table_hook.create(0x141F1FD10_g, lua_server_info_to_table_stub);
scheduler::once([] scheduler::once([]
{ {

View File

@ -170,32 +170,34 @@ namespace workshop
} }
} }
std::string get_mod_resized_name(const std::string& dir_name) std::string get_mod_resized_name()
{ {
if (dir_name == "usermaps" || dir_name.empty()) const std::string loaded_mod_id = game::getPublisherIdFromLoadedMod();
if (loaded_mod_id == "usermaps" || loaded_mod_id.empty())
{ {
return dir_name; return loaded_mod_id;
} }
std::string result = dir_name; std::string mod_name = loaded_mod_id;
for (unsigned int i = 0; i < *game::modsCount; ++i) for (unsigned int i = 0; i < *game::modsCount; ++i)
{ {
const auto& mod_data = game::modsPool[i]; const auto& mod_data = game::modsPool[i];
if (utils::string::ends_with(mod_data.contentPathToZoneFiles, dir_name)) if (mod_data.publisherId == loaded_mod_id)
{ {
result = mod_data.title; mod_name = mod_data.title;
break; break;
} }
} }
if (result.size() > 31) if (mod_name.size() > 31)
{ {
result.resize(31); mod_name.resize(31);
} }
return result; return mod_name;
} }
std::string get_usermap_publisher_id(const std::string& zone_name) std::string get_usermap_publisher_id(const std::string& zone_name)
@ -218,29 +220,22 @@ namespace workshop
return {}; return {};
} }
std::string get_mod_publisher_id(const std::string& dir_name) std::string get_mod_publisher_id()
{ {
if (dir_name == "usermaps" || dir_name.empty()) const std::string loaded_mod_id = game::getPublisherIdFromLoadedMod();
if (loaded_mod_id == "usermaps" || loaded_mod_id.empty())
{ {
return dir_name; return loaded_mod_id;
} }
for (unsigned int i = 0; i < *game::modsCount; ++i) if (!utils::string::is_numeric(loaded_mod_id))
{ {
const auto& mod_data = game::modsPool[i]; printf("[ Workshop ] WARNING: The publisherId: %s, is not numerical you might have set your mod folder incorrectly!\n",
if (utils::string::ends_with(mod_data.contentPathToZoneFiles, dir_name)) loaded_mod_id.data());
{
if (!utils::string::is_numeric(mod_data.publisherId))
{
printf("[ Workshop ] WARNING: The publisherId is not numerical you might have set your mod folder incorrectly!\n%s\n",
mod_data.absolutePathZoneFiles);
} }
return mod_data.publisherId; return loaded_mod_id;
}
}
return {};
} }
bool check_valid_usermap_id(const std::string& mapname, const std::string& pub_id) bool check_valid_usermap_id(const std::string& mapname, const std::string& pub_id)
@ -274,6 +269,11 @@ namespace workshop
void setup_same_mod_as_host(const std::string& usermap, const std::string& mod) void setup_same_mod_as_host(const std::string& usermap, const std::string& mod)
{ {
if (game::getPublisherIdFromLoadedMod() == mod)
{
return;
}
if (!usermap.empty() || mod != "usermaps") if (!usermap.empty() || mod != "usermaps")
{ {
game::loadMod(0, mod.data(), true); game::loadMod(0, mod.data(), true);

View File

@ -3,8 +3,8 @@
namespace workshop namespace workshop
{ {
std::string get_usermap_publisher_id(const std::string& folder_name); std::string get_usermap_publisher_id(const std::string& folder_name);
std::string get_mod_publisher_id(const std::string& folder_name); std::string get_mod_publisher_id();
std::string get_mod_resized_name(const std::string& folder_name); std::string get_mod_resized_name();
bool check_valid_usermap_id(const std::string& mapname, const std::string& pub_id); bool check_valid_usermap_id(const std::string& mapname, const std::string& pub_id);
bool check_valid_mod_id(const std::string& pub_id); bool check_valid_mod_id(const std::string& pub_id);
void setup_same_mod_as_host(const std::string& usermap, const std::string& mod); void setup_same_mod_as_host(const std::string& usermap, const std::string& mod);

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#define PROTOCOL 6 #define PROTOCOL 7
#define SUB_PROTOCOL 1 #define SUB_PROTOCOL 1
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -114,6 +114,7 @@ namespace game
WEAK symbol<const char*(const char* name)> CopyString{0x1422AC220, 0x14056BD70}; WEAK symbol<const char*(const char* name)> CopyString{0x1422AC220, 0x14056BD70};
WEAK symbol<bool()> isModLoaded{0x1420D5020}; WEAK symbol<bool()> isModLoaded{0x1420D5020};
WEAK symbol<const char*()> getPublisherIdFromLoadedMod{0x1420D7680, 0x1404E3230};
WEAK symbol<void(int localClientNum, const char* mod, bool)> loadMod{0x1420D6930}; WEAK symbol<void(int localClientNum, const char* mod, bool)> loadMod{0x1420D6930};
WEAK symbol<void()> reloadUserContent{0x1420D66C0, 0x1404E25C0}; WEAK symbol<void()> reloadUserContent{0x1420D66C0, 0x1404E25C0};
@ -214,6 +215,9 @@ namespace game
// Utils // Utils
WEAK symbol<const char*(char* str)> I_CleanStr{0x1422E9050, 0x140580E80}; WEAK symbol<const char*(char* str)> I_CleanStr{0x1422E9050, 0x140580E80};
WEAK symbol<void(char* dest, size_t destsize, const char* src)> I_strcpy{
0x1422E9410, 0x1405811E0
};
// Variables // Variables
WEAK symbol<cmd_function_s> cmd_functions{0x15689DF58, 0x14946F860}; WEAK symbol<cmd_function_s> cmd_functions{0x15689DF58, 0x14946F860};
@ -222,6 +226,7 @@ namespace game
WEAK symbol<gentity_s> g_entities{0x0, 0x1471031B0}; WEAK symbol<gentity_s> g_entities{0x0, 0x1471031B0};
WEAK symbol<int> level_time{0x0, 0x1474FDC94}; WEAK symbol<int> level_time{0x0, 0x1474FDC94};
WEAK symbol<int> level_rounds_played{0x14A55BDEC, 0x1475097BC};
WEAK symbol<SOCKET> ip_socket{0x157E75818, 0x14A640988}; WEAK symbol<SOCKET> ip_socket{0x157E75818, 0x14A640988};

View File

@ -292,6 +292,11 @@ namespace
const auto is_server = utils::flags::has_flag("dedicated") || (!has_client && has_server); const auto is_server = utils::flags::has_flag("dedicated") || (!has_client && has_server);
if (!has_client && !has_server)
{
throw std::runtime_error("Can't find a valid BlackOps3.exe or BlackOps3_UnrankedDedicatedServer.exe. Make sure you put boiii.exe in your Black Ops 3 installation folder.");
}
if (!is_server) if (!is_server)
{ {
trigger_high_performance_gpu_switch(); trigger_high_performance_gpu_switch();

View File

@ -224,9 +224,7 @@ namespace utils::cryptography
{ {
this->free(); this->free();
if (ecc_import(cs(key.data()), ul(key.size()), if (ecc_import(cs(key.data()), ul(key.size()), &this->key_storage_) != CRYPT_OK)
&this->key_storage_) != CRYPT_OK
)
{ {
ZeroMemory(&this->key_storage_, sizeof(this->key_storage_)); ZeroMemory(&this->key_storage_, sizeof(this->key_storage_));
} }
@ -242,7 +240,7 @@ namespace utils::cryptography
return {cs(buffer), length}; return {cs(buffer), length};
} }
return ""; return {};
} }
std::string ecc::key::get_openssl() const std::string ecc::key::get_openssl() const
@ -255,7 +253,17 @@ namespace utils::cryptography
return {cs(buffer), length}; return {cs(buffer), length};
} }
return ""; return {};
}
void ecc::key::set_openssl(const std::string& key)
{
this->free();
if (ecc_import_openssl(cs(key.data()), ul(key.size()), &this->key_storage_) != CRYPT_OK)
{
ZeroMemory(&this->key_storage_, sizeof(this->key_storage_));
}
} }
void ecc::key::free() void ecc::key::free()
@ -305,12 +313,14 @@ namespace utils::cryptography
std::string ecc::sign_message(const key& key, const std::string& message) std::string ecc::sign_message(const key& key, const std::string& message)
{ {
if (!key.is_valid()) return ""; if (!key.is_valid()) return {};
uint8_t buffer[512]; uint8_t buffer[512];
unsigned long length = sizeof(buffer); unsigned long length = sizeof(buffer);
ecc_sign_hash(cs(message.data()), ul(message.size()), buffer, &length, prng_.get_state(), prng_.get_id(), const auto hash = sha512::compute(message);
ecc_sign_hash(cs(hash.data()), ul(hash.size()), buffer, &length, prng_.get_state(), prng_.get_id(),
&key.get()); &key.get());
return std::string(cs(buffer), length); return std::string(cs(buffer), length);
@ -320,11 +330,13 @@ namespace utils::cryptography
{ {
if (!key.is_valid()) return false; if (!key.is_valid()) return false;
const auto hash = sha512::compute(message);
auto result = 0; auto result = 0;
return (ecc_verify_hash(cs(signature.data()), return (ecc_verify_hash(cs(signature.data()),
ul(signature.size()), ul(signature.size()),
cs(message.data()), cs(hash.data()),
ul(message.size()), &result, ul(hash.size()), &result,
&key.get()) == CRYPT_OK && result != 0); &key.get()) == CRYPT_OK && result != 0);
} }
@ -396,7 +408,6 @@ namespace utils::cryptography
rsa_free(&new_key); rsa_free(&new_key);
}); });
std::string out_data{}; std::string out_data{};
out_data.resize(std::max(ul(data.size() * 3), ul(0x100))); out_data.resize(std::max(ul(data.size() * 3), ul(0x100)));

View File

@ -32,6 +32,7 @@ namespace utils::cryptography
std::string serialize(int type = PK_PRIVATE) const; std::string serialize(int type = PK_PRIVATE) const;
std::string get_openssl() const; std::string get_openssl() const;
void set_openssl(const std::string& key);
void free(); void free();