1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-31 22:05:10 +02:00

multiplayer load changes

This commit is contained in:
Patrick Simmons 2014-10-19 11:21:48 -04:00
parent cfa6f46d62
commit 99a63c4bbd
2 changed files with 88 additions and 62 deletions

View File

@ -246,51 +246,68 @@ void CClient::loadGame(const std::string & fname, const bool server, const std::
else else
serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port); serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);
CStopWatch tmh; CStopWatch tmh;
try if(server)
{ {
std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME)); try
std::string controlServerSaveName; {
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))) if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
{ {
controlServerSaveName = *CResourceHandler::get("local")->getResourceName(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 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"; controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1";
CResourceHandler::get("local")->createResource(controlServerSaveName, true); CResourceHandler::get("local")->createResource(controlServerSaveName, true);
} }
if(clientSaveName.empty()) if(clientSaveName.empty())
throw std::runtime_error("Cannot open client part of " + fname); throw std::runtime_error("Cannot open client part of " + fname);
if(controlServerSaveName.empty()) if(controlServerSaveName.empty())
throw std::runtime_error("Cannot open server part of " + fname); throw std::runtime_error("Cannot open server part of " + fname);
unique_ptr<CLoadFile> loader; unique_ptr<CLoadFile> loader;
{ {
CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion);
loadCommonState(checkingLoader); loadCommonState(checkingLoader);
loader = checkingLoader.decay(); loader = checkingLoader.decay();
} }
logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff(); logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff();
const_cast<CGameInfo*>(CGI)->mh = new CMapHandler(); const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
const_cast<CGameInfo*>(CGI)->mh->map = gs->map; const_cast<CGameInfo*>(CGI)->mh->map = gs->map;
pathInfo = make_unique<CPathsInfo>(getMapSize()); pathInfo = make_unique<CPathsInfo>(getMapSize());
CGI->mh->init(); CGI->mh->init();
logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff(); logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();
*loader >> *this; *loader >> *this;
logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff(); logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();
} }
catch(std::exception &e) catch(std::exception &e)
{ {
logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what(); logGlobal->errorStream() << "Cannot load game " << fname << ". Error: " << e.what();
throw; //obviously we cannot continue here throw; //obviously we cannot continue here
} }
}
if(server) if(server)
{
serv = sh.connectToServer(); serv = sh.connectToServer();
(*serv) << *this;
}
else
{
(*serv) >> *this;
const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
CGI->mh->map = gs->map;
logNetwork->infoStream() <<"Creating mapHandler: "<<tmh.getDiff();
CGI->mh->init();
pathInfo = make_unique<CPathsInfo>(getMapSize());
logNetwork->infoStream() <<"Initializing mapHandler (together): "<<tmh.getDiff();
}
if(player_==-1) if(player_==-1)
player_ = player->getNum(); player_ = player->getNum();
@ -313,38 +330,39 @@ void CClient::loadGame(const std::string & fname, const bool server, const std::
logNetwork->infoStream() << "Server opened savegame properly."; logNetwork->infoStream() << "Server opened savegame properly.";
} }
std::set<PlayerColor> clientPlayers;
if(server) if(server)
{ {
*serv << ui32(gs->scenarioOps->playerInfos.size()+2-loadNumPlayers); //number of players + neutral for(auto & elem : gs->scenarioOps->playerInfos)
for(auto & elem : gs->scenarioOps->playerInfos) if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player)
if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player) {
{ clientPlayers.insert(elem.first);
*serv << ui8(elem.first.getNum()); //players if(elem.first!=player)
if(elem.first!=player) {
{ auto AiToGive = aiNameForPlayer(elem.second, false);
auto AiToGive = aiNameForPlayer(elem.second, false); logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive;
logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % elem.first % AiToGive; installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first);
installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), elem.first); }
} else
else {
{ installNewPlayerInterface(make_shared<CPlayerInterface>(*player),*player);
installNewPlayerInterface(make_shared<CPlayerInterface>(*player),*player); }
} }
} clientPlayers.insert(PlayerColor::NEUTRAL);
*serv << ui8(PlayerColor::NEUTRAL.getNum());
} }
else else
{ {
*serv << ui32(1); clientPlayers.insert(*player);
*serv << ui8(player->getNum()); installNewPlayerInterface(make_shared<CPlayerInterface>(*player),*player);
installNewPlayerInterface(make_shared<CPlayerInterface>(*player),*player);
} }
serv->enableStackSendingByID();
serv->disableSmartPointerSerialization();
(*serv) << clientPlayers;
logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff(); logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff();
serv->addStdVecItems(gs); serv->addStdVecItems(gs);
serv->enableStackSendingByID();
serv->disableSmartPointerSerialization();
loadNeutralBattleAI(); loadNeutralBattleAI();

View File

@ -32,6 +32,12 @@
#include "../lib/UnlockGuard.h" #include "../lib/UnlockGuard.h"
#include "../client/Client.h"
extern template void CClient::serialize<COSer<CSaveFile>>( COSer<CSaveFile> &h, const int version );
extern template void CClient::serialize<CISer<CConnection>>( CISer<CConnection> &h, const int version );
extern template void CClient::serialize<COSer<CConnection>>( COSer<CConnection> &h, const int version );
#if defined(__GNUC__) && !defined (__MINGW32__) && !defined(VCMI_ANDROID) #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(VCMI_ANDROID)
#include <execinfo.h> #include <execinfo.h>
#endif #endif
@ -491,11 +497,13 @@ void CVCMIServer::loadGame()
c << ui8(0); c << ui8(0);
CConnection* cc; //tcp::socket * ss; CConnection* cc; //tcp::socket * ss;
CClient client_in;
for(int i=0; i<clients; i++) for(int i=0; i<clients; i++)
{ {
if(!i) if(!i)
{ {
cc = &c; cc = &c;
(*cc) >> client_in;
} }
else else
{ {
@ -508,8 +516,8 @@ void CVCMIServer::loadGame()
continue; continue;
} }
cc = new CConnection(s,NAME); cc = new CConnection(s,NAME);
cc->addStdVecItems(gh.gs); (*cc) << client_in;
} }
gh.conns.insert(cc); gh.conns.insert(cc);
} }