From fa5a14e2d817121b4fda7382d6b9530153e3b0b4 Mon Sep 17 00:00:00 2001 From: KasyanDiGris Date: Sun, 26 Aug 2018 19:09:56 +0300 Subject: [PATCH] Stabilize vcmi (#488) * Shared statusbar * Fixed server fails on client disconnected --- client/gui/CGuiHandler.h | 2 +- client/mainmenu/CMainMenu.cpp | 6 +++--- client/widgets/TextControls.cpp | 4 +--- client/widgets/TextControls.h | 16 ++++++++++++---- client/windows/CAdvmapInterface.cpp | 16 ++++++++-------- client/windows/CAdvmapInterface.h | 2 +- client/windows/CCastleInterface.cpp | 12 ++++++------ client/windows/CHeroWindow.cpp | 2 +- client/windows/CKingdomInterface.cpp | 2 +- client/windows/CSpellWindow.cpp | 2 +- client/windows/CTradeWindow.cpp | 4 ++-- client/windows/GUIClasses.cpp | 18 +++++++++--------- server/CVCMIServer.cpp | 11 +++++++---- 13 files changed, 53 insertions(+), 44 deletions(-) diff --git a/client/gui/CGuiHandler.h b/client/gui/CGuiHandler.h index 641a885ac..e83143b8e 100644 --- a/client/gui/CGuiHandler.h +++ b/client/gui/CGuiHandler.h @@ -59,7 +59,7 @@ class CGuiHandler public: CFramerateManager * mainFPSmng; //to keep const framerate std::list> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on) - CGStatusBar * statusbar; + std::shared_ptr statusbar; private: std::vector> disposed; diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 687c6c6d0..58bef9650 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -370,7 +370,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType) blitAt(CPicture("MUMAP.bmp"), 16, 77, *background); pos = background->center(); //center, window has size of bg graphic - statusBar = std::make_shared(std::make_shared(Rect(7, 465, 440, 18), 0)); //226, 472 + statusBar = CGStatusBar::create(std::make_shared(Rect(7, 465, 440, 18), 0)); //226, 472 playerName = std::make_shared(Rect(19, 436, 334, 16), *background); playerName->setText(settings["general"]["playerName"].String()); playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1); @@ -420,7 +420,7 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S buttonOk = std::make_shared(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), SDLK_RETURN); buttonCancel = std::make_shared(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, SDLK_ESCAPE); - statusBar = std::make_shared(std::make_shared(Rect(7, 381, 348, 18), 0)); //226, 472 + statusBar = CGStatusBar::create(std::make_shared(Rect(7, 381, 348, 18), 0)); //226, 472 inputNames[0]->setText(firstPlayer, true); inputNames[0]->giveFocus(); @@ -478,7 +478,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host) inputPort->setText(CServerHandler::getDefaultPortStr(), true); buttonCancel = std::make_shared(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE); - statusBar = std::make_shared(std::make_shared(Rect(7, 186, 218, 18), 0)); + statusBar = CGStatusBar::create(std::make_shared(Rect(7, 186, 218, 18), 0)); } void CSimpleJoinScreen::connectToServer() diff --git a/client/widgets/TextControls.cpp b/client/widgets/TextControls.cpp index 1f4f12b86..166543131 100644 --- a/client/widgets/TextControls.cpp +++ b/client/widgets/TextControls.cpp @@ -351,7 +351,6 @@ void CGStatusBar::clear() CGStatusBar::CGStatusBar(std::shared_ptr background_, EFonts Font, EAlignment Align, const SDL_Color & Color) : CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "") { - init(); background = background_; addChild(background.get()); pos = background->pos; @@ -363,7 +362,6 @@ CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw) : CLabel(x, y, FONT_SMALL, CENTER) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - init(); background = std::make_shared(name); pos = background->pos; if((unsigned int)maxw < pos.w) @@ -387,7 +385,7 @@ void CGStatusBar::show(SDL_Surface * to) void CGStatusBar::init() { oldStatusBar = GH.statusbar; - GH.statusbar = this; + GH.statusbar = shared_from_this(); } Point CGStatusBar::getBorderSize() diff --git a/client/widgets/TextControls.h b/client/widgets/TextControls.h index fee051a23..f01a2d3b6 100644 --- a/client/widgets/TextControls.h +++ b/client/widgets/TextControls.h @@ -114,23 +114,31 @@ public: }; /// Status bar which is shown at the bottom of the in-game screens -class CGStatusBar : public CLabel +class CGStatusBar : public CLabel, public std::enable_shared_from_this { bool textLock; //Used for blocking changes to the text void init(); - CGStatusBar * oldStatusBar; + std::shared_ptr oldStatusBar; + + CGStatusBar(std::shared_ptr background_, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color & Color = Colors::WHITE); + CGStatusBar(int x, int y, std::string name, int maxw = -1); protected: Point getBorderSize() override; public: + template + static std::shared_ptr create(Args... args) + { + std::shared_ptr ret{new CGStatusBar{args...}}; + ret->init(); + return ret; + } void clear();//clears statusbar and refreshes void setText(const std::string & Text) override; //prints text and refreshes statusbar void show(SDL_Surface * to) override; //shows statusbar (with current text) - CGStatusBar(std::shared_ptr background_, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color & Color = Colors::WHITE); - CGStatusBar(int x, int y, std::string name, int maxw = -1); ~CGStatusBar(); void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called diff --git a/client/windows/CAdvmapInterface.cpp b/client/windows/CAdvmapInterface.cpp index a42dc2171..80fdd9713 100644 --- a/client/windows/CAdvmapInterface.cpp +++ b/client/windows/CAdvmapInterface.cpp @@ -244,7 +244,7 @@ void CTerrainRect::hover(bool on) { if (!on) { - adventureInt->statusbar.clear(); + adventureInt->statusbar->clear(); CCS->curh->changeGraphic(ECursor::ADVENTURE,0); } //Hoverable::hover(on); @@ -555,7 +555,7 @@ CAdvMapInt::CAdvMapInt(): mode(EAdvMapMode::NORMAL), worldViewScale(0.0f), //actual init later in changeMode minimap(Rect(ADVOPT.minimapX, ADVOPT.minimapY, ADVOPT.minimapW, ADVOPT.minimapH)), - statusbar(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG), + statusbar(CGStatusBar::create(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG)), heroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD), townList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD), infoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192)), state(NA), @@ -930,7 +930,7 @@ void CAdvMapInt::activate() CIntObject::activate(KEYBOARD); screenBuf = screen; - GH.statusbar = &statusbar; + GH.statusbar = statusbar; if(!duringAITurn) { activeMapPanel->activate(); @@ -1001,7 +1001,7 @@ void CAdvMapInt::showAll(SDL_Surface * to) resdatabar.showAll(to); - statusbar.show(to); + statusbar->show(to); LOCPLINT->cingconsole->show(to); } @@ -1079,7 +1079,7 @@ void CAdvMapInt::show(SDL_Surface * to) } infoBar.show(to); - statusbar.showAll(to); + statusbar->showAll(to); } void CAdvMapInt::handleMapScrollingUpdate() @@ -1645,7 +1645,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) if(!LOCPLINT->cb->isVisible(mapPos)) { CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); - statusbar.clear(); + statusbar->clear(); return; } auto objRelations = PlayerRelations::ALLIES; @@ -1655,13 +1655,13 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) objRelations = LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner); std::string text = curHero() ? objAtTile->getHoverText(curHero()) : objAtTile->getHoverText(LOCPLINT->playerID); boost::replace_all(text,"\n"," "); - statusbar.setText(text); + statusbar->setText(text); } else { std::string hlp; CGI->mh->getTerrainDescr(mapPos, hlp, false); - statusbar.setText(hlp); + statusbar->setText(hlp); } if(spellBeingCasted) diff --git a/client/windows/CAdvmapInterface.h b/client/windows/CAdvmapInterface.h index 81a21a2cb..6c851828d 100644 --- a/client/windows/CAdvmapInterface.h +++ b/client/windows/CAdvmapInterface.h @@ -168,7 +168,7 @@ public: SDL_Surface * bgWorldView; std::vector> gems; CMinimap minimap; - CGStatusBar statusbar; + std::shared_ptr statusbar; std::shared_ptr kingOverview; std::shared_ptr underground; diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 60fab310a..1e0348698 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -1130,7 +1130,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst Rect barRect(9, 182, 732, 18); auto statusbarBackground = std::make_shared(*(panel.get()), barRect, 9, 555, false); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); resdatabar = std::make_shared("ARESBAR", 3, 575, 32, 2, 85, 85); townlist = std::make_shared(3, Point(744, 414), "IAM014", "IAM015"); @@ -1326,7 +1326,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town): Rect barRect(5, 556, 740, 18); auto statusbarBackground = std::make_shared(*background, barRect, 5, 556, false); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); title = std::make_shared(399, 12, FONT_MEDIUM, CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->Name()); exit = std::make_shared(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, SDLK_RETURN); @@ -1373,7 +1373,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin icon = std::make_shared(town->town->clientInfo.buildingsIcons, building->bid, 0, 125, 50); auto statusbarBackground = std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); name = std::make_shared(197, 30, FONT_MEDIUM, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->hcommands[7]) % building->Name())); description = std::make_shared(building->Description(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, CENTER); @@ -1549,7 +1549,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town): Rect barRect(4, 554, 740, 18); auto statusbarBackground = std::make_shared(*background, barRect, 4, 554, false); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); } std::string CFortScreen::getBgName(const CGTownInstance * town) @@ -1690,7 +1690,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem) Rect barRect(7, 556, 737, 18); auto statusbarBackground = std::make_shared(*background, barRect, 7, 556, false); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); exit = std::make_shared(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, SDLK_RETURN); exit->assignedKeys.insert(SDLK_ESCAPE); @@ -1757,7 +1757,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art Rect barRect(8, pos.h - 26, pos.w - 16, 19); auto statusbarBackground = std::make_shared(*background, barRect, 8, pos.h - 26, false); - statusbar = std::make_shared(statusbarBackground); + statusbar = CGStatusBar::create(statusbarBackground); animBG = std::make_shared("TPSMITBK", 64, 50); animBG->needRefresh = true; diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 2683506b4..2e0abe4da 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -110,7 +110,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero) name = std::make_shared(190, 38, EFonts::FONT_BIG, EAlignment::CENTER, Colors::YELLOW); title = std::make_shared(190, 65, EFonts::FONT_MEDIUM, EAlignment::CENTER, Colors::WHITE); - statusBar = std::make_shared(7, 559, "ADROLLVR.bmp", 660); + statusBar = CGStatusBar::create(7, 559, "ADROLLVR.bmp", 660); quitButton = std::make_shared(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, SDLK_RETURN); quitButton->assignedKeys.insert(SDLK_ESCAPE); diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index 32a71fd8b..3073b041a 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -472,7 +472,7 @@ CKingdomInterface::CKingdomInterface() generateMinesList(ownedObjects); generateButtons(); - statusbar = std::make_shared(std::make_shared("KSTATBAR", 10,pos.h - 45)); + statusbar = CGStatusBar::create(std::make_shared("KSTATBAR", 10,pos.h - 45)); resdatabar = std::make_shared("KRESBAR", 3, 111+footerPos, 32, 2, 76, 76); } diff --git a/client/windows/CSpellWindow.cpp b/client/windows/CSpellWindow.cpp index 3931287e4..3ba5ee167 100644 --- a/client/windows/CSpellWindow.cpp +++ b/client/windows/CSpellWindow.cpp @@ -184,7 +184,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m for(auto item : schoolBorders) item->preload(); mana = std::make_shared(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast(myHero->mana)); - statusBar = std::make_shared(7, 569, "Spelroll.bmp"); + statusBar = CGStatusBar::create(7, 569, "Spelroll.bmp"); SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y); interactiveAreas.push_back(std::make_shared(temp_rect, std::bind(&CSpellWindow::fexitb, this), 460, this)); diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 20e3cbbee..a8027fc9e 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -659,7 +659,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta madeTransaction = false; bool sliderNeeded = true; - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); std::string title; @@ -1135,7 +1135,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, //Total experience on the Altar texts.push_back(std::make_shared(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW)); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); ok = std::make_shared(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, SDLK_RETURN); ok->assignedKeys.insert(SDLK_ESCAPE); diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index ee210bc23..86f861712 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -205,7 +205,7 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, c OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); slider = std::make_shared(Point(176,279),135,std::bind(&CRecruitmentWindow::sliderMoved,this, _1),0,0,0,true); @@ -656,7 +656,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj) auto rumorText = boost::str(boost::format(CGI->generaltexth->allTexts[216]) % LOCPLINT->cb->getTavernRumor(tavernObj)); rumor = std::make_shared(rumorText, Rect(32, 190, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); cancel = std::make_shared(Point(310, 428), "ICANCEL.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), SDLK_ESCAPE); recruit = std::make_shared(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN); thiefGuild = std::make_shared(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t); @@ -920,7 +920,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, questlogButton[1] = std::make_shared(Point(740, 44), "hsbtns4.def", CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1)); Rect barRect(5, 578, 725, 18); - statusBar = std::make_shared(std::make_shared(*background, barRect, 5, 578, false)); + statusBar = CGStatusBar::create(std::make_shared(*background, barRect, 5, 578, false)); //garrison interface garr = std::make_shared(69, 131, 4, Point(418,0), heroInst[0], heroInst[1], true, true); @@ -1013,7 +1013,7 @@ CShipyardWindow::CShipyardWindow(const std::vector & cost, int state, int } } - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); title = std::make_shared(164, 27, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[13]); costLabel = std::make_shared(164, 220, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->jktexts[14]); @@ -1178,7 +1178,7 @@ CTransformerWindow::CTransformerWindow(const CGHeroInstance * _hero, const CGTow all = std::make_shared(Point(146, 416), "ALTARMY.DEF", CGI->generaltexth->zelp[590], [&](){ addAll(); }, SDLK_a); convert = std::make_shared(Point(269, 416), "ALTSACR.DEF", CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, SDLK_RETURN); cancel = std::make_shared(Point(392, 416), "ICANCEL.DEF", CGI->generaltexth->zelp[592], [&](){ close(); },SDLK_ESCAPE); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); titleLeft = std::make_shared(153, 29,FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[485]);//holding area titleRight = std::make_shared(153+295, 29, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[486]);//transformer @@ -1283,7 +1283,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket items.push_back(std::make_shared(this, goods[i], 54+i*104, 234)); cancel = std::make_shared(Point(200, 313), "IOKAY.DEF", CGI->generaltexth->zelp[632], [&](){ close(); }, SDLK_RETURN); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); } void CUniversityWindow::makeDeal(int skill) @@ -1324,7 +1324,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo confirm->block(!available); cancel = std::make_shared(Point(252,299), "ICANCEL.DEF", CGI->generaltexth->zelp[631], [&](){ close(); }, SDLK_ESCAPE); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); } void CUnivConfirmWindow::makeDeal(int skill) @@ -1409,7 +1409,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI upgradeAll->addImage(image); quit = std::make_shared(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), SDLK_RETURN); - statusBar = std::make_shared(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); + statusBar = CGStatusBar::create(std::make_shared(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); garr = std::make_shared(108, 60, 18, Point(), hero, nullptr); updateGarrisons(); @@ -1590,7 +1590,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): exitb = std::make_shared(Point(748, 556), "TPMAGE1", CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, SDLK_RETURN); exitb->assignedKeys.insert(SDLK_ESCAPE); - statusBar = std::make_shared(3, 555, "TStatBar.bmp", 742); + statusBar = CGStatusBar::create(3, 555, "TStatBar.bmp", 742); resdatabar = std::make_shared(); resdatabar->moveBy(pos.topLeft(), true); diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index a70dc4547..de87a368a 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -443,14 +443,17 @@ void CVCMIServer::clientConnected(std::shared_ptr c, std::vector c) { connections -= c; - for(auto & pair : playerNames) + for(auto it = playerNames.begin(); it != playerNames.end();) { - if(pair.second.connection != c->connectionID) + if(it->second.connection != c->connectionID) + { + it++; continue; + } - int id = pair.first; + int id = it->first; announceTxt(boost::str(boost::format("%s (pid %d cid %d) left the game") % id % playerNames[id].name % c->connectionID)); - playerNames.erase(id); + playerNames.erase(it++); // Reset in-game players client used back to AI if(PlayerSettings * s = si->getPlayersSettings(id))