Connection.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Connection.cpp, 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. #include "StdInc.h"
  11. #include "Connection.h"
  12. #include "BinaryDeserializer.h"
  13. #include "BinarySerializer.h"
  14. #include "../networkPacks/NetPacksBase.h"
  15. #include "../network/NetworkConnection.h"
  16. VCMI_LIB_NAMESPACE_BEGIN
  17. class DLL_LINKAGE ConnectionPackWriter final : public IBinaryWriter
  18. {
  19. public:
  20. std::vector<uint8_t> buffer;
  21. int write(const void * data, unsigned size) final;
  22. };
  23. class DLL_LINKAGE ConnectionPackReader final : public IBinaryReader
  24. {
  25. public:
  26. const std::vector<uint8_t> * buffer;
  27. size_t position;
  28. int read(void * data, unsigned size) final;
  29. };
  30. int ConnectionPackWriter::write(const void * data, unsigned size)
  31. {
  32. const uint8_t * begin_ptr = static_cast<const uint8_t *>(data);
  33. const uint8_t * end_ptr = begin_ptr + size;
  34. buffer.insert(buffer.end(), begin_ptr, end_ptr);
  35. return size;
  36. }
  37. int ConnectionPackReader::read(void * data, unsigned size)
  38. {
  39. if (position + size > buffer->size())
  40. throw std::runtime_error("End of file reached when reading received network pack!");
  41. uint8_t * begin_ptr = static_cast<uint8_t *>(data);
  42. std::copy_n(buffer->begin() + position, size, begin_ptr);
  43. position += size;
  44. return size;
  45. }
  46. CConnection::CConnection(std::weak_ptr<NetworkConnection> networkConnection)
  47. : networkConnection(networkConnection)
  48. , packReader(std::make_unique<ConnectionPackReader>())
  49. , packWriter(std::make_unique<ConnectionPackWriter>())
  50. , deserializer(std::make_unique<BinaryDeserializer>(packReader.get()))
  51. , serializer(std::make_unique<BinarySerializer>(packWriter.get()))
  52. , connectionID(-1)
  53. {
  54. assert(networkConnection.lock() != nullptr);
  55. enableSmartPointerSerialization();
  56. disableStackSendingByID();
  57. deserializer->fileVersion = SERIALIZATION_VERSION;
  58. }
  59. CConnection::~CConnection() = default;
  60. void CConnection::sendPack(const CPack * pack)
  61. {
  62. auto connectionPtr = networkConnection.lock();
  63. if (!connectionPtr)
  64. throw std::runtime_error("Attempt to send packet on a closed connection!");
  65. *serializer & pack;
  66. logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
  67. connectionPtr->sendPacket(packWriter->buffer);
  68. packWriter->buffer.clear();
  69. }
  70. CPack * CConnection::retrievePack(const std::vector<uint8_t> & data)
  71. {
  72. CPack * result;
  73. packReader->buffer = &data;
  74. packReader->position = 0;
  75. *deserializer & result;
  76. logNetwork->trace("Received CPack of type %s", (result ? typeid(*result).name() : "nullptr"));
  77. return result;
  78. }
  79. bool CConnection::isMyConnection(const std::shared_ptr<NetworkConnection> & otherConnection) const
  80. {
  81. return otherConnection != nullptr && networkConnection.lock() == otherConnection;
  82. }
  83. void CConnection::disableStackSendingByID()
  84. {
  85. packReader->sendStackInstanceByIds = false;
  86. packWriter->sendStackInstanceByIds = false;
  87. }
  88. void CConnection::enableStackSendingByID()
  89. {
  90. packReader->sendStackInstanceByIds = true;
  91. packWriter->sendStackInstanceByIds = true;
  92. }
  93. void CConnection::enterLobbyConnectionMode()
  94. {
  95. deserializer->loadedPointers.clear();
  96. serializer->savedPointers.clear();
  97. disableSmartVectorMemberSerialization();
  98. disableSmartPointerSerialization();
  99. disableStackSendingByID();
  100. }
  101. void CConnection::enterGameplayConnectionMode(CGameState * gs)
  102. {
  103. enableStackSendingByID();
  104. disableSmartPointerSerialization();
  105. packReader->addStdVecItems(gs);
  106. packWriter->addStdVecItems(gs);
  107. }
  108. void CConnection::disableSmartPointerSerialization()
  109. {
  110. deserializer->smartPointerSerialization = false;
  111. serializer->smartPointerSerialization = false;
  112. }
  113. void CConnection::enableSmartPointerSerialization()
  114. {
  115. deserializer->smartPointerSerialization = true;
  116. serializer->smartPointerSerialization = true;
  117. }
  118. void CConnection::disableSmartVectorMemberSerialization()
  119. {
  120. packReader->smartVectorMembersSerialization = false;
  121. packWriter->smartVectorMembersSerialization = false;
  122. }
  123. void CConnection::enableSmartVectorMemberSerializatoin()
  124. {
  125. packReader->smartVectorMembersSerialization = true;
  126. packWriter->smartVectorMembersSerialization = true;
  127. }
  128. VCMI_LIB_NAMESPACE_END