small stuff

This commit is contained in:
Skull Merlin 2022-02-17 07:11:35 +02:00
parent 0b953a2906
commit 8e425ffe03
9 changed files with 263 additions and 83 deletions

2
deps/rapidjson vendored

@ -1 +1 @@
Subproject commit e4bde977440d4a00f820b6586899e48a972d2493
Subproject commit fd3dc29a5c2852df569e1ea81dbde2c412ac5051

View File

@ -10,6 +10,7 @@
#include <utils/string.hpp>
#include <utils/memory.hpp>
#include "utils/io.hpp"
#include <game/dvars.hpp>
namespace command
{
@ -296,38 +297,6 @@ namespace command
console::info("Total %i matches\n", matches.size());
});*/
add("dvarDump", [](const params& argument)
{
console::info("================================ DVAR DUMP ========================================\n");
std::string filename;
if (argument.size() == 2)
{
filename = "h1-mod/";
filename.append(argument[1]);
if (!filename.ends_with(".txt"))
{
filename.append(".txt");
}
}
for (auto i = 0; i < *game::dvarCount; i++)
{
const auto dvar = game::sortedDvars[i];
if (dvar)
{
if (!filename.empty())
{
const auto line = std::format("{} \"{}\"\r\n", dvar->hash,
game::Dvar_ValueToString(dvar, dvar->current));
utils::io::write_file(filename, line, i != 0);
}
console::info("%s \"%s\"\n", dvar->hash,
game::Dvar_ValueToString(dvar, dvar->current));
}
}
console::info("\n%i dvars\n", *game::dvarCount);
console::info("================================ END DVAR DUMP ====================================\n");
});
add("commandDump", [](const params& argument)
{
console::info("================================ COMMAND DUMP =====================================\n");
@ -360,6 +329,7 @@ namespace command
console::info("\n%i commands\n", i);
console::info("================================ END COMMAND DUMP =================================\n");
});
/*
add("listassetpool", [](const params& params)
{
@ -502,7 +472,7 @@ namespace command
: "^1off"));
});
/*add("give", [](const params& params)
add("give", [](const params& params)
{
if (!game::SV_Loaded())
{
@ -546,7 +516,7 @@ namespace command
{
game::G_TakePlayerWeapon(ps, wp);
}
});*/
});
}
static void add_commands_mp()

View File

@ -336,6 +336,8 @@ namespace game_console
}
}
void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output)
{
const auto _x = (x + width) - 10.0f;

View File

@ -2,19 +2,9 @@
namespace game_console
{
enum console_type
{
con_type_error = 1,
con_type_warning = 3,
con_type_info = 7
};
//void print(int type, const char* fmt, ...);
bool console_char_event(int local_client_num, int key);
bool console_key_event(int local_client_num, int key, int down);
bool match_compare(const std::string& input, const std::string& text, const bool exact);
void find_matches(std::string input, std::vector<std::string>& suggestions, const bool exact);
void execute(const char* cmd);
}

View File

@ -3,6 +3,7 @@
#include "localized_strings.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include <utils/concurrency.hpp>
#include "game/game.hpp"
namespace localized_strings
@ -11,37 +12,30 @@ namespace localized_strings
{
utils::hook::detour seh_string_ed_get_string_hook;
std::unordered_map<std::string, std::string>& get_localized_overrides()
{
static std::unordered_map<std::string, std::string> overrides;
return overrides;
}
std::mutex& get_synchronization_mutex()
{
static std::mutex mutex;
return mutex;
}
using localized_map = std::unordered_map<std::string, std::string>;
utils::concurrency::container<localized_map> localized_overrides;
const char* seh_string_ed_get_string(const char* reference)
{
std::lock_guard<std::mutex> _(get_synchronization_mutex());
return localized_overrides.access<const char*>([&](const localized_map& map)
{
const auto entry = map.find(reference);
if (entry != map.end())
{
return utils::string::va("%s", entry->second.data());
}
auto& overrides = get_localized_overrides();
const auto entry = overrides.find(reference);
if (entry != overrides.end())
{
return utils::string::va("%s", entry->second.data());
}
return seh_string_ed_get_string_hook.invoke<const char*>(reference);
return seh_string_ed_get_string_hook.invoke<const char*>(reference);
});
}
}
void override(const std::string& key, const std::string& value)
{
std::lock_guard<std::mutex> _(get_synchronization_mutex());
get_localized_overrides()[key] = value;
localized_overrides.access([&](localized_map& map)
{
map[key] = value;
});
}
class component final : public component_interface
@ -50,7 +44,7 @@ namespace localized_strings
void post_unpack() override
{
// Change some localized strings
seh_string_ed_get_string_hook.create(SELECT_VALUE(0x1403924A0, 0x1404BB2A0), &seh_string_ed_get_string); // H1(1.4)
seh_string_ed_get_string_hook.create(SELECT_VALUE(0x1403924A0, 0x1404BB2A0), &seh_string_ed_get_string);
}
};
}

View File

@ -0,0 +1,180 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "command.hpp"
#include "scheduler.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include "game/game.hpp"
#include <game/dvars.hpp>
namespace map_rotation
{
DWORD previousPriority;
namespace
{
void set_dvar(const std::string& dvar, const std::string& value)
{
command::execute(utils::string::va("%s \"%s\"", dvar.data(), value.data()), true);
}
void set_gametype(const std::string& gametype)
{
set_dvar("g_gametype", gametype);
}
void launch_map(const std::string& mapname)
{
command::execute(utils::string::va("map %s", mapname.data()), false);
}
void launch_default_map()
{
auto* mapname = game::Dvar_FindVar("mapname");
if (mapname && mapname->current.string && strlen(mapname->current.string) && mapname->current.string !=
"mp_vlobby_room"s)
{
launch_map(mapname->current.string);
}
else
{
launch_map("mp_crash_snow");
}
}
std::string load_current_map_rotation()
{
auto* rotation = game::Dvar_FindVar("sv_mapRotationCurrent");
if (!strlen(rotation->current.string))
{
rotation = game::Dvar_FindVar("sv_mapRotation");
set_dvar("sv_mapRotationCurrent", rotation->current.string);
}
return rotation->current.string;
}
std::vector<std::string> parse_current_map_rotation()
{
const auto rotation = load_current_map_rotation();
return utils::string::split(rotation, ' ');
}
void store_new_rotation(const std::vector<std::string>& elements, const size_t index)
{
std::string value{};
for (auto i = index; i < elements.size(); ++i)
{
if (i != index)
{
value.push_back(' ');
}
value.append(elements[i]);
}
set_dvar("sv_mapRotationCurrent", value);
}
void change_process_priority()
{
auto* const dvar = game::Dvar_FindVar("sv_autoPriority");
if (dvar && dvar->current.enabled)
{
scheduler::on_game_initialized([]()
{
//printf("=======================setting OLD priority=======================\n");
SetPriorityClass(GetCurrentProcess(), previousPriority);
}, scheduler::pipeline::main, 1s);
previousPriority = GetPriorityClass(GetCurrentProcess());
//printf("=======================setting NEW priority=======================\n");
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
}
}
void perform_map_rotation()
{
if (game::Live_SyncOnlineDataFlags(0) != 0)
{
scheduler::on_game_initialized(perform_map_rotation, scheduler::pipeline::main, 1s);
return;
}
const auto rotation = parse_current_map_rotation();
for (size_t i = 0; !rotation.empty() && i < (rotation.size() - 1); i += 2)
{
const auto& key = rotation[i];
const auto& value = rotation[i + 1];
if (key == "gametype")
{
set_gametype(value);
}
else if (key == "map")
{
store_new_rotation(rotation, i + 2);
change_process_priority();
if (!game::SV_MapExists(value.data()))
{
printf("map_rotation: '%s' map doesn't exist!\n", value.data());
launch_default_map();
return;
}
launch_map(value);
return;
}
else
{
printf("Invalid map rotation key: %s\n", key.data());
}
}
launch_default_map();
}
void trigger_map_rotation()
{
scheduler::schedule([]()
{
if (game::CL_IsCgameInitialized())
{
return scheduler::cond_continue;
}
command::execute("map_rotate", false);
return scheduler::cond_end;
}, scheduler::pipeline::main, 1s);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
if (!game::environment::is_dedi())
{
return;
}
scheduler::once([]()
{
dvars::register_string("sv_mapRotation", "", game::DVAR_FLAG_NONE, true);
dvars::register_string("sv_mapRotationCurrent", "", game::DVAR_FLAG_NONE, true);
dvars::register_string("sv_autoPriority", "", game::DVAR_FLAG_NONE, true);
}, scheduler::pipeline::main);
command::add("map_rotate", &perform_map_rotation);
// Hook GScr_ExitLevel
utils::hook::jump(0x140376630, &trigger_map_rotation); // not sure if working
previousPriority = GetPriorityClass(GetCurrentProcess());
}
};
}
REGISTER_COMPONENT(map_rotation::component)

View File

@ -7,6 +7,7 @@
#include <utils/hook.hpp>
#include <utils/concurrency.hpp>
#include <utils/string.hpp>
#include <utils/thread.hpp>
namespace scheduler
{
@ -146,25 +147,55 @@ namespace scheduler
}, type, delay);
}
void on_game_initialized(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
{
schedule([=]()
{
const auto dw_init = game::environment::is_sp() ? true : game::Live_SyncOnlineDataFlags(0) == 0;
if (dw_init && game::Sys_IsDatabaseReady2())
{
once(callback, type, delay);
return cond_end;
}
return cond_continue;
}, pipeline::main);
}
class component final : public component_interface
{
public:
void post_start() override
{
thread = utils::thread::create_named_thread("Async Scheduler", []()
{
while (!kill)
{
execute(pipeline::async);
std::this_thread::sleep_for(10ms);
}
});
}
void post_unpack() override
{
//thread = std::thread([]()
//{
// while (!kill)
// {
// execute(pipeline::async);
// std::this_thread::sleep_for(10ms);
// }
//});
r_end_frame_hook.create(SELECT_VALUE(0x1404F7310, 0x1405FE470), scheduler::r_end_frame_stub); // H1(1.4)
g_run_frame_hook.create(SELECT_VALUE(0x1402772D0, 0x1402772D0), scheduler::server_frame_stub); // H1(1.4)
main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1401CE8D0), scheduler::main_frame_stub); // H1(1.4)
}
void pre_destroy() override
{
kill = true;
if (thread.joinable())
{
thread.join();
}
}
};
}
REGISTER_COMPONENT(scheduler::component)
REGISTER_COMPONENT(scheduler::component)

View File

@ -2,6 +2,7 @@
#include <utils/string.hpp>
#include "game.hpp"
#include <component/console.hpp>
namespace dvars
{
@ -217,6 +218,7 @@ namespace dvars
"fs_userDocuments",
"fs_usermapdir",
"g_gametype",
"gametype",
"g_hardcore",
"g_listEntity",
"g_loadScripts",
@ -325,10 +327,10 @@ namespace dvars
"sv_lastSaveCommitedToDevice",
"sv_local_client_snapshot_msec",
"sv_mapname",
"mapname",
"mapname",
"sv_mapRotation",
"sv_mapRotationCurrent",
"cl_maxpackets",
"cl_maxpackets",
"sv_maxclients",
"sv_maxPhysExplosionSpheres",
"sv_maxPing",
@ -382,6 +384,10 @@ namespace dvars
"sv_wwwDownload",
"sv_zlib_threshold",
"sv_zombietime",
"sv_mapRotation",
"sv_mapRotationCurrent",
"sv_autoPriority",
//"xpartygo",
"svwp",
"syncTimeTimeout",
"sys_configSum",
@ -490,7 +496,8 @@ namespace dvars
"custom_scr_team_teamkillspawndelay",
"custom_scr_vehicles_enabled",
"name",
"custom_timelimit"
"custom_timelimit",
"map"
};
bool can_add_dvar_to_list(std::string name)

View File

@ -15,6 +15,8 @@ namespace game
WEAK symbol<void()> Com_Frame_Try_Block_Function{ 0, 0x1400D8310 }; //H1MP MWR TEST
WEAK symbol<CodPlayMode()> Com_GetCurrentCoDPlayMode{ 0, 0x1405039A0 }; // H1(1.4)
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{ 0, 0x140165580 };
WEAK symbol<void()> Com_Quit_f{ 0x140352BE0, 0x1400DA830 }; // H1(1.4)
@ -93,6 +95,7 @@ namespace game
WEAK symbol<int(int clientNum)> G_GetClientScore{ 0, 0x140342F90 }; // H1(1.4)
WEAK symbol<const char* (int clientNum)> SV_GetGuid{ 0, 0x140484B90 }; // H1(1.4)
WEAK symbol<int(int clientNum)> SV_GetClientPing{ 0, 0x140484B70 }; // H1(1.4)
WEAK symbol<playerState_s* (int num)> SV_GetPlayerstateForClientNum{ 0x1404426D0, 0 }; // H1SP(1.4)
WEAK symbol<void* (const char* text, int maxChars, void* font, int fontHeight, float x, float y, float xScale, float yScale,
float rotation, float* color, int style, int cursor_pos, char cursor_char, void* style_unk)> H1_AddBaseDrawTextCmd{ 0x1404F3DC0,0x1405FB1F0 }; // H1(1.4)
@ -134,7 +137,7 @@ namespace game
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{ 0, 0x1405C1C50 };
WEAK symbol<void(VariableValue* result, unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{ 0, 0x1405C6100 };
WEAK symbol<unsigned int(const char* name)> G_GetWeaponForName{ 0, 0x14051B260 };
WEAK symbol<unsigned int(const char* name)> G_GetWeaponForName{ 0x1402C2A90, 0 }; // H1SP(1.4)
//WEAK symbol<int(void* ps, unsigned int weapon, int a3, int a4, __int64 a5, int a6)>
//G_GivePlayerWeapon{ 0, 0x14051B660 };
@ -144,6 +147,7 @@ namespace game
WEAK symbol<void(void* ps, const unsigned int weapon, int hadWeapon)> G_InitializeAmmo{ 0, 0x1404C4110 };
WEAK symbol<void(int clientNum, const unsigned int weapon)> G_SelectWeapon{ 0,0x14051C0D0 };
WEAK symbol<int(playerState_s* ps, unsigned int weapon)> G_TakePlayerWeapon{ 0x1402C3900, 0 }; // H1SP(1.4)
WEAK symbol<char* (GfxImage* image, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipCount,
uint32_t imageFlags, DXGI_FORMAT imageFormat, int a8, const char* name, const void* initData)> Image_Setup{ 0, 0x14074B2A0 };
@ -167,7 +171,9 @@ namespace game
WEAK symbol<const char* (scr_string_t stringValue)> SL_ConvertToString{ 0x14036D420, 0x1405BFBB0 };
WEAK symbol<scr_string_t(const char* str, unsigned int user)> SL_GetString{ 0x14036D9A0, 0x1405C0170 };
WEAK symbol<bool()> SV_Loaded{ 0x140442F60, 0x140442F60 };
WEAK symbol<bool()> SV_Loaded{ 0x140442F60, 0x1404864A0 }; // H1(1.4)
WEAK symbol<bool(const char* map)> SV_MapExists{ 0, 0x14047ED60 }; // H1(1.4)
WEAK symbol<void()> Sys_ShowConsole{ 0x1403E3B90, 0x140514910 }; // H1(1.4)