mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Chenges (networking for PG, minor fixes)
This commit is contained in:
parent
dc0cdf68b6
commit
4ba3c68ced
@ -72,6 +72,7 @@ void CButtonBase::showAll( SDL_Surface * to )
|
||||
|
||||
void CButtonBase::addTextOverlay( const std::string Text, EFonts font, SDL_Color color)
|
||||
{
|
||||
delete text;
|
||||
text = new TextOverlay;
|
||||
text->text = Text;
|
||||
|
||||
|
@ -1824,11 +1824,11 @@ void CPlayerInterface::gameOver(ui8 player, bool victory )
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!victory) //enemy has lost
|
||||
if(!victory && cb->getPlayerStatus(playerID) == PlayerState::INGAME) //enemy has lost
|
||||
{
|
||||
std::string txt = CGI->generaltexth->allTexts[5]; //%s has been vanquished!
|
||||
boost::algorithm::replace_first(txt, "%s", CGI->generaltexth->capColors[player]);
|
||||
//showInfoDialog(txt,std::vector<SComponent*>(1, new SComponent(SComponent::flag, player, 0)));
|
||||
showInfoDialog(txt,std::vector<SComponent*>(1, new SComponent(SComponent::flag, player, 0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,11 @@
|
||||
#include "../hch/CArtHandler.h" /*for campaign bonuses*/
|
||||
#include "../hch/CBuildingHandler.h" /*for campaign bonuses*/
|
||||
#include "CBitmapHandler.h"
|
||||
#include "Client.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
|
||||
#define NOT_LIB
|
||||
#include "../lib/RegisterTypes.cpp"
|
||||
|
||||
/*
|
||||
* CPreGame.cpp, part of VCMI engine
|
||||
@ -97,6 +102,29 @@ static void clearInfo()
|
||||
playerNames.clear();
|
||||
}
|
||||
|
||||
class CBaseForPGApply
|
||||
{
|
||||
public:
|
||||
virtual void applyOnPG(CSelectionScreen *selScr, void *pack) const =0;
|
||||
virtual ~CBaseForPGApply(){};
|
||||
template<typename U> static CBaseForPGApply *getApplier(const U * t=NULL)
|
||||
{
|
||||
return new CApplyOnPG<U>;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class CApplyOnPG : public CBaseForPGApply
|
||||
{
|
||||
public:
|
||||
void applyOnPG(CSelectionScreen *selScr, void *pack) const
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
ptr->apply(selScr);
|
||||
}
|
||||
};
|
||||
|
||||
CApplier<CBaseForPGApply> *applier = NULL;
|
||||
|
||||
void CMapInfo::countPlayers()
|
||||
{
|
||||
actualHumanPlayers = playerAmnt = humenPlayers = 0;
|
||||
@ -186,7 +214,7 @@ CMenuScreen::CMenuScreen( EState which )
|
||||
case newGame:
|
||||
{
|
||||
bgAd = new CPicture(BitmapHandler::loadBitmap("ZNEWGAM.bmp"), 114, 312, true);
|
||||
buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[10].second, bind(&CGPreGame::openSel, CGP, newGame, false), 545, 4, "ZTSINGL.DEF", SDLK_s);
|
||||
buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[10].second, bind(&CGPreGame::openSel, CGP, newGame, SINGLE_PLAYER), 545, 4, "ZTSINGL.DEF", SDLK_s);
|
||||
buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[11].second, &pushIntT<CMultiMode>, 568, 120, "ZTMULTI.DEF", SDLK_m);
|
||||
buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[12].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[campaignMain])), 541, 233, "ZTCAMPN.DEF", SDLK_c);
|
||||
buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[13].second, 0 /*cb*/, 545, 358, "ZTTUTOR.DEF", SDLK_t);
|
||||
@ -196,8 +224,8 @@ CMenuScreen::CMenuScreen( EState which )
|
||||
case loadGame:
|
||||
{
|
||||
bgAd = new CPicture(BitmapHandler::loadBitmap("ZLOADGAM.bmp"), 114, 312, true);
|
||||
buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[10].second, bind(&CGPreGame::openSel, CGP, loadGame, false), 545, 4, "ZTSINGL.DEF", SDLK_s);
|
||||
buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[11].second, bind(&CGPreGame::openSel, CGP, loadGame, true), 568, 120, "ZTMULTI.DEF", SDLK_m);
|
||||
buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[10].second, bind(&CGPreGame::openSel, CGP, loadGame, SINGLE_PLAYER), 545, 4, "ZTSINGL.DEF", SDLK_s);
|
||||
buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[11].second, bind(&CGPreGame::openSel, CGP, loadGame, HOT_SEAT), 568, 120, "ZTMULTI.DEF", SDLK_m);
|
||||
buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[12].second, 0 /*cb*/, 541, 233, "ZTCAMPN.DEF", SDLK_c);
|
||||
buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[13].second, 0 /*cb*/, 545, 358, "ZTTUTOR.DEF", SDLK_t);
|
||||
buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[14].second, bind(&CMenuScreen::moveTo, this, CGP->scrs[mainMenu]), 582, 464, "ZTBACK.DEF", SDLK_ESCAPE);
|
||||
@ -208,7 +236,7 @@ CMenuScreen::CMenuScreen( EState which )
|
||||
buttons[0] = new AdventureMapButton("", "", 0 /*cb*/, 535, 8, "ZSSSOD.DEF", SDLK_s);
|
||||
buttons[1] = new AdventureMapButton("", "", 0 /*cb*/, 494, 117, "ZSSROE.DEF", SDLK_m);
|
||||
buttons[2] = new AdventureMapButton("", "", 0 /*cb*/, 486, 241, "ZSSARM.DEF", SDLK_c);
|
||||
buttons[3] = new AdventureMapButton("", "", bind(&CGPreGame::openSel, CGP, campaignList, false), 550, 358, "ZSSCUS.DEF", SDLK_t);
|
||||
buttons[3] = new AdventureMapButton("", "", bind(&CGPreGame::openSel, CGP, campaignList, SINGLE_PLAYER), 550, 358, "ZSSCUS.DEF", SDLK_t);
|
||||
buttons[4] = new AdventureMapButton("", "", bind(&CMenuScreen::moveTo, this, CGP->scrs[newGame]), 582, 464, "ZSSEXIT.DEF", SDLK_ESCAPE);
|
||||
|
||||
}
|
||||
@ -259,10 +287,9 @@ CGPreGame::~CGPreGame()
|
||||
delete scrs[i];
|
||||
}
|
||||
|
||||
void CGPreGame::openSel( CMenuScreen::EState type, bool multi )
|
||||
void CGPreGame::openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi /*= CMenuScreen::SINGLE_PLAYER*/)
|
||||
{
|
||||
resetPlayerNames();
|
||||
|
||||
GH.pushInt(new CSelectionScreen(type, multi));
|
||||
}
|
||||
|
||||
@ -314,10 +341,19 @@ void CGPreGame::resetPlayerNames()
|
||||
playerNames.push_back(CGI->generaltexth->allTexts[434]); //we have only one player and his name is "Player"
|
||||
}
|
||||
|
||||
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer)
|
||||
:multiPlayer(MultiPlayer)
|
||||
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/)
|
||||
:multiPlayer(MultiPlayer), serv(NULL)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
applier = new CApplier<CBaseForPGApply>;
|
||||
|
||||
CServerHandler *sh = NULL;
|
||||
if(multiPlayer == CMenuScreen::MULTI_PLAYER)
|
||||
{
|
||||
sh = new CServerHandler;
|
||||
sh->startServer();
|
||||
}
|
||||
|
||||
IShowActivable::type = BLOCK_ADV_HOTKEYS;
|
||||
pos.w = 762;
|
||||
pos.h = 584;
|
||||
@ -349,7 +385,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer)
|
||||
sInfo.turnTime = 0;
|
||||
curTab = NULL;
|
||||
|
||||
card = new InfoCard(type); //right info card
|
||||
card = new InfoCard(type, multiPlayer == CMenuScreen::MULTI_PLAYER); //right info card
|
||||
if (type == CMenuScreen::campaignList)
|
||||
{
|
||||
opt = NULL;
|
||||
@ -378,6 +414,12 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer)
|
||||
random->addTextOverlay(CGI->generaltexth->allTexts[740], FONT_SMALL);
|
||||
|
||||
start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRBEG.DEF", SDLK_b);
|
||||
|
||||
if(multiPlayer == CMenuScreen::MULTI_PLAYER)
|
||||
{
|
||||
AdventureMapButton *hideChat = new AdventureMapButton(CGI->generaltexth->zelp[48], 0, 619, 75, "GSPBUT2.DEF", SDLK_h);
|
||||
hideChat->addTextOverlay(CGI->generaltexth->allTexts[531], FONT_SMALL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CMenuScreen::loadGame:
|
||||
@ -408,6 +450,13 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer)
|
||||
}
|
||||
|
||||
back = new AdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 529, backName, SDLK_ESCAPE);
|
||||
|
||||
|
||||
if(multiPlayer == CMenuScreen::MULTI_PLAYER)
|
||||
{
|
||||
serv = sh->connectToServer();
|
||||
}
|
||||
delete sh;
|
||||
}
|
||||
|
||||
CSelectionScreen::~CSelectionScreen()
|
||||
@ -416,6 +465,7 @@ CSelectionScreen::~CSelectionScreen()
|
||||
curOpts = NULL;
|
||||
playerColor = -1;
|
||||
playerNames.clear();
|
||||
delete applier;
|
||||
}
|
||||
|
||||
void CSelectionScreen::toggleTab(CIntObject *tab)
|
||||
@ -598,6 +648,19 @@ void CSelectionScreen::difficultyChange( int to )
|
||||
GH.totalRedraw();
|
||||
}
|
||||
|
||||
void CSelectionScreen::handleConnection()
|
||||
{
|
||||
while(serv)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CSelectionScreen::toggleChat()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// A new size filter (Small, Medium, ...) has been selected. Populate
|
||||
// selMaps with the relevant data.
|
||||
void SelectionTab::filter( int size, bool selectFirst )
|
||||
@ -1167,8 +1230,14 @@ void SelectionTab::selectFName( const std::string &fname )
|
||||
|
||||
|
||||
|
||||
InfoCard::InfoCard( CMenuScreen::EState Type )
|
||||
: difficulty(NULL), sizes(NULL), sFlags(NULL), bg(NULL)
|
||||
CChatBox::CChatBox(const Rect &rect)
|
||||
{
|
||||
const int height = 10;
|
||||
//inputBox = new CTextInput(Rect(rect.x, rect.y + rect.h - height, rect.w, height));
|
||||
}
|
||||
|
||||
InfoCard::InfoCard( CMenuScreen::EState Type, bool network )
|
||||
: difficulty(NULL), sizes(NULL), sFlags(NULL), bg(NULL), chatOn(false), chat(NULL)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
pos.x += 393;
|
||||
@ -1209,6 +1278,12 @@ InfoCard::InfoCard( CMenuScreen::EState Type )
|
||||
|
||||
//description needs bg
|
||||
moveChild(new CPicture(*bg, descriptionRect), this, mapDescription, true); //move subpicture bg to our description control (by default it's our (Infocard) child)
|
||||
|
||||
if(network)
|
||||
{
|
||||
new CPicture("CHATPLUG.bmp", 17, 276);
|
||||
chat = new CChatBox(descriptionRect);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1413,6 +1488,36 @@ void InfoCard::showTeamsPopup()
|
||||
GH.pushInt(new CInfoPopup(bmp, true));
|
||||
}
|
||||
|
||||
void InfoCard::toggleChat()
|
||||
{
|
||||
setChat(!chatOn);
|
||||
}
|
||||
|
||||
void InfoCard::setChat(bool activateChat)
|
||||
{
|
||||
if(chatOn == activateChat)
|
||||
return;
|
||||
|
||||
assert(active);
|
||||
|
||||
if(activateChat)
|
||||
{
|
||||
mapDescription->recActions = 0;
|
||||
mapDescription->deactivate();
|
||||
chat->recActions = 255;
|
||||
chat->activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
mapDescription->recActions = 255;
|
||||
mapDescription->activate();
|
||||
chat->recActions = 0;
|
||||
chat->deactivate();
|
||||
}
|
||||
|
||||
chatOn = activateChat;
|
||||
}
|
||||
|
||||
OptionsTab::OptionsTab( CMenuScreen::EState Type)
|
||||
:type(Type)
|
||||
{
|
||||
@ -2172,6 +2277,8 @@ CMultiMode::CMultiMode()
|
||||
txt->setText(CGI->generaltexth->allTexts[434]); //Player
|
||||
|
||||
btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[266], bind(&CMultiMode::openHotseat, this), 373, 78, "MUBHOT.DEF");
|
||||
btns[1] = new AdventureMapButton("Host TCP/IP game", "", bind(&CMultiMode::hostTCP, this), 373, 78 + 57*1, "MUBHOST.DEF");
|
||||
btns[2] = new AdventureMapButton("Join TCP/IP game", "", bind(&CMultiMode::joinTCP, this), 373, 78 + 57*2, "MUBJOIN.DEF");
|
||||
btns[6] = new AdventureMapButton(CGI->generaltexth->zelp[288], bind(&CGuiHandler::popIntTotally, ref(GH), this), 373, 424, "MUBCANC.DEF", SDLK_ESCAPE);
|
||||
}
|
||||
|
||||
@ -2180,6 +2287,19 @@ void CMultiMode::openHotseat()
|
||||
GH.pushInt(new CHotSeatPlayers(txt->text));
|
||||
}
|
||||
|
||||
void CMultiMode::hostTCP()
|
||||
{
|
||||
playerNames.clear();
|
||||
playerNames.push_back(txt->text);
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, CMenuScreen::MULTI_PLAYER));
|
||||
}
|
||||
|
||||
void CMultiMode::joinTCP()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CHotSeatPlayers::CHotSeatPlayers(const std::string &firstPlayer)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
@ -2206,7 +2326,7 @@ void CHotSeatPlayers::enterSelectionScreen()
|
||||
if(txt[i]->text.length())
|
||||
playerNames.push_back(txt[i]->text);
|
||||
|
||||
GH.popInts(2);
|
||||
GH.popInts(2); //pop MP mode window and this
|
||||
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame));
|
||||
}
|
||||
|
||||
@ -2779,7 +2899,7 @@ void CBonusSelection::CRegion::show( SDL_Surface * to )
|
||||
}
|
||||
|
||||
CSavingScreen::CSavingScreen(bool hotseat)
|
||||
: CSelectionScreen(CMenuScreen::saveGame, hotseat)
|
||||
: CSelectionScreen(CMenuScreen::saveGame, hotseat ? CMenuScreen::HOT_SEAT : CMenuScreen::SINGLE_PLAYER)
|
||||
{
|
||||
ourGame = mapInfoFromGame();
|
||||
sInfo = *LOCPLINT->cb->getStartInfo();
|
||||
@ -2791,3 +2911,7 @@ CSavingScreen::~CSavingScreen()
|
||||
|
||||
}
|
||||
|
||||
void ChatMessage::apply(CSelectionScreen *selScreen)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ class CCampaign;
|
||||
class CGStatusBar;
|
||||
class CTextBox;
|
||||
class CCampaignState;
|
||||
class CConnection;
|
||||
|
||||
class CMapInfo
|
||||
{
|
||||
@ -64,6 +65,10 @@ public:
|
||||
mainMenu, newGame, loadGame, campaignMain, saveGame, scenarioInfo, campaignList
|
||||
};
|
||||
|
||||
enum EMultiMode {
|
||||
SINGLE_PLAYER = 0, HOT_SEAT, MULTI_PLAYER
|
||||
};
|
||||
|
||||
CPicture *bgAd;
|
||||
AdventureMapButton *buttons[5];
|
||||
|
||||
@ -82,13 +87,25 @@ struct FileInfo
|
||||
bool inLod; //tells if this file is located in Lod
|
||||
};
|
||||
|
||||
class CChatBox : public CIntObject
|
||||
{
|
||||
public:
|
||||
CTextBox *chatHistory;
|
||||
CTextInput *inputBox;
|
||||
|
||||
CChatBox(const Rect &rect);
|
||||
};
|
||||
|
||||
class InfoCard : public CIntObject
|
||||
{
|
||||
CPicture *bg;
|
||||
public:
|
||||
CMenuScreen::EState type;
|
||||
|
||||
bool chatOn; //if chat is shown, then description is hidden
|
||||
CTextBox *mapDescription;
|
||||
CChatBox *chat;
|
||||
|
||||
CHighlightableButtonsGroup *difficulty;
|
||||
CDefHandler *sizes, *sFlags;;
|
||||
|
||||
@ -96,7 +113,9 @@ public:
|
||||
void showAll(SDL_Surface * to);
|
||||
void clickRight(tribool down, bool previousState);
|
||||
void showTeamsPopup();
|
||||
InfoCard(CMenuScreen::EState Type);
|
||||
void toggleChat();
|
||||
void setChat(bool activateChat);
|
||||
InfoCard(CMenuScreen::EState Type, bool network = false);
|
||||
~InfoCard();
|
||||
};
|
||||
|
||||
@ -214,9 +233,11 @@ public:
|
||||
const CMapInfo *current;
|
||||
StartInfo sInfo;
|
||||
CIntObject *curTab;
|
||||
bool multiPlayer;
|
||||
CMenuScreen::EMultiMode multiPlayer;
|
||||
|
||||
CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer = false);
|
||||
CConnection *serv; //connection to server, used in MP mode
|
||||
|
||||
CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer = CMenuScreen::SINGLE_PLAYER);
|
||||
~CSelectionScreen();
|
||||
void toggleTab(CIntObject *tab);
|
||||
void changeSelection(const CMapInfo *to);
|
||||
@ -224,6 +245,9 @@ public:
|
||||
void startCampaign();
|
||||
void startGame();
|
||||
void difficultyChange(int to);
|
||||
|
||||
void toggleChat();
|
||||
void handleConnection();
|
||||
};
|
||||
|
||||
class CSavingScreen : public CSelectionScreen
|
||||
@ -257,6 +281,8 @@ public:
|
||||
|
||||
CMultiMode();
|
||||
void openHotseat();
|
||||
void hostTCP();
|
||||
void joinTCP();
|
||||
};
|
||||
|
||||
class CHotSeatPlayers : public CIntObject
|
||||
@ -359,7 +385,7 @@ public:
|
||||
~CGPreGame();
|
||||
void update();
|
||||
void run();
|
||||
void openSel(CMenuScreen::EState type, bool multi = false);
|
||||
void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER);
|
||||
|
||||
void resetPlayerNames();
|
||||
void loadGraphics();
|
||||
|
@ -26,11 +26,11 @@
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <sstream>
|
||||
#include "CPreGame.h"
|
||||
|
||||
#undef DLL_EXPORT
|
||||
#define DLL_EXPORT
|
||||
#define NOT_LIB
|
||||
#include "../lib/RegisterTypes.cpp"
|
||||
extern std::string NAME;
|
||||
namespace intpr = boost::interprocess;
|
||||
@ -45,13 +45,21 @@ namespace intpr = boost::interprocess;
|
||||
*
|
||||
*/
|
||||
|
||||
template <typename T> class CApplyOnCL;
|
||||
|
||||
class CBaseForCLApply
|
||||
{
|
||||
public:
|
||||
virtual void applyOnClAfter(CClient *cl, void *pack) const =0;
|
||||
virtual void applyOnClBefore(CClient *cl, void *pack) const =0;
|
||||
virtual ~CBaseForCLApply(){}
|
||||
|
||||
template<typename U> static CBaseForCLApply *getApplier(const U * t=NULL)
|
||||
{
|
||||
return new CApplyOnCL<U>;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class CApplyOnCL : public CBaseForCLApply
|
||||
{
|
||||
public:
|
||||
@ -67,46 +75,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CCLApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,CBaseForCLApply*> apps;
|
||||
|
||||
CCLApplier()
|
||||
{
|
||||
registerTypes2(*this);
|
||||
}
|
||||
~CCLApplier()
|
||||
{
|
||||
std::map<ui16,CBaseForCLApply*>::iterator iter;
|
||||
|
||||
for(iter = apps.begin(); iter != apps.end(); iter++)
|
||||
delete iter->second;
|
||||
}
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = new CApplyOnCL<T>;
|
||||
}
|
||||
|
||||
} *applier = NULL;
|
||||
CApplier<CBaseForCLApply> *applier = NULL;
|
||||
|
||||
void CClient::init()
|
||||
{
|
||||
hotSeat = false;
|
||||
connectionHandler = NULL;
|
||||
pathInfo = NULL;
|
||||
applier = new CCLApplier;
|
||||
applier = new CApplier<CBaseForCLApply>;
|
||||
registerTypes2(*applier);
|
||||
IObjectInterface::cb = this;
|
||||
serv = NULL;
|
||||
gs = NULL;
|
||||
cb = NULL;
|
||||
terminate = false;
|
||||
boost::interprocess::shared_memory_object::remove("vcmi_memory"); //if the application has previously crashed, the memory may not have been removed. to avoid problems - try to destroy it
|
||||
try
|
||||
{
|
||||
shared = new SharedMem();
|
||||
} HANDLE_EXCEPTIONC(tlog1 << "Cannot open interprocess memory: ";)
|
||||
}
|
||||
|
||||
CClient::CClient(void)
|
||||
@ -114,18 +96,20 @@ CClient::CClient(void)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
CClient::CClient(CConnection *con, StartInfo *si)
|
||||
:waitingRequest(false)
|
||||
{
|
||||
init();
|
||||
newGame(con,si);
|
||||
}
|
||||
|
||||
CClient::~CClient(void)
|
||||
{
|
||||
delete pathInfo;
|
||||
delete applier;
|
||||
delete shared;
|
||||
}
|
||||
|
||||
void CClient::waitForMoveAndSend(int color)
|
||||
{
|
||||
try
|
||||
@ -144,7 +128,7 @@ void CClient::run()
|
||||
CPack *pack = NULL;
|
||||
while(!terminate)
|
||||
{
|
||||
pack = retreivePack(); //get the package from the server
|
||||
pack = serv->retreivePack(); //get the package from the server
|
||||
|
||||
if (terminate)
|
||||
{
|
||||
@ -231,8 +215,9 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
LOCPLINT = NULL;
|
||||
while (!playerint.empty())
|
||||
{
|
||||
delete playerint.begin()->second;
|
||||
CGameInterface *pint = playerint.begin()->second;
|
||||
playerint.erase(playerint.begin());
|
||||
delete pint;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CCallback *cb, callbacks)
|
||||
@ -251,13 +236,10 @@ void CClient::loadGame( const std::string & fname )
|
||||
{
|
||||
tlog0 <<"\n\nLoading procedure started!\n\n";
|
||||
|
||||
CServerHandler sh;
|
||||
sh.startServer();
|
||||
|
||||
timeHandler tmh;
|
||||
|
||||
char portc[10];
|
||||
SDL_itoa(conf.cc.port,portc,10);
|
||||
runServer(portc); //create new server
|
||||
tlog0 <<"Restarting server: "<<tmh.getDif()<<std::endl;
|
||||
|
||||
{
|
||||
ui32 ver;
|
||||
char sig[8];
|
||||
@ -284,14 +266,10 @@ void CClient::loadGame( const std::string & fname )
|
||||
|
||||
tlog0 <<"Initing maphandler: "<<tmh.getDif()<<std::endl;
|
||||
}
|
||||
|
||||
waitForServer();
|
||||
tlog0 <<"Waiting for server: "<<tmh.getDif()<<std::endl;
|
||||
|
||||
serv = new CConnection(conf.cc.server,portc,NAME);
|
||||
serv = sh.connectToServer();
|
||||
serv->addStdVecItems(gs);
|
||||
tlog0 <<"Setting up connection: "<<tmh.getDif()<<std::endl;
|
||||
|
||||
tmh.update();
|
||||
ui8 pom8;
|
||||
*serv << ui8(3) << ui8(1); //load game; one client
|
||||
*serv << fname;
|
||||
@ -333,32 +311,8 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
{
|
||||
if (con == NULL)
|
||||
{
|
||||
timeHandler pomtime;
|
||||
char portc[10];
|
||||
SDL_itoa(conf.cc.port,portc,10);
|
||||
CClient::runServer(portc);
|
||||
tlog0<<"Preparing shared memory and starting server: "<<pomtime.getDif()<<std::endl;
|
||||
|
||||
pomtime.getDif();//reset timers
|
||||
|
||||
//wait until server is ready
|
||||
tlog0<<"Waiting for server... ";
|
||||
waitForServer();
|
||||
tlog0 << pomtime.getDif()<<std::endl;
|
||||
while(!con)
|
||||
{
|
||||
try
|
||||
{
|
||||
tlog0 << "Establishing connection...\n";
|
||||
con = new CConnection(conf.cc.server,portc,NAME);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
tlog1 << "\nCannot establish connection! Retrying within 2 seconds" <<std::endl;
|
||||
SDL_Delay(2000);
|
||||
}
|
||||
}
|
||||
THC tlog0<<"\tConnecting to the server: "<<pomtime.getDif()<<std::endl;
|
||||
CServerHandler sh;
|
||||
con = sh.connectToServer();
|
||||
}
|
||||
|
||||
timeHandler tmh;
|
||||
@ -429,21 +383,6 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
playerint[255]->init(new CCallback(gs,255,this));
|
||||
}
|
||||
|
||||
void CClient::runServer(const char * portc)
|
||||
{
|
||||
static std::string comm = std::string(BIN_DIR PATH_SEPARATOR SERVER_NAME " ") + portc + " > server_log.txt"; //needs to be static, if not - will be probably destroyed before new thread reads it
|
||||
boost::thread servthr(boost::bind(system,comm.c_str())); //runs server executable; //TODO: will it work on non-windows platforms?
|
||||
}
|
||||
|
||||
void CClient::waitForServer()
|
||||
{
|
||||
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
|
||||
while(!shared->sr->ready)
|
||||
{
|
||||
shared->sr->cond.wait(slock);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void CClient::serialize( Handler &h, const int version )
|
||||
{
|
||||
@ -487,16 +426,6 @@ void CClient::serialize( Handler &h, const int version )
|
||||
}
|
||||
}
|
||||
|
||||
CPack * CClient::retreivePack()
|
||||
{
|
||||
CPack *ret = NULL;
|
||||
boost::unique_lock<boost::mutex> lock(*serv->rmx);
|
||||
tlog5 << "Listening... ";
|
||||
*serv >> ret;
|
||||
tlog5 << "\treceived server message of type " << typeid(*ret).name() << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CClient::handlePack( CPack * pack )
|
||||
{
|
||||
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier
|
||||
@ -564,3 +493,79 @@ void CClient::stopConnection()
|
||||
|
||||
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
|
||||
template void CClient::serialize( COSer<CSaveFile> &h, const int version );
|
||||
|
||||
void CServerHandler::startServer()
|
||||
{
|
||||
th.update();
|
||||
|
||||
serverThread = new boost::thread(&CServerHandler::callServer, this); //runs server executable; //TODO: will it work on non-windows platforms?
|
||||
if(verbose)
|
||||
tlog0 << "Setting up thread calling server: " << th.getDif() << std::endl;
|
||||
}
|
||||
|
||||
void CServerHandler::waitForServer()
|
||||
{
|
||||
if(!serverThread)
|
||||
startServer();
|
||||
|
||||
th.update();
|
||||
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
|
||||
while(!shared->sr->ready)
|
||||
{
|
||||
shared->sr->cond.wait(slock);
|
||||
}
|
||||
if(verbose)
|
||||
tlog0 << "Waiting for server: " << th.getDif() << std::endl;
|
||||
}
|
||||
|
||||
CConnection * CServerHandler::connectToServer()
|
||||
{
|
||||
if(!shared->sr->ready)
|
||||
waitForServer();
|
||||
|
||||
th.update();
|
||||
CConnection *ret = NULL;
|
||||
while(!ret)
|
||||
{
|
||||
try
|
||||
{
|
||||
tlog0 << "Establishing connection...\n";
|
||||
ret = new CConnection(conf.cc.server, port, NAME);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
tlog1 << "\nCannot establish connection! Retrying within 2 seconds" <<std::endl;
|
||||
SDL_Delay(2000);
|
||||
}
|
||||
}
|
||||
if(verbose)
|
||||
tlog0<<"\tConnecting to the server: "<<th.getDif()<<std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CServerHandler::CServerHandler()
|
||||
{
|
||||
serverThread = NULL;
|
||||
shared = NULL;
|
||||
port = boost::lexical_cast<std::string>(conf.cc.port);
|
||||
|
||||
boost::interprocess::shared_memory_object::remove("vcmi_memory"); //if the application has previously crashed, the memory may not have been removed. to avoid problems - try to destroy it
|
||||
try
|
||||
{
|
||||
shared = new SharedMem();
|
||||
} HANDLE_EXCEPTIONC(tlog1 << "Cannot open interprocess memory: ";)
|
||||
}
|
||||
|
||||
CServerHandler::~CServerHandler()
|
||||
{
|
||||
delete shared;
|
||||
delete serverThread; //detaches, not kills thread
|
||||
}
|
||||
|
||||
void CServerHandler::callServer()
|
||||
{
|
||||
std::string comm = std::string(BIN_DIR PATH_SEPARATOR SERVER_NAME " ") + port + " > server_log.txt";
|
||||
std::system(comm.c_str());
|
||||
tlog0 << "Server finished\n";
|
||||
}
|
||||
|
@ -27,9 +27,30 @@ struct BattleAction;
|
||||
struct SharedMem;
|
||||
class CClient;
|
||||
struct CPathsInfo;
|
||||
namespace boost { class thread; }
|
||||
|
||||
void processCommand(const std::string &message, CClient *&client);
|
||||
|
||||
//structure to handle running server and connecting to it
|
||||
class CServerHandler
|
||||
{
|
||||
private:
|
||||
void callServer(); //calls server via system(), should be called as thread
|
||||
public:
|
||||
timeHandler th;
|
||||
boost::thread *serverThread; //thread that called system to run server
|
||||
SharedMem *shared; //interprocess memory (for waiting for server)
|
||||
bool verbose; //whether to print log msgs
|
||||
std::string port; //port number in text form
|
||||
|
||||
void startServer(); //creates a thread with callServer
|
||||
void waitForServer(); //waits till server is ready
|
||||
CConnection * connectToServer(); //connects to server
|
||||
|
||||
CServerHandler();
|
||||
~CServerHandler();
|
||||
};
|
||||
|
||||
class CClient : public IGameCallback
|
||||
{
|
||||
public:
|
||||
@ -38,7 +59,6 @@ public:
|
||||
std::map<ui8,CGameInterface *> playerint;
|
||||
bool hotSeat;
|
||||
CConnection *serv;
|
||||
SharedMem *shared;
|
||||
BattleAction *curbaction;
|
||||
CPathsInfo *pathInfo;
|
||||
|
||||
@ -111,10 +131,6 @@ public:
|
||||
friend class CCallback; //handling players actions
|
||||
friend void processCommand(const std::string &message, CClient *&client); //handling console
|
||||
|
||||
|
||||
static void runServer(const char * portc);
|
||||
void waitForServer();
|
||||
CPack * retreivePack(); //gets from server next pack (allocates it with new)
|
||||
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
||||
void updatePaths();
|
||||
|
||||
|
@ -66,7 +66,12 @@ class CBaseForGSApply
|
||||
public:
|
||||
virtual void applyOnGS(CGameState *gs, void *pack) const =0;
|
||||
virtual ~CBaseForGSApply(){};
|
||||
template<typename U> static CBaseForGSApply *getApplier(const U * t=NULL)
|
||||
{
|
||||
return new CApplyOnGS<U>;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class CApplyOnGS : public CBaseForGSApply
|
||||
{
|
||||
public:
|
||||
@ -80,29 +85,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CGSApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,CBaseForGSApply*> apps;
|
||||
|
||||
CGSApplier()
|
||||
{
|
||||
registerTypes2(*this);
|
||||
}
|
||||
~CGSApplier()
|
||||
{
|
||||
std::map<ui16,CBaseForGSApply*>::iterator iter;
|
||||
|
||||
for(iter = apps.begin(); iter != apps.end(); iter++)
|
||||
delete iter->second;
|
||||
}
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = new CApplyOnGS<T>;
|
||||
}
|
||||
|
||||
} *applierGs = NULL;
|
||||
CApplier<CBaseForGSApply> *applierGs = NULL;
|
||||
|
||||
class IObjectCaller
|
||||
{
|
||||
@ -1373,7 +1356,8 @@ CGameState::CGameState()
|
||||
map = NULL;
|
||||
curB = NULL;
|
||||
scenarioOps = NULL;
|
||||
applierGs = new CGSApplier;
|
||||
applierGs = new CApplier<CBaseForGSApply>;
|
||||
registerTypes2(*applierGs);
|
||||
objCaller = new CObjectCallersHandler;
|
||||
campaign = NULL;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CTownHandler.h"
|
||||
#include "../hch/CCampaignHandler.h"
|
||||
#include "NetPacks.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -219,6 +220,16 @@ void CConnection::reportState(CLogger &out)
|
||||
}
|
||||
}
|
||||
|
||||
CPack * CConnection::retreivePack()
|
||||
{
|
||||
CPack *ret = NULL;
|
||||
boost::unique_lock<boost::mutex> lock(*rmx);
|
||||
tlog5 << "Listening... ";
|
||||
*this >> ret;
|
||||
tlog5 << "\treceived server message of type " << typeid(*ret).name() << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CSaveFile::CSaveFile( const std::string &fname )
|
||||
:sfile(NULL)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ class CGameState;
|
||||
class CCreature;
|
||||
class LibClasses;
|
||||
class CHero;
|
||||
class CPack;
|
||||
extern DLL_EXPORT LibClasses * VLC;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
@ -863,6 +864,29 @@ public:
|
||||
template<class T>
|
||||
CConnection &operator&(const T&);
|
||||
~CConnection(void);
|
||||
|
||||
CPack *retreivePack(); //gets from server next pack (allocates it with new)
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,T*> apps;
|
||||
|
||||
~CApplier()
|
||||
{
|
||||
std::map<ui16,T*>::iterator iter;
|
||||
|
||||
for(iter = apps.begin(); iter != apps.end(); iter++)
|
||||
delete iter->second;
|
||||
}
|
||||
template<typename U> void registerType(const U * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = T::getApplier(t);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // __CONNECTION_H__
|
||||
|
@ -23,6 +23,7 @@ class CGameHandler;
|
||||
class CConnection;
|
||||
class CCampaignState;
|
||||
class CArtifact;
|
||||
class CSelectionScreen;
|
||||
|
||||
struct CPack
|
||||
{
|
||||
@ -1618,5 +1619,22 @@ struct CenterView : public CPackForClient//515
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************************************************/
|
||||
|
||||
struct CPackForSelectionScreen : public CPack
|
||||
{
|
||||
void apply(CSelectionScreen *selScreen){}; //that functions are implemented in CPreGame.cpp
|
||||
};
|
||||
|
||||
struct ChatMessage : public CPackForSelectionScreen
|
||||
{
|
||||
std::string playerName, message;
|
||||
|
||||
void apply(CSelectionScreen *selScreen);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & playerName & message;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__NETPACKS_H__
|
||||
|
@ -1,12 +1,11 @@
|
||||
#define VCMI_DLL
|
||||
|
||||
|
||||
#include "Connection.h"
|
||||
#include "NetPacks.h"
|
||||
#include "VCMI_Lib.h"
|
||||
#include "../hch/CObjectHandler.h"
|
||||
#include "../hch/CHeroHandler.h"
|
||||
#include "../hch/CTownHandler.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
/*
|
||||
* RegisterTypes.cpp, part of VCMI engine
|
||||
*
|
||||
@ -17,6 +16,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VCMI_DLL
|
||||
#undef DLL_EXPORT
|
||||
#define DLL_EXPORT
|
||||
#endif
|
||||
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
void registerTypes1(Serializer &s)
|
||||
{
|
||||
@ -171,10 +177,17 @@ void registerTypes3(Serializer &s)
|
||||
s.template registerType<PlayerMessage>();
|
||||
}
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
void registerTypes4(Serializer &s)
|
||||
{
|
||||
s.template registerType<ChatMessage>();
|
||||
}
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
void registerTypes(Serializer &s)
|
||||
{
|
||||
registerTypes1(s);
|
||||
registerTypes2(s);
|
||||
registerTypes3(s);
|
||||
registerTypes4(s);
|
||||
}
|
||||
|
@ -60,10 +60,16 @@ CondSh<BattleResult *> battleResult(NULL);
|
||||
std::ptrdiff_t randomizer (ptrdiff_t i) {return rand();}
|
||||
std::ptrdiff_t (*p_myrandom)(std::ptrdiff_t) = randomizer;
|
||||
|
||||
|
||||
class CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
virtual bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack) const =0;
|
||||
virtual ~CBaseForGHApply(){}
|
||||
template<typename U> static CBaseForGHApply *getApplier(const U * t=NULL)
|
||||
{
|
||||
return new CApplyOnGH<U>;
|
||||
}
|
||||
};
|
||||
template <typename T> class CApplyOnGH : public CBaseForGHApply
|
||||
{
|
||||
@ -76,22 +82,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CGHApplier
|
||||
{
|
||||
public:
|
||||
std::map<ui16,CBaseForGHApply*> apps;
|
||||
|
||||
CGHApplier()
|
||||
{
|
||||
registerTypes3(*this);
|
||||
}
|
||||
template<typename T> void registerType(const T * t=NULL)
|
||||
{
|
||||
ui16 ID = typeList.registerType(t);
|
||||
apps[ID] = new CApplyOnGH<T>;
|
||||
}
|
||||
|
||||
} *applier = NULL;
|
||||
CApplier<CBaseForGHApply> *applier = NULL;
|
||||
|
||||
CMP_stack cmpst ;
|
||||
|
||||
@ -938,7 +929,8 @@ CGameHandler::CGameHandler(void)
|
||||
QID = 1;
|
||||
gs = NULL;
|
||||
IObjectInterface::cb = this;
|
||||
applier = new CGHApplier;
|
||||
applier = new CApplier<CBaseForGHApply>;
|
||||
registerTypes3(*applier);
|
||||
visitObjectAfterVictory = false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user