| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #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 <boost/bind.hpp>
- #include <boost/thread.hpp>
- #include "../hch/CObjectHandler.h"
- #include "../hch/CGeneralTextHandler.h"
- #include "../hch/CArtHandler.h"
- #include <boost/thread/shared_mutex.hpp>
- CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
- std::string toString(MetaString &ms)
- {
- std::string ret;
- for(int i=0;i<ms.message.size();i++)
- {
- if(ms.message[i]>0)
- {
- ret += ms.strings[ms.message[i]-1];
- }
- else
- {
- std::vector<std::string> *vec;
- int type = ms.texts[-ms.message[i]-1].first;
- if(type == 5)
- {
- ret += CGI->arth->artifacts[ms.texts[-ms.message[i]-1].second].name;
- continue;
- }
- else if(type == 7)
- {
- ret += CGI->creh->creatures[ms.texts[-ms.message[i]-1].second].namePl;
- continue;
- }
- else if(type == 9)
- {
- ret += CGI->objh->mines[ms.texts[-ms.message[i]-1].second].first;
- 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;
- }
- ret += (*vec)[ms.texts[-ms.message[i]-1].second];
- }
- }
- }
- return ret;
- }
- CClient::CClient(void)
- {
- }
- CClient::CClient(CConnection *con, StartInfo *si)
- :serv(con)
- {
- timeHandler tmh;
- CGI->state = new CGameState();
- THC std::cout<<"\tGamestate: "<<tmh.getDif()<<std::endl;
- CConnection &c(*con);
- ////////////////////////////////////////////////////
- ui8 pom8;
- c << ui8(2) << ui8(1); //new game; one client
- c << *si;
- c >> pom8;
- if(pom8) throw "Server cannot open the map!";
- c << ui8(si->playerInfos.size());
- for(int i=0;i<si->playerInfos.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: "<<tmh.getDif()<<std::endl;
- Mapa * mapa = new Mapa(mapname);
- THC std::cout<<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
- std::cout << "\tServer checksum for "<<mapname <<": "<<sum << std::endl;
- std::cout << "\tOur checksum for the map: "<< mapa->checksum << std::endl;
- if(mapa->checksum != sum)
- exit(-1);
- std::cout << "\tUsing random seed: "<<seed << std::endl;
- gs = CGI->state;
- gs->scenarioOps = si;
- gs->init(si,mapa,seed);
- CGI->mh = new CMapHandler();
- THC std::cout<<"Initializing GameState (together): "<<tmh.getDif()<<std::endl;
- CGI->mh->map = mapa;
- THC std::cout<<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
- CGI->mh->init();
- THC std::cout<<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
- for (int i=0; i<CGI->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<CGameInterface*>(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."<<std::endl;
- boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
- break;
- }
- case 101:
- {
- NewTurn n;
- *serv >> n;
- std::cout << "New day: "<<(unsigned)n.day<<". Applying changes... ";
- gs->apply(&n);
- std::cout << "done!"<<std::endl;
- 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="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
- gs->apply(th);
- int player = gs->map->objects[th->id]->getOwner();
- if(playerint[player])
- {
- for(std::set<int3>::iterator i=th->fowRevealed.begin(); i != th->fowRevealed.end(); i++)
- playerint[player]->tileRevealed(*i);
- //boost::function<void(int3)> 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<ui8, CGameInterface*>::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<CGHeroInstance*>(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 1001:
- {
- SetObjectProperty sop;
- *serv >> sop;
- std::cout << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
- gs->apply(&sop);
- break;
- }
- case 1002:
- {
- SetHoverName shn;
- *serv >> shn;
- std::cout << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
- gs->mx->lock();
- gs->map->objects[shn.id]->hoverName = toString(shn.name);
- gs->mx->unlock();
- break;
- }
- case 9999:
- break;
- default:
- throw std::exception("Not supported server message!");
- break;
- }
- }
- void CClient::run()
- {
- try
- {
- ui16 typ;
- while(1)
- {
- *serv >> typ;
- process(typ);
- }
- } HANDLE_EXCEPTION
- }
|