Connection.cpp 4.3 KB

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