From da1adab808c1a0e8017880e2a13d65d0dc0def83 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Sat, 25 Dec 2010 08:14:35 +0000 Subject: [PATCH] - bugfixes for fog of war enable at game end - Added more safety guards in threaded sockets in case this causes problems when things get very busy in the game during monster battles --- source/glest_game/graphics/renderer.cpp | 16 +++- .../glest_game/network/client_interface.cpp | 37 ++++------ source/glest_game/network/connection_slot.cpp | 74 ++++++++++--------- source/glest_game/network/connection_slot.h | 6 +- .../glest_game/network/server_interface.cpp | 12 +-- source/glest_game/world/world.h | 4 +- 6 files changed, 78 insertions(+), 71 deletions(-) diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index ebd4f02a..6ea29ae3 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -1818,7 +1818,13 @@ void Renderer::renderWater() { SurfaceCell *tc1= map->getSurfaceCell(i, j+1); int thisTeamIndex= world->getThisTeamIndex(); - if(tc0->getNearSubmerged() && (tc0->isExplored(thisTeamIndex) || tc1->isExplored(thisTeamIndex))){ + + bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); + if(cellExplored == false) { + cellExplored = (tc0->isExplored(thisTeamIndex) || tc1->isExplored(thisTeamIndex)); + } + + if(tc0->getNearSubmerged() && cellExplored == true) { glNormal3f(0.f, 1.f, 0.f); closed= false; @@ -4166,7 +4172,13 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, SurfaceCell *sc = map->getSurfaceCell(mapPos); Object *o = sc->getObject(); - bool isExplored = (sc->isExplored(world->getThisTeamIndex()) && o != NULL); + + bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); + if(cellExplored == false) { + cellExplored = sc->isExplored(world->getThisTeamIndex()); + } + + bool isExplored = (cellExplored == true && o != NULL); //bool isVisible = (sc->isVisible(world->getThisTeamIndex()) && o != NULL); bool isVisible = true; diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 338ad91d..ce37d24b 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -66,12 +66,10 @@ ClientInterface::ClientInterface() { this->setReceivedDataSynchCheck(false); } -ClientInterface::~ClientInterface() -{ +ClientInterface::~ClientInterface() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] destructor for %p\n",__FILE__,__FUNCTION__,__LINE__,this); - if(clientSocket != NULL && clientSocket->isConnected() == true) - { + if(clientSocket != NULL && clientSocket->isConnected() == true) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); string sQuitText = "has chosen to leave the game!"; @@ -79,9 +77,7 @@ ClientInterface::~ClientInterface() } SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - close(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete clientSocket; @@ -90,11 +86,11 @@ ClientInterface::~ClientInterface() SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -void ClientInterface::connect(const Ip &ip, int port) -{ +void ClientInterface::connect(const Ip &ip, int port) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__); delete clientSocket; + clientSocket = NULL; this->ip = ip; this->port = port; @@ -107,26 +103,23 @@ void ClientInterface::connect(const Ip &ip, int port) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END - socket = %d\n",__FILE__,__FUNCTION__,clientSocket->getSocketId()); } -void ClientInterface::reset() -{ - if(getSocket() != NULL) - { +void ClientInterface::reset() { + if(getSocket() != NULL) { string sQuitText = "has chosen to leave the game!"; sendTextMessage(sQuitText,-1); close(); } } -void ClientInterface::update() -{ +void ClientInterface::update() { NetworkMessageCommandList networkMessageCommandList(currentFrameCount); //send as many commands as we can - while(!requestedCommands.empty()){ - if(networkMessageCommandList.addCommand(&requestedCommands.back())){ + while(requestedCommands.empty() == false) { + if(networkMessageCommandList.addCommand(&requestedCommands.back())) { requestedCommands.pop_back(); } - else{ + else { break; } } @@ -136,14 +129,14 @@ void ClientInterface::update() if(networkMessageCommandList.getCommandCount() > 0 || (lastNetworkCommandListSendTime > 0 && lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait)) { - sendMessage(&networkMessageCommandList); lastNetworkCommandListSendTime = time(NULL); + sendMessage(&networkMessageCommandList); } // Possible cause of out of synch since we have more commands that need // to be sent in this frame - if(!requestedCommands.empty()) { - char szBuf[1024]=""; + if(requestedCommands.empty() == false) { + char szBuf[4096]=""; SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,requestedCommands.size()); string sMsg = "may go out of synch: client requestedCommands.size() = " + intToStr(requestedCommands.size()); @@ -514,12 +507,10 @@ void ClientInterface::updateLobby() { } } -void ClientInterface::updateKeyframe(int frameCount) -{ +void ClientInterface::updateKeyframe(int frameCount) { currentFrameCount = frameCount; bool done= false; - while(done == false) { //wait for the next message waitForMessage(); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index c64bdce1..a335bc7c 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -35,13 +35,15 @@ namespace Glest{ namespace Game{ ConnectionSlotThread::ConnectionSlotThread(int slotIndex) : BaseThread() { this->slotIndex = slotIndex; this->slotInterface = NULL; - this->event = NULL; + //this->event = NULL; + eventList.clear(); } ConnectionSlotThread::ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex) : BaseThread() { this->slotIndex = slotIndex; this->slotInterface = slotInterface; - this->event = NULL; + //this->event = NULL; + eventList.clear(); } void ConnectionSlotThread::setQuitStatus(bool value) { @@ -56,38 +58,36 @@ void ConnectionSlotThread::setQuitStatus(bool value) { } void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event = %p\n",__FILE__,__FUNCTION__,__LINE__,event); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event = %p\n",__FILE__,__FUNCTION__,__LINE__,event); if(event != NULL) { MutexSafeWrapper safeMutex(&triggerIdMutex); - this->event = event; + eventList.push_back(event); safeMutex.ReleaseLock(); } - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); semTaskSignalled.signal(); } void ConnectionSlotThread::setTaskCompleted(ConnectionSlotEvent *event) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); if(event != NULL) { MutexSafeWrapper safeMutex(&triggerIdMutex); event->eventCompleted = true; + eventList.erase(eventList.begin()); safeMutex.ReleaseLock(); } - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } -bool ConnectionSlotThread::isSignalCompleted() { +bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) { //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); - MutexSafeWrapper safeMutex(&triggerIdMutex); - bool result = (this->event != NULL ? this->event->eventCompleted : true); + bool result = (event != NULL ? event->eventCompleted : true); safeMutex.ReleaseLock(); - - if(result == false) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, result = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,result); - + //if(result == false) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, result = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,result); return result; } @@ -104,29 +104,36 @@ void ConnectionSlotThread::execute() { break; } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); semTaskSignalled.waitTillSignalled(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); if(getQuitStatus() == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - this->slotInterface->slotUpdateTask(this->event); + MutexSafeWrapper safeMutex(&triggerIdMutex); + int eventCount = eventList.size(); + safeMutex.ReleaseLock(true); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + if(eventCount > 0) { + safeMutex.Lock(); + ConnectionSlotEvent *event = eventList[0]; + safeMutex.ReleaseLock(); + + this->slotInterface->slotUpdateTask(event); + setTaskCompleted(event); + } + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); if(getQuitStatus() == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } - - setTaskCompleted(this->event); - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -177,21 +184,18 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex this->clearChatInfo(); } -ConnectionSlot::~ConnectionSlot() -{ +ConnectionSlot::~ConnectionSlot() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__); - BaseThread::shutdownAndWait(slotThreadWorker); - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - delete slotThreadWorker; + if(BaseThread::shutdownAndWait(slotThreadWorker) == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + delete slotThreadWorker; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } slotThreadWorker = NULL; SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - close(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); } @@ -701,15 +705,15 @@ void ConnectionSlot::signalUpdate(ConnectionSlotEvent *event) { slotThreadWorker->signalUpdate(event); } -bool ConnectionSlot::updateCompleted() { +bool ConnectionSlot::updateCompleted(ConnectionSlotEvent *event) { assert(slotThreadWorker != NULL); //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); bool waitingForThread = (slotThreadWorker != NULL && - slotThreadWorker->isSignalCompleted() == false && - slotThreadWorker->getQuitStatus() == false && - slotThreadWorker->getRunningStatus() == true); + slotThreadWorker->isSignalCompleted(event) == false && + slotThreadWorker->getQuitStatus() == false && + slotThreadWorker->getRunningStatus() == true); //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, waitingForThread = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,waitingForThread); diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 5c680ca7..9d48d1c6 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -74,7 +74,7 @@ protected: ConnectionSlotCallbackInterface *slotInterface; Semaphore semTaskSignalled; Mutex triggerIdMutex; - ConnectionSlotEvent *event; + vector eventList; int slotIndex; virtual void setQuitStatus(bool value); @@ -85,7 +85,7 @@ public: ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex); virtual void execute(); void signalUpdate(ConnectionSlotEvent *event); - bool isSignalCompleted(); + bool isSignalCompleted(ConnectionSlotEvent *event); int getSlotIndex() const {return slotIndex; } }; @@ -147,7 +147,7 @@ public: void clearPendingNetworkCommandList(); void signalUpdate(ConnectionSlotEvent *event); - bool updateCompleted(); + bool updateCompleted(ConnectionSlotEvent *event); virtual void sendMessage(const NetworkMessage* networkMessage); int getCurrentFrameCount() const { return currentFrameCount; } diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 3be50d4c..cc9e2cc2 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -458,15 +458,15 @@ bool ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot event.socketTriggered = socketTriggered; event.triggerId = slotIndex; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); // Step #1 tell all connection slot worker threads to receive socket data if(connectionSlot != NULL) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); if(socketTriggered == true || connectionSlot->isConnected() == false) { connectionSlot->signalUpdate(&event); slotSignalled = true; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); } } @@ -564,7 +564,7 @@ void ServerInterface::update() { //connectionSlot = slots[i]; // Not done waiting for data yet - bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted() : true); + bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[i]) : true); if(updateFinished == false) { threadsDone = false; break; @@ -618,7 +618,7 @@ void ServerInterface::update() { connectionSlot = slots[i]; // Not done waiting for data yet - bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted() : true); + bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[i]) : true); if(updateFinished == false) { threadsDone = false; //sleep(0); @@ -1208,7 +1208,7 @@ void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int connectionSlot->clearThreadErrorList(); } - if(connectionSlot->updateCompleted() == false) { + if(connectionSlot->updateCompleted(&eventList[i]) == false) { threadsDone = false; break; } diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index f74e825a..6e8f31b9 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -211,7 +211,8 @@ public: int getUpdateFps(int factionIndex) const; bool canTickWorld() const; - void exploreCells(const Vec2i &newPos, int sightRange, int teamIndex); + void exploreCells(const Vec2i &newPos, int sightRange, int teamIndex); + bool showWorldForPlayer(int factionIndex) const; private: @@ -232,7 +233,6 @@ private: void updateAllFactionUnits(); void underTakeDeadFactionUnits(); void updateAllFactionConsumableCosts(); - bool showWorldForPlayer(int factionIndex) const; }; }}//end namespace