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
{
2022-03-01 13:31:30 -05:00
launch_map ( " mp_crash " ) ;
2022-02-17 00:11:35 -05:00
}
}
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 , 1 s ) ;
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 , 1 s ) ;
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 , 1 s ) ;
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
{
2022-03-12 18:56:15 -05:00
dvars : : register_string ( " sv_mapRotation " , " " , game : : DVAR_FLAG_NONE , " " ) ;
dvars : : register_string ( " sv_mapRotationCurrent " , " " , game : : DVAR_FLAG_NONE , " " ) ;
dvars : : register_string ( " sv_autoPriority " , " " , game : : DVAR_FLAG_NONE , " Lowers the process priority during map changes to not cause lags on other servers. " ) ;
2022-02-23 15:23:00 -05:00
} , 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 )