small stuff
This commit is contained in:
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
180
src/client/component/map_rotation.cpp
Normal file
180
src/client/component/map_rotation.cpp
Normal 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)
|
@ -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)
|
Reference in New Issue
Block a user