From 03eaa2c033bf1e9839485f4d194d41bb9b539caa Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 24 Dec 2010 08:43:09 +0000 Subject: [PATCH] numerous important bugfixes: - observers and end game fog of war enable would most likely cause out of synch, I think its fixed now - better handling of threaded logging - cleanup of socket thread processing to ensure all network packets get processed properly and in order --- source/glest_game/game/game.cpp | 55 +------- .../glest_game/network/client_interface.cpp | 10 +- source/glest_game/network/connection_slot.cpp | 24 +++- source/glest_game/network/connection_slot.h | 6 +- .../glest_game/network/server_interface.cpp | 99 ++++++-------- source/glest_game/type_instances/faction.cpp | 2 - source/glest_game/type_instances/unit.cpp | 12 +- source/glest_game/world/world.cpp | 85 ++++++++---- source/glest_game/world/world.h | 3 +- .../platform/common/simple_threads.cpp | 23 +++- .../sources/platform/posix/socket.cpp | 4 +- source/shared_lib/sources/util/util.cpp | 129 ++---------------- 12 files changed, 165 insertions(+), 287 deletions(-) diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 78054dd38..d8e73a150 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -1005,7 +1005,7 @@ void Game::mouseDownRight(int x, int y){ try { Map *map= world.getMap(); const Metrics &metrics= Metrics::getInstance(); - + if(metrics.isInMinimap(x, y) ){ int xm= x - metrics.getMinimapX(); int ym= y - metrics.getMinimapY(); @@ -1611,59 +1611,13 @@ void Game::render2d(){ VisibleQuadContainerCache &qCache =renderer.getQuadCache(); int visibleUnitCount = qCache.visibleQuadUnitList.size(); - /* - int visibleUnitCount = 0; - for(int i=0; i< world.getFactionCount(); ++i){ - for(int j=0; j< world.getFaction(i)->getUnitCount(); ++j){ - Unit *unit = world.getFaction(i)->getUnit(j); - if(world.toRenderUnit(unit, visibleQuad)) { - visibleUnitCount++; - } - } - } - */ str+= "Visible unit count: " + intToStr(visibleUnitCount) +"\n"; int visibleObjectCount = qCache.visibleObjectList.size(); - /* - int visibleObjectCount = 0; - Map *map= world.getMap(); - int thisTeamIndex= world.getThisTeamIndex(); - PosQuadIterator pqi(visibleQuad, Map::cellScale); - while(pqi.next()){ - const Vec2i &pos= pqi.getPos(); - bool isPosVisible = map->isInside(pos.x, pos.y); - if(isPosVisible == true) { - Vec2i mapPos = Map::toSurfCoords(pos); - SurfaceCell *sc= map->getSurfaceCell(mapPos.x, mapPos.y); - Object *o= sc->getObject(); - bool isExplored = (sc->isExplored(thisTeamIndex) && o!=NULL); - //bool isVisible = (sc->isVisible(thisTeamIndex) && o!=NULL); - bool isVisible = true; - if(isExplored == true && isVisible == true) { - visibleObjectCount++; - } - } - } - */ str+= "Visible object count: " + intToStr(visibleObjectCount) +"\n"; // resources - - /* for(int i = 0; i < world.getFactionCount(); ++i) { - //str+= "Player "+intToStr(i)+" res: "; - str+= this->gameSettings.getNetworkPlayerName(i) + " res: "; - for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) { - str+= intToStr(world.getFaction(i)->getResource(j)->getAmount()); - str+=" "; - } - str+="\n"; - } - */ - - for(int i = 0; i < world.getFactionCount(); ++i) { - //str+= "Player "+intToStr(i)+" res: "; string factionInfo = this->gameSettings.getNetworkPlayerName(i) + " [" + formatString(this->gameSettings.getFactionTypeName(i)) + " team: " + intToStr(this->gameSettings.getTeam(i)) + "] res: "; @@ -1671,7 +1625,6 @@ void Game::render2d(){ factionInfo += intToStr(world.getFaction(i)->getResource(j)->getAmount()); factionInfo += " "; } - //str+="\n"; factionDebugInfo[i] = factionInfo; } @@ -1692,9 +1645,6 @@ void Game::render2d(){ for(int i = 0; i < world.getFactionCount(); ++i) { string factionInfo = factionDebugInfo[i]; Vec3f playerColor = world.getFaction(i)->getTexture()->getPixmapConst()->getPixel3f(0, 0); - //renderer.renderTextShadow(factionInfo, coreData.getMenuFontNormal(), - // Vec4f(playerColor.x,playerColor.y,playerColor.z,fontColor.w), - // 10, metrics.getVirtualH() - mh - 60 - 210 - (i * 12), false); renderer.renderText(factionInfo, coreData.getMenuFontBig(), Vec4f(playerColor.x,playerColor.y,playerColor.z,1.0), @@ -1706,9 +1656,6 @@ void Game::render2d(){ } renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f)); } - //else if(renderer.getAllowRenderUnitTitles() == true) { - // renderer.setAllowRenderUnitTitles(false); - //} //network status if(renderNetworkStatus == true) { diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 6c15861f5..338ad91db 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -208,7 +208,7 @@ void ClientInterface::updateLobby() { versionMatched = true; string playerNameStr = getHumanPlayerName(); - sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + networkMessageIntro.getVersionString() + + sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + networkMessageIntro.getVersionString() + "\nClient: " + getNetworkVersionString() + " player [" + playerNameStr + "]"; printf("%s\n",sErr.c_str()); @@ -553,7 +553,7 @@ void ClientInterface::updateKeyframe(int frameCount) isConnected() == true && difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 1000)) { //sleep(waitSleepTime); - sleep(0); + //sleep(0); waitCount++; } @@ -605,7 +605,7 @@ void ClientInterface::updateKeyframe(int frameCount) while(receiveMessage(&networkMessageQuit) == false && isConnected() == true && difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 1000)) { - sleep(0); + //sleep(0); } quit= true; done= true; @@ -619,7 +619,7 @@ void ClientInterface::updateKeyframe(int frameCount) while(receiveMessage(&networkMessageText) == false && isConnected() == true && difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 1000)) { - sleep(0); + //sleep(0); } ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex()); @@ -866,7 +866,7 @@ void ClientInterface::waitForMessage() } // Sleep ever second we wait to let other threads work else if(chrono.getMillis() % 1000 == 0) { - sleep(0); + //sleep(0); } //sleep(waitSleepTime); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index bb9073433..c64bdce1a 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -227,7 +227,11 @@ void ConnectionSlot::update(bool checkForNewClients) { this->vctFileList.clear(); this->receivedNetworkGameStatus = false; this->gotIntro = false; + + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,intToStr(__LINE__)); this->vctPendingNetworkCommandList.clear(); + safeMutexSlot.ReleaseLock(); + this->currentFrameCount = 0; this->currentLagCount = 0; this->lastReceiveCommandListTime = 0; @@ -336,7 +340,7 @@ void ConnectionSlot::update(bool checkForNewClients) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount); for(int i= 0; irequestCommand(networkMessageCommandList.getCommand(i)); + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,intToStr(__LINE__)); vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); } } @@ -657,7 +661,7 @@ void ConnectionSlot::update(bool checkForNewClients) { void ConnectionSlot::validateConnection() { if(gotIntro == false && connectedTime > 0 && difftime(time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %f\n",__FILE__,__FUNCTION__,__LINE__,difftime(time(NULL),connectedTime)); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %f\n",__FILE__,__FUNCTION__,__LINE__,difftime(time(NULL),connectedTime)); close(); } } @@ -722,4 +726,20 @@ string ConnectionSlot::getHumanPlayerName(int index) { return serverInterface->getHumanPlayerName(index); } +vector ConnectionSlot::getPendingNetworkCommandList(bool clearList) { + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,intToStr(__LINE__)); + vector ret = vctPendingNetworkCommandList; + if(clearList == true) { + vctPendingNetworkCommandList.clear(); + } + safeMutexSlot.ReleaseLock(); + + return ret; +} + +void ConnectionSlot::clearPendingNetworkCommandList() { + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,intToStr(__LINE__)); + vctPendingNetworkCommandList.clear(); +} + }}//end namespace diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 2b785d551..5c680ca7f 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -104,6 +104,8 @@ private: bool receivedNetworkGameStatus; time_t connectedTime; bool gotIntro; + + Mutex mutexPendingNetworkCommandList; vector vctPendingNetworkCommandList; ConnectionSlotThread* slotThreadWorker; int currentFrameCount; @@ -141,8 +143,8 @@ public: std::vector getThreadErrorList() const { return threadErrorList; } void clearThreadErrorList() { threadErrorList.clear(); } - vector getPendingNetworkCommandList() { return vctPendingNetworkCommandList; } - void clearPendingNetworkCommandList() { vctPendingNetworkCommandList.clear(); } + vector getPendingNetworkCommandList(bool clearList=false); + void clearPendingNetworkCommandList(); void signalUpdate(ConnectionSlotEvent *event); bool updateCompleted(); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index a5aaba989..3be50d4c8 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -57,7 +57,7 @@ double LAG_CHECK_GRACE_PERIOD = 15; // The max amount of time to 'freeze' gameplay per packet when a client is lagging // badly and we want to give time for them to catch up -double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 2; +double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1; ServerInterface::ServerInterface() { gameHasBeenInitiated = false; @@ -291,54 +291,43 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(event != NULL) { - ConnectionSlot *connectionSlot = event->connectionSlot; + //ConnectionSlot *connectionSlot = event->connectionSlot; bool &socketTriggered = event->socketTriggered; bool checkForNewClients = true; // Safety check since we can experience a disconnect and the slot is NULL MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[event->triggerId],intToStr(__LINE__) + "_" + intToStr(event->triggerId)); + ConnectionSlot *connectionSlot = NULL; + if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) { + connectionSlot = slots[event->triggerId]; + } - if(event->triggerId >= 0 && slots[event->triggerId] == connectionSlot) { - if(connectionSlot != NULL && - (gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggered == true))) { - if(connectionSlot->isConnected() == false || socketTriggered == true) { - if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socketTriggeredList[i] = %i\n",__FILE__,__FUNCTION__,(socketTriggered ? 1 : 0)); + if(connectionSlot != NULL && + (gameHasBeenInitiated == false || + (connectionSlot->getSocket() != NULL && socketTriggered == true))) { + if(connectionSlot->isConnected() == false || socketTriggered == true) { + /* + if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socketTriggeredList[i] = %i\n",__FILE__,__FUNCTION__,(socketTriggered ? 1 : 0)); - if(connectionSlot->isConnected()) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to call connectionSlot->update() for socketId = %d\n",__FILE__,__FUNCTION__,__LINE__,connectionSlot->getSocket()->getSocketId()); - } - else { - if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] getSocket() == NULL\n",__FILE__,__FUNCTION__); - } + if(connectionSlot->isConnected()) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to call connectionSlot->update() for socketId = %d\n",__FILE__,__FUNCTION__,__LINE__,connectionSlot->getSocket()->getSocketId()); + } + else { + if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] getSocket() == NULL\n",__FILE__,__FUNCTION__); + } - if(slots[event->triggerId] == connectionSlot) { - 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__); + */ - connectionSlot->update(checkForNewClients); + connectionSlot->update(checkForNewClients); - // This means no clients are trying to connect at the moment - if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) { - checkForNewClients = false; - } - } - else { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - event->connectionSlot = slots[event->triggerId]; - } - } - } - } - else { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(event->triggerId >= 0) { - event->connectionSlot = slots[event->triggerId]; - } - else { - event->connectionSlot = NULL; - } - } + // This means no clients are trying to connect at the moment + if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) { + checkForNewClients = false; + } + } + } + safeMutexSlot.ReleaseLock(); } SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -537,7 +526,7 @@ void ServerInterface::update() { MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); ConnectionSlot* connectionSlot = slots[i]; - 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 socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false); ConnectionSlotEvent &event = eventList[i]; @@ -548,7 +537,7 @@ void ServerInterface::update() { // Step #2 check all connection slot worker threads for completed status time_t waitForThreadElapsed = time(NULL); - const int MAX_SLOT_THREAD_WAIT_TIME = 10; + const int MAX_SLOT_THREAD_WAIT_TIME = 6; std::map slotsCompleted; for(bool threadsDone = false; threadsDone == false && difftime(time(NULL),waitForThreadElapsed) < MAX_SLOT_THREAD_WAIT_TIME;) { @@ -572,7 +561,7 @@ void ServerInterface::update() { connectionSlot->clearThreadErrorList(); } - connectionSlot = slots[i]; + //connectionSlot = slots[i]; // Not done waiting for data yet bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted() : true); @@ -636,7 +625,7 @@ void ServerInterface::update() { break; } else { - connectionSlot = slots[i]; + //connectionSlot = slots[i]; // New lag check std::pair clientLagExceededOrWarned = std::make_pair(false,false); @@ -698,21 +687,12 @@ void ServerInterface::update() { MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - if(connectionSlot->getPendingNetworkCommandList().size() > 0) { - // New lag check - //std::pair clientLagExceededOrWarned = clientLagCheck(connectionSlot); - //if(clientLagExceededOrWarned.first == true) { - // SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, clientLagExceeded = %d, warned = %d\n",__FILE__,__FUNCTION__,__LINE__,i,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second); - //} - //else { - vector vctPendingNetworkCommandList = connectionSlot->getPendingNetworkCommandList(); - - for(int idx = 0; idx < vctPendingNetworkCommandList.size(); ++idx) { - NetworkCommand &cmd = vctPendingNetworkCommandList[idx]; - this->requestCommand(&cmd); - } - connectionSlot->clearPendingNetworkCommandList(); - //} + vector pendingList = connectionSlot->getPendingNetworkCommandList(true); + if(pendingList.size() > 0) { + for(int idx = 0; idx < pendingList.size(); ++idx) { + NetworkCommand &cmd = pendingList[idx]; + this->requestCommand(&cmd); + } } } } @@ -733,7 +713,6 @@ void ServerInterface::update() { this->addChatInfo(msg); string newChatText = msg.chatText.c_str(); - //string newChatSender = msg.chatSender.c_str(); int newChatTeamIndex = msg.chatTeamIndex; int newChatPlayerIndex = msg.chatPlayerIndex; @@ -779,8 +758,6 @@ void ServerInterface::update() { } } } - - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } void ServerInterface::updateKeyframe(int frameCount){ diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 5b2217c61..cc8099533 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -878,9 +878,7 @@ void Faction::cleanupResourceTypeTargetCache(std::vector *deleteListPtr) const int cleanupInterval = (GameConstants::updateFps * 5); bool needToCleanup = (getFrameCount() % cleanupInterval == 0); - //if(deleteListPtr != NULL || difftime(time(NULL),lastResourceTargettListPurge) >= 120) { if(deleteListPtr != NULL || needToCleanup == true) { - //lastResourceTargettListPurge = time(NULL); std::vector deleteList; if(deleteListPtr != NULL) { diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 72b9fc5cf..10ac69ed8 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -259,7 +259,7 @@ Unit::~Unit() { //Just to be sure, should already be removed if (livingUnitsp.erase(this)) { 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__); //remove commands @@ -301,7 +301,7 @@ Unit::~Unit() { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -void Unit::setModelFacing(CardinalDir value) { +void Unit::setModelFacing(CardinalDir value) { modelFacing = value; lastRotation = targetRotation = rotation = value * 90.f; } @@ -1222,12 +1222,12 @@ string Unit::getDesc() const{ //hp string str= "\n"; - + //maxUnitCount if(type->getMaxUnitCount()>0){ str += lang.get("MaxUnitCount")+ ": " + intToStr(faction->getCountForMaxUnitCount(type)) + "/" + intToStr(type->getMaxUnitCount()); } - + str += "\n"+lang.get("Hp")+ ": " + intToStr(hp) + "/" + intToStr(type->getTotalMaxHp(&totalUpgrade)); if(type->getHpRegeneration()!=0){ str+= " (" + lang.get("Regeneration") + ": " + intToStr(type->getHpRegeneration()) + ")"; @@ -1430,7 +1430,7 @@ void Unit::deleteQueuedCommand(Command *command) { if(getCurrCommand()==command) { this->setCurrentUnitTitle(""); - this->unitPath->clear(); + this->unitPath->clear(); } undoCommand(command); delete command; @@ -1795,8 +1795,6 @@ bool Unit::isBadHarvestPos(const Vec2i &value, bool checkPeerUnits) const { } void Unit::cleanupOldBadHarvestPos() { - //if(difftime(time(NULL),lastBadHarvestListPurge) >= 240) { - //lastBadHarvestListPurge = time(NULL); const int cleanupInterval = (GameConstants::updateFps * 5); bool needToCleanup = (getFrameCount() % cleanupInterval == 0); if(needToCleanup == true) { diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 76a66e11a..311fa19c2 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -621,6 +621,10 @@ bool World::toRenderUnit(const Unit *unit) const { throw runtime_error("unit == NULL"); } + if(showWorldForPlayer(thisFactionIndex) == true) { + return true; + } + return (map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) && map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isExplored(thisTeamIndex) ) || @@ -1057,7 +1061,7 @@ void World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex) { bool cacheLookupPosResult = false; bool cacheLookupSightResult = false; - // Experimental cache lookup of previously calculated cells + sight range + // cache lookup of previously calculated cells + sight range if(MaxExploredCellsLookupItemCache > 0) { if(difftime(time(NULL),ExploredCellsLookupItem::lastDebug) >= 10) { ExploredCellsLookupItem::lastDebug = time(NULL); @@ -1173,14 +1177,42 @@ void World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex) { } } +bool World::showWorldForPlayer(int factionIndex) const { + bool ret = false; + if(factionIndex == thisFactionIndex) { + // Player is an Observer + if(thisTeamIndex == GameConstants::maxPlayers -1 + fpt_Observer) { + ret = true; + } + // Game over and not a network game + else if(game->getGameOver() == true && + game->getGameSettings()->isNetworkGame() == false) { + ret = true; + } + // Game is over but playing a Network game so check if we can + // turn off fog of war? + else if(game->getGameOver() == true && + game->getGameSettings()->isNetworkGame() == true && + game->getGameSettings()->getEnableObserverModeAtEndGame() == true) { + ret = true; + // If the player has at least 1 Unit alive that is mobile (can move) + // then we cannot turn off fog of war + for(int i = 0; i < getFaction(factionIndex)->getUnitCount(); ++i) { + Unit *unit = getFaction(factionIndex)->getUnit(i); + if(unit != NULL && unit->isAlive() && unit->getType()->isMobile() == true) { + ret = false; + break; + } + } + } + } + + return ret; +} + //computes the fog of war texture, contained in the minimap void World::computeFow(int factionIdxToTick) { - //reset texture - //if(factionIdxToTick == -1 || factionIdxToTick == 0) { - //if(factionIdxToTick == -1 || factionIdxToTick == this->thisFactionIndex) { - //if(frameCount % (GameConstants::updateFps) == 0) { minimap.resetFowTex(); - //} //reset cells if(factionIdxToTick == -1 || factionIdxToTick == this->thisFactionIndex) { @@ -1188,24 +1220,23 @@ void World::computeFow(int factionIdxToTick) { for(int j = 0; j < map.getSurfaceH(); ++j) { for(int k = 0; k < GameConstants::maxPlayers + GameConstants::specialFactions; ++k) { if(fogOfWar || k != thisTeamIndex) { - if( k == thisTeamIndex && - (thisTeamIndex == GameConstants::maxPlayers -1 + fpt_Observer || - (game->getGameOver() == true && (game->getGameSettings()->isNetworkGame() == false || - (game->getGameSettings()->getEnableObserverModeAtEndGame() == true && - getFaction(k)->getUnitCount() <= 0))))) { - map.getSurfaceCell(i, j)->setVisible(k, true); - map.getSurfaceCell(i, j)->setExplored(k, true); + if(showWorldForPlayer(k) == true) { + //map.getSurfaceCell(i, j)->setVisible(k, true); + //map.getSurfaceCell(i, j)->setExplored(k, true); const Vec2i pos(i,j); - //Vec2i surfPos= Map::toSurfCoords(pos); Vec2i surfPos= pos; //compute max alpha float maxAlpha= 0.0f; - if(surfPos.x>1 && surfPos.y>1 && surfPos.x 1 && surfPos.y > 1 && + surfPos.x < map.getSurfaceW() - 2 && + surfPos.y < map.getSurfaceH() - 2) { maxAlpha= 1.f; } - else if(surfPos.x>0 && surfPos.y>0 && surfPos.x 0 && surfPos.y > 0 && + surfPos.x < map.getSurfaceW() - 1 && + surfPos.y < map.getSurfaceH() - 1){ maxAlpha= 0.3f; } @@ -1228,19 +1259,22 @@ void World::computeFow(int factionIdxToTick) { for(int k = 0; k < GameConstants::maxPlayers + GameConstants::specialFactions; ++k) { if(fogOfWar || k != thisTeamIndex) { if(k == thisTeamIndex && thisTeamIndex == GameConstants::maxPlayers -1 + fpt_Observer) { - map.getSurfaceCell(i, j)->setVisible(k, true); - map.getSurfaceCell(i, j)->setExplored(k, true); + //map.getSurfaceCell(i, j)->setVisible(k, true); + //map.getSurfaceCell(i, j)->setExplored(k, true); const Vec2i pos(i,j); - //Vec2i surfPos= Map::toSurfCoords(pos); Vec2i surfPos= pos; //compute max alpha float maxAlpha= 0.0f; - if(surfPos.x>1 && surfPos.y>1 && surfPos.x 1 && surfPos.y > 1 && + surfPos.x < map.getSurfaceW() - 2 && + surfPos.y < map.getSurfaceH() - 2) { maxAlpha= 1.f; } - else if(surfPos.x>0 && surfPos.y>0 && surfPos.x 0 && surfPos.y > 0 && + surfPos.x < map.getSurfaceW() - 1 && + surfPos.y < map.getSurfaceH() - 1){ maxAlpha= 0.3f; } @@ -1274,8 +1308,13 @@ void World::computeFow(int factionIdxToTick) { //fire ParticleSystem *fire= unit->getFire(); - if(fire!=NULL){ - fire->setActive(map.getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(thisTeamIndex)); + if(fire != NULL) { + bool cellVisible = showWorldForPlayer(thisFactionIndex); + if(cellVisible == false) { + cellVisible = map.getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(thisTeamIndex); + } + + fire->setActive(cellVisible); } } } diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index d34f1fe2c..f74e825a8 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -231,7 +231,8 @@ private: void updateAllFactionUnits(); void underTakeDeadFactionUnits(); - void updateAllFactionConsumableCosts(); + void updateAllFactionConsumableCosts(); + bool showWorldForPlayer(int factionIndex) const; }; }}//end namespace diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index 38611bfb6..25c6b4187 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -198,7 +198,6 @@ LogFileThread::LogFileThread() : BaseThread() { void LogFileThread::addLogEntry(SystemFlags::DebugType type, string logEntry) { MutexSafeWrapper safeMutex(&mutexLogList); - //logList[type].push_back(make_pair(entry,time(NULL))); LogFileEntry entry; entry.type = type; entry.entry = logEntry; @@ -218,7 +217,7 @@ void LogFileThread::execute() { try { for(;this->getQuitStatus() == false;) { - if(difftime(time(NULL),lastSaveToDisk) >= 5) { + if(difftime(time(NULL),lastSaveToDisk) >= 3) { lastSaveToDisk = time(NULL); saveToDisk(); } @@ -247,14 +246,24 @@ void LogFileThread::execute() { void LogFileThread::saveToDisk() { MutexSafeWrapper safeMutex(&mutexLogList); - if(logList.size() > 0) { - for(int i = 0; i 0) { + vector tempLogList = logList; + safeMutex.ReleaseLock(true); + + logCount = tempLogList.size(); + for(int i = 0; i < logCount; ++i) { + LogFileEntry &entry = tempLogList[i]; SystemFlags::logDebugEntry(entry.type, entry.entry, entry.entryDateTime); } - logList.clear(); + + safeMutex.Lock(); + logList.erase(logList.begin(),logList.begin() + logCount); + safeMutex.ReleaseLock(); + } + else { + safeMutex.ReleaseLock(); } - safeMutex.ReleaseLock(); } }}//end namespace diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 0fae4b668..756554920 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -1035,7 +1035,7 @@ int Socket::send(const void *data, int dataSize) { attemptCount++; SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); - sleep(0); + //sleep(0); //if(Socket::isWritable(true) == true) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); #ifdef __APPLE__ @@ -1063,7 +1063,7 @@ int Socket::send(const void *data, int dataSize) { attemptCount++; SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,totalBytesSent); - sleep(0); + //sleep(0); //if(bytesSent > 0 || Socket::isWritable(true) == true) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index 30ea865ba..b820d953e 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -276,141 +276,28 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { return; } - // Get the current time. - time_t curtime = time (NULL); - // Convert it to local time representation. - struct tm *loctime = localtime (&curtime); - char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); - va_list argList; va_start(argList, fmt); const int max_debug_buffer_size = 8096; char szBuf[max_debug_buffer_size]=""; vsnprintf(szBuf,max_debug_buffer_size-1,fmt, argList); - -/* - // Either output to a logfile or - if(currentDebugLog.debugLogFileName != "") { - if( currentDebugLog.fileStream == NULL || - currentDebugLog.fileStream->is_open() == false) { - - // If the file is already open (shared) by another debug type - // do not over-write the file but share the stream pointer - for(std::map::iterator iterMap = SystemFlags::debugLogFileList.begin(); - iterMap != SystemFlags::debugLogFileList.end(); iterMap++) { - SystemFlags::SystemFlagsType ¤tDebugLog2 = iterMap->second; - - if( iterMap->first != type && - currentDebugLog.debugLogFileName == currentDebugLog2.debugLogFileName && - currentDebugLog2.fileStream != NULL) { - currentDebugLog.fileStream = currentDebugLog2.fileStream; - currentDebugLog.fileStreamOwner = false; - currentDebugLog.mutex = currentDebugLog2.mutex; - break; - } - } - - string debugLog = currentDebugLog.debugLogFileName; - - if(SystemFlags::lockFile == -1) { - const string lock_file_name = "debug.lck"; - string lockfile = extractDirectoryPathFromFile(debugLog); - lockfile += lock_file_name; - SystemFlags::lockfilename = lockfile; - -#ifndef WIN32 - //SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); - SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#else - SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#endif - if (SystemFlags::lockFile < 0 || acquire_file_lock(SystemFlags::lockFile) == false) { - string newlockfile = lockfile; - int idx = 1; - for(idx = 1; idx <= 100; ++idx) { - newlockfile = lockfile + intToStr(idx); - //SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); -#ifndef WIN32 - SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#else - SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); - -#endif - if(SystemFlags::lockFile >= 0 && acquire_file_lock(SystemFlags::lockFile) == true) { - break; - } - } - - SystemFlags::lockFileCountIndex = idx; - SystemFlags::lockfilename = newlockfile; - debugLog += intToStr(idx); - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n",debugLog.c_str()); - } - } - } - else if(SystemFlags::lockFileCountIndex > 0) { - debugLog += intToStr(SystemFlags::lockFileCountIndex); - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n",debugLog.c_str()); - } - } - - if(currentDebugLog.fileStream == NULL) { - currentDebugLog.fileStream = new std::ofstream(); - currentDebugLog.fileStream->open(debugLog.c_str(), ios_base::out | ios_base::trunc); - currentDebugLog.fileStreamOwner = true; - currentDebugLog.mutex = new Mutex(); - } - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening logfile [%s] type = %d, currentDebugLog.fileStreamOwner = %d, file stream open = %d\n",debugLog.c_str(),type, currentDebugLog.fileStreamOwner,currentDebugLog.fileStream->is_open()); - } - - if(currentDebugLog.fileStream->is_open() == true) { - MutexSafeWrapper safeMutex(currentDebugLog.mutex); - - (*currentDebugLog.fileStream) << "Starting Mega-Glest logging for type: " << type << "\n"; - (*currentDebugLog.fileStream).flush(); - - safeMutex.ReleaseLock(); - } - } - - assert(currentDebugLog.fileStream != NULL); - - if(currentDebugLog.fileStream->is_open() == true) { - MutexSafeWrapper safeMutex(currentDebugLog.mutex); - - // All items in the if clause we don't want timestamps - if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { - (*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << szBuf; - } - else if (type == debugError) { - (*currentDebugLog.fileStream) << "[" << szBuf2 << "] *ERROR* " << szBuf; - } - else { - (*currentDebugLog.fileStream) << szBuf; - } - (*currentDebugLog.fileStream).flush(); - - safeMutex.ReleaseLock(); - } - } -*/ + va_end(argList); if(SystemFlags::ENABLE_THREADED_LOGGING && threadLogger != NULL) { threadLogger->addLogEntry(type, szBuf); } else { + // Get the current time. + time_t curtime = time (NULL); + // Convert it to local time representation. + struct tm *loctime = localtime (&curtime); + char szBuf2[100]=""; + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + logDebugEntry(type, szBuf, curtime); } - va_end(argList); }