Connection.h 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337
  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. T ins;
  981. for(ui32 i=0;i<length;i++)
  982. {
  983. *this >> ins;
  984. data.insert(ins);
  985. }
  986. }
  987. template <typename T, typename U>
  988. void loadSerializable(boost::unordered_set<T, U> &data)
  989. {
  990. READ_CHECK_U32(length);
  991. T ins;
  992. for(ui32 i=0;i<length;i++)
  993. {
  994. *this >> ins;
  995. data.insert(ins);
  996. }
  997. }
  998. template <typename T>
  999. void loadSerializable(std::list<T> &data)
  1000. {
  1001. READ_CHECK_U32(length);
  1002. T ins;
  1003. for(ui32 i=0;i<length;i++)
  1004. {
  1005. *this >> ins;
  1006. data.push_back(ins);
  1007. }
  1008. }
  1009. template <typename T1, typename T2>
  1010. void loadSerializable(std::pair<T1,T2> &data)
  1011. {
  1012. *this >> data.first >> data.second;
  1013. }
  1014. template <typename T1, typename T2>
  1015. void loadSerializable(std::map<T1,T2> &data)
  1016. {
  1017. READ_CHECK_U32(length);
  1018. T1 t;
  1019. for(ui32 i=0;i<length;i++)
  1020. {
  1021. *this >> t;
  1022. *this >> data[t];
  1023. }
  1024. }
  1025. void loadSerializable(std::string &data)
  1026. {
  1027. READ_CHECK_U32(length);
  1028. data.resize(length);
  1029. this->This()->read((void*)data.c_str(),length);
  1030. }
  1031. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1032. void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  1033. {
  1034. si32 which;
  1035. *this >> which;
  1036. if(which == 0)
  1037. {
  1038. T0 obj;
  1039. *this >> obj;
  1040. data = obj;
  1041. }
  1042. else if(which == 1)
  1043. {
  1044. T1 obj;
  1045. *this >> obj;
  1046. data = obj;
  1047. }
  1048. else
  1049. assert(0);
  1050. //TODO write more if needed, general solution would be much longer
  1051. }
  1052. template <typename T>
  1053. void loadSerializable(boost::optional<T> & data)
  1054. {
  1055. ui8 present;
  1056. *this >> present;
  1057. if(present)
  1058. {
  1059. T t;
  1060. *this >> t;
  1061. data = t;
  1062. }
  1063. else
  1064. {
  1065. data = boost::optional<T>();
  1066. }
  1067. }
  1068. // void loadSerializable(CStackInstance *&s)
  1069. // {
  1070. // if(sendStackInstanceByIds)
  1071. // {
  1072. // CArmedInstance *armed;
  1073. // SlotID slot;
  1074. // *this >> armed >> slot;
  1075. // assert(armed->hasStackAtSlot(slot));
  1076. // s = armed->stacks[slot];
  1077. // }
  1078. // else
  1079. // loadSerializableBySerializeCall(s);
  1080. // }
  1081. template <typename E>
  1082. void loadEnum(E &data)
  1083. {
  1084. si32 read;
  1085. *this >> read;
  1086. data = static_cast<E>(read);
  1087. }
  1088. void loadBoolean(bool &data)
  1089. {
  1090. ui8 read;
  1091. *this >> read;
  1092. data = static_cast<bool>(read);
  1093. }
  1094. void loadBooleanVector(std::vector<bool> & data)
  1095. {
  1096. std::vector<ui8> convData;
  1097. loadSerializable(convData);
  1098. std::copy(convData.begin(), convData.end(), std::back_inserter(data));
  1099. }
  1100. };
  1101. class DLL_LINKAGE CSaveFile
  1102. : public COSer<CSaveFile>
  1103. {
  1104. void dummyMagicFunction()
  1105. {
  1106. *this << std::string("This function makes stuff working.");
  1107. }
  1108. public:
  1109. std::string fName;
  1110. unique_ptr<std::ofstream> sfile;
  1111. CSaveFile(const std::string &fname); //throws!
  1112. ~CSaveFile();
  1113. int write(const void * data, unsigned size);
  1114. void openNextFile(const std::string &fname); //throws!
  1115. void clear();
  1116. void reportState(CLogger * out);
  1117. void putMagicBytes(const std::string &text);
  1118. };
  1119. class DLL_LINKAGE CLoadFile
  1120. : public CISer<CLoadFile>
  1121. {
  1122. void dummyMagicFunction()
  1123. {
  1124. std::string dummy = "This function makes stuff working.";
  1125. *this >> dummy;
  1126. }
  1127. public:
  1128. std::string fName;
  1129. unique_ptr<std::ifstream> sfile;
  1130. CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
  1131. ~CLoadFile();
  1132. int read(const void * data, unsigned size); //throws!
  1133. void openNextFile(const std::string &fname, int minimalVersion); //throws!
  1134. void clear();
  1135. void reportState(CLogger * out);
  1136. void checkMagicBytes(const std::string &text);
  1137. };
  1138. class DLL_LINKAGE CLoadIntegrityValidator : public CISer<CLoadIntegrityValidator>
  1139. {
  1140. public:
  1141. unique_ptr<CLoadFile> primaryFile, controlFile;
  1142. bool foundDesync;
  1143. CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
  1144. int read(const void * data, unsigned size); //throws!
  1145. void checkMagicBytes(const std::string &text);
  1146. unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
  1147. };
  1148. typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
  1149. typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > TAcceptor;
  1150. class DLL_LINKAGE CConnection
  1151. :public CISer<CConnection>, public COSer<CConnection>
  1152. {
  1153. //CGameState *gs;
  1154. CConnection(void);
  1155. void init();
  1156. void reportState(CLogger * out);
  1157. public:
  1158. boost::mutex *rmx, *wmx; // read/write mutexes
  1159. TSocket * socket;
  1160. bool logging;
  1161. bool connected;
  1162. bool myEndianess, contactEndianess; //true if little endian, if endianess is different we'll have to revert received multi-byte vars
  1163. boost::asio::io_service *io_service;
  1164. std::string name; //who uses this connection
  1165. int connectionID;
  1166. boost::thread *handler;
  1167. bool receivedStop, sendStop;
  1168. CConnection(std::string host, std::string port, std::string Name);
  1169. CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
  1170. CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
  1171. int write(const void * data, unsigned size);
  1172. int read(void * data, unsigned size);
  1173. void close();
  1174. bool isOpen() const;
  1175. template<class T>
  1176. CConnection &operator&(const T&);
  1177. virtual ~CConnection(void);
  1178. CPack *retreivePack(); //gets from server next pack (allocates it with new)
  1179. void sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID);
  1180. void disableStackSendingByID();
  1181. void enableStackSendingByID();
  1182. void disableSmartPointerSerialization();
  1183. void enableSmartPointerSerializatoin();
  1184. void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
  1185. void enterPregameConnectionMode();
  1186. };
  1187. DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
  1188. template<typename T>
  1189. class CApplier
  1190. {
  1191. public:
  1192. std::map<ui16,T*> apps;
  1193. ~CApplier()
  1194. {
  1195. typename std::map<ui16, T*>::iterator iter;
  1196. for(iter = apps.begin(); iter != apps.end(); iter++)
  1197. delete iter->second;
  1198. }
  1199. template<typename U> void registerType(const U * t=NULL)
  1200. {
  1201. ui16 ID = typeList.registerType(t);
  1202. apps[ID] = T::getApplier(t);
  1203. }
  1204. };