- more bugfixes for slot switching and joining in progress games

- disallow server to toggle pause state when client is joining
- fix dmp extension on linux
This commit is contained in:
Mark Vejvoda 2013-03-06 14:29:49 +00:00
parent b8357b8696
commit 560ed46cc0
14 changed files with 205 additions and 90 deletions

View File

@ -483,13 +483,17 @@ void Commander::tryDisconnectNetworkPlayer(const Faction* faction, int playerInd
pushNetworkCommand(&command);
}
void Commander::tryPauseGame(bool clearCaches) const {
NetworkCommand command(this->world,nctPauseResume, 1, (clearCaches == true ? 1 : 0));
void Commander::tryPauseGame(bool joinNetworkGame, bool clearCaches) const {
NetworkCommand command(this->world,nctPauseResume,1);
command.commandTypeId = (clearCaches == true ? 1 : 0);
command.unitTypeId = (joinNetworkGame == true ? 1 : 0);
pushNetworkCommand(&command);
}
void Commander::tryResumeGame(bool clearCaches) const {
NetworkCommand command(this->world,nctPauseResume, 0, (clearCaches == true ? 1 : 0));
void Commander::tryResumeGame(bool joinNetworkGame, bool clearCaches) const {
NetworkCommand command(this->world,nctPauseResume,0);
command.commandTypeId = (clearCaches == true ? 1 : 0);
command.unitTypeId = (joinNetworkGame == true ? 1 : 0);
pushNetworkCommand(&command);
}
@ -873,12 +877,13 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const {
commandWasHandled = true;
bool pauseGame = networkCommand->getUnitId() != 0;
bool clearCaches = networkCommand->getCommandTypeId();
bool pauseGame = networkCommand->getUnitId() != 0;
bool clearCaches = networkCommand->getCommandTypeId();
bool joinNetworkGame = networkCommand->getUnitTypeId();
Game *game = this->world->getGame();
//printf("nctPauseResume pauseGame = %d\n",pauseGame);
game->setPaused(pauseGame,true,clearCaches);
game->setPaused(pauseGame,true,clearCaches,joinNetworkGame);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctPauseResume\n",__FILE__,__FUNCTION__,__LINE__);
}

View File

@ -114,8 +114,10 @@ public:
void trySwitchTeam(const Faction* faction, int teamIndex) const;
void trySwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) const;
void tryDisconnectNetworkPlayer(const Faction* faction, int playerIndex) const;
void tryPauseGame(bool clearCaches) const;
void tryResumeGame(bool clearCaches) const;
void tryPauseGame(bool joinNetworkGame, bool clearCaches) const;
void tryResumeGame(bool joinNetworkGame, bool clearCaches) const;
void tryNetworkPlayerDisconnected(int factionIndex) const;
Command* buildCommand(const NetworkCommand* networkCommand) const;

View File

@ -79,6 +79,7 @@ Game::Game() : ProgramState(NULL) {
avgRenderFps=0;
currentAvgRenderFpsTotal=0;
paused=false;
pausedForJoinGame=false;
pauseRequestSent=false;
resumeRequestSent=false;
pauseStateChanged=false;
@ -238,6 +239,7 @@ void Game::resetMembers() {
currentAvgRenderFpsTotal=0;
tickCount=0;
paused= false;
pausedForJoinGame=false;
resumeRequestSent=false;
pauseRequestSent=false;
pauseStateChanged=false;
@ -1519,6 +1521,9 @@ void Game::init(bool initForPreviewOnly) {
if(role == nrClient) {
ClientInterface *clientInterface = dynamic_cast<ClientInterface *>(networkManager.getClientInterface());
if(clientInterface != NULL && clientInterface->getResumeInGameJoin() == true) {
//printf("Client sending resume message to server...\n");
clientInterface->sendResumeGameMessage();
//this->initialResumeSpeedLoops = true;
}
@ -2085,7 +2090,7 @@ void Game::update() {
}
}
if(paused == false || clientNeedsGameSetup == true) {
if(pausedForJoinGame == false || clientNeedsGameSetup == true) {
//printf("================= Switching player pausing game\n");
for(int i = 0; i < world.getFactionCount(); ++i) {
@ -2164,15 +2169,17 @@ void Game::update() {
}
}
if(pauseAndSaveGameForNewClient == true && paused == false &&
if(pauseAndSaveGameForNewClient == true && pausedForJoinGame == false &&
pauseRequestSent == false) {
commander.tryPauseGame(true);
//printf("Pausing game for join in progress game...\n");
commander.tryPauseGame(true,true);
pauseRequestSent = true;
//return;
return;
}
}
//else if(server->getPauseForInGameConnection() == true && paused == true &&
if(paused == true) {
if(pausedForJoinGame == true) {
if(pauseStateChanged == true) {
pauseStateChanged = false;
}
@ -2188,7 +2195,9 @@ void Game::update() {
slot->setUnPauseForInGameConnection(false);
}
}
commander.tryResumeGame(false);
//printf("Resuming game for join in progress game resumeRequestSent: %d...\n",resumeRequestSent);
commander.tryResumeGame(true,false);
resumeRequestSent = true;
// server->setAllowInGameConnections(false);
@ -2266,7 +2275,7 @@ void Game::update() {
//}
// Make the server wait a bit for clients to start.
if(paused == false && resumeRequestSent == true) {
if(pausedForJoinGame == false && resumeRequestSent == true) {
resumeRequestSent = false;
//sleep(500);
}
@ -2562,6 +2571,7 @@ bool Game::switchSetupForSlots(ServerInterface *& serverInterface,
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] caught exception error = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
}
}
//printf("AFTER switchSlot returned\n");
}
else {
try {
@ -3136,14 +3146,14 @@ void Game::tryPauseToggle(bool pauseValue) {
if(allowAdminMenuItems) {
if(pauseValue == true) {
commander.tryPauseGame(false);
commander.tryPauseGame(false,false);
}
else {
if(isNetworkGame == false) {
setPaused(pauseValue, true);
setPaused(pauseValue, true,false,false);
}
else {
commander.tryResumeGame(false);
commander.tryResumeGame(false,false);
}
}
}
@ -3437,10 +3447,10 @@ void Game::mouseDownLeft(int x, int y) {
if(allowAdminMenuItems) {
if(getPaused() == false) {
commander.tryPauseGame(false);
commander.tryPauseGame(false,false);
}
else {
commander.tryResumeGame(false);
commander.tryResumeGame(false,false);
}
}
}
@ -4347,10 +4357,10 @@ void Game::keyDown(SDL_KeyboardEvent key) {
if(allowAdminMenuItems) {
if(getPaused() == false) {
commander.tryPauseGame(false);
commander.tryPauseGame(false,false);
}
else {
commander.tryResumeGame(false);
commander.tryResumeGame(false,false);
}
}
}
@ -5433,17 +5443,51 @@ void Game::decSpeed() {
}
}
void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches) {
void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches, bool joinNetworkGame) {
bool speedChangesAllowed= !NetworkManager::getInstance().isNetworkGame();
//printf("Toggle pause value = %d, speedChangesAllowed = %d, forceAllowPauseStateChange = %d\n",value,speedChangesAllowed,forceAllowPauseStateChange);
if(forceAllowPauseStateChange == true || speedChangesAllowed == true) {
//printf("setPaused paused = %d, value = %d\n",paused,value);
// Cannot change pause state while client is joining in progress game
if(pausedForJoinGame == true && joinNetworkGame == false) {
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
Lang &lang= Lang::getInstance();
const vector<string> languageList = this->gameSettings.getUniqueNetworkPlayerLanguages();
bool haveClientConnectedButNoReady = 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() == true && slot->isReady() == false) {
for(unsigned int i = 0; i < languageList.size(); ++i) {
char szMsg[8096]="";
if(lang.hasString("JoinPlayerToCurrentGameLaunch",languageList[i]) == true) {
snprintf(szMsg,8096,lang.get("JoinPlayerToCurrentGameLaunch",languageList[i]).c_str(), slot->getName().c_str());
}
else {
snprintf(szMsg,8096,"Player: %s is about to join the game, please wait...",slot->getName().c_str());
}
bool localEcho = lang.isLanguageLocal(languageList[i]);
server->sendTextMessage(szMsg,-1, localEcho,languageList[i]);
haveClientConnectedButNoReady = true;
}
}
}
if(haveClientConnectedButNoReady == true) {
return;
}
}
Lang &lang= Lang::getInstance();
if(value == false) {
console.addLine(lang.get("GameResumed"));
paused= false;
pausedForJoinGame = false;
pauseStateChanged = true;
if(clearCaches == true) {
@ -5467,6 +5511,7 @@ void Game::setPaused(bool value,bool forceAllowPauseStateChange,bool clearCaches
else {
console.addLine(lang.get("GamePaused"));
paused= true;
pausedForJoinGame = joinNetworkGame;
pauseStateChanged = true;
//!!!

View File

@ -93,6 +93,8 @@ private:
bool pauseRequestSent;
bool resumeRequestSent;
bool pauseStateChanged;
bool pausedForJoinGame;
bool gameOver;
bool renderNetworkStatus;
bool showFullConsole;
@ -243,7 +245,7 @@ public:
Uint64 getTickCount() {return tickCount;}
bool getPaused();
void setPaused(bool value, bool forceAllowPauseStateChange=false,bool clearCaches=false);
void setPaused(bool value, bool forceAllowPauseStateChange,bool clearCaches,bool joinNetworkGame);
void tryPauseToggle(bool pause);
void setupRenderForVideo();
void saveGame();

View File

@ -5231,7 +5231,7 @@ static bool MinidumpCallback(const google_breakpad::MinidumpDescriptor& descript
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
char szBuf[8096];
snprintf(szBuf,8096,"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp",descriptor.directory().c_str(),descriptor.path());
snprintf(szBuf,8096,"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s",descriptor.directory().c_str(),descriptor.path());
//MessageBox(NULL, szBuf, "Unhandled error", MB_OK|MB_SYSTEMMODAL);
message(szBuf);
}

View File

@ -2709,7 +2709,8 @@ void MenuStateConnectedGame::update() {
clientInterface->updateLobby();
if(clientInterface->isConnected() && clientInterface->getPausedForInGameJoin() == false &&
//if(clientInterface->isConnected() && clientInterface->getPausedForInGameJoin() == false &&
if(clientInterface->isConnected() && clientInterface->getJoinGameInProgress() == false &&
pingCount >= 3 && clientInterface->getLastPingLag() >= (GameConstants::networkPingInterval * 3)) {
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(fileFTPProgressList.empty() == true) {

View File

@ -53,7 +53,6 @@ ClientInterface::ClientInterface() : GameNetworkInterface() {
cachedPendingCommandsIndex = 0;
cachedLastPendingFrameCount = 0;
this->pausedForInGameJoin = false;
this->readyForInGameJoin = false;
clientSocket= NULL;
sessionKey = 0;
@ -83,11 +82,13 @@ void ClientInterface::shutdownNetworkCommandListThread() {
if(networkCommandListThread != NULL) {
time_t elapsed = time(NULL);
this->quit = true;
networkCommandListThread->signalQuit();
for(;networkCommandListThread->canShutdown(false) == false &&
difftime((long int)time(NULL),elapsed) <= 15;) {
//sleep(150);
}
sleep(0);
if(networkCommandListThread->canShutdown(true)) {
delete networkCommandListThread;
networkCommandListThread = NULL;
@ -656,13 +657,14 @@ void ClientInterface::updateLobby() {
if(receiveMessage(&networkMessageReady)) {
this->readyForInGameJoin = true;
}
//printf("ClientInterface got nmtReady this->readyForInGameJoin: %d\n",this->readyForInGameJoin);
}
break;
case nmtCommandList:
{
int waitCount = 0;
//make sure we read the message
time_t receiveTimeElapsed = time(NULL);
NetworkMessageCommandList networkMessageCommandList;
@ -670,7 +672,6 @@ void ClientInterface::updateLobby() {
if(gotCmd == false) {
throw megaglest_runtime_error("error retrieving nmtCommandList returned false!");
}
this->pausedForInGameJoin = true;
}
break;
@ -1088,7 +1089,6 @@ 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 = this->readyForInGameJoin;
this->pausedForInGameJoin = false;
this->readyForInGameJoin = false;
Logger &logger= Logger::getInstance();
@ -1594,7 +1594,6 @@ void ClientInterface::close()
this->joinGameInProgress = false;
this->joinGameInProgressLaunch = false;
this->pausedForInGameJoin = false;
this->readyForInGameJoin = false;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
@ -1795,13 +1794,19 @@ void ClientInterface::broadcastGameSetup(const GameSettings *gameSettings) {
void ClientInterface::broadcastGameStart(const GameSettings *gameSettings) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//MutexSafeWrapper safeMutex(&serverSynchAccessor,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
if(this->joinGameInProgress == true) {
this->joinGameInProgressLaunch = true;
}
//printf("Sending game launch joinGameInProgress: %d\n",joinGameInProgress);
NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtLaunch);
//broadcastMessage(&networkMessageLaunch);
sendMessage(&networkMessageLaunch);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
this->joinGameInProgressLaunch = true;
}
void ClientInterface::setGameSettingsReceived(bool value) {
//printf("In [%s:%s] Line: %d gameSettingsReceived = %d value = %d, gameSettingsReceivedCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameSettingsReceived,value,gameSettingsReceivedCount);
gameSettingsReceived = value;

View File

@ -70,7 +70,6 @@ private:
bool joinGameInProgress;
bool joinGameInProgressLaunch;
bool pausedForInGameJoin;
bool readyForInGameJoin;
bool resumeInGameJoin;
@ -85,7 +84,6 @@ public:
bool getJoinGameInProgress() const { return joinGameInProgress; }
bool getJoinGameInProgressLaunch() const { return joinGameInProgressLaunch; }
bool getPausedForInGameJoin() const { return pausedForInGameJoin; }
bool getReadyForInGameJoin() const { return readyForInGameJoin; }
bool getResumeInGameJoin() const { return resumeInGameJoin; }

View File

@ -380,6 +380,14 @@ ConnectionSlot::~ConnectionSlot() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
void ConnectionSlot::setPlayerIndex(int value) {
playerIndex = value;
if(this->slotThreadWorker != NULL) {
this->slotThreadWorker->setSlotIndex(playerIndex);
}
}
void ConnectionSlot::setReady() {
this->ready= true;
this->skipLagCheck = false;
@ -960,7 +968,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
if(networkMessageLaunch.getMessageType() == nmtLaunch) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__);
//printf("Got launch request from client joinGameInProgress = %d!\n",joinGameInProgress);
//printf("Got launch request from client joinGameInProgress = %d joinGameInProgress = %d!\n",joinGameInProgress,joinGameInProgress);
}
else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",__FILE__,__FUNCTION__,__LINE__);
@ -974,8 +982,8 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
}
int minHeadLessPlayersRequired = Config::getInstance().getInt("MinHeadlessPlayersRequired","2");
if(joinGameInProgress == false && networkMessageLaunch.getMessageType() == nmtLaunch &&
ready == false &&
if(this->joinGameInProgress == false && networkMessageLaunch.getMessageType() == nmtLaunch &&
this->ready == false &&
this->serverInterface->getConnectedSlotCount(true) < minHeadLessPlayersRequired) {
Lang &lang= Lang::getInstance();
const vector<string> languageList = this->serverInterface->getGameSettings()->getUniqueNetworkPlayerLanguages();
@ -1000,7 +1008,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
}
}
else {
if(joinGameInProgress == false) {
if(this->joinGameInProgress == false) {
GameSettings gameSettingsBuffer;
networkMessageLaunch.buildGameSettings(&gameSettingsBuffer);
@ -1011,10 +1019,10 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
this->serverInterface->broadcastGameSetup(&gameSettingsBuffer, true);
}
if(joinGameInProgress == false && networkMessageLaunch.getMessageType() == nmtLaunch) {
if(this->joinGameInProgress == false && networkMessageLaunch.getMessageType() == nmtLaunch) {
this->serverInterface->setMasterserverAdminRequestLaunch(true);
}
else if(joinGameInProgress == true && networkMessageLaunch.getMessageType() == nmtLaunch) {
else if(this->joinGameInProgress == true && networkMessageLaunch.getMessageType() == nmtLaunch) {
//printf("!!! setStartInGameConnectionLaunch for client joinGameInProgress = %d!\n",joinGameInProgress);
//GameSettings gameSettingsBuffer;

View File

@ -102,7 +102,9 @@ public:
virtual void execute();
void signalUpdate(ConnectionSlotEvent *event);
bool isSignalCompleted(ConnectionSlotEvent *event);
int getSlotIndex() const {return slotIndex; }
void setSlotIndex(int index) { this->slotIndex = index; }
void purgeCompletedEvents();
void purgeAllEvents();
@ -172,7 +174,7 @@ public:
ConnectionSlotThread *getWorkerThread() { return slotThreadWorker; }
void update(bool checkForNewClients,int lockedSlotIndex);
void setPlayerIndex(int value) { playerIndex = value; }
void setPlayerIndex(int value);
int getPlayerIndex() const {return playerIndex;}
uint32 getConnectedRemoteIPAddress() const { return connectedRemoteIPAddress; }

View File

@ -495,6 +495,9 @@ void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex) {
bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
bool result = false;
//printf("#1 Server is switching slots\n");
//assert(fromPlayerIndex >= 0 && fromPlayerIndex < GameConstants::maxPlayers);
if(fromPlayerIndex < 0 || fromPlayerIndex >= GameConstants::maxPlayers) {
char szBuf[8096]="";
@ -517,9 +520,10 @@ bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) {
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[fromPlayerIndex],CODE_AT_LINE_X(fromPlayerIndex));
MutexSafeWrapper safeMutexSlot2(slotAccessorMutexes[toPlayerIndex],CODE_AT_LINE_X(toPlayerIndex));
//printf("#1 Server is switching slots\n");
//printf("#1a Server is switching slots\n");
if(slots[toPlayerIndex] != NULL &&
slots[toPlayerIndex]->isConnected() == false) {
slots[toPlayerIndex]->hasValidSocketId() == false) {
//printf("#2 Server is switching slots\n");
@ -548,6 +552,8 @@ bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) {
safeMutexSlot2.ReleaseLock();
safeMutex.ReleaseLock();
}
//printf("#4 Server is switching slots\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return result;
}
@ -1014,11 +1020,17 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
threadsDone = true;
// Examine all threads for completion of delegation
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//printf("#1 Check lag for i: %d\n",i);
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot* connectionSlot = slots[i];
if(connectionSlot != NULL && connectionSlot->hasValidSocketId() == true &&
if(connectionSlot != NULL && connectionSlot->isConnected() == true &&
connectionSlot->getSkipLagCheck() == false &&
mapSlotSignalledList[i] == true &&
slotsCompleted.find(i) == slotsCompleted.end()) {
//printf("#2 Check lag for i: %d playerindex: %d name [%s] socket: %d\n",i,connectionSlot->getPlayerIndex(),connectionSlot->getName().c_str(),connectionSlot->getSocketId());
try {
std::vector<std::string> errorList = connectionSlot->getThreadErrorList();
// Show any collected errors from threads
@ -1035,6 +1047,7 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
// Not done waiting for data yet
bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[i]) : true);
if(updateFinished == false) {
//printf("#2a Check lag for i: %d\n",i);
threadsDone = false;
break;
}
@ -1070,6 +1083,8 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
}
ConnectionSlotEvent &event = eventList[i];
mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
//printf("#2b Check lag for i: %d\n",i);
threadsDone = false;
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second);
@ -1087,7 +1102,12 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
}
}
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
//printf("#3 Check lag for i: %d\n",i);
if(connectionSlot != NULL && connectionSlot->isConnected() == true &&
connectionSlot->getSkipLagCheck() == false) {
//printf("#4 Check lag for i: %d\n",i);
try {
if(gameHasBeenInitiated == true &&
difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
@ -1117,6 +1137,8 @@ void ServerInterface::checkForLaggingClients(std::map<int,bool> &mapSlotSignalle
errorMsgList.push_back(ex.what());
}
}
//printf("#5 Check lag for i: %d\n",i);
}
}
}
@ -2144,18 +2166,28 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
if(connectionSlot != NULL && connectionSlot->isConnected()) {
connectionSlot->getSocket()->setBlock(true);
}
else if(this->getAllowInGameConnections() == true) {
// 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) {
addSlot(i);
connectionSlot = slots[i];
}
connectionSlot->setCanAcceptConnections(true);
bool requiresUPNPTrigger = false;
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);
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot *connectionSlot= slots[i];
if((connectionSlot == NULL || connectionSlot->isConnected() == false) &&
this->getAllowInGameConnections() == true) {
// 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) {
addSlot(i);
connectionSlot = slots[i];
requiresUPNPTrigger = true;
}
connectionSlot->setCanAcceptConnections(true);
}
}
}
@ -2203,6 +2235,10 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) {
shutdownFTPServer();
}
if(requiresUPNPTrigger == true) {
this->getServerSocket()->NETdiscoverUPnPDevices();
}
gameLaunched = true;
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);

View File

@ -1536,7 +1536,7 @@ void World::clearCaches() {
}
void World::togglePauseGame(bool pauseStatus,bool forceAllowPauseStateChange) {
game->setPaused(pauseStatus, forceAllowPauseStateChange);
game->setPaused(pauseStatus, forceAllowPauseStateChange, false, false);
}
void World::addConsoleText(const string &text) {

View File

@ -980,8 +980,7 @@ bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
{
bool bResult = false;
if(socketTriggeredList.empty() == false)
{
if(socketTriggeredList.empty() == false) {
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds;
FD_ZERO(&rfds);
@ -989,11 +988,9 @@ bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
string socketDebugList = "";
PLATFORM_SOCKET imaxsocket = 0;
for(std::map<PLATFORM_SOCKET,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); ++itermap)
{
itermap != socketTriggeredList.end(); ++itermap) {
PLATFORM_SOCKET socket = itermap->first;
if(Socket::isSocketValid(&socket) == true)
{
if(Socket::isSocketValid(&socket) == true) {
FD_SET(socket, &rfds);
imaxsocket = max(socket,imaxsocket);
@ -1004,8 +1001,7 @@ bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
}
}
if(imaxsocket > 0)
{
if(imaxsocket > 0) {
/* Wait up to 0 seconds. */
struct timeval tv;
tv.tv_sec = 0;
@ -1017,24 +1013,19 @@ bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
retval = select((int)imaxsocket + 1, &rfds, NULL, NULL, &tv);
}
if(retval < 0)
{
if(retval < 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s, socketDebugList [%s]\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str(),socketDebugList.c_str());
}
else if(retval)
{
else if(retval) {
bResult = true;
for(std::map<PLATFORM_SOCKET,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); ++itermap)
{
itermap != socketTriggeredList.end(); ++itermap) {
PLATFORM_SOCKET socket = itermap->first;
if (FD_ISSET(socket, &rfds))
{
if (FD_ISSET(socket, &rfds)) {
itermap->second = true;
}
else
{
else {
itermap->second = false;
}
}

View File

@ -16,6 +16,7 @@
#include <algorithm>
#include "platform_util.h"
#include "platform_common.h"
#include <memory>
using namespace std;
@ -136,6 +137,9 @@ public:
}
};
const bool debugMutexLock = false;
const int debugMutexLockMillisecondThreshold = 2000;
Mutex::Mutex(string ownerId) {
mutexAccessor = SDL_CreateMutex();
SDLMutexSafeWrapper safeMutex(&mutexAccessor);
@ -151,7 +155,10 @@ Mutex::Mutex(string ownerId) {
}
deleteownerId = "";
//chronoPerf = new Chrono();
chronoPerf = NULL;
if(debugMutexLock == true) {
chronoPerf = new Chrono();
}
}
Mutex::~Mutex() {
@ -168,8 +175,10 @@ Mutex::~Mutex() {
throw megaglest_runtime_error(szBuf);
}
//delete chronoPerf;
//chronoPerf = NULL;
if(debugMutexLock == true) {
delete chronoPerf;
chronoPerf = NULL;
}
if(mutex != NULL) {
deleteownerId = ownerId;
@ -184,16 +193,21 @@ void Mutex::p() {
snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str());
throw megaglest_runtime_error(szBuf);
}
//Chrono chrono;
//chrono.start();
std::auto_ptr<Chrono> chronoLockPerf;
if(debugMutexLock == true) {
chronoLockPerf.reset(new Chrono());
chronoLockPerf->start();
}
SDL_mutexP(mutex);
refCount++;
//if(chrono.getMillis() > 2000) {
// printf("Last ownerid: [%s]\n",lastownerId.c_str());
//}
//chronoPerf->start();
if(debugMutexLock == true) {
if(chronoLockPerf->getMillis() >= debugMutexLockMillisecondThreshold) {
printf("\n**WARNING possible mutex lock detected ms [%lld] Last ownerid: [%s]\n",(long long int)chronoLockPerf->getMillis(),lastownerId.c_str());
}
chronoPerf->start();
}
}
void Mutex::v() {
@ -205,9 +219,15 @@ void Mutex::v() {
refCount--;
lastownerId = ownerId;
//if(chronoPerf->getMillis() > 2000) {
// lastownerId = PlatformExceptionHandler::getStackTrace();
//}
if(debugMutexLock == true) {
if(chronoPerf->getMillis() >= debugMutexLockMillisecondThreshold) {
printf("About to get stacktrace for stuck mutex ...\n");
string oldLastownerId = lastownerId;
lastownerId = PlatformExceptionHandler::getStackTrace();
printf("\n**WARNING possible mutex lock (on unlock) detected ms [%lld] Last ownerid: [%s]\noldLastownerId: [%s]\n",(long long int)chronoPerf->getMillis(),lastownerId.c_str(),oldLastownerId.c_str());
}
}
SDL_mutexV(mutex);
}