#include "Client.h" #include "../lib/Connection.h" #include "../StartInfo.h" #include "../map.h" #include "../CGameState.h" #include "../CGameInfo.h" #include "../mapHandler.h" #include "../CCallback.h" #include "../CPlayerInterface.h" #include "../CConsoleHandler.h" #include "../lib/NetPacks.h" #include #include #include #include "../hch/CObjectHandler.h" #include "../hch/CGeneralTextHandler.h" #include "../hch/CArtHandler.h" #include #include "../lib/VCMI_Lib.h" CSharedCond > mess(new std::set); std::string toString(MetaString &ms) { std::string ret; for(int i=0;i0) { ret += ms.strings[ms.message[i]-1]; } else { std::vector *vec; int type = ms.texts[-ms.message[i]-1].first, ser = ms.texts[-ms.message[i]-1].second; if(type == 5) { ret += CGI->arth->artifacts[ser].name; continue; } else if(type == 7) { ret += CGI->creh->creatures[ser].namePl; continue; } else if(type == 9) { ret += CGI->objh->mines[ser].first; continue; } else if(type == 10) { ret += CGI->objh->mines[ser].second; continue; } else { switch(type) { case 1: vec = &CGI->generaltexth->allTexts; break; case 2: vec = &CGI->objh->xtrainfo; break; case 3: vec = &CGI->objh->names; break; case 4: vec = &CGI->objh->restypes; break; case 6: vec = &CGI->generaltexth->arraytxt; break; case 8: vec = &CGI->objh->creGens; break; case 11: vec = &CGI->objh->advobtxt; } ret += (*vec)[ser]; } } } for(int i=0;istate = new CGameState(); THC std::cout<<"\tGamestate: "<> pom8; if(pom8) throw "Server cannot open the map!"; c << ui8(si->playerInfos.size()); for(int i=0;iplayerInfos.size();i++) c << ui8(si->playerInfos[i].color); ui32 seed, sum; std::string mapname; c >> mapname >> sum >> seed; THC std::cout<<"\tSending/Getting info to/from the server: "<checksum << std::endl; if(mapa->checksum != sum) { #ifndef __GNUC__ throw std::exception("Wrong checksum"); #else throw std::exception(); #endif exit(-1); } std::cout << "\tUsing random seed: "<state; gs->scenarioOps = si; gs->init(si,mapa,seed); CGI->mh = new CMapHandler(); THC std::cout<<"Initializing GameState (together): "<mh->map = mapa; THC std::cout<<"Creating mapHandler: "<mh->init(); THC std::cout<<"Initializing mapHandler (together): "<state->scenarioOps->playerInfos.size();i++) //initializing interfaces { ui8 color = gs->scenarioOps->playerInfos[i].color; CCallback *cb = new CCallback(gs,color,this); if(!gs->scenarioOps->playerInfos[i].human) playerint[color] = static_cast(CAIHandler::getNewAI(cb,"EmptyAI.dll")); else { gs->currentPlayer = color; playerint[color] = new CPlayerInterface(color,i); playerint[color]->init(cb); } } CGI->consoleh->cb = new CCallback(gs,-1,this); } CClient::~CClient(void) { } void CClient::process(int what) { switch (what) { case 100: //one of our interaces has turn { ui8 player; *serv >> player;//who? std::cout << "It's turn of "<<(unsigned)player<<" player."<> n; std::cout << "New day: "<<(unsigned)n.day<<". Applying changes... "; gs->apply(&n); std::cout << "done!"<> sr; std::cout << "Set amount of "<objh->restypes[sr.resid] << " of player "<<(unsigned)sr.player <<" to "<apply(&sr); playerint[sr.player]->receivedResource(sr.resid,sr.val); break; } case 103: //show info dialog { InfoWindow iw; *serv >> iw; std::vector comps; for(int i=0;ishowInfoDialog(toString(iw.text),comps); break; } case 104: { SetResources sr; *serv >> sr; std::cout << "Set amount of resources of player "<<(unsigned)sr.player<apply(&sr); playerint[sr.player]->receivedResource(-1,-1); break; } case 105: { SetPrimSkill sps; *serv >> sps; std::cout << "Changing hero primary skill"<apply(&sps); playerint[gs->getHero(sps.id)->tempOwner]->heroPrimarySkillChanged(gs->getHero(sps.id),sps.which,sps.val); break; } case 107: { ShowInInfobox sii; *serv >> sii; SComponent sc(sii.c); sc.description = toString(sii.text); if(playerint[sii.player]->human) static_cast(playerint[sii.player])->showComp(sc); break; } case 500: { RemoveHero rh; *serv >> rh; CGHeroInstance *h = static_cast(gs->map->objects[rh.id]); std::cout << "Removing hero with id = "<<(unsigned)rh.id<mh->removeObject(h); gs->apply(&rh); playerint[h->tempOwner]->heroKilled(h); break; } case 501: //hero movement response - we have to notify interfaces and callback { TryMoveHero *th = new TryMoveHero; //will be deleted by callback after processing *serv >> *th; std::cout << "HeroMove: id="<id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<end<apply(th); int player = gs->map->objects[th->id]->getOwner(); if(playerint[player]) { for(std::set::iterator i=th->fowRevealed.begin(); i != th->fowRevealed.end(); i++) playerint[player]->tileRevealed(*i); //boost::function tr = boost::bind(&CGameInterface::tileRevealed,playerint[player]); //std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),tr); } //notify interfacesabout move int nn=0; //number of interfece of currently browsed player for(std::map::iterator i=playerint.begin();i!=playerint.end();i++) { if(gs->players[i->first].fogOfWarMap[th->start.x-1][th->start.y][th->start.z] || gs->players[i->first].fogOfWarMap[th->end.x-1][th->end.y][th->end.z]) { HeroMoveDetails hmd(th->start,th->end,static_cast(gs->map->objects[th->id])); hmd.successful = th->result; i->second->heroMoved(hmd); } } //add info for callback mess.mx->lock(); mess.res->insert(th); mess.mx->unlock(); mess.cv->notify_all(); break; } case 502: { SetGarrisons sg; *serv >> sg; gs->apply(&sg); for(std::map::iterator i = sg.garrs.begin(); i!=sg.garrs.end(); i++) playerint[gs->map->objects[i->first]->tempOwner]->garrisonChanged(gs->map->objects[i->first]); break; } case 503: { SetStrInfo ssi; *serv >> ssi; gs->apply(&ssi); //TODO: notify interfaces break; } case 504: { NewStructures ns; *serv >> ns; gs->apply(&ns); BOOST_FOREACH(si32 bid, ns.bid) playerint[gs->map->objects[ns.tid]->tempOwner]->buildChanged(static_cast(gs->map->objects[ns.tid]),bid,1); break; } case 1001: { SetObjectProperty sop; *serv >> sop; std::cout << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<apply(&sop); break; } case 1002: { SetHoverName shn; *serv >> shn; std::cout << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <mx->lock(); gs->map->objects[shn.id]->hoverName = toString(shn.name); gs->mx->unlock(); break; } case 3000: { BattleStart bs; *serv >> bs; //uses new to allocate memory for battleInfo - must be deleted when battle is over std::cout << "Starting battle!" <apply(&bs); if(playerint.find(gs->curB->side1) != playerint.end()) playerint[gs->curB->side1]->battleStart(&gs->curB->army1, &gs->curB->army2, gs->curB->tile, gs->getHero(gs->curB->hero1), gs->getHero(gs->curB->hero2), 0); if(playerint.find(gs->curB->side2) != playerint.end()) playerint[gs->curB->side2]->battleStart(&gs->curB->army1, &gs->curB->army2, gs->curB->tile, gs->getHero(gs->curB->hero1), gs->getHero(gs->curB->hero2), 1); break; } case 3001: { BattleNextRound bnr; *serv >> bnr; std::cout << "Round nr " << bnr.round <apply(&bnr); //tell players about next round if(playerint.find(gs->curB->side1) != playerint.end()) playerint[gs->curB->side1]->battleNewRound(bnr.round); if(playerint.find(gs->curB->side2) != playerint.end()) playerint[gs->curB->side2]->battleNewRound(bnr.round); break; } case 3002: { BattleSetActiveStack sas; *serv >> sas; std::cout << "Active stack: " << sas.stack <apply(&sas); boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,gs->curB->getStack(sas.stack)->owner)); break; } case 3003: { BattleResult br; *serv >> br; std::cout << "Battle ends. Winner: " << (unsigned)br.winner<< ". Type of end: "<< (unsigned)br.result <curB->side1) != playerint.end()) playerint[gs->curB->side1]->battleEnd(&br); if(playerint.find(gs->curB->side2) != playerint.end()) playerint[gs->curB->side2]->battleEnd(&br); gs->apply(&br); break; } case 3004: { BattleStackMoved br; *serv >> br; std::cout << "Stack "<curB->side1) != playerint.end()) playerint[gs->curB->side1]->battleStackMoved(br.stack,br.tile,br.flags&1,br.flags&2); if(playerint.find(gs->curB->side2) != playerint.end()) playerint[gs->curB->side2]->battleStackMoved(br.stack,br.tile,br.flags&1,br.flags&2); gs->apply(&br); break; } case 9999: break; default: #ifndef __GNUC__ throw std::exception("Not supported server message!"); #else throw std::exception(); #endif break; } } void CClient::waitForMoveAndSend(int color) { BattleAction ba = playerint[color]->activeStack(gs->curB->activeStack); *serv << ui16(3002) << ba; } void CClient::run() { try { ui16 typ; while(1) { *serv >> typ; process(typ); } } HANDLE_EXCEPTION }