2015-07-03 00:10:01 -04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Diagnostics ;
using System.Runtime.InteropServices ;
using System.Net ;
using System.Threading ;
2015-08-20 01:06:44 -04:00
using SharedLibrary ;
2017-05-26 18:49:27 -04:00
using System.IO ;
using SharedLibrary.Network ;
using System.Threading.Tasks ;
2015-07-03 00:10:01 -04:00
namespace IW4MAdmin
{
2017-05-26 18:49:27 -04:00
class Manager : SharedLibrary . Interfaces . IManager
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
static Manager Instance ;
public List < Server > Servers { get ; private set ; }
List < Command > Commands ;
Kayak . IScheduler webServiceTask ;
Thread WebThread ;
public bool Running { get ; private set ; }
#if FTP_LOG
const double UPDATE_FREQUENCY = 15000 ;
#else
const double UPDATE_FREQUENCY = 300 ;
#endif
public Log Logger ;
private Manager ( )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
IFile logFile = new IFile ( "Logs/IW4MAdminManager.log" , true ) ;
Logger = new Log ( logFile , Log . Level . Production , 0 ) ;
Servers = new List < Server > ( ) ;
Commands = new List < Command > ( ) ;
2015-07-03 00:10:01 -04:00
}
2017-05-26 18:49:27 -04:00
public List < Server > GetServers ( )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
return Servers ;
2015-07-03 00:10:01 -04:00
}
2017-05-26 18:49:27 -04:00
public List < Command > GetCommands ( )
2015-08-17 16:38:42 -04:00
{
2017-05-26 18:49:27 -04:00
return Commands ;
2015-08-17 16:38:42 -04:00
}
2017-05-26 18:49:27 -04:00
public static Manager GetInstance ( )
2015-08-22 02:04:30 -04:00
{
2017-05-26 18:49:27 -04:00
return Instance = = null ? Instance = new Manager ( ) : Instance ;
2015-08-22 02:04:30 -04:00
}
2017-05-26 18:49:27 -04:00
public void Init ( )
2015-07-06 13:13:42 -04:00
{
2017-05-26 18:49:27 -04:00
var Configs = Directory . EnumerateFiles ( "config/servers" ) . Where ( x = > x . Contains ( ".cfg" ) ) ;
2015-07-06 13:13:42 -04:00
2017-05-26 18:49:27 -04:00
if ( Configs . Count ( ) = = 0 )
Config . Generate ( ) ;
2015-08-17 16:38:42 -04:00
2017-05-26 18:49:27 -04:00
PluginImporter . Load ( ) ;
2015-08-17 16:38:42 -04:00
2017-05-26 18:49:27 -04:00
foreach ( var file in Configs )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
var Conf = Config . Read ( file ) ;
var ServerInstance = new IW4MServer ( this , Conf . IP , Conf . Port , Conf . Password ) ;
2015-08-17 16:38:42 -04:00
2017-05-26 18:49:27 -04:00
Task . Run ( async ( ) = >
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
try
2015-07-06 13:13:42 -04:00
{
2017-05-26 18:49:27 -04:00
await ServerInstance . Initialize ( ) ;
Servers . Add ( ServerInstance ) ;
Logger . Write ( $"Now monitoring {ServerInstance.Hostname}" , Log . Level . Production ) ;
2015-07-06 13:13:42 -04:00
}
2015-08-28 00:39:36 -04:00
2017-05-26 18:49:27 -04:00
catch ( SharedLibrary . Exceptions . ServerException e )
{
Logger . Write ( $"Not monitoring server {Conf.IP}:{Conf.Port} due to uncorrectable errors" , Log . Level . Production ) ;
if ( e . GetType ( ) = = typeof ( SharedLibrary . Exceptions . DvarException ) )
Logger . Write ( $"Could not get the dvar value for {(e as SharedLibrary.Exceptions.DvarException).Data[" dvar_name "]} (ensure the server has a map loaded)" , Log . Level . Production ) ;
else if ( e . GetType ( ) = = typeof ( SharedLibrary . Exceptions . NetworkException ) )
Logger . Write ( "Could not communicate with the server (ensure the configuration is correct)" , Log . Level . Production ) ;
}
} ) ;
2015-07-06 13:13:42 -04:00
2015-07-03 00:10:01 -04:00
}
2015-07-06 13:13:42 -04:00
2017-05-26 18:49:27 -04:00
SharedLibrary . WebService . Init ( ) ;
webServiceTask = WebService . getScheduler ( ) ;
2015-07-03 00:10:01 -04:00
2017-05-26 18:49:27 -04:00
WebThread = new Thread ( webServiceTask . Start ) ;
WebThread . Name = "Web Thread" ;
WebThread . Start ( ) ;
2015-07-03 00:10:01 -04:00
2017-05-26 18:49:27 -04:00
while ( Servers . Count < 1 )
Thread . Sleep ( 500 ) ;
2015-07-03 00:10:01 -04:00
2017-05-26 18:49:27 -04:00
Running = true ;
2015-07-03 00:10:01 -04:00
}
2017-05-26 18:49:27 -04:00
2015-07-03 00:10:01 -04:00
2017-05-26 18:49:27 -04:00
public void Start ( )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
int Processed ;
DateTime Start ;
2015-07-03 00:10:01 -04:00
2017-05-26 18:49:27 -04:00
while ( Running )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
Processed = 0 ;
Start = DateTime . Now ;
foreach ( Server S in Servers )
Processed + = S . ProcessUpdatesAsync ( ) . Result ;
// ideally we don't want to sleep on the thread, but polling
// as much as possible will use unnecessary CPU
int ElapsedTime = ( int ) ( DateTime . Now - Start ) . TotalMilliseconds ;
while ( ( Processed ! = Servers . Count | | ElapsedTime < UPDATE_FREQUENCY ) & & Running )
2015-07-03 00:10:01 -04:00
{
2017-05-26 18:49:27 -04:00
Thread . Sleep ( ( int ) ( UPDATE_FREQUENCY - ElapsedTime ) ) ;
ElapsedTime = ( int ) ( DateTime . Now - Start ) . TotalMilliseconds ;
2015-07-03 00:10:01 -04:00
}
}
2017-05-26 18:49:27 -04:00
#if ! DEBUG
foreach ( var S in Servers )
S . Broadcast ( "^1IW4MAdmin going offline!" ) ;
#endif
Servers . Clear ( ) ;
WebThread . Abort ( ) ;
webServiceTask . Stop ( ) ;
2015-07-03 00:10:01 -04:00
}
2015-07-06 15:51:08 -04:00
2017-05-26 18:49:27 -04:00
public void Stop ( )
2015-07-06 15:51:08 -04:00
{
2017-05-26 18:49:27 -04:00
Running = false ;
2015-07-06 15:51:08 -04:00
}
2015-07-03 00:10:01 -04:00
}
}