Line data Source code
1 : #include <shared.hpp> 2 : #include <iostream> 3 : #include <sstream> 4 : 5 : #include <boost/asio.hpp> 6 : #include <boost/asio/ip/tcp.hpp> 7 : #include <boost/archive/binary_oarchive.hpp> 8 : #include <boost/archive/binary_iarchive.hpp> 9 : #include "Serialization.cpp" 10 : 11 : using namespace shared; 12 : 13 2 : void Binary::send(std::shared_ptr<shared::Player> player, std::string serializedData, bool answerRequired) 14 : { 15 2 : std::string header; 16 2 : if (answerRequired) 17 : { 18 2 : header = "binary " + std::to_string(serializedData.size()) + "\n"; 19 : } 20 : else 21 : { 22 0 : header = "rulesturn " + std::to_string(serializedData.size()) + "\n"; 23 : } 24 2 : std::lock_guard<std::mutex> lock(player->socketWriteMutex); 25 2 : boost::asio::write(player->getSocket(), boost::asio::buffer(header)); 26 2 : boost::asio::write(player->getSocket(), boost::asio::buffer(serializedData)); 27 2 : } 28 : 29 2 : std::string Binary::receive(std::shared_ptr<shared::Player> player, std::istream &alreadyReceived, size_t totalSize) 30 : { 31 2 : std::stringstream buffer; 32 2 : buffer << alreadyReceived.rdbuf(); 33 2 : std::string fullMessage = buffer.str(); 34 : 35 2 : boost::system::error_code error; 36 2 : boost::asio::streambuf receiveBuffer; 37 : 38 2 : if (fullMessage.size() > totalSize) 39 : { 40 0 : for (size_t i = fullMessage.size(); i > totalSize; i--) 41 : { 42 0 : alreadyReceived.unget(); 43 : } 44 : 45 0 : return fullMessage.substr(0, totalSize); 46 : } 47 2 : else if (fullMessage.size() == totalSize) 48 : { 49 0 : return fullMessage; 50 : } 51 2 : size_t size = totalSize - fullMessage.size(); 52 : 53 : try 54 : { 55 2 : std::lock_guard<std::mutex> lock(player->socketReadMutex); 56 2 : boost::asio::read(player->getSocket(), receiveBuffer, boost::asio::transfer_exactly(size), error); 57 2 : } 58 0 : catch (const boost::system::system_error &e) 59 : { 60 0 : std::cerr << "Error: " << e.what() << std::endl; 61 0 : } 62 : 63 2 : if (error == boost::asio::error::operation_aborted || error == boost::asio::error::eof) 64 : { 65 0 : player->disconnectPlayer(); 66 : } 67 2 : else if (error) 68 : { 69 0 : std::cerr << "Error: " << error.message() << std::endl; 70 0 : player->disconnectPlayer(); 71 : } 72 : 73 : std::string messageReceived( 74 2 : boost::asio::buffers_begin(receiveBuffer.data()), 75 4 : boost::asio::buffers_end(receiveBuffer.data())); 76 : 77 2 : if (fullMessage.size() == 0) 78 : { 79 1 : return messageReceived; 80 : } 81 : else 82 : { 83 1 : fullMessage += messageReceived; 84 1 : return fullMessage; 85 : } 86 2 : } 87 : 88 : template <typename T> 89 10 : void Binary::castToObject(std::string receivedData, T &data) 90 : { 91 10 : std::stringstream receivedStream(receivedData); 92 10 : boost::archive::binary_iarchive ia(receivedStream); 93 10 : ia >> data; 94 10 : } 95 : 96 : template <typename T> 97 10 : void Binary::castToBinary(T &data, std::string &serializedData) 98 : { 99 10 : std::stringstream stream; 100 10 : boost::archive::binary_oarchive oa(stream); 101 10 : oa << data; 102 10 : serializedData = stream.str(); 103 10 : } 104 : 105 : // We need to instantiate the templates for the types we use in other library than shared 106 : template void Binary::castToBinary<Map>(Map &data, std::string &serializedData); 107 : template void Binary::castToObject<Map>(std::string receivedData, Map &data); 108 : 109 : template void Binary::castToBinary<RuleArgsStruct>(RuleArgsStruct &data, std::string &serializedData); 110 : template void Binary::castToObject<RuleArgsStruct>(std::string receivedData, RuleArgsStruct &data); 111 : 112 : template void Binary::castToBinary<Barbarian>(Barbarian &data, std::string &serializedData); 113 : template void Binary::castToObject<Barbarian>(std::string receivedData, Barbarian &data); 114 : 115 : template void Binary::castToBinary<BarbarianVillage>(BarbarianVillage &data, std::string &serializedData); 116 : template void Binary::castToObject<BarbarianVillage>(std::string receivedData, BarbarianVillage &data); 117 : 118 : template void Binary::castToBinary<City>(City &data, std::string &serializedData); 119 : template void Binary::castToObject<City>(std::string receivedData, City &data); 120 : 121 : template void Binary::castToBinary<Caravan>(Caravan &data, std::string &serializedData); 122 : template void Binary::castToObject<Caravan>(std::string receivedData, Caravan &data); 123 : 124 : template void Binary::castToBinary<ControlPawn>(ControlPawn &data, std::string &serializedData); 125 : template void Binary::castToObject<ControlPawn>(std::string receivedData, ControlPawn &data); 126 : 127 : template void Binary::castToBinary<Hexagon>(Hexagon &data, std::string &serializedData); 128 : template void Binary::castToObject<Hexagon>(std::string receivedData, Hexagon &data);