- 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:
parent
b8357b8696
commit
560ed46cc0
|
@ -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__);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
//!!!
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue