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 e683f79710
25 changed files with 481 additions and 96 deletions

3
.gitmodules vendored
View File

@ -45,3 +45,6 @@
path = deps/zlib
url = https://github.com/madler/zlib.git
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
require("shaderdialog")
require("gamemodes")
end
-- 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 = {
Standard = {
Label = Engine.Localize("@MPUI_STANDARD_CAPS"),

View File

@ -7,6 +7,8 @@ end
game:addlocalizedstring("MENU_NUMPLAYERS", "Players")
game:addlocalizedstring("MENU_PING", "Ping")
game:addlocalizedstring("SERVERLIST_PLAYER_COUNT", "&&1 Players")
game:addlocalizedstring("SERVERLIST_SERVER_COUNT", "&&1 Servers")
local columns = {
{
@ -195,8 +197,33 @@ function menu_systemlink_join(f19_arg0, f19_arg1)
SystemLinkJoinMenu.UpdateCounterText(menu, nil)
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)
SystemLinkJoinMenu.UpdateCounterText(menu, event)
playercount:setText(Engine.Localize("@SERVERLIST_PLAYER_COUNT", serverlist:getplayercount()))
servercount:setText(Engine.Localize("@SERVERLIST_SERVER_COUNT", serverlist:getservercount()))
end)
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 input = "X-Labs-H1Mod-Auth";
std::string input = "H1Mod-Auth";
DATA_BLOB data_in{}, data_out{};
data_in.pbData = reinterpret_cast<uint8_t*>(input.data());

View File

@ -138,21 +138,37 @@ namespace discord
{
const auto data = utils::http::get_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;
void download_default_avatar()
{
const auto data = utils::http::get_data(DEFAULT_AVATAR_URL);
if (data.has_value())
if (!data.has_value())
{
has_default_avatar = true;
materials::add(DEFAULT_AVATAR, data.value());
return;
}
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 "console.hpp"
#include "scheduler.hpp"
#include <utils/hook.hpp>
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
{
public:
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)
{
if (params.size() <= 1)

View File

@ -123,9 +123,10 @@ namespace patches
const auto menu_id = atoi(params.get(1));
const auto client = &svs_clients[ent->s.entityNum];
// 22 => "end_game"
if (menu_id == 22 && client->header.remoteAddress.type != game::NA_LOOPBACK)
// 32 => "end_game"
if (menu_id == 32 && client->header.remoteAddress.type != game::NA_LOOPBACK)
{
game::SV_DropClient_Internal(client, "PLATFORM_STEAM_KICK_CHEAT", true);
return;
}
@ -194,15 +195,74 @@ namespace patches
char buffer[2048];
va_list ap;
va_start(ap, fmt);
{
va_list ap;
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);
}
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
@ -242,13 +302,10 @@ namespace patches
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
utils::hook::set<const char*>(SELECT_VALUE(0x7E3DF0_b, 0x937B80_b),
"Create2DTexture( %s, %i, %i, %i, %i ) failed\n\n"
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.");
utils::hook::set<const char*>(SELECT_VALUE(0x800EA8_b, 0x954FF0_b),
"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."
utils::hook::call(SELECT_VALUE(0x55E919_b, 0x681A69_b), create_2d_texture_stub_1); // Sys_Error for "Create2DTexture( %s, %i, %i, %i, %i ) failed"
utils::hook::call(SELECT_VALUE(0x55EACB_b, 0x681C1B_b), create_2d_texture_stub_2); // Com_Error for ^
utils::hook::call(SELECT_VALUE(0x5B35BA_b, 0x6CB1BC_b), swap_chain_stub); // Com_Error for "IDXGISwapChain::Present failed: %s"
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."
// "fix" for rare 'Out of memory error' error
// 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));
}
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
{
public:

View File

@ -9,4 +9,7 @@ namespace server_list
void handle_info_response(const game::netadr_s& address, const utils::info_string& info);
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 "scripting.hpp"
#include "updater.hpp"
#include "server_list.hpp"
#include "game/ui_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);
};
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();
lua["updater"] = updater_table;

View File

@ -26,9 +26,9 @@
#define DATA_PATH "data/"
#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_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 BINARY_NAME "h1-mod.exe"
@ -139,7 +139,7 @@ namespace updater
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());
}
@ -191,6 +191,12 @@ namespace updater
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
@ -337,12 +343,20 @@ namespace updater
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;
}
rapidjson::Document j;
j.Parse(files_data.value().data());
j.Parse(value.buffer.data());
if (!j.IsArray())
{
@ -433,11 +447,19 @@ namespace updater
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;
}
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)

View File

@ -1500,12 +1500,12 @@ namespace scripting
{"_meth_82e8", 0x82E8}, // SP 0x000000 MP 0x411730
{"_meth_82e9", 0x82E9}, // SP 0x000000 MP 0x411720
{"_meth_82ea", 0x82EA}, // SP 0x2905B0 MP 0x40BAD0
{"_meth_82eb", 0x82EB}, // SP 0x28F5E0 MP 0x40AB90
{"_meth_82ec", 0x82EC}, // SP 0x28F6D0 MP 0x40ACC0
{"fragbuttonpressed", 0x82EB}, // SP 0x28F5E0 MP 0x40AB90
{"secondaryoffhandbuttonpressed", 0x82EC}, // SP 0x28F6D0 MP 0x40ACC0
{"issighted", 0x82ED}, // SP 0x2919D0 MP 0x40D2E0
{"setvelocity", 0x82EE}, // SP 0x28DC30 MP 0x4090E0
{"_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
{"stoplocalsound", 0x82F2}, // SP 0x28DBA0 MP 0x409420
{"setweaponammoclip", 0x82F3}, // SP 0x2928A0 MP 0x405D60
@ -1603,7 +1603,7 @@ namespace scripting
{"botsetstance", 0x8350}, // SP 0x000000 MP 0x5473D0
{"botsetscriptmove", 0x8351}, // SP 0x000000 MP 0x547250
{"_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
{"getnearestnode", 0x8355}, // SP 0x000000 MP 0x546DE0
{"botclearscriptenemy", 0x8356}, // SP 0x000000 MP 0x544EE0
@ -1616,7 +1616,7 @@ namespace scripting
{"_meth_835e", 0x835E}, // SP 0x000000 MP 0x5460F0
{"botfindnoderandom", 0x835F}, // SP 0x000000 MP 0x544FE0
{"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
{"botgetpersonality", 0x8364}, // SP 0x000000 MP 0x545700
{"_meth_8365", 0x8365}, // SP 0x000000 MP 0x5474A0
@ -2890,10 +2890,10 @@ namespace scripting
{"origin", 0x2DF},
{"other", 0x2E0},
{"over", 0x2E1},
{"owner", 0x2E2},
{"_not_owner", 0x2E2}, // was "owner"
{"pacifist", 0x2E3},
{"pacifistwait", 0x2E4},
{"pain", 0x2E5},
{"owner", 0x2E5}, // was "pain"
{"pantssize", 0x2E6},
{"parentindex", 0x2E7},
{"parentname", 0x2E8},
@ -2925,10 +2925,10 @@ namespace scripting
{"perkrestricted", 0x302},
{"perks", 0x303},
{"perkslots", 0x304},
{"pers", 0x305},
{"_not_pers", 0x305}, // was "pers"
{"persistentperksunlocked", 0x306},
{"persistentweaponsunlocked", 0x307},
{"phone_off", 0x308},
{"pers", 0x308}, // was "phone_off"
{"phone_on", 0x309},
{"physics_finished", 0x30A},
{"physics_impact", 0x30B},
@ -3312,10 +3312,10 @@ namespace scripting
{"tag_sight_off", 0x485},
{"tag_sight_on", 0x486},
{"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_sync", 0x48A},
{"tag_tip", 0x48B},
{"tag_stowed_back", 0x48B}, // was "tag_tip"
{"tag_turret", 0x48C},
{"tag_turret_base", 0x48D},
{"tag_turret_pitch", 0x48E},
@ -3340,10 +3340,10 @@ namespace scripting
{"target", 0x4A1},
{"target_script_trigger", 0x4A2},
{"targetname", 0x4A3},
{"team", 0x4A4},
{"_not_team", 0x4A4}, // was "team"
{"team3", 0x4A5},
{"teambalanced", 0x4A6},
{"teammode_axisallies", 0x4A7},
{"team", 0x4A7}, // was "teammode_axisallies"
{"teammode_ffa", 0x4A8},
{"teammovewaittime", 0x4A9},
{"their_score", 0x4AA},
@ -3370,10 +3370,10 @@ namespace scripting
{"traversecost", 0x4BF},
{"traversesoonnotifydist", 0x4C0},
{"trend", 0x4C1},
{"trigger", 0x4C2},
{"_not_trigger", 0x4C2}, // was "trigger"
{"trigger_damage", 0x4C3},
{"trigger_use", 0x4C4},
{"trigger_use_touch", 0x4C5},
{"trigger", 0x4C5}, // was "trigger_use_touch"
{"truck_cam", 0x4C6},
{"turnrate", 0x4C7},
{"turret_deactivate", 0x4C8},
@ -3492,5 +3492,97 @@ namespace scripting
{"codescripts/struct", 0x53E},
{"codescripts/message", 0x53F},
{"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(int localClientNum)> SV_FastRestart{0x0, 0x54BE00};
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(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, 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, int what, int data)> hksi_lua_gc{0, 0x236EF0};
WEAK symbol<const char*> typenames{0x98CD20, 0x10AD750};
}
}

View File

@ -181,16 +181,6 @@ void limit_parallel_dll_loading()
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()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
@ -217,8 +207,6 @@ int main()
try
{
//apply_proper_directory();
if (!component_loader::post_start()) return 0;
auto mode = detect_mode_from_arguments();

View File

@ -74,7 +74,7 @@ BEGIN
VALUE "FileDescription", "H1-Mod"
VALUE "FileVersion", VERSION_FILE
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 "Info", "https://h1.gg"
VALUE "OriginalFilename", "h1-mod.exe"

View File

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

View File

@ -3,9 +3,18 @@
#include <string>
#include <optional>
#include <future>
#include <gsl/gsl>
#include <curl/curl.h>
namespace utils::http
{
std::optional<std::string> get_data(const std::string& url);
std::future<std::optional<std::string>> get_data_async(const std::string& url);
struct result
{
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->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;
success = instance->initialize(&error);

View File

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

View File

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