2022-02-17 00:11:35 -05:00
|
|
|
#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([]()
|
2022-02-27 01:36:54 -05:00
|
|
|
{
|
|
|
|
//printf("=======================setting OLD priority=======================\n");
|
|
|
|
SetPriorityClass(GetCurrentProcess(), previousPriority);
|
|
|
|
}, scheduler::pipeline::main, 1s);
|
2022-02-17 00:11:35 -05:00
|
|
|
|
|
|
|
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([]()
|
2022-02-23 15:23:00 -05:00
|
|
|
{
|
|
|
|
if (game::CL_IsCgameInitialized())
|
2022-02-17 00:11:35 -05:00
|
|
|
{
|
2022-02-23 15:23:00 -05:00
|
|
|
return scheduler::cond_continue;
|
|
|
|
}
|
2022-02-17 00:11:35 -05:00
|
|
|
|
2022-02-23 15:23:00 -05:00
|
|
|
command::execute("map_rotate", false);
|
|
|
|
return scheduler::cond_end;
|
|
|
|
}, scheduler::pipeline::main, 1s);
|
2022-02-17 00:11:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class component final : public component_interface
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void post_unpack() override
|
|
|
|
{
|
|
|
|
if (!game::environment::is_dedi())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
scheduler::once([]()
|
2022-02-23 15:23:00 -05:00
|
|
|
{
|
|
|
|
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);
|
2022-02-17 00:11:35 -05:00
|
|
|
|
|
|
|
command::add("map_rotate", &perform_map_rotation);
|
|
|
|
|
|
|
|
// Hook GScr_ExitLevel
|
|
|
|
utils::hook::jump(0x140376630, &trigger_map_rotation); // not sure if working
|
|
|
|
|
|
|
|
previousPriority = GetPriorityClass(GetCurrentProcess());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-02-23 15:23:00 -05:00
|
|
|
REGISTER_COMPONENT(map_rotation::component)
|