- attempt to fix lag issue when resuming paused network game (also for resume joining in progress game)

This commit is contained in:
Mark Vejvoda 2013-03-01 06:52:33 +00:00
parent 5aaa023476
commit b6cefa3388
8 changed files with 238 additions and 112 deletions

View File

@ -110,6 +110,7 @@ Game::Game() : ProgramState(NULL) {
withRainEffect=false;
program=NULL;
gameStarted=false;
this->initialResumeSpeedLoops=false;
highlightCellTexture=NULL;
lastMasterServerGameStatsDump=0;
@ -166,6 +167,7 @@ Game::Game() : ProgramState(NULL) {
void Game::resetMembers() {
Unit::setGame(this);
gameStarted = false;
this->initialResumeSpeedLoops = false;
original_updateFps = GameConstants::updateFps;
original_cameraFps = GameConstants::cameraFps;
@ -1514,6 +1516,14 @@ void Game::init(bool initForPreviewOnly) {
perfList.push_back(perfBuf);
}
if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL && clientInterface->getResumeInGameJoin() == true) {
clientInterface->sendResumeGameMessage();
//this->initialResumeSpeedLoops = true;
}
}
gameStarted = true;
if(this->masterserverMode == true) {
@ -1698,6 +1708,15 @@ void Game::update() {
// b) Updates depandant on speed
int updateLoops= getUpdateLoops();
// Temp speed boost when player first joins an in progress game
//if(this->initialResumeSpeedLoops == true && updateLoops == 1) {
if(this->initialResumeSpeedLoops == true) {
printf("Resume #1\n");
this->initialResumeSpeedLoops = false;
updateLoops = 80;
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(showPerfStats) {
sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis());
@ -2154,6 +2173,18 @@ void Game::update() {
}
commander.tryResumeGame(false);
resumeRequestSent = true;
// server->setAllowInGameConnections(false);
// for(int i = 0; i < world.getFactionCount(); ++i) {
// Faction *faction = world.getFaction(i);
// ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex());
// if(slot != NULL && slot->isConnected() == false) {
// server->setAllowInGameConnections(false);
// server->removeSlot(faction->getStartLocationIndex());
// }
// }
//server->shutdownFTPServer();
//return;
}
else if(server->getStartInGameConnectionLaunch() == true) {
@ -2220,7 +2251,7 @@ void Game::update() {
// Make the server wait a bit for clients to start.
if(paused == false && resumeRequestSent == true) {
resumeRequestSent = false;
sleep(500);
//sleep(500);
}
}
// END - Handle joining in progress games
@ -5406,6 +5437,15 @@ void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches
}
}
setupPopupMenus(false);
//!!!
NetworkManager &networkManager= NetworkManager::getInstance();
if(networkManager.getNetworkRole() == nrClient) {
//ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
//if(clientInterface != NULL && clientInterface->getResumeInGameJoin() == true) {
initialResumeSpeedLoops = true;
//}
}
}
else {
console.addLine(lang.get("GamePaused"));

View File

@ -198,6 +198,7 @@ private:
MasterSlaveThreadController masterController;
bool inJoinGameLoading;
bool initialResumeSpeedLoops;
public:
Game();

View File

@ -52,8 +52,8 @@ ClientInterface::ClientInterface() : GameNetworkInterface() {
networkCommandListThread = NULL;
cachedPendingCommandsIndex = 0;
pausedForInGameJoin = false;
readyForInGameJoin = false;
this->pausedForInGameJoin = false;
this->readyForInGameJoin = false;
clientSocket= NULL;
sessionKey = 0;
launchGame= false;
@ -657,7 +657,7 @@ void ClientInterface::updateLobby() {
if(gotCmd == false) {
throw megaglest_runtime_error("error retrieving nmtCommandList returned false!");
}
pausedForInGameJoin = true;
this->pausedForInGameJoin = true;
}
break;
@ -932,7 +932,8 @@ void ClientInterface::updateFrame(int *checkFrame) {
}
else {
if(checkFrame == NULL) {
sleep(15);
//sleep(15);
sleep(0);
}
}
}
@ -1014,9 +1015,9 @@ bool ClientInterface::isMasterServerAdminOverride() {
void ClientInterface::waitUntilReady(Checksum* checksum) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
bool signalServerWhenReadyToStartJoinedGame = readyForInGameJoin;
pausedForInGameJoin = false;
readyForInGameJoin = false;
bool signalServerWhenReadyToStartJoinedGame = this->readyForInGameJoin;
this->pausedForInGameJoin = false;
this->readyForInGameJoin = false;
Logger &logger= Logger::getInstance();
Chrono chrono;
@ -1260,7 +1261,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//check checksum
if(joinGameInProgress == false && networkMessageReady.getChecksum() != checksum->getSum()) {
if(this->joinGameInProgress == false && networkMessageReady.getChecksum() != checksum->getSum()) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
Lang &lang= Lang::getInstance();
@ -1342,8 +1343,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) {
//printf("Client signalServerWhenReadyToStartJoinedGame = %d\n",signalServerWhenReadyToStartJoinedGame);
if(signalServerWhenReadyToStartJoinedGame == true) {
NetworkMessageReady networkMessageReady;
sendMessage(&networkMessageReady);
this->resumeInGameJoin = true;
}
else {
// delay the start a bit, so clients have more room to get messages
@ -1358,6 +1358,11 @@ void ClientInterface::waitUntilReady(Checksum* checksum) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
}
void ClientInterface::sendResumeGameMessage() {
NetworkMessageReady networkMessageReady;
sendMessage(&networkMessageReady);
}
void ClientInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal,
string targetLanguage) {

View File

@ -70,6 +70,7 @@ private:
bool joinGameInProgressLaunch;
bool pausedForInGameJoin;
bool readyForInGameJoin;
bool resumeInGameJoin;
public:
ClientInterface();
@ -85,6 +86,9 @@ public:
bool getPausedForInGameJoin() const { return pausedForInGameJoin; }
bool getReadyForInGameJoin() const { return readyForInGameJoin; }
bool getResumeInGameJoin() const { return resumeInGameJoin; }
void sendResumeGameMessage();
//message processing
virtual void update();
virtual void updateLobby();

View File

@ -187,55 +187,98 @@ void ConnectionSlotThread::execute() {
break;
}
semTaskSignalled.waitTillSignalled();
if(this->slotInterface->getAllowInGameConnections() == true &&
this->slotInterface->isClientConnected(slotIndex) == false) {
//printf("#1 Non connected slot: %d waiting for client connection..\n",slotIndex);
sleep(100);
static string masterSlaveOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MasterSlaveThreadControllerSafeWrapper safeMasterController(masterController,20000,masterSlaveOwnerId);
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
//printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount);
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount);
//if(eventCount > 0) {
ConnectionSlotEvent eventCopy;
eventCopy.eventType = eReceiveSocketData;
eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex);
eventCopy.eventId = -1;
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
//if(eventCopy.eventId > 0) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount,(int)eventCopy.eventId);
//printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
//this->slotInterface->slotUpdateTask(&eventCopy);
//printf("#2 Non connected slot: %d waiting for client connection..\n",slotIndex);
this->slotUpdateTask(&eventCopy);
//setTaskCompleted(eventCopy.eventId);
//printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
//}
//}
//else {
// safeMutex.ReleaseLock();
//}
}
else {
semTaskSignalled.waitTillSignalled();
MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE);
int eventCount = eventList.size();
static string masterSlaveOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MasterSlaveThreadControllerSafeWrapper safeMasterController(masterController,20000,masterSlaveOwnerId);
//printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount);
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
if(eventCount > 0) {
ConnectionSlotEvent eventCopy;
eventCopy.eventId = -1;
MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE);
int eventCount = eventList.size();
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventCompleted == false) {
eventCopy = slotEvent;
break;
}
}
//printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount);
safeMutex.ReleaseLock();
if(eventCount > 0) {
ConnectionSlotEvent eventCopy;
eventCopy.eventId = -1;
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventCompleted == false) {
eventCopy = slotEvent;
break;
}
}
if(eventCopy.eventId > 0) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
safeMutex.ReleaseLock();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount,(int)eventCopy.eventId);
//printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
//this->slotInterface->slotUpdateTask(&eventCopy);
this->slotUpdateTask(&eventCopy);
setTaskCompleted(eventCopy.eventId);
//printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
}
}
else {
safeMutex.ReleaseLock();
}
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
if(eventCopy.eventId > 0) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount,(int)eventCopy.eventId);
//printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
//this->slotInterface->slotUpdateTask(&eventCopy);
this->slotUpdateTask(&eventCopy);
setTaskCompleted(eventCopy.eventId);
//printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId);
}
}
else {
safeMutex.ReleaseLock();
}
}
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -348,10 +391,10 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) {
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
if(serverInterface->getGameHasBeenInitiated() == true &&
serverInterface->getAllowInGameConnections() == true) {
//if(serverInterface->getGameHasBeenInitiated() == true &&
//serverInterface->getAllowInGameConnections() == true) {
//printf("Checking updateSlot event = %p\n",event);
}
//}
if(event != NULL) {
bool &socketTriggered = event->socketTriggered;
@ -363,13 +406,13 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(serverInterface->getGameHasBeenInitiated() == true &&
serverInterface->getAllowInGameConnections() == true) {
//if(serverInterface->getGameHasBeenInitiated() == true &&
//serverInterface->getAllowInGameConnections() == true) {
//printf("Checking for new client connection on slot, checkForNewClients: %d this->canAcceptConnections: %d\n",checkForNewClients,this->canAcceptConnections);
}
//}
if((serverInterface->getGameHasBeenInitiated() == false ||
serverInterface->getAllowInGameConnections() == true ||
(serverInterface->getAllowInGameConnections() == true && this->isConnected() == false) ||
//(this->getSocket() != NULL && socketTriggered == true))) {
socketTriggered == true)) {
if(socketTriggered == true ||
@ -1289,7 +1332,8 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
double LAG_CHECK_GRACE_PERIOD = 15;
if(this->serverInterface->getGameStartTime() > 0 &&
difftime((long int)time(NULL),this->serverInterface->getGameStartTime()) >= LAG_CHECK_GRACE_PERIOD) {
difftime((long int)time(NULL),this->serverInterface->getGameStartTime()) >= LAG_CHECK_GRACE_PERIOD &&
difftime((long int)time(NULL),this->getConnectedTime()) >= LAG_CHECK_GRACE_PERIOD) {
if(this->isConnected() == true && this->gotIntro == true && this->skipLagCheck == false) {
double clientLag = this->serverInterface->getCurrentFrameCount() - this->getCurrentFrameCount();
double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0);

View File

@ -66,6 +66,10 @@ public:
//
class ConnectionSlotCallbackInterface {
public:
virtual bool isClientConnected(int index) = 0;
virtual bool getAllowInGameConnections() const = 0;
virtual ConnectionSlot *getSlot(int index) = 0;
virtual void slotUpdateTask(ConnectionSlotEvent *event) = 0;
virtual ~ConnectionSlotCallbackInterface() {}
};

View File

@ -78,6 +78,7 @@ ServerInterface::ServerInterface(bool publishEnabled) :GameNetworkInterface() {
inBroadcastMessage = false;
lastGlobalLagCheckTime = 0;
masterserverAdminRequestLaunch = false;
lastListenerSlotCheckTime = 0;
// This is an admin port listening only on the localhost intended to
// give current connection status info
@ -260,11 +261,7 @@ ServerInterface::~ServerInterface() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
close();
if(ftpServer != NULL) {
ftpServer->shutdownAndWait();
delete ftpServer;
ftpServer = NULL;
}
shutdownFTPServer();
shutdownMasterserverPublishThread();
lastMasterserverHeartbeatTime = 0;
@ -885,11 +882,12 @@ void ServerInterface::signalClientsToRecieveData(std::map<PLATFORM_SOCKET,bool>
//socketTriggeredList[clientSocket] = true;
//socketTriggered = socketTriggeredList[clientSocket];
//}
}
ConnectionSlotEvent &event = eventList[i];
bool socketSignalled = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
if(connectionSlot != NULL && socketTriggered == true) {
mapSlotSignalledList[i] = socketSignalled;
ConnectionSlotEvent &event = eventList[i];
bool socketSignalled = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
if(connectionSlot != NULL && socketTriggered == true) {
mapSlotSignalledList[i] = socketSignalled;
}
}
}
}
@ -956,7 +954,8 @@ void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSigna
//printf("===> IN slot %d - About to checkForCompletedClients\n",i);
ConnectionSlot* connectionSlot = slots[i];
if(connectionSlot != NULL && mapSlotSignalledList[i] == true &&
if(connectionSlot != NULL && connectionSlot->isConnected() == true &&
mapSlotSignalledList[i] == true &&
connectionSlot->getJoinGameInProgress() == false &&
slotsCompleted.find(i) == slotsCompleted.end()) {
try {
@ -1017,7 +1016,8 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot* connectionSlot = slots[i];
if(connectionSlot != NULL && mapSlotSignalledList[i] == true &&
if(connectionSlot != NULL && connectionSlot->isConnected() == true &&
mapSlotSignalledList[i] == true &&
slotsCompleted.find(i) == slotsCompleted.end()) {
try {
std::vector<std::string> errorList = connectionSlot->getThreadErrorList();
@ -1306,8 +1306,9 @@ void ServerInterface::dispatchPendingUnMarkCellMessages(std::vector <string> &er
}
void ServerInterface::update() {
bool miniDebugPerf = false;
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled || miniDebugPerf) chrono.start();
//printf("\nServerInterface::update -- A\n");
@ -1320,6 +1321,7 @@ void ServerInterface::update() {
//printf("\nServerInterface::update -- B\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
processTextMessageQueue();
processBroadCastMessageQueue();
@ -1327,6 +1329,7 @@ void ServerInterface::update() {
//printf("\nServerInterface::update -- C\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
//update all slots
@ -1335,9 +1338,10 @@ void ServerInterface::update() {
//printf("\nServerInterface::update -- D\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(gameHasBeenInitiated == false ||
this->getAllowInGameConnections() == true ||
//this->getAllowInGameConnections() == true ||
socketTriggeredList.empty() == false) {
//printf("\nServerInterface::update -- E\n");
@ -1352,8 +1356,10 @@ void ServerInterface::update() {
if(hasData) if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(gameHasBeenInitiated == false || hasData == true || this->getAllowInGameConnections() == true) {
//if(gameHasBeenInitiated == false || hasData == true || this->getAllowInGameConnections() == true) {
if(gameHasBeenInitiated == false || hasData == true) {
std::map<int,bool> mapSlotSignalledList;
// Step #1 tell all connection slot worker threads to receive socket data
@ -1361,6 +1367,7 @@ void ServerInterface::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #2\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(gameHasBeenInitiated == false || hasData == true) {
// Step #2 check all connection slot worker threads for completed status
@ -1368,6 +1375,7 @@ void ServerInterface::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #3 check clients for any lagging scenarios and try to deal with them
@ -1375,6 +1383,7 @@ void ServerInterface::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//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
@ -1382,6 +1391,7 @@ void ServerInterface::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
// Step #5 dispatch pending chat messages
@ -1401,6 +1411,7 @@ void ServerInterface::update() {
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
}
else if(gameHasBeenInitiated == true &&
difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
@ -1411,6 +1422,7 @@ void ServerInterface::update() {
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
}
else if(gameHasBeenInitiated == true &&
difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
@ -1422,8 +1434,12 @@ void ServerInterface::update() {
checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
}
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
// Check if we need to switch masterserver admin to a new player because original admin disconnected
if(gameHasBeenInitiated == true && this->gameSettings.getMasterserver_admin() > 0) {
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//!!!
bool foundAdminSlot = false;
int iFirstConnectedSlot = -1;
@ -1458,7 +1474,10 @@ void ServerInterface::update() {
}
//printf("\nServerInterface::update -- G\n");
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
checkListenerSlots();
if(miniDebugPerf && chrono.getMillis() > 10) printf("In [%s::%s Line: %d] took " MG_I64_SPECIFIER " msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
}
catch(const exception &ex) {
//printf("\nServerInterface::update -- H\n");
@ -2089,7 +2108,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
if(connectionSlot != NULL && connectionSlot->isConnected()) {
connectionSlot->getSocket()->setBlock(true);
}
else if(allowInGameConnections == true) {
else if(this->getAllowInGameConnections() == true) {
// Open slots for joining in progress game
if(gameSettings->getFactionControl(factionIndex) != ctClosed &&
gameSettings->getFactionControl(factionIndex) != ctHuman) {
@ -2107,7 +2126,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
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);
if(allowInGameConnections == false) {
if(this->getAllowInGameConnections() == false) {
serverSocket.stopBroadCastThread();
}
@ -2127,12 +2146,8 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
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);
if(allowInGameConnections == false) {
if(ftpServer != NULL) {
ftpServer->shutdownAndWait();
delete ftpServer;
ftpServer = NULL;
}
if(this->getAllowInGameConnections() == false) {
shutdownFTPServer();
}
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);
@ -2148,12 +2163,8 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
}
}
if(allowInGameConnections == false) {
if(ftpServer != NULL) {
ftpServer->shutdownAndWait();
delete ftpServer;
ftpServer = NULL;
}
if(this->getAllowInGameConnections() == false) {
shutdownFTPServer();
}
gameLaunched = true;
@ -2162,35 +2173,46 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
return bOkToStart;
}
void ServerInterface::shutdownFTPServer() {
if(ftpServer != NULL) {
ftpServer->shutdownAndWait();
delete ftpServer;
ftpServer = NULL;
}
}
void ServerInterface::checkListenerSlots() {
if(gameLaunched == true && allowInGameConnections == true) {
bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets","true");
if(gameLaunched == true && this->getAllowInGameConnections() == true) {
if(difftime((long int)time(NULL),lastListenerSlotCheckTime) >= 7) {
lastListenerSlotCheckTime = time(NULL);
bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets","true");
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
int factionIndex = gameSettings.getFactionIndexForStartLocation(i);
if(gameSettings.getFactionControl(factionIndex) != ctClosed &&
gameSettings.getFactionControl(factionIndex) != ctHuman) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
int factionIndex = gameSettings.getFactionIndexForStartLocation(i);
if(gameSettings.getFactionControl(factionIndex) != ctClosed &&
gameSettings.getFactionControl(factionIndex) != ctHuman) {
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot *connectionSlot= slots[i];
// Open slots for joining in progress game
if(connectionSlot == NULL) {
printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot *connectionSlot= slots[i];
// Open slots for joining in progress game
if(connectionSlot == NULL) {
printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
addSlot(i);
connectionSlot = slots[i];
if(useInGameBlockingClientSockets == true) {
connectionSlot->getSocket()->setBlock(true);
addSlot(i);
connectionSlot = slots[i];
if(useInGameBlockingClientSockets == true) {
connectionSlot->getSocket()->setBlock(true);
}
connectionSlot->setCanAcceptConnections(true);
}
connectionSlot->setCanAcceptConnections(true);
}
else if(connectionSlot != NULL &&
connectionSlot->getCanAcceptConnections() == false &&
connectionSlot->isConnected() == false) {
printf("Removing slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
else if(connectionSlot != NULL &&
connectionSlot->getCanAcceptConnections() == false &&
connectionSlot->isConnected() == false) {
printf("Removing slot for in game connections, slot: %d, factionindex: %d name: %s\n",i,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str());
this->removeSlot(i);
this->removeSlot(i);
}
}
}
}
@ -2325,6 +2347,9 @@ void ServerInterface::updateListen() {
if(gameHasBeenInitiated == true && this->getAllowInGameConnections() == false) {
return;
}
//printf("updateListen() #1!\n");
int openSlotCount = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));

View File

@ -99,6 +99,7 @@ private:
bool allowInGameConnections;
bool gameLaunched;
time_t lastListenerSlotCheckTime;
public:
ServerInterface(bool publishEnabled);
@ -108,13 +109,15 @@ public:
time_t getGameStartTime() const { return gameStartTime; }
bool getAllowInGameConnections() const { return allowInGameConnections; }
virtual bool getAllowInGameConnections() const { return allowInGameConnections; }
void setAllowInGameConnections(bool value) { allowInGameConnections = value; }
bool getStartInGameConnectionLaunch();
bool getPauseForInGameConnection();
bool getUnPauseForInGameConnection();
void shutdownFTPServer();
virtual void close();
virtual void update();
virtual void updateLobby() { };
@ -150,7 +153,7 @@ public:
void addSlot(int playerIndex);
bool switchSlot(int fromPlayerIndex, int toPlayerIndex);
void removeSlot(int playerIndex, int lockedSlotIndex = -1);
ConnectionSlot *getSlot(int playerIndex);
virtual ConnectionSlot *getSlot(int playerIndex);
int getSlotCount();
int getConnectedSlotCount(bool authenticated);
@ -172,7 +175,7 @@ public:
virtual void slotUpdateTask(ConnectionSlotEvent *event) { };
bool hasClientConnection();
bool isClientConnected(int index);
virtual bool isClientConnected(int index);
int getCurrentFrameCount() const {
return currentFrameCount;