2016-09-10 03:28:11 +03:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*/
|
2017-07-13 11:26:03 +03:00
|
|
|
#include "StdInc.h"
|
|
|
|
#include "Connection.h"
|
|
|
|
|
|
|
|
#include "../registerTypes/RegisterTypes.h"
|
|
|
|
#include "../mapping/CMap.h"
|
|
|
|
#include "../CGameState.h"
|
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
|
2022-07-26 16:07:42 +03:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
|
|
|
|
#if defined(__hppa__) || \
|
|
|
|
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
|
|
|
(defined(__MIPS__) && defined(__MISPEB__)) || \
|
|
|
|
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
|
|
|
|
defined(__sparc__)
|
|
|
|
#define BIG_ENDIAN
|
|
|
|
#else
|
|
|
|
#define LIL_ENDIAN
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void CConnection::init()
|
|
|
|
{
|
2016-11-13 12:44:46 +03:00
|
|
|
enableSmartPointerSerialization();
|
2016-09-10 03:28:11 +03:00
|
|
|
disableStackSendingByID();
|
|
|
|
registerTypes(iser);
|
|
|
|
registerTypes(oser);
|
|
|
|
#ifdef LIL_ENDIAN
|
|
|
|
myEndianess = true;
|
|
|
|
#else
|
|
|
|
myEndianess = false;
|
|
|
|
#endif
|
|
|
|
std::string pom;
|
2023-01-10 04:47:00 +04:00
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
//we got connection
|
2018-01-05 20:21:07 +03:00
|
|
|
oser & std::string("Aiya!\n") & name & uuid & myEndianess; //identify ourselves
|
2023-01-08 05:42:12 +04:00
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
iser & pom & pom & contactUuid & contactEndianess;
|
|
|
|
logNetwork->info("Established connection with %s. UUID: %s", pom, contactUuid);
|
2016-09-10 03:28:11 +03:00
|
|
|
|
2023-01-10 04:47:00 +04:00
|
|
|
connected = true;
|
2016-10-29 19:52:19 +03:00
|
|
|
iser.fileVersion = SERIALIZATION_VERSION;
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
2023-01-03 03:52:44 +04:00
|
|
|
CConnection::CConnection(ENetHost * _client, ENetPeer * _peer, std::string Name, std::string UUID)
|
2023-01-10 04:47:00 +04:00
|
|
|
: client(_client), peer(_peer), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false), channel(1)
|
2023-01-03 03:52:44 +04:00
|
|
|
{
|
2023-01-08 05:42:12 +04:00
|
|
|
//init();
|
2023-01-03 03:52:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::string Name, std::string UUID)
|
2023-01-10 04:47:00 +04:00
|
|
|
: client(_client), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false), channel(0)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2023-01-03 03:52:44 +04:00
|
|
|
ENetAddress address;
|
|
|
|
enet_address_set_host(&address, host.c_str());
|
|
|
|
address.port = port;
|
|
|
|
|
|
|
|
peer = enet_host_connect(client, &address, 2, 0);
|
|
|
|
if(peer == NULL)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2023-01-03 03:52:44 +04:00
|
|
|
throw std::runtime_error("Can't establish connection :(");
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
2023-01-08 05:42:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::dispatch(ENetPacket * packet)
|
|
|
|
{
|
2023-01-10 04:47:00 +04:00
|
|
|
boost::unique_lock<boost::mutex> lock(mutexRead);
|
2023-01-08 05:42:12 +04:00
|
|
|
packets.push_back(packet);
|
|
|
|
}
|
|
|
|
|
|
|
|
const ENetPeer * CConnection::getPeer() const
|
|
|
|
{
|
|
|
|
return peer;
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
2023-01-03 03:52:44 +04:00
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
int CConnection::write(const void * data, unsigned size)
|
|
|
|
{
|
2023-01-10 04:47:00 +04:00
|
|
|
if(size == 0)
|
|
|
|
return 0;
|
|
|
|
boost::unique_lock<boost::mutex> lock(mutexWrite);
|
2023-01-03 03:52:44 +04:00
|
|
|
ENetPacket * packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
2023-01-10 04:47:00 +04:00
|
|
|
enet_peer_send(peer, channel, packet);
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
2022-12-26 20:13:07 +02:00
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
int CConnection::read(void * data, unsigned size)
|
|
|
|
{
|
2023-01-10 04:47:00 +04:00
|
|
|
const int timout = 1000;
|
|
|
|
if(size == 0)
|
|
|
|
return 0;
|
|
|
|
for(int i = 0; packets.empty() && (i < timout || connected); ++i)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2023-01-10 04:47:00 +04:00
|
|
|
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
2023-01-10 04:47:00 +04:00
|
|
|
boost::unique_lock<boost::mutex> lock(mutexRead);
|
|
|
|
auto * packet = packets.front();
|
|
|
|
packets.pop_front();
|
2023-01-03 03:52:44 +04:00
|
|
|
|
2023-01-10 04:47:00 +04:00
|
|
|
if(packet->dataLength > 0)
|
|
|
|
memcpy(data, packet->data, packet->dataLength);
|
|
|
|
int ret = packet->dataLength;
|
|
|
|
assert(ret == size);
|
|
|
|
enet_packet_destroy(packet);
|
2023-01-03 03:52:44 +04:00
|
|
|
|
|
|
|
return ret;
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
2023-01-03 03:52:44 +04:00
|
|
|
|
2018-01-13 11:43:26 +03:00
|
|
|
CConnection::~CConnection()
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
|
|
|
if(handler)
|
|
|
|
handler->join();
|
2023-01-08 05:42:12 +04:00
|
|
|
|
|
|
|
for(auto * packet : packets)
|
|
|
|
enet_packet_destroy(packet);
|
2016-09-10 03:28:11 +03:00
|
|
|
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
CConnection & CConnection::operator&(const T &t) {
|
|
|
|
// throw std::exception();
|
|
|
|
//XXX this is temporaly ? solution to fix gcc (4.3.3, other?) compilation
|
|
|
|
// problem for more details contact t0@czlug.icis.pcz.pl or impono@gmail.com
|
|
|
|
// do not remove this exception it shoudnt be called
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::close()
|
|
|
|
{
|
2023-01-10 04:47:00 +04:00
|
|
|
boost::unique_lock<boost::mutex> lock(mutexWrite);
|
2023-01-03 03:52:44 +04:00
|
|
|
enet_peer_disconnect(peer, 0);
|
|
|
|
enet_peer_reset(peer);
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CConnection::isOpen() const
|
|
|
|
{
|
2023-01-03 03:52:44 +04:00
|
|
|
return connected;
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
2017-08-11 20:03:05 +03:00
|
|
|
void CConnection::reportState(vstd::CLoggerBase * out)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2017-08-10 19:39:27 +03:00
|
|
|
out->debug("CConnection");
|
2023-01-03 03:52:44 +04:00
|
|
|
/*if(socket && socket->is_open())
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2017-08-10 19:39:27 +03:00
|
|
|
out->debug("\tWe have an open and valid socket");
|
2017-08-11 20:03:05 +03:00
|
|
|
out->debug("\t %d bytes awaiting", socket->available());
|
2023-01-03 03:52:44 +04:00
|
|
|
}*/
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 21:52:23 +03:00
|
|
|
CPack * CConnection::retrievePack()
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2022-12-26 21:28:36 +02:00
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
CPack * pack = nullptr;
|
|
|
|
iser & pack;
|
2018-02-26 00:16:15 +08:00
|
|
|
logNetwork->trace("Received CPack of type %s", (pack ? typeid(*pack).name() : "nullptr"));
|
2018-01-05 20:21:07 +03:00
|
|
|
if(pack == nullptr)
|
|
|
|
{
|
|
|
|
logNetwork->error("Received a nullptr CPack! You should check whether client and server ABI matches.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pack->c = this->shared_from_this();
|
|
|
|
}
|
2022-12-26 21:28:36 +02:00
|
|
|
|
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
return pack;
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
void CConnection::sendPack(const CPack * pack)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2018-01-05 20:21:07 +03:00
|
|
|
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
2022-12-26 20:13:07 +02:00
|
|
|
|
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
oser & pack;
|
2022-12-26 20:13:07 +02:00
|
|
|
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::disableStackSendingByID()
|
|
|
|
{
|
|
|
|
CSerializer::sendStackInstanceByIds = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::enableStackSendingByID()
|
|
|
|
{
|
|
|
|
CSerializer::sendStackInstanceByIds = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::disableSmartPointerSerialization()
|
|
|
|
{
|
|
|
|
iser.smartPointerSerialization = oser.smartPointerSerialization = false;
|
|
|
|
}
|
|
|
|
|
2016-11-13 12:44:46 +03:00
|
|
|
void CConnection::enableSmartPointerSerialization()
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
|
|
|
iser.smartPointerSerialization = oser.smartPointerSerialization = true;
|
|
|
|
}
|
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
void CConnection::enterLobbyConnectionMode()
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
|
|
|
iser.loadedPointers.clear();
|
|
|
|
oser.savedPointers.clear();
|
|
|
|
disableSmartVectorMemberSerialization();
|
2018-01-05 20:21:07 +03:00
|
|
|
disableSmartPointerSerialization();
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
2018-01-05 20:21:07 +03:00
|
|
|
void CConnection::enterGameplayConnectionMode(CGameState * gs)
|
2016-09-10 03:28:11 +03:00
|
|
|
{
|
2018-01-05 20:21:07 +03:00
|
|
|
enableStackSendingByID();
|
2016-09-10 03:28:11 +03:00
|
|
|
disableSmartPointerSerialization();
|
2018-01-05 20:21:07 +03:00
|
|
|
addStdVecItems(gs);
|
2016-09-10 03:28:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::disableSmartVectorMemberSerialization()
|
|
|
|
{
|
|
|
|
CSerializer::smartVectorMembersSerialization = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConnection::enableSmartVectorMemberSerializatoin()
|
|
|
|
{
|
|
|
|
CSerializer::smartVectorMembersSerialization = true;
|
|
|
|
}
|
|
|
|
|
2017-08-11 16:50:00 +03:00
|
|
|
std::string CConnection::toString() const
|
|
|
|
{
|
2018-01-05 20:21:07 +03:00
|
|
|
boost::format fmt("Connection with %s (ID: %d UUID: %s)");
|
|
|
|
fmt % name % connectionID % uuid;
|
|
|
|
return fmt.str();
|
2017-08-11 16:50:00 +03:00
|
|
|
}
|
2022-07-26 16:07:42 +03:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|