Connection.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. /*
  2. * Connection.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include <typeinfo> //XXX this is in namespace std if you want w/o use typeinfo.h?
  12. #include <type_traits>
  13. #include <boost/variant.hpp>
  14. #include <boost/mpl/eval_if.hpp>
  15. #include <boost/mpl/equal_to.hpp>
  16. #include <boost/mpl/int.hpp>
  17. #include <boost/mpl/identity.hpp>
  18. #include <boost/any.hpp>
  19. #include "ConstTransitivePtr.h"
  20. #include "CCreatureSet.h" //for CStackInstance
  21. #include "CObjectHandler.h" //for CArmedInstance
  22. #include "Mapping/CCampaignHandler.h" //for CCampaignState
  23. const ui32 version = 739;
  24. class CConnection;
  25. class CGObjectInstance;
  26. class CStackInstance;
  27. class CGameState;
  28. class CCreature;
  29. class LibClasses;
  30. class CHero;
  31. struct CPack;
  32. extern DLL_LINKAGE LibClasses * VLC;
  33. namespace mpl = boost::mpl;
  34. const std::string SAVEGAME_MAGIC = "VCMISVG";
  35. namespace boost
  36. {
  37. namespace asio
  38. {
  39. namespace ip
  40. {
  41. class tcp;
  42. }
  43. class io_service;
  44. template <typename Protocol> class stream_socket_service;
  45. template <typename Protocol,typename StreamSocketService>
  46. class basic_stream_socket;
  47. template <typename Protocol> class socket_acceptor_service;
  48. template <typename Protocol,typename SocketAcceptorService>
  49. class basic_socket_acceptor;
  50. }
  51. class mutex;
  52. }
  53. enum SerializationLvl
  54. {
  55. Wrong=0,
  56. Boolean,
  57. Primitive,
  58. Array,
  59. Pointer,
  60. Enum,
  61. Serializable,
  62. BooleanVector
  63. };
  64. struct TypeComparer
  65. {
  66. bool operator()(const std::type_info *a, const std::type_info *b) const
  67. {
  68. return a->before(*b);
  69. }
  70. };
  71. class DLL_LINKAGE CTypeList
  72. {
  73. typedef std::multimap<const std::type_info *,ui16,TypeComparer> TTypeMap;
  74. TTypeMap types;
  75. public:
  76. CTypeList();
  77. ui16 registerType(const std::type_info *type);
  78. template <typename T> ui16 registerType(const T * t = NULL)
  79. {
  80. return registerType(getTypeInfo(t));
  81. }
  82. ui16 getTypeID(const std::type_info *type);
  83. template <typename T> ui16 getTypeID(const T * t = NULL)
  84. {
  85. return getTypeID(getTypeInfo(t));
  86. }
  87. template <typename T> const std::type_info * getTypeInfo(const T * t = NULL)
  88. {
  89. if(t)
  90. return &typeid(*t);
  91. else
  92. return &typeid(T);
  93. }
  94. };
  95. extern DLL_LINKAGE CTypeList typeList;
  96. template<typename Ser>
  97. struct SaveBoolean
  98. {
  99. static void invoke(Ser &s, const bool &data)
  100. {
  101. s.saveBoolean(data);
  102. }
  103. };
  104. template<typename Ser>
  105. struct LoadBoolean
  106. {
  107. static void invoke(Ser &s, bool &data)
  108. {
  109. s.loadBoolean(data);
  110. }
  111. };
  112. template<typename Ser>
  113. struct SaveBooleanVector
  114. {
  115. static void invoke(Ser &s, const std::vector<bool> &data)
  116. {
  117. s.saveBooleanVector(data);
  118. }
  119. };
  120. template<typename Ser>
  121. struct LoadBooleanVector
  122. {
  123. static void invoke(Ser &s, std::vector<bool> &data)
  124. {
  125. s.loadBooleanVector(data);
  126. }
  127. };
  128. template<typename Ser,typename T>
  129. struct SavePrimitive
  130. {
  131. static void invoke(Ser &s, const T &data)
  132. {
  133. s.savePrimitive(data);
  134. }
  135. };
  136. template<typename Ser,typename T>
  137. struct SaveSerializable
  138. {
  139. static void invoke(Ser &s, const T &data)
  140. {
  141. s.saveSerializable(data);
  142. }
  143. };
  144. template<typename Ser,typename T>
  145. struct SaveEnum
  146. {
  147. static void invoke(Ser &s, const T &data)
  148. {
  149. s.saveEnum(data);
  150. }
  151. };
  152. template<typename Ser,typename T>
  153. struct LoadEnum
  154. {
  155. static void invoke(Ser &s, T &data)
  156. {
  157. s.loadEnum(data);
  158. }
  159. };
  160. template<typename Ser,typename T>
  161. struct LoadPrimitive
  162. {
  163. static void invoke(Ser &s, T &data)
  164. {
  165. s.loadPrimitive(data);
  166. }
  167. };
  168. template<typename Ser,typename T>
  169. struct SavePointer
  170. {
  171. static void invoke(Ser &s, const T &data)
  172. {
  173. s.savePointer(data);
  174. }
  175. };
  176. template<typename Ser,typename T>
  177. struct LoadPointer
  178. {
  179. static void invoke(Ser &s, T &data)
  180. {
  181. s.loadPointer(data);
  182. }
  183. };
  184. template<typename Ser,typename T>
  185. struct SaveArray
  186. {
  187. static void invoke(Ser &s, const T &data)
  188. {
  189. s.saveArray(data);
  190. }
  191. };
  192. template<typename Ser,typename T>
  193. struct LoadArray
  194. {
  195. static void invoke(Ser &s, T &data)
  196. {
  197. s.loadArray(data);
  198. }
  199. };
  200. template<typename Ser,typename T>
  201. struct LoadSerializable
  202. {
  203. static void invoke(Ser &s, T &data)
  204. {
  205. s.loadSerializable(data);
  206. }
  207. };
  208. template<typename Ser,typename T>
  209. struct SaveWrong
  210. {
  211. static void invoke(Ser &s, const T &data)
  212. {
  213. throw std::runtime_error("Wrong save serialization call!");
  214. }
  215. };
  216. template<typename Ser,typename T>
  217. struct LoadWrong
  218. {
  219. static void invoke(Ser &s, const T &data)
  220. {
  221. throw std::runtime_error("Wrong load serialization call!");
  222. }
  223. };
  224. template<typename T>
  225. struct SerializationLevel
  226. {
  227. typedef mpl::integral_c_tag tag;
  228. typedef
  229. typename mpl::eval_if<
  230. boost::is_same<T, bool>,
  231. mpl::int_<Boolean>,
  232. //else
  233. typename mpl::eval_if<
  234. boost::is_same<T, std::vector<bool> >,
  235. mpl::int_<BooleanVector>,
  236. //else
  237. typename mpl::eval_if<
  238. boost::is_fundamental<T>,
  239. mpl::int_<Primitive>,
  240. //else
  241. typename mpl::eval_if<
  242. boost::is_enum<T>,
  243. mpl::int_<Enum>,
  244. //else
  245. typename mpl::eval_if<
  246. boost::is_class<T>,
  247. mpl::int_<Serializable>,
  248. //else
  249. typename mpl::eval_if<
  250. boost::is_array<T>,
  251. mpl::int_<Array>,
  252. //else
  253. typename mpl::eval_if<
  254. boost::is_pointer<T>,
  255. mpl::int_<Pointer>,
  256. //else
  257. typename mpl::eval_if<
  258. boost::is_enum<T>,
  259. mpl::int_<Primitive>,
  260. //else
  261. mpl::int_<Wrong>
  262. >
  263. >
  264. >
  265. >
  266. >
  267. >
  268. >
  269. >::type type;
  270. static const int value = SerializationLevel::type::value;
  271. };
  272. template <typename T, typename U>
  273. struct VectorisedObjectInfo
  274. {
  275. const std::vector<ConstTransitivePtr<T> > *vector; //pointer to the appropriate vector
  276. const U T::*idPtr; //pointer to the field representing the position in the vector
  277. VectorisedObjectInfo(const std::vector< ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
  278. :vector(Vector), idPtr(IdPtr)
  279. {
  280. }
  281. };
  282. template<typename T>
  283. si32 idToNumber(const T &t, typename boost::enable_if<boost::is_convertible<T,si32> >::type * dummy = 0)
  284. {
  285. return t;
  286. }
  287. template<typename T, typename NT>
  288. NT idToNumber(const BaseForID<T, NT> &t)
  289. {
  290. return t.getNum();
  291. }
  292. /// Class which is responsible for storing and loading data.
  293. class DLL_LINKAGE CSerializer
  294. {
  295. public:
  296. typedef std::map<const std::type_info *, boost::any, TypeComparer> TTypeVecMap;
  297. TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
  298. bool smartVectorMembersSerialization;
  299. bool sendStackInstanceByIds;
  300. CSerializer();
  301. ~CSerializer();
  302. virtual void reportState(CLogger &out){};
  303. template <typename T, typename U>
  304. void registerVectoredType(const std::vector<T*> *Vector, const U T::*IdPtr)
  305. {
  306. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
  307. }
  308. template <typename T, typename U>
  309. void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
  310. {
  311. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
  312. }
  313. template <typename T, typename U>
  314. const VectorisedObjectInfo<T, U> *getVectorisedTypeInfo()
  315. {
  316. const std::type_info *myType = NULL;
  317. //
  318. // if(boost::is_base_of<CGObjectInstance, T>::value) //ugly workaround to support also types derived from CGObjectInstance -> if we encounter one, treat it aas CGObj..
  319. // myType = &typeid(CGObjectInstance);
  320. // else
  321. myType = &typeid(T);
  322. TTypeVecMap::iterator i = vectors.find(myType);
  323. if(i == vectors.end())
  324. return NULL;
  325. else
  326. {
  327. assert(!i->second.empty());
  328. assert(i->second.type() == typeid(VectorisedObjectInfo<T, U>));
  329. VectorisedObjectInfo<T, U> *ret = &(boost::any_cast<VectorisedObjectInfo<T, U>&>(i->second));
  330. return ret;
  331. }
  332. }
  333. template <typename T, typename U>
  334. T* getVectorItemFromId(const VectorisedObjectInfo<T, U> &oInfo, U id) const
  335. {
  336. /* if(id < 0)
  337. return NULL;*/
  338. si32 idAsNumber = idToNumber(id);
  339. assert(oInfo.vector);
  340. assert(static_cast<si32>(oInfo.vector->size()) > idAsNumber);
  341. return const_cast<T*>((*oInfo.vector)[idAsNumber].get());
  342. }
  343. template <typename T, typename U>
  344. U getIdFromVectorItem(const VectorisedObjectInfo<T, U> &oInfo, const T* obj) const
  345. {
  346. if(!obj)
  347. return U(-1);
  348. return obj->*oInfo.idPtr;
  349. }
  350. void addStdVecItems(CGameState *gs, LibClasses *lib = VLC);
  351. };
  352. class DLL_LINKAGE CSaverBase : public virtual CSerializer
  353. {
  354. };
  355. class CBasicPointerSaver
  356. {
  357. public:
  358. virtual void savePtr(CSaverBase &ar, const void *data) const =0;
  359. virtual ~CBasicPointerSaver(){}
  360. };
  361. template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
  362. {
  363. public:
  364. void savePtr(CSaverBase &ar, const void *data) const
  365. {
  366. Serializer &s = static_cast<Serializer&>(ar);
  367. const T *ptr = static_cast<const T*>(data);
  368. //T is most derived known type, it's time to call actual serialize
  369. const_cast<T&>(*ptr).serialize(s,version);
  370. }
  371. };
  372. template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
  373. struct VectorisedTypeFor
  374. {
  375. typedef typename
  376. //if
  377. mpl::eval_if<boost::is_base_of<CGObjectInstance,T>,
  378. mpl::identity<CGObjectInstance>,
  379. //else
  380. mpl::identity<T>
  381. >::type type;
  382. };
  383. template <typename U>
  384. struct VectorizedIDType
  385. {
  386. typedef typename
  387. //if
  388. mpl::eval_if<boost::is_same<CArtifact,U>,
  389. mpl::identity<ArtifactID>,
  390. //else if
  391. mpl::eval_if<boost::is_same<CCreature,U>,
  392. mpl::identity<CreatureID>,
  393. //else if
  394. mpl::eval_if<boost::is_same<CArtifactInstance,U>,
  395. mpl::identity<ArtifactInstanceID>,
  396. //else if
  397. mpl::eval_if<boost::is_base_of<CGObjectInstance,U>,
  398. mpl::identity<ObjectInstanceID>,
  399. //else
  400. mpl::identity<si32>
  401. > > > >::type type;
  402. };
  403. template <typename Handler>
  404. struct VariantVisitorSaver : boost::static_visitor<>
  405. {
  406. Handler &h;
  407. VariantVisitorSaver(Handler &H):h(H)
  408. {
  409. }
  410. template <typename T>
  411. void operator()(const T &t)
  412. {
  413. h << t;
  414. }
  415. };
  416. template<typename Ser,typename T>
  417. struct SaveIfStackInstance
  418. {
  419. static bool invoke(Ser &s, const T &data)
  420. {
  421. return false;
  422. }
  423. };
  424. template<typename Ser>
  425. struct SaveIfStackInstance<Ser, CStackInstance *>
  426. {
  427. static bool invoke(Ser &s, const CStackInstance* const &data)
  428. {
  429. assert(data->armyObj);
  430. SlotID slot;
  431. if(data->getNodeType() == CBonusSystemNode::COMMANDER)
  432. slot = SlotID::COMMANDER_SLOT_PLACEHOLDER;
  433. else
  434. slot = data->armyObj->findStack(data);
  435. assert(slot != SlotID());
  436. s << data->armyObj << slot;
  437. return true;
  438. }
  439. };
  440. template<typename Ser,typename T>
  441. struct LoadIfStackInstance
  442. {
  443. static bool invoke(Ser &s, T &data)
  444. {
  445. return false;
  446. }
  447. };
  448. template<typename Ser>
  449. struct LoadIfStackInstance<Ser, CStackInstance *>
  450. {
  451. static bool invoke(Ser &s, CStackInstance* &data)
  452. {
  453. CArmedInstance *armedObj;
  454. SlotID slot;
  455. s >> armedObj >> slot;
  456. if(slot != SlotID::COMMANDER_SLOT_PLACEHOLDER)
  457. {
  458. assert(armedObj->hasStackAtSlot(slot));
  459. data = armedObj->stacks[slot];
  460. }
  461. else
  462. {
  463. auto hero = dynamic_cast<CGHeroInstance *>(armedObj);
  464. assert(hero);
  465. assert(hero->commander);
  466. data = hero->commander;
  467. }
  468. return true;
  469. }
  470. };
  471. /// The class which manages saving objects.
  472. template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
  473. {
  474. public:
  475. bool saving;
  476. std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
  477. std::map<const void*, ui32> savedPointers;
  478. bool smartPointerSerialization;
  479. COSer()
  480. {
  481. saving=true;
  482. smartPointerSerialization = true;
  483. }
  484. ~COSer()
  485. {
  486. std::map<ui16,CBasicPointerSaver*>::iterator iter;
  487. for(iter = savers.begin(); iter != savers.end(); iter++)
  488. delete iter->second;
  489. }
  490. template<typename T> void registerType(const T * t=NULL)
  491. {
  492. ui16 ID = typeList.registerType(t);
  493. savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
  494. }
  495. Serializer * This()
  496. {
  497. return static_cast<Serializer*>(this);
  498. }
  499. template<class T>
  500. Serializer & operator<<(const T &t)
  501. {
  502. this->This()->save(t);
  503. return * this->This();
  504. }
  505. template<class T>
  506. COSer & operator&(const T & t)
  507. {
  508. return * this->This() << t;
  509. }
  510. int write(const void * data, unsigned size);
  511. template <typename T>
  512. void savePrimitive(const T &data)
  513. {
  514. this->This()->write(&data,sizeof(data));
  515. }
  516. template <typename T>
  517. void savePointer(const T &data)
  518. {
  519. //write if pointer is not NULL
  520. ui8 hlp = (data!=NULL);
  521. *this << hlp;
  522. //if pointer is NULL then we don't need anything more...
  523. if(!hlp)
  524. return;
  525. if(smartVectorMembersSerialization)
  526. {
  527. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType;
  528. typedef typename VectorisedTypeFor<TObjectType>::type VType;
  529. typedef typename VectorizedIDType<TObjectType>::type IDType;
  530. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  531. {
  532. IDType id = getIdFromVectorItem<VType>(*info, data);
  533. *this << id;
  534. if(id != IDType(-1)) //vector id is enough
  535. return;
  536. }
  537. }
  538. if(sendStackInstanceByIds)
  539. {
  540. const bool gotSaved = SaveIfStackInstance<Serializer,T>::invoke(*This(), data);
  541. if(gotSaved)
  542. return;
  543. }
  544. if(smartPointerSerialization)
  545. {
  546. std::map<const void*,ui32>::iterator i = savedPointers.find(data);
  547. if(i != savedPointers.end())
  548. {
  549. //this pointer has been already serialized - write only it's id
  550. *this << i->second;
  551. return;
  552. }
  553. //give id to this pointer
  554. ui32 pid = (ui32)savedPointers.size();
  555. savedPointers[data] = pid;
  556. *this << pid;
  557. }
  558. //write type identifier
  559. ui16 tid = typeList.getTypeID(data);
  560. *this << tid;
  561. This()->savePointerHlp(tid, data);
  562. }
  563. //that part of ptr serialization was extracted to allow customization of its behavior in derived classes
  564. template <typename T>
  565. void savePointerHlp(ui16 tid, const T &data)
  566. {
  567. if(!tid)
  568. *this << *data; //if type is unregistered simply write all data in a standard way
  569. else
  570. savers[tid]->savePtr(*this,data); //call serializer specific for our real type
  571. }
  572. template <typename T>
  573. void saveArray(const T &data)
  574. {
  575. ui32 size = ARRAY_COUNT(data);
  576. for(ui32 i=0; i < size; i++)
  577. *this << data[i];
  578. }
  579. template <typename T>
  580. void save(const T &data)
  581. {
  582. typedef
  583. //if
  584. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  585. mpl::identity<SaveBoolean<Serializer> >,
  586. //else if
  587. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  588. mpl::identity<SaveBooleanVector<Serializer> >,
  589. //else if
  590. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  591. mpl::identity<SavePrimitive<Serializer,T> >,
  592. //else if
  593. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  594. mpl::identity<SaveEnum<Serializer,T> >,
  595. //else if
  596. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  597. mpl::identity<SavePointer<Serializer,T> >,
  598. //else if
  599. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  600. mpl::identity<SaveArray<Serializer,T> >,
  601. //else if
  602. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  603. mpl::identity<SaveSerializable<Serializer,T> >,
  604. //else
  605. mpl::identity<SaveWrong<Serializer,T> >
  606. >
  607. >
  608. >
  609. >
  610. >
  611. >
  612. >::type typex;
  613. typex::invoke(* this->This(), data);
  614. }
  615. template <typename T>
  616. void saveSerializable(const T &data)
  617. {
  618. const_cast<T&>(data).serialize(*this,version);
  619. }
  620. template <typename T>
  621. void saveSerializable(const shared_ptr<T> &data)
  622. {
  623. T *internalPtr = data.get();
  624. *this << internalPtr;
  625. }
  626. template <typename T>
  627. void saveSerializable(const unique_ptr<T> &data)
  628. {
  629. T *internalPtr = data.get();
  630. *this << internalPtr;
  631. }
  632. template <typename T>
  633. void saveSerializable(const std::vector<T> &data)
  634. {
  635. ui32 length = data.size();
  636. *this << length;
  637. for(ui32 i=0;i<length;i++)
  638. *this << data[i];
  639. }
  640. template <typename T>
  641. void saveSerializable(const std::set<T> &data)
  642. {
  643. std::set<T> &d = const_cast<std::set<T> &>(data);
  644. ui32 length = d.size();
  645. *this << length;
  646. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  647. *this << *i;
  648. }
  649. template <typename T, typename U>
  650. void saveSerializable(const boost::unordered_set<T, U> &data)
  651. {
  652. boost::unordered_set<T, U> &d = const_cast<boost::unordered_set<T, U> &>(data);
  653. ui32 length = d.size();
  654. *this << length;
  655. for(typename boost::unordered_set<T, U>::iterator i=d.begin();i!=d.end();i++)
  656. *this << *i;
  657. }
  658. template <typename T>
  659. void saveSerializable(const std::list<T> &data)
  660. {
  661. std::list<T> &d = const_cast<std::list<T> &>(data);
  662. ui32 length = d.size();
  663. *this << length;
  664. for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
  665. *this << *i;
  666. }
  667. void saveSerializable(const std::string &data)
  668. {
  669. *this << ui32(data.length());
  670. this->This()->write(data.c_str(),data.size());
  671. }
  672. template <typename T1, typename T2>
  673. void saveSerializable(const std::pair<T1,T2> &data)
  674. {
  675. *this << data.first << data.second;
  676. }
  677. template <typename T1, typename T2>
  678. void saveSerializable(const std::map<T1,T2> &data)
  679. {
  680. *this << ui32(data.size());
  681. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  682. *this << i->first << i->second;
  683. }
  684. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  685. void saveSerializable(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  686. {
  687. si32 which = data.which();
  688. *this << which;
  689. VariantVisitorSaver<Serializer> visitor(*this->This());
  690. boost::apply_visitor(visitor, data);
  691. }
  692. template <typename T>
  693. void saveSerializable(const boost::optional<T> &data)
  694. {
  695. if(data)
  696. {
  697. *this << (ui8)1;
  698. *this << *data;
  699. }
  700. else
  701. {
  702. *this << (ui8)0;
  703. }
  704. }
  705. template <typename E>
  706. void saveEnum(const E &data)
  707. {
  708. si32 writ = static_cast<si32>(data);
  709. *this << writ;
  710. }
  711. void saveBoolean(const bool & data)
  712. {
  713. ui8 writ = static_cast<ui8>(data);
  714. *this << writ;
  715. }
  716. void saveBooleanVector(const std::vector<bool> & data)
  717. {
  718. std::vector<ui8> convData;
  719. std::copy(data.begin(), data.end(), std::back_inserter(convData));
  720. saveSerializable(convData);
  721. }
  722. };
  723. class DLL_LINKAGE CLoaderBase : public virtual CSerializer
  724. {};
  725. class CBasicPointerLoader
  726. {
  727. public:
  728. virtual void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
  729. virtual ~CBasicPointerLoader(){}
  730. };
  731. template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
  732. {
  733. public:
  734. void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
  735. {
  736. Serializer &s = static_cast<Serializer&>(ar);
  737. T *&ptr = *static_cast<T**>(data);
  738. //create new object under pointer
  739. typedef typename boost::remove_pointer<T>::type npT;
  740. ptr = new npT;
  741. s.ptrAllocated(ptr, pid);
  742. //T is most derived known type, it's time to call actual serialize
  743. ptr->serialize(s,version);
  744. }
  745. };
  746. /// The class which manages loading of objects.
  747. template <typename Serializer> class DLL_LINKAGE CISer : public CLoaderBase
  748. {
  749. public:
  750. bool saving;
  751. std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
  752. ui32 fileVersion;
  753. bool reverseEndianess; //if source has different endianess than us, we reverse bytes
  754. std::map<ui32, void*> loadedPointers;
  755. bool smartPointerSerialization;
  756. CISer()
  757. {
  758. saving = false;
  759. fileVersion = 0;
  760. smartPointerSerialization = true;
  761. reverseEndianess = false;
  762. }
  763. ~CISer()
  764. {
  765. std::map<ui16,CBasicPointerLoader*>::iterator iter;
  766. for(iter = loaders.begin(); iter != loaders.end(); iter++)
  767. delete iter->second;
  768. }
  769. template<typename T> void registerType(const T * t=NULL)
  770. {
  771. ui16 ID = typeList.registerType(t);
  772. loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
  773. }
  774. Serializer * This()
  775. {
  776. return static_cast<Serializer*>(this);
  777. }
  778. template<class T>
  779. Serializer & operator>>(T &t)
  780. {
  781. this->This()->load(t);
  782. return * this->This();
  783. }
  784. template<class T>
  785. CISer & operator&(T & t)
  786. {
  787. return * this->This() >> t;
  788. }
  789. int write(const void * data, unsigned size);
  790. template <typename T>
  791. void load(T &data)
  792. {
  793. typedef
  794. //if
  795. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  796. mpl::identity<LoadBoolean<Serializer> >,
  797. //else if
  798. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  799. mpl::identity<LoadBooleanVector<Serializer> >,
  800. //else if
  801. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  802. mpl::identity<LoadPrimitive<Serializer,T> >,
  803. //else if
  804. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  805. mpl::identity<LoadEnum<Serializer,T> >,
  806. //else if
  807. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  808. mpl::identity<LoadPointer<Serializer,T> >,
  809. //else if
  810. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  811. mpl::identity<LoadArray<Serializer,T> >,
  812. //else if
  813. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  814. mpl::identity<LoadSerializable<Serializer,T> >,
  815. //else
  816. mpl::identity<LoadWrong<Serializer,T> >
  817. >
  818. >
  819. >
  820. >
  821. >
  822. >
  823. >::type typex;
  824. typex::invoke(* this->This(), data);
  825. }
  826. template <typename T>
  827. void loadPrimitive(T &data)
  828. {
  829. if(0) //for testing #989
  830. {
  831. this->This()->read(&data,sizeof(data));
  832. }
  833. else
  834. {
  835. unsigned length = sizeof(data);
  836. char* dataPtr = (char*)&data;
  837. this->This()->read(dataPtr,length);
  838. if(reverseEndianess)
  839. std::reverse(dataPtr, dataPtr + length);
  840. }
  841. }
  842. template <typename T>
  843. void loadSerializableBySerializeCall(T &data)
  844. {
  845. ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
  846. typedef typename boost::remove_const<T>::type nonConstT;
  847. nonConstT &hlp = const_cast<nonConstT&>(data);
  848. hlp.serialize(*this,fileVersion);
  849. //data.serialize(*this,myVersion);
  850. }
  851. template <typename T>
  852. void loadSerializable(T &data)
  853. {
  854. loadSerializableBySerializeCall(data);
  855. }
  856. template <typename T>
  857. void loadArray(T &data)
  858. {
  859. ui32 size = ARRAY_COUNT(data);
  860. for(ui32 i = 0; i < size; i++)
  861. *this >> data[i];
  862. }
  863. template <typename T>
  864. void loadPointer(T &data)
  865. {
  866. ui8 hlp;
  867. *this >> hlp;
  868. if(!hlp)
  869. {
  870. data = NULL;
  871. return;
  872. }
  873. if(smartVectorMembersSerialization)
  874. {
  875. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
  876. typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
  877. typedef typename VectorizedIDType<TObjectType>::type IDType;
  878. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  879. {
  880. IDType id;
  881. *this >> id;
  882. if(id != IDType(-1))
  883. {
  884. data = static_cast<T>(getVectorItemFromId<VType, IDType>(*info, id));
  885. return;
  886. }
  887. }
  888. }
  889. if(sendStackInstanceByIds)
  890. {
  891. bool gotLoaded = LoadIfStackInstance<Serializer,T>::invoke(*This(), data);
  892. if(gotLoaded)
  893. return;
  894. }
  895. ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
  896. if(smartPointerSerialization)
  897. {
  898. *this >> pid; //get the id
  899. std::map<ui32, void*>::iterator i = loadedPointers.find(pid); //lookup
  900. if(i != loadedPointers.end())
  901. {
  902. //we already got this pointer
  903. data = static_cast<T>(i->second);
  904. return;
  905. }
  906. }
  907. //get type id
  908. ui16 tid;
  909. *this >> tid;
  910. This()->loadPointerHlp(tid, data, pid);
  911. }
  912. //that part of ptr deserialization was extracted to allow customization of its behavior in derived classes
  913. template <typename T>
  914. void loadPointerHlp( ui16 tid, T & data, ui32 pid )
  915. {
  916. if(!tid)
  917. {
  918. typedef typename boost::remove_pointer<T>::type npT;
  919. typedef typename boost::remove_const<npT>::type ncpT;
  920. data = new ncpT;
  921. ptrAllocated(data, pid);
  922. *this >> *data;
  923. }
  924. else
  925. {
  926. loaders[tid]->loadPtr(*this,&data, pid);
  927. }
  928. }
  929. template <typename T>
  930. void ptrAllocated(const T *ptr, ui32 pid)
  931. {
  932. if(smartPointerSerialization && pid != 0xffffffff)
  933. loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
  934. }
  935. #define READ_CHECK_U32(x) \
  936. ui32 length; \
  937. *this >> length; \
  938. if(length > 500000) \
  939. { \
  940. tlog2 << "Warning: very big length: " << length << "\n" ;\
  941. reportState(tlog2); \
  942. };
  943. template <typename T>
  944. void loadSerializable(shared_ptr<T> &data)
  945. {
  946. T *internalPtr;
  947. *this >> internalPtr;
  948. data.reset(internalPtr);
  949. }
  950. template <typename T>
  951. void loadSerializable(unique_ptr<T> &data)
  952. {
  953. T *internalPtr;
  954. *this >> internalPtr;
  955. data.reset(internalPtr);
  956. }
  957. template <typename T>
  958. void loadSerializable(std::vector<T> &data)
  959. {
  960. READ_CHECK_U32(length);
  961. data.resize(length);
  962. for(ui32 i=0;i<length;i++)
  963. *this >> data[i];
  964. }
  965. template <typename T>
  966. void loadSerializable(std::set<T> &data)
  967. {
  968. READ_CHECK_U32(length);
  969. T ins;
  970. for(ui32 i=0;i<length;i++)
  971. {
  972. *this >> ins;
  973. data.insert(ins);
  974. }
  975. }
  976. template <typename T, typename U>
  977. void loadSerializable(boost::unordered_set<T, U> &data)
  978. {
  979. READ_CHECK_U32(length);
  980. T ins;
  981. for(ui32 i=0;i<length;i++)
  982. {
  983. *this >> ins;
  984. data.insert(ins);
  985. }
  986. }
  987. template <typename T>
  988. void loadSerializable(std::list<T> &data)
  989. {
  990. READ_CHECK_U32(length);
  991. T ins;
  992. for(ui32 i=0;i<length;i++)
  993. {
  994. *this >> ins;
  995. data.push_back(ins);
  996. }
  997. }
  998. template <typename T1, typename T2>
  999. void loadSerializable(std::pair<T1,T2> &data)
  1000. {
  1001. *this >> data.first >> data.second;
  1002. }
  1003. template <typename T1, typename T2>
  1004. void loadSerializable(std::map<T1,T2> &data)
  1005. {
  1006. READ_CHECK_U32(length);
  1007. T1 t;
  1008. for(ui32 i=0;i<length;i++)
  1009. {
  1010. *this >> t;
  1011. *this >> data[t];
  1012. }
  1013. }
  1014. void loadSerializable(std::string &data)
  1015. {
  1016. READ_CHECK_U32(length);
  1017. data.resize(length);
  1018. this->This()->read((void*)data.c_str(),length);
  1019. }
  1020. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1021. void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  1022. {
  1023. si32 which;
  1024. *this >> which;
  1025. if(which == 0)
  1026. {
  1027. T0 obj;
  1028. *this >> obj;
  1029. data = obj;
  1030. }
  1031. else if(which == 1)
  1032. {
  1033. T1 obj;
  1034. *this >> obj;
  1035. data = obj;
  1036. }
  1037. else
  1038. assert(0);
  1039. //TODO write more if needed, general solution would be much longer
  1040. }
  1041. template <typename T>
  1042. void loadSerializable(boost::optional<T> & data)
  1043. {
  1044. ui8 present;
  1045. *this >> present;
  1046. if(present)
  1047. {
  1048. T t;
  1049. *this >> t;
  1050. data = t;
  1051. }
  1052. else
  1053. {
  1054. data = boost::optional<T>();
  1055. }
  1056. }
  1057. void loadSerializable(CStackInstance *&s)
  1058. {
  1059. if(sendStackInstanceByIds)
  1060. {
  1061. CArmedInstance *armed;
  1062. SlotID slot;
  1063. *this >> armed >> slot;
  1064. assert(armed->hasStackAtSlot(slot));
  1065. s = armed->stacks[slot];
  1066. }
  1067. else
  1068. loadSerializableBySerializeCall(s);
  1069. }
  1070. template <typename E>
  1071. void loadEnum(E &data)
  1072. {
  1073. si32 read;
  1074. *this >> read;
  1075. data = static_cast<E>(read);
  1076. }
  1077. void loadBoolean(bool &data)
  1078. {
  1079. ui8 read;
  1080. *this >> read;
  1081. data = static_cast<bool>(read);
  1082. }
  1083. void loadBooleanVector(std::vector<bool> & data)
  1084. {
  1085. std::vector<ui8> convData;
  1086. loadSerializable(convData);
  1087. std::copy(convData.begin(), convData.end(), std::back_inserter(data));
  1088. }
  1089. };
  1090. class DLL_LINKAGE CSaveFile
  1091. : public COSer<CSaveFile>
  1092. {
  1093. void dummyMagicFunction()
  1094. {
  1095. *this << std::string("This function makes stuff working.");
  1096. }
  1097. public:
  1098. std::string fName;
  1099. unique_ptr<std::ofstream> sfile;
  1100. CSaveFile(const std::string &fname); //throws!
  1101. ~CSaveFile();
  1102. int write(const void * data, unsigned size);
  1103. void openNextFile(const std::string &fname); //throws!
  1104. void clear();
  1105. void reportState(CLogger &out);
  1106. void putMagicBytes(const std::string &text);
  1107. };
  1108. class DLL_LINKAGE CLoadFile
  1109. : public CISer<CLoadFile>
  1110. {
  1111. void dummyMagicFunction()
  1112. {
  1113. std::string dummy = "This function makes stuff working.";
  1114. *this >> dummy;
  1115. }
  1116. public:
  1117. std::string fName;
  1118. unique_ptr<std::ifstream> sfile;
  1119. CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
  1120. ~CLoadFile();
  1121. int read(const void * data, unsigned size); //throws!
  1122. void openNextFile(const std::string &fname, int minimalVersion); //throws!
  1123. void clear();
  1124. void reportState(CLogger &out);
  1125. void checkMagicBytes(const std::string &text);
  1126. };
  1127. class DLL_LINKAGE CLoadIntegrityValidator : public CISer<CLoadIntegrityValidator>
  1128. {
  1129. public:
  1130. unique_ptr<CLoadFile> primaryFile, controlFile;
  1131. bool foundDesync;
  1132. CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
  1133. int read(const void * data, unsigned size); //throws!
  1134. void checkMagicBytes(const std::string &text);
  1135. unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
  1136. };
  1137. typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
  1138. typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > TAcceptor;
  1139. class DLL_LINKAGE CConnection
  1140. :public CISer<CConnection>, public COSer<CConnection>
  1141. {
  1142. //CGameState *gs;
  1143. CConnection(void);
  1144. void init();
  1145. void reportState(CLogger &out);
  1146. public:
  1147. boost::mutex *rmx, *wmx; // read/write mutexes
  1148. TSocket * socket;
  1149. bool logging;
  1150. bool connected;
  1151. bool myEndianess, contactEndianess; //true if little endian, if endianess is different we'll have to revert received multi-byte vars
  1152. boost::asio::io_service *io_service;
  1153. std::string name; //who uses this connection
  1154. int connectionID;
  1155. boost::thread *handler;
  1156. bool receivedStop, sendStop;
  1157. CConnection(std::string host, std::string port, std::string Name);
  1158. CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
  1159. CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
  1160. int write(const void * data, unsigned size);
  1161. int read(void * data, unsigned size);
  1162. void close();
  1163. bool isOpen() const;
  1164. template<class T>
  1165. CConnection &operator&(const T&);
  1166. virtual ~CConnection(void);
  1167. CPack *retreivePack(); //gets from server next pack (allocates it with new)
  1168. void sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID);
  1169. void disableStackSendingByID();
  1170. void enableStackSendingByID();
  1171. void disableSmartPointerSerialization();
  1172. void enableSmartPointerSerializatoin();
  1173. void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
  1174. void enterPregameConnectionMode();
  1175. };
  1176. DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
  1177. template<typename T>
  1178. class CApplier
  1179. {
  1180. public:
  1181. std::map<ui16,T*> apps;
  1182. ~CApplier()
  1183. {
  1184. typename std::map<ui16, T*>::iterator iter;
  1185. for(iter = apps.begin(); iter != apps.end(); iter++)
  1186. delete iter->second;
  1187. }
  1188. template<typename U> void registerType(const U * t=NULL)
  1189. {
  1190. ui16 ID = typeList.registerType(t);
  1191. apps[ID] = T::getApplier(t);
  1192. }
  1193. };