123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /*
- * Connection.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "Connection.h"
- #include "BinaryDeserializer.h"
- #include "BinarySerializer.h"
- #include "../gameState/CGameState.h"
- #include "../networkPacks/NetPacksBase.h"
- #include "../network/NetworkInterface.h"
- VCMI_LIB_NAMESPACE_BEGIN
- class DLL_LINKAGE ConnectionPackWriter final : public IBinaryWriter
- {
- public:
- std::vector<std::byte> buffer;
- int write(const std::byte * data, unsigned size) final;
- };
- class DLL_LINKAGE ConnectionPackReader final : public IBinaryReader
- {
- public:
- const std::vector<std::byte> * buffer;
- size_t position;
- int read(std::byte * data, unsigned size) final;
- };
- int ConnectionPackWriter::write(const std::byte * data, unsigned size)
- {
- buffer.insert(buffer.end(), data, data + size);
- return size;
- }
- int ConnectionPackReader::read(std::byte * data, unsigned size)
- {
- if (position + size > buffer->size())
- throw std::runtime_error("End of file reached when reading received network pack!");
- std::copy_n(buffer->begin() + position, size, data);
- position += size;
- return size;
- }
- CConnection::CConnection(std::weak_ptr<INetworkConnection> networkConnection)
- : networkConnection(networkConnection)
- , packReader(std::make_unique<ConnectionPackReader>())
- , packWriter(std::make_unique<ConnectionPackWriter>())
- , deserializer(std::make_unique<BinaryDeserializer>(packReader.get()))
- , serializer(std::make_unique<BinarySerializer>(packWriter.get()))
- , connectionID(-1)
- {
- assert(networkConnection.lock() != nullptr);
- enterLobbyConnectionMode();
- deserializer->version = ESerializationVersion::CURRENT;
- }
- CConnection::~CConnection() = default;
- void CConnection::sendPack(const CPack & pack)
- {
- std::scoped_lock lock(writeMutex);
- auto connectionPtr = networkConnection.lock();
- if (!connectionPtr)
- throw std::runtime_error("Attempt to send packet on a closed connection!");
- packWriter->buffer.clear();
- (*serializer) & (&pack);
- logNetwork->trace("Sending a pack of type %s", typeid(pack).name());
- connectionPtr->sendPacket(packWriter->buffer);
- packWriter->buffer.clear();
- serializer->savedPointers.clear();
- }
- std::unique_ptr<CPack> CConnection::retrievePack(const std::vector<std::byte> & data)
- {
- std::unique_ptr<CPack> result;
- packReader->buffer = &data;
- packReader->position = 0;
- *deserializer & result;
- if (result == nullptr)
- throw std::runtime_error("Failed to retrieve pack!");
- if (packReader->position != data.size())
- throw std::runtime_error("Failed to retrieve pack! Not all data has been read!");
- auto packRawPtr = result.get();
- logNetwork->trace("Received CPack of type %s", typeid(*packRawPtr).name());
- deserializer->loadedPointers.clear();
- deserializer->loadedSharedPointers.clear();
- return result;
- }
- bool CConnection::isMyConnection(const std::shared_ptr<INetworkConnection> & otherConnection) const
- {
- return otherConnection != nullptr && networkConnection.lock() == otherConnection;
- }
- std::shared_ptr<INetworkConnection> CConnection::getConnection()
- {
- return networkConnection.lock();
- }
- void CConnection::disableStackSendingByID()
- {
- packReader->sendStackInstanceByIds = false;
- packWriter->sendStackInstanceByIds = false;
- }
- void CConnection::enableStackSendingByID()
- {
- packReader->sendStackInstanceByIds = true;
- packWriter->sendStackInstanceByIds = true;
- }
- void CConnection::enterLobbyConnectionMode()
- {
- deserializer->loadedPointers.clear();
- serializer->savedPointers.clear();
- disableSmartVectorMemberSerialization();
- disableStackSendingByID();
- }
- void CConnection::setCallback(IGameCallback * cb)
- {
- deserializer->cb = cb;
- }
- void CConnection::enterGameplayConnectionMode(CGameState * gs)
- {
- enableStackSendingByID();
- setCallback(gs->callback);
- enableSmartVectorMemberSerializatoin(gs);
- }
- void CConnection::disableSmartVectorMemberSerialization()
- {
- packReader->smartVectorMembersSerialization = false;
- packWriter->smartVectorMembersSerialization = false;
- }
- void CConnection::enableSmartVectorMemberSerializatoin(CGameState * gs)
- {
- packWriter->addStdVecItems(gs);
- packReader->addStdVecItems(gs);
- }
- void CConnection::setSerializationVersion(ESerializationVersion version)
- {
- deserializer->version = version;
- serializer->version = version;
- }
- VCMI_LIB_NAMESPACE_END
|