Connection.h 32 KB

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