mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-13 01:20:34 +02:00
Fix connection to game lobby & map load
This commit is contained in:
@ -131,7 +131,11 @@ public:
|
|||||||
static const std::string NAME_AFFIX = "client";
|
static const std::string NAME_AFFIX = "client";
|
||||||
static const std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
static const std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
||||||
|
|
||||||
CServerHandler::~CServerHandler() = default;
|
CServerHandler::~CServerHandler()
|
||||||
|
{
|
||||||
|
networkClient->stop();
|
||||||
|
threadNetwork->join();
|
||||||
|
}
|
||||||
|
|
||||||
CServerHandler::CServerHandler()
|
CServerHandler::CServerHandler()
|
||||||
: state(EClientState::NONE)
|
: state(EClientState::NONE)
|
||||||
@ -148,6 +152,16 @@ CServerHandler::CServerHandler()
|
|||||||
uuid = settings["server"]["uuid"].String();
|
uuid = settings["server"]["uuid"].String();
|
||||||
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
|
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
|
||||||
registerTypesLobbyPacks(*applier);
|
registerTypesLobbyPacks(*applier);
|
||||||
|
|
||||||
|
threadNetwork = std::make_unique<boost::thread>(&CServerHandler::threadRunNetwork, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CServerHandler::threadRunNetwork()
|
||||||
|
{
|
||||||
|
logGlobal->info("Starting network thread");
|
||||||
|
setThreadName("runNetwork");
|
||||||
|
networkClient->run();
|
||||||
|
logGlobal->info("Ending network thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names)
|
void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names)
|
||||||
@ -178,12 +192,13 @@ void CServerHandler::startLocalServerAndConnect(const std::function<void()> & on
|
|||||||
|
|
||||||
auto errorMsg = CGI->generaltexth->translate("vcmi.server.errors.existingProcess");
|
auto errorMsg = CGI->generaltexth->translate("vcmi.server.errors.existingProcess");
|
||||||
|
|
||||||
if (!checkNetworkPortIsFree(localhostAddress, getDefaultPort()))
|
// TODO: restore
|
||||||
{
|
// if (!checkNetworkPortIsFree(localhostAddress, getDefaultPort()))
|
||||||
logNetwork->error("Port is busy, check if another instance of vcmiserver is working");
|
// {
|
||||||
CInfoWindow::showInfoDialog(errorMsg, {});
|
// logNetwork->error("Port is busy, check if another instance of vcmiserver is working");
|
||||||
return;
|
// CInfoWindow::showInfoDialog(errorMsg, {});
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
#if defined(SINGLE_PROCESS_APP)
|
#if defined(SINGLE_PROCESS_APP)
|
||||||
boost::condition_variable cond;
|
boost::condition_variable cond;
|
||||||
@ -195,7 +210,7 @@ void CServerHandler::startLocalServerAndConnect(const std::function<void()> & on
|
|||||||
args.push_back("--lobby-port=" + std::to_string(settings["session"]["port"].Integer()));
|
args.push_back("--lobby-port=" + std::to_string(settings["session"]["port"].Integer()));
|
||||||
args.push_back("--lobby-uuid=" + settings["session"]["hostUuid"].String());
|
args.push_back("--lobby-uuid=" + settings["session"]["hostUuid"].String());
|
||||||
}
|
}
|
||||||
threadRunLocalServer = std::make_shared<boost::thread>([&cond, args, this] {
|
threadRunLocalServer = std::make_unique<boost::thread>([&cond, args, this] {
|
||||||
setThreadName("CVCMIServer");
|
setThreadName("CVCMIServer");
|
||||||
CVCMIServer::create(&cond, args);
|
CVCMIServer::create(&cond, args);
|
||||||
onServerFinished();
|
onServerFinished();
|
||||||
@ -207,7 +222,7 @@ void CServerHandler::startLocalServerAndConnect(const std::function<void()> & on
|
|||||||
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
|
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
threadRunLocalServer = std::make_shared<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable;
|
threadRunLocalServer = std::make_unique<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable;
|
||||||
#endif
|
#endif
|
||||||
logNetwork->trace("Setting up thread calling server: %d ms", th->getDiff());
|
logNetwork->trace("Setting up thread calling server: %d ms", th->getDiff());
|
||||||
|
|
||||||
@ -268,6 +283,10 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
|||||||
serverPort->Integer() = port;
|
serverPort->Integer() = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (onConnectedCallback)
|
||||||
|
throw std::runtime_error("Attempt to connect while there is already a pending connection!");
|
||||||
|
|
||||||
|
onConnectedCallback = onConnected;
|
||||||
networkClient->start(addr.size() ? addr : getHostAddress(), port ? port : getHostPort());
|
networkClient->start(addr.size() ? addr : getHostAddress(), port ? port : getHostPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,14 +307,18 @@ void CServerHandler::onConnectionFailed(const std::string & errorMessage)
|
|||||||
networkClient->start(getHostAddress(), getHostPort());
|
networkClient->start(getHostAddress(), getHostPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::onConnectionEstablished()
|
void CServerHandler::onConnectionEstablished(const std::shared_ptr<NetworkConnection> & netConnection)
|
||||||
{
|
{
|
||||||
|
logNetwork->info("Connection established");
|
||||||
|
c = std::make_shared<CConnection>(netConnection);
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
sendClientConnecting();
|
sendClientConnecting();
|
||||||
|
|
||||||
//FIXME: call functor provided in CServerHandler::justConnectToServer
|
if (onConnectedCallback)
|
||||||
assert(0);
|
{
|
||||||
//onConnected();
|
onConnectedCallback();
|
||||||
|
onConnectedCallback = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::applyPacksOnLobbyScreen()
|
void CServerHandler::applyPacksOnLobbyScreen()
|
||||||
@ -620,7 +643,6 @@ void CServerHandler::sendStartGame(bool allowOnlyAI) const
|
|||||||
}
|
}
|
||||||
sendLobbyPack(lsg);
|
sendLobbyPack(lsg);
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
c->disableStackSendingByID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::startMapAfterConnection(std::shared_ptr<CMapInfo> to)
|
void CServerHandler::startMapAfterConnection(std::shared_ptr<CMapInfo> to)
|
||||||
@ -699,10 +721,7 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(c)
|
if(c)
|
||||||
{
|
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
c->disableStackSendingByID();
|
|
||||||
}
|
|
||||||
|
|
||||||
//reset settings
|
//reset settings
|
||||||
Settings saveSession = settings.write["server"]["reconnect"];
|
Settings saveSession = settings.write["server"]["reconnect"];
|
||||||
@ -898,7 +917,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CServerHandler::onPacketReceived(const std::vector<uint8_t> & message)
|
void CServerHandler::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message)
|
||||||
{
|
{
|
||||||
CPack * pack = c->retrievePack(message);
|
CPack * pack = c->retrievePack(message);
|
||||||
if(state == EClientState::DISCONNECTING)
|
if(state == EClientState::DISCONNECTING)
|
||||||
@ -914,7 +933,7 @@ void CServerHandler::onPacketReceived(const std::vector<uint8_t> & message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerHandler::onDisconnected()
|
void CServerHandler::onDisconnected(const std::shared_ptr<NetworkConnection> &)
|
||||||
{
|
{
|
||||||
if(state == EClientState::DISCONNECTING)
|
if(state == EClientState::DISCONNECTING)
|
||||||
{
|
{
|
||||||
|
@ -98,14 +98,17 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien
|
|||||||
|
|
||||||
std::shared_ptr<HighScoreCalculation> highScoreCalc;
|
std::shared_ptr<HighScoreCalculation> highScoreCalc;
|
||||||
|
|
||||||
|
std::function<void()> onConnectedCallback;
|
||||||
|
|
||||||
|
void threadRunNetwork();
|
||||||
void threadRunServer();
|
void threadRunServer();
|
||||||
void onServerFinished();
|
void onServerFinished();
|
||||||
void sendLobbyPack(const CPackForLobby & pack) const override;
|
void sendLobbyPack(const CPackForLobby & pack) const override;
|
||||||
|
|
||||||
void onPacketReceived(const std::vector<uint8_t> & message) override;
|
void onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) override;
|
||||||
void onConnectionFailed(const std::string & errorMessage) override;
|
void onConnectionFailed(const std::string & errorMessage) override;
|
||||||
void onConnectionEstablished() override;
|
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
void onDisconnected() override;
|
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<CConnection> c;
|
std::shared_ptr<CConnection> c;
|
||||||
@ -122,7 +125,8 @@ public:
|
|||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
std::unique_ptr<CStopWatch> th;
|
std::unique_ptr<CStopWatch> th;
|
||||||
std::shared_ptr<boost::thread> threadRunLocalServer;
|
std::unique_ptr<boost::thread> threadRunLocalServer;
|
||||||
|
std::unique_ptr<boost::thread> threadNetwork;
|
||||||
|
|
||||||
CClient * client;
|
CClient * client;
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
|
|||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
// Check if it's LobbyClientConnected for our client
|
// Check if it's LobbyClientConnected for our client
|
||||||
if(pack.uuid == handler.c->uuid)
|
// TODO: restore
|
||||||
|
//if(pack.uuid == handler.c->uuid)
|
||||||
{
|
{
|
||||||
handler.c->connectionID = pack.clientId;
|
handler.c->connectionID = pack.clientId;
|
||||||
if(handler.mapToStart)
|
if(handler.mapToStart)
|
||||||
|
@ -615,6 +615,7 @@ void CSimpleJoinScreen::startConnection(const std::string & addr, ui16 port)
|
|||||||
{
|
{
|
||||||
// async call to prevent thread race
|
// async call to prevent thread race
|
||||||
GH.dispatchMainThread([this](){
|
GH.dispatchMainThread([this](){
|
||||||
|
// FIXME: this enum value is never set!!!
|
||||||
if(CSH->state == EClientState::CONNECTION_FAILED)
|
if(CSH->state == EClientState::CONNECTION_FAILED)
|
||||||
{
|
{
|
||||||
CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.mainMenu.serverConnectionFailed"), {});
|
CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.mainMenu.serverConnectionFailed"), {});
|
||||||
|
@ -42,7 +42,7 @@ static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
|
|||||||
return timeFormatted.toString();
|
return timeFormatted.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyClient::onPacketReceived(const std::vector<uint8_t> & message)
|
void LobbyClient::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message)
|
||||||
{
|
{
|
||||||
// FIXME: find better approach
|
// FIXME: find better approach
|
||||||
const char * payloadBegin = reinterpret_cast<const char*>(message.data());
|
const char * payloadBegin = reinterpret_cast<const char*>(message.data());
|
||||||
@ -69,7 +69,7 @@ void LobbyClient::onPacketReceived(const std::vector<uint8_t> & message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyClient::onConnectionEstablished()
|
void LobbyClient::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &)
|
||||||
{
|
{
|
||||||
JsonNode toSend;
|
JsonNode toSend;
|
||||||
toSend["type"].String() = "authentication";
|
toSend["type"].String() = "authentication";
|
||||||
@ -84,7 +84,7 @@ void LobbyClient::onConnectionFailed(const std::string & errorMessage)
|
|||||||
CInfoWindow::showInfoDialog("Failed to connect to game lobby!\n" + errorMessage, {});
|
CInfoWindow::showInfoDialog("Failed to connect to game lobby!\n" + errorMessage, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyClient::onDisconnected()
|
void LobbyClient::onDisconnected(const std::shared_ptr<NetworkConnection> &)
|
||||||
{
|
{
|
||||||
GH.windows().popWindows(1);
|
GH.windows().popWindows(1);
|
||||||
CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
|
CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
|
||||||
|
@ -32,10 +32,10 @@ class LobbyClient : public INetworkClientListener
|
|||||||
std::unique_ptr<NetworkClient> networkClient;
|
std::unique_ptr<NetworkClient> networkClient;
|
||||||
LobbyWindow * window;
|
LobbyWindow * window;
|
||||||
|
|
||||||
void onPacketReceived(const std::vector<uint8_t> & message) override;
|
void onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) override;
|
||||||
void onConnectionFailed(const std::string & errorMessage) override;
|
void onConnectionFailed(const std::string & errorMessage) override;
|
||||||
void onConnectionEstablished() override;
|
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
void onDisconnected() override;
|
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LobbyClient(LobbyWindow * window);
|
explicit LobbyClient(LobbyWindow * window);
|
||||||
|
@ -56,11 +56,12 @@ void NetworkClient::onConnected(const boost::system::error_code & ec)
|
|||||||
connection = std::make_shared<NetworkConnection>(socket, *this);
|
connection = std::make_shared<NetworkConnection>(socket, *this);
|
||||||
connection->start();
|
connection->start();
|
||||||
|
|
||||||
listener.onConnectionEstablished();
|
listener.onConnectionEstablished(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkClient::run()
|
void NetworkClient::run()
|
||||||
{
|
{
|
||||||
|
boost::asio::executor_work_guard<decltype(io->get_executor())> work{io->get_executor()};
|
||||||
io->run();
|
io->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +70,11 @@ void NetworkClient::poll()
|
|||||||
io->poll();
|
io->poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkClient::stop()
|
||||||
|
{
|
||||||
|
io->stop();
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
|
void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
|
||||||
{
|
{
|
||||||
connection->sendPacket(message);
|
connection->sendPacket(message);
|
||||||
@ -76,12 +82,12 @@ void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
|
|||||||
|
|
||||||
void NetworkClient::onDisconnected(const std::shared_ptr<NetworkConnection> & connection)
|
void NetworkClient::onDisconnected(const std::shared_ptr<NetworkConnection> & connection)
|
||||||
{
|
{
|
||||||
listener.onDisconnected();
|
listener.onDisconnected(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkClient::onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message)
|
void NetworkClient::onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message)
|
||||||
{
|
{
|
||||||
listener.onPacketReceived(message);
|
listener.onPacketReceived(connection, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
void start(const std::string & host, uint16_t port);
|
void start(const std::string & host, uint16_t port);
|
||||||
void run();
|
void run();
|
||||||
void poll();
|
void poll();
|
||||||
|
void stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -16,7 +16,9 @@ NetworkConnection::NetworkConnection(const std::shared_ptr<NetworkSocket> & sock
|
|||||||
: socket(socket)
|
: socket(socket)
|
||||||
, listener(listener)
|
, listener(listener)
|
||||||
{
|
{
|
||||||
|
socket->set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
|
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304));
|
||||||
|
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkConnection::start()
|
void NetworkConnection::start()
|
||||||
|
@ -17,7 +17,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
class DLL_LINKAGE NetworkConnection :public std::enable_shared_from_this<NetworkConnection>, boost::noncopyable
|
class DLL_LINKAGE NetworkConnection :public std::enable_shared_from_this<NetworkConnection>, boost::noncopyable
|
||||||
{
|
{
|
||||||
static const int messageHeaderSize = sizeof(uint32_t);
|
static const int messageHeaderSize = sizeof(uint32_t);
|
||||||
static const int messageMaxSize = 65536; // arbitrary size to prevent potential massive allocation if we receive garbage input
|
static const int messageMaxSize = 64 * 1024 * 1024; // arbitrary size to prevent potential massive allocation if we receive garbage input
|
||||||
|
|
||||||
std::shared_ptr<NetworkSocket> socket;
|
std::shared_ptr<NetworkSocket> socket;
|
||||||
|
|
||||||
|
@ -34,14 +34,12 @@ protected:
|
|||||||
~INetworkServerListener() = default;
|
~INetworkServerListener() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE INetworkClientListener
|
class DLL_LINKAGE INetworkClientListener : public INetworkConnectionListener
|
||||||
{
|
{
|
||||||
friend class NetworkClient;
|
friend class NetworkClient;
|
||||||
protected:
|
protected:
|
||||||
virtual void onPacketReceived(const std::vector<uint8_t> & message) = 0;
|
|
||||||
virtual void onConnectionFailed(const std::string & errorMessage) = 0;
|
virtual void onConnectionFailed(const std::string & errorMessage) = 0;
|
||||||
virtual void onConnectionEstablished() = 0;
|
virtual void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) = 0;
|
||||||
virtual void onDisconnected() = 0;
|
|
||||||
|
|
||||||
~INetworkClientListener() = default;
|
~INetworkClientListener() = default;
|
||||||
};
|
};
|
||||||
|
@ -13,397 +13,150 @@
|
|||||||
#include "BinaryDeserializer.h"
|
#include "BinaryDeserializer.h"
|
||||||
#include "BinarySerializer.h"
|
#include "BinarySerializer.h"
|
||||||
|
|
||||||
//#include "../networkPacks/NetPacksBase.h"
|
#include "../networkPacks/NetPacksBase.h"
|
||||||
|
#include "../network/NetworkConnection.h"
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class DLL_LINKAGE ConnectionPackWriter final : public IBinaryWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<uint8_t> buffer;
|
||||||
|
|
||||||
|
int write(const void * data, unsigned size) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE ConnectionPackReader final : public IBinaryReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const std::vector<uint8_t> * buffer;
|
||||||
|
size_t position;
|
||||||
|
|
||||||
|
int read(void * data, unsigned size) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ConnectionPackWriter::write(const void * data, unsigned size)
|
||||||
|
{
|
||||||
|
const uint8_t * begin_ptr = static_cast<const uint8_t *>(data);
|
||||||
|
const uint8_t * end_ptr = begin_ptr + size;
|
||||||
|
buffer.insert(buffer.end(), begin_ptr, end_ptr);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConnectionPackReader::read(void * data, unsigned size)
|
||||||
|
{
|
||||||
|
if (position + size > buffer->size())
|
||||||
|
throw std::runtime_error("End of file reached when reading received network pack!");
|
||||||
|
|
||||||
|
uint8_t * begin_ptr = static_cast<uint8_t *>(data);
|
||||||
|
|
||||||
|
std::copy_n(buffer->begin() + position, size, begin_ptr);
|
||||||
|
position += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
CConnection::CConnection(std::weak_ptr<NetworkConnection> networkConnection)
|
CConnection::CConnection(std::weak_ptr<NetworkConnection> 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);
|
||||||
|
|
||||||
|
enableSmartPointerSerialization();
|
||||||
|
disableStackSendingByID();
|
||||||
|
deserializer->fileVersion = SERIALIZATION_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CConnection::~CConnection() = default;
|
||||||
|
|
||||||
void CConnection::sendPack(const CPack * pack)
|
void CConnection::sendPack(const CPack * pack)
|
||||||
{
|
{
|
||||||
|
auto connectionPtr = networkConnection.lock();
|
||||||
|
|
||||||
|
if (!connectionPtr)
|
||||||
|
throw std::runtime_error("Attempt to send packet on a closed connection!");
|
||||||
|
|
||||||
|
*serializer & pack;
|
||||||
|
|
||||||
|
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
||||||
|
|
||||||
|
connectionPtr->sendPacket(packWriter->buffer);
|
||||||
|
packWriter->buffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPack * CConnection::retrievePack(const std::vector<uint8_t> & data)
|
CPack * CConnection::retrievePack(const std::vector<uint8_t> & data)
|
||||||
{
|
{
|
||||||
return nullptr;
|
CPack * result;
|
||||||
|
|
||||||
|
packReader->buffer = &data;
|
||||||
|
packReader->position = 0;
|
||||||
|
|
||||||
|
*deserializer & result;
|
||||||
|
|
||||||
|
logNetwork->trace("Received CPack of type %s", (result ? typeid(*result).name() : "nullptr"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConnection::isMyConnection(const std::shared_ptr<NetworkConnection> & otherConnection) const
|
||||||
|
{
|
||||||
|
return otherConnection != nullptr && networkConnection.lock() == otherConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::disableStackSendingByID()
|
void CConnection::disableStackSendingByID()
|
||||||
{
|
{
|
||||||
|
packReader->sendStackInstanceByIds = false;
|
||||||
}
|
packWriter->sendStackInstanceByIds = false;
|
||||||
|
|
||||||
void CConnection::enterLobbyConnectionMode()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::enterGameplayConnectionMode(CGameState * gs)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int CConnection::write(const void * data, unsigned size)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CConnection::read(void * data, unsigned size)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
using namespace boost;
|
|
||||||
using namespace boost::asio::ip;
|
|
||||||
|
|
||||||
struct ConnectionBuffers
|
|
||||||
{
|
|
||||||
boost::asio::streambuf readBuffer;
|
|
||||||
boost::asio::streambuf writeBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CConnection::init()
|
|
||||||
{
|
|
||||||
enableBufferedWrite = false;
|
|
||||||
enableBufferedRead = false;
|
|
||||||
connectionBuffers = std::make_unique<ConnectionBuffers>();
|
|
||||||
|
|
||||||
socket->set_option(boost::asio::ip::tcp::no_delay(true));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304));
|
|
||||||
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304));
|
|
||||||
}
|
|
||||||
catch (const boost::system::system_error & e)
|
|
||||||
{
|
|
||||||
logNetwork->error("error setting socket option: %s", e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
enableSmartPointerSerialization();
|
|
||||||
disableStackSendingByID();
|
|
||||||
#ifndef VCMI_ENDIAN_BIG
|
|
||||||
myEndianess = true;
|
|
||||||
#else
|
|
||||||
myEndianess = false;
|
|
||||||
#endif
|
|
||||||
connected = true;
|
|
||||||
std::string pom;
|
|
||||||
//we got connection
|
|
||||||
oser & std::string("Aiya!\n") & name & uuid & myEndianess; //identify ourselves
|
|
||||||
iser & pom & pom & contactUuid & contactEndianess;
|
|
||||||
logNetwork->info("Established connection with %s. UUID: %s", pom, contactUuid);
|
|
||||||
mutexRead = std::make_shared<boost::mutex>();
|
|
||||||
mutexWrite = std::make_shared<boost::mutex>();
|
|
||||||
|
|
||||||
iser.fileVersion = SERIALIZATION_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
CConnection::CConnection(const std::string & host, ui16 port, std::string Name, std::string UUID):
|
|
||||||
io_service(std::make_shared<asio::io_service>()),
|
|
||||||
iser(this),
|
|
||||||
oser(this),
|
|
||||||
name(std::move(Name)),
|
|
||||||
uuid(std::move(UUID))
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
boost::system::error_code error = asio::error::host_not_found;
|
|
||||||
socket = std::make_shared<tcp::socket>(*io_service);
|
|
||||||
|
|
||||||
tcp::resolver resolver(*io_service);
|
|
||||||
tcp::resolver::iterator end;
|
|
||||||
tcp::resolver::iterator pom;
|
|
||||||
tcp::resolver::iterator endpoint_iterator = resolver.resolve(tcp::resolver::query(host, std::to_string(port)), error);
|
|
||||||
if(error)
|
|
||||||
{
|
|
||||||
logNetwork->error("Problem with resolving: \n%s", error.message());
|
|
||||||
throw std::runtime_error("Problem with resolving");
|
|
||||||
}
|
|
||||||
pom = endpoint_iterator;
|
|
||||||
if(pom != end)
|
|
||||||
logNetwork->info("Found endpoints:");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logNetwork->error("Critical problem: No endpoints found!");
|
|
||||||
throw std::runtime_error("No endpoints found!");
|
|
||||||
}
|
|
||||||
while(pom != end)
|
|
||||||
{
|
|
||||||
logNetwork->info("\t%d:%s", i, (boost::asio::ip::tcp::endpoint&)*pom);
|
|
||||||
pom++;
|
|
||||||
}
|
|
||||||
i=0;
|
|
||||||
while(endpoint_iterator != end)
|
|
||||||
{
|
|
||||||
logNetwork->info("Trying connection to %s(%d)", (boost::asio::ip::tcp::endpoint&)*endpoint_iterator, i++);
|
|
||||||
socket->connect(*endpoint_iterator, error);
|
|
||||||
if(!error)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to connect!");
|
|
||||||
}
|
|
||||||
endpoint_iterator++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CConnection::CConnection(std::shared_ptr<TSocket> Socket, std::string Name, std::string UUID):
|
|
||||||
iser(this),
|
|
||||||
oser(this),
|
|
||||||
socket(std::move(Socket)),
|
|
||||||
name(std::move(Name)),
|
|
||||||
uuid(std::move(UUID))
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
CConnection::CConnection(const std::shared_ptr<TAcceptor> & acceptor,
|
|
||||||
const std::shared_ptr<boost::asio::io_service> & io_service,
|
|
||||||
std::string Name,
|
|
||||||
std::string UUID):
|
|
||||||
io_service(io_service),
|
|
||||||
iser(this),
|
|
||||||
oser(this),
|
|
||||||
name(std::move(Name)),
|
|
||||||
uuid(std::move(UUID))
|
|
||||||
{
|
|
||||||
boost::system::error_code error = asio::error::host_not_found;
|
|
||||||
socket = std::make_shared<tcp::socket>(*io_service);
|
|
||||||
acceptor->accept(*socket,error);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
logNetwork->error("Error on accepting: %s", error.message());
|
|
||||||
socket.reset();
|
|
||||||
throw std::runtime_error("Can't establish connection :(");
|
|
||||||
}
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::flushBuffers()
|
|
||||||
{
|
|
||||||
if(!enableBufferedWrite)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!socket)
|
|
||||||
throw std::runtime_error("Can't write to closed socket!");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
asio::write(*socket, connectionBuffers->writeBuffer);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
//connection has been lost
|
|
||||||
connected = false;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
enableBufferedWrite = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CConnection::write(const void * data, unsigned size)
|
|
||||||
{
|
|
||||||
if (!socket)
|
|
||||||
throw std::runtime_error("Can't write to closed socket!");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(enableBufferedWrite)
|
|
||||||
{
|
|
||||||
std::ostream ostream(&connectionBuffers->writeBuffer);
|
|
||||||
|
|
||||||
ostream.write(static_cast<const char *>(data), size);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = static_cast<int>(asio::write(*socket, asio::const_buffers_1(asio::const_buffer(data, size))));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
//connection has been lost
|
|
||||||
connected = false;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int CConnection::read(void * data, unsigned size)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(enableBufferedRead)
|
|
||||||
{
|
|
||||||
auto available = connectionBuffers->readBuffer.size();
|
|
||||||
|
|
||||||
while(available < size)
|
|
||||||
{
|
|
||||||
auto bytesRead = socket->read_some(connectionBuffers->readBuffer.prepare(1024));
|
|
||||||
connectionBuffers->readBuffer.commit(bytesRead);
|
|
||||||
available = connectionBuffers->readBuffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istream istream(&connectionBuffers->readBuffer);
|
|
||||||
|
|
||||||
istream.read(static_cast<char *>(data), size);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = static_cast<int>(asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size))));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
//connection has been lost
|
|
||||||
connected = false;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CConnection::~CConnection()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
|
|
||||||
if(handler)
|
|
||||||
{
|
|
||||||
// ugly workaround to avoid self-join if last strong reference to shared_ptr that owns this class has been released in this very thread, e.g. on netpack processing
|
|
||||||
if (boost::this_thread::get_id() != handler->get_id())
|
|
||||||
handler->join();
|
|
||||||
else
|
|
||||||
handler->detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
if(socket)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket->shutdown(boost::asio::ip::tcp::socket::shutdown_receive);
|
|
||||||
}
|
|
||||||
catch (const boost::system::system_error & e)
|
|
||||||
{
|
|
||||||
logNetwork->error("error closing socket: %s", e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
socket->close();
|
|
||||||
socket.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CConnection::isOpen() const
|
|
||||||
{
|
|
||||||
return socket && connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::reportState(vstd::CLoggerBase * out)
|
|
||||||
{
|
|
||||||
out->debug("CConnection");
|
|
||||||
if(socket && socket->is_open())
|
|
||||||
{
|
|
||||||
out->debug("\tWe have an open and valid socket");
|
|
||||||
out->debug("\t %d bytes awaiting", socket->available());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CPack * CConnection::retrievePack()
|
|
||||||
{
|
|
||||||
enableBufferedRead = true;
|
|
||||||
|
|
||||||
CPack * pack = nullptr;
|
|
||||||
boost::unique_lock<boost::mutex> lock(*mutexRead);
|
|
||||||
iser & pack;
|
|
||||||
logNetwork->trace("Received CPack of type %s", (pack ? typeid(*pack).name() : "nullptr"));
|
|
||||||
if(pack == nullptr)
|
|
||||||
logNetwork->error("Received a nullptr CPack! You should check whether client and server ABI matches.");
|
|
||||||
|
|
||||||
enableBufferedRead = false;
|
|
||||||
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::sendPack(const CPack * pack)
|
|
||||||
{
|
|
||||||
boost::unique_lock<boost::mutex> lock(*mutexWrite);
|
|
||||||
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
|
||||||
|
|
||||||
enableBufferedWrite = true;
|
|
||||||
|
|
||||||
oser & pack;
|
|
||||||
|
|
||||||
flushBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::disableStackSendingByID()
|
|
||||||
{
|
|
||||||
CSerializer::sendStackInstanceByIds = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::enableStackSendingByID()
|
void CConnection::enableStackSendingByID()
|
||||||
{
|
{
|
||||||
CSerializer::sendStackInstanceByIds = true;
|
packReader->sendStackInstanceByIds = true;
|
||||||
}
|
packWriter->sendStackInstanceByIds = true;
|
||||||
|
|
||||||
void CConnection::disableSmartPointerSerialization()
|
|
||||||
{
|
|
||||||
iser.smartPointerSerialization = oser.smartPointerSerialization = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CConnection::enableSmartPointerSerialization()
|
|
||||||
{
|
|
||||||
iser.smartPointerSerialization = oser.smartPointerSerialization = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::enterLobbyConnectionMode()
|
void CConnection::enterLobbyConnectionMode()
|
||||||
{
|
{
|
||||||
iser.loadedPointers.clear();
|
deserializer->loadedPointers.clear();
|
||||||
oser.savedPointers.clear();
|
serializer->savedPointers.clear();
|
||||||
disableSmartVectorMemberSerialization();
|
disableSmartVectorMemberSerialization();
|
||||||
disableSmartPointerSerialization();
|
disableSmartPointerSerialization();
|
||||||
|
disableStackSendingByID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::enterGameplayConnectionMode(CGameState * gs)
|
void CConnection::enterGameplayConnectionMode(CGameState * gs)
|
||||||
{
|
{
|
||||||
enableStackSendingByID();
|
enableStackSendingByID();
|
||||||
disableSmartPointerSerialization();
|
disableSmartPointerSerialization();
|
||||||
addStdVecItems(gs);
|
|
||||||
|
packReader->addStdVecItems(gs);
|
||||||
|
packWriter->addStdVecItems(gs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConnection::disableSmartPointerSerialization()
|
||||||
|
{
|
||||||
|
deserializer->smartPointerSerialization = false;
|
||||||
|
serializer->smartPointerSerialization = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConnection::enableSmartPointerSerialization()
|
||||||
|
{
|
||||||
|
deserializer->smartPointerSerialization = true;
|
||||||
|
serializer->smartPointerSerialization = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::disableSmartVectorMemberSerialization()
|
void CConnection::disableSmartVectorMemberSerialization()
|
||||||
{
|
{
|
||||||
CSerializer::smartVectorMembersSerialization = false;
|
packReader->smartVectorMembersSerialization = false;
|
||||||
|
packWriter->smartVectorMembersSerialization = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::enableSmartVectorMemberSerializatoin()
|
void CConnection::enableSmartVectorMemberSerializatoin()
|
||||||
{
|
{
|
||||||
CSerializer::smartVectorMembersSerialization = true;
|
packReader->smartVectorMembersSerialization = true;
|
||||||
}
|
packWriter->smartVectorMembersSerialization = true;
|
||||||
|
|
||||||
std::string CConnection::toString() const
|
|
||||||
{
|
|
||||||
boost::format fmt("Connection with %s (ID: %d UUID: %s)");
|
|
||||||
fmt % name % connectionID % uuid;
|
|
||||||
return fmt.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -9,84 +9,49 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CSerializer.h"
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
class BinaryDeserializer;
|
class BinaryDeserializer;
|
||||||
class BinarySerializer;
|
class BinarySerializer;
|
||||||
struct CPack;
|
struct CPack;
|
||||||
struct ConnectionBuffers;
|
|
||||||
class NetworkConnection;
|
class NetworkConnection;
|
||||||
|
class ConnectionPackReader;
|
||||||
|
class ConnectionPackWriter;
|
||||||
|
class CGameState;
|
||||||
|
|
||||||
/// Main class for network communication
|
/// Wrapper class for game connection
|
||||||
/// Allows establishing connection and bidirectional read-write
|
/// Handles serialization and deserialization of data received from network
|
||||||
class DLL_LINKAGE CConnection : public IBinaryReader, public IBinaryWriter, public std::enable_shared_from_this<CConnection>
|
class DLL_LINKAGE CConnection : boost::noncopyable
|
||||||
{
|
{
|
||||||
/// Non-owning pointer to underlying connection
|
/// Non-owning pointer to underlying connection
|
||||||
std::weak_ptr<NetworkConnection> networkConnection;
|
std::weak_ptr<NetworkConnection> networkConnection;
|
||||||
|
|
||||||
// void init();
|
std::unique_ptr<ConnectionPackReader> packReader;
|
||||||
// void reportState(vstd::CLoggerBase * out) override;
|
std::unique_ptr<ConnectionPackWriter> packWriter;
|
||||||
//
|
std::unique_ptr<BinaryDeserializer> deserializer;
|
||||||
int write(const void * data, unsigned size) override;
|
std::unique_ptr<BinarySerializer> serializer;
|
||||||
int read(void * data, unsigned size) override;
|
|
||||||
// void flushBuffers();
|
void disableStackSendingByID();
|
||||||
//
|
void enableStackSendingByID();
|
||||||
// bool enableBufferedWrite;
|
void disableSmartPointerSerialization();
|
||||||
// bool enableBufferedRead;
|
void enableSmartPointerSerialization();
|
||||||
// std::unique_ptr<ConnectionBuffers> connectionBuffers;
|
void disableSmartVectorMemberSerialization();
|
||||||
//
|
void enableSmartVectorMemberSerializatoin();
|
||||||
std::unique_ptr<BinaryDeserializer> iser;
|
|
||||||
std::unique_ptr<BinarySerializer> oser;
|
|
||||||
//
|
|
||||||
// std::string contactUuid;
|
|
||||||
// std::string name; //who uses this connection
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool isMyConnection(const std::shared_ptr<NetworkConnection> & otherConnection) const;
|
||||||
|
|
||||||
std::string uuid;
|
std::string uuid;
|
||||||
int connectionID;
|
int connectionID;
|
||||||
|
|
||||||
CConnection(std::weak_ptr<NetworkConnection> networkConnection);
|
CConnection(std::weak_ptr<NetworkConnection> networkConnection);
|
||||||
// CConnection(const std::string & host, ui16 port, std::string Name, std::string UUID);
|
~CConnection();
|
||||||
// CConnection(const std::shared_ptr<TAcceptor> & acceptor, const std::shared_ptr<boost::asio::io_service> & Io_service, std::string Name, std::string UUID);
|
|
||||||
// CConnection(std::shared_ptr<TSocket> Socket, std::string Name, std::string UUID); //use immediately after accepting connection into socket
|
|
||||||
// virtual ~CConnection();
|
|
||||||
|
|
||||||
// void close();
|
|
||||||
// bool isOpen() const;
|
|
||||||
//
|
|
||||||
// CPack * retrievePack();
|
|
||||||
void sendPack(const CPack * pack);
|
void sendPack(const CPack * pack);
|
||||||
|
|
||||||
CPack * retrievePack(const std::vector<uint8_t> & data);
|
CPack * retrievePack(const std::vector<uint8_t> & data);
|
||||||
// std::vector<uint8_t> serializePack(const CPack * pack);
|
|
||||||
//
|
|
||||||
void disableStackSendingByID();
|
|
||||||
// void enableStackSendingByID();
|
|
||||||
// void disableSmartPointerSerialization();
|
|
||||||
// void enableSmartPointerSerialization();
|
|
||||||
// void disableSmartVectorMemberSerialization();
|
|
||||||
// void enableSmartVectorMemberSerializatoin();
|
|
||||||
//
|
|
||||||
void enterLobbyConnectionMode();
|
void enterLobbyConnectionMode();
|
||||||
void enterGameplayConnectionMode(CGameState * gs);
|
void enterGameplayConnectionMode(CGameState * gs);
|
||||||
//
|
|
||||||
// std::string toString() const;
|
|
||||||
//
|
|
||||||
// template<class T>
|
|
||||||
// CConnection & operator>>(T &t)
|
|
||||||
// {
|
|
||||||
// iser & t;
|
|
||||||
// return * this;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// template<class T>
|
|
||||||
// CConnection & operator<<(const T &t)
|
|
||||||
// {
|
|
||||||
// oser & t;
|
|
||||||
// return * this;
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -177,7 +177,10 @@ void CVCMIServer::onNewConnection(const std::shared_ptr<NetworkConnection> & con
|
|||||||
establishOutgoingConnection();
|
establishOutgoingConnection();
|
||||||
|
|
||||||
if(state == EServerState::LOBBY)
|
if(state == EServerState::LOBBY)
|
||||||
|
{
|
||||||
activeConnections.push_back(std::make_shared<CConnection>(connection));//, SERVER_NAME, uuid);)
|
activeConnections.push_back(std::make_shared<CConnection>(connection));//, SERVER_NAME, uuid);)
|
||||||
|
activeConnections.back()->enterLobbyConnectionMode();
|
||||||
|
}
|
||||||
// TODO: else: deny connection
|
// TODO: else: deny connection
|
||||||
// TODO: else: try to reconnect / send state to reconnected client
|
// TODO: else: try to reconnect / send state to reconnected client
|
||||||
}
|
}
|
||||||
@ -193,26 +196,16 @@ void CVCMIServer::onPacketReceived(const std::shared_ptr<NetworkConnection> & co
|
|||||||
//FIXME: delete pack?
|
//FIXME: delete pack?
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVCMIServer::onPacketReceived(const std::vector<uint8_t> & message)
|
|
||||||
{
|
|
||||||
//TODO: handle pack received from lobby
|
|
||||||
}
|
|
||||||
|
|
||||||
void CVCMIServer::onConnectionFailed(const std::string & errorMessage)
|
void CVCMIServer::onConnectionFailed(const std::string & errorMessage)
|
||||||
{
|
{
|
||||||
//TODO: handle failure to connect to lobby
|
//TODO: handle failure to connect to lobby
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVCMIServer::onConnectionEstablished()
|
void CVCMIServer::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &)
|
||||||
{
|
{
|
||||||
//TODO: handle connection to lobby - login?
|
//TODO: handle connection to lobby - login?
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVCMIServer::onDisconnected()
|
|
||||||
{
|
|
||||||
//TODO: handle disconnection from lobby
|
|
||||||
}
|
|
||||||
|
|
||||||
void CVCMIServer::setState(EServerState value)
|
void CVCMIServer::setState(EServerState value)
|
||||||
{
|
{
|
||||||
state.store(value);
|
state.store(value);
|
||||||
@ -225,9 +218,13 @@ EServerState CVCMIServer::getState() const
|
|||||||
|
|
||||||
std::shared_ptr<CConnection> CVCMIServer::findConnection(const std::shared_ptr<NetworkConnection> & netConnection)
|
std::shared_ptr<CConnection> CVCMIServer::findConnection(const std::shared_ptr<NetworkConnection> & netConnection)
|
||||||
{
|
{
|
||||||
//TODO
|
for (auto const & gameConnection : activeConnections)
|
||||||
assert(0);
|
{
|
||||||
return nullptr;
|
if (gameConnection->isMyConnection(netConnection))
|
||||||
|
return gameConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Unknown connection received in CVCMIServer::findConnection");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVCMIServer::run()
|
void CVCMIServer::run()
|
||||||
@ -294,10 +291,8 @@ void CVCMIServer::prepareToRestart()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto c : activeConnections)
|
for(auto c : activeConnections)
|
||||||
{
|
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
c->disableStackSendingByID();
|
|
||||||
}
|
|
||||||
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
||||||
gh = nullptr;
|
gh = nullptr;
|
||||||
}
|
}
|
||||||
@ -417,8 +412,8 @@ void CVCMIServer::announcePack(std::unique_ptr<CPackForLobby> pack)
|
|||||||
{
|
{
|
||||||
// FIXME: we need to avoid sending something to client that not yet get answer for LobbyClientConnected
|
// FIXME: we need to avoid sending something to client that not yet get answer for LobbyClientConnected
|
||||||
// Until UUID set we only pass LobbyClientConnected to this client
|
// Until UUID set we only pass LobbyClientConnected to this client
|
||||||
if(c->uuid == uuid && !dynamic_cast<LobbyClientConnected *>(pack.get()))
|
//if(c->uuid == uuid && !dynamic_cast<LobbyClientConnected *>(pack.get()))
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
c->sendPack(pack.get());
|
c->sendPack(pack.get());
|
||||||
}
|
}
|
||||||
|
@ -70,16 +70,12 @@ private:
|
|||||||
std::unique_ptr<boost::thread> remoteConnectionsThread;
|
std::unique_ptr<boost::thread> remoteConnectionsThread;
|
||||||
std::atomic<EServerState> state;
|
std::atomic<EServerState> state;
|
||||||
|
|
||||||
// INetworkServerListener impl
|
// INetworkListener impl
|
||||||
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override;
|
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override;
|
||||||
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
||||||
void onNewConnection(const std::shared_ptr<NetworkConnection> &) override;
|
void onNewConnection(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
|
|
||||||
// INetworkClientListener impl
|
|
||||||
void onPacketReceived(const std::vector<uint8_t> & message) override;
|
|
||||||
void onConnectionFailed(const std::string & errorMessage) override;
|
void onConnectionFailed(const std::string & errorMessage) override;
|
||||||
void onConnectionEstablished() override;
|
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
void onDisconnected() override;
|
|
||||||
|
|
||||||
void establishOutgoingConnection();
|
void establishOutgoingConnection();
|
||||||
|
|
||||||
|
@ -210,10 +210,7 @@ void ApplyOnServerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
|||||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||||
{
|
{
|
||||||
for(auto & c : srv.activeConnections)
|
for(auto & c : srv.activeConnections)
|
||||||
{
|
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
c->disableStackSendingByID();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
void ClientPermissionsCheckerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||||
|
Reference in New Issue
Block a user