From ff12aca83a942f7beba5cf849f9bf2cee9c366e7 Mon Sep 17 00:00:00 2001 From: Ilya Pomaskin Date: Fri, 10 Oct 2014 14:36:35 +0400 Subject: [PATCH 01/13] bind -> std::bind --- client/CPreGame.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index c18aefa49..a21468903 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -3194,7 +3194,7 @@ void CBonusSelection::init() //bonus choosing graphics->fonts[FONT_MEDIUM]->renderTextLeft(background, CGI->generaltexth->allTexts[71], Colors::WHITE, Point(511, 432)); - bonuses = new CToggleGroup(bind(&CBonusSelection::selectBonus, this, _1)); + bonuses = new CToggleGroup(std::bind(&CBonusSelection::selectBonus, this, _1)); //set left part of window bool isCurrentMapConquerable = ourCampaign->currentMap && ourCampaign->camp->conquerable(*ourCampaign->currentMap); @@ -3447,7 +3447,7 @@ void CBonusSelection::updateBonusSelection() updateStartButtonState(-1); delete bonuses; - bonuses = new CToggleGroup(bind(&CBonusSelection::selectBonus, this, _1)); + bonuses = new CToggleGroup(std::bind(&CBonusSelection::selectBonus, this, _1)); static const char *bonusPics[] = {"SPELLBON.DEF", "TWCRPORT.DEF", "", "ARTIFBON.DEF", "SPELLBON.DEF", "PSKILBON.DEF", "SSKILBON.DEF", "BORES.DEF", "PORTRAITSLARGE", "PORTRAITSLARGE"}; From a734ad072b9ad984abab02508836ff2c570992e0 Mon Sep 17 00:00:00 2001 From: Michael Pavlyshko Date: Sat, 11 Oct 2014 13:21:45 +0300 Subject: [PATCH 02/13] fix Clang 3.4 launcher build and probably Clang 3.2 build --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f3dbde1e..6397f5285 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_install: #new SDL2 - sudo add-apt-repository --yes ppa:zoogie/sdl2-snapshots #new Qt - - sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa + - sudo add-apt-repository --yes ppa:beineri/opt-qt532 #new FFmpeg - sudo add-apt-repository --yes ppa:djcj/vlc-stable #new CMake @@ -20,13 +20,13 @@ before_install: - sudo apt-get install -qq $SUPPORT - sudo apt-get install -qq $PACKAGE - - sudo apt-get install -qq cmake yasm libboost1.55-all-dev zlib1g-dev + - sudo apt-get install -qq cmake libboost1.55-all-dev zlib1g-dev - sudo apt-get install -qq libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev - sudo apt-get install -qq libavformat-dev libswscale-dev - sudo apt-get install -qq qtdeclarative5-dev #setup compiler - #- source /opt/qt53/bin/qt53-env.sh + - source /opt/qt53/bin/qt53-env.sh - export CC=${REAL_CC} CXX=${REAL_CXX} before_script: @@ -44,8 +44,8 @@ matrix: exclude: - env: ignore=this include: - #- compiler: clang # fails all the time - missing packages? - # env: REAL_CC=clang-3.2 REAL_CXX=clang++-3.2 PACKAGE=clang-3.2 SUPPORT=g++-4.8 + - compiler: clang # fails all the time - missing packages? + env: REAL_CC=clang-3.2 REAL_CXX=clang++-3.2 PACKAGE=clang-3.2 SUPPORT=g++-4.8 - compiler: clang env: REAL_CC=clang-3.3 REAL_CXX=clang++-3.3 PACKAGE=clang-3.3 SUPPORT=g++-4.8 - compiler: clang From d0e82caaf3a4c7ba4e43fee607aaa560b29d0adb Mon Sep 17 00:00:00 2001 From: Michael Pavlyshko Date: Sat, 11 Oct 2014 13:29:30 +0300 Subject: [PATCH 03/13] fix package name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6397f5285..93069dbac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_install: - sudo apt-get install -qq cmake libboost1.55-all-dev zlib1g-dev - sudo apt-get install -qq libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev - sudo apt-get install -qq libavformat-dev libswscale-dev - - sudo apt-get install -qq qtdeclarative5-dev + - sudo apt-get install -qq qt53declarative #setup compiler - source /opt/qt53/bin/qt53-env.sh From cfa6f46d62971cefc7a8cb4e4e3703a52ade531f Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sun, 19 Oct 2014 07:47:09 -0400 Subject: [PATCH 04/13] VERY buggy, unusable, but progress is being made... --- client/CMT.cpp | 13 +++++-- client/Client.cpp | 77 +++++++++++++++++++++++++++++++----------- client/Client.h | 2 +- lib/CCreatureSet.cpp | 3 +- server/CVCMIServer.cpp | 2 +- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/client/CMT.cpp b/client/CMT.cpp index 5151a8c39..f88491db0 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -224,7 +224,13 @@ int main(int argc, char** argv) ("oneGoodAI", "puts one default AI and the rest will be EmptyAI") ("autoSkip", "automatically skip turns in GUI") ("disable-video", "disable video player") - ("nointro,i", "skips intro movies"); + ("nointro,i", "skips intro movies") + ("loadserver","specifies we are the multiplayer server for loaded games") + ("loadnumplayers",po::value(),"specifies the number of players connecting to a multiplayer game") + ("loadhumanplayerindices",po::value>(),"Indexes of human players (0=Red, etc.)") + ("loadplayer", po::value(),"specifies which player we are in multiplayer loaded games (0=Red, etc.)") + ("loadserverip",po::value(),"IP for loaded game server") + ("loadserverport",po::value(),"port for loaded game server"); if(argc > 1) { @@ -1222,7 +1228,10 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/) case StartInfo::LOAD_GAME: std::string fname = options->mapname; boost::algorithm::erase_last(fname,".vlgm1"); - client->loadGame(fname); + if(!vm.count("loadplayer")) + client->loadGame(fname); + else + client->loadGame(fname,vm.count("loadserver"),vm.count("loadhumanplayerindices") ? vm["loadhumanplayerindices"].as>() : std::vector(),vm.count("loadnumplayers") ? vm["loadnumplayers"].as() : 1,vm["loadplayer"].as(),vm.count("loadserverip") ? vm["loadserverip"].as() : "", vm.count("loadserverport") ? vm["loadserverport"].as() : "3030"); break; } diff --git a/client/Client.cpp b/client/Client.cpp index f4d479375..55374d26b 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -236,12 +236,15 @@ void CClient::endGame( bool closeConnection /*= true*/ ) logNetwork->infoStream() << "Client stopped."; } -void CClient::loadGame( const std::string & fname ) +void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) { logNetwork->infoStream() <<"Loading procedure started!"; CServerHandler sh; - sh.startServer(); + if(server) + sh.startServer(); + else + serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); CStopWatch tmh; try @@ -286,30 +289,65 @@ void CClient::loadGame( const std::string & fname ) throw; //obviously we cannot continue here } - serv = sh.connectToServer(); - serv->addStdVecItems(gs); + if(server) + serv = sh.connectToServer(); - tmh.update(); - ui8 pom8; - *serv << ui8(3) << ui8(1); //load game; one client - *serv << fname; - *serv >> pom8; - if(pom8) - throw std::runtime_error("Server cannot open the savegame!"); - else - logNetwork->infoStream() << "Server opened savegame properly."; + if(player_==-1) + player_ = player->getNum(); + else + player = PlayerColor(player_); + + serv->addStdVecItems(gs); /*why is this here?*/ + + std::cout << player << std::endl; + if(server) + { + tmh.update(); + ui8 pom8; + *serv << ui8(3) << ui8(loadNumPlayers); //load game; one client if single-player + *serv << fname; + *serv >> pom8; + if(pom8) + throw std::runtime_error("Server cannot open the savegame!"); + else + logNetwork->infoStream() << "Server opened savegame properly."; + } + + if(server) + { + *serv << ui32(gs->scenarioOps->playerInfos.size()+2-loadNumPlayers); //number of players + neutral + for(auto & elem : gs->scenarioOps->playerInfos) + if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) + { + *serv << ui8(elem.first.getNum()); //players + if(elem.first!=player) + { + auto AiToGive = aiNameForPlayer(elem.second, false); + logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; + installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); + } + else + { + installNewPlayerInterface(make_shared(*player),*player); + } + } + *serv << ui8(PlayerColor::NEUTRAL.getNum()); + } + else + { + *serv << ui32(1); + *serv << ui8(player->getNum()); + installNewPlayerInterface(make_shared(*player),*player); + } - *serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral - for(auto & elem : gs->scenarioOps->playerInfos) - { - *serv << ui8(elem.first.getNum()); //players - } - *serv << ui8(PlayerColor::NEUTRAL.getNum()); logNetwork->infoStream() <<"Sent info to server: "<addStdVecItems(gs); serv->enableStackSendingByID(); serv->disableSmartPointerSerialization(); + loadNeutralBattleAI(); + // logGlobal->traceStream() << "Objects:"; // for(int i = 0; i < gs->map->objects.size(); i++) // { @@ -833,6 +871,7 @@ CConnection * CServerHandler::connectToServer() #endif th.update(); //put breakpoint here to attach to server before it does something stupid + CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port); if(verbose) diff --git a/client/Client.h b/client/Client.h index a099d1007..c119dce4d 100644 --- a/client/Client.h +++ b/client/Client.h @@ -151,7 +151,7 @@ public: void endGame(bool closeConnection = true); void stopConnection(); void save(const std::string & fname); - void loadGame(const std::string & fname); + void loadGame(const std::string & fname, const bool server = true, const std::vector& humanplayerindices = std::vector(), const int loadnumplayers = 1, int player_ = -1, const std::string & ipaddr = "", const std::string & port = ""); void run(); void campaignMapFinished( shared_ptr camp ); void finishCampaign( shared_ptr camp ); diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index 7dea9f9f0..55276af25 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -387,11 +387,12 @@ CStackInstance * CCreatureSet::detachStack(SlotID slot) CStackInstance *ret = stacks[slot]; //if(CArmedInstance *armedObj = castToArmyObj()) + if(ret) { ret->setArmyObj(nullptr); //detaches from current armyobj + assert(!ret->armyObj); //we failed detaching? } - assert(!ret->armyObj); //we failed detaching? stacks.erase(slot); armyChanged(); return ret; diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 3dcc5e959..e91f19171 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -463,7 +463,7 @@ void CVCMIServer::loadGame() boost::system::error_code error; ui8 clients; - c >> clients >> fname; //how many clients should be connected - TODO: support more than one + c >> clients >> fname; //how many clients should be connected // { // char sig[8]; From 99a63c4bbdbeaab52758271632fadd39e508f5b5 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sun, 19 Oct 2014 11:21:48 -0400 Subject: [PATCH 05/13] multiplayer load changes --- client/Client.cpp | 138 +++++++++++++++++++++++------------------ server/CVCMIServer.cpp | 12 +++- 2 files changed, 88 insertions(+), 62 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 55374d26b..3e176acff 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -246,51 +246,68 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: else serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); - CStopWatch tmh; - try - { - std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); - std::string controlServerSaveName; + CStopWatch tmh; + if(server) + { + try + { + std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); + std::string controlServerSaveName; - if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) - { - controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); - } - else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler - { - controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; - CResourceHandler::get("local")->createResource(controlServerSaveName, true); - } + if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) + { + controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); + } + else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler + { + controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; + CResourceHandler::get("local")->createResource(controlServerSaveName, true); + } - if(clientSaveName.empty()) - throw std::runtime_error("Cannot open client part of " + fname); - if(controlServerSaveName.empty()) - throw std::runtime_error("Cannot open server part of " + fname); + if(clientSaveName.empty()) + throw std::runtime_error("Cannot open client part of " + fname); + if(controlServerSaveName.empty()) + throw std::runtime_error("Cannot open server part of " + fname); - unique_ptr loader; - { - CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); - loadCommonState(checkingLoader); - loader = checkingLoader.decay(); - } - logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); - const_cast(CGI)->mh = new CMapHandler(); - const_cast(CGI)->mh->map = gs->map; - pathInfo = make_unique(getMapSize()); - CGI->mh->init(); - logNetwork->infoStream() <<"Initing maphandler: "< loader; + { + CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); + loadCommonState(checkingLoader); + loader = checkingLoader.decay(); + } + logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); + const_cast(CGI)->mh = new CMapHandler(); + const_cast(CGI)->mh->map = gs->map; + pathInfo = make_unique(getMapSize()); + CGI->mh->init(); + logNetwork->infoStream() <<"Initing maphandler: "<> *this; - logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); - } - catch(std::exception &e) - { - logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); - throw; //obviously we cannot continue here - } + *loader >> *this; + logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); + } + catch(std::exception &e) + { + logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); + throw; //obviously we cannot continue here + } + } if(server) + { serv = sh.connectToServer(); + (*serv) << *this; + } + else + { + (*serv) >> *this; + + const_cast(CGI)->mh = new CMapHandler(); + CGI->mh->map = gs->map; + logNetwork->infoStream() <<"Creating mapHandler: "<mh->init(); + pathInfo = make_unique(getMapSize()); + logNetwork->infoStream() <<"Initializing mapHandler (together): "<getNum(); @@ -313,38 +330,39 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: logNetwork->infoStream() << "Server opened savegame properly."; } + std::set clientPlayers; if(server) { - *serv << ui32(gs->scenarioOps->playerInfos.size()+2-loadNumPlayers); //number of players + neutral - for(auto & elem : gs->scenarioOps->playerInfos) - if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) - { - *serv << ui8(elem.first.getNum()); //players - if(elem.first!=player) - { - auto AiToGive = aiNameForPlayer(elem.second, false); - logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; - installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); - } - else - { - installNewPlayerInterface(make_shared(*player),*player); - } - } - *serv << ui8(PlayerColor::NEUTRAL.getNum()); + for(auto & elem : gs->scenarioOps->playerInfos) + if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) + { + clientPlayers.insert(elem.first); + if(elem.first!=player) + { + auto AiToGive = aiNameForPlayer(elem.second, false); + logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; + installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); + } + else + { + installNewPlayerInterface(make_shared(*player),*player); + } + } + clientPlayers.insert(PlayerColor::NEUTRAL); } else { - *serv << ui32(1); - *serv << ui8(player->getNum()); - installNewPlayerInterface(make_shared(*player),*player); + clientPlayers.insert(*player); + installNewPlayerInterface(make_shared(*player),*player); } + serv->enableStackSendingByID(); + serv->disableSmartPointerSerialization(); + (*serv) << clientPlayers; + logNetwork->infoStream() <<"Sent info to server: "<addStdVecItems(gs); - serv->enableStackSendingByID(); - serv->disableSmartPointerSerialization(); loadNeutralBattleAI(); diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index e91f19171..d1ec14ee9 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -32,6 +32,12 @@ #include "../lib/UnlockGuard.h" +#include "../client/Client.h" + +extern template void CClient::serialize>( COSer &h, const int version ); +extern template void CClient::serialize>( CISer &h, const int version ); +extern template void CClient::serialize>( COSer &h, const int version ); + #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(VCMI_ANDROID) #include #endif @@ -491,11 +497,13 @@ void CVCMIServer::loadGame() c << ui8(0); CConnection* cc; //tcp::socket * ss; + CClient client_in; for(int i=0; i> client_in; } else { @@ -508,8 +516,8 @@ void CVCMIServer::loadGame() continue; } cc = new CConnection(s,NAME); - cc->addStdVecItems(gh.gs); - } + (*cc) << client_in; + } gh.conns.insert(cc); } From 3685e9604273b6e7ba7cf3d6fcd43c5560acf7d7 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sun, 19 Oct 2014 22:13:10 -0400 Subject: [PATCH 06/13] Revert "multiplayer load changes" This reverts commit 368d2c8836cc6e3b5af9cf71e892bf4515f26bda. --- client/Client.cpp | 142 ++++++++++++++++++----------------------- server/CVCMIServer.cpp | 12 +--- 2 files changed, 64 insertions(+), 90 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 3e176acff..55374d26b 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -246,68 +246,51 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: else serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); - CStopWatch tmh; - if(server) - { - try - { - std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); - std::string controlServerSaveName; + CStopWatch tmh; + try + { + std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); + std::string controlServerSaveName; - if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) - { - controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); - } - else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler - { - controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; - CResourceHandler::get("local")->createResource(controlServerSaveName, true); - } + if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) + { + controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); + } + else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler + { + controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; + CResourceHandler::get("local")->createResource(controlServerSaveName, true); + } - if(clientSaveName.empty()) - throw std::runtime_error("Cannot open client part of " + fname); - if(controlServerSaveName.empty()) - throw std::runtime_error("Cannot open server part of " + fname); - - unique_ptr loader; - { - CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); - loadCommonState(checkingLoader); - loader = checkingLoader.decay(); - } - logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); - const_cast(CGI)->mh = new CMapHandler(); - const_cast(CGI)->mh->map = gs->map; - pathInfo = make_unique(getMapSize()); - CGI->mh->init(); - logNetwork->infoStream() <<"Initing maphandler: "<> *this; - logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); - } - catch(std::exception &e) - { - logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); - throw; //obviously we cannot continue here - } - } - - if(server) - { - serv = sh.connectToServer(); - (*serv) << *this; - } - else - { - (*serv) >> *this; + if(clientSaveName.empty()) + throw std::runtime_error("Cannot open client part of " + fname); + if(controlServerSaveName.empty()) + throw std::runtime_error("Cannot open server part of " + fname); + unique_ptr loader; + { + CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); + loadCommonState(checkingLoader); + loader = checkingLoader.decay(); + } + logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); const_cast(CGI)->mh = new CMapHandler(); - CGI->mh->map = gs->map; - logNetwork->infoStream() <<"Creating mapHandler: "<mh->init(); + const_cast(CGI)->mh->map = gs->map; pathInfo = make_unique(getMapSize()); - logNetwork->infoStream() <<"Initializing mapHandler (together): "<mh->init(); + logNetwork->infoStream() <<"Initing maphandler: "<> *this; + logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); + } + catch(std::exception &e) + { + logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); + throw; //obviously we cannot continue here + } + + if(server) + serv = sh.connectToServer(); if(player_==-1) player_ = player->getNum(); @@ -330,39 +313,38 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: logNetwork->infoStream() << "Server opened savegame properly."; } - std::set clientPlayers; if(server) { - for(auto & elem : gs->scenarioOps->playerInfos) - if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) - { - clientPlayers.insert(elem.first); - if(elem.first!=player) - { - auto AiToGive = aiNameForPlayer(elem.second, false); - logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; - installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); - } - else - { - installNewPlayerInterface(make_shared(*player),*player); - } - } - clientPlayers.insert(PlayerColor::NEUTRAL); + *serv << ui32(gs->scenarioOps->playerInfos.size()+2-loadNumPlayers); //number of players + neutral + for(auto & elem : gs->scenarioOps->playerInfos) + if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) + { + *serv << ui8(elem.first.getNum()); //players + if(elem.first!=player) + { + auto AiToGive = aiNameForPlayer(elem.second, false); + logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; + installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); + } + else + { + installNewPlayerInterface(make_shared(*player),*player); + } + } + *serv << ui8(PlayerColor::NEUTRAL.getNum()); } else { - clientPlayers.insert(*player); - installNewPlayerInterface(make_shared(*player),*player); + *serv << ui32(1); + *serv << ui8(player->getNum()); + installNewPlayerInterface(make_shared(*player),*player); } - serv->enableStackSendingByID(); - serv->disableSmartPointerSerialization(); - (*serv) << clientPlayers; - logNetwork->infoStream() <<"Sent info to server: "<addStdVecItems(gs); + serv->enableStackSendingByID(); + serv->disableSmartPointerSerialization(); loadNeutralBattleAI(); diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index d1ec14ee9..e91f19171 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -32,12 +32,6 @@ #include "../lib/UnlockGuard.h" -#include "../client/Client.h" - -extern template void CClient::serialize>( COSer &h, const int version ); -extern template void CClient::serialize>( CISer &h, const int version ); -extern template void CClient::serialize>( COSer &h, const int version ); - #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(VCMI_ANDROID) #include #endif @@ -497,13 +491,11 @@ void CVCMIServer::loadGame() c << ui8(0); CConnection* cc; //tcp::socket * ss; - CClient client_in; for(int i=0; i> client_in; } else { @@ -516,8 +508,8 @@ void CVCMIServer::loadGame() continue; } cc = new CConnection(s,NAME); - (*cc) << client_in; - } + cc->addStdVecItems(gh.gs); + } gh.conns.insert(cc); } From 41da0ad2e69d71ff89486e1d17741d81632b0356 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Tue, 21 Oct 2014 08:11:54 -0400 Subject: [PATCH 07/13] multiplayerload changes (committing so I can revert...) --- client/CPlayerInterface.cpp | 17 +-- client/Client.cpp | 203 +++++++++++++++++++++++++++++++----- client/Client.h | 1 + server/CVCMIServer.cpp | 1 - 4 files changed, 188 insertions(+), 34 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 152ce7004..6671d93e6 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1257,14 +1257,15 @@ template void CPlayerInterface::serializeTempl( Handler &h, c { h & pathsMap; - for(auto &p : pathsMap) - { - CGPath path; - cb->getPathsInfo(p.first)->getPath(p.second, path); - paths[p.first] = path; - logGlobal->traceStream() << boost::format("Restored path for hero %s leading to %s with %d nodes") - % p.first->nodeName() % p.second % path.nodes.size(); - } + if(cb) + for(auto &p : pathsMap) + { + CGPath path; + cb->getPathsInfo(p.first)->getPath(p.second, path); + paths[p.first] = path; + logGlobal->traceStream() << boost::format("Restored path for hero %s leading to %s with %d nodes") + % p.first->nodeName() % p.second % path.nodes.size(); + } } h & spellbookSettings; diff --git a/client/Client.cpp b/client/Client.cpp index 55374d26b..dd014035d 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -236,15 +236,13 @@ void CClient::endGame( bool closeConnection /*= true*/ ) logNetwork->infoStream() << "Client stopped."; } +#if 0 void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) { logNetwork->infoStream() <<"Loading procedure started!"; CServerHandler sh; - if(server) - sh.startServer(); - else - serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); + sh.startServer(); CStopWatch tmh; try @@ -289,17 +287,105 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: throw; //obviously we cannot continue here } + serv = sh.connectToServer(); + serv->addStdVecItems(gs); + + tmh.update(); + ui8 pom8; + *serv << ui8(3) << ui8(1); //load game; one client + *serv << fname; + *serv >> pom8; + if(pom8) + throw std::runtime_error("Server cannot open the savegame!"); + else + logNetwork->infoStream() << "Server opened savegame properly."; + + *serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral + for(auto & elem : gs->scenarioOps->playerInfos) + { + *serv << ui8(elem.first.getNum()); //players + } + *serv << ui8(PlayerColor::NEUTRAL.getNum()); + logNetwork->infoStream() <<"Sent info to server: "<enableStackSendingByID(); + serv->disableSmartPointerSerialization(); + +// logGlobal->traceStream() << "Objects:"; +// for(int i = 0; i < gs->map->objects.size(); i++) +// { +// auto o = gs->map->objects[i]; +// if(o) +// logGlobal->traceStream() << boost::format("\tindex=%5d, id=%5d; address=%5d, pos=%s, name=%s") % i % o->id % (int)o.get() % o->pos % o->getHoverText(); +// else +// logGlobal->traceStream() << boost::format("\tindex=%5d --- nullptr") % i; +// } +} +#endif + +#if 1 +void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) +{ + logNetwork->infoStream() <<"Loading procedure started!"; + + CServerHandler sh; if(server) - serv = sh.connectToServer(); + sh.startServer(); + else + serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); + + CStopWatch tmh; + unique_ptr loader; + try + { + std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); + std::string controlServerSaveName; + + if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) + { + controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); + } + else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler + { + controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; + CResourceHandler::get("local")->createResource(controlServerSaveName, true); + } + + if(clientSaveName.empty()) + throw std::runtime_error("Cannot open client part of " + fname); + if(controlServerSaveName.empty()) + throw std::runtime_error("Cannot open server part of " + fname); + + { + CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); + loadCommonState(checkingLoader); + loader = checkingLoader.decay(); + } + logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); + const_cast(CGI)->mh = new CMapHandler(); + const_cast(CGI)->mh->map = gs->map; + pathInfo = make_unique(getMapSize()); + CGI->mh->init(); + logNetwork->infoStream() <<"Initing maphandler: "<errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); + throw; //obviously we cannot continue here + } if(player_==-1) player_ = player->getNum(); else player = PlayerColor(player_); - serv->addStdVecItems(gs); /*why is this here?*/ - std::cout << player << std::endl; + + std::set clientPlayers; + if(server) + serv = sh.connectToServer(); + //*loader >> *this; + if(server) { tmh.update(); @@ -315,38 +401,34 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: if(server) { - *serv << ui32(gs->scenarioOps->playerInfos.size()+2-loadNumPlayers); //number of players + neutral for(auto & elem : gs->scenarioOps->playerInfos) if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) { - *serv << ui8(elem.first.getNum()); //players - if(elem.first!=player) - { - auto AiToGive = aiNameForPlayer(elem.second, false); - logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; - installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); - } - else - { - installNewPlayerInterface(make_shared(*player),*player); - } + clientPlayers.insert(elem.first); } - *serv << ui8(PlayerColor::NEUTRAL.getNum()); + clientPlayers.insert(PlayerColor::NEUTRAL); } else { - *serv << ui32(1); - *serv << ui8(player->getNum()); - installNewPlayerInterface(make_shared(*player),*player); + clientPlayers.insert(player.get()); } + *serv << ui32(clientPlayers.size()); + for(auto & elem : clientPlayers) + *serv << ui8(elem.getNum()); + serialize(*loader,0,clientPlayers); + serv->addStdVecItems(gs); /*why is this here?*/ + + //*loader >> *this; + logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); + logNetwork->infoStream() <<"Sent info to server: "<addStdVecItems(gs); + //*serv << clientPlayers; serv->enableStackSendingByID(); serv->disableSmartPointerSerialization(); - loadNeutralBattleAI(); + //loadNeutralBattleAI(); //wtf did this come from // logGlobal->traceStream() << "Objects:"; // for(int i = 0; i < gs->map->objects.size(); i++) @@ -358,6 +440,7 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: // logGlobal->traceStream() << boost::format("\tindex=%5d --- nullptr") % i; // } } +#endif void CClient::newGame( CConnection *con, StartInfo *si ) { @@ -560,6 +643,76 @@ void CClient::serialize( Handler &h, const int version ) } } +template +void CClient::serialize( Handler &h, const int version, const std::set& playerIDs) +{ + h & hotSeat; + if(h.saving) + { + ui8 players = playerint.size(); + h & players; + + for(auto i = playerint.begin(); i != playerint.end(); i++) + { + LOG_TRACE_PARAMS(logGlobal, "Saving player %s interface", i->first); + assert(i->first == i->second->playerID); + h & i->first & i->second->dllName & i->second->human; + i->second->saveGame(dynamic_cast&>(h), version); + //evil cast that i still like better than sfinae-magic. If I had a "static if"... + } + } + else + { + ui8 players = 0; //fix for uninitialized warning + h & players; + + for(int i=0; i < players; i++) + { + std::string dllname; + PlayerColor pid; + bool isHuman = false; + + h & pid & dllname & isHuman; + LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid); + + shared_ptr nInt; + if(dllname.length()) + { + if(pid == PlayerColor::NEUTRAL) + { + installNewBattleInterface(CDynLibHandler::getNewBattleAI(dllname), pid); + //TODO? consider serialization + continue; + } + else if(playerIDs.count(pid)) + { + assert(!isHuman); + nInt = CDynLibHandler::getNewAI(dllname); + } + } + else + { + assert(isHuman); + nInt = make_shared(pid); + } + + if(!nInt) + nInt = make_shared(pid); + + nInt->dllName = dllname; + nInt->human = isHuman; + nInt->playerID = pid; + + if(playerIDs.count(pid)) + installNewPlayerInterface(nInt, pid); + nInt->loadGame(dynamic_cast&>(h), version); //another evil cast, check above + } + + if(!vstd::contains(battleints, PlayerColor::NEUTRAL)) + loadNeutralBattleAI(); + } +} + void CClient::handlePack( CPack * pack ) { CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier diff --git a/client/Client.h b/client/Client.h index c119dce4d..3740c3a1f 100644 --- a/client/Client.h +++ b/client/Client.h @@ -237,5 +237,6 @@ public: ////////////////////////////////////////////////////////////////////////// template void serialize(Handler &h, const int version); + template void serialize(Handler &h, const int version, const std::set& playerIDs); void battleFinished(); }; diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index e91f19171..9832f6120 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -508,7 +508,6 @@ void CVCMIServer::loadGame() continue; } cc = new CConnection(s,NAME); - cc->addStdVecItems(gh.gs); } gh.conns.insert(cc); } From 7babdccd594af5e6df9d3fde7c72f81a640b39a5 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Thu, 23 Oct 2014 22:18:42 -0400 Subject: [PATCH 08/13] This is very wrong but works better than anything else I've tried. --- client/Client.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index dd014035d..525df1ff6 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -374,11 +374,6 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: throw; //obviously we cannot continue here } - if(player_==-1) - player_ = player->getNum(); - else - player = PlayerColor(player_); - std::cout << player << std::endl; std::set clientPlayers; @@ -413,10 +408,10 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: clientPlayers.insert(player.get()); } + serialize(*loader,0,clientPlayers); *serv << ui32(clientPlayers.size()); for(auto & elem : clientPlayers) *serv << ui8(elem.getNum()); - serialize(*loader,0,clientPlayers); serv->addStdVecItems(gs); /*why is this here?*/ //*loader >> *this; @@ -428,7 +423,7 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: serv->enableStackSendingByID(); serv->disableSmartPointerSerialization(); - //loadNeutralBattleAI(); //wtf did this come from + loadNeutralBattleAI(); //wtf did this come from // logGlobal->traceStream() << "Objects:"; // for(int i = 0; i < gs->map->objects.size(); i++) @@ -680,11 +675,12 @@ void CClient::serialize( Handler &h, const int version, const std::set(pid); } - if(!nInt) - nInt = make_shared(pid); - nInt->dllName = dllname; nInt->human = isHuman; nInt->playerID = pid; if(playerIDs.count(pid)) - installNewPlayerInterface(nInt, pid); + installNewPlayerInterface(nInt, pid); nInt->loadGame(dynamic_cast&>(h), version); //another evil cast, check above } if(!vstd::contains(battleints, PlayerColor::NEUTRAL)) - loadNeutralBattleAI(); + loadNeutralBattleAI(); } } @@ -931,7 +924,7 @@ void CClient::installNewPlayerInterface(shared_ptr gameInterface boost::unique_lock un(*LOCPLINT->pim); PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE); - if(!color) + if(!color) privilagedGameEventReceivers.push_back(gameInterface); playerint[colorUsed] = gameInterface; From 6aa3c11084cbb35c15ab27d7c9bfc502d1fa9817 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Thu, 23 Oct 2014 23:15:41 -0400 Subject: [PATCH 09/13] SUCCESS! --- client/Client.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 525df1ff6..9e08d810f 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -326,6 +326,8 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: #if 1 void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) { + PlayerColor player(player_); //intentional shadowing + logNetwork->infoStream() <<"Loading procedure started!"; CServerHandler sh; @@ -374,7 +376,10 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: throw; //obviously we cannot continue here } - std::cout << player << std::endl; +/* + if(!server) + player = PlayerColor(player_); +*/ std::set clientPlayers; if(server) @@ -394,6 +399,8 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: logNetwork->infoStream() << "Server opened savegame properly."; } + player = PlayerColor(player_); + if(server) { for(auto & elem : gs->scenarioOps->playerInfos) @@ -405,9 +412,14 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: } else { - clientPlayers.insert(player.get()); + clientPlayers.insert(player); } + std::cout << "CLIENTPLAYERS:\n"; + for(auto x : clientPlayers) + std::cout << x << std::endl; + std::cout << "ENDCLIENTPLAYERS\n"; + serialize(*loader,0,clientPlayers); *serv << ui32(clientPlayers.size()); for(auto & elem : clientPlayers) From 1dabdf7b3a7d47e12db6457c75267cafbbf4930e Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sat, 25 Oct 2014 05:04:08 -0400 Subject: [PATCH 10/13] Minor fixes to multiplayer load game support --- client/Client.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 9e08d810f..60e8e98e1 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -399,8 +399,6 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: logNetwork->infoStream() << "Server opened savegame properly."; } - player = PlayerColor(player_); - if(server) { for(auto & elem : gs->scenarioOps->playerInfos) @@ -709,17 +707,18 @@ void CClient::serialize( Handler &h, const int version, const std::setplayerID = pid; if(playerIDs.count(pid)) - installNewPlayerInterface(nInt, pid); - nInt->loadGame(dynamic_cast&>(h), version); //another evil cast, check above + installNewPlayerInterface(nInt, pid); + + nInt->loadGame(dynamic_cast&>(h), version); //another evil cast, check above } - if(!vstd::contains(battleints, PlayerColor::NEUTRAL)) - loadNeutralBattleAI(); +/* if(!vstd::contains(battleints, PlayerColor::NEUTRAL)) + loadNeutralBattleAI();*/ } } void CClient::handlePack( CPack * pack ) -{ +{ CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier if(apply) { From 407755ee777b4909911cdb73dee16d63ec014f9e Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sat, 25 Oct 2014 05:39:12 -0400 Subject: [PATCH 11/13] Minor multiplayer load bugfixes --- client/Client.cpp | 93 +---------------------------------------------- 1 file changed, 2 insertions(+), 91 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 60e8e98e1..aedebbb44 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -236,93 +236,6 @@ void CClient::endGame( bool closeConnection /*= true*/ ) logNetwork->infoStream() << "Client stopped."; } -#if 0 -void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) -{ - logNetwork->infoStream() <<"Loading procedure started!"; - - CServerHandler sh; - sh.startServer(); - - CStopWatch tmh; - try - { - std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); - std::string controlServerSaveName; - - if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME))) - { - controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)); - } - else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler - { - controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1"; - CResourceHandler::get("local")->createResource(controlServerSaveName, true); - } - - if(clientSaveName.empty()) - throw std::runtime_error("Cannot open client part of " + fname); - if(controlServerSaveName.empty()) - throw std::runtime_error("Cannot open server part of " + fname); - - unique_ptr loader; - { - CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); - loadCommonState(checkingLoader); - loader = checkingLoader.decay(); - } - logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); - const_cast(CGI)->mh = new CMapHandler(); - const_cast(CGI)->mh->map = gs->map; - pathInfo = make_unique(getMapSize()); - CGI->mh->init(); - logNetwork->infoStream() <<"Initing maphandler: "<> *this; - logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); - } - catch(std::exception &e) - { - logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); - throw; //obviously we cannot continue here - } - - serv = sh.connectToServer(); - serv->addStdVecItems(gs); - - tmh.update(); - ui8 pom8; - *serv << ui8(3) << ui8(1); //load game; one client - *serv << fname; - *serv >> pom8; - if(pom8) - throw std::runtime_error("Server cannot open the savegame!"); - else - logNetwork->infoStream() << "Server opened savegame properly."; - - *serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral - for(auto & elem : gs->scenarioOps->playerInfos) - { - *serv << ui8(elem.first.getNum()); //players - } - *serv << ui8(PlayerColor::NEUTRAL.getNum()); - logNetwork->infoStream() <<"Sent info to server: "<enableStackSendingByID(); - serv->disableSmartPointerSerialization(); - -// logGlobal->traceStream() << "Objects:"; -// for(int i = 0; i < gs->map->objects.size(); i++) -// { -// auto o = gs->map->objects[i]; -// if(o) -// logGlobal->traceStream() << boost::format("\tindex=%5d, id=%5d; address=%5d, pos=%s, name=%s") % i % o->id % (int)o.get() % o->pos % o->getHoverText(); -// else -// logGlobal->traceStream() << boost::format("\tindex=%5d --- nullptr") % i; -// } -} -#endif - #if 1 void CClient::loadGame(const std::string & fname, const bool server, const std::vector& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port) { @@ -433,8 +346,6 @@ void CClient::loadGame(const std::string & fname, const bool server, const std:: serv->enableStackSendingByID(); serv->disableSmartPointerSerialization(); - loadNeutralBattleAI(); //wtf did this come from - // logGlobal->traceStream() << "Objects:"; // for(int i = 0; i < gs->map->objects.size(); i++) // { @@ -712,8 +623,8 @@ void CClient::serialize( Handler &h, const int version, const std::setloadGame(dynamic_cast&>(h), version); //another evil cast, check above } -/* if(!vstd::contains(battleints, PlayerColor::NEUTRAL)) - loadNeutralBattleAI();*/ + if(playerIDs.count(PlayerColor::NEUTRAL)) + loadNeutralBattleAI(); } } From ec590b9428bf2c0a2f316400e130fa02a66aa7dc Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sat, 25 Oct 2014 19:09:21 -0400 Subject: [PATCH 12/13] Legion artifact bugfixes --- config/artifacts.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/artifacts.json b/config/artifacts.json index 36eb3fa02..13bb52605 100644 --- a/config/artifacts.json +++ b/config/artifacts.json @@ -1656,7 +1656,7 @@ "bonuses" : [ { "type" : "CREATURE_GROWTH", - "subtype" : 2, + "subtype" : 1, "val" : 5, "propagator": "VISITED_TOWN_AND_VISITOR" } @@ -1669,7 +1669,7 @@ "bonuses" : [ { "type" : "CREATURE_GROWTH", - "subtype" : 3, + "subtype" : 2, "val" : 4, "propagator": "VISITED_TOWN_AND_VISITOR" } @@ -1682,7 +1682,7 @@ "bonuses" : [ { "type" : "CREATURE_GROWTH", - "subtype" : 4, + "subtype" : 3, "val" : 3, "propagator": "VISITED_TOWN_AND_VISITOR" } @@ -1695,7 +1695,7 @@ "bonuses" : [ { "type" : "CREATURE_GROWTH", - "subtype" : 5, + "subtype" : 4, "val" : 2, "propagator": "VISITED_TOWN_AND_VISITOR" } @@ -1708,7 +1708,7 @@ "bonuses" : [ { "type" : "CREATURE_GROWTH", - "subtype" : 6, + "subtype" : 5, "val" : 1, "propagator": "VISITED_TOWN_AND_VISITOR" } From 436272f00c3c0446bd6a557a0844a3627a3a30c2 Mon Sep 17 00:00:00 2001 From: Patrick Simmons Date: Sat, 25 Oct 2014 21:15:40 -0400 Subject: [PATCH 13/13] Fix pathfinding bug. --- lib/mapObjects/CGHeroInstance.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index c013ccda7..235a8bd0d 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -101,7 +101,11 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &fro } } if (!nativeArmy) + { ret = VLC->heroh->terrCosts[from.terType]; + ret-=getSecSkillLevel(SecondarySkill::PATHFINDING)*25; + ret = ret < 100 ? 100 : ret; + } } return ret; }