Client.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "Client.h"
  2. #include "../lib/Connection.h"
  3. #include "../StartInfo.h"
  4. #include "../map.h"
  5. #include "../CGameState.h"
  6. #include "../CGameInfo.h"
  7. #include "../mapHandler.h"
  8. #include "../CCallback.h"
  9. #include "../CPlayerInterface.h"
  10. #include "../CConsoleHandler.h"
  11. #include "../lib/NetPacks.h"
  12. #include <boost/bind.hpp>
  13. #include <boost/thread.hpp>
  14. #include "../hch/CObjectHandler.h"
  15. #include "../hch/CGeneralTextHandler.h"
  16. #include "../hch/CArtHandler.h"
  17. #include <boost/thread/shared_mutex.hpp>
  18. CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
  19. std::string toString(MetaString &ms)
  20. {
  21. std::string ret;
  22. for(int i=0;i<ms.message.size();i++)
  23. {
  24. if(ms.message[i]>0)
  25. {
  26. ret += ms.strings[ms.message[i]-1];
  27. }
  28. else
  29. {
  30. std::vector<std::string> *vec;
  31. int type = ms.texts[-ms.message[i]-1].first,
  32. ser = ms.texts[-ms.message[i]-1].second;
  33. if(type == 5)
  34. {
  35. ret += CGI->arth->artifacts[ser].name;
  36. continue;
  37. }
  38. else if(type == 7)
  39. {
  40. ret += CGI->creh->creatures[ser].namePl;
  41. continue;
  42. }
  43. else if(type == 9)
  44. {
  45. ret += CGI->objh->mines[ser].first;
  46. continue;
  47. }
  48. else if(type == 10)
  49. {
  50. ret += CGI->objh->mines[ser].second;
  51. continue;
  52. }
  53. else
  54. {
  55. switch(type)
  56. {
  57. case 1:
  58. vec = &CGI->generaltexth->allTexts;
  59. break;
  60. case 2:
  61. vec = &CGI->objh->xtrainfo;
  62. break;
  63. case 3:
  64. vec = &CGI->objh->names;
  65. break;
  66. case 4:
  67. vec = &CGI->objh->restypes;
  68. break;
  69. case 6:
  70. vec = &CGI->generaltexth->arraytxt;
  71. break;
  72. case 8:
  73. vec = &CGI->objh->creGens;
  74. break;
  75. case 11:
  76. vec = &CGI->objh->advobtxt;
  77. }
  78. ret += (*vec)[ser];
  79. }
  80. }
  81. }
  82. return ret;
  83. }
  84. CClient::CClient(void)
  85. {
  86. }
  87. CClient::CClient(CConnection *con, StartInfo *si)
  88. :serv(con)
  89. {
  90. timeHandler tmh;
  91. CGI->state = new CGameState();
  92. THC std::cout<<"\tGamestate: "<<tmh.getDif()<<std::endl;
  93. CConnection &c(*con);
  94. ////////////////////////////////////////////////////
  95. ui8 pom8;
  96. c << ui8(2) << ui8(1); //new game; one client
  97. c << *si;
  98. c >> pom8;
  99. if(pom8) throw "Server cannot open the map!";
  100. c << ui8(si->playerInfos.size());
  101. for(int i=0;i<si->playerInfos.size();i++)
  102. c << ui8(si->playerInfos[i].color);
  103. ui32 seed, sum;
  104. std::string mapname;
  105. c >> mapname >> sum >> seed;
  106. THC std::cout<<"\tSending/Getting info to/from the server: "<<tmh.getDif()<<std::endl;
  107. Mapa * mapa = new Mapa(mapname);
  108. THC std::cout<<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
  109. std::cout << "\tServer checksum for "<<mapname <<": "<<sum << std::endl;
  110. std::cout << "\tOur checksum for the map: "<< mapa->checksum << std::endl;
  111. if(mapa->checksum != sum)
  112. {
  113. throw std::exception("Wrong checksum");
  114. exit(-1);
  115. }
  116. std::cout << "\tUsing random seed: "<<seed << std::endl;
  117. gs = CGI->state;
  118. gs->scenarioOps = si;
  119. gs->init(si,mapa,seed);
  120. CGI->mh = new CMapHandler();
  121. THC std::cout<<"Initializing GameState (together): "<<tmh.getDif()<<std::endl;
  122. CGI->mh->map = mapa;
  123. THC std::cout<<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
  124. CGI->mh->init();
  125. THC std::cout<<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
  126. for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces
  127. {
  128. ui8 color = gs->scenarioOps->playerInfos[i].color;
  129. CCallback *cb = new CCallback(gs,color,this);
  130. if(!gs->scenarioOps->playerInfos[i].human)
  131. playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,"EmptyAI.dll"));
  132. else
  133. {
  134. gs->currentPlayer = color;
  135. playerint[color] = new CPlayerInterface(color,i);
  136. playerint[color]->init(cb);
  137. }
  138. }
  139. CGI->consoleh->cb = new CCallback(gs,-1,this);
  140. }
  141. CClient::~CClient(void)
  142. {
  143. }
  144. void CClient::process(int what)
  145. {
  146. switch (what)
  147. {
  148. case 100: //one of our interaces has turn
  149. {
  150. ui8 player;
  151. *serv >> player;//who?
  152. std::cout << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
  153. boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
  154. break;
  155. }
  156. case 101:
  157. {
  158. NewTurn n;
  159. *serv >> n;
  160. std::cout << "New day: "<<(unsigned)n.day<<". Applying changes... ";
  161. gs->apply(&n);
  162. std::cout << "done!"<<std::endl;
  163. break;
  164. }
  165. case 102: //set resource amount
  166. {
  167. SetResource sr;
  168. *serv >> sr;
  169. std::cout << "Set amount of "<<CGI->objh->restypes[sr.resid]
  170. << " of player "<<(unsigned)sr.player <<" to "<<sr.val<<std::endl;
  171. gs->apply(&sr);
  172. playerint[sr.player]->receivedResource(sr.resid,sr.val);
  173. break;
  174. }
  175. case 103: //show info dialog
  176. {
  177. InfoWindow iw;
  178. *serv >> iw;
  179. std::vector<Component*> comps;
  180. for(int i=0;i<iw.components.size();i++)
  181. comps.push_back(&iw.components[i]);
  182. playerint[iw.player]->showInfoDialog(toString(iw.text),comps);
  183. break;
  184. }
  185. case 501: //hero movement response - we have to notify interfaces and callback
  186. {
  187. TryMoveHero *th = new TryMoveHero; //will be deleted by callback after processing
  188. *serv >> *th;
  189. std::cout << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
  190. gs->apply(th);
  191. int player = gs->map->objects[th->id]->getOwner();
  192. if(playerint[player])
  193. {
  194. for(std::set<int3>::iterator i=th->fowRevealed.begin(); i != th->fowRevealed.end(); i++)
  195. playerint[player]->tileRevealed(*i);
  196. //boost::function<void(int3)> tr = boost::bind(&CGameInterface::tileRevealed,playerint[player]);
  197. //std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),tr);
  198. }
  199. //notify interfacesabout move
  200. int nn=0; //number of interfece of currently browsed player
  201. for(std::map<ui8, CGameInterface*>::iterator i=playerint.begin();i!=playerint.end();i++)
  202. {
  203. 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])
  204. {
  205. HeroMoveDetails hmd(th->start,th->end,static_cast<CGHeroInstance*>(gs->map->objects[th->id]));
  206. hmd.successful = th->result;
  207. i->second->heroMoved(hmd);
  208. }
  209. }
  210. //add info for callback
  211. mess.mx->lock();
  212. mess.res->insert(th);
  213. mess.mx->unlock();
  214. mess.cv->notify_all();
  215. break;
  216. }
  217. case 502:
  218. {
  219. SetGarrisons sg;
  220. *serv >> sg;
  221. gs->apply(&sg);
  222. for(std::map<ui32,CCreatureSet>::iterator i = sg.garrs.begin(); i!=sg.garrs.end(); i++)
  223. playerint[gs->map->objects[i->first]->tempOwner]->garrisonChanged(gs->map->objects[i->first]);
  224. break;
  225. }
  226. case 1001:
  227. {
  228. SetObjectProperty sop;
  229. *serv >> sop;
  230. std::cout << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
  231. gs->apply(&sop);
  232. break;
  233. }
  234. case 1002:
  235. {
  236. SetHoverName shn;
  237. *serv >> shn;
  238. std::cout << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
  239. gs->mx->lock();
  240. gs->map->objects[shn.id]->hoverName = toString(shn.name);
  241. gs->mx->unlock();
  242. break;
  243. }
  244. case 9999:
  245. break;
  246. default:
  247. throw std::exception("Not supported server message!");
  248. break;
  249. }
  250. }
  251. void CClient::run()
  252. {
  253. try
  254. {
  255. ui16 typ;
  256. while(1)
  257. {
  258. *serv >> typ;
  259. process(typ);
  260. }
  261. } HANDLE_EXCEPTION
  262. }