2010-03-17 07:25:19 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2011-12-14 08:40:48 +01:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-17 07:25:19 +01:00
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
# include "server_interface.h"
# include <stdexcept>
2013-12-17 08:54:33 +01:00
# include "window.h"
# include "logger.h"
2010-03-17 07:25:19 +01:00
# include "platform_util.h"
# include "conversion.h"
# include "config.h"
# include "lang.h"
2010-03-20 00:26:00 +01:00
# include "util.h"
2010-10-23 11:06:47 +02:00
# include "game_util.h"
2010-12-29 02:10:53 +01:00
# include "miniftpserver.h"
2013-12-17 08:54:33 +01:00
# include "map_preview.h"
# include "stats.h"
# include <time.h>
2011-10-12 08:54:36 +02:00
# include <set>
2012-03-25 08:55:43 +02:00
# include <iostream>
2012-04-17 21:42:53 +02:00
# include <iterator>
2013-12-17 08:54:33 +01:00
2010-03-20 00:26:00 +01:00
# include "leak_dumper.h"
2010-03-17 07:25:19 +01:00
using namespace std ;
using namespace Shared : : Platform ;
using namespace Shared : : Util ;
2011-12-05 06:26:48 +01:00
using namespace Shared : : Map ;
2010-03-17 07:25:19 +01:00
2011-01-13 09:17:18 +01:00
namespace Glest { namespace Game {
2014-01-02 22:56:37 +01:00
double maxFrameCountLagAllowed = 30 ;
double maxClientLagTimeAllowed = 25 ;
double maxFrameCountLagAllowedEver = 30 ;
double maxClientLagTimeAllowedEver = 25 ;
double warnFrameCountLagPercent = 0.50 ;
double LAG_CHECK_GRACE_PERIOD = 15 ;
double LAG_CHECK_INTERVAL_PERIOD = 4 ;
const int MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = 15000 ;
const int MAX_CLIENT_PAUSE_FOR_LAG_COUNT = 3 ;
const int MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS = 1500 ;
const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30 ;
2014-01-04 00:10:30 +01:00
const int MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS = 4000 ;
2014-01-02 22:56:37 +01:00
ServerInterface : : ServerInterface ( bool publishEnabled , ClientLagCallbackInterface * clientLagCallbackInterface ) : GameNetworkInterface ( ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
2014-01-02 22:56:37 +01:00
this - > clientLagCallbackInterface = clientLagCallbackInterface ;
this - > clientsAutoPausedDueToLag = false ;
2013-12-19 08:35:27 +01:00
allowInGameConnections = false ;
gameLaunched = false ;
2013-02-15 19:25:10 +01:00
2013-12-25 07:27:44 +01:00
serverSynchAccessor = new Mutex ( CODE_AT_LINE ) ;
switchSetupRequestsSynchAccessor = new Mutex ( CODE_AT_LINE ) ;
2013-02-16 11:07:36 +01:00
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
2013-12-25 07:27:44 +01:00
slotAccessorMutexes [ index ] = new Mutex ( CODE_AT_LINE ) ;
2011-12-02 17:07:59 +01:00
}
2013-12-25 07:27:44 +01:00
masterServerThreadAccessor = new Mutex ( CODE_AT_LINE ) ;
textMessageQueueThreadAccessor = new Mutex ( CODE_AT_LINE ) ;
broadcastMessageQueueThreadAccessor = new Mutex ( CODE_AT_LINE ) ;
inBroadcastMessageThreadAccessor = new Mutex ( CODE_AT_LINE ) ;
2011-12-02 17:07:59 +01:00
2012-10-30 19:03:03 +01:00
serverSocketAdmin = NULL ;
2011-01-13 09:17:18 +01:00
nextEventId = 1 ;
gameHasBeenInitiated = false ;
exitServer = false ;
gameSettingsUpdateCount = 0 ;
currentFrameCount = 0 ;
gameStartTime = 0 ;
2013-05-26 05:35:31 +02:00
resumeGameStartTime = 0 ;
2011-01-13 09:17:18 +01:00
publishToMasterserverThread = NULL ;
lastMasterserverHeartbeatTime = 0 ;
needToRepublishToMasterserver = false ;
ftpServer = NULL ;
inBroadcastMessage = false ;
2011-05-18 23:14:14 +02:00
lastGlobalLagCheckTime = 0 ;
2011-09-24 09:46:56 +02:00
masterserverAdminRequestLaunch = false ;
2013-03-01 07:52:33 +01:00
lastListenerSlotCheckTime = 0 ;
2011-01-13 09:17:18 +01:00
2012-03-27 07:39:02 +02:00
// This is an admin port listening only on the localhost intended to
// give current connection status info
2012-10-30 19:03:03 +01:00
# ifndef __APPLE__
2012-11-15 16:08:30 +01:00
try {
2013-12-19 08:35:27 +01:00
serverSocketAdmin = new ServerSocket ( true ) ;
2012-11-15 16:08:30 +01:00
serverSocketAdmin - > setBlock ( false ) ;
serverSocketAdmin - > setBindPort ( Config : : getInstance ( ) . getInt ( " ServerAdminPort " , intToStr ( GameConstants : : serverAdminPort ) . c_str ( ) ) ) ;
serverSocketAdmin - > setBindSpecificAddress ( Config : : getInstance ( ) . getString ( " ServerAdminBindAddress " , " 127.0.0.1 " ) ) ;
serverSocketAdmin - > listen ( 5 ) ;
}
catch ( const std : : exception & ex ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Warning Server admin port bind/listen error: \n %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
2013-12-19 08:35:27 +01:00
2012-11-15 16:08:30 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " %s " , szBuf ) ;
}
2012-10-30 19:03:03 +01:00
# endif
2012-03-25 08:55:43 +02:00
2011-01-13 09:17:18 +01:00
maxFrameCountLagAllowed = Config : : getInstance ( ) . getInt ( " MaxFrameCountLagAllowed " , intToStr ( maxFrameCountLagAllowed ) . c_str ( ) ) ;
maxFrameCountLagAllowedEver = Config : : getInstance ( ) . getInt ( " MaxFrameCountLagAllowedEver " , intToStr ( maxFrameCountLagAllowedEver ) . c_str ( ) ) ;
2011-05-16 08:32:06 +02:00
maxClientLagTimeAllowedEver = Config : : getInstance ( ) . getInt ( " MaxClientLagTimeAllowedEver " , intToStr ( maxClientLagTimeAllowedEver ) . c_str ( ) ) ;
2011-01-13 09:17:18 +01:00
maxClientLagTimeAllowed = Config : : getInstance ( ) . getInt ( " MaxClientLagTimeAllowed " , intToStr ( maxClientLagTimeAllowed ) . c_str ( ) ) ;
warnFrameCountLagPercent = Config : : getInstance ( ) . getFloat ( " WarnFrameCountLagPercent " , doubleToStr ( warnFrameCountLagPercent ) . c_str ( ) ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] maxFrameCountLagAllowed = %f, maxFrameCountLagAllowedEver = %f, maxClientLagTimeAllowed = %f, maxClientLagTimeAllowedEver = %f \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , maxFrameCountLagAllowed , maxFrameCountLagAllowedEver , maxClientLagTimeAllowed , maxClientLagTimeAllowedEver ) ;
2011-01-13 09:17:18 +01:00
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
slots [ index ] = NULL ;
switchSetupRequests [ index ] = NULL ;
2010-03-17 07:25:19 +01:00
}
2011-01-13 09:17:18 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
serverSocket . setBlock ( false ) ;
2012-10-06 14:56:53 +02:00
serverSocket . setBindPort ( Config : : getInstance ( ) . getInt ( " PortServer " , intToStr ( GameConstants : : serverPort ) . c_str ( ) ) ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
2013-12-25 07:27:44 +01:00
gameStatsThreadAccessor = new Mutex ( CODE_AT_LINE ) ;
2013-12-19 08:35:27 +01:00
gameStats = NULL ;
2013-10-31 01:57:36 +01:00
2013-12-19 08:35:27 +01:00
Config & config = Config : : getInstance ( ) ;
string scenarioDir = " " ;
2011-12-05 06:26:48 +01:00
vector < string > pathList = config . getPathListForType ( ptMaps , scenarioDir ) ;
vector < string > invalidMapList ;
vector < string > allMaps = MapPreview : : findAllValidMaps ( pathList , scenarioDir , false , true , & invalidMapList ) ;
if ( allMaps . empty ( ) ) {
2013-11-01 06:25:55 +01:00
//throw megaglest_runtime_error("No maps were found!");
printf ( " No maps were found (srv)! \n " ) ;
2011-12-05 06:26:48 +01:00
}
2012-07-06 00:03:15 +02:00
std : : sort ( allMaps . begin ( ) , allMaps . end ( ) ) ;
2013-12-19 08:35:27 +01:00
vector < string > results ;
2011-12-05 06:26:48 +01:00
copy ( allMaps . begin ( ) , allMaps . end ( ) , std : : back_inserter ( results ) ) ;
mapFiles = results ;
2011-10-12 08:54:36 +02:00
results . clear ( ) ;
findDirs ( config . getPathListForType ( ptTilesets ) , results ) ;
if ( results . empty ( ) ) {
2013-11-01 06:25:55 +01:00
//throw megaglest_runtime_error("No tile-sets were found!");
printf ( " No tile-sets were found (srv)! " ) ;
2011-10-12 08:54:36 +02:00
}
2013-12-19 08:35:27 +01:00
tilesetFiles = results ;
2011-10-12 08:54:36 +02:00
results . clear ( ) ;
findDirs ( config . getPathListForType ( ptTechs ) , results ) ;
if ( results . empty ( ) ) {
2013-11-01 06:25:55 +01:00
//throw megaglest_runtime_error("No tech-trees were found!");
printf ( " No tech-trees were found (srv)! \n " ) ;
2011-10-12 08:54:36 +02:00
}
2013-12-19 08:35:27 +01:00
techTreeFiles = results ;
2011-10-12 08:54:36 +02:00
2011-01-13 09:17:18 +01:00
if ( Config : : getInstance ( ) . getBool ( " EnableFTPServer " , " true " ) = = true ) {
std : : pair < string , string > mapsPath ;
vector < string > pathList = Config : : getInstance ( ) . getPathListForType ( ptMaps ) ;
2011-09-01 03:11:23 +02:00
if ( pathList . empty ( ) = = false ) {
2011-01-13 09:17:18 +01:00
mapsPath . first = pathList [ 0 ] ;
if ( pathList . size ( ) > 1 ) {
mapsPath . second = pathList [ 1 ] ;
}
}
std : : pair < string , string > tilesetsPath ;
vector < string > tilesetsList = Config : : getInstance ( ) . getPathListForType ( ptTilesets ) ;
2011-09-01 03:11:23 +02:00
if ( tilesetsList . empty ( ) = = false ) {
2011-01-13 09:17:18 +01:00
tilesetsPath . first = tilesetsList [ 0 ] ;
if ( tilesetsList . size ( ) > 1 ) {
tilesetsPath . second = tilesetsList [ 1 ] ;
}
}
2011-03-10 00:09:32 +01:00
std : : pair < string , string > techtreesPath ;
vector < string > techtreesList = Config : : getInstance ( ) . getPathListForType ( ptTechs ) ;
2011-09-01 03:11:23 +02:00
if ( techtreesList . empty ( ) = = false ) {
2011-03-10 00:09:32 +01:00
techtreesPath . first = techtreesList [ 0 ] ;
if ( techtreesList . size ( ) > 1 ) {
techtreesPath . second = techtreesList [ 1 ] ;
}
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
int portNumber = Config : : getInstance ( ) . getInt ( " FTPServerPort " , intToStr ( ServerSocket : : getFTPServerPort ( ) ) . c_str ( ) ) ;
ServerSocket : : setFTPServerPort ( portNumber ) ;
2012-11-02 20:08:55 +01:00
//printf("In [%s::%s] portNumber = %d ServerSocket::getFTPServerPort() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,portNumber,ServerSocket::getFTPServerPort());
2011-03-11 13:14:24 +01:00
bool allowInternetTilesetFileTransfers = Config : : getInstance ( ) . getBool ( " EnableFTPServerInternetTilesetXfer " , " true " ) ;
bool allowInternetTechtreeFileTransfers = Config : : getInstance ( ) . getBool ( " EnableFTPServerInternetTechtreeXfer " , " true " ) ;
2013-02-15 19:25:10 +01:00
// Get path to temp files
string tempFilePath = " temp/ " ;
if ( getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) ! = " " ) {
tempFilePath = getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) + tempFilePath ;
}
else {
string userData = config . getString ( " UserData_Root " , " " ) ;
if ( userData ! = " " ) {
endPathWithSlash ( userData ) ;
}
tempFilePath = userData + tempFilePath ;
}
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Temp files path [%s] \n " , tempFilePath . c_str ( ) ) ;
2011-03-10 00:09:32 +01:00
ftpServer = new FTPServerThread ( mapsPath , tilesetsPath , techtreesPath ,
2013-02-15 19:25:10 +01:00
publishEnabled , allowInternetTilesetFileTransfers ,
allowInternetTechtreeFileTransfers , portNumber , GameConstants : : maxPlayers ,
this , tempFilePath ) ;
2011-01-13 09:17:18 +01:00
ftpServer - > start ( ) ;
}
2012-03-25 08:55:43 +02:00
if ( publishToMasterserverThread = = NULL ) {
if ( needToRepublishToMasterserver = = true | | GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
2013-01-23 15:51:28 +01:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2012-03-25 08:55:43 +02:00
publishToMasterserverThread = new SimpleTaskThread ( this , 0 , 125 ) ;
2013-01-23 15:51:28 +01:00
publishToMasterserverThread - > setUniqueID ( mutexOwnerId ) ;
2012-03-25 08:55:43 +02:00
publishToMasterserverThread - > start ( ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2012-03-25 08:55:43 +02:00
}
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
2011-03-11 13:14:24 +01:00
void ServerInterface : : setPublishEnabled ( bool value ) {
if ( ftpServer ! = NULL ) {
ftpServer - > setInternetEnabled ( value ) ;
}
}
2012-03-04 00:59:44 +01:00
void ServerInterface : : shutdownMasterserverPublishThread ( ) {
MutexSafeWrapper safeMutex ( masterServerThreadAccessor , CODE_AT_LINE ) ;
if ( publishToMasterserverThread ! = NULL ) {
time_t elapsed = time ( NULL ) ;
publishToMasterserverThread - > signalQuit ( ) ;
for ( ; publishToMasterserverThread - > canShutdown ( false ) = = false & &
2012-09-22 22:13:57 +02:00
difftime ( ( long int ) time ( NULL ) , elapsed ) < = 15 ; ) {
2012-03-04 00:59:44 +01:00
//sleep(150);
}
if ( publishToMasterserverThread - > canShutdown ( true ) ) {
delete publishToMasterserverThread ;
publishToMasterserverThread = NULL ;
}
}
}
2011-01-13 09:17:18 +01:00
ServerInterface : : ~ ServerInterface ( ) {
2011-11-23 09:00:09 +01:00
//printf("===> Destructor for ServerInterface\n");
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-01-10 22:16:28 +01:00
masterController . clearSlaves ( true ) ;
2011-01-13 09:17:18 +01:00
exitServer = true ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
if ( slots [ index ] ! = NULL ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
delete slots [ index ] ;
slots [ index ] = NULL ;
2011-01-13 09:17:18 +01:00
}
2013-12-19 08:35:27 +01:00
if ( switchSetupRequests [ index ] ! = NULL ) {
delete switchSetupRequests [ index ] ;
switchSetupRequests [ index ] = NULL ;
2011-01-13 09:17:18 +01:00
}
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
close ( ) ;
2013-03-01 07:52:33 +01:00
shutdownFTPServer ( ) ;
2012-03-04 00:59:44 +01:00
shutdownMasterserverPublishThread ( ) ;
2011-11-23 09:00:09 +01:00
2011-01-13 09:17:18 +01:00
lastMasterserverHeartbeatTime = 0 ;
if ( needToRepublishToMasterserver = = true ) {
2013-11-07 19:39:08 +01:00
simpleTask ( NULL , NULL ) ;
2010-10-24 07:52:21 +02:00
}
2011-12-02 17:07:59 +01:00
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
delete slotAccessorMutexes [ index ] ;
slotAccessorMutexes [ index ] = NULL ;
2011-12-02 17:07:59 +01:00
}
delete textMessageQueueThreadAccessor ;
textMessageQueueThreadAccessor = NULL ;
delete broadcastMessageQueueThreadAccessor ;
broadcastMessageQueueThreadAccessor = NULL ;
delete inBroadcastMessageThreadAccessor ;
inBroadcastMessageThreadAccessor = NULL ;
delete serverSynchAccessor ;
serverSynchAccessor = NULL ;
delete masterServerThreadAccessor ;
masterServerThreadAccessor = NULL ;
2012-03-25 08:55:43 +02:00
delete serverSocketAdmin ;
serverSocketAdmin = NULL ;
2012-04-14 23:21:09 +02:00
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < ( int ) broadcastMessageQueue . size ( ) ; + + index ) {
pair < NetworkMessage * , int > & item = broadcastMessageQueue [ index ] ;
2012-04-14 23:21:09 +02:00
if ( item . first ! = NULL ) {
delete item . first ;
}
item . first = NULL ;
}
broadcastMessageQueue . clear ( ) ;
2013-02-16 11:07:36 +01:00
delete switchSetupRequestsSynchAccessor ;
switchSetupRequestsSynchAccessor = NULL ;
2013-10-31 01:57:36 +01:00
delete gameStatsThreadAccessor ;
gameStatsThreadAccessor = NULL ;
delete gameStats ;
gameStats = NULL ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
2010-10-23 11:06:47 +02:00
2013-02-16 11:07:36 +01:00
SwitchSetupRequest * * ServerInterface : : getSwitchSetupRequests ( ) {
MutexSafeWrapper safeMutex ( switchSetupRequestsSynchAccessor , CODE_AT_LINE ) ;
return & switchSetupRequests [ 0 ] ;
}
SwitchSetupRequest * ServerInterface : : getSwitchSetupRequests ( int index ) {
MutexSafeWrapper safeMutex ( switchSetupRequestsSynchAccessor , CODE_AT_LINE ) ;
return switchSetupRequests [ index ] ;
}
void ServerInterface : : setSwitchSetupRequests ( int index , SwitchSetupRequest * ptr ) {
MutexSafeWrapper safeMutex ( switchSetupRequestsSynchAccessor , CODE_AT_LINE ) ;
switchSetupRequests [ index ] = ptr ;
}
2011-01-13 09:17:18 +01:00
int ServerInterface : : isValidClientType ( uint32 clientIp ) {
int result = 0 ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
if ( slots [ index ] ! = NULL ) {
Socket * socket = slots [ index ] - > getSocket ( ) ;
2011-01-13 09:17:18 +01:00
if ( socket ! = NULL ) {
uint32 slotIp = socket - > getConnectedIPAddress ( socket - > getIpAddress ( ) ) ;
if ( slotIp = = clientIp ) {
result = 1 ;
break ;
}
}
2011-01-07 07:21:23 +01:00
}
}
2011-01-13 09:17:18 +01:00
return result ;
}
2011-11-29 06:07:18 +01:00
int ServerInterface : : isClientAllowedToGetFile ( uint32 clientIp , const char * username , const char * filename ) {
int result = 1 ;
2013-12-19 08:35:27 +01:00
if ( username ! = NULL & &
strlen ( username ) > 0 & &
filename ! = NULL & &
strlen ( filename ) > 0 ) {
2011-11-29 06:07:18 +01:00
string user = username ;
string file = filename ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d username [%s] file [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , username , filename ) ;
2011-11-29 06:07:18 +01:00
if ( StartsWith ( user , " tilesets " ) = = true & & EndsWith ( file , " 7z " ) = = false ) {
if ( Config : : getInstance ( ) . getBool ( " DisableFTPServerXferUncompressedTilesets " , " false " ) = = true ) {
result = 0 ;
}
else {
2013-12-19 08:35:27 +01:00
char szIP [ 100 ] = " " ;
2011-11-29 06:07:18 +01:00
Ip : : Inet_NtoA ( clientIp , szIP ) ;
string clientIP = szIP ;
std : : vector < std : : string > serverList = Socket : : getLocalIPAddressList ( ) ;
result = 0 ;
2013-12-19 08:35:27 +01:00
for ( unsigned int index = 0 ; index < serverList . size ( ) ; + + index ) {
string serverIP = serverList [ index ] ;
2011-11-29 06:07:18 +01:00
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d clientIP [%s] serverIP [%s] %d / %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientIP . c_str ( ) , serverIP . c_str ( ) , index , serverList . size ( ) ) ;
2011-11-29 06:07:18 +01:00
vector < string > clientTokens ;
Tokenize ( clientIP , clientTokens , " . " ) ;
vector < string > serverTokens ;
Tokenize ( serverIP , serverTokens , " . " ) ;
if ( clientTokens . size ( ) = = 4 & & serverTokens . size ( ) = = 4 ) {
if ( clientTokens [ 0 ] = = serverTokens [ 0 ] | |
clientTokens [ 1 ] = = serverTokens [ 1 ] | |
clientTokens [ 2 ] = = serverTokens [ 2 ] ) {
result = 1 ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d clientIP [%s] IS NOT BLOCKED \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientIP . c_str ( ) ) ;
2011-11-29 06:07:18 +01:00
break ;
}
}
}
}
}
}
return result ;
}
2011-01-13 09:17:18 +01:00
void ServerInterface : : addClientToServerIPAddress ( uint32 clientIp , uint32 ServerIp ) {
FTPServerThread : : addClientToServerIPAddress ( clientIp , ServerIp ) ;
}
void ServerInterface : : addSlot ( int playerIndex ) {
2013-02-24 01:28:45 +01:00
//printf("Adding slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound());
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2012-10-31 21:50:42 +01:00
if ( playerIndex < 0 | | playerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
2012-11-02 20:08:55 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] playerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex ) ;
2012-10-31 21:50:42 +01:00
throw megaglest_runtime_error ( szBuf ) ;
}
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
2012-10-30 19:03:03 +01:00
if ( serverSocketAdmin ! = NULL & & serverSocketAdmin - > isSocketValid ( ) = = false ) {
2012-07-06 16:41:23 +02:00
serverSocketAdmin - > listen ( 5 ) ;
}
2011-01-13 09:17:18 +01:00
if ( serverSocket . isPortBound ( ) = = false ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-06-24 03:23:18 +02:00
serverSocket . bind ( serverSocket . getBindPort ( ) ) ;
}
2011-01-13 09:17:18 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ playerIndex ] , CODE_AT_LINE_X ( playerIndex ) ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
ConnectionSlot * slot = slots [ playerIndex ] ;
if ( slot ! = NULL ) {
2013-12-19 08:35:27 +01:00
slots [ playerIndex ] = NULL ;
2011-01-13 09:17:18 +01:00
}
slots [ playerIndex ] = new ConnectionSlot ( this , playerIndex ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-11-27 06:27:50 +01:00
safeMutexSlot . ReleaseLock ( ) ;
2011-01-13 09:17:18 +01:00
delete slot ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
safeMutex . ReleaseLock ( ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
updateListen ( ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
2013-02-24 01:28:45 +01:00
void ServerInterface : : removeSlot ( int playerIndex , int lockedSlotIndex ) {
//printf("Removing slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound());
2013-12-19 08:35:27 +01:00
if ( playerIndex < 0 | | playerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s %d] playerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2013-02-24 01:28:45 +01:00
Lang & lang = Lang : : getInstance ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
MutexSafeWrapper safeMutexSlot ( NULL , CODE_AT_LINE_X ( playerIndex ) ) ;
if ( playerIndex ! = lockedSlotIndex ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
safeMutexSlot . setMutex ( slotAccessorMutexes [ playerIndex ] , CODE_AT_LINE_X ( playerIndex ) ) ;
}
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
vector < string > msgList ;
2013-12-19 08:35:27 +01:00
ConnectionSlot * slot = slots [ playerIndex ] ;
bool notifyDisconnect = false ;
const vector < string > languageList = this - > gameSettings . getUniqueNetworkPlayerLanguages ( ) ;
2013-02-24 01:28:45 +01:00
if ( slot ! = NULL ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
if ( slot - > getLastReceiveCommandListTime ( ) > 0 ) {
char szBuf [ 4096 ] = " " ;
2013-12-19 08:35:27 +01:00
for ( unsigned int index = 0 ; index < languageList . size ( ) ; + + index ) {
2013-02-24 01:28:45 +01:00
string msgTemplate = " Player %s, disconnected from the game. " ;
2013-12-19 08:35:27 +01:00
if ( lang . hasString ( " PlayerDisconnected " , languageList [ index ] ) = = true ) {
msgTemplate = lang . getString ( " PlayerDisconnected " , languageList [ index ] ) ;
2013-02-24 01:28:45 +01:00
}
# ifdef WIN32
_snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , slot - > getName ( ) . c_str ( ) ) ;
# else
snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , slot - > getName ( ) . c_str ( ) ) ;
# endif
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , szBuf ) ;
msgList . push_back ( szBuf ) ;
}
notifyDisconnect = true ;
}
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
slots [ playerIndex ] = NULL ;
safeMutexSlot . ReleaseLock ( ) ;
safeMutex . ReleaseLock ( ) ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2013-06-04 05:47:04 +02:00
if ( slot ! = NULL ) slot - > close ( ) ;
2013-02-24 01:28:45 +01:00
delete slot ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
updateListen ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2013-02-24 01:28:45 +01:00
if ( notifyDisconnect = = true ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
for ( unsigned int index = 0 ; index < languageList . size ( ) ; + + index ) {
bool localEcho = lang . isLanguageLocal ( languageList [ index ] ) ;
queueTextMessage ( msgList [ index ] , - 1 , localEcho , languageList [ index ] ) ;
2013-02-24 01:28:45 +01:00
}
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex , lockedSlotIndex ) ;
}
2011-01-13 09:17:18 +01:00
bool ServerInterface : : switchSlot ( int fromPlayerIndex , int toPlayerIndex ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
bool result = false ;
2013-03-06 15:29:49 +01:00
//printf("#1 Server is switching slots\n");
2012-10-31 21:50:42 +01:00
if ( fromPlayerIndex < 0 | | fromPlayerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
2012-11-02 20:08:55 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] fromPlayerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , fromPlayerIndex ) ;
2012-10-31 21:50:42 +01:00
throw megaglest_runtime_error ( szBuf ) ;
}
if ( toPlayerIndex < 0 | | toPlayerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
2012-11-02 20:08:55 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] toPlayerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , toPlayerIndex ) ;
2012-10-31 21:50:42 +01:00
throw megaglest_runtime_error ( szBuf ) ;
}
2011-01-13 09:17:18 +01:00
if ( fromPlayerIndex = = toPlayerIndex ) {
return false ;
}
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ fromPlayerIndex ] , CODE_AT_LINE_X ( fromPlayerIndex ) ) ;
MutexSafeWrapper safeMutexSlot2 ( slotAccessorMutexes [ toPlayerIndex ] , CODE_AT_LINE_X ( toPlayerIndex ) ) ;
2013-02-16 11:07:36 +01:00
2013-03-06 15:29:49 +01:00
//printf("#1a Server is switching slots\n");
2012-04-16 21:29:37 +02:00
if ( slots [ toPlayerIndex ] ! = NULL & &
2013-03-06 15:29:49 +01:00
slots [ toPlayerIndex ] - > hasValidSocketId ( ) = = false ) {
2013-02-16 11:07:36 +01:00
//printf("#2 Server is switching slots\n");
2011-01-13 09:17:18 +01:00
slots [ fromPlayerIndex ] - > setPlayerIndex ( toPlayerIndex ) ;
slots [ toPlayerIndex ] - > setPlayerIndex ( fromPlayerIndex ) ;
2013-12-19 08:35:27 +01:00
ConnectionSlot * tmp = slots [ toPlayerIndex ] ;
slots [ toPlayerIndex ] = slots [ fromPlayerIndex ] ;
slots [ fromPlayerIndex ] = tmp ;
2013-05-28 09:10:13 +02:00
2011-01-13 09:17:18 +01:00
safeMutex . ReleaseLock ( ) ;
2013-02-16 11:07:36 +01:00
2011-01-13 09:17:18 +01:00
PlayerIndexMessage playerIndexMessage ( toPlayerIndex ) ;
slots [ toPlayerIndex ] - > sendMessage ( & playerIndexMessage ) ;
2013-02-16 11:07:36 +01:00
//slots[fromPlayerIndex]->resetJoinGameInProgressFlags();
//slots[toPlayerIndex]->setJoinGameInProgressFlags();
2011-11-27 06:27:50 +01:00
safeMutexSlot . ReleaseLock ( ) ;
safeMutexSlot2 . ReleaseLock ( ) ;
2011-01-13 09:17:18 +01:00
result = true ;
updateListen ( ) ;
}
else {
2013-02-16 11:07:36 +01:00
//printf("#3 Server is switching slots aborted, is slot already connected?\n");
2011-11-27 06:27:50 +01:00
safeMutexSlot . ReleaseLock ( ) ;
safeMutexSlot2 . ReleaseLock ( ) ;
2011-01-13 09:17:18 +01:00
safeMutex . ReleaseLock ( ) ;
2011-01-10 22:00:55 +01:00
}
2013-03-06 15:29:49 +01:00
//printf("#4 Server is switching slots\n");
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
return result ;
}
2014-01-08 21:48:56 +01:00
Mutex * ServerInterface : : getSlotMutex ( int playerIndex ) {
return slotAccessorMutexes [ playerIndex ] ;
}
ConnectionSlot * ServerInterface : : getSlot ( int playerIndex , bool lockMutex ) {
2013-12-19 08:35:27 +01:00
if ( playerIndex < 0 | | playerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s %d] playerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2014-01-08 21:48:56 +01:00
MutexSafeWrapper safeMutexSlot ( ( lockMutex = = true ? slotAccessorMutexes [ playerIndex ] : NULL ) , CODE_AT_LINE_X ( playerIndex ) ) ;
2011-11-25 10:12:53 +01:00
ConnectionSlot * result = slots [ playerIndex ] ;
return result ;
}
2013-12-19 08:35:27 +01:00
bool ServerInterface : : isClientConnected ( int playerIndex ) {
if ( playerIndex < 0 | | playerIndex > = GameConstants : : maxPlayers ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s %d] playerIndex is invalid = %d " , extractFileFromDirectoryPath ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) . c_str ( ) , __FUNCTION__ , __LINE__ , playerIndex ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2011-11-25 10:12:53 +01:00
bool result = false ;
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ playerIndex ] , CODE_AT_LINE_X ( playerIndex ) ) ;
if ( slots [ playerIndex ] ! = NULL & & slots [ playerIndex ] - > isConnected ( ) = = true ) {
2011-11-25 10:12:53 +01:00
result = true ;
}
return result ;
2011-01-13 09:17:18 +01:00
}
bool ServerInterface : : hasClientConnection ( ) {
bool result = false ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
if ( isClientConnected ( index ) = = true ) {
2010-05-17 08:41:05 +02:00
result = true ;
break ;
}
}
2011-01-13 09:17:18 +01:00
return result ;
}
2012-07-07 07:35:25 +02:00
int ServerInterface : : getSlotCount ( ) {
int slotCount = 0 ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
if ( slots [ index ] ! = NULL ) {
2012-07-07 07:35:25 +02:00
+ + slotCount ;
}
}
return slotCount ;
}
2013-01-12 00:48:57 +01:00
int ServerInterface : : getConnectedSlotCount ( bool authenticated ) {
2011-01-13 09:17:18 +01:00
int connectedSlotCount = 0 ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
if ( slots [ index ] ! = NULL & & slots [ index ] - > isConnected ( ) = = true ) {
2013-01-12 00:48:57 +01:00
if ( authenticated = = false | |
2013-12-19 08:35:27 +01:00
( authenticated = = true & & slots [ index ] - > getConnectHasHandshaked ( ) = = true ) ) {
2013-01-12 00:48:57 +01:00
+ + connectedSlotCount ;
}
2010-03-17 07:25:19 +01:00
}
}
2011-01-13 09:17:18 +01:00
return connectedSlotCount ;
}
int64 ServerInterface : : getNextEventId ( ) {
nextEventId + + ;
if ( nextEventId > INT_MAX ) {
nextEventId = 1 ;
}
return nextEventId ;
}
std : : pair < bool , bool > ServerInterface : : clientLagCheck ( ConnectionSlot * connectionSlot , bool skipNetworkBroadCast ) {
std : : pair < bool , bool > clientLagExceededOrWarned = std : : make_pair ( false , false ) ;
static bool alreadyInLagCheck = false ;
2011-05-18 23:14:14 +02:00
2013-02-15 19:25:10 +01:00
if ( alreadyInLagCheck = = true | |
( connectionSlot ! = NULL & & ( connectionSlot - > getSkipLagCheck ( ) = = true | |
connectionSlot - > getConnectHasHandshaked ( ) = = false ) ) ) {
2011-01-13 09:17:18 +01:00
return clientLagExceededOrWarned ;
2010-05-15 20:59:17 +02:00
}
2011-01-13 09:17:18 +01:00
try {
2010-07-01 08:11:14 +02:00
alreadyInLagCheck = true ;
2013-05-26 05:35:31 +02:00
if ( ( gameStartTime > 0 & &
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD ) & &
( resumeGameStartTime = = 0 | |
( resumeGameStartTime > 0 & &
difftime ( ( long int ) time ( NULL ) , resumeGameStartTime ) > = LAG_CHECK_GRACE_PERIOD ) ) ) {
2010-07-01 08:11:14 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
2013-12-19 08:35:27 +01:00
double clientLag = this - > getCurrentFrameCount ( ) - connectionSlot - > getCurrentFrameCount ( ) ;
double clientLagCount = ( gameSettings . getNetworkFramePeriod ( ) > 0 ? ( clientLag / gameSettings . getNetworkFramePeriod ( ) ) : 0 ) ;
connectionSlot - > setCurrentLagCount ( clientLagCount ) ;
2010-07-01 08:11:14 +02:00
2013-12-19 08:35:27 +01:00
double clientLagTime = difftime ( ( long int ) time ( NULL ) , connectionSlot - > getLastReceiveCommandListTime ( ) ) ;
2011-02-21 02:34:31 +01:00
2010-07-01 08:11:14 +02:00
if ( this - > getCurrentFrameCount ( ) > 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] playerIndex = %d, clientLag = %f, clientLagCount = %f, this->getCurrentFrameCount() = %d, connectionSlot->getCurrentFrameCount() = %d, clientLagTime = %f \n " ,
2012-11-02 20:08:55 +01:00
extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ,
2011-01-13 09:17:18 +01:00
connectionSlot - > getPlayerIndex ( ) ,
clientLag , clientLagCount ,
this - > getCurrentFrameCount ( ) ,
connectionSlot - > getCurrentFrameCount ( ) ,
clientLagTime ) ;
2010-06-28 02:21:12 +02:00
}
2010-07-01 08:11:14 +02:00
// TEST LAG Error and warnings!!!
//clientLagCount = maxFrameCountLagAllowed + 1;
//clientLagTime = maxClientLagTimeAllowed + 1;
/*
if ( difftime ( time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD + 5 ) {
clientLagTime = maxClientLagTimeAllowed + 1 ;
2010-06-28 02:21:12 +02:00
}
2010-07-01 08:11:14 +02:00
else if ( difftime ( time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD ) {
clientLagTime = ( maxClientLagTimeAllowed * warnFrameCountLagPercent ) + 1 ;
}
*/
// END test
2010-06-28 02:21:12 +02:00
2011-05-18 23:14:14 +02:00
2014-01-02 22:56:37 +01:00
//printf("skipNetworkBroadCast [%d] clientLagCount [%f][%f][%f] clientLagTime [%f][%f][%f]\n",skipNetworkBroadCast,clientLagCount,(maxFrameCountLagAllowed * warnFrameCountLagPercent),maxFrameCountLagAllowed,clientLagTime,(maxClientLagTimeAllowed * warnFrameCountLagPercent),maxClientLagTimeAllowed);
2010-07-01 08:11:14 +02:00
// New lag check
if ( ( maxFrameCountLagAllowed > 0 & & clientLagCount > maxFrameCountLagAllowed ) | |
2010-08-27 20:53:59 +02:00
( maxClientLagTimeAllowed > 0 & & clientLagTime > maxClientLagTimeAllowed ) | |
2011-05-18 23:14:14 +02:00
( maxFrameCountLagAllowedEver > 0 & & clientLagCount > maxFrameCountLagAllowedEver ) | |
( maxClientLagTimeAllowedEver > 0 & & clientLagTime > maxClientLagTimeAllowedEver ) ) {
2014-01-02 22:56:37 +01:00
2010-07-29 07:51:50 +02:00
clientLagExceededOrWarned . first = true ;
2014-01-02 22:56:37 +01:00
//printf("#1 Client Warned\n");
2010-06-30 09:03:04 +02:00
2011-04-05 20:39:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
const vector < string > languageList = this - > gameSettings . getUniqueNetworkPlayerLanguages ( ) ;
2013-12-19 08:35:27 +01:00
for ( unsigned int index = 0 ; index < languageList . size ( ) ; + + index ) {
2011-04-05 20:39:47 +02:00
char szBuf [ 4096 ] = " " ;
string msgTemplate = " DROPPING %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], disconnecting client. " ;
if ( lang . hasString ( " ClientLagDropping " ) = = true ) {
2013-12-19 08:35:27 +01:00
msgTemplate = lang . getString ( " ClientLagDropping " , languageList [ index ] ) ;
2011-04-05 20:39:47 +02:00
}
if ( gameSettings . getNetworkPauseGameForLaggedClients ( ) = = true & &
2011-05-18 23:14:14 +02:00
( ( maxFrameCountLagAllowedEver < = 0 | | clientLagCount < = maxFrameCountLagAllowedEver ) & &
( maxClientLagTimeAllowedEver < = 0 | | clientLagTime < = maxClientLagTimeAllowedEver ) ) ) {
2011-04-05 20:39:47 +02:00
msgTemplate = " PAUSING GAME TEMPORARILY for %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], waiting for client to catch up... " ;
if ( lang . hasString ( " ClientLagPausing " ) = = true ) {
2013-12-19 08:35:27 +01:00
msgTemplate = lang . getString ( " ClientLagPausing " , languageList [ index ] ) ;
2011-04-05 20:39:47 +02:00
}
}
2011-01-13 09:17:18 +01:00
# ifdef WIN32
2011-04-05 20:39:47 +02:00
_snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , connectionSlot - > getName ( ) . c_str ( ) , maxFrameCountLagAllowed , maxClientLagTimeAllowed , clientLagCount , clientLagTime ) ;
2011-01-13 09:17:18 +01:00
# else
2011-04-05 20:39:47 +02:00
snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , connectionSlot - > getName ( ) . c_str ( ) , maxFrameCountLagAllowed , maxClientLagTimeAllowed , clientLagCount , clientLagTime ) ;
2011-01-13 09:17:18 +01:00
# endif
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , szBuf ) ;
2010-06-28 02:21:12 +02:00
2011-04-05 20:39:47 +02:00
if ( skipNetworkBroadCast = = false ) {
string sMsg = szBuf ;
2013-12-19 08:35:27 +01:00
bool echoLocal = lang . isLanguageLocal ( languageList [ index ] ) ;
sendTextMessage ( sMsg , - 1 , echoLocal , languageList [ index ] , connectionSlot - > getPlayerIndex ( ) ) ;
2011-04-05 20:39:47 +02:00
}
}
2010-07-01 08:11:14 +02:00
2010-08-27 20:53:59 +02:00
if ( gameSettings . getNetworkPauseGameForLaggedClients ( ) = = false | |
2011-05-16 08:32:06 +02:00
( maxFrameCountLagAllowedEver > 0 & & clientLagCount > maxFrameCountLagAllowedEver ) | |
( maxClientLagTimeAllowedEver > 0 & & clientLagTime > maxClientLagTimeAllowedEver ) ) {
2013-02-15 19:25:10 +01:00
//printf("Closing connection slot lagged out!\n");
2010-07-01 08:11:14 +02:00
connectionSlot - > close ( ) ;
}
2011-02-21 02:34:31 +01:00
2010-07-01 08:11:14 +02:00
}
// New lag check warning
else if ( ( maxFrameCountLagAllowed > 0 & & warnFrameCountLagPercent > 0 & &
clientLagCount > ( maxFrameCountLagAllowed * warnFrameCountLagPercent ) ) | |
( maxClientLagTimeAllowed > 0 & & warnFrameCountLagPercent > 0 & &
clientLagTime > ( maxClientLagTimeAllowed * warnFrameCountLagPercent ) ) ) {
2014-01-02 22:56:37 +01:00
2010-07-29 07:51:50 +02:00
clientLagExceededOrWarned . second = true ;
2014-01-02 22:56:37 +01:00
//printf("#2 Client Warned\n");
2010-07-29 07:51:50 +02:00
2010-07-01 08:11:14 +02:00
if ( connectionSlot - > getLagCountWarning ( ) = = false ) {
connectionSlot - > setLagCountWarning ( true ) ;
2011-04-05 20:39:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
const vector < string > languageList = this - > gameSettings . getUniqueNetworkPlayerLanguages ( ) ;
2013-12-19 08:35:27 +01:00
for ( unsigned int index = 0 ; index < languageList . size ( ) ; + + index ) {
2011-04-05 20:39:47 +02:00
char szBuf [ 4096 ] = " " ;
string msgTemplate = " LAG WARNING for %s, may exceed max allowed LAG count of %f [time = %f], clientLag = %f [%f], WARNING... " ;
if ( lang . hasString ( " ClientLagWarning " ) = = true ) {
2013-12-19 08:35:27 +01:00
msgTemplate = lang . getString ( " ClientLagWarning " , languageList [ index ] ) ;
2011-04-05 20:39:47 +02:00
}
2010-07-01 08:11:14 +02:00
# ifdef WIN32
2011-04-05 20:39:47 +02:00
_snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , connectionSlot - > getName ( ) . c_str ( ) , maxFrameCountLagAllowed , maxClientLagTimeAllowed , clientLagCount , clientLagTime ) ;
2010-07-01 08:11:14 +02:00
# else
2011-04-05 20:39:47 +02:00
snprintf ( szBuf , 4095 , msgTemplate . c_str ( ) , connectionSlot - > getName ( ) . c_str ( ) , maxFrameCountLagAllowed , maxClientLagTimeAllowed , clientLagCount , clientLagTime ) ;
2010-07-01 08:11:14 +02:00
# endif
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , szBuf ) ;
2010-07-01 08:11:14 +02:00
2011-04-05 20:39:47 +02:00
if ( skipNetworkBroadCast = = false ) {
string sMsg = szBuf ;
2013-12-19 08:35:27 +01:00
bool echoLocal = lang . isLanguageLocal ( languageList [ index ] ) ;
sendTextMessage ( sMsg , - 1 , echoLocal , languageList [ index ] , connectionSlot - > getPlayerIndex ( ) ) ;
2011-04-05 20:39:47 +02:00
}
}
2010-07-01 08:11:14 +02:00
}
}
else if ( connectionSlot - > getLagCountWarning ( ) = = true ) {
connectionSlot - > setLagCountWarning ( false ) ;
2010-06-28 02:21:12 +02:00
}
2010-06-17 02:08:27 +02:00
}
}
2010-06-15 07:36:07 +02:00
}
2010-07-01 08:11:14 +02:00
catch ( const exception & ex ) {
alreadyInLagCheck = false ;
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( ex . what ( ) ) ;
2010-07-01 08:11:14 +02:00
}
2011-02-21 02:34:31 +01:00
2011-01-13 09:17:18 +01:00
alreadyInLagCheck = false ;
return clientLagExceededOrWarned ;
}
void ServerInterface : : updateSocketTriggeredList ( std : : map < PLATFORM_SOCKET , bool > & socketTriggeredList ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2011-11-25 00:15:21 +01:00
if ( connectionSlot ! = NULL ) {
PLATFORM_SOCKET clientSocket = connectionSlot - > getSocketId ( ) ;
if ( Socket : : isSocketValid ( & clientSocket ) = = true ) {
socketTriggeredList [ clientSocket ] = false ;
}
2011-01-13 09:17:18 +01:00
}
}
}
void ServerInterface : : validateConnectedClients ( ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL ) {
connectionSlot - > validateConnection ( ) ;
}
}
}
2013-01-10 22:16:28 +01:00
bool ServerInterface : : signalClientReceiveCommands ( ConnectionSlot * connectionSlot ,
int slotIndex , bool socketTriggered , ConnectionSlotEvent & event ) {
bool slotSignalled = false ;
event . eventType = eReceiveSocketData ;
event . networkMessage = NULL ;
event . connectionSlot = connectionSlot ;
event . socketTriggered = socketTriggered ;
event . triggerId = slotIndex ;
event . eventId = getNextEventId ( ) ;
if ( connectionSlot ! = NULL ) {
if ( socketTriggered = = true | | connectionSlot - > isConnected ( ) = = false ) {
connectionSlot - > signalUpdate ( & event ) ;
slotSignalled = true ;
}
}
return slotSignalled ;
}
2011-01-13 09:17:18 +01:00
void ServerInterface : : signalClientsToRecieveData ( std : : map < PLATFORM_SOCKET , bool > & socketTriggeredList ,
std : : map < int , ConnectionSlotEvent > & eventList ,
std : : map < int , bool > & mapSlotSignalledList ) {
2013-01-12 05:40:44 +01:00
//printf("====================================In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2013-02-15 19:25:10 +01:00
//printf("Signal clients get new data\n");
2013-01-10 22:16:28 +01:00
const bool newThreadManager = Config : : getInstance ( ) . getBool ( " EnableNewThreadManager " , " false " ) ;
if ( newThreadManager = = true ) {
masterController . clearSlaves ( true ) ;
std : : vector < SlaveThreadControllerInterface * > slaveThreadList ;
2013-01-12 05:40:44 +01:00
for ( int i = 0 ; exitServer = = false & & i < GameConstants : : maxPlayers ; + + i ) {
2013-01-10 22:16:28 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ i ] , CODE_AT_LINE_X ( i ) ) ;
ConnectionSlot * connectionSlot = slots [ i ] ;
2011-01-13 09:17:18 +01:00
2013-01-10 22:16:28 +01:00
bool socketTriggered = false ;
2011-11-25 00:15:21 +01:00
2013-01-10 22:16:28 +01:00
if ( connectionSlot ! = NULL ) {
PLATFORM_SOCKET clientSocket = connectionSlot - > getSocketId ( ) ;
if ( Socket : : isSocketValid ( & clientSocket ) ) {
socketTriggered = socketTriggeredList [ clientSocket ] ;
}
2013-02-15 19:25:10 +01:00
else if ( this - > getGameHasBeenInitiated ( ) = = true & &
this - > getAllowInGameConnections ( ) = = true ) {
socketTriggeredList [ clientSocket ] = true ;
socketTriggered = socketTriggeredList [ clientSocket ] ;
}
2013-01-10 22:16:28 +01:00
}
ConnectionSlotEvent & event = eventList [ i ] ;
2013-01-12 05:40:44 +01:00
event . eventType = eReceiveSocketData ;
event . networkMessage = NULL ;
event . connectionSlot = connectionSlot ;
event . socketTriggered = socketTriggered ;
event . triggerId = i ;
event . eventId = getNextEventId ( ) ;
2013-01-10 22:16:28 +01:00
if ( connectionSlot ! = NULL ) {
if ( socketTriggered = = true | | connectionSlot - > isConnected ( ) = = false ) {
2013-01-12 05:40:44 +01:00
if ( connectionSlot - > getWorkerThread ( ) ! = NULL ) {
slaveThreadList . push_back ( connectionSlot - > getWorkerThread ( ) ) ;
mapSlotSignalledList [ i ] = true ;
}
2013-01-10 22:16:28 +01:00
}
}
}
masterController . setSlaves ( slaveThreadList ) ;
masterController . signalSlaves ( & eventList ) ;
}
else {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2013-01-10 22:16:28 +01:00
if ( connectionSlot ! = NULL ) {
2013-05-26 08:03:32 +02:00
bool socketTriggered = false ;
2013-01-10 22:16:28 +01:00
PLATFORM_SOCKET clientSocket = connectionSlot - > getSocketId ( ) ;
if ( Socket : : isSocketValid ( & clientSocket ) ) {
socketTriggered = socketTriggeredList [ clientSocket ] ;
}
2013-03-01 07:52:33 +01:00
2013-12-19 08:35:27 +01:00
ConnectionSlotEvent & event = eventList [ index ] ;
bool socketSignalled = signalClientReceiveCommands ( connectionSlot , index , socketTriggered , event ) ;
2013-03-01 07:52:33 +01:00
if ( connectionSlot ! = NULL & & socketTriggered = = true ) {
2013-12-19 08:35:27 +01:00
mapSlotSignalledList [ index ] = socketSignalled ;
2013-03-01 07:52:33 +01:00
}
2013-02-26 08:05:46 +01:00
}
2011-01-13 09:17:18 +01:00
}
}
}
2014-01-02 22:56:37 +01:00
void ServerInterface : : checkForCompletedClientsUsingThreadManager (
std : : map < int , bool > & mapSlotSignalledList , std : : vector < string > & errorMsgList ) {
2011-11-23 09:00:09 +01:00
2014-01-02 22:56:37 +01:00
masterController . waitTillSlavesTrigger ( MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS ) ;
masterController . clearSlaves ( true ) ;
2013-02-26 08:05:46 +01:00
2014-01-02 22:56:37 +01:00
for ( int i = 0 ; exitServer = = false & & i < GameConstants : : maxPlayers ; + + i ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ i ] , CODE_AT_LINE_X ( i ) ) ;
2011-11-23 09:00:09 +01:00
2014-01-02 22:56:37 +01:00
ConnectionSlot * connectionSlot = slots [ i ] ;
if ( connectionSlot ! = NULL & & mapSlotSignalledList [ i ] = = true ) {
try {
std : : vector < std : : string > errorList =
connectionSlot - > getThreadErrorList ( ) ;
// Collect any collected errors from threads
if ( errorList . empty ( ) = = false ) {
for ( int iErrIdx = 0 ; iErrIdx < ( int ) errorList . size ( ) ; + + iErrIdx ) {
string & sErr = errorList [ iErrIdx ] ;
if ( sErr ! = " " ) {
errorMsgList . push_back ( sErr ) ;
}
}
connectionSlot - > clearThreadErrorList ( ) ;
}
} catch ( const exception & ex ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
errorMsgList . push_back ( ex . what ( ) ) ;
}
}
}
}
void ServerInterface : : checkForCompletedClientsUsingLoop (
std : : map < int , bool > & mapSlotSignalledList , std : : vector < string > & errorMsgList ,
std : : map < int , ConnectionSlotEvent > & eventList ) {
//time_t waitForThreadElapsed = time(NULL);
Chrono waitForThreadElapsed ( true ) ;
std : : map < int , bool > slotsCompleted ;
for ( bool threadsDone = false ; exitServer = = false & & threadsDone = = false & &
waitForThreadElapsed . getMillis ( ) < = MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS ; ) {
threadsDone = true ;
// Examine all threads for completion of delegation
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true & &
mapSlotSignalledList [ index ] = = true & &
connectionSlot - > getJoinGameInProgress ( ) = = false & &
slotsCompleted . find ( index ) = = slotsCompleted . end ( ) ) {
2011-11-23 09:00:09 +01:00
2011-01-13 09:17:18 +01:00
try {
std : : vector < std : : string > errorList = connectionSlot - > getThreadErrorList ( ) ;
// Collect any collected errors from threads
2014-01-02 22:56:37 +01:00
if ( errorList . empty ( ) = = false ) {
for ( int iErrIdx = 0 ; iErrIdx < ( int ) errorList . size ( ) ; + + iErrIdx ) {
2011-01-13 09:17:18 +01:00
string & sErr = errorList [ iErrIdx ] ;
2014-01-02 22:56:37 +01:00
if ( sErr ! = " " ) {
2011-01-13 09:17:18 +01:00
errorMsgList . push_back ( sErr ) ;
}
}
connectionSlot - > clearThreadErrorList ( ) ;
}
2014-01-02 22:56:37 +01:00
// Not done waiting for data yet
bool updateFinished = ( connectionSlot ! = NULL ? connectionSlot - > updateCompleted ( & eventList [ index ] ) : true ) ;
if ( updateFinished = = false ) {
threadsDone = false ;
break ;
}
else {
slotsCompleted [ index ] = true ;
}
2011-01-13 09:17:18 +01:00
}
2014-01-02 22:56:37 +01:00
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-11-23 09:00:09 +01:00
2011-01-13 09:17:18 +01:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
2011-01-13 02:46:32 +01:00
}
2013-01-10 22:16:28 +01:00
}
}
2014-01-02 22:56:37 +01:00
}
2013-02-26 08:05:46 +01:00
2014-01-24 22:44:21 +01:00
std : : string ServerInterface : : getIpAddress ( bool mutexLock ) {
2014-01-30 07:47:55 +01:00
string result = serverSocket . getIpAddress ( ) ;
2014-01-24 22:44:21 +01:00
return result ;
}
2014-01-02 22:56:37 +01:00
void ServerInterface : : setClientLagCallbackInterface ( ClientLagCallbackInterface * intf ) {
this - > clientLagCallbackInterface = intf ;
}
2013-12-19 08:35:27 +01:00
2014-01-02 22:56:37 +01:00
bool ServerInterface : : getClientsAutoPausedDueToLag ( ) {
return this - > clientsAutoPausedDueToLag ;
}
void ServerInterface : : checkForCompletedClients ( std : : map < int , bool > & mapSlotSignalledList ,
std : : vector < string > & errorMsgList ,
std : : map < int , ConnectionSlotEvent > & eventList ) {
2013-01-10 22:16:28 +01:00
2014-01-02 22:56:37 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2013-01-10 22:16:28 +01:00
2014-01-02 22:56:37 +01:00
const bool newThreadManager = Config : : getInstance ( ) . getBool ( " EnableNewThreadManager " , " false " ) ;
if ( newThreadManager = = true ) {
checkForCompletedClientsUsingThreadManager ( mapSlotSignalledList , errorMsgList ) ;
}
else {
checkForCompletedClientsUsingLoop ( mapSlotSignalledList , errorMsgList , eventList ) ;
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2013-01-10 22:16:28 +01:00
2014-01-02 22:56:37 +01:00
void ServerInterface : : checkForAutoPauseForLaggingClient ( int index , ConnectionSlot * connectionSlot ) {
2011-11-23 09:00:09 +01:00
2014-01-17 20:32:21 +01:00
if ( gameSettings . getNetworkPauseGameForLaggedClients ( ) = = true & &
this - > clientsAutoPausedDueToLag = = false ) {
2014-01-02 22:56:37 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
2014-01-17 20:32:21 +01:00
if ( connectionSlot - > getAutoPauseGameCountForLag ( ) < MAX_CLIENT_PAUSE_FOR_LAG_COUNT ) {
2014-01-02 22:56:37 +01:00
if ( this - > clientLagCallbackInterface ! = NULL ) {
if ( this - > clientsAutoPausedDueToLagTimer . isStarted ( ) = = false | |
this - > clientsAutoPausedDueToLagTimer . getMillis ( ) > = MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS ) {
connectionSlot - > incrementAutoPauseGameCountForLag ( ) ;
this - > clientsAutoPausedDueToLag = true ;
if ( this - > clientLagCallbackInterface - > clientLagHandler ( index , true ) = = false ) {
connectionSlot - > close ( ) ;
2013-01-10 22:16:28 +01:00
}
else {
2014-01-02 22:56:37 +01:00
if ( this - > clientsAutoPausedDueToLagTimer . isStarted ( ) = = true ) {
2013-01-10 22:16:28 +01:00
2014-01-02 22:56:37 +01:00
this - > clientsAutoPausedDueToLagTimer . reset ( ) ;
this - > clientsAutoPausedDueToLagTimer . stop ( ) ;
}
this - > clientsAutoPausedDueToLagTimer . start ( ) ;
}
2013-01-10 22:16:28 +01:00
}
}
}
2010-03-17 07:25:19 +01:00
}
2011-01-13 09:17:18 +01:00
}
}
2010-03-17 07:25:19 +01:00
2011-11-25 06:37:55 +01:00
void ServerInterface : : checkForLaggingClients ( std : : map < int , bool > & mapSlotSignalledList ,
2011-01-13 09:17:18 +01:00
std : : map < int , ConnectionSlotEvent > & eventList ,
std : : map < PLATFORM_SOCKET , bool > & socketTriggeredList ,
std : : vector < string > & errorMsgList ) {
2011-05-18 23:14:14 +02:00
bool lastGlobalLagCheckTimeUpdate = false ;
2013-01-12 05:40:44 +01:00
if ( gameHasBeenInitiated = = true ) {
2013-12-19 08:35:27 +01:00
2014-01-02 22:56:37 +01:00
//time_t waitForClientsElapsed = time(NULL);
Chrono waitForClientsElapsed ( true ) ;
//time_t waitForThreadElapsed = time(NULL);
Chrono waitForThreadElapsed ( true ) ;
2013-01-12 05:40:44 +01:00
std : : map < int , bool > slotsCompleted ;
std : : map < int , bool > slotsWarnedList ;
2013-12-19 08:35:27 +01:00
2013-01-12 05:40:44 +01:00
for ( bool threadsDone = false ;
exitServer = = false & & threadsDone = = false & &
2014-01-02 22:56:37 +01:00
waitForThreadElapsed . getMillis ( ) < = MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS ; ) {
2013-12-19 08:35:27 +01:00
2013-01-12 05:40:44 +01:00
threadsDone = true ;
// Examine all threads for completion of delegation
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
2013-03-06 15:29:49 +01:00
//printf("#1 Check lag for i: %d\n",i);
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2013-03-06 15:29:49 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true & &
2013-12-19 08:35:27 +01:00
connectionSlot - > getSkipLagCheck ( ) = = false & &
mapSlotSignalledList [ index ] = = true & &
slotsCompleted . find ( index ) = = slotsCompleted . end ( ) ) {
2013-03-06 15:29:49 +01:00
//printf("#2 Check lag for i: %d playerindex: %d name [%s] socket: %d\n",i,connectionSlot->getPlayerIndex(),connectionSlot->getName().c_str(),connectionSlot->getSocketId());
2013-01-12 05:40:44 +01:00
try {
std : : vector < std : : string > errorList = connectionSlot - > getThreadErrorList ( ) ;
// Show any collected errors from threads
if ( errorList . empty ( ) = = false ) {
2013-11-19 07:14:06 +01:00
for ( int iErrIdx = 0 ; iErrIdx < ( int ) errorList . size ( ) ; + + iErrIdx ) {
2013-01-12 05:40:44 +01:00
string & sErr = errorList [ iErrIdx ] ;
if ( sErr ! = " " ) {
errorMsgList . push_back ( sErr ) ;
}
2011-01-13 09:17:18 +01:00
}
2013-01-12 05:40:44 +01:00
connectionSlot - > clearThreadErrorList ( ) ;
2011-01-13 09:17:18 +01:00
}
2010-08-20 22:03:06 +02:00
2013-01-12 05:40:44 +01:00
// Not done waiting for data yet
2013-12-19 08:35:27 +01:00
bool updateFinished = ( connectionSlot ! = NULL ? connectionSlot - > updateCompleted ( & eventList [ index ] ) : true ) ;
2013-01-12 05:40:44 +01:00
if ( updateFinished = = false ) {
2013-03-06 15:29:49 +01:00
//printf("#2a Check lag for i: %d\n",i);
2013-01-12 05:40:44 +01:00
threadsDone = false ;
break ;
2011-01-13 09:17:18 +01:00
}
2013-01-12 05:40:44 +01:00
else {
// New lag check
std : : pair < bool , bool > clientLagExceededOrWarned = std : : make_pair ( false , false ) ;
if ( gameHasBeenInitiated = = true & & connectionSlot ! = NULL & &
connectionSlot - > isConnected ( ) = = true ) {
2013-12-19 08:35:27 +01:00
clientLagExceededOrWarned = clientLagCheck ( connectionSlot , slotsWarnedList [ index ] ) ;
2010-08-20 22:03:06 +02:00
2013-01-12 05:40:44 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientLagExceededOrWarned . first , clientLagExceededOrWarned . second , gameSettings . getNetworkPauseGameForLaggedClients ( ) ) ;
2010-05-15 20:59:17 +02:00
2013-01-12 05:40:44 +01:00
if ( clientLagExceededOrWarned . first = = true ) {
2013-12-19 08:35:27 +01:00
slotsWarnedList [ index ] = true ;
2013-01-12 05:40:44 +01:00
}
}
// If the client has exceeded lag and the server wants
// to pause while they catch up, re-trigger the
// client reader thread
2014-01-02 22:56:37 +01:00
if ( ( clientLagExceededOrWarned . second = = true & &
2013-12-19 08:35:27 +01:00
gameSettings . getNetworkPauseGameForLaggedClients ( ) = = true ) ) {
2013-01-12 05:40:44 +01:00
2014-01-02 22:56:37 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientLagExceededOrWarned . first , clientLagExceededOrWarned . second , ( int ) waitForClientsElapsed . getMillis ( ) , MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS ) ;
checkForAutoPauseForLaggingClient ( index , connectionSlot ) ;
slotsCompleted [ index ] = true ;
2011-01-13 09:17:18 +01:00
}
2013-01-12 05:40:44 +01:00
else {
2013-12-19 08:35:27 +01:00
slotsCompleted [ index ] = true ;
2013-01-12 05:40:44 +01:00
}
2011-01-13 09:17:18 +01:00
}
2011-01-13 02:46:32 +01:00
}
2013-01-12 05:40:44 +01:00
catch ( const exception & ex ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
errorMsgList . push_back ( ex . what ( ) ) ;
}
2011-01-13 02:46:32 +01:00
}
2011-05-18 23:14:14 +02:00
2013-03-06 15:29:49 +01:00
//printf("#3 Check lag for i: %d\n",i);
2013-12-19 08:35:27 +01:00
if ( connectionSlot ! = NULL & &
connectionSlot - > isConnected ( ) = = true & &
connectionSlot - > getSkipLagCheck ( ) = = false ) {
2013-03-06 15:29:49 +01:00
//printf("#4 Check lag for i: %d\n",i);
2013-01-12 05:40:44 +01:00
try {
if ( gameHasBeenInitiated = = true & &
2013-06-19 02:01:29 +02:00
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD & &
difftime ( ( long int ) time ( NULL ) , lastGlobalLagCheckTime ) > = LAG_CHECK_INTERVAL_PERIOD ) {
2011-05-18 23:14:14 +02:00
2013-01-12 05:40:44 +01:00
//printf("\n\n\n^^^^^^^^^^^^^^ PART A\n\n\n");
2011-05-18 23:14:14 +02:00
2013-01-12 05:40:44 +01:00
// New lag check
std : : pair < bool , bool > clientLagExceededOrWarned = std : : make_pair ( false , false ) ;
2013-06-19 02:01:29 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
2013-01-12 05:40:44 +01:00
//printf("\n\n\n^^^^^^^^^^^^^^ PART B\n\n\n");
2011-05-18 23:14:14 +02:00
2013-01-12 05:40:44 +01:00
lastGlobalLagCheckTimeUpdate = true ;
2013-12-19 08:35:27 +01:00
clientLagExceededOrWarned = clientLagCheck ( connectionSlot , slotsWarnedList [ index ] ) ;
2011-05-18 23:14:14 +02:00
2013-01-12 05:40:44 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientLagExceededOrWarned . first , clientLagExceededOrWarned . second , gameSettings . getNetworkPauseGameForLaggedClients ( ) ) ;
2011-05-18 23:14:14 +02:00
2013-01-12 05:40:44 +01:00
if ( clientLagExceededOrWarned . first = = true ) {
2013-12-19 08:35:27 +01:00
slotsWarnedList [ index ] = true ;
2013-01-12 05:40:44 +01:00
}
2013-06-11 02:07:28 +02:00
// If the client has exceeded lag and the server wants
// to pause while they catch up, re-trigger the
// client reader thread
2014-01-02 22:56:37 +01:00
if ( ( clientLagExceededOrWarned . second = = true & &
2013-12-19 08:35:27 +01:00
gameSettings . getNetworkPauseGameForLaggedClients ( ) = = true ) ) {
2014-01-02 22:56:37 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , clientLagExceededOrWarned . first , clientLagExceededOrWarned . second , ( int ) waitForClientsElapsed . getMillis ( ) , MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS ) ;
2013-06-11 02:07:28 +02:00
2014-01-02 22:56:37 +01:00
checkForAutoPauseForLaggingClient ( index , connectionSlot ) ;
2013-06-11 02:07:28 +02:00
}
2011-05-18 23:14:14 +02:00
}
}
}
2013-01-12 05:40:44 +01:00
catch ( const exception & ex ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
errorMsgList . push_back ( ex . what ( ) ) ;
}
2011-05-18 23:14:14 +02:00
}
2013-03-06 15:29:49 +01:00
//printf("#5 Check lag for i: %d\n",i);
2011-05-18 23:14:14 +02:00
}
2011-01-13 09:17:18 +01:00
}
}
2011-05-18 23:14:14 +02:00
if ( lastGlobalLagCheckTimeUpdate = = true ) {
lastGlobalLagCheckTime = time ( NULL ) ;
}
2011-01-13 09:17:18 +01:00
}
void ServerInterface : : executeNetworkCommandsFromClients ( ) {
if ( gameHasBeenInitiated = = true ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
vector < NetworkCommand > pendingList = connectionSlot - > getPendingNetworkCommandList ( true ) ;
2011-09-01 03:11:23 +02:00
if ( pendingList . empty ( ) = = false ) {
2013-11-19 07:14:06 +01:00
for ( int idx = 0 ; exitServer = = false & & idx < ( int ) pendingList . size ( ) ; + + idx ) {
2011-01-13 09:17:18 +01:00
NetworkCommand & cmd = pendingList [ idx ] ;
this - > requestCommand ( & cmd ) ;
}
2013-12-19 08:35:27 +01:00
//printf("Executed: %d commands from slot: %d\n",pendingList.size(),index);
2011-01-13 09:17:18 +01:00
}
}
}
}
}
void ServerInterface : : dispatchPendingChatMessages ( std : : vector < string > & errorMsgList ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & &
2011-11-25 18:01:35 +01:00
connectionSlot - > getChatTextList ( false ) . empty ( ) = = false ) {
2011-01-13 09:17:18 +01:00
try {
2011-11-27 06:27:50 +01:00
std : : vector < ChatMsgInfo > chatText = connectionSlot - > getChatTextList ( true ) ;
2011-01-13 09:17:18 +01:00
for ( int chatIdx = 0 ;
2013-12-19 08:35:27 +01:00
exitServer = = false & & slots [ index ] ! = NULL & &
2013-11-19 07:14:06 +01:00
chatIdx < ( int ) chatText . size ( ) ; chatIdx + + ) {
2013-12-19 08:35:27 +01:00
connectionSlot = slots [ index ] ;
2011-11-25 22:56:36 +01:00
if ( connectionSlot ! = NULL ) {
2011-11-27 06:27:50 +01:00
ChatMsgInfo msg ( chatText [ chatIdx ] ) ;
2011-01-13 09:17:18 +01:00
this - > addChatInfo ( msg ) ;
string newChatText = msg . chatText . c_str ( ) ;
int newChatTeamIndex = msg . chatTeamIndex ;
int newChatPlayerIndex = msg . chatPlayerIndex ;
2011-04-05 20:39:47 +02:00
string newChatLanguage = msg . targetLanguage ;
2011-01-13 02:46:32 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , newChatText . c_str ( ) , newChatTeamIndex , newChatPlayerIndex ) ;
2011-01-13 02:46:32 +01:00
2013-12-19 08:35:27 +01:00
if ( newChatLanguage = = " " | |
newChatLanguage = = connectionSlot - > getNetworkPlayerLanguage ( ) ) {
2011-04-05 22:19:25 +02:00
NetworkMessageText networkMessageText ( newChatText . c_str ( ) , newChatTeamIndex , newChatPlayerIndex , newChatLanguage ) ;
2013-12-19 08:35:27 +01:00
broadcastMessage ( & networkMessageText , connectionSlot - > getPlayerIndex ( ) , index ) ;
2011-04-05 20:39:47 +02:00
}
2011-01-13 02:46:32 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , newChatText . c_str ( ) , newChatTeamIndex ) ;
2011-11-25 22:56:36 +01:00
}
2011-01-13 02:46:32 +01:00
}
2011-01-13 09:17:18 +01:00
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] index = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , index ) ;
2011-01-13 09:17:18 +01:00
// Its possible that the slot is disconnected here
// so check the original pointer again
2013-12-19 08:35:27 +01:00
if ( slots [ index ] ! = NULL ) {
slots [ index ] - > clearChatInfo ( ) ;
2011-11-27 06:27:50 +01:00
}
2011-01-13 09:17:18 +01:00
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-01-13 09:17:18 +01:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
}
}
}
2011-01-13 02:46:32 +01:00
2012-06-12 22:37:00 +02:00
void ServerInterface : : dispatchPendingMarkCellMessages ( std : : vector < string > & errorMsgList ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2012-06-12 22:37:00 +02:00
if ( connectionSlot ! = NULL & &
connectionSlot - > getMarkedCellList ( false ) . empty ( ) = = false ) {
2013-12-19 08:35:27 +01:00
2012-06-12 22:37:00 +02:00
try {
std : : vector < MarkedCell > chatText = connectionSlot - > getMarkedCellList ( true ) ;
for ( int chatIdx = 0 ;
2013-12-19 08:35:27 +01:00
exitServer = = false & & slots [ index ] ! = NULL & &
2013-11-19 07:14:06 +01:00
chatIdx < ( int ) chatText . size ( ) ; chatIdx + + ) {
2013-12-19 08:35:27 +01:00
connectionSlot = slots [ index ] ;
2012-06-12 22:37:00 +02:00
if ( connectionSlot ! = NULL ) {
MarkedCell msg ( chatText [ chatIdx ] ) ;
this - > addMarkedCell ( msg ) ;
2012-09-21 00:18:10 +02:00
NetworkMessageMarkCell networkMessageMarkCell ( msg . getTargetPos ( ) , msg . getFactionIndex ( ) , msg . getNote ( ) , msg . getPlayerIndex ( ) ) ;
2013-12-19 08:35:27 +01:00
broadcastMessage ( & networkMessageMarkCell , connectionSlot - > getPlayerIndex ( ) , index ) ;
2012-11-02 20:08:55 +01:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
2012-06-12 22:37:00 +02:00
}
}
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] i = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , index ) ;
2012-06-12 22:37:00 +02:00
// Its possible that the slot is disconnected here
// so check the original pointer again
2013-12-19 08:35:27 +01:00
if ( slots [ index ] ! = NULL ) {
slots [ index ] - > clearMarkedCellList ( ) ;
2012-06-12 22:37:00 +02:00
}
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2012-06-12 22:37:00 +02:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
}
}
}
2012-07-13 23:50:34 +02:00
void ServerInterface : : dispatchPendingHighlightCellMessages ( std : : vector < string > & errorMsgList ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2012-07-13 23:50:34 +02:00
if ( connectionSlot ! = NULL & &
connectionSlot - > getHighlightedCellList ( false ) . empty ( ) = = false ) {
2013-12-19 08:35:27 +01:00
2012-07-13 23:50:34 +02:00
try {
std : : vector < MarkedCell > highlightedCells = connectionSlot - > getHighlightedCellList ( true ) ;
for ( int chatIdx = 0 ;
2013-12-19 08:35:27 +01:00
exitServer = = false & & slots [ index ] ! = NULL & &
2013-11-19 07:14:06 +01:00
chatIdx < ( int ) highlightedCells . size ( ) ; chatIdx + + ) {
2013-12-19 08:35:27 +01:00
connectionSlot = slots [ index ] ;
2012-07-13 23:50:34 +02:00
if ( connectionSlot ! = NULL ) {
MarkedCell msg ( highlightedCells [ chatIdx ] ) ;
this - > setHighlightedCell ( msg ) ;
NetworkMessageHighlightCell networkMessageHighlightCell ( msg . getTargetPos ( ) , msg . getFactionIndex ( ) ) ;
2013-12-19 08:35:27 +01:00
broadcastMessage ( & networkMessageHighlightCell , connectionSlot - > getPlayerIndex ( ) , index ) ;
2012-07-13 23:50:34 +02:00
}
}
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] index = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , index ) ;
2012-07-13 23:50:34 +02:00
// Its possible that the slot is disconnected here
// so check the original pointer again
2013-12-19 08:35:27 +01:00
if ( slots [ index ] ! = NULL ) {
slots [ index ] - > clearHighlightedCellList ( ) ;
2012-07-13 23:50:34 +02:00
}
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2012-07-13 23:50:34 +02:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
}
}
}
2012-06-12 22:37:00 +02:00
2012-06-13 18:19:44 +02:00
void ServerInterface : : dispatchPendingUnMarkCellMessages ( std : : vector < string > & errorMsgList ) {
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2012-06-13 18:19:44 +02:00
if ( connectionSlot ! = NULL & &
connectionSlot - > getUnMarkedCellList ( false ) . empty ( ) = = false ) {
2013-12-19 08:35:27 +01:00
2012-06-13 18:19:44 +02:00
try {
std : : vector < UnMarkedCell > chatText = connectionSlot - > getUnMarkedCellList ( true ) ;
for ( int chatIdx = 0 ;
2013-12-19 08:35:27 +01:00
exitServer = = false & & slots [ index ] ! = NULL & &
2013-11-19 07:14:06 +01:00
chatIdx < ( int ) chatText . size ( ) ; chatIdx + + ) {
2013-12-19 08:35:27 +01:00
connectionSlot = slots [ index ] ;
2012-06-13 18:19:44 +02:00
if ( connectionSlot ! = NULL ) {
UnMarkedCell msg ( chatText [ chatIdx ] ) ;
this - > addUnMarkedCell ( msg ) ;
NetworkMessageUnMarkCell networkMessageMarkCell ( msg . getTargetPos ( ) , msg . getFactionIndex ( ) ) ;
2013-12-19 08:35:27 +01:00
broadcastMessage ( & networkMessageMarkCell , connectionSlot - > getPlayerIndex ( ) , index ) ;
2012-11-02 20:08:55 +01:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
2012-06-13 18:19:44 +02:00
}
}
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] i = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , index ) ;
2012-06-13 18:19:44 +02:00
// Its possible that the slot is disconnected here
// so check the original pointer again
2013-12-19 08:35:27 +01:00
if ( slots [ index ] ! = NULL ) {
slots [ index ] - > clearUnMarkedCellList ( ) ;
2012-06-13 18:19:44 +02:00
}
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2012-06-13 18:19:44 +02:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
}
}
}
2014-01-02 22:56:37 +01:00
void ServerInterface : : checkForAutoResumeForLaggingClients ( ) {
2014-01-17 20:32:21 +01:00
if ( gameSettings . getNetworkPauseGameForLaggedClients ( ) = = true & &
this - > clientsAutoPausedDueToLag = = true & &
2014-01-02 22:56:37 +01:00
this - > clientsAutoPausedDueToLagTimer . getMillis ( ) > = MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS ) {
//printf("this->clientsAutoPausedDueToLag: %d [%lld]\n",this->clientsAutoPausedDueToLag,(long long)this->clientsAutoPausedDueToLagTimer.getMillis());
if ( this - > clientLagCallbackInterface ! = NULL ) {
this - > clientsAutoPausedDueToLag = false ;
this - > clientLagCallbackInterface - > clientLagHandler ( - 1 , false ) ;
this - > clientsAutoPausedDueToLagTimer . reset ( ) ;
this - > clientsAutoPausedDueToLagTimer . stop ( ) ;
this - > clientsAutoPausedDueToLagTimer . start ( ) ;
}
}
}
2011-01-13 09:17:18 +01:00
void ServerInterface : : update ( ) {
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- A\n");
2011-01-13 09:17:18 +01:00
std : : vector < string > errorMsgList ;
try {
2010-08-20 22:03:06 +02:00
// The first thing we will do is check all clients to ensure they have
// properly identified themselves within the alloted time period
validateConnectedClients ( ) ;
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- B\n");
2011-01-11 23:09:46 +01:00
processTextMessageQueue ( ) ;
2011-01-12 01:16:50 +01:00
processBroadCastMessageQueue ( ) ;
2011-01-11 23:09:46 +01:00
2014-01-02 22:56:37 +01:00
checkForAutoResumeForLaggingClients ( ) ;
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- C\n");
2011-11-25 22:56:36 +01:00
std : : map < PLATFORM_SOCKET , bool > socketTriggeredList ;
2010-07-01 02:08:59 +02:00
//update all slots
2011-11-25 22:56:36 +01:00
updateSocketTriggeredList ( socketTriggeredList ) ;
2010-05-15 20:59:17 +02:00
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- D\n");
2013-02-15 19:25:10 +01:00
if ( gameHasBeenInitiated = = false | |
socketTriggeredList . empty ( ) = = false ) {
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- E\n");
2011-11-25 22:56:36 +01:00
std : : map < int , ConnectionSlotEvent > eventList ;
2013-06-04 02:31:41 +02:00
bool hasData = false ;
if ( gameHasBeenInitiated = = false ) {
hasData = Socket : : hasDataToRead ( socketTriggeredList ) ;
}
else {
hasData = true ;
}
2013-12-19 08:35:27 +01:00
if ( hasData & & SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] hasData == true \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2010-03-17 07:25:19 +01:00
2013-03-01 07:52:33 +01:00
if ( gameHasBeenInitiated = = false | | hasData = = true ) {
2013-03-02 08:33:01 +01:00
//printf("START Server update #2\n");
2011-11-25 22:56:36 +01:00
std : : map < int , bool > mapSlotSignalledList ;
2010-06-29 08:50:35 +02:00
2010-07-01 02:08:59 +02:00
// Step #1 tell all connection slot worker threads to receive socket data
2014-01-02 22:56:37 +01:00
if ( gameHasBeenInitiated = = false ) {
signalClientsToRecieveData ( socketTriggeredList , eventList , mapSlotSignalledList ) ;
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ============ Step #2 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-07-01 02:08:59 +02:00
2013-03-02 08:33:01 +01:00
//printf("START Server update #2\n");
2013-02-26 08:05:46 +01:00
if ( gameHasBeenInitiated = = false | | hasData = = true ) {
2013-03-02 08:33:01 +01:00
//printf("START Server update #3\n");
2013-02-26 08:05:46 +01:00
// Step #2 check all connection slot worker threads for completed status
2013-12-19 08:35:27 +01:00
if ( gameHasBeenInitiated = = false ) {
checkForCompletedClients ( mapSlotSignalledList , errorMsgList , eventList ) ;
}
2013-02-26 08:05:46 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ============ Step #3 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-08-07 05:26:38 +02:00
2013-03-02 08:33:01 +01:00
//printf("START Server update #4\n");
2013-02-26 08:05:46 +01:00
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
2013-12-19 08:35:27 +01:00
2013-02-26 08:05:46 +01:00
// Step #3 check clients for any lagging scenarios and try to deal with them
2013-12-19 08:35:27 +01:00
if ( gameHasBeenInitiated = = false ) {
checkForLaggingClients ( mapSlotSignalledList , eventList , socketTriggeredList , errorMsgList ) ;
}
2013-02-26 08:05:46 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ============ Step #4 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-06-29 08:50:35 +02:00
2013-03-02 08:33:01 +01:00
//printf("START Server update #5\n");
2013-02-26 08:05:46 +01:00
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #4 dispatch network commands to the pending list so that they are done in proper order
executeNetworkCommandsFromClients ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ============ Step #5 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-05-15 20:59:17 +02:00
2013-03-02 08:33:01 +01:00
//printf("START Server update #6\n");
2013-02-26 08:05:46 +01:00
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #5 dispatch pending chat messages
dispatchPendingChatMessages ( errorMsgList ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-02-15 04:32:14 +01:00
2013-02-26 08:05:46 +01:00
dispatchPendingMarkCellMessages ( errorMsgList ) ;
dispatchPendingUnMarkCellMessages ( errorMsgList ) ;
2012-06-12 22:37:00 +02:00
2013-02-26 08:05:46 +01:00
dispatchPendingHighlightCellMessages ( errorMsgList ) ;
2013-03-02 08:33:01 +01:00
2013-06-04 23:55:16 +02:00
if ( gameHasBeenInitiated = = true & &
2013-12-19 08:35:27 +01:00
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD & &
difftime ( ( long int ) time ( NULL ) , lastGlobalLagCheckTime ) > = LAG_CHECK_INTERVAL_PERIOD ) {
2013-06-19 02:01:29 +02:00
2013-06-04 23:55:16 +02:00
std : : map < int , bool > mapSlotSignalledList ;
checkForLaggingClients ( mapSlotSignalledList , eventList , socketTriggeredList , errorMsgList ) ;
}
2013-03-02 08:33:01 +01:00
//printf("START Server update #7\n");
2013-02-26 08:05:46 +01:00
}
else if ( gameHasBeenInitiated = = true & &
2013-06-19 02:01:29 +02:00
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD & &
difftime ( ( long int ) time ( NULL ) , lastGlobalLagCheckTime ) > = LAG_CHECK_INTERVAL_PERIOD ) {
2013-02-26 08:05:46 +01:00
//printf("Skip network data process because hasData == false\n");
2013-03-02 08:33:01 +01:00
//printf("START Server update #8\n");
2013-02-26 08:05:46 +01:00
std : : map < int , bool > mapSlotSignalledList ;
checkForLaggingClients ( mapSlotSignalledList , eventList , socketTriggeredList , errorMsgList ) ;
}
2013-03-02 08:33:01 +01:00
//printf("START Server update #9\n");
2010-07-01 02:08:59 +02:00
}
2011-11-25 22:56:36 +01:00
else if ( gameHasBeenInitiated = = true & &
2013-06-19 02:01:29 +02:00
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD & &
difftime ( ( long int ) time ( NULL ) , lastGlobalLagCheckTime ) > = LAG_CHECK_INTERVAL_PERIOD ) {
2011-11-25 22:56:36 +01:00
//printf("\nServerInterface::update -- E1\n");
2013-03-02 08:33:01 +01:00
//printf("START Server update #10\n");
2011-11-25 22:56:36 +01:00
2011-11-27 06:27:50 +01:00
std : : map < int , bool > mapSlotSignalledList ;
checkForLaggingClients ( mapSlotSignalledList , eventList , socketTriggeredList , errorMsgList ) ;
2011-11-25 22:56:36 +01:00
}
2013-03-02 08:33:01 +01:00
//printf("START Server update #11\n");
2010-07-01 02:08:59 +02:00
}
2011-11-25 22:56:36 +01:00
else if ( gameHasBeenInitiated = = true & &
2013-06-19 02:01:29 +02:00
difftime ( ( long int ) time ( NULL ) , gameStartTime ) > = LAG_CHECK_GRACE_PERIOD & &
difftime ( ( long int ) time ( NULL ) , lastGlobalLagCheckTime ) > = LAG_CHECK_INTERVAL_PERIOD ) {
2011-11-25 22:56:36 +01:00
//printf("\nServerInterface::update -- F\n");
2013-03-02 08:33:01 +01:00
//printf("START Server update #12\n");
2011-11-27 06:27:50 +01:00
std : : map < int , ConnectionSlotEvent > eventList ;
std : : map < int , bool > mapSlotSignalledList ;
checkForLaggingClients ( mapSlotSignalledList , eventList , socketTriggeredList , errorMsgList ) ;
2011-11-25 22:56:36 +01:00
}
2013-03-02 08:33:01 +01:00
//printf("START Server update #13\n");
2012-03-03 05:33:39 +01:00
// Check if we need to switch masterserver admin to a new player because original admin disconnected
2013-12-19 08:35:27 +01:00
if ( gameHasBeenInitiated = = true & &
this - > gameSettings . getMasterserver_admin ( ) > 0 ) {
2013-03-01 07:52:33 +01:00
2013-12-19 08:35:27 +01:00
bool foundAdminSlot = false ;
2012-03-03 05:33:39 +01:00
int iFirstConnectedSlot = - 1 ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
if ( slots [ index ] ! = NULL & & slots [ index ] - > isConnected ( ) = = true ) {
2012-03-03 05:33:39 +01:00
if ( iFirstConnectedSlot < 0 ) {
2013-12-19 08:35:27 +01:00
iFirstConnectedSlot = index ;
2012-03-03 05:33:39 +01:00
}
2013-12-19 08:35:27 +01:00
if ( this - > gameSettings . getMasterserver_admin ( ) = = slots [ index ] - > getSessionKey ( ) ) {
2012-03-03 05:33:39 +01:00
foundAdminSlot = true ;
break ;
}
}
}
if ( foundAdminSlot = = false & & iFirstConnectedSlot > = 0 ) {
printf ( " Switching masterserver admin to slot#%d... \n " , iFirstConnectedSlot ) ;
2012-12-19 20:55:49 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ iFirstConnectedSlot ] , CODE_AT_LINE_X ( iFirstConnectedSlot ) ) ;
if ( slots [ iFirstConnectedSlot ] ! = NULL ) {
string sMsg = " Switching player to admin mode: " + slots [ iFirstConnectedSlot ] - > getName ( ) ;
sendTextMessage ( sMsg , - 1 , true , " " ) ;
2012-03-03 05:33:39 +01:00
2012-12-19 20:55:49 +01:00
this - > gameSettings . setMasterserver_admin ( slots [ iFirstConnectedSlot ] - > getSessionKey ( ) ) ;
this - > gameSettings . setMasterserver_admin_faction_index ( slots [ iFirstConnectedSlot ] - > getPlayerIndex ( ) ) ;
2012-06-22 16:30:48 +02:00
2012-12-19 20:55:49 +01:00
safeMutexSlot . ReleaseLock ( ) ;
this - > broadcastGameSetup ( & this - > gameSettings ) ;
}
2012-03-03 05:33:39 +01:00
}
}
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- G\n");
2013-03-02 08:33:01 +01:00
//printf("START Server update #14\n");
2013-02-16 20:11:36 +01:00
checkListenerSlots ( ) ;
2013-03-01 07:52:33 +01:00
2013-03-02 08:33:01 +01:00
//printf("START Server update #15\n");
2010-07-01 02:08:59 +02:00
}
catch ( const exception & ex ) {
2011-05-18 23:14:14 +02:00
//printf("\nServerInterface::update -- H\n");
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-07-01 02:08:59 +02:00
errorMsgList . push_back ( ex . what ( ) ) ;
}
2013-12-19 08:35:27 +01:00
2011-09-01 03:11:23 +02:00
if ( errorMsgList . empty ( ) = = false ) {
2013-12-19 08:35:27 +01:00
for ( int iErrIdx = 0 ; iErrIdx < ( int ) errorMsgList . size ( ) ; + + iErrIdx ) {
string & sErr = errorMsgList [ iErrIdx ] ;
if ( sErr ! = " " ) {
2011-01-13 09:17:18 +01:00
DisplayErrorMessage ( sErr ) ;
}
}
}
}
void ServerInterface : : updateKeyframe ( int frameCount ) {
currentFrameCount = frameCount ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , currentFrameCount , requestedCommands . size ( ) ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
NetworkMessageCommandList networkMessageCommandList ( frameCount ) ;
2013-09-12 05:33:43 +02:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
networkMessageCommandList . setNetworkPlayerFactionCRC ( index , this - > getNetworkPlayerFactionCRC ( index ) ) ;
}
2012-03-20 05:53:26 +01:00
2011-01-13 09:17:18 +01:00
while ( requestedCommands . empty ( ) = = false ) {
2014-01-02 22:56:37 +01:00
// First add the command to the broadcast list (for all clients)
2011-03-28 05:54:23 +02:00
if ( networkMessageCommandList . addCommand ( & requestedCommands . back ( ) ) ) {
2014-01-02 22:56:37 +01:00
// Add the command to the local server command list
2011-01-13 09:17:18 +01:00
pendingCommands . push_back ( requestedCommands . back ( ) ) ;
requestedCommands . pop_back ( ) ;
}
else {
break ;
}
}
try {
2010-06-30 09:03:04 +02:00
// Possible cause of out of synch since we have more commands that need
// to be sent in this frame
2011-01-02 01:39:13 +01:00
if ( requestedCommands . empty ( ) = = false ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , requestedCommands . size ( ) ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , requestedCommands . size ( ) ) ;
2010-06-05 02:00:36 +02:00
2010-08-21 15:04:52 +02:00
string sMsg = " may go out of synch: server requestedCommands.size() = " + intToStr ( requestedCommands . size ( ) ) ;
2011-04-05 20:39:47 +02:00
sendTextMessage ( sMsg , - 1 , true , " " ) ;
2010-06-30 09:03:04 +02:00
}
2010-06-05 02:00:36 +02:00
2014-01-04 00:10:30 +01:00
// broadcast commands
// If we have more than 0 commands to send, automatically broadcast them
bool sendBroadcastMessage = ( networkMessageCommandList . getCommandCount ( ) > 0 ) ;
if ( sendBroadcastMessage = = false ) {
2013-03-02 08:33:01 +01:00
2014-01-04 00:10:30 +01:00
// Is auto pause due to lag NOT enabled
if ( this - > getClientsAutoPausedDueToLag ( ) = = false ) {
// ****NOTE:
// We always need to broadcast when not pause as clients
// look for broadcasts every network frame.
sendBroadcastMessage = true ;
}
// Auto pause is enabled due to client lagging, only send empty command
// broadcasts every MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS
else if ( this - > getClientsAutoPausedDueToLag ( ) = = true & &
( lastBroadcastCommandsTimer . isStarted ( ) = = false | |
lastBroadcastCommandsTimer . getMillis ( ) > = MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS ) ) {
sendBroadcastMessage = true ;
}
}
if ( sendBroadcastMessage = = true ) {
2014-01-02 22:56:37 +01:00
if ( lastBroadcastCommandsTimer . isStarted ( ) = = false ) {
lastBroadcastCommandsTimer . start ( ) ;
}
else {
lastBroadcastCommandsTimer . stop ( ) ;
lastBroadcastCommandsTimer . reset ( ) ;
lastBroadcastCommandsTimer . start ( ) ;
}
broadcastMessage ( & networkMessageCommandList ) ;
}
2010-06-30 09:03:04 +02:00
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-06-30 09:03:04 +02:00
DisplayErrorMessage ( ex . what ( ) ) ;
}
2011-01-13 09:17:18 +01:00
}
2010-04-15 03:19:00 +02:00
2013-12-19 08:35:27 +01:00
bool ServerInterface : : shouldDiscardNetworkMessage ( NetworkMessageType networkMessageType ,
ConnectionSlot * connectionSlot ) {
2011-01-13 09:17:18 +01:00
bool discard = false ;
if ( connectionSlot ! = NULL ) {
2010-05-04 04:32:43 +02:00
switch ( networkMessageType ) {
case nmtIntro :
{
discard = true ;
NetworkMessageIntro msg = NetworkMessageIntro ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
2010-07-09 17:01:49 +02:00
case nmtPing :
{
discard = true ;
NetworkMessagePing msg = NetworkMessagePing ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
2010-07-09 19:12:57 +02:00
lastPingInfo = msg ;
2010-07-09 17:01:49 +02:00
}
break ;
2010-05-04 04:32:43 +02:00
case nmtLaunch :
{
discard = true ;
NetworkMessageLaunch msg = NetworkMessageLaunch ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtText :
{
discard = true ;
2010-07-06 07:30:34 +02:00
NetworkMessageText netMsg = NetworkMessageText ( ) ;
connectionSlot - > receiveMessage ( & netMsg ) ;
2011-04-05 20:39:47 +02:00
ChatMsgInfo msg ( netMsg . getText ( ) . c_str ( ) , netMsg . getTeamIndex ( ) , netMsg . getPlayerIndex ( ) , netMsg . getTargetLanguage ( ) ) ;
2011-01-13 09:17:18 +01:00
this - > addChatInfo ( msg ) ;
2010-08-27 22:09:55 +02:00
string newChatText = msg . chatText . c_str ( ) ;
2010-10-23 06:00:39 +02:00
//string newChatSender = msg.chatSender.c_str();
2010-08-27 22:09:55 +02:00
int newChatTeamIndex = msg . chatTeamIndex ;
2010-10-22 09:28:55 +02:00
int newChatPlayerIndex = msg . chatPlayerIndex ;
2011-04-05 20:39:47 +02:00
string newChatLanguage = msg . targetLanguage . c_str ( ) ;
2010-08-27 22:09:55 +02:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , newChatText . c_str ( ) , newChatTeamIndex , newChatPlayerIndex ) ;
2010-08-27 22:09:55 +02:00
2011-04-05 20:39:47 +02:00
NetworkMessageText networkMessageText ( newChatText . c_str ( ) , newChatTeamIndex , newChatPlayerIndex , newChatLanguage ) ;
2010-08-27 22:09:55 +02:00
broadcastMessage ( & networkMessageText , connectionSlot - > getPlayerIndex ( ) ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , newChatText . c_str ( ) , newChatTeamIndex ) ;
2010-08-27 22:09:55 +02:00
2010-05-04 04:32:43 +02:00
}
break ;
2012-06-12 22:37:00 +02:00
case nmtMarkCell :
{
discard = true ;
NetworkMessageMarkCell networkMessageMarkCell ;
connectionSlot - > receiveMessage ( & networkMessageMarkCell ) ;
MarkedCell msg ( networkMessageMarkCell . getTarget ( ) ,
networkMessageMarkCell . getFactionIndex ( ) ,
2012-09-21 00:18:10 +02:00
networkMessageMarkCell . getText ( ) . c_str ( ) ,
networkMessageMarkCell . getPlayerIndex ( ) ) ;
2012-06-12 22:37:00 +02:00
this - > addMarkedCell ( msg ) ;
NetworkMessageMarkCell networkMessageMarkCellBroadcast (
networkMessageMarkCell . getTarget ( ) ,
networkMessageMarkCell . getFactionIndex ( ) ,
2012-09-21 00:18:10 +02:00
networkMessageMarkCell . getText ( ) . c_str ( ) ,
networkMessageMarkCell . getPlayerIndex ( ) ) ;
2012-06-12 22:37:00 +02:00
broadcastMessage ( & networkMessageMarkCellBroadcast , connectionSlot - > getPlayerIndex ( ) ) ;
2012-11-02 20:08:55 +01:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
2012-06-12 22:37:00 +02:00
}
break ;
2012-06-13 18:19:44 +02:00
case nmtUnMarkCell :
{
discard = true ;
NetworkMessageUnMarkCell networkMessageMarkCell ;
connectionSlot - > receiveMessage ( & networkMessageMarkCell ) ;
UnMarkedCell msg ( networkMessageMarkCell . getTarget ( ) ,
networkMessageMarkCell . getFactionIndex ( ) ) ;
this - > addUnMarkedCell ( msg ) ;
NetworkMessageUnMarkCell networkMessageMarkCellBroadcast (
networkMessageMarkCell . getTarget ( ) ,
networkMessageMarkCell . getFactionIndex ( ) ) ;
broadcastMessage ( & networkMessageMarkCellBroadcast , connectionSlot - > getPlayerIndex ( ) ) ;
2012-11-02 20:08:55 +01:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
2012-06-13 18:19:44 +02:00
2012-07-13 23:50:34 +02:00
}
break ;
case nmtHighlightCell :
{
discard = true ;
NetworkMessageHighlightCell networkMessageHighlightCell ;
connectionSlot - > receiveMessage ( & networkMessageHighlightCell ) ;
MarkedCell msg ( networkMessageHighlightCell . getTarget ( ) ,
networkMessageHighlightCell . getFactionIndex ( ) ,
2012-09-21 00:18:10 +02:00
" none " , - 1 ) ;
2012-07-13 23:50:34 +02:00
this - > setHighlightedCell ( msg ) ;
NetworkMessageHighlightCell networkMessageHighlightCellBroadcast (
networkMessageHighlightCell . getTarget ( ) ,
networkMessageHighlightCell . getFactionIndex ( ) ) ;
broadcastMessage ( & networkMessageHighlightCellBroadcast , connectionSlot - > getPlayerIndex ( ) ) ;
2012-11-02 20:08:55 +01:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatTeamIndex);
2012-07-13 23:50:34 +02:00
2012-06-13 18:19:44 +02:00
}
break ;
2010-05-04 04:32:43 +02:00
case nmtSynchNetworkGameData :
{
discard = true ;
NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtSynchNetworkGameDataStatus :
{
discard = true ;
NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtSynchNetworkGameDataFileCRCCheck :
{
discard = true ;
NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtSynchNetworkGameDataFileGet :
{
discard = true ;
NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtSwitchSetupRequest :
{
discard = true ;
SwitchSetupRequest msg = SwitchSetupRequest ( ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
case nmtPlayerIndexMessage :
{
discard = true ;
PlayerIndexMessage msg = PlayerIndexMessage ( 0 ) ;
connectionSlot - > receiveMessage ( & msg ) ;
}
break ;
}
}
2011-01-13 09:17:18 +01:00
return discard ;
}
void ServerInterface : : waitUntilReady ( Checksum * checksum ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s] START \n " , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
Logger & logger = Logger : : getInstance ( ) ;
gameHasBeenInitiated = true ;
Chrono chrono ;
chrono . start ( ) ;
bool allReady = false ;
2011-03-31 20:30:53 +02:00
if ( Config : : getInstance ( ) . getBool ( " EnableGameServerLoadCancel " , " false " ) = = true ) {
logger . setCancelLoadingEnabled ( true ) ;
}
2011-03-31 20:13:02 +02:00
2013-12-19 08:35:27 +01:00
Lang & lang = Lang : : getInstance ( ) ;
uint64 waitLoopIterationCount = 0 ;
uint64 MAX_LOOP_COUNT_BEFORE_SLEEP = 10 ;
MAX_LOOP_COUNT_BEFORE_SLEEP = Config : : getInstance ( ) . getInt ( " NetworkServerLoopGameLoadingCap " , intToStr ( MAX_LOOP_COUNT_BEFORE_SLEEP ) . c_str ( ) ) ;
2013-12-14 08:04:12 +01:00
if ( MAX_LOOP_COUNT_BEFORE_SLEEP = = 0 ) {
MAX_LOOP_COUNT_BEFORE_SLEEP = 1 ;
}
2013-12-19 08:35:27 +01:00
int sleepMillis = Config : : getInstance ( ) . getInt ( " NetworkServerLoopGameLoadingCapSleepMillis " , " 10 " ) ;
int64 lastStatusUpdate = 0 ;
2011-11-15 17:41:10 +01:00
2013-12-19 08:35:27 +01:00
while ( exitServer = = false & &
allReady = = false & &
logger . getCancelLoading ( ) = = false ) {
2013-05-18 07:57:22 +02:00
2011-11-14 06:18:09 +01:00
waitLoopIterationCount + + ;
2013-12-19 08:35:27 +01:00
if ( waitLoopIterationCount > 0 & &
waitLoopIterationCount % MAX_LOOP_COUNT_BEFORE_SLEEP = = 0 ) {
2011-11-15 17:41:10 +01:00
sleep ( sleepMillis ) ;
2011-11-14 06:18:09 +01:00
waitLoopIterationCount = 0 ;
}
2011-01-13 09:17:18 +01:00
vector < string > waitingForHosts ;
2010-03-17 07:25:19 +01:00
allReady = true ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2010-05-04 04:32:43 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
if ( connectionSlot - > isReady ( ) = = false ) {
2013-12-19 08:35:27 +01:00
2011-11-25 22:56:36 +01:00
NetworkMessageType networkMessageType = connectionSlot - > getNextMessageType ( ) ;
2010-03-17 07:25:19 +01:00
2010-05-04 04:32:43 +02:00
// consume old messages from the lobby
bool discarded = shouldDiscardNetworkMessage ( networkMessageType , connectionSlot ) ;
if ( discarded = = false ) {
2013-12-19 08:35:27 +01:00
2010-05-04 04:32:43 +02:00
NetworkMessageReady networkMessageReady ;
if ( networkMessageType = = nmtReady & &
connectionSlot - > receiveMessage ( & networkMessageReady ) ) {
2013-12-19 08:35:27 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s] networkMessageType==nmtReady \n " , __FUNCTION__ ) ;
2010-05-04 04:32:43 +02:00
connectionSlot - > setReady ( ) ;
2013-06-04 02:31:41 +02:00
connectionSlot - > setGameStarted ( true ) ;
2010-05-04 04:32:43 +02:00
}
else if ( networkMessageType ! = nmtInvalid ) {
string sErr = " Unexpected network message: " + intToStr ( networkMessageType ) ;
2013-12-19 08:35:27 +01:00
sendTextMessage ( sErr , - 1 , true , " " , index ) ;
2010-05-04 04:32:43 +02:00
DisplayErrorMessage ( sErr ) ;
2011-03-31 20:13:02 +02:00
logger . setCancelLoading ( false ) ;
2010-05-04 04:32:43 +02:00
return ;
}
2010-03-17 07:25:19 +01:00
}
2010-04-30 04:34:19 +02:00
waitingForHosts . push_back ( connectionSlot - > getName ( ) ) ;
2010-03-17 07:25:19 +01:00
allReady = false ;
}
}
}
//check for timeout
2010-05-04 04:32:43 +02:00
if ( allReady = = false ) {
2011-01-13 09:17:18 +01:00
if ( chrono . getMillis ( ) > readyWaitTimeout ) {
2011-04-05 20:39:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
const vector < string > languageList = this - > gameSettings . getUniqueNetworkPlayerLanguages ( ) ;
2013-12-19 08:35:27 +01:00
for ( unsigned int langIndex = 0 ; langIndex < languageList . size ( ) ; + + langIndex ) {
2011-04-05 20:39:47 +02:00
string sErr = " Timeout waiting for clients. " ;
if ( lang . hasString ( " TimeoutWaitingForClients " ) = = true ) {
2013-12-19 08:35:27 +01:00
sErr = lang . getString ( " TimeoutWaitingForClients " , languageList [ langIndex ] ) ;
2011-04-05 20:39:47 +02:00
}
2013-12-19 08:35:27 +01:00
bool localEcho = lang . isLanguageLocal ( languageList [ langIndex ] ) ;
sendTextMessage ( sErr , - 1 , localEcho , languageList [ langIndex ] ) ;
2011-04-05 20:39:47 +02:00
if ( localEcho = = true ) {
DisplayErrorMessage ( sErr ) ;
}
}
2011-03-31 20:13:02 +02:00
logger . setCancelLoading ( false ) ;
2011-01-13 09:17:18 +01:00
return ;
}
else {
2013-05-18 07:57:22 +02:00
if ( chrono . getMillis ( ) - lastStatusUpdate > 200 ) {
lastStatusUpdate = chrono . getMillis ( ) ;
2011-01-13 09:17:18 +01:00
string waitForHosts = " " ;
2013-12-19 08:35:27 +01:00
for ( int hostIndex = 0 ; hostIndex < ( int ) waitingForHosts . size ( ) ; hostIndex + + ) {
2011-01-13 09:17:18 +01:00
if ( waitForHosts ! = " " ) {
waitForHosts + = " , " ;
}
2013-12-19 08:35:27 +01:00
waitForHosts + = waitingForHosts [ hostIndex ] ;
2011-01-13 09:17:18 +01:00
}
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-10-29 07:13:38 +01:00
string updateTextFormat = lang . getString ( " NetworkGameServerLoadStatus " ) ;
2013-12-19 08:35:27 +01:00
if ( updateTextFormat = = " " | |
updateTextFormat [ 0 ] = = ' ? ' ) {
2011-03-31 20:13:02 +02:00
updateTextFormat = " Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds) " ;
}
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 8096 , updateTextFormat . c_str ( ) , ( long long int ) ( chrono . getMillis ( ) / 1000 ) , int ( readyWaitTimeout / 1000 ) ) ;
2011-03-31 20:13:02 +02:00
2012-10-19 03:31:20 +02:00
char szBuf1 [ 8096 ] = " " ;
2013-10-29 07:13:38 +01:00
string statusTextFormat = lang . getString ( " NetworkGameStatusWaiting " ) ;
2013-12-19 08:35:27 +01:00
if ( statusTextFormat = = " " | |
statusTextFormat [ 0 ] = = ' ? ' ) {
2011-03-31 20:13:02 +02:00
statusTextFormat = " Waiting for players: %s " ;
}
2012-10-19 03:31:20 +02:00
snprintf ( szBuf1 , 8096 , statusTextFormat . c_str ( ) , waitForHosts . c_str ( ) ) ;
2011-03-31 20:13:02 +02:00
logger . add ( szBuf , true , szBuf1 ) ;
uint32 loadingStatus = nmls_NONE ;
//send ready message after, so clients start delayed
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-03-31 20:13:02 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
2013-12-19 08:35:27 +01:00
switch ( slotIndex ) {
2011-03-31 20:13:02 +02:00
case 0 :
loadingStatus | = nmls_PLAYER1_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER1_READY ;
}
break ;
case 1 :
loadingStatus | = nmls_PLAYER2_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER2_READY ;
}
break ;
case 2 :
loadingStatus | = nmls_PLAYER3_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER3_READY ;
}
break ;
case 3 :
loadingStatus | = nmls_PLAYER4_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER4_READY ;
}
break ;
case 4 :
loadingStatus | = nmls_PLAYER5_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER5_READY ;
}
break ;
case 5 :
loadingStatus | = nmls_PLAYER6_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER6_READY ;
}
break ;
case 6 :
loadingStatus | = nmls_PLAYER7_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER7_READY ;
}
break ;
case 7 :
loadingStatus | = nmls_PLAYER8_CONNECTED ;
if ( connectionSlot - > isReady ( ) ) {
loadingStatus | = nmls_PLAYER8_READY ;
}
break ;
}
}
}
// send loading status message
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-03-31 20:13:02 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
NetworkMessageLoadingStatus networkMessageLoadingStatus ( loadingStatus ) ;
connectionSlot - > sendMessage ( & networkMessageLoadingStatus ) ;
}
}
2012-04-14 23:21:09 +02:00
sleep ( 0 ) ;
2011-01-13 09:17:18 +01:00
}
}
2010-03-17 07:25:19 +01:00
}
2011-01-20 09:19:14 +01:00
2012-09-22 22:13:57 +02:00
Shared : : Platform : : Window : : handleEvent ( ) ;
2010-03-17 07:25:19 +01:00
}
2011-03-31 20:13:02 +02:00
if ( logger . getCancelLoading ( ) = = true ) {
2011-04-05 20:39:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
const vector < string > languageList = this - > gameSettings . getUniqueNetworkPlayerLanguages ( ) ;
2013-12-19 08:35:27 +01:00
for ( unsigned int langIndex = 0 ; langIndex < languageList . size ( ) ; + + langIndex ) {
string sErr = lang . getString ( " GameCancelledByUser " , languageList [ langIndex ] ) ;
bool localEcho = lang . isLanguageLocal ( languageList [ langIndex ] ) ;
sendTextMessage ( sErr , - 1 , localEcho , languageList [ langIndex ] ) ;
2011-04-05 20:39:47 +02:00
if ( localEcho = = true ) {
DisplayErrorMessage ( sErr ) ;
}
}
2011-03-31 20:13:02 +02:00
quitGame ( true ) ;
logger . setCancelLoading ( false ) ;
return ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s] PART B (telling client we are ready! \n " , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
try {
2010-06-30 09:03:04 +02:00
//send ready message after, so clients start delayed
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2010-06-30 09:03:04 +02:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = true ) {
NetworkMessageReady networkMessageReady ( checksum - > getSum ( ) ) ;
connectionSlot - > sendMessage ( & networkMessageReady ) ;
2013-06-04 02:31:41 +02:00
connectionSlot - > setGameStarted ( true ) ;
2010-06-30 09:03:04 +02:00
}
2010-03-17 07:25:19 +01:00
}
2010-06-30 09:03:04 +02:00
gameStartTime = time ( NULL ) ;
2011-01-13 09:17:18 +01:00
}
2010-06-30 09:03:04 +02:00
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error detected [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-06-30 09:03:04 +02:00
DisplayErrorMessage ( ex . what ( ) ) ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s] END \n " , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
}
void ServerInterface : : processBroadCastMessageQueue ( ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlot ( broadcastMessageQueueThreadAccessor , CODE_AT_LINE ) ;
2011-09-01 03:11:23 +02:00
if ( broadcastMessageQueue . empty ( ) = = false ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] broadcastMessageQueue.size() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , broadcastMessageQueue . size ( ) ) ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < ( int ) broadcastMessageQueue . size ( ) ; + + index ) {
pair < NetworkMessage * , int > & item = broadcastMessageQueue [ index ] ;
if ( item . first ! = NULL ) {
this - > broadcastMessage ( item . first , item . second ) ;
delete item . first ;
}
item . first = NULL ;
2011-01-13 09:17:18 +01:00
}
2013-12-19 08:35:27 +01:00
broadcastMessageQueue . clear ( ) ;
2011-01-13 09:17:18 +01:00
}
}
2012-11-01 01:06:23 +01:00
void ServerInterface : : queueBroadcastMessage ( NetworkMessage * networkMessage , int excludeSlot ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlot ( broadcastMessageQueueThreadAccessor , CODE_AT_LINE ) ;
2012-11-01 01:06:23 +01:00
pair < NetworkMessage * , int > item ;
2013-12-19 08:35:27 +01:00
item . first = networkMessage ;
2011-01-13 09:17:18 +01:00
item . second = excludeSlot ;
broadcastMessageQueue . push_back ( item ) ;
}
void ServerInterface : : processTextMessageQueue ( ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlot ( textMessageQueueThreadAccessor , CODE_AT_LINE ) ;
2011-09-01 03:11:23 +02:00
if ( textMessageQueue . empty ( ) = = false ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] textMessageQueue.size() = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , textMessageQueue . size ( ) ) ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < ( int ) textMessageQueue . size ( ) ; + + index ) {
TextMessageQueue & item = textMessageQueue [ index ] ;
2011-04-05 20:39:47 +02:00
sendTextMessage ( item . text , item . teamIndex , item . echoLocal , item . targetLanguage ) ;
2011-03-28 05:54:23 +02:00
}
textMessageQueue . clear ( ) ;
2011-01-13 09:17:18 +01:00
}
}
2011-04-05 20:39:47 +02:00
void ServerInterface : : queueTextMessage ( const string & text , int teamIndex ,
bool echoLocal , string targetLanguage ) {
2011-11-29 06:07:18 +01:00
//printf("Line: %d text [%s]\n",__LINE__,text.c_str());
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlot ( textMessageQueueThreadAccessor , CODE_AT_LINE ) ;
2011-01-13 09:17:18 +01:00
TextMessageQueue item ;
2013-12-19 08:35:27 +01:00
item . text = text ;
item . teamIndex = teamIndex ;
item . echoLocal = echoLocal ;
2011-04-05 20:39:47 +02:00
item . targetLanguage = targetLanguage ;
2011-01-13 09:17:18 +01:00
textMessageQueue . push_back ( item ) ;
}
2011-04-05 20:39:47 +02:00
void ServerInterface : : sendTextMessage ( const string & text , int teamIndex ,
bool echoLocal , string targetLanguage ) {
sendTextMessage ( text , teamIndex , echoLocal , targetLanguage , - 1 ) ;
2011-01-13 09:17:18 +01:00
}
2011-04-05 20:39:47 +02:00
void ServerInterface : : sendTextMessage ( const string & text , int teamIndex , bool echoLocal ,
string targetLanguage , int lockedSlotIndex ) {
2011-11-29 06:07:18 +01:00
//printf("Line: %d text [%s] echoLocal = %d\n",__LINE__,text.c_str(),echoLocal);
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] text [%s] teamIndex = %d, echoLocal = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , text . c_str ( ) , teamIndex , echoLocal , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2011-04-05 20:39:47 +02:00
NetworkMessageText networkMessageText ( text , teamIndex , getHumanPlayerIndex ( ) , targetLanguage ) ;
2011-01-13 09:17:18 +01:00
broadcastMessage ( & networkMessageText , - 1 , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
if ( echoLocal = = true ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-07-01 08:11:14 +02:00
2011-04-05 20:39:47 +02:00
ChatMsgInfo msg ( text . c_str ( ) , teamIndex , networkMessageText . getPlayerIndex ( ) , targetLanguage ) ;
2010-07-01 02:08:59 +02:00
this - > addChatInfo ( msg ) ;
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
2012-09-21 00:18:10 +02:00
void ServerInterface : : sendMarkCellMessage ( Vec2i targetPos , int factionIndex , string note , int playerIndex ) {
sendMarkCellMessage ( targetPos , factionIndex , note , playerIndex , - 1 ) ;
2012-06-12 22:37:00 +02:00
}
2012-09-21 00:18:10 +02:00
void ServerInterface : : sendMarkCellMessage ( Vec2i targetPos , int factionIndex , string note , int playerIndex , int lockedSlotIndex ) {
NetworkMessageMarkCell networkMessageMarkCell ( targetPos , factionIndex , note , playerIndex ) ;
2012-06-12 22:37:00 +02:00
broadcastMessage ( & networkMessageMarkCell , - 1 , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2012-06-12 22:37:00 +02:00
}
2012-07-13 23:50:34 +02:00
void ServerInterface : : sendHighlightCellMessage ( Vec2i targetPos , int factionIndex ) {
sendHighlightCellMessage ( targetPos , factionIndex , - 1 ) ;
}
void ServerInterface : : sendHighlightCellMessage ( Vec2i targetPos , int factionIndex , int lockedSlotIndex ) {
NetworkMessageHighlightCell networkMessageHighlightCell ( targetPos , factionIndex ) ;
broadcastMessage ( & networkMessageHighlightCell , - 1 , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2012-07-13 23:50:34 +02:00
}
2012-06-13 18:19:44 +02:00
void ServerInterface : : sendUnMarkCellMessage ( Vec2i targetPos , int factionIndex ) {
sendUnMarkCellMessage ( targetPos , factionIndex , - 1 ) ;
}
void ServerInterface : : sendUnMarkCellMessage ( Vec2i targetPos , int factionIndex , int lockedSlotIndex ) {
NetworkMessageUnMarkCell networkMessageMarkCell ( targetPos , factionIndex ) ;
broadcastMessage ( & networkMessageMarkCell , - 1 , lockedSlotIndex ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2012-06-13 18:19:44 +02:00
}
2011-01-13 09:17:18 +01:00
void ServerInterface : : quitGame ( bool userManuallyQuit ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
NetworkMessageQuit networkMessageQuit ;
broadcastMessage ( & networkMessageQuit ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
string ServerInterface : : getNetworkStatus ( ) {
Lang & lang = Lang : : getInstance ( ) ;
2013-12-19 08:35:27 +01:00
string str = " " ;
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2010-03-17 07:25:19 +01:00
2013-12-19 08:35:27 +01:00
str + = intToStr ( index ) + " : " ;
2010-03-17 07:25:19 +01:00
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL ) {
if ( connectionSlot - > isConnected ( ) ) {
int clientLagCount = connectionSlot - > getCurrentLagCount ( ) ;
2012-09-22 22:13:57 +02:00
double lastClientCommandListTimeLag = difftime ( ( long int ) time ( NULL ) , connectionSlot - > getLastReceiveCommandListTime ( ) ) ;
2010-07-02 04:50:20 +02:00
//float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " , lag = %d [%.2f] " , clientLagCount , lastClientCommandListTimeLag ) ;
2013-06-01 04:31:12 +02:00
str + = connectionSlot - > getName ( ) + " [ " + connectionSlot - > getUUID ( ) + " ] " + string ( szBuf ) ;
2010-03-17 07:25:19 +01:00
}
}
2010-12-25 23:38:00 +01:00
else {
2013-12-19 08:35:27 +01:00
str + = lang . getString ( " NotConnected " ) ;
2010-03-17 07:25:19 +01:00
}
2013-12-19 08:35:27 +01:00
str + = ' \n ' ;
2010-03-17 07:25:19 +01:00
}
2011-01-13 09:17:18 +01:00
return str ;
}
bool ServerInterface : : launchGame ( const GameSettings * gameSettings ) {
bool bOkToStart = true ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; exitServer = = false & & index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & &
2011-04-28 00:51:44 +02:00
( connectionSlot - > getAllowDownloadDataSynch ( ) = = true | | connectionSlot - > getAllowGameDataSynchCheck ( ) = = true ) & &
2011-01-13 09:17:18 +01:00
connectionSlot - > isConnected ( ) ) {
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
if ( connectionSlot - > getNetworkGameDataSynchCheckOk ( ) = = false ) {
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , connectionSlot - > getNetworkGameDataSynchCheckOkMap ( ) , connectionSlot - > getNetworkGameDataSynchCheckOkTile ( ) , connectionSlot - > getNetworkGameDataSynchCheckOkTech ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , connectionSlot - > getNetworkGameDataSynchCheckOkMap ( ) , connectionSlot - > getNetworkGameDataSynchCheckOkTile ( ) , connectionSlot - > getNetworkGameDataSynchCheckOkTech ( ) ) ;
2011-04-28 00:51:44 +02:00
2011-01-13 09:17:18 +01:00
bOkToStart = false ;
break ;
}
}
}
if ( bOkToStart = = true ) {
2011-02-15 04:32:14 +01:00
2011-03-05 21:15:28 +01:00
bool useInGameBlockingClientSockets = Config : : getInstance ( ) . getBool ( " EnableInGameBlockingSockets " , " true " ) ;
2013-03-24 06:16:56 +01:00
if ( useInGameBlockingClientSockets = = true ) {
2013-12-19 08:35:27 +01:00
2013-03-24 06:16:56 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
for ( int index = 0 ; index < GameConstants : : maxPlayers ; + + index ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ index ] , CODE_AT_LINE_X ( index ) ) ;
ConnectionSlot * connectionSlot = slots [ index ] ;
2013-03-24 06:16:56 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) ) {
connectionSlot - > getSocket ( ) - > setBlock ( true ) ;
}
}
}
2013-03-06 15:29:49 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
bool requiresUPNPTrigger = false ;
for ( int startIndex = 0 ; startIndex < GameConstants : : maxPlayers ; + + startIndex ) {
int factionIndex = gameSettings - > getFactionIndexForStartLocation ( startIndex ) ;
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ startIndex ] , CODE_AT_LINE_X ( startIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ startIndex ] ;
2013-03-06 15:29:49 +01:00
if ( ( connectionSlot = = NULL | | connectionSlot - > isConnected ( ) = = false ) & &
this - > getAllowInGameConnections ( ) = = true ) {
2013-12-19 08:35:27 +01:00
2013-03-06 15:29:49 +01:00
// Open slots for joining in progress game
if ( gameSettings - > getFactionControl ( factionIndex ) ! = ctClosed & &
gameSettings - > getFactionControl ( factionIndex ) ! = ctHuman ) {
//printf("Opening slot for in game connections for slot: %d, faction: %d\n",i,factionIndex);
if ( connectionSlot = = NULL ) {
2013-12-19 08:35:27 +01:00
addSlot ( startIndex ) ;
connectionSlot = slots [ startIndex ] ;
2013-03-06 15:29:49 +01:00
requiresUPNPTrigger = true ;
2013-02-15 19:25:10 +01:00
}
2013-03-06 15:29:49 +01:00
connectionSlot - > setCanAcceptConnections ( true ) ;
2013-02-15 19:25:10 +01:00
}
2011-02-15 04:32:14 +01:00
}
}
2011-02-16 05:43:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2011-01-13 09:17:18 +01:00
2013-03-01 07:52:33 +01:00
if ( this - > getAllowInGameConnections ( ) = = false ) {
2013-02-15 19:25:10 +01:00
serverSocket . stopBroadCastThread ( ) ;
}
2011-01-13 09:17:18 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2011-01-13 09:17:18 +01:00
2013-02-15 19:25:10 +01:00
this - > gameSettings = * gameSettings ;
//printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings->getMapCRC(),gameSettings->getTilesetCRC(),gameSettings->getTechCRC());
2011-01-13 09:17:18 +01:00
NetworkMessageLaunch networkMessageLaunch ( gameSettings , nmtLaunch ) ;
broadcastMessage ( & networkMessageLaunch ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2011-01-13 09:17:18 +01:00
2012-03-04 00:59:44 +01:00
shutdownMasterserverPublishThread ( ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( masterServerThreadAccessor , CODE_AT_LINE ) ;
2011-01-13 09:17:18 +01:00
lastMasterserverHeartbeatTime = 0 ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ftpServer = %p \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ftpServer ) ;
2011-01-13 09:17:18 +01:00
2013-03-01 07:52:33 +01:00
if ( this - > getAllowInGameConnections ( ) = = false ) {
shutdownFTPServer ( ) ;
2011-01-13 09:17:18 +01:00
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2011-01-13 09:17:18 +01:00
2012-03-25 08:55:43 +02:00
if ( publishToMasterserverThread = = NULL ) {
2013-12-19 08:35:27 +01:00
if ( needToRepublishToMasterserver = = true | |
GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
2013-01-23 15:51:28 +01:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2012-03-25 08:55:43 +02:00
publishToMasterserverThread = new SimpleTaskThread ( this , 0 , 125 ) ;
2013-01-23 15:51:28 +01:00
publishToMasterserverThread - > setUniqueID ( mutexOwnerId ) ;
2012-03-25 08:55:43 +02:00
publishToMasterserverThread - > start ( ) ;
2010-11-09 10:06:52 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
2012-03-25 08:55:43 +02:00
}
2011-01-13 09:17:18 +01:00
}
2010-12-25 23:38:00 +01:00
2013-03-01 07:52:33 +01:00
if ( this - > getAllowInGameConnections ( ) = = false ) {
shutdownFTPServer ( ) ;
2011-01-13 09:17:18 +01:00
}
2013-02-16 20:26:17 +01:00
2014-01-04 00:10:30 +01:00
if ( ( needToRepublishToMasterserver = = true | |
GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) & &
requiresUPNPTrigger = = true ) {
2013-03-06 15:29:49 +01:00
this - > getServerSocket ( ) - > NETdiscoverUPnPDevices ( ) ;
}
2013-02-19 23:00:15 +01:00
gameLaunched = true ;
2011-01-13 09:17:18 +01:00
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
return bOkToStart ;
}
2010-06-03 09:52:17 +02:00
2013-03-01 07:52:33 +01:00
void ServerInterface : : shutdownFTPServer ( ) {
if ( ftpServer ! = NULL ) {
ftpServer - > shutdownAndWait ( ) ;
delete ftpServer ;
ftpServer = NULL ;
}
}
2013-02-16 20:11:36 +01:00
void ServerInterface : : checkListenerSlots ( ) {
2013-12-19 08:35:27 +01:00
if ( gameLaunched = = true & &
this - > getAllowInGameConnections ( ) = = true ) {
2013-03-01 07:52:33 +01:00
if ( difftime ( ( long int ) time ( NULL ) , lastListenerSlotCheckTime ) > = 7 ) {
2013-12-19 08:35:27 +01:00
lastListenerSlotCheckTime = time ( NULL ) ;
2013-03-01 07:52:33 +01:00
bool useInGameBlockingClientSockets = Config : : getInstance ( ) . getBool ( " EnableInGameBlockingSockets " , " true " ) ;
2013-02-16 20:11:36 +01:00
2013-03-01 07:52:33 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
for ( int startIndex = 0 ; startIndex < GameConstants : : maxPlayers ; + + startIndex ) {
int factionIndex = gameSettings . getFactionIndexForStartLocation ( startIndex ) ;
2013-03-01 07:52:33 +01:00
if ( gameSettings . getFactionControl ( factionIndex ) ! = ctClosed & &
gameSettings . getFactionControl ( factionIndex ) ! = ctHuman ) {
2013-02-19 23:00:15 +01:00
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ startIndex ] , CODE_AT_LINE_X ( startIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ startIndex ] ;
2013-03-01 07:52:33 +01:00
// Open slots for joining in progress game
if ( connectionSlot = = NULL ) {
2013-12-19 08:35:27 +01:00
printf ( " Opening slot for in game connections, slot: %d, factionindex: %d name: %s \n " , startIndex , factionIndex , gameSettings . getFactionTypeName ( factionIndex ) . c_str ( ) ) ;
2013-03-01 07:52:33 +01:00
2013-12-19 08:35:27 +01:00
addSlot ( startIndex ) ;
connectionSlot = slots [ startIndex ] ;
2013-03-24 06:16:56 +01:00
if ( useInGameBlockingClientSockets = = true ) {
connectionSlot - > getSocket ( ) - > setBlock ( true ) ;
}
2013-03-01 07:52:33 +01:00
connectionSlot - > setCanAcceptConnections ( true ) ;
2013-02-26 08:05:46 +01:00
}
2013-03-01 07:52:33 +01:00
else if ( connectionSlot ! = NULL & &
connectionSlot - > getCanAcceptConnections ( ) = = false & &
connectionSlot - > isConnected ( ) = = false ) {
2013-12-19 08:35:27 +01:00
printf ( " Removing slot for in game connections, slot: %d, factionindex: %d name: %s \n " , startIndex , factionIndex , gameSettings . getFactionTypeName ( factionIndex ) . c_str ( ) ) ;
2013-02-26 08:05:46 +01:00
2013-12-19 08:35:27 +01:00
this - > removeSlot ( startIndex ) ;
2013-03-01 07:52:33 +01:00
}
2013-02-16 20:11:36 +01:00
}
2013-02-19 23:00:15 +01:00
}
2013-02-16 20:11:36 +01:00
}
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] needToRepublishToMasterserver = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , needToRepublishToMasterserver ) ;
}
2012-01-20 05:15:13 +01:00
void ServerInterface : : broadcastGameSetup ( GameSettings * gameSettingsBuffer , bool setGameSettingsBuffer ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-02-16 11:07:36 +01:00
2013-12-14 08:04:12 +01:00
if ( gameSettingsBuffer = = NULL ) {
throw megaglest_runtime_error ( " gameSettingsBuffer == NULL " ) ;
}
2013-12-19 08:35:27 +01:00
for ( unsigned int factionIndex = 0 ; factionIndex < ( unsigned int ) gameSettingsBuffer - > getFactionCount ( ) ; + + factionIndex ) {
int slotIndex = gameSettingsBuffer - > getStartLocationIndex ( factionIndex ) ;
if ( gameSettingsBuffer - > getFactionControl ( factionIndex ) = = ctNetwork & &
2013-12-14 08:04:12 +01:00
isClientConnected ( slotIndex ) = = false ) {
2013-12-19 08:35:27 +01:00
gameSettingsBuffer - > setNetworkPlayerName ( factionIndex , GameConstants : : NETWORK_SLOT_UNCONNECTED_SLOTNAME ) ;
2013-02-16 11:07:36 +01:00
}
}
2012-01-20 05:15:13 +01:00
if ( setGameSettingsBuffer = = true ) {
validateGameSettings ( gameSettingsBuffer ) ;
2013-12-19 08:35:27 +01:00
}
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
if ( setGameSettingsBuffer = = true ) {
2012-01-20 05:15:13 +01:00
gameSettings = * gameSettingsBuffer ;
gameSettingsUpdateCount + + ;
}
2013-12-19 08:35:27 +01:00
2012-01-20 05:15:13 +01:00
NetworkMessageLaunch networkMessageLaunch ( gameSettingsBuffer , nmtBroadCastSetup ) ;
2011-01-13 09:17:18 +01:00
broadcastMessage ( & networkMessageLaunch ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
2010-06-03 09:52:17 +02:00
2012-11-01 01:06:23 +01:00
void ServerInterface : : broadcastMessage ( NetworkMessage * networkMessage , int excludeSlot , int lockedSlotIndex ) {
2011-01-13 09:17:18 +01:00
try {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-06-03 09:52:17 +02:00
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlotBroadCastAccessor ( inBroadcastMessageThreadAccessor , CODE_AT_LINE ) ;
2013-12-19 08:35:27 +01:00
if ( inBroadcastMessage = = true & &
dynamic_cast < NetworkMessageText * > ( networkMessage ) ! = NULL ) {
2011-01-13 09:17:18 +01:00
safeMutexSlotBroadCastAccessor . ReleaseLock ( ) ;
2012-11-01 01:06:23 +01:00
NetworkMessageText * txtMsg = dynamic_cast < NetworkMessageText * > ( networkMessage ) ;
2013-12-14 08:04:12 +01:00
if ( txtMsg ! = NULL ) {
NetworkMessageText * msgCopy = txtMsg - > getCopy ( ) ;
queueBroadcastMessage ( msgCopy , excludeSlot ) ;
}
2011-01-13 09:17:18 +01:00
return ;
}
else {
inBroadcastMessage = true ;
safeMutexSlotBroadCastAccessor . ReleaseLock ( true ) ;
}
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( NULL , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slotIndex ! = lockedSlotIndex ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] i = %d, lockedSlotIndex = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , slotIndex , lockedSlotIndex ) ;
safeMutexSlot . setMutex ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
2010-03-17 07:25:19 +01:00
}
2010-12-25 23:38:00 +01:00
2013-12-19 08:35:27 +01:00
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-01-13 09:17:18 +01:00
2013-12-19 08:35:27 +01:00
if ( slotIndex ! = excludeSlot & & connectionSlot ! = NULL ) {
2011-01-13 09:17:18 +01:00
if ( connectionSlot - > isConnected ( ) ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] before sendMessage \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
connectionSlot - > sendMessage ( networkMessage ) ;
2013-12-19 08:35:27 +01:00
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] after sendMessage \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-06-03 09:52:17 +02:00
}
2011-01-13 09:17:18 +01:00
if ( gameHasBeenInitiated = = true & & connectionSlot - > isConnected ( ) = = false ) {
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 before removeSlot for slot# %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , slotIndex ) ;
2013-02-15 19:25:10 +01:00
if ( this - > getAllowInGameConnections ( ) = = false ) {
2013-12-19 08:35:27 +01:00
removeSlot ( slotIndex , slotIndex ) ;
2013-02-15 19:25:10 +01:00
}
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 after removeSlot for slot# %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , slotIndex ) ;
2010-06-03 09:52:17 +02:00
}
}
2013-12-19 08:35:27 +01:00
else if ( slotIndex = = excludeSlot & & gameHasBeenInitiated = = true & &
2011-01-13 09:17:18 +01:00
connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) = = false ) {
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 before removeSlot for slot# %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , slotIndex ) ;
2013-02-15 19:25:10 +01:00
if ( this - > getAllowInGameConnections ( ) = = false ) {
2013-12-19 08:35:27 +01:00
removeSlot ( slotIndex , slotIndex ) ;
2013-02-15 19:25:10 +01:00
}
2013-12-19 08:35:27 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 after removeSlot for slot# %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , slotIndex ) ;
2011-01-13 09:17:18 +01:00
}
}
safeMutexSlotBroadCastAccessor . Lock ( ) ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
inBroadcastMessage = false ;
2013-12-19 08:35:27 +01:00
2011-01-13 09:17:18 +01:00
safeMutexSlotBroadCastAccessor . ReleaseLock ( ) ;
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-01-13 09:17:18 +01:00
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSlotBroadCastAccessor ( inBroadcastMessageThreadAccessor , CODE_AT_LINE ) ;
2011-01-13 09:17:18 +01:00
inBroadcastMessage = false ;
safeMutexSlotBroadCastAccessor . ReleaseLock ( ) ;
2010-07-08 10:29:51 +02:00
string sMsg = ex . what ( ) ;
2011-04-05 20:39:47 +02:00
sendTextMessage ( sMsg , - 1 , true , " " , lockedSlotIndex ) ;
2011-01-13 09:17:18 +01:00
}
}
2010-05-15 20:59:17 +02:00
2012-11-01 01:06:23 +01:00
void ServerInterface : : broadcastMessageToConnectedClients ( NetworkMessage * networkMessage , int excludeSlot ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
try {
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2010-03-17 07:25:19 +01:00
2013-12-19 08:35:27 +01:00
if ( slotIndex ! = excludeSlot & & connectionSlot ! = NULL ) {
2010-07-01 02:08:59 +02:00
if ( connectionSlot - > isConnected ( ) ) {
connectionSlot - > sendMessage ( networkMessage ) ;
}
2010-03-17 07:25:19 +01:00
}
}
}
2011-01-13 09:17:18 +01:00
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-01-13 09:17:18 +01:00
DisplayErrorMessage ( ex . what ( ) ) ;
}
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
void ServerInterface : : updateListen ( ) {
2013-12-19 08:35:27 +01:00
if ( gameHasBeenInitiated = = true & &
this - > getAllowInGameConnections ( ) = = false ) {
2011-01-13 09:17:18 +01:00
return ;
}
2013-03-01 07:52:33 +01:00
2011-01-13 09:17:18 +01:00
int openSlotCount = 0 ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
2010-05-28 07:31:17 +02:00
2013-12-19 08:35:27 +01:00
bool isSlotOpen = ( slots [ slotIndex ] ! = NULL & & slots [ slotIndex ] - > isConnected ( ) = = false ) ;
2010-05-28 07:31:17 +02:00
if ( isSlotOpen = = true ) {
2010-03-17 07:25:19 +01:00
+ + openSlotCount ;
}
}
2012-03-25 08:55:43 +02:00
2011-01-13 09:17:18 +01:00
serverSocket . listen ( openSlotCount ) ;
}
2010-03-17 07:25:19 +01:00
2011-01-13 09:17:18 +01:00
int ServerInterface : : getOpenSlotCount ( ) {
int openSlotCount = 0 ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
2010-05-15 20:59:17 +02:00
2013-12-19 08:35:27 +01:00
bool isSlotOpen = ( slots [ slotIndex ] ! = NULL & & slots [ slotIndex ] - > isConnected ( ) = = false ) ;
2010-05-28 07:31:17 +02:00
if ( isSlotOpen = = true ) {
2010-05-12 17:25:56 +02:00
+ + openSlotCount ;
}
}
2011-01-13 09:17:18 +01:00
return openSlotCount ;
}
2011-09-26 06:50:13 +02:00
int ServerInterface : : getGameSettingsUpdateCount ( ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] START gameSettingsUpdateCount = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , gameSettingsUpdateCount ) ;
2011-09-26 06:50:13 +02:00
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
2011-09-26 06:50:13 +02:00
int result = gameSettingsUpdateCount ;
safeMutex . ReleaseLock ( ) ;
return result ;
}
2012-01-20 05:15:13 +01:00
void ServerInterface : : validateGameSettings ( GameSettings * serverGameSettings ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2012-01-20 05:15:13 +01:00
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
2012-01-20 05:15:13 +01:00
string mapFile = serverGameSettings - > getMap ( ) ;
2012-07-06 00:03:15 +02:00
printf ( " Trying to set map to [%s]. Current map is [%s] \n " , serverGameSettings - > getMap ( ) . c_str ( ) , gameSettings . getMap ( ) . c_str ( ) ) ;
2012-01-20 05:15:13 +01:00
if ( find ( mapFiles . begin ( ) , mapFiles . end ( ) , mapFile ) = = mapFiles . end ( ) ) {
2013-12-19 08:35:27 +01:00
2012-07-06 00:03:15 +02:00
printf ( " map not found on this server \n " ) ;
2013-12-19 08:35:27 +01:00
int currentIndex = - 1 ;
string currentMap = gameSettings . getMap ( ) ;
for ( int mapIndex = 0 ; mapIndex < ( int ) mapFiles . size ( ) ; + + mapIndex ) {
string current = mapFiles [ mapIndex ] ;
if ( current = = currentMap ) {
currentIndex = mapIndex ;
2012-07-06 00:03:15 +02:00
break ;
}
}
2013-12-19 08:35:27 +01:00
if ( currentIndex = = - 1 ) {
2012-07-06 00:03:15 +02:00
serverGameSettings - > setMap ( gameSettings . getMap ( ) ) ;
2013-12-19 08:35:27 +01:00
}
else {
2012-07-06 00:03:15 +02:00
if ( mapFile > gameSettings . getMap ( ) ) {
printf ( " mapFile>gameSettings [%s] > [%s] \n " , mapFile . c_str ( ) , gameSettings . getMap ( ) . c_str ( ) ) ;
2013-12-19 08:35:27 +01:00
int nextIndex = - 1 ;
for ( int mapIndex = 0 ; mapIndex < ( int ) mapFiles . size ( ) ; + + mapIndex ) {
string current = mapFiles [ mapIndex ] ;
if ( current > mapFile ) {
nextIndex = mapIndex ;
2012-07-06 00:03:15 +02:00
break ;
}
}
2013-12-19 08:35:27 +01:00
if ( nextIndex > - 1 ) {
2012-07-06 00:03:15 +02:00
serverGameSettings - > setMap ( mapFiles [ nextIndex ] ) ;
//printf("switch up\n");
2013-12-19 08:35:27 +01:00
}
else {
2012-07-06 00:03:15 +02:00
//printf("overflow top\n");
serverGameSettings - > setMap ( mapFiles [ 0 ] ) ;
}
}
2013-12-19 08:35:27 +01:00
else {
2012-07-06 00:03:15 +02:00
printf ( " mapFile<gameSettings [%s] < [%s] \n " , mapFile . c_str ( ) , gameSettings . getMap ( ) . c_str ( ) ) ;
2013-12-19 08:35:27 +01:00
int nextIndex = - 1 ;
for ( int mapIndex = ( int ) mapFiles . size ( ) - 1 ; mapIndex > = 0 ; mapIndex - - ) {
string current = mapFiles [ mapIndex ] ;
if ( current < mapFile ) {
nextIndex = mapIndex ;
2012-07-06 00:03:15 +02:00
break ;
}
}
2012-01-20 05:15:13 +01:00
2013-12-19 08:35:27 +01:00
if ( nextIndex > - 1 ) {
2012-07-06 00:03:15 +02:00
serverGameSettings - > setMap ( mapFiles [ nextIndex ] ) ;
//printf("switch down\n");
2013-12-19 08:35:27 +01:00
}
else {
2012-07-06 00:03:15 +02:00
//printf("overflow bottom\n");
serverGameSettings - > setMap ( mapFiles [ ( mapFiles . size ( ) - 1 ) ] ) ;
}
}
printf ( " switching map from [%s] to [%s] \n " , mapFile . c_str ( ) , serverGameSettings - > getMap ( ) . c_str ( ) ) ;
}
2012-01-20 05:15:13 +01:00
serverGameSettings - > setMapFilterIndex ( gameSettings . getMapFilterIndex ( ) ) ;
2012-07-06 00:03:15 +02:00
Checksum checksum ;
2013-12-17 08:54:33 +01:00
string file = Config : : getMapPath ( serverGameSettings - > getMap ( ) , " " , false ) ;
2012-07-06 00:03:15 +02:00
checksum . addFile ( file ) ;
serverGameSettings - > setMapCRC ( checksum . getSum ( ) ) ;
2012-01-20 05:15:13 +01:00
}
string tilesetFile = serverGameSettings - > getTileset ( ) ;
if ( find ( tilesetFiles . begin ( ) , tilesetFiles . end ( ) , tilesetFile ) = = tilesetFiles . end ( ) ) {
printf ( " Reverting tileset from [%s] to [%s] \n " , serverGameSettings - > getTileset ( ) . c_str ( ) , gameSettings . getTileset ( ) . c_str ( ) ) ;
serverGameSettings - > setTileset ( gameSettings . getTileset ( ) ) ;
serverGameSettings - > setTilesetCRC ( gameSettings . getTilesetCRC ( ) ) ;
}
string techtreeFile = serverGameSettings - > getTech ( ) ;
if ( find ( techTreeFiles . begin ( ) , techTreeFiles . end ( ) , techtreeFile ) = = techTreeFiles . end ( ) ) {
printf ( " Reverting tech from [%s] to [%s] \n " , serverGameSettings - > getTech ( ) . c_str ( ) , gameSettings . getTech ( ) . c_str ( ) ) ;
serverGameSettings - > setTech ( gameSettings . getTech ( ) ) ;
serverGameSettings - > setTechCRC ( gameSettings . getTechCRC ( ) ) ;
}
}
2011-01-13 09:17:18 +01:00
void ServerInterface : : setGameSettings ( GameSettings * serverGameSettings , bool waitForClientAck ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( serverSynchAccessor , CODE_AT_LINE ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , gameSettingsUpdateCount , waitForClientAck ) ;
2011-10-12 08:54:36 +02:00
2011-12-28 05:46:36 +01:00
if ( serverGameSettings - > getScenario ( ) = = " " ) {
string mapFile = serverGameSettings - > getMap ( ) ;
if ( find ( mapFiles . begin ( ) , mapFiles . end ( ) , mapFile ) = = mapFiles . end ( ) ) {
printf ( " Reverting map from [%s] to [%s] \n " , serverGameSettings - > getMap ( ) . c_str ( ) , gameSettings . getMap ( ) . c_str ( ) ) ;
2012-01-20 05:15:13 +01:00
2011-12-28 05:46:36 +01:00
serverGameSettings - > setMapFilterIndex ( gameSettings . getMapFilterIndex ( ) ) ;
serverGameSettings - > setMap ( gameSettings . getMap ( ) ) ;
serverGameSettings - > setMapCRC ( gameSettings . getMapCRC ( ) ) ;
}
2012-01-20 05:15:13 +01:00
2011-12-28 05:46:36 +01:00
string tilesetFile = serverGameSettings - > getTileset ( ) ;
if ( find ( tilesetFiles . begin ( ) , tilesetFiles . end ( ) , tilesetFile ) = = tilesetFiles . end ( ) ) {
printf ( " Reverting tileset from [%s] to [%s] \n " , serverGameSettings - > getTileset ( ) . c_str ( ) , gameSettings . getTileset ( ) . c_str ( ) ) ;
2012-01-20 05:15:13 +01:00
2011-12-28 05:46:36 +01:00
serverGameSettings - > setTileset ( gameSettings . getTileset ( ) ) ;
serverGameSettings - > setTilesetCRC ( gameSettings . getTilesetCRC ( ) ) ;
}
2012-01-20 05:15:13 +01:00
2011-12-28 05:46:36 +01:00
string techtreeFile = serverGameSettings - > getTech ( ) ;
if ( find ( techTreeFiles . begin ( ) , techTreeFiles . end ( ) , techtreeFile ) = = techTreeFiles . end ( ) ) {
printf ( " Reverting tech from [%s] to [%s] \n " , serverGameSettings - > getTech ( ) . c_str ( ) , gameSettings . getTech ( ) . c_str ( ) ) ;
2012-01-20 05:15:13 +01:00
2011-12-28 05:46:36 +01:00
serverGameSettings - > setTech ( gameSettings . getTech ( ) ) ;
serverGameSettings - > setTechCRC ( gameSettings . getTechCRC ( ) ) ;
}
2011-10-12 08:54:36 +02:00
}
2011-01-13 09:17:18 +01:00
gameSettings = * serverGameSettings ;
2013-06-01 04:31:12 +02:00
2011-01-13 09:17:18 +01:00
if ( getAllowGameDataSynchCheck ( ) = = true ) {
if ( waitForClientAck = = true & & gameSettingsUpdateCount > 0 ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Waiting for client acks #1 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
time_t tStart = time ( NULL ) ;
bool gotAckFromAllClients = false ;
2012-09-22 22:13:57 +02:00
while ( gotAckFromAllClients = = false & & difftime ( ( long int ) time ( NULL ) , tStart ) < = 5 ) {
2011-01-13 09:17:18 +01:00
gotAckFromAllClients = true ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
2011-11-23 09:00:09 +01:00
//printf("===> START slot %d - About to setGameSettings #1\n",i);
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) ) {
if ( connectionSlot - > getReceivedNetworkGameStatus ( ) = = false ) {
gotAckFromAllClients = false ;
}
2013-12-19 08:35:27 +01:00
connectionSlot - > update ( true , slotIndex ) ;
2011-01-13 09:17:18 +01:00
}
2011-11-23 09:00:09 +01:00
//printf("===> END slot %d - About to setGameSettings #1\n",i);
2011-01-13 09:17:18 +01:00
}
}
}
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) ) {
connectionSlot - > setReceivedNetworkGameStatus ( false ) ;
}
}
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData ( getGameSettings ( ) ) ;
broadcastMessageToConnectedClients ( & networkMessageSynchNetworkGameData ) ;
if ( waitForClientAck = = true ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Waiting for client acks #2 \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
time_t tStart = time ( NULL ) ;
bool gotAckFromAllClients = false ;
2012-09-22 22:13:57 +02:00
while ( gotAckFromAllClients = = false & & difftime ( ( long int ) time ( NULL ) , tStart ) < = 5 ) {
2011-01-13 09:17:18 +01:00
gotAckFromAllClients = true ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
//printf("===> START slot %d - About to setGameSettings 2\n",slotIndex);
2011-11-23 09:00:09 +01:00
2013-12-19 08:35:27 +01:00
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2011-01-13 09:17:18 +01:00
if ( connectionSlot ! = NULL & & connectionSlot - > isConnected ( ) ) {
if ( connectionSlot - > getReceivedNetworkGameStatus ( ) = = false ) {
gotAckFromAllClients = false ;
}
2013-12-19 08:35:27 +01:00
connectionSlot - > update ( true , slotIndex ) ;
2011-01-13 09:17:18 +01:00
}
2013-12-19 08:35:27 +01:00
//printf("===> END slot %d - About to setGameSettings 2\n",slotIndex);
2011-01-13 09:17:18 +01:00
}
}
}
}
2011-09-24 09:46:56 +02:00
gameSettingsUpdateCount + + ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] END \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
}
void ServerInterface : : close ( ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] START \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ ) ;
2011-01-13 09:17:18 +01:00
}
string ServerInterface : : getHumanPlayerName ( int index ) {
string result = Config : : getInstance ( ) . getString ( " NetPlayerName " , Socket : : getHostName ( ) . c_str ( ) ) ;
if ( index > = 0 | | gameSettings . getThisFactionIndex ( ) > = 0 ) {
if ( index < 0 ) {
index = gameSettings . getThisFactionIndex ( ) ;
}
if ( gameSettings . getNetworkPlayerName ( index ) ! = " " ) {
result = gameSettings . getNetworkPlayerName ( index ) ;
}
}
return result ;
}
int ServerInterface : : getHumanPlayerIndex ( ) const {
return gameSettings . getStartLocationIndex ( gameSettings . getThisFactionIndex ( ) ) ;
}
std : : map < string , string > ServerInterface : : publishToMasterserver ( ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
int slotCountUsed = 1 ;
int slotCountHumans = 1 ;
int slotCountConnectedPlayers = 1 ;
2012-07-10 15:49:49 +02:00
if ( GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
slotCountUsed = 0 ;
slotCountHumans = 0 ;
slotCountConnectedPlayers = 0 ;
}
2011-01-13 09:17:18 +01:00
Config & config = Config : : getInstance ( ) ;
std : : map < string , string > publishToServerInfo ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slots [ slotIndex ] ! = NULL ) {
2010-10-23 11:06:47 +02:00
slotCountUsed + + ;
slotCountHumans + + ;
2013-12-19 08:35:27 +01:00
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
2010-10-23 11:06:47 +02:00
if ( ( connectionSlot ! = NULL ) & & ( connectionSlot - > isConnected ( ) ) ) {
slotCountConnectedPlayers + + ;
}
}
}
2013-12-19 08:35:27 +01:00
publishToServerInfo [ " uuid " ] = Config : : getInstance ( ) . getString ( " PlayerId " , " " ) ;
publishToServerInfo [ " glestVersion " ] = glestVersionString ;
publishToServerInfo [ " platform " ] = getPlatformNameString ( ) + " - " + getGITRevisionString ( ) ;
publishToServerInfo [ " binaryCompileDate " ] = getCompileDateTime ( ) ;
2014-11-07 01:26:23 +01:00
publishToServerInfo [ " serverTitle " ] = this - > getGameSettings ( ) - > getGameName ( ) ;
2013-12-19 08:35:27 +01:00
publishToServerInfo [ " tech " ] = this - > getGameSettings ( ) - > getTech ( ) ;
publishToServerInfo [ " map " ] = this - > getGameSettings ( ) - > getMap ( ) ;
publishToServerInfo [ " tileset " ] = this - > getGameSettings ( ) - > getTileset ( ) ;
2013-11-01 15:38:28 +01:00
bool updateSlots = true ;
MutexSafeWrapper safeMutex2 ( gameStatsThreadAccessor , CODE_AT_LINE ) ;
if ( gameStats ! = NULL ) {
for ( int factionIndex = 0 ; factionIndex < gameStats - > getFactionCount ( ) ; + + factionIndex ) {
if ( gameStats - > getVictory ( factionIndex ) = = true ) {
updateSlots = false ;
break ;
}
}
}
safeMutex2 . ReleaseLock ( ) ;
if ( updateSlots = = true ) {
2013-12-19 08:35:27 +01:00
publishToServerInfo [ " activeSlots " ] = intToStr ( slotCountUsed ) ;
publishToServerInfo [ " networkSlots " ] = intToStr ( slotCountHumans ) ;
2013-11-01 15:38:28 +01:00
publishToServerInfo [ " connectedClients " ] = intToStr ( slotCountConnectedPlayers ) ;
}
2013-12-19 08:35:27 +01:00
string serverPort = config . getString ( " PortServer " , intToStr ( GameConstants : : serverPort ) . c_str ( ) ) ;
string externalPort = config . getString ( " PortExternal " , serverPort . c_str ( ) ) ;
publishToServerInfo [ " externalconnectport " ] = externalPort ;
publishToServerInfo [ " privacyPlease " ] = intToStr ( config . getBool ( " PrivacyPlease " , " false " ) ) ;
publishToServerInfo [ " gameStatus " ] = intToStr ( game_status_in_progress ) ;
2011-01-25 08:41:12 +01:00
2011-01-13 09:17:18 +01:00
if ( publishToMasterserverThread = = NULL ) {
2013-12-19 08:35:27 +01:00
publishToServerInfo [ " gameCmd " ] = " gameOver " ;
publishToServerInfo [ " gameStatus " ] = intToStr ( game_status_finished ) ;
2010-10-23 11:06:47 +02:00
}
2013-10-31 01:57:36 +01:00
//printf("Host game id = %s\n",this->getGameSettings()->getGameUUID().c_str());
publishToServerInfo [ " gameUUID " ] = this - > getGameSettings ( ) - > getGameUUID ( ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
return publishToServerInfo ;
}
2013-10-31 01:57:36 +01:00
std : : map < string , string > ServerInterface : : publishToMasterserverStats ( ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
MutexSafeWrapper safeMutex ( gameStatsThreadAccessor , CODE_AT_LINE ) ;
std : : map < string , string > publishToServerInfo ;
if ( gameStats ! = NULL ) {
2013-12-19 08:35:27 +01:00
publishToServerInfo [ " gameUUID " ] = this - > getGameSettings ( ) - > getGameUUID ( ) ;
publishToServerInfo [ " tech " ] = this - > getGameSettings ( ) - > getTech ( ) ;
publishToServerInfo [ " factionCount " ] = intToStr ( gameStats - > getFactionCount ( ) ) ;
publishToServerInfo [ " framesPlayed " ] = intToStr ( gameStats - > getFramesPlayed ( ) ) ;
publishToServerInfo [ " framesToCalculatePlaytime " ] = intToStr ( gameStats - > getFramesToCalculatePlaytime ( ) ) ;
publishToServerInfo [ " maxConcurrentUnitCount " ] = intToStr ( gameStats - > getMaxConcurrentUnitCount ( ) ) ;
publishToServerInfo [ " totalEndGameConcurrentUnitCount " ] = intToStr ( gameStats - > getTotalEndGameConcurrentUnitCount ( ) ) ;
publishToServerInfo [ " isHeadlessServer " ] = intToStr ( gameStats - > getIsMasterserverMode ( ) ) ;
2013-10-31 01:57:36 +01:00
for ( int factionIndex = 0 ; factionIndex < gameStats - > getFactionCount ( ) ; + + factionIndex ) {
publishToServerInfo [ " factionIndex_ " + intToStr ( factionIndex ) ] = intToStr ( factionIndex ) ;
publishToServerInfo [ " controlType_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getControl ( factionIndex ) ) ;
publishToServerInfo [ " resourceMultiplier_ " + intToStr ( factionIndex ) ] = floatToStr ( gameStats - > getResourceMultiplier ( factionIndex ) ) ;
publishToServerInfo [ " factionTypeName_ " + intToStr ( factionIndex ) ] = gameStats - > getFactionTypeName ( factionIndex ) ;
publishToServerInfo [ " personalityType_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getPersonalityType ( factionIndex ) ) ;
publishToServerInfo [ " teamIndex_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getTeam ( factionIndex ) ) ;
publishToServerInfo [ " wonGame_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getVictory ( factionIndex ) ) ;
publishToServerInfo [ " killCount_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getKills ( factionIndex ) ) ;
publishToServerInfo [ " enemyKillCount_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getEnemyKills ( factionIndex ) ) ;
publishToServerInfo [ " deathCount_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getDeaths ( factionIndex ) ) ;
publishToServerInfo [ " unitsProducedCount_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getUnitsProduced ( factionIndex ) ) ;
publishToServerInfo [ " resourceHarvestedCount_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getResourcesHarvested ( factionIndex ) ) ;
publishToServerInfo [ " playerName_ " + intToStr ( factionIndex ) ] = gameStats - > getPlayerName ( factionIndex ) ;
publishToServerInfo [ " quitBeforeGameEnd_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getPlayerLeftBeforeEnd ( factionIndex ) ) ;
publishToServerInfo [ " quitTime_ " + intToStr ( factionIndex ) ] = intToStr ( gameStats - > getTimePlayerLeft ( factionIndex ) ) ;
2013-11-01 22:31:55 +01:00
publishToServerInfo [ " playerUUID_ " + intToStr ( factionIndex ) ] = this - > getGameSettings ( ) - > getNetworkPlayerUUID ( factionIndex ) ;
2013-11-02 20:05:59 +01:00
publishToServerInfo [ " platform_ " + intToStr ( factionIndex ) ] = this - > getGameSettings ( ) - > getNetworkPlayerPlatform ( factionIndex ) ;
2013-10-31 01:57:36 +01:00
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
}
return publishToServerInfo ;
}
void ServerInterface : : setGameStats ( Stats * stats ) {
if ( stats = = NULL ) {
return ;
}
MutexSafeWrapper safeMutex ( gameStatsThreadAccessor , CODE_AT_LINE ) ;
if ( gameStats = = NULL ) {
gameStats = new Stats ( ) ;
}
* gameStats = * stats ;
}
2013-11-07 19:39:08 +01:00
void ServerInterface : : simpleTask ( BaseThread * callingThread , void * userdata ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( masterServerThreadAccessor , CODE_AT_LINE ) ;
2012-03-25 08:55:43 +02:00
2012-09-22 22:13:57 +02:00
if ( difftime ( ( long int ) time ( NULL ) , lastMasterserverHeartbeatTime ) > = MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS ) {
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2010-10-23 11:06:47 +02:00
2013-03-01 18:21:58 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Checking to see masterserver needs an update of the game status [%d] callingThread [%p] publishToMasterserverThread [%p] \n " , needToRepublishToMasterserver , callingThread , publishToMasterserverThread ) ;
2010-10-23 11:06:47 +02:00
lastMasterserverHeartbeatTime = time ( NULL ) ;
2010-10-24 00:06:49 +02:00
if ( needToRepublishToMasterserver = = true ) {
2010-12-20 17:45:31 +01:00
try {
2011-01-13 09:17:18 +01:00
if ( Config : : getInstance ( ) . getString ( " Masterserver " , " " ) ! = " " ) {
2014-01-25 03:20:01 +01:00
string request = Config : : getInstance ( ) . getString ( " Masterserver " ) ;
if ( request ! = " " ) {
endPathWithSlash ( request , false ) ;
}
request + = " addServerInfo.php? " ;
2011-01-13 09:17:18 +01:00
std : : map < string , string > newPublishToServerInfo = publishToMasterserver ( ) ;
CURL * handle = SystemFlags : : initHTTP ( ) ;
for ( std : : map < string , string > : : const_iterator iterMap = newPublishToServerInfo . begin ( ) ;
2011-09-01 20:08:56 +02:00
iterMap ! = newPublishToServerInfo . end ( ) ; + + iterMap ) {
2011-01-13 09:17:18 +01:00
request + = iterMap - > first ;
request + = " = " ;
request + = SystemFlags : : escapeURL ( iterMap - > second , handle ) ;
request + = " & " ;
}
2013-10-31 01:57:36 +01:00
//printf("The Host request is:\n%s\n",request.c_str());
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " The Host request is: \n %s \n " , request . c_str ( ) ) ;
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] the request is: \n %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , request . c_str ( ) ) ;
2011-01-13 09:17:18 +01:00
2013-03-01 18:21:58 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Calling masterserver [%s]... \n " , request . c_str ( ) ) ;
2011-01-13 09:17:18 +01:00
std : : string serverInfo = SystemFlags : : getHTTP ( request , handle ) ;
2013-10-31 01:57:36 +01:00
//printf("Result:\n%s\n",serverInfo .c_str());
2014-01-25 03:20:01 +01:00
string requestStats = Config : : getInstance ( ) . getString ( " Masterserver " ) ;
if ( requestStats ! = " " ) {
endPathWithSlash ( requestStats , false ) ;
}
requestStats + = " addGameStats.php? " ;
2013-10-31 01:57:36 +01:00
std : : map < string , string > newPublishToServerInfoStats = publishToMasterserverStats ( ) ;
if ( newPublishToServerInfoStats . empty ( ) = = false ) {
for ( std : : map < string , string > : : const_iterator iterMap = newPublishToServerInfoStats . begin ( ) ;
iterMap ! = newPublishToServerInfoStats . end ( ) ; + + iterMap ) {
requestStats + = iterMap - > first ;
requestStats + = " = " ;
requestStats + = SystemFlags : : escapeURL ( iterMap - > second , handle ) ;
requestStats + = " & " ;
}
2013-11-02 20:07:00 +01:00
//printf("The Host stats request is:\n%s\n",requestStats.c_str());
2013-10-31 01:57:36 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " The Host request is: \n %s \n " , requestStats . c_str ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] the request is: \n %s \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , requestStats . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Calling masterserver [%s]... \n " , requestStats . c_str ( ) ) ;
std : : string serverInfoStats = SystemFlags : : getHTTP ( requestStats , handle ) ;
2013-11-02 20:07:00 +01:00
//printf("Result:\n%s\n",serverInfoStats .c_str());
2013-10-31 01:57:36 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] the result is: \n '%s' \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , serverInfoStats . c_str ( ) ) ;
}
2011-01-13 09:17:18 +01:00
SystemFlags : : cleanupHTTP ( & handle ) ;
2013-03-01 18:21:58 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Done Calling masterserver \n " ) ;
2011-01-13 09:17:18 +01:00
//printf("the result is:\n'%s'\n",serverInfo.c_str());
2012-11-02 20:08:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line %d] the result is: \n '%s' \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , serverInfo . c_str ( ) ) ;
2011-01-13 09:17:18 +01:00
}
else {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line %d] error, no masterserver defined! \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-13 09:17:18 +01:00
}
}
catch ( const exception & ex ) {
2012-11-02 20:08:55 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line %d] error during game status update: [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-10-23 11:06:47 +02:00
}
}
2012-03-25 08:55:43 +02:00
if ( GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
DumpStatsToLog ( false ) ;
}
}
if ( GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
//printf("Attempt Accept\n");
2012-10-30 19:03:03 +01:00
if ( serverSocketAdmin ! = NULL ) {
Socket * cli = serverSocketAdmin - > accept ( false ) ;
if ( cli ! = NULL ) {
printf ( " Got status request connection, dumping info... \n " ) ;
string data = DumpStatsToLog ( true ) ;
2013-11-02 12:04:52 +01:00
cli - > send ( data . c_str ( ) , ( int ) data . length ( ) ) ;
2012-10-30 19:03:03 +01:00
cli - > disconnectSocket ( ) ;
}
2012-03-25 08:55:43 +02:00
}
}
}
std : : string ServerInterface : : DumpStatsToLog ( bool dumpToStringOnly ) const {
string headlessLogFile = Config : : getInstance ( ) . getString ( " HeadlessLogFile " , " headless.log " ) ;
if ( getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) ! = " " ) {
headlessLogFile = getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) + headlessLogFile ;
}
else {
string userData = Config : : getInstance ( ) . getString ( " UserData_Root " , " " ) ;
if ( userData ! = " " ) {
endPathWithSlash ( userData ) ;
}
headlessLogFile = userData + headlessLogFile ;
}
ostringstream out ;
out < < " ========================================= " < < std : : endl ;
out < < " Headless Server Current Game information: " < < std : : endl ;
out < < " ========================================= " < < std : : endl ;
int connectedSlotCount = 0 ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * slot = slots [ slotIndex ] ;
2012-03-25 08:55:43 +02:00
if ( slot ! = NULL ) {
2013-12-19 08:35:27 +01:00
2012-03-25 08:55:43 +02:00
connectedSlotCount + + ;
2013-12-19 08:35:27 +01:00
out < < " Network connection for index: " < < slotIndex < < std : : endl ;
2012-03-25 08:55:43 +02:00
out < < " ------------------------------ " < < std : : endl ;
out < < " Connected: " < < boolToStr ( slot - > isConnected ( ) ) < < std : : endl ;
out < < " Handshake received: " < < boolToStr ( slot - > getConnectHasHandshaked ( ) ) < < std : : endl ;
if ( slot - > isConnected ( ) = = true ) {
2013-12-19 08:35:27 +01:00
time_t connectTime = slot - > getConnectedTime ( ) ;
struct tm * loctime = localtime ( & connectTime ) ;
char szBuf [ 8096 ] = " " ;
2012-03-25 08:55:43 +02:00
strftime ( szBuf , 100 , " %Y-%m-%d %H:%M:%S " , loctime ) ;
2013-12-19 08:35:27 +01:00
const int HOURS_IN_DAY = 24 ;
const int MINUTES_IN_HOUR = 60 ;
2012-03-25 08:55:43 +02:00
const int SECONDS_IN_MINUTE = 60 ;
2013-12-19 08:35:27 +01:00
int InSeconds = difftime ( ( long int ) time ( NULL ) , slot - > getConnectedTime ( ) ) ;
2012-03-25 08:55:43 +02:00
// compute seconds
int seconds = InSeconds % SECONDS_IN_MINUTE ;
// throw away seconds used in previous statement and convert to minutes
int InMinutes = InSeconds / SECONDS_IN_MINUTE ;
// compute minutes
int minutes = InMinutes % MINUTES_IN_HOUR ;
// throw away minutes used in previous statement and convert to hours
int InHours = InMinutes / MINUTES_IN_HOUR ;
// compute hours
int hours = InHours % HOURS_IN_DAY ;
2013-12-19 08:35:27 +01:00
out < < " Connected at: " < < szBuf < < std : : endl ;
out < < " Connection duration: " < < hours < < " hours " < < minutes < < " minutes " < < seconds < < " seconds. " < < std : : endl ;
out < < " Player Index: " < < slot - > getPlayerIndex ( ) < < std : : endl ;
out < < " IP Address: " < < slot - > getIpAddress ( ) < < std : : endl ;
out < < " Player name: " < < slot - > getName ( ) < < std : : endl ;
out < < " Player uuid: " < < slot - > getUUID ( ) < < std : : endl ;
out < < " Language: " < < slot - > getNetworkPlayerLanguage ( ) < < std : : endl ;
out < < " Game Version: " < < slot - > getVersionString ( ) < < std : : endl ;
out < < " Session id: " < < slot - > getSessionKey ( ) < < std : : endl ;
out < < " Socket id: " < < slot - > getSocketId ( ) < < std : : endl ;
2012-03-25 08:55:43 +02:00
}
}
2010-10-23 11:06:47 +02:00
}
2013-12-19 08:35:27 +01:00
out < < " Total Slot Count: " < < connectedSlotCount < < std : : endl ;
2012-03-25 08:55:43 +02:00
out < < " ========================================= " < < std : : endl ;
std : : string result = out . str ( ) ;
if ( dumpToStringOnly = = false ) {
# if defined(WIN32) && !defined(__MINGW32__)
FILE * fp = _wfopen ( utf8_decode ( headlessLogFile ) . c_str ( ) , L " w " ) ;
std : : ofstream logFile ( fp ) ;
# else
std : : ofstream logFile ;
logFile . open ( headlessLogFile . c_str ( ) , ios_base : : out | ios_base : : trunc ) ;
# endif
logFile < < result ;
logFile . close ( ) ;
# if defined(WIN32) && !defined(__MINGW32__)
if ( fp ) {
fclose ( fp ) ;
}
# endif
}
return result ;
2010-10-23 11:06:47 +02:00
}
2011-11-23 09:00:09 +01:00
void ServerInterface : : notifyBadClientConnectAttempt ( string ipAddress ) {
2012-11-02 20:08:55 +01:00
//printf("In [%s::%s Line: %d] ipAddress [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ipAddress.c_str());
2011-11-23 09:00:09 +01:00
if ( badClientConnectIPList . find ( ipAddress ) = = badClientConnectIPList . end ( ) ) {
2012-09-22 22:13:57 +02:00
badClientConnectIPList [ ipAddress ] = make_pair ( 0 , ( long int ) time ( NULL ) ) ;
2011-11-23 09:00:09 +01:00
}
pair < uint64 , time_t > & lastBadConnectionAttempt = badClientConnectIPList [ ipAddress ] ;
const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS = Config : : getInstance ( ) . getInt ( " BlockBadClientConnectMaxSeconds " , " 60 " ) ;
const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS = Config : : getInstance ( ) . getInt ( " BlockBadClientConnectMaxAttempts " , " 6 " ) ;
bool addToBlockedClientsList = false ;
2012-09-22 22:13:57 +02:00
if ( difftime ( ( long int ) time ( NULL ) , lastBadConnectionAttempt . second ) < = BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS ) {
2011-11-23 09:00:09 +01:00
if ( lastBadConnectionAttempt . first + 1 > BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS ) {
addToBlockedClientsList = true ;
}
}
else {
// Reset after x seconds
lastBadConnectionAttempt . first = 0 ;
}
2013-02-15 19:25:10 +01:00
if ( this - > getAllowInGameConnections ( ) = = true ) {
printf ( " notifyBadClientConnectAttempt() #1: %s! \n " , ipAddress . c_str ( ) ) ;
}
2011-11-23 09:00:09 +01:00
if ( addToBlockedClientsList = = true ) {
serverSocket . addIPAddressToBlockedList ( ipAddress ) ;
}
lastBadConnectionAttempt . first + + ;
lastBadConnectionAttempt . second = time ( NULL ) ;
}
2010-10-23 11:06:47 +02:00
2013-02-19 23:00:15 +01:00
bool ServerInterface : : getStartInGameConnectionLaunch ( ) {
bool result = false ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slots [ slotIndex ] ! = NULL ) {
ConnectionSlot * slot = slots [ slotIndex ] ;
2013-02-19 23:00:15 +01:00
if ( slot - > getStartInGameConnectionLaunch ( ) = = true ) {
result = true ;
break ;
}
}
}
return result ;
}
bool ServerInterface : : getPauseForInGameConnection ( ) {
bool result = false ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slots [ slotIndex ] ! = NULL ) {
ConnectionSlot * slot = slots [ slotIndex ] ;
2013-02-19 23:00:15 +01:00
if ( slot - > getPauseForInGameConnection ( ) = = true ) {
result = true ;
break ;
}
}
}
return result ;
}
bool ServerInterface : : getUnPauseForInGameConnection ( ) {
bool result = false ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slots [ slotIndex ] ! = NULL ) {
ConnectionSlot * slot = slots [ slotIndex ] ;
2013-05-26 05:35:31 +02:00
if ( slot - > isConnected ( ) = = true ) {
if ( slot - > isReady ( ) = = true ) {
result = true ;
if ( slot - > getUnPauseForInGameConnection ( ) = = false ) {
result = false ;
break ;
}
}
else {
result = false ;
break ;
}
2013-02-19 23:00:15 +01:00
}
}
}
2013-12-14 08:04:12 +01:00
if ( result = = true ) {
2013-05-26 05:35:31 +02:00
resumeGameStartTime = time ( NULL ) ;
}
2013-02-19 23:00:15 +01:00
return result ;
}
2013-06-05 22:04:03 +02:00
ConnectionSlot * ServerInterface : : findSlotForUUID ( string uuid , bool unConnectedOnly ) {
ConnectionSlot * result = NULL ;
if ( uuid ! = " " ) {
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutexSlot ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
ConnectionSlot * connectionSlot = slots [ slotIndex ] ;
if ( connectionSlot ! = NULL ) {
2013-06-05 22:04:03 +02:00
if ( connectionSlot - > getUUID ( ) = = uuid ) {
if ( unConnectedOnly = = false | |
( unConnectedOnly = = true & & connectionSlot - > isConnected ( ) = = false ) ) {
2013-12-19 08:35:27 +01:00
2013-06-05 22:04:03 +02:00
if ( result = = NULL | |
2013-12-19 08:35:27 +01:00
( result - > getConnectedTime ( ) > connectionSlot - > getConnectedTime ( ) ) )
2013-06-05 22:04:03 +02:00
result = connectionSlot ;
}
}
}
}
}
return result ;
}
2012-04-13 22:20:40 +02:00
void ServerInterface : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * serverInterfaceNode = rootNode - > addChild ( " ServerInterface " ) ;
2013-12-19 08:35:27 +01:00
for ( int slotIndex = 0 ; exitServer = = false & & slotIndex < GameConstants : : maxPlayers ; + + slotIndex ) {
MutexSafeWrapper safeMutex ( slotAccessorMutexes [ slotIndex ] , CODE_AT_LINE_X ( slotIndex ) ) ;
if ( slots [ slotIndex ] ! = NULL ) {
2012-04-13 22:20:40 +02:00
XmlNode * slotNode = serverInterfaceNode - > addChild ( " Slot " ) ;
2013-12-19 08:35:27 +01:00
ConnectionSlot * slot = slots [ slotIndex ] ;
2012-04-13 22:20:40 +02:00
if ( slot ! = NULL ) {
slotNode - > addAttribute ( " isconnected " , intToStr ( slot - > isConnected ( ) ) , mapTagReplacements ) ;
slotNode - > addAttribute ( " sessionkey " , intToStr ( slot - > getSessionKey ( ) ) , mapTagReplacements ) ;
slotNode - > addAttribute ( " ipaddress " , slot - > getSocket ( false ) - > getIpAddress ( ) , mapTagReplacements ) ;
slotNode - > addAttribute ( " name " , slot - > getName ( ) , mapTagReplacements ) ;
2013-06-01 04:31:12 +02:00
slotNode - > addAttribute ( " uuid " , slot - > getUUID ( ) , mapTagReplacements ) ;
2012-04-13 22:20:40 +02:00
}
else {
slotNode - > addAttribute ( " isconnected " , intToStr ( false ) , mapTagReplacements ) ;
}
}
}
}
2010-03-17 07:25:19 +01:00
} } //end namespace