Merge pull request #119 from h1-mod/develop

v1.0.3
This commit is contained in:
fed 2022-06-27 20:00:19 +00:00 committed by GitHub
commit 4a44785941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 481 additions and 96 deletions

3
.gitmodules vendored
View File

@ -45,3 +45,6 @@
path = deps/zlib path = deps/zlib
url = https://github.com/madler/zlib.git url = https://github.com/madler/zlib.git
branch = develop branch = develop
[submodule "deps/curl"]
path = deps/curl
url = https://github.com/curl/curl.git

View File

@ -4,6 +4,7 @@ end
if (Engine.InFrontend()) then if (Engine.InFrontend()) then
require("shaderdialog") require("shaderdialog")
require("gamemodes")
end end
-- defined in mp_hud/hudutils.lua -- defined in mp_hud/hudutils.lua

View File

@ -1,7 +1,3 @@
if (game:issingleplayer() or not Engine.InFrontend()) then
return
end
Cac.GameModes.Data = { Cac.GameModes.Data = {
Standard = { Standard = {
Label = Engine.Localize("@MPUI_STANDARD_CAPS"), Label = Engine.Localize("@MPUI_STANDARD_CAPS"),

View File

@ -7,6 +7,8 @@ end
game:addlocalizedstring("MENU_NUMPLAYERS", "Players") game:addlocalizedstring("MENU_NUMPLAYERS", "Players")
game:addlocalizedstring("MENU_PING", "Ping") game:addlocalizedstring("MENU_PING", "Ping")
game:addlocalizedstring("SERVERLIST_PLAYER_COUNT", "&&1 Players")
game:addlocalizedstring("SERVERLIST_SERVER_COUNT", "&&1 Servers")
local columns = { local columns = {
{ {
@ -195,8 +197,33 @@ function menu_systemlink_join(f19_arg0, f19_arg1)
SystemLinkJoinMenu.UpdateCounterText(menu, nil) SystemLinkJoinMenu.UpdateCounterText(menu, nil)
Lobby.BuildServerList(Engine.GetFirstActiveController()) Lobby.BuildServerList(Engine.GetFirstActiveController())
local playercount = LUI.UIText.new({
rightAnchor = true,
topAnchor = true,
height = 18,
bottom = 58,
font = CoD.TextSettings.BodyFont.Font,
width = 300,
alignment = LUI.Alignment.Right,
})
menu:addElement(playercount)
local servercount = LUI.UIText.new({
rightAnchor = true,
topAnchor = true,
height = 18,
bottom = 58 - 25,
font = CoD.TextSettings.BodyFont.Font,
width = 300,
alignment = LUI.Alignment.Right,
})
menu:addElement(servercount)
menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event)
SystemLinkJoinMenu.UpdateCounterText(menu, event) SystemLinkJoinMenu.UpdateCounterText(menu, event)
playercount:setText(Engine.Localize("@SERVERLIST_PLAYER_COUNT", serverlist:getplayercount()))
servercount:setText(Engine.Localize("@SERVERLIST_SERVER_COUNT", serverlist:getservercount()))
end) end)
SystemLinkJoinMenu.UpdateGameList(menu) SystemLinkJoinMenu.UpdateGameList(menu)

2
deps/asmjit vendored

@ -1 +1 @@
Subproject commit 06d0badec53710a4f572cf5642881ce570c5d274 Subproject commit 35f92e8706db78c6aa7482b5e1cdb59c5972a965

1
deps/curl vendored Submodule

@ -0,0 +1 @@
Subproject commit e2e7f54b7bea521fa8373095d0f43261a720cda0

73
deps/premake/curl.lua vendored Normal file
View File

@ -0,0 +1,73 @@
curl = {
source = path.join(dependencies.basePath, "curl"),
}
function curl.import()
links { "curl" }
filter "toolset:msc*"
links { "Crypt32.lib" }
filter {}
curl.includes()
end
function curl.includes()
filter "toolset:msc*"
includedirs {
path.join(curl.source, "include"),
}
defines {
"CURL_STRICTER",
"CURL_STATICLIB",
"CURL_DISABLE_LDAP",
}
filter {}
end
function curl.project()
if not os.istarget("windows") then
return
end
project "curl"
language "C"
curl.includes()
includedirs {
path.join(curl.source, "lib"),
}
files {
path.join(curl.source, "lib/**.c"),
path.join(curl.source, "lib/**.h"),
}
defines {
"BUILDING_LIBCURL",
}
filter "toolset:msc*"
defines {
"USE_SCHANNEL",
"USE_WINDOWS_SSPI",
"USE_THREADS_WIN32",
}
filter "toolset:not msc*"
defines {
"USE_GNUTLS",
"USE_THREADS_POSIX",
}
filter {}
warnings "Off"
kind "StaticLib"
end
table.insert(dependencies, curl)

2
deps/sol2 vendored

@ -1 +1 @@
Subproject commit c9055478c7c437f9a97610329701652673ab8262 Subproject commit dca62a0f02bb45f3de296de3ce00b1275eb34c25

View File

@ -42,7 +42,7 @@ namespace auth
std::string get_protected_data() std::string get_protected_data()
{ {
std::string input = "X-Labs-H1Mod-Auth"; std::string input = "H1Mod-Auth";
DATA_BLOB data_in{}, data_out{}; DATA_BLOB data_in{}, data_out{};
data_in.pbData = reinterpret_cast<uint8_t*>(input.data()); data_in.pbData = reinterpret_cast<uint8_t*>(input.data());

View File

@ -138,21 +138,37 @@ namespace discord
{ {
const auto data = utils::http::get_data( const auto data = utils::http::get_data(
utils::string::va(AVATAR_URL, id.data(), avatar.data())); utils::string::va(AVATAR_URL, id.data(), avatar.data()));
if (data.has_value()) if (!data.has_value())
{ {
materials::add(utils::string::va(AVATAR, id.data()), data.value()); return;
} }
const auto& value = data.value();
if (value.code != CURLE_OK)
{
return;
}
materials::add(utils::string::va(AVATAR, id.data()), value.buffer);
} }
bool has_default_avatar = false; bool has_default_avatar = false;
void download_default_avatar() void download_default_avatar()
{ {
const auto data = utils::http::get_data(DEFAULT_AVATAR_URL); const auto data = utils::http::get_data(DEFAULT_AVATAR_URL);
if (data.has_value()) if (!data.has_value())
{ {
has_default_avatar = true; return;
materials::add(DEFAULT_AVATAR, data.value());
} }
const auto& value = data.value();
if (value.code != CURLE_OK)
{
return;
}
has_default_avatar = true;
materials::add(DEFAULT_AVATAR, value.buffer);
} }
} }

View File

@ -5,16 +5,67 @@
#include "command.hpp" #include "command.hpp"
#include "console.hpp" #include "console.hpp"
#include "scheduler.hpp"
#include <utils/hook.hpp> #include <utils/hook.hpp>
namespace lui namespace lui
{ {
namespace
{
uint64_t event_count{};
bool begin_game_message_event_stub(int a1, const char* name, void* a3)
{
if (event_count > 30)
{
return false;
}
else
{
event_count++;
}
return utils::hook::invoke<bool>(0x2655A0_b, a1, name, a3);
}
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:
void post_unpack() override void post_unpack() override
{ {
if (game::environment::is_mp())
{
// Patch game message overflow
utils::hook::call(0x266E6B_b, begin_game_message_event_stub);
scheduler::loop([]()
{
if (event_count > 0)
{
event_count--;
}
}, scheduler::pipeline::lui, 50ms);
}
// Increase max extra LUI memory
/*const auto max_memory = 0x900000 * 2;
utils::hook::set<uint32_t>(0x278E61_b - 4, max_memory);
utils::hook::set<uint32_t>(0x27A2C5_b - 4, max_memory);
utils::hook::set<uint32_t>(0x27A993_b - 4, max_memory);
utils::hook::set<uint32_t>(0x27AB3A_b - 4, max_memory);
utils::hook::set<uint32_t>(0x27AB35_b - 4, max_memory);
utils::hook::set<uint32_t>(0x27C002_b - 4, max_memory);*/
// Increase max extra frontend memory
/*const auto max_frontend_memory = 0x180000 * 2;
utils::hook::set<uint32_t>(0x278EA6_b - 4, max_frontend_memory);
utils::hook::set<uint32_t>(0x278F01_b - 4, max_frontend_memory);
utils::hook::set<uint32_t>(0x27A2D4_b - 4, max_frontend_memory);
utils::hook::set<uint32_t>(0x27A2E3_b - 4, max_frontend_memory);
utils::hook::set<uint32_t>(0x27F9E9_b - 4, max_frontend_memory);
utils::hook::set<uint32_t>(0x27FA84_b - 4, max_frontend_memory);*/
command::add("lui_open", [](const command::params& params) command::add("lui_open", [](const command::params& params)
{ {
if (params.size() <= 1) if (params.size() <= 1)

View File

@ -123,9 +123,10 @@ namespace patches
const auto menu_id = atoi(params.get(1)); const auto menu_id = atoi(params.get(1));
const auto client = &svs_clients[ent->s.entityNum]; const auto client = &svs_clients[ent->s.entityNum];
// 22 => "end_game" // 32 => "end_game"
if (menu_id == 22 && client->header.remoteAddress.type != game::NA_LOOPBACK) if (menu_id == 32 && client->header.remoteAddress.type != game::NA_LOOPBACK)
{ {
game::SV_DropClient_Internal(client, "PLATFORM_STEAM_KICK_CHEAT", true);
return; return;
} }
@ -194,15 +195,74 @@ namespace patches
char buffer[2048]; char buffer[2048];
{
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap); vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap);
va_end(ap); va_end(ap);
}
return utils::hook::invoke<int>(SELECT_VALUE(0x429200_b, 0x5AF0F0_b), dest, size, "%s", buffer); return utils::hook::invoke<int>(SELECT_VALUE(0x429200_b, 0x5AF0F0_b), dest, size, "%s", buffer);
} }
void create_2d_texture_stub_1(const char* fmt, ...)
{
fmt = "Create2DTexture( %s, %i, %i, %i, %i ) failed\n\n"
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.";
char buffer[2048];
{
va_list ap;
va_start(ap, fmt);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap);
va_end(ap);
}
game::Sys_Error("%s", buffer);
}
void create_2d_texture_stub_2(game::errorParm code, const char* fmt, ...)
{
fmt = "Create2DTexture( %s, %i, %i, %i, %i ) failed\n\n"
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.";
char buffer[2048];
{
va_list ap;
va_start(ap, fmt);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap);
va_end(ap);
}
game::Com_Error(code, "%s", buffer);
}
void swap_chain_stub(game::errorParm code, const char* fmt, ...)
{
fmt = "IDXGISwapChain::Present failed: %s\n\n"
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.";
char buffer[2048];
{
va_list ap;
va_start(ap, fmt);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap);
va_end(ap);
}
game::Com_Error(code, "%s", buffer);
}
} }
class component final : public component_interface class component final : public component_interface
@ -242,13 +302,10 @@ namespace patches
utils::hook::call(SELECT_VALUE(0x376EB5_b, 0x156D41_b), db_read_raw_file_stub); utils::hook::call(SELECT_VALUE(0x376EB5_b, 0x156D41_b), db_read_raw_file_stub);
// Remove useless information from errors + add additional help to common errors // Remove useless information from errors + add additional help to common errors
utils::hook::set<const char*>(SELECT_VALUE(0x7E3DF0_b, 0x937B80_b), utils::hook::call(SELECT_VALUE(0x55E919_b, 0x681A69_b), create_2d_texture_stub_1); // Sys_Error for "Create2DTexture( %s, %i, %i, %i, %i ) failed"
"Create2DTexture( %s, %i, %i, %i, %i ) failed\n\n" utils::hook::call(SELECT_VALUE(0x55EACB_b, 0x681C1B_b), create_2d_texture_stub_2); // Com_Error for ^
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers."); utils::hook::call(SELECT_VALUE(0x5B35BA_b, 0x6CB1BC_b), swap_chain_stub); // Com_Error for "IDXGISwapChain::Present failed: %s"
utils::hook::set<const char*>(SELECT_VALUE(0x800EA8_b, 0x954FF0_b), utils::hook::call(SELECT_VALUE(0x457BC9_b, 0x1D8E09_b), out_of_memory_text_stub); // Com_sprintf for "Out of memory. You are probably low on disk space."
"IDXGISwapChain::Present failed: %s\n\n"
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.");
utils::hook::call(SELECT_VALUE(0x457BC9_b, 0x1D8E09_b), out_of_memory_text_stub); // "Out of memory. You are probably low on disk space."
// "fix" for rare 'Out of memory error' error // "fix" for rare 'Out of memory error' error
// this will *at least* generate the configs for mp/sp, which is the #1 issue // this will *at least* generate the configs for mp/sp, which is the #1 issue

View File

@ -375,6 +375,23 @@ namespace server_list
insert_server(std::move(server)); insert_server(std::move(server));
} }
int get_player_count()
{
std::lock_guard<std::mutex> _(mutex);
auto count = 0;
for (const auto& server : servers)
{
count += server.clients - server.bots;
}
return count;
}
int get_server_count()
{
std::lock_guard<std::mutex> _(mutex);
return static_cast<int>(servers.size());
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:

View File

@ -9,4 +9,7 @@ namespace server_list
void handle_info_response(const game::netadr_s& address, const utils::info_string& info); void handle_info_response(const game::netadr_s& address, const utils::info_string& info);
bool sl_key_event(int key, int down); bool sl_key_event(int key, int down);
int get_player_count();
int get_server_count();
} }

View File

@ -17,6 +17,7 @@
#include "fastfiles.hpp" #include "fastfiles.hpp"
#include "scripting.hpp" #include "scripting.hpp"
#include "updater.hpp" #include "updater.hpp"
#include "server_list.hpp"
#include "game/ui_scripting/execution.hpp" #include "game/ui_scripting/execution.hpp"
#include "game/scripting/execution.hpp" #include "game/scripting/execution.hpp"
@ -342,6 +343,12 @@ namespace ui_scripting
::game::Dvar_SetFromStringByNameFromSource("virtualLobbyPresentable", "1", ::game::DvarSetSource::DVAR_SOURCE_INTERNAL); ::game::Dvar_SetFromStringByNameFromSource("virtualLobbyPresentable", "1", ::game::DvarSetSource::DVAR_SOURCE_INTERNAL);
}; };
auto server_list_table = table();
lua["serverlist"] = server_list_table;
server_list_table["getplayercount"] = server_list::get_player_count;
server_list_table["getservercount"] = server_list::get_server_count;
auto updater_table = table(); auto updater_table = table();
lua["updater"] = updater_table; lua["updater"] = updater_table;

View File

@ -26,9 +26,9 @@
#define DATA_PATH "data/" #define DATA_PATH "data/"
#define DATA_PATH_DEV "data-dev/" #define DATA_PATH_DEV "data-dev/"
#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" #define ERR_UPDATE_CHECK_FAIL "Failed to check for updates:\n%s"
#define ERR_UPDATE_CHECK_FAIL_BAD_RESPONSE "Bad response" #define ERR_UPDATE_CHECK_FAIL_BAD_RESPONSE "Bad response"
#define ERR_DOWNLOAD_FAIL "Failed to download file " #define ERR_DOWNLOAD_FAIL "Failed to download file %s:\n%s"
#define ERR_WRITE_FAIL "Failed to write file " #define ERR_WRITE_FAIL "Failed to write file "
#define BINARY_NAME "h1-mod.exe" #define BINARY_NAME "h1-mod.exe"
@ -139,7 +139,7 @@ namespace updater
return utils::string::va("%i", uint32_t(time(nullptr))); return utils::string::va("%i", uint32_t(time(nullptr)));
} }
std::optional<std::string> download_file(const std::string& name) std::optional<utils::http::result> download_file(const std::string& name)
{ {
return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str());
} }
@ -191,6 +191,12 @@ namespace updater
return {}; return {};
} }
std::string curl_error(CURLcode code)
{
const auto str_error = curl_easy_strerror(code);
return utils::string::va("%s (%i)", str_error, code);
}
} }
// workaround // workaround
@ -337,12 +343,20 @@ namespace updater
if (!files_data.has_value()) if (!files_data.has_value())
{ {
set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); set_update_check_status(true, false, utils::string::va(ERR_UPDATE_CHECK_FAIL, "Unknown error"));
return;
}
const auto& value = files_data.value();
if (value.code != CURLE_OK)
{
const auto error = curl_error(value.code);
set_update_check_status(true, false, utils::string::va(ERR_UPDATE_CHECK_FAIL, error.data()));
return; return;
} }
rapidjson::Document j; rapidjson::Document j;
j.Parse(files_data.value().data()); j.Parse(value.buffer.data());
if (!j.IsArray()) if (!j.IsArray())
{ {
@ -433,11 +447,19 @@ namespace updater
if (!data.has_value()) if (!data.has_value())
{ {
set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); set_update_download_status(true, false, utils::string::va(ERR_DOWNLOAD_FAIL, file.data(), "Unknown error"));
return; return;
} }
downloads.push_back({file, data.value()}); const auto& value = data.value();
if (value.code != CURLE_OK)
{
const auto error = curl_error(value.code);
set_update_download_status(true, false, utils::string::va(ERR_DOWNLOAD_FAIL, file.data(), error.data()));
return;
}
downloads.push_back({file, value.buffer});
} }
for (const auto& download : downloads) for (const auto& download : downloads)

View File

@ -1500,12 +1500,12 @@ namespace scripting
{"_meth_82e8", 0x82E8}, // SP 0x000000 MP 0x411730 {"_meth_82e8", 0x82E8}, // SP 0x000000 MP 0x411730
{"_meth_82e9", 0x82E9}, // SP 0x000000 MP 0x411720 {"_meth_82e9", 0x82E9}, // SP 0x000000 MP 0x411720
{"_meth_82ea", 0x82EA}, // SP 0x2905B0 MP 0x40BAD0 {"_meth_82ea", 0x82EA}, // SP 0x2905B0 MP 0x40BAD0
{"_meth_82eb", 0x82EB}, // SP 0x28F5E0 MP 0x40AB90 {"fragbuttonpressed", 0x82EB}, // SP 0x28F5E0 MP 0x40AB90
{"_meth_82ec", 0x82EC}, // SP 0x28F6D0 MP 0x40ACC0 {"secondaryoffhandbuttonpressed", 0x82EC}, // SP 0x28F6D0 MP 0x40ACC0
{"issighted", 0x82ED}, // SP 0x2919D0 MP 0x40D2E0 {"issighted", 0x82ED}, // SP 0x2919D0 MP 0x40D2E0
{"setvelocity", 0x82EE}, // SP 0x28DC30 MP 0x4090E0 {"setvelocity", 0x82EE}, // SP 0x28DC30 MP 0x4090E0
{"_meth_82ef", 0x82EF}, // SP 0x28E570 MP 0x409920 {"_meth_82ef", 0x82EF}, // SP 0x28E570 MP 0x409920
{"_meth_82f0", 0x82F0}, // SP 0x28E980 MP 0x409B70 {"getnormalizedmovement", 0x82F0}, // SP 0x28E980 MP 0x409B70
{"playlocalsound", 0x82F1}, // SP 0x28DAC0 MP 0x409330 {"playlocalsound", 0x82F1}, // SP 0x28DAC0 MP 0x409330
{"stoplocalsound", 0x82F2}, // SP 0x28DBA0 MP 0x409420 {"stoplocalsound", 0x82F2}, // SP 0x28DBA0 MP 0x409420
{"setweaponammoclip", 0x82F3}, // SP 0x2928A0 MP 0x405D60 {"setweaponammoclip", 0x82F3}, // SP 0x2928A0 MP 0x405D60
@ -1603,7 +1603,7 @@ namespace scripting
{"botsetstance", 0x8350}, // SP 0x000000 MP 0x5473D0 {"botsetstance", 0x8350}, // SP 0x000000 MP 0x5473D0
{"botsetscriptmove", 0x8351}, // SP 0x000000 MP 0x547250 {"botsetscriptmove", 0x8351}, // SP 0x000000 MP 0x547250
{"_meth_8352", 0x8352}, // SP 0x000000 MP 0x546EA0 {"_meth_8352", 0x8352}, // SP 0x000000 MP 0x546EA0
{"_meth_8353", 0x8353}, // SP 0x000000 MP 0x547090 {"botsetscriptgoal", 0x8353}, // SP 0x000000 MP 0x547090
{"botclearscriptgoal", 0x8354}, // SP 0x000000 MP 0x544F60 {"botclearscriptgoal", 0x8354}, // SP 0x000000 MP 0x544F60
{"getnearestnode", 0x8355}, // SP 0x000000 MP 0x546DE0 {"getnearestnode", 0x8355}, // SP 0x000000 MP 0x546DE0
{"botclearscriptenemy", 0x8356}, // SP 0x000000 MP 0x544EE0 {"botclearscriptenemy", 0x8356}, // SP 0x000000 MP 0x544EE0
@ -1616,7 +1616,7 @@ namespace scripting
{"_meth_835e", 0x835E}, // SP 0x000000 MP 0x5460F0 {"_meth_835e", 0x835E}, // SP 0x000000 MP 0x5460F0
{"botfindnoderandom", 0x835F}, // SP 0x000000 MP 0x544FE0 {"botfindnoderandom", 0x835F}, // SP 0x000000 MP 0x544FE0
{"botmemoryevent", 0x8360}, // SP 0x000000 MP 0x545E50 {"botmemoryevent", 0x8360}, // SP 0x000000 MP 0x545E50
{"_meth_8362", 0x8362}, // SP 0x000000 MP 0x546190 {"botnodepick", 0x8362}, // SP 0x000000 MP 0x546190
{"bothasscriptgoal", 0x8363}, // SP 0x000000 MP 0x545B70 {"bothasscriptgoal", 0x8363}, // SP 0x000000 MP 0x545B70
{"botgetpersonality", 0x8364}, // SP 0x000000 MP 0x545700 {"botgetpersonality", 0x8364}, // SP 0x000000 MP 0x545700
{"_meth_8365", 0x8365}, // SP 0x000000 MP 0x5474A0 {"_meth_8365", 0x8365}, // SP 0x000000 MP 0x5474A0
@ -2890,10 +2890,10 @@ namespace scripting
{"origin", 0x2DF}, {"origin", 0x2DF},
{"other", 0x2E0}, {"other", 0x2E0},
{"over", 0x2E1}, {"over", 0x2E1},
{"owner", 0x2E2}, {"_not_owner", 0x2E2}, // was "owner"
{"pacifist", 0x2E3}, {"pacifist", 0x2E3},
{"pacifistwait", 0x2E4}, {"pacifistwait", 0x2E4},
{"pain", 0x2E5}, {"owner", 0x2E5}, // was "pain"
{"pantssize", 0x2E6}, {"pantssize", 0x2E6},
{"parentindex", 0x2E7}, {"parentindex", 0x2E7},
{"parentname", 0x2E8}, {"parentname", 0x2E8},
@ -2925,10 +2925,10 @@ namespace scripting
{"perkrestricted", 0x302}, {"perkrestricted", 0x302},
{"perks", 0x303}, {"perks", 0x303},
{"perkslots", 0x304}, {"perkslots", 0x304},
{"pers", 0x305}, {"_not_pers", 0x305}, // was "pers"
{"persistentperksunlocked", 0x306}, {"persistentperksunlocked", 0x306},
{"persistentweaponsunlocked", 0x307}, {"persistentweaponsunlocked", 0x307},
{"phone_off", 0x308}, {"pers", 0x308}, // was "phone_off"
{"phone_on", 0x309}, {"phone_on", 0x309},
{"physics_finished", 0x30A}, {"physics_finished", 0x30A},
{"physics_impact", 0x30B}, {"physics_impact", 0x30B},
@ -3312,10 +3312,10 @@ namespace scripting
{"tag_sight_off", 0x485}, {"tag_sight_off", 0x485},
{"tag_sight_on", 0x486}, {"tag_sight_on", 0x486},
{"tag_stow_back_mid_attach", 0x487}, {"tag_stow_back_mid_attach", 0x487},
{"tag_stowed_back", 0x488}, {"_not_tag_stowed_back", 0x488}, // was "tag_stowed_back"
{"tag_stowed_hip_rear", 0x489}, {"tag_stowed_hip_rear", 0x489},
{"tag_sync", 0x48A}, {"tag_sync", 0x48A},
{"tag_tip", 0x48B}, {"tag_stowed_back", 0x48B}, // was "tag_tip"
{"tag_turret", 0x48C}, {"tag_turret", 0x48C},
{"tag_turret_base", 0x48D}, {"tag_turret_base", 0x48D},
{"tag_turret_pitch", 0x48E}, {"tag_turret_pitch", 0x48E},
@ -3340,10 +3340,10 @@ namespace scripting
{"target", 0x4A1}, {"target", 0x4A1},
{"target_script_trigger", 0x4A2}, {"target_script_trigger", 0x4A2},
{"targetname", 0x4A3}, {"targetname", 0x4A3},
{"team", 0x4A4}, {"_not_team", 0x4A4}, // was "team"
{"team3", 0x4A5}, {"team3", 0x4A5},
{"teambalanced", 0x4A6}, {"teambalanced", 0x4A6},
{"teammode_axisallies", 0x4A7}, {"team", 0x4A7}, // was "teammode_axisallies"
{"teammode_ffa", 0x4A8}, {"teammode_ffa", 0x4A8},
{"teammovewaittime", 0x4A9}, {"teammovewaittime", 0x4A9},
{"their_score", 0x4AA}, {"their_score", 0x4AA},
@ -3370,10 +3370,10 @@ namespace scripting
{"traversecost", 0x4BF}, {"traversecost", 0x4BF},
{"traversesoonnotifydist", 0x4C0}, {"traversesoonnotifydist", 0x4C0},
{"trend", 0x4C1}, {"trend", 0x4C1},
{"trigger", 0x4C2}, {"_not_trigger", 0x4C2}, // was "trigger"
{"trigger_damage", 0x4C3}, {"trigger_damage", 0x4C3},
{"trigger_use", 0x4C4}, {"trigger_use", 0x4C4},
{"trigger_use_touch", 0x4C5}, {"trigger", 0x4C5}, // was "trigger_use_touch"
{"truck_cam", 0x4C6}, {"truck_cam", 0x4C6},
{"turnrate", 0x4C7}, {"turnrate", 0x4C7},
{"turret_deactivate", 0x4C8}, {"turret_deactivate", 0x4C8},
@ -3492,5 +3492,97 @@ namespace scripting
{"codescripts/struct", 0x53E}, {"codescripts/struct", 0x53E},
{"codescripts/message", 0x53F}, {"codescripts/message", 0x53F},
{"maps/mp/gametypes/_callbacksetup", 0x540}, {"maps/mp/gametypes/_callbacksetup", 0x540},
// additional findings from gametype/map scripts - mikey (6/26/2022)
{"common_scripts/_fx", 0xA4FB},
{"common_scripts/_pipes", 0xA4F9},
{"common_scripts/utility", 0xA4FA},
{"QuickMessageToAll", 0x70a2},
{"SetupCallbacks", 0x8301},
{"_effect", 0x58f},
{"_objective_delete", 0x603},
{"addSpawnPoints", 0x82f},
{"addStartSpawnPoints", 0x831},
{"addToCharactersArray", 0x848},
{"allowUse", 0xab2},
{"applyLoadout", 0xcae}, // has applyLoadout notify like IW6's giveLoadout does at the end + similar logic
{"characters", 0x1c8e},
{"checkDynamicSpawns", 0x1cfa},
{"clearOnVictimDisconnect", 0x1ef9},
{"conf_fx", 0x20e9},
{"console", 0x2153},
{"createUseObject", 0x244c},
{"curOrigin", 0x24c8},
{"deleteObjPoint", 0x2859},
{"dogtags", 0x2cdf},
{"finalKill", 0x373e},
{"findBoxCenter", 0x3779},
{"forfeitInProgress", 0x39df},
{"gamemodeModifyPlayerDamage", 0x3bf6},
{"getNextObjID", 0x4041},
{"getOtherTeam", 0x4067},
{"getSpawnPoint", 0x40d2},
{"getSpawnpoint_FreeForAll", 0x40d5},
{"getTeamSpawnPoints", 0x411f},
{"giveLoadout", 0x41e0}, // this may not even be giveLoadout but it's a wrapper for it and it does the same logic so
{"guid", 0x4450},
{"inGracePeriod", 0x4c6d},
{"initSpawns", 0x4e26},
{"initializeMatchRules", 0x4de0},
{"initializeTagPathVariables", 0x4de3},
{"mapCenter", 0x5986},
{"maps/mp/_compass", 0xa731},
{"maps/mp/_load", 0xa74c},
{"maps/mp/_utility", 0xa764},
{"maps/mp/gametypes/_class", 0xA78B},
{"maps/mp/gametypes/_damage", 0xA78D},
{"maps/mp/gametypes/_gameobjects", 0xA794},
{"maps/mp/gametypes/_globallogic", 0xA797},
{"maps/mp/gametypes/_menus", 0xa7a9},
{"maps/mp/gametypes/_objpoints", 0xa7ac},
{"maps/mp/gametypes/_spawnlogic", 0xa7b9},
{"maps/mp/gametypes/_spawnscoring", 0xa7ba},
{"matchRules_damageMultiplier", 0x59e6},
{"matchRules_vampirism", 0x59eb},
{"modifyPlayerDamage", 0x5d51},
{"objId", 0x6304},
{"onForfeit", 0x64af},
{"onNormalDeath", 0x64bf},
{"onPlayerScore", 0x64d5},
{"onStartGameType", 0x64ec},
{"onUse", 0x64f8},
{"participants", 0x669d},
{"reInitializeMatchRulesOnMigration", 0x7307},
{"registerHalfTimeDvar", 0x72ef},
{"registerNumLivesDvar", 0x72f4},
{"registerRoundLimitDvar", 0x72f6},
{"registerRoundSwitchDvar", 0x72f7},
{"registerScoreLimitDvar", 0x72f8},
{"registerTimeLimitDvar", 0x72f9},
{"registerWinLimitDvar", 0x72fe},
{"removeFromCharactersArray", 0x73a7},
{"setClass", 0x7f3b},
{"setCommonRulesFromMatchRulesData", 0x7f3f},
{"setObjectiveHintText", 0x7fc3},
{"setObjectiveScoreText", 0x7fc4},
{"setObjectiveText", 0x7fc5},
{"setUseTime", 0x834c},
{"setupMiniMap", 0x8324},
{"showToTeam", 0x8535},
{"spawnDogTags", 0x899e},
{"spawnMaxs", 0x89f3},
{"spawnMins", 0x89f6},
{"spawnPoints", 0x8a01},
{"splitscreen", 0x8a7c},
{"tag_stowed_hip", 0x90d3},
{"tagTeamUpdater", 0x910a},
{"teamBased", 0x91eb},
{"teamNameList", 0x91f7},
{"teamObjIds", 0x6305},
{"teamSpawnPoints", 0x9201},
{"v", 0x9c42},
{"visuals", 0x9e9c},
{"multiTeamBased", 0x5fec},
}; };
} }

View File

@ -197,6 +197,7 @@ namespace game
WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0x0, 0x0}; WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0x0, 0x0};
WEAK symbol<void(int localClientNum)> SV_FastRestart{0x0, 0x54BE00}; WEAK symbol<void(int localClientNum)> SV_FastRestart{0x0, 0x54BE00};
WEAK symbol<void(void* cl, int type, const char* fmt, ...)> SV_SendServerCommand{0x0, 0x1CC040}; WEAK symbol<void(void* cl, int type, const char* fmt, ...)> SV_SendServerCommand{0x0, 0x1CC040};
WEAK symbol<void(mp::client_t* drop, const char* reason, bool tellThem)> SV_DropClient_Internal{0x0, 0x54E7F0};
WEAK symbol<void()> Sys_ShowConsole{0x0, 0x0}; WEAK symbol<void()> Sys_ShowConsole{0x0, 0x0};
WEAK symbol<void(const char* error, ...)> Sys_Error{0x0, 0x1D8710}; WEAK symbol<void(const char* error, ...)> Sys_Error{0x0, 0x1D8710};
@ -295,6 +296,7 @@ namespace game
WEAK symbol<int(lua_State* s, const char* what, lua_Debug* ar)> hksi_lua_getinfo{0xB84D0, 0x22FFE0}; WEAK symbol<int(lua_State* s, const char* what, lua_Debug* ar)> hksi_lua_getinfo{0xB84D0, 0x22FFE0};
WEAK symbol<int(lua_State* s, int level, lua_Debug* ar)> hksi_lua_getstack{0xB87A0, 0x2302B0}; WEAK symbol<int(lua_State* s, int level, lua_Debug* ar)> hksi_lua_getstack{0xB87A0, 0x2302B0};
WEAK symbol<void(lua_State* s, const char* fmt, ...)> hksi_luaL_error{0xBF120, 0x22F930}; WEAK symbol<void(lua_State* s, const char* fmt, ...)> hksi_luaL_error{0xBF120, 0x22F930};
WEAK symbol<void(lua_State* s, int what, int data)> hksi_lua_gc{0, 0x236EF0};
WEAK symbol<const char*> typenames{0x98CD20, 0x10AD750}; WEAK symbol<const char*> typenames{0x98CD20, 0x10AD750};
} }
} }

View File

@ -181,16 +181,6 @@ void limit_parallel_dll_loading()
RegCloseKey(key); RegCloseKey(key);
} }
// solution for other processes that may launch the mod
void apply_proper_directory()
{
char module_path[MAX_PATH];
GetModuleFileNameA(nullptr, module_path, MAX_PATH);
PathRemoveFileSpecA(module_path);
SetCurrentDirectoryA(module_path);
SetDllDirectoryA(module_path);
}
int main() int main()
{ {
ShowWindow(GetConsoleWindow(), SW_HIDE); ShowWindow(GetConsoleWindow(), SW_HIDE);
@ -217,8 +207,6 @@ int main()
try try
{ {
//apply_proper_directory();
if (!component_loader::post_start()) return 0; if (!component_loader::post_start()) return 0;
auto mode = detect_mode_from_arguments(); auto mode = detect_mode_from_arguments();

View File

@ -74,7 +74,7 @@ BEGIN
VALUE "FileDescription", "H1-Mod" VALUE "FileDescription", "H1-Mod"
VALUE "FileVersion", VERSION_FILE VALUE "FileVersion", VERSION_FILE
VALUE "InternalName", "H1-Mod" VALUE "InternalName", "H1-Mod"
VALUE "LegalCopyright", "Copyright (C) 2021 H1-Mod. All rights reserved." VALUE "LegalCopyright", "Copyright © 2022 H1-Mod. All rights reserved."
VALUE "Licence", "GPLv3" VALUE "Licence", "GPLv3"
VALUE "Info", "https://h1.gg" VALUE "Info", "https://h1.gg"
VALUE "OriginalFilename", "h1-mod.exe" VALUE "OriginalFilename", "h1-mod.exe"

View File

@ -4,41 +4,61 @@
namespace utils::http namespace utils::http
{ {
std::optional<std::string> get_data(const std::string& url) namespace
{ {
CComPtr<IStream> stream; size_t write_callback(void* contents, const size_t size, const size_t nmemb, void* userp)
{
auto* buffer = static_cast<std::string*>(userp);
if (FAILED(URLOpenBlockingStreamA(nullptr, url.data(), &stream, 0, nullptr))) const auto total_size = size * nmemb;
buffer->append(static_cast<char*>(contents), total_size);
return total_size;
}
}
std::optional<result> get_data(const std::string& url)
{
curl_slist* header_list = nullptr;
auto* curl = curl_easy_init();
if (!curl)
{ {
return {}; return {};
} }
char buffer[0x1000]; auto _ = gsl::finally([&]()
std::string result;
HRESULT status{};
do
{ {
DWORD bytes_read = 0; curl_slist_free_all(header_list);
status = stream->Read(buffer, sizeof(buffer), &bytes_read); curl_easy_cleanup(curl);
});
if (bytes_read > 0) std::string buffer{};
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
curl_easy_setopt(curl, CURLOPT_URL, url.data());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
const auto code = curl_easy_perform(curl);
if (code == CURLE_OK)
{ {
result.append(buffer, bytes_read); result result;
} result.code = code;
} result.buffer = std::move(buffer);
while (SUCCEEDED(status) && status != S_FALSE);
if (FAILED(status)) return result;
}
else
{ {
return {}; result result;
result.code = code;
return result;
}
} }
return {result}; std::future<std::optional<result>> get_data_async(const std::string& url)
}
std::future<std::optional<std::string>> get_data_async(const std::string& url)
{ {
return std::async(std::launch::async, [url]() return std::async(std::launch::async, [url]()
{ {

View File

@ -3,9 +3,18 @@
#include <string> #include <string>
#include <optional> #include <optional>
#include <future> #include <future>
#include <gsl/gsl>
#include <curl/curl.h>
namespace utils::http namespace utils::http
{ {
std::optional<std::string> get_data(const std::string& url); struct result
std::future<std::optional<std::string>> get_data_async(const std::string& url); {
CURLcode code;
std::string buffer;
};
std::optional<result> get_data(const std::string& url);
std::future<std::optional<result>> get_data_async(const std::string& url);
} }

View File

@ -29,7 +29,7 @@ namespace utils
instance->setAppName(L"H1-Mod"); instance->setAppName(L"H1-Mod");
instance->setAppUserModelId( instance->setAppUserModelId(
WinToastLib::WinToast::configureAUMI(L"X Labs", L"H1-Mod", L"", L"20201212")); WinToastLib::WinToast::configureAUMI(L"H1-Mod", L"H1", L"", L"20201212"));
WinToastLib::WinToast::WinToastError error; WinToastLib::WinToast::WinToastError error;
success = instance->initialize(&error); success = instance->initialize(&error);

View File

@ -60,7 +60,7 @@ BEGIN
BEGIN BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", "X Labs" VALUE "CompanyName", "H1-Mod"
VALUE "FileDescription", "Steam mod runner" VALUE "FileDescription", "Steam mod runner"
VALUE "FileVersion", "1.0.0.0" VALUE "FileVersion", "1.0.0.0"
VALUE "InternalName", "Runner" VALUE "InternalName", "Runner"

View File

@ -60,7 +60,7 @@ BEGIN
BEGIN BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", "X Labs" VALUE "CompanyName", "H1-Mod"
VALUE "FileDescription", "TLS index allocation dll" VALUE "FileDescription", "TLS index allocation dll"
VALUE "FileVersion", "1.0.0.0" VALUE "FileVersion", "1.0.0.0"
VALUE "InternalName", "TLS DLL" VALUE "InternalName", "TLS DLL"