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 ; }
2017-05-28 16:47:21 -04:00
List < AsyncStatus > TaskStatuses ;
2017-05-27 18:08:04 -04:00
Database ClientDatabase ;
SharedLibrary . Interfaces . IPenaltyList ClientPenalties ;
2017-05-26 18:49:27 -04:00
List < Command > Commands ;
Kayak . IScheduler webServiceTask ;
Thread WebThread ;
2017-05-27 19:29:20 -04:00
public SharedLibrary . Interfaces . ILogger Logger { get ; private set ; }
2017-05-26 18:49:27 -04:00
public bool Running { get ; private set ; }
#if FTP_LOG
2017-05-28 16:47:21 -04:00
const int UPDATE_FREQUENCY = 15000 ;
2017-05-26 18:49:27 -04:00
#else
2017-05-28 16:47:21 -04:00
const int UPDATE_FREQUENCY = 300 ;
2017-05-26 18:49:27 -04:00
#endif
private Manager ( )
2015-07-03 00:10:01 -04:00
{
2017-05-27 19:29:20 -04:00
//IFile logFile = new IFile("Logs/IW4MAdminManager.log", true);
Logger = new Logger ( "Logs/IW4MAdmin.log" ) ;
//Logger = new Log(logFile, Log.Level.Production, 0);
2017-05-26 18:49:27 -04:00
Servers = new List < Server > ( ) ;
Commands = new List < Command > ( ) ;
2017-05-28 16:47:21 -04:00
TaskStatuses = new List < AsyncStatus > ( ) ;
2017-05-27 18:08:04 -04:00
ClientDatabase = new ClientsDB ( "Database/clients.rm" ) ;
ClientPenalties = new PenaltyList ( ) ;
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-27 19:29:20 -04:00
return Instance ? ? ( Instance = new Manager ( ) ) ;
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-27 18:08:04 -04:00
SharedLibrary . WebService . Init ( ) ;
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 ) ;
2017-05-28 16:47:21 -04:00
// this way we can keep track of execution time and see if problems arise.
2017-05-28 21:07:33 -04:00
var Status = new AsyncStatus ( ServerInstance , UPDATE_FREQUENCY ) ;
2017-05-28 16:47:21 -04:00
TaskStatuses . Add ( Status ) ;
2017-05-27 19:29:20 -04:00
Logger . WriteVerbose ( $"Now monitoring {ServerInstance.Hostname}" ) ;
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 )
{
2017-05-27 19:29:20 -04:00
Logger . WriteWarning ( $"Not monitoring server {Conf.IP}:{Conf.Port} due to uncorrectable errors" ) ;
2017-05-26 18:49:27 -04:00
if ( e . GetType ( ) = = typeof ( SharedLibrary . Exceptions . DvarException ) )
2017-05-27 19:29:20 -04:00
Logger . WriteError ( $"Could not get the dvar value for {(e as SharedLibrary.Exceptions.DvarException).Data[" dvar_name "]} (ensure the server has a map loaded)" ) ;
2017-05-26 18:49:27 -04:00
else if ( e . GetType ( ) = = typeof ( SharedLibrary . Exceptions . NetworkException ) )
2017-05-27 19:29:20 -04:00
Logger . WriteError ( "Could not communicate with the server (ensure the configuration is correct)" ) ;
2017-05-26 18:49:27 -04:00
}
} ) ;
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
webServiceTask = WebService . getScheduler ( ) ;
2015-07-03 00:10:01 -04:00
2017-05-28 16:47:21 -04:00
WebThread = new Thread ( webServiceTask . Start )
{
Name = "Web Thread"
} ;
2017-05-26 18:49:27 -04:00
WebThread . Start ( ) ;
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-28 16:47:21 -04:00
while ( Running )
2015-07-03 00:10:01 -04:00
{
2017-05-28 16:47:21 -04:00
foreach ( var Status in TaskStatuses )
2015-07-03 00:10:01 -04:00
{
2017-05-28 16:47:21 -04:00
if ( Status . RequestedTask = = null | | Status . RequestedTask . IsCompleted )
{
Status . Update ( new Task ( ( ) = > ( Status . Dependant as Server ) . ProcessUpdatesAsync ( Status . GetToken ( ) ) ) ) ;
if ( Status . RunAverage > 500 )
2017-05-28 21:07:33 -04:00
Logger . WriteWarning ( $"Update task average execution is longer than desired for {(Status.Dependant as Server).getIP()}::{(Status.Dependant as Server).getPort()} [{Status.RunAverage}ms]" ) ;
2017-05-28 16:47:21 -04:00
}
2015-07-03 00:10:01 -04:00
}
2017-05-28 16:47:21 -04:00
Thread . Sleep ( UPDATE_FREQUENCY ) ;
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
}
2017-05-27 18:08:04 -04:00
public ClientsDB GetClientDatabase ( )
{
return ClientDatabase as ClientsDB ;
}
public SharedLibrary . Interfaces . IPenaltyList GetClientPenalties ( )
{
return ClientPenalties ;
}
2017-05-27 19:29:20 -04:00
public SharedLibrary . Interfaces . ILogger GetLogger ( )
{
return Logger ;
}
2015-07-03 00:10:01 -04:00
}
}