From 62b0365e7080666524961b1b95efa4a6dbf913b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sun, 27 Jul 2008 17:07:37 +0000 Subject: [PATCH] Improvements for netcode. AI is working. Townlist won't crash. Moving hero is wrong but won't crash. Giving starting hero is working properly. Town defs are wrong but displayed. --- AI/EmptyAI/CEmptyAI.cpp | 1 + AI/EmptyAI/exp_funcs.cpp | 12 ++-- AI_Base.h | 12 +--- CAdvmapInterface.cpp | 24 +++---- CCallback.cpp | 12 +++- CCallback.h | 7 +- CGameState.cpp | 115 +++++++++++++++++++++++++++++- CGameState.h | 20 +++--- CMT.cpp | 31 ++++++--- CPlayerInterface.cpp | 23 ++++-- CPlayerInterface.h | 2 + client/Client.cpp | 31 +++------ client/Client.h | 3 + global.h | 4 -- lib/Connection.h | 2 +- map.h | 2 +- mapHandler.cpp | 146 +++++++++------------------------------ server/CGameHandler.cpp | 58 +++++++++++----- server/CVCMIServer.cpp | 19 ++--- 19 files changed, 290 insertions(+), 234 deletions(-) diff --git a/AI/EmptyAI/CEmptyAI.cpp b/AI/EmptyAI/CEmptyAI.cpp index 345659259..658b947e0 100644 --- a/AI/EmptyAI/CEmptyAI.cpp +++ b/AI/EmptyAI/CEmptyAI.cpp @@ -10,6 +10,7 @@ void CEmptyAI::init(ICallback * CB) } void CEmptyAI::yourTurn() { + cb->endTurn(); } void CEmptyAI::heroKilled(const CGHeroInstance *) { diff --git a/AI/EmptyAI/exp_funcs.cpp b/AI/EmptyAI/exp_funcs.cpp index 769885432..1c700fe5d 100644 --- a/AI/EmptyAI/exp_funcs.cpp +++ b/AI/EmptyAI/exp_funcs.cpp @@ -1,30 +1,30 @@ +#define VCMI_DLL #include "../../AI_Base.h" #include "CEmptyAI.h" #include #include std::set ais; - -DLL_EXPORT int GetGlobalAiVersion() +extern "C" DLL_EXPORT int GetGlobalAiVersion() { return AI_INTERFACE_VER; } -DLL_EXPORT void GetAiName(char* name) +extern "C" DLL_EXPORT void GetAiName(char* name) { strcpy(name,NAME); } -DLL_EXPORT char * GetAiNameS() +extern "C" DLL_EXPORT char * GetAiNameS() { char * ret = new char[50]; strcpy(ret,NAME); return ret; } -DLL_EXPORT CGlobalAI * GetNewAI() +extern "C" DLL_EXPORT CGlobalAI * GetNewAI() { return new CEmptyAI(); // return } -DLL_EXPORT void ReleaseAI(CGlobalAI * i) +extern "C" DLL_EXPORT void ReleaseAI(CGlobalAI * i) { delete (CEmptyAI*)i; ais.erase(i); diff --git a/AI_Base.h b/AI_Base.h index 2a4247d5e..90be85824 100644 --- a/AI_Base.h +++ b/AI_Base.h @@ -1,16 +1,6 @@ #pragma once #include #include -#include "int3.h" #include "CGameInterface.h" -#define AI_INTERFACE_VER 1 -#ifdef _WIN32 - #define DLL_EXPORT extern "C" __declspec(dllexport) - #define VCMI_API -#elif __GNUC__ >= 4 - #define DLL_EXPORT extern "C" __attribute__ ((visibility("default"))) - #define VCMI_API __attribute__ ((visibility("default"))) -#else - #define VCMI_EXPORT extern "C" -#endif \ No newline at end of file +#define AI_INTERFACE_VER 1 \ No newline at end of file diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index 7fc291a09..25f3dea3a 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -216,17 +216,17 @@ void CMinimap::deactivate() } void CMinimap::showTile(int3 pos) { - int mw = map[0]->w, mh = map[0]->h; - double wo = ((double)mw)/CGI->mh->sizes.x, ho = ((double)mh)/CGI->mh->sizes.y; - for (int ii=0; iipos.w) && (pos.y*ho+jjpos.h)) - CSDL_Ext::SDL_PutPixel(FoW[pos.z],pos.x*wo+ii,pos.y*ho+jj,0,0,0,0,0); + //int mw = map[0]->w, mh = map[0]->h; + //double wo = ((double)mw)/CGI->mh->sizes.x, ho = ((double)mh)/CGI->mh->sizes.y; + //for (int ii=0; iipos.w) && (pos.y*ho+jjpos.h)) + // CSDL_Ext::SDL_PutPixel(FoW[pos.z],pos.x*wo+ii,pos.y*ho+jj,0,0,0,0,0); - } - } + // } + //} } void CMinimap::hideTile(int3 pos) { @@ -598,10 +598,6 @@ CResDataBar::CResDataBar() { bg = BitmapHandler::loadBitmap("ZRESBAR.bmp"); SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255)); - //std::vector kolory; - //SDL_Color p1={40,65,139,255}, p2={36,59,125,255}, p3={35,56,121,255}; - //kolory+=p1,p2,p3; - //blueToPlayersAdv(bg,LOCPLINT->playerID,2,&kolory); graphics->blueToPlayersAdv(bg,LOCPLINT->playerID); pos = genRect(bg->h,bg->w,3,575); diff --git a/CCallback.cpp b/CCallback.cpp index 9673576c0..fb8f4552a 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -14,6 +14,9 @@ #include "CPlayerInterface.h" #include "hch/CBuildingHandler.h" #include "hch/CObjectHandler.h" +#include "lib/Connection.h" +#include "client/Client.h" +#include //LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType) @@ -205,7 +208,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount if( ( found = (ID == t->town->basicCreatures[av->first]) ) //creature is available among basic cretures || (found = (ID == t->town->upgradedCreatures[av->first])) )//creature is available among upgraded cretures { - amount = std::min(amount,av->second); //reduce recruited amount up to available amount + amount = min(amount,av->second); //reduce recruited amount up to available amount ser = av->first; break; } @@ -272,6 +275,13 @@ bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int new //TODO: write return false; } +void CCallback::endTurn() +{ + std::cout << "Player "<<(unsigned)player<<" end his turn."<serv->wmx->lock(); + *cl->serv << ui16(100); //report that we ended turn + cl->serv->wmx->unlock(); +} UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) { UpgradeInfo ret; diff --git a/CCallback.h b/CCallback.h index 34bf91854..9b3f5cd71 100644 --- a/CCallback.h +++ b/CCallback.h @@ -17,6 +17,7 @@ class CGTownInstance; struct StartInfo; class CStack; struct lua_State; +class CClient; //structure gathering info about upgrade possibilites struct UpgradeInfo { @@ -39,6 +40,7 @@ public: virtual void recruitCreatures(const CGObjectInstance *obj, int ID, int amount)=0; virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made + virtual void endTurn()=0; //get info virtual bool verifyPath(CPath * path, bool blockSea)=0; @@ -85,8 +87,9 @@ struct HeroMoveDetails class CCallback : public ICallback { private: - CCallback(CGameState * GS, int Player):gs(GS),player(Player){}; + CCallback(CGameState * GS, int Player, CClient *C):gs(GS),player(Player),cl(C){}; CGameState * gs; + CClient *cl; bool isVisible(int3 pos, int Player); protected: @@ -106,7 +109,7 @@ public: void recruitCreatures(const CGObjectInstance *obj, int ID, int amount); bool dismissCreature(const CArmedInstance *obj, int stackPos); bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1); - + void endTurn(); //get info bool verifyPath(CPath * path, bool blockSea); diff --git a/CGameState.cpp b/CGameState.cpp index 38274bc59..c1d7118f6 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -22,6 +22,8 @@ #include "CLuaHandler.h" #include "lib/NetPacks.h" #include +#include +#include boost::rand48 ran; class CMP_stack @@ -33,12 +35,80 @@ public: } } cmpst ; +CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) +{ + CGObjectInstance * nobj; + switch(id) + { + case 34: //hero + { + CGHeroInstance * nobj; + nobj = new CGHeroInstance(); + nobj->pos = pos; + nobj->tempOwner = owner; + nobj->defInfo = new CGDefInfo(); + nobj->defInfo->id = 34; + nobj->defInfo->subid = subid; + nobj->defInfo->printPriority = 0; + nobj->type = VLC->heroh->heroes[subid]; + for(int i=0;i<6;i++) + { + nobj->defInfo->blockMap[i]=255; + nobj->defInfo->visitMap[i]=0; + } + nobj->ID = id; + nobj->subID = subid; + nobj->defInfo->handler=NULL; + nobj->defInfo->blockMap[5] = 253; + nobj->defInfo->visitMap[5] = 2; + nobj->artifacts.resize(20); + nobj->artifWorn[16] = 3; + nobj->primSkills.resize(4); + nobj->primSkills[0] = nobj->type->heroClass->initialAttack; + nobj->primSkills[1] = nobj->type->heroClass->initialDefence; + nobj->primSkills[2] = nobj->type->heroClass->initialPower; + nobj->primSkills[3] = nobj->type->heroClass->initialKnowledge; + nobj->mana = 10 * nobj->primSkills[3]; + return nobj; + } + case 98: //town + nobj = new CGTownInstance; + break; + default: //rest of objects + nobj = new CGObjectInstance; + nobj->defInfo = VLC->dobjinfo->gobjs[id][subid]; + break; + } + nobj->ID = id; + nobj->subID = subid; + if(!nobj->defInfo) + std::cout <<"No def declaration for " <pos = pos; + //nobj->state = NULL;//new CLuaObjectScript(); + nobj->tempOwner = owner; + nobj->info = NULL; + nobj->defInfo->id = id; + nobj->defInfo->subid = subid; + + //assigning defhandler + if(nobj->ID==34 || nobj->ID==98) + return nobj; + nobj->defInfo = VLC->dobjinfo->gobjs[id][subid]; + //if(!nobj->defInfo->handler) + //{ + // nobj->defInfo->handler = CDefHandler::giveDef(nobj->defInfo->name); + // nobj->defInfo->width = nobj->defInfo->handler->ourImages[0].bitmap->w/32; + // nobj->defInfo->height = nobj->defInfo->handler->ourImages[0].bitmap->h/32; + //} + return nobj; +} CStack::CStack(CCreature * C, int A, int O, int I, bool AO) :creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints) { } void CGameState::apply(IPack * pack) { + mx->lock(); switch(pack->getType()) { case 101://NewTurn @@ -60,6 +130,7 @@ void CGameState::apply(IPack * pack) t->builded = 0; } } + mx->unlock(); } int CGameState::pickHero(int owner) { @@ -302,6 +373,26 @@ int CGameState::getDate(int mode) const } return 0; } +CGameState::CGameState() +{ + mx = new boost::shared_mutex(); +} +CGameState::~CGameState() +{ + delete mx; +} +bool CGameState::checkFunc(int obid, std::string name) +{ + if (objscr.find(obid)!=objscr.end()) + { + if(objscr[obid].find(name)!=objscr[obid].end()) + { + return true; + } + } + return false; +} + void CGameState::init(StartInfo * si, Mapa * map, int Seed) { day = 0; @@ -339,9 +430,29 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) } //std::cout<<"\tRandomizing objects: "<players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==RoE)) + { + int3 hpos = map->players[i].posOfMainTown; + hpos.x+=1;// hpos.y+=1; + int j; + for(j=0; jplayerInfos.size(); j++) + if(scenarioOps->playerInfos[j].color == i) + break; + if(j == scenarioOps->playerInfos.size()) + continue; + int h=pickHero(i); + CGHeroInstance * nnn = static_cast(createObject(34,h,hpos,i)); + nnn->id = map->objects.size(); + //nnn->defInfo->handler = graphics->flags1[0]; + map->heroes.push_back(nnn); + map->objects.push_back(nnn); + } + } + //std::cout<<"\tGiving starting heroes: "<playerInfos.size();i++) { diff --git a/CGameState.h b/CGameState.h index 71945e00c..5c551e1a5 100644 --- a/CGameState.h +++ b/CGameState.h @@ -25,6 +25,11 @@ class CMapHandler; class CPathfinder; struct IPack; +namespace boost +{ + class shared_mutex; +} + struct DLL_EXPORT PlayerState { public: @@ -78,18 +83,11 @@ private: std::map villages, forts, capitols; //def-info for town graphics - bool checkFunc(int obid, std::string name) - { - if (objscr.find(obid)!=objscr.end()) - { - if(objscr[obid].find(name)!=objscr[obid].end()) - { - return true; - } - } - return false; - } + boost::shared_mutex *mx; + CGameState(); + ~CGameState(); + bool checkFunc(int obid, std::string name); void init(StartInfo * si, Mapa * map, int Seed); void apply(IPack * pack); void randomizeObject(CGObjectInstance *cur); diff --git a/CMT.cpp b/CMT.cpp index 6c3df98cf..12b45bcf1 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "SDL_TTF.h" @@ -44,6 +45,10 @@ std::string NAME = NAME_VER + std::string(" (client)"); DLL_EXPORT void initDLL(CLodHandler *b); SDL_Surface * screen, * screen2; extern SDL_Surface * CSDL_Ext::std32bppSurface; + +std::queue events; +boost::mutex eventsM; + TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16; void handleCPPObjS(std::map * mapa, CCPPObjectScript * script) { @@ -56,9 +61,7 @@ void handleCPPObjS(std::map * mapa, CCPPObjectScript * sc } int _tmain(int argc, _TCHAR* argv[]) { - //boost::thread servthr(boost::bind(system,"VCMI_server.exe")); //runs server executable; - //TODO: add versions for other platforms - + std::cout.flags(ios::unitbuf); std::cout << NAME << std::endl; srand ( time(NULL) ); CPG=NULL; @@ -146,9 +149,8 @@ int _tmain(int argc, _TCHAR* argv[]) StartInfo *options = new StartInfo(cpg->runLoop()); /////////////////////////////////////////////////////////////////////////////////////// - cgi->state = new CGameState(); - THC std::cout<<"\tGamestate: "< server_log.txt")); //runs server executable; + //TODO: will it work on non-windows platforms? THC tmh.getDif();pomtime.getDif();//reset timers @@ -173,9 +175,23 @@ int _tmain(int argc, _TCHAR* argv[]) std::ofstream lll("client_log.txt"); CConnection c("localhost","3030",NAME,lll); THC std::cout<<"\tConnecting to the server: "< #include "CPlayerInterface.h" #include "CAdvmapInterface.h" #include "CMessage.h" @@ -20,6 +21,7 @@ #include "CCastleInterface.h" #include "CHeroWindow.h" #include "timeHandler.h" +#include #include #include #include "hch/CPreGameTextHandler.h" @@ -35,6 +37,9 @@ using namespace CSDL_Ext; extern TTF_Font * GEOR16; extern bool continueReadingConsole; +CPlayerInterface * LOCPLINT; +extern std::queue events; +extern boost::mutex eventsM; class OCM_HLP_CGIN { @@ -894,6 +899,7 @@ void TimeInterested::deactivate() } CPlayerInterface::CPlayerInterface(int Player, int serial) { + LOCPLINT = this; playerID=Player; serialID=serial; CGI->localPlayer = playerID; @@ -920,6 +926,7 @@ void CPlayerInterface::init(ICallback * CB) } void CPlayerInterface::yourTurn() { + LOCPLINT = this; makingTurn = true; CGI->localPlayer = serialID; unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling @@ -977,10 +984,13 @@ void CPlayerInterface::yourTurn() timeinterested[i]->tick(); } LOCPLINT->adventureInt->updateScreen = false; - while (SDL_PollEvent(&sEvent)) //wait for event... + eventsM.lock(); + while(!events.empty()) { - handleEvent(&sEvent); + handleEvent(&events.front()); + events.pop(); } + eventsM.unlock(); if (!castleInt) //stuff for advMapInt { ++LOCPLINT->adventureInt->animValHitCount; //for animations @@ -1047,6 +1057,7 @@ void CPlayerInterface::yourTurn() SDL_framerateDelay(mainFPSmng); } adventureInt->hide(); + cb->endTurn(); } inline void subRect(const int & x, const int & y, const int & z, SDL_Rect & r, const int & hid) @@ -2051,7 +2062,7 @@ CStatusBar::CStatusBar(int x, int y, std::string name, int maxw) pos.x=x; pos.y=y; if(maxw >= 0) - pos.w = std::min(bg->w,maxw); + pos.w = min(bg->w,maxw); else pos.w=bg->w; pos.h=bg->h; @@ -2437,7 +2448,7 @@ void CTownList::mouseMoved (SDL_MouseMotionEvent & sEvent) LOCPLINT->statusbar->clear(); return; }; - LOCPLINT->statusbar->print(items[from+ny]->state->hoverText(const_cast(items[from+ny]))); + LOCPLINT->statusbar->print(items[from+ny]->name); } void CTownList::clickLeft(tribool down) @@ -2630,7 +2641,7 @@ void CRecrutationWindow::clickLeft(tribool down) if(isItIn(&genRect(132,102,pos.x+curx,pos.y+64),LOCPLINT->current->motion.x,LOCPLINT->current->motion.y)) { which = i; - int newAmount = std::min(amounts[i],creatures[i].amount); + int newAmount = min(amounts[i],creatures[i].amount); slider->amount = newAmount; if(slider->value > newAmount) slider->moveTo(newAmount); @@ -2727,7 +2738,7 @@ CRecrutationWindow::CRecrutationWindow(const std::vector > &C pos.y = screen->h/2 - bitmap->h/2; pos.w = bitmap->w; pos.h = bitmap->h; - slider = new CSlider(pos.x+176,pos.y+279,135,boost::bind(&CRecrutationWindow::sliderMoved,this, _1),1,std::min(amounts[0],creatures[0].amount),0,true); + slider = new CSlider(pos.x+176,pos.y+279,135,boost::bind(&CRecrutationWindow::sliderMoved,this, _1),1,min(amounts[0],creatures[0].amount),0,true); std::string pom; printAtMiddle(CGI->generaltexth->allTexts[346],113,231,GEOR13,zwykly,bitmap); //cost per troop t printAtMiddle(CGI->generaltexth->allTexts[465],205,231,GEOR13,zwykly,bitmap); //available t diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 8097dd505..d3efc047a 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -524,4 +524,6 @@ public: void show(SDL_Surface * to = NULL); }; +extern CPlayerInterface * LOCPLINT; + #endif //CPLAYERINTERFACE_H \ No newline at end of file diff --git a/client/Client.cpp b/client/Client.cpp index 8c83ab03a..d4c75e38b 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -9,14 +9,17 @@ #include "../CPlayerInterface.h" #include "../CConsoleHandler.h" #include "../lib/NetPacks.h" - +#include +#include CClient::CClient(void) { } CClient::CClient(CConnection *con, StartInfo *si) :serv(con) -{ +{ timeHandler tmh; + CGI->state = new CGameState(); + THC std::cout<<"\tGamestate: "<state->scenarioOps->playerInfos.size();i++) //initializing interfaces { - + CCallback *cb = new CCallback(CGI->state,CGI->state->scenarioOps->playerInfos[i].color,this); if(!CGI->state->scenarioOps->playerInfos[i].human) - CGI->playerint.push_back(static_cast(CAIHandler::getNewAI(new CCallback(CGI->state,CGI->state->scenarioOps->playerInfos[i].color),"EmptyAI.dll"))); + CGI->playerint.push_back(static_cast(CAIHandler::getNewAI(cb,"EmptyAI.dll"))); else { CGI->state->currentPlayer=CGI->state->scenarioOps->playerInfos[i].color; CGI->playerint.push_back(new CPlayerInterface(CGI->state->scenarioOps->playerInfos[i].color,i)); - ((CPlayerInterface*)(CGI->playerint[i]))->init(new CCallback(CGI->state,CGI->state->scenarioOps->playerInfos[i].color)); + ((CPlayerInterface*)(CGI->playerint[i]))->init(cb); } } - CGI->consoleh->cb = new CCallback(CGI->state,-1); + CGI->consoleh->cb = new CCallback(CGI->state,-1,this); } CClient::~CClient(void) { @@ -79,9 +82,7 @@ void CClient::process(int what) ui8 player; *serv >> player;//who? std::cout << "It's turn of "<<(unsigned)player<<" player."<playerint[gs->players[player].serial]->yourTurn(); - *serv << ui16(100); //report that we ended turn - std::cout << "Player "<<(unsigned)player<<" end his turn."<playerint[gs->players[player].serial])); break; } case 101: @@ -109,16 +110,4 @@ void CClient::run() process(typ); } } HANDLE_EXCEPTION - //while(1) //main game loop, one execution per turn - //{ - // CGI->consoleh->cb->newTurn(); - // for (int i=0;iplayerint.size();i++) - // { - // CGI->state->currentPlayer=CGI->playerint[i]->playerID; - // try - // { - // CGI->playerint[i]->yourTurn(); - // }HANDLE_EXCEPTION - // } - //} } \ No newline at end of file diff --git a/client/Client.h b/client/Client.h index 962f77207..893dd3532 100644 --- a/client/Client.h +++ b/client/Client.h @@ -4,6 +4,7 @@ struct StartInfo; class CGameState; class CGameInterface; class CConnection; +class CCallback; class CClient { CGameState *gs; @@ -16,4 +17,6 @@ public: void process(int what); void run(); + + friend class CCallback; }; diff --git a/global.h b/global.h index 0634bbd50..51d66a917 100644 --- a/global.h +++ b/global.h @@ -31,10 +31,6 @@ enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHE HERO_BARBARIAN, HERO_BATTLEMAGE, HERO_BEASTMASTER, HERO_WITCH, HERO_PLANESWALKER, HERO_ELEMENTALIST}; class CGameInfo; extern CGameInfo* CGI; -#define CURPLINT (((CPlayerInterface*)((CGI)->playerint[(CGI)->state->currentPlayer]))) -#define LOCPLINT (((CPlayerInterface*)((CGI)->playerint[(CGI)->localPlayer]))) -//CURPLINT gives pointer to the interface of human player which is currently making turn, -//LOCPLINT gives pointer to the interface which is currently showed (on this machine) #define HEROI_TYPE (0) #define TOWNI_TYPE (1) diff --git a/lib/Connection.h b/lib/Connection.h index 21bedabd1..69621b2e0 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -176,8 +176,8 @@ class DLL_EXPORT CConnection std::ostream &out; CConnection(void); void init(); - boost::mutex *rmx, *wmx; // read/write mutexes public: + boost::mutex *rmx, *wmx; // read/write mutexes template void savePrimitive(const T &data) diff --git a/map.h b/map.h index 16c822380..d73d1ddc9 100644 --- a/map.h +++ b/map.h @@ -462,7 +462,7 @@ struct DLL_EXPORT Mapa std::vector disposedHeroes; std::vector predefinedHeroes; std::vector defy; // list of .def files with definitions from .h3m (may be custom) - std::set defs; // other defInfos - for randomized objects, objects added or modified by script + std::set defs; // other defInfos - for randomized objects, objects added or modified by scripts PlayerInfo players[8]; // info about players std::vector teams; // teams[i] = team of player no i LossCondition lossCondition; diff --git a/mapHandler.cpp b/mapHandler.cpp index 9df769597..30e859301 100644 --- a/mapHandler.cpp +++ b/mapHandler.cpp @@ -568,34 +568,41 @@ void CMapHandler::init() { timeHandler th; th.getDif(); - loadDefs(); + loadDefs(); //loading castles' defs THC std::cout<<"Reading terrain defs: "<>ccc; + for(int i=0;istate->villages[i]; + map->defs.insert(CGI->state->forts[i]); + } + else + n = CGI->state->capitols[i%ccc]; + ifs >> n->name; + map->defs.insert(n); + } + std::cout<<"\tLoading town def info: "<heroes.size();i++) + { + if(!map->heroes[i]->defInfo->handler) + { + map->heroes[i]->defInfo->handler = graphics->flags1[0]; + map->heroes[i]->defInfo->width = map->heroes[i]->defInfo->handler->ourImages[0].bitmap->w/32; + map->heroes[i]->defInfo->height = map->heroes[i]->defInfo->handler->ourImages[0].bitmap->h/32; + } + } + std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs std::for_each(map->defs.begin(),map->defs.end(),processDef); //and non-h3m defs THC std::cout<<"\tUnpacking and handling defs: "<>ccc; - //for(int i=0;idobjinfo->castles[i%ccc]); - // ifs >> n->name; - // if (!(n->handler = CDefHandler::giveDef(n->name))) - // std::cout << "Cannot open "<name<width = n->handler->ourImages[0].bitmap->w/32; - // n->height = n->handler->ourImages[0].bitmap->h/32; - // } - // if(iplayers[i].heroesNames.size();j++) @@ -603,7 +610,7 @@ void CMapHandler::init() usedHeroes.insert(map->players[i].heroesNames[j].heroID); } } - std::cout<<"\tLoading town defs, picking random factions and heroes: "<players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==RoE)) - // { - // int3 hpos = map->players[i].posOfMainTown; - // hpos.x+=1;// hpos.y+=1; - // int j; - // for(j=0;jstate->scenarioOps->playerInfos.size();j++) - // if(CGI->state->scenarioOps->playerInfos[j].color==i) - // break; - // if(j==CGI->state->scenarioOps->playerInfos.size()) - // continue; - // int h=pickHero(i); - // CGHeroInstance * nnn = (CGHeroInstance*)createObject(34,h,hpos,i); - // nnn->defInfo->handler = graphics->flags1[0]; - // map->heroes.push_back(nnn); - // map->objects.push_back(nnn); - // } - //} - std::cout<<"\tGiving starting heroes: "< CMapHandler::getVisitableObjs(int3 pos) return ret; } -CGObjectInstance * CMapHandler::createObject(int id, int subid, int3 pos, int owner) -{ - CGObjectInstance * nobj; - switch(id) - { - case 34: //hero - { - CGHeroInstance * nobj; - nobj = new CGHeroInstance(); - nobj->pos = pos; - nobj->tempOwner = owner; - nobj->defInfo = new CGDefInfo(); - nobj->defInfo->id = 34; - nobj->defInfo->subid = subid; - nobj->defInfo->printPriority = 0; - nobj->type = CGI->heroh->heroes[subid]; - for(int i=0;i<6;i++) - { - nobj->defInfo->blockMap[i]=255; - nobj->defInfo->visitMap[i]=0; - } - nobj->ID = id; - nobj->subID = subid; - nobj->defInfo->handler=NULL; - nobj->defInfo->blockMap[5] = 253; - nobj->defInfo->visitMap[5] = 2; - nobj->artifacts.resize(20); - nobj->artifWorn[16] = 3; - nobj->primSkills.resize(4); - nobj->primSkills[0] = nobj->type->heroClass->initialAttack; - nobj->primSkills[1] = nobj->type->heroClass->initialDefence; - nobj->primSkills[2] = nobj->type->heroClass->initialPower; - nobj->primSkills[3] = nobj->type->heroClass->initialKnowledge; - nobj->mana = 10 * nobj->primSkills[3]; - return nobj; - } - case 98: //town - nobj = new CGTownInstance; - break; - default: //rest of objects - nobj = new CGObjectInstance; - nobj->defInfo = CGI->dobjinfo->gobjs[id][subid]; - break; - } - nobj->ID = id; - nobj->subID = subid; - if(!nobj->defInfo) - std::cout <<"No def declaration for " <pos = pos; - //nobj->state = NULL;//new CLuaObjectScript(); - nobj->tempOwner = owner; - nobj->info = NULL; - nobj->defInfo->id = id; - nobj->defInfo->subid = subid; - - //assigning defhandler - if(nobj->ID==34 || nobj->ID==98) - return nobj; - nobj->defInfo = CGI->dobjinfo->gobjs[id][subid]; - if(!nobj->defInfo->handler) - { - nobj->defInfo->handler = CDefHandler::giveDef(nobj->defInfo->name); - nobj->defInfo->width = nobj->defInfo->handler->ourImages[0].bitmap->w/32; - nobj->defInfo->height = nobj->defInfo->handler->ourImages[0].bitmap->h/32; - } - return nobj; -} - std::string CMapHandler::getDefName(int id, int subid) { CGDefInfo* temp = CGI->dobjinfo->gobjs[id][subid]; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 92c49ebcd..498ee2042 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -12,7 +12,8 @@ #include "../hch/CObjectHandler.h" #include "../hch/CTownHandler.h" #include "../hch/CHeroHandler.h" - +#include "boost/date_time/posix_time/posix_time_types.hpp" //no i/o just types +extern bool end; bool makingTurn; boost::condition_variable cTurn; boost::mutex mTurn; @@ -20,23 +21,41 @@ boost::shared_mutex gsm; void CGameHandler::handleConnection(std::set players, CConnection &c) { - ui16 pom; - while(1) + try { - c >> pom; - switch(pom) + ui16 pom; + while(!end) { - case 100: //my interface end its turn - mTurn.lock(); - makingTurn = false; - mTurn.unlock(); - cTurn.notify_all(); - break; - default: - throw std::exception("Not supported client message!"); - break; + c >> pom; + switch(pom) + { + case 100: //my interface end its turn + mTurn.lock(); + makingTurn = false; + mTurn.unlock(); + cTurn.notify_all(); + break; + default: + throw std::exception("Not supported client message!"); + break; + } } } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + end = true; + } + catch (const std::exception * e) + { + std::cerr << e->what()<< std::endl; + end = true; + delete e; + } + catch(...) + { + end = true; + } } template void CGameHandler::sendToAllClients(CPack * info) { @@ -110,11 +129,12 @@ void CGameHandler::newTurn() // i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k); // } //} - if((gs->day>1) && i->firstday) && i->firstsecond.towns[j]->dailyIncome(); } n.res.insert(r); } + gs->apply(&n); sendToAllClients(&n); //for (std::set::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++) //{ @@ -147,7 +167,7 @@ void CGameHandler::run() boost::thread(boost::bind(&CGameHandler::handleConnection,this,pom,boost::ref(**i))); } - while (1) + while (!end) { newTurn(); for(std::map::iterator i = gs->players.begin(); i != gs->players.end(); i++) @@ -157,9 +177,11 @@ void CGameHandler::run() *connections[i->first] << ui16(100) << i->first; //wait till turn is done boost::unique_lock lock(mTurn); - while(makingTurn) + while(makingTurn && !end) { - cTurn.wait(lock); + boost::posix_time::time_duration p; + p= boost::posix_time::seconds(1); + cTurn.timed_wait(lock,p); } } diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 38614cac8..919123807 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -19,6 +19,7 @@ using namespace boost; using namespace boost::asio; using namespace boost::asio::ip; +bool end = false; CVCMIServer::CVCMIServer() : io(new io_service()), acceptor(new tcp::acceptor(*io, tcp::endpoint(tcp::v4(), 3030))) @@ -26,8 +27,8 @@ CVCMIServer::CVCMIServer() } CVCMIServer::~CVCMIServer() { - delete io; - delete acceptor; + //delete io; + //delete acceptor; } void CVCMIServer::newGame(CConnection &c) @@ -96,7 +97,7 @@ void CVCMIServer::start() } CConnection connection(s,NAME,std::cout); std::cout<<"Got connection!" << std::endl; - while(1) + while(!end) { uint8_t mode; connection >> mode; @@ -127,17 +128,9 @@ int _tmain(int argc, _TCHAR* argv[]) { io_service io_service; CVCMIServer server; - while(1) + while(!end) server.start(); io_service.run(); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - } - catch(...) - { - ; - } + } HANDLE_EXCEPTION return 0; }