1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

Finalized new TCP networking API

This commit is contained in:
Ivan Savenko 2024-01-12 01:10:41 +02:00
parent 476a05fed3
commit 80e960bc8e
23 changed files with 306 additions and 241 deletions

View File

@ -46,7 +46,6 @@
#include "../lib/mapping/CMapInfo.h" #include "../lib/mapping/CMapInfo.h"
#include "../lib/mapObjects/MiscObjects.h" #include "../lib/mapObjects/MiscObjects.h"
#include "../lib/modding/ModIncompatibility.h" #include "../lib/modding/ModIncompatibility.h"
#include "../lib/network/NetworkClient.h"
#include "../lib/rmg/CMapGenOptions.h" #include "../lib/rmg/CMapGenOptions.h"
#include "../lib/serializer/Connection.h" #include "../lib/serializer/Connection.h"
#include "../lib/filesystem/Filesystem.h" #include "../lib/filesystem/Filesystem.h"
@ -132,15 +131,16 @@ static const std::string NAME = GameConstants::VCMI_VERSION + std::string(" (")
CServerHandler::~CServerHandler() CServerHandler::~CServerHandler()
{ {
networkClient->stop(); networkHandler->stop();
threadNetwork->join(); threadNetwork->join();
} }
CServerHandler::CServerHandler() CServerHandler::CServerHandler()
: state(EClientState::NONE) : state(EClientState::NONE)
, networkClient(std::make_unique<NetworkClient>(*this)) , networkHandler(INetworkHandler::createHandler())
, networkClient(networkHandler->createClientTCP(*this))
, applier(std::make_unique<CApplier<CBaseForLobbyApply>>()) , applier(std::make_unique<CApplier<CBaseForLobbyApply>>())
, lobbyClient(std::make_unique<GlobalLobbyClient>()) , lobbyClient(std::make_unique<GlobalLobbyClient>(networkHandler))
, client(nullptr) , client(nullptr)
, loadMode(0) , loadMode(0)
, campaignStateToSend(nullptr) , campaignStateToSend(nullptr)
@ -155,7 +155,7 @@ void CServerHandler::threadRunNetwork()
{ {
logGlobal->info("Starting network thread"); logGlobal->info("Starting network thread");
setThreadName("runNetwork"); setThreadName("runNetwork");
networkClient->run(); networkHandler->run();
logGlobal->info("Ending network thread"); logGlobal->info("Ending network thread");
} }
@ -277,7 +277,7 @@ void CServerHandler::onConnectionFailed(const std::string & errorMessage)
{ {
// retry - local server might be still starting up // retry - local server might be still starting up
logNetwork->debug("\nCannot establish connection. %s. Retrying...", errorMessage); logNetwork->debug("\nCannot establish connection. %s. Retrying...", errorMessage);
networkClient->setTimer(std::chrono::milliseconds(100)); networkHandler->createTimer(*this, std::chrono::milliseconds(100));
} }
else else
{ {
@ -299,7 +299,7 @@ void CServerHandler::onTimer()
networkClient->start(getLocalHostname(), getLocalPort()); networkClient->start(getLocalHostname(), getLocalPort());
} }
void CServerHandler::onConnectionEstablished(const std::shared_ptr<NetworkConnection> & netConnection) void CServerHandler::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & netConnection)
{ {
logNetwork->info("Connection established"); logNetwork->info("Connection established");
c = std::make_shared<CConnection>(netConnection); c = std::make_shared<CConnection>(netConnection);
@ -852,7 +852,7 @@ public:
} }
}; };
void CServerHandler::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message)
{ {
CPack * pack = c->retrievePack(message); CPack * pack = c->retrievePack(message);
if(state == EClientState::DISCONNECTING) if(state == EClientState::DISCONNECTING)
@ -868,7 +868,7 @@ void CServerHandler::onPacketReceived(const std::shared_ptr<NetworkConnection> &
} }
} }
void CServerHandler::onDisconnected(const std::shared_ptr<NetworkConnection> &) void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> &)
{ {
if(state == EClientState::DISCONNECTING) if(state == EClientState::DISCONNECTING)
{ {

View File

@ -11,7 +11,7 @@
#include "../lib/CStopWatch.h" #include "../lib/CStopWatch.h"
#include "../lib/network/NetworkListener.h" #include "../lib/network/NetworkInterface.h"
#include "../lib/StartInfo.h" #include "../lib/StartInfo.h"
#include "../lib/CondSh.h" #include "../lib/CondSh.h"
@ -82,11 +82,12 @@ public:
}; };
/// structure to handle running server and connecting to it /// structure to handle running server and connecting to it
class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClientListener, boost::noncopyable class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClientListener, public INetworkTimerListener, boost::noncopyable
{ {
friend class ApplyOnLobbyHandlerNetPackVisitor; friend class ApplyOnLobbyHandlerNetPackVisitor;
std::unique_ptr<NetworkClient> networkClient; std::unique_ptr<INetworkHandler> networkHandler;
std::unique_ptr<INetworkClient> networkClient;
std::unique_ptr<GlobalLobbyClient> lobbyClient; std::unique_ptr<GlobalLobbyClient> lobbyClient;
std::unique_ptr<CApplier<CBaseForLobbyApply>> applier; std::unique_ptr<CApplier<CBaseForLobbyApply>> applier;
std::shared_ptr<CMapInfo> mapToStart; std::shared_ptr<CMapInfo> mapToStart;
@ -98,10 +99,10 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien
void onServerFinished(); void onServerFinished();
void sendLobbyPack(const CPackForLobby & pack) const override; void sendLobbyPack(const CPackForLobby & pack) const override;
void onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) override; void onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) override;
void onConnectionFailed(const std::string & errorMessage) override; void onConnectionFailed(const std::string & errorMessage) override;
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override; void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override; void onDisconnected(const std::shared_ptr<INetworkConnection> &) override;
void onTimer() override; void onTimer() override;
void applyPackOnLobbyScreen(CPackForLobby & pack); void applyPackOnLobbyScreen(CPackForLobby & pack);

View File

@ -21,21 +21,12 @@
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
#include "../../lib/MetaString.h" #include "../../lib/MetaString.h"
#include "../../lib/TextOperations.h" #include "../../lib/TextOperations.h"
#include "../../lib/network/NetworkClient.h"
GlobalLobbyClient::~GlobalLobbyClient() GlobalLobbyClient::~GlobalLobbyClient() = default;
{
networkClient->stop();
networkThread->join();
}
GlobalLobbyClient::GlobalLobbyClient() GlobalLobbyClient::GlobalLobbyClient(const std::unique_ptr<INetworkHandler> & handler)
: networkClient(std::make_unique<NetworkClient>(*this)) : networkClient(handler->createClientTCP(*this))
{ {}
networkThread = std::make_unique<boost::thread>([this](){
networkClient->run();
});
}
static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0) static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
{ {
@ -46,7 +37,7 @@ static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
return TextOperations::getFormattedTimeLocal(std::chrono::system_clock::to_time_t(timeNowChrono)); return TextOperations::getFormattedTimeLocal(std::chrono::system_clock::to_time_t(timeNowChrono));
} }
void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message)
{ {
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex); boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
@ -158,7 +149,7 @@ void GlobalLobbyClient::receiveActiveAccounts(const JsonNode & json)
//} //}
} }
void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> &)
{ {
JsonNode toSend; JsonNode toSend;
@ -198,17 +189,12 @@ void GlobalLobbyClient::onConnectionFailed(const std::string & errorMessage)
loginWindowPtr->onConnectionFailed(errorMessage); loginWindowPtr->onConnectionFailed(errorMessage);
} }
void GlobalLobbyClient::onDisconnected(const std::shared_ptr<NetworkConnection> &) void GlobalLobbyClient::onDisconnected(const std::shared_ptr<INetworkConnection> &)
{ {
GH.windows().popWindows(1); GH.windows().popWindows(1);
CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {}); CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
} }
void GlobalLobbyClient::onTimer()
{
// no-op
}
void GlobalLobbyClient::sendMessage(const JsonNode & data) void GlobalLobbyClient::sendMessage(const JsonNode & data)
{ {
std::string payloadString = data.toJson(true); std::string payloadString = data.toJson(true);

View File

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "../../lib/network/NetworkListener.h" #include "../../lib/network/NetworkInterface.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
class JsonNode; class JsonNode;
@ -20,18 +20,16 @@ class GlobalLobbyWindow;
class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
{ {
std::unique_ptr<boost::thread> networkThread; std::unique_ptr<INetworkClient> networkClient;
std::unique_ptr<NetworkClient> networkClient;
std::weak_ptr<GlobalLobbyLoginWindow> loginWindow; std::weak_ptr<GlobalLobbyLoginWindow> loginWindow;
std::weak_ptr<GlobalLobbyWindow> lobbyWindow; std::weak_ptr<GlobalLobbyWindow> lobbyWindow;
std::shared_ptr<GlobalLobbyWindow> lobbyWindowLock; // helper strong reference to prevent window destruction on closing std::shared_ptr<GlobalLobbyWindow> lobbyWindowLock; // helper strong reference to prevent window destruction on closing
void onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) override; void onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) override;
void onConnectionFailed(const std::string & errorMessage) override; void onConnectionFailed(const std::string & errorMessage) override;
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override; void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override; void onDisconnected(const std::shared_ptr<INetworkConnection> &) override;
void onTimer() override;
void sendClientRegister(); void sendClientRegister();
void sendClientLogin(); void sendClientLogin();
@ -44,7 +42,7 @@ class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
void receiveActiveAccounts(const JsonNode & json); void receiveActiveAccounts(const JsonNode & json);
public: public:
explicit GlobalLobbyClient(); explicit GlobalLobbyClient(const std::unique_ptr<INetworkHandler> & handler);
~GlobalLobbyClient(); ~GlobalLobbyClient();
void sendMessage(const JsonNode & data); void sendMessage(const JsonNode & data);

View File

@ -130,7 +130,10 @@ void InterfaceObjectConfigurable::build(const JsonNode &config)
for(const auto & item : items->Vector()) for(const auto & item : items->Vector())
addWidget(item["name"].String(), buildWidget(item)); addWidget(item["name"].String(), buildWidget(item));
// load only if set
if (!config["width"].isNull())
pos.w = config["width"].Integer(); pos.w = config["width"].Integer();
if (!config["height"].isNull())
pos.h = config["height"].Integer(); pos.h = config["height"].Integer();
} }

View File

@ -126,6 +126,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/network/NetworkClient.cpp ${MAIN_LIB_DIR}/network/NetworkClient.cpp
${MAIN_LIB_DIR}/network/NetworkConnection.cpp ${MAIN_LIB_DIR}/network/NetworkConnection.cpp
${MAIN_LIB_DIR}/network/NetworkHandler.cpp
${MAIN_LIB_DIR}/network/NetworkServer.cpp ${MAIN_LIB_DIR}/network/NetworkServer.cpp
${MAIN_LIB_DIR}/networkPacks/NetPacksLib.cpp ${MAIN_LIB_DIR}/networkPacks/NetPacksLib.cpp
@ -478,7 +479,8 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/network/NetworkClient.h ${MAIN_LIB_DIR}/network/NetworkClient.h
${MAIN_LIB_DIR}/network/NetworkConnection.h ${MAIN_LIB_DIR}/network/NetworkConnection.h
${MAIN_LIB_DIR}/network/NetworkDefines.h ${MAIN_LIB_DIR}/network/NetworkDefines.h
${MAIN_LIB_DIR}/network/NetworkListener.h ${MAIN_LIB_DIR}/network/NetworkHandler.h
${MAIN_LIB_DIR}/network/NetworkInterface.h
${MAIN_LIB_DIR}/network/NetworkServer.h ${MAIN_LIB_DIR}/network/NetworkServer.h
${MAIN_LIB_DIR}/networkPacks/ArtifactLocation.h ${MAIN_LIB_DIR}/networkPacks/ArtifactLocation.h

View File

@ -13,9 +13,9 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
NetworkClient::NetworkClient(INetworkClientListener & listener) NetworkClient::NetworkClient(INetworkClientListener & listener, const std::shared_ptr<NetworkContext> & context)
: io(new NetworkService) : io(context)
, socket(new NetworkSocket(*io)) , socket(std::make_shared<NetworkSocket>(*context))
, listener(listener) , listener(listener)
{ {
} }
@ -39,54 +39,29 @@ void NetworkClient::onConnected(const boost::system::error_code & ec)
return; return;
} }
connection = std::make_shared<NetworkConnection>(socket, *this); connection = std::make_shared<NetworkConnection>(*this, socket);
connection->start(); connection->start();
listener.onConnectionEstablished(connection); listener.onConnectionEstablished(connection);
} }
void NetworkClient::run()
{
boost::asio::executor_work_guard<decltype(io->get_executor())> work{io->get_executor()};
io->run();
}
void NetworkClient::poll()
{
io->poll();
}
void NetworkClient::stop()
{
io->stop();
}
bool NetworkClient::isConnected() const bool NetworkClient::isConnected() const
{ {
return connection != nullptr; return connection != nullptr;
} }
void NetworkClient::setTimer(std::chrono::milliseconds duration)
{
auto timer = std::make_shared<NetworkTimer>(*io, duration);
timer->async_wait([this, timer](const boost::system::error_code& error){
if (!error)
listener.onTimer();
});
}
void NetworkClient::sendPacket(const std::vector<uint8_t> & message) void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
{ {
connection->sendPacket(message); connection->sendPacket(message);
} }
void NetworkClient::onDisconnected(const std::shared_ptr<NetworkConnection> & connection) void NetworkClient::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
{ {
this->connection.reset(); this->connection.reset();
listener.onDisconnected(connection); 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<INetworkConnection> & connection, const std::vector<uint8_t> & message)
{ {
listener.onPacketReceived(connection, message); listener.onPacketReceived(connection, message);
} }

View File

@ -10,15 +10,14 @@
#pragma once #pragma once
#include "NetworkDefines.h" #include "NetworkDefines.h"
#include "NetworkListener.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
class NetworkConnection; class NetworkConnection;
class DLL_LINKAGE NetworkClient : boost::noncopyable, public INetworkConnectionListener class NetworkClient : public INetworkConnectionListener, public INetworkClient
{ {
std::shared_ptr<NetworkService> io; std::shared_ptr<NetworkContext> io;
std::shared_ptr<NetworkSocket> socket; std::shared_ptr<NetworkSocket> socket;
std::shared_ptr<NetworkConnection> connection; std::shared_ptr<NetworkConnection> connection;
@ -26,22 +25,17 @@ class DLL_LINKAGE NetworkClient : boost::noncopyable, public INetworkConnectionL
void onConnected(const boost::system::error_code & ec); void onConnected(const boost::system::error_code & ec);
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override; void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override; void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
public: public:
NetworkClient(INetworkClientListener & listener); NetworkClient(INetworkClientListener & listener, const std::shared_ptr<NetworkContext> & context);
virtual ~NetworkClient() = default;
bool isConnected() const; bool isConnected() const override;
void setTimer(std::chrono::milliseconds duration); void sendPacket(const std::vector<uint8_t> & message) override;
void sendPacket(const std::vector<uint8_t> & message);
void start(const std::string & host, uint16_t port); void start(const std::string & host, uint16_t port) override;
void run();
void poll();
void stop();
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -12,7 +12,7 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
NetworkConnection::NetworkConnection(const std::shared_ptr<NetworkSocket> & socket, INetworkConnectionListener & listener) NetworkConnection::NetworkConnection(INetworkConnectionListener & listener, const std::shared_ptr<NetworkSocket> & socket)
: socket(socket) : socket(socket)
, listener(listener) , listener(listener)
{ {

View File

@ -10,11 +10,10 @@
#pragma once #pragma once
#include "NetworkDefines.h" #include "NetworkDefines.h"
#include "NetworkListener.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE NetworkConnection :public std::enable_shared_from_this<NetworkConnection>, boost::noncopyable class NetworkConnection : public INetworkConnection, public std::enable_shared_from_this<NetworkConnection>
{ {
static const int messageHeaderSize = sizeof(uint32_t); static const int messageHeaderSize = sizeof(uint32_t);
static const int messageMaxSize = 64 * 1024 * 1024; // 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
@ -29,10 +28,10 @@ class DLL_LINKAGE NetworkConnection :public std::enable_shared_from_this<Network
uint32_t readPacketSize(); uint32_t readPacketSize();
public: public:
NetworkConnection(const std::shared_ptr<NetworkSocket> & socket, INetworkConnectionListener & listener); NetworkConnection(INetworkConnectionListener & listener, const std::shared_ptr<NetworkSocket> & socket);
void start(); void start();
void sendPacket(const std::vector<uint8_t> & message); void sendPacket(const std::vector<uint8_t> & message) override;
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -11,9 +11,11 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "NetworkInterface.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
using NetworkService = boost::asio::io_service; using NetworkContext = boost::asio::io_service;
using NetworkSocket = boost::asio::ip::tcp::socket; using NetworkSocket = boost::asio::ip::tcp::socket;
using NetworkAcceptor = boost::asio::ip::tcp::acceptor; using NetworkAcceptor = boost::asio::ip::tcp::acceptor;
using NetworkBuffer = boost::asio::streambuf; using NetworkBuffer = boost::asio::streambuf;

View File

@ -0,0 +1,57 @@
/*
* NetworkHandler.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 "NetworkHandler.h"
#include "NetworkClient.h"
#include "NetworkServer.h"
VCMI_LIB_NAMESPACE_BEGIN
std::unique_ptr<INetworkHandler> INetworkHandler::createHandler()
{
return std::make_unique<NetworkHandler>();
}
NetworkHandler::NetworkHandler()
: io(std::make_shared<NetworkContext>())
{}
std::unique_ptr<INetworkServer> NetworkHandler::createServerTCP(INetworkServerListener & listener)
{
return std::make_unique<NetworkServer>(listener, io);
}
std::unique_ptr<INetworkClient> NetworkHandler::createClientTCP(INetworkClientListener & listener)
{
return std::make_unique<NetworkClient>(listener, io);
}
void NetworkHandler::run()
{
boost::asio::executor_work_guard<decltype(io->get_executor())> work{io->get_executor()};
io->run();
}
void NetworkHandler::createTimer(INetworkTimerListener & listener, std::chrono::milliseconds duration)
{
auto timer = std::make_shared<NetworkTimer>(*io, duration);
timer->async_wait([&listener, timer](const boost::system::error_code& error){
if (!error)
listener.onTimer();
});
}
void NetworkHandler::stop()
{
io->stop();
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,31 @@
/*
* NetworkHandler.h, 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
*
*/
#pragma once
#include "NetworkDefines.h"
VCMI_LIB_NAMESPACE_BEGIN
class NetworkHandler : public INetworkHandler
{
std::shared_ptr<NetworkContext> io;
public:
NetworkHandler();
std::unique_ptr<INetworkServer> createServerTCP(INetworkServerListener & listener) override;
std::unique_ptr<INetworkClient> createClientTCP(INetworkClientListener & listener) override;
void createTimer(INetworkTimerListener & listener, std::chrono::milliseconds duration) override;
void run() override;
void stop() override;
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,104 @@
/*
* NetworkHandler.h, 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
*
*/
#pragma once
VCMI_LIB_NAMESPACE_BEGIN
/// Base class for connections with other services, either incoming or outgoing
class DLL_LINKAGE INetworkConnection : boost::noncopyable
{
public:
virtual ~INetworkConnection() = default;
virtual void sendPacket(const std::vector<uint8_t> & message) = 0;
};
using NetworkConnectionPtr = std::shared_ptr<INetworkConnection>;
using NetworkConnectionWeakPtr = std::weak_ptr<INetworkConnection>;
/// Base class for outgoing connections support
class DLL_LINKAGE INetworkClient : boost::noncopyable
{
public:
virtual ~INetworkClient() = default;
virtual bool isConnected() const = 0;
virtual void sendPacket(const std::vector<uint8_t> & message) = 0;
virtual void start(const std::string & host, uint16_t port) = 0;
};
/// Base class for incoming connections support
class DLL_LINKAGE INetworkServer : boost::noncopyable
{
public:
virtual ~INetworkServer() = default;
virtual void sendPacket(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) = 0;
virtual void closeConnection(const std::shared_ptr<INetworkConnection> &) = 0;
virtual void start(uint16_t port) = 0;
};
/// Base interface that must be implemented by user of networking API to handle any connection callbacks
class DLL_LINKAGE INetworkConnectionListener
{
public:
virtual void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) = 0;
virtual void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) = 0;
virtual ~INetworkConnectionListener() = default;
};
/// Interface that must be implemented by user of networking API to handle outgoing connection callbacks
class DLL_LINKAGE INetworkClientListener : public INetworkConnectionListener
{
public:
virtual void onConnectionFailed(const std::string & errorMessage) = 0;
virtual void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) = 0;
};
/// Interface that must be implemented by user of networking API to handle incoming connection callbacks
class DLL_LINKAGE INetworkServerListener : public INetworkConnectionListener
{
public:
virtual void onNewConnection(const std::shared_ptr<INetworkConnection> &) = 0;
};
/// Interface that must be implemented by user of networking API to handle timers on network thread
class DLL_LINKAGE INetworkTimerListener
{
public:
virtual ~INetworkTimerListener() = default;
virtual void onTimer() = 0;
};
/// Main class for handling of all network activity
class DLL_LINKAGE INetworkHandler : boost::noncopyable
{
public:
virtual ~INetworkHandler() = default;
/// Constructs default implementation
static std::unique_ptr<INetworkHandler> createHandler();
/// Creates an instance of TCP server that allows to receiving connections on a local port
virtual std::unique_ptr<INetworkServer> createServerTCP(INetworkServerListener & listener) = 0;
/// Creates an instance of TCP client that allows to establish single outgoing connection to a remote port
virtual std::unique_ptr<INetworkClient> createClientTCP(INetworkClientListener & listener) = 0;
/// Creates a timer that will be called once, after specified interval has passed
virtual void createTimer(INetworkTimerListener & listener, std::chrono::milliseconds duration) = 0;
/// Starts network processing on this thread. Does not returns until networking processing has been terminated
virtual void run() = 0;
virtual void stop() = 0;
};
VCMI_LIB_NAMESPACE_END

View File

@ -1,56 +0,0 @@
/*
* NetworkListener.h, 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
*
*/
#pragma once
VCMI_LIB_NAMESPACE_BEGIN
class NetworkConnection;
class NetworkServer;
class NetworkClient;
using NetworkConnectionPtr = std::shared_ptr<NetworkConnection>;
using NetworkConnectionWeakPtr = std::weak_ptr<NetworkConnection>;
class DLL_LINKAGE INetworkConnectionListener
{
friend class NetworkConnection;
protected:
virtual void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) = 0;
virtual void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) = 0;
public:
virtual ~INetworkConnectionListener() = default;
};
class DLL_LINKAGE INetworkServerListener : public INetworkConnectionListener
{
friend class NetworkServer;
protected:
virtual void onNewConnection(const std::shared_ptr<NetworkConnection> &) = 0;
virtual void onTimer() = 0;
public:
virtual ~INetworkServerListener() = default;
};
class DLL_LINKAGE INetworkClientListener : public INetworkConnectionListener
{
friend class NetworkClient;
protected:
virtual void onConnectionFailed(const std::string & errorMessage) = 0;
virtual void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) = 0;
virtual void onTimer() = 0;
public:
virtual ~INetworkClientListener() = default;
};
VCMI_LIB_NAMESPACE_END

View File

@ -13,16 +13,15 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
NetworkServer::NetworkServer(INetworkServerListener & listener) NetworkServer::NetworkServer(INetworkServerListener & listener, const std::shared_ptr<NetworkContext> & context)
: listener(listener) : listener(listener)
, io(context)
{ {
} }
void NetworkServer::start(uint16_t port) void NetworkServer::start(uint16_t port)
{ {
io = std::make_shared<boost::asio::io_service>();
acceptor = std::make_shared<NetworkAcceptor>(*io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)); acceptor = std::make_shared<NetworkAcceptor>(*io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
startAsyncAccept(); startAsyncAccept();
} }
@ -32,16 +31,6 @@ void NetworkServer::startAsyncAccept()
acceptor->async_accept(*upcomingConnection, std::bind(&NetworkServer::connectionAccepted, this, upcomingConnection, _1)); acceptor->async_accept(*upcomingConnection, std::bind(&NetworkServer::connectionAccepted, this, upcomingConnection, _1));
} }
void NetworkServer::run()
{
io->run();
}
void NetworkServer::run(std::chrono::milliseconds duration)
{
io->run_for(duration);
}
void NetworkServer::connectionAccepted(std::shared_ptr<NetworkSocket> upcomingConnection, const boost::system::error_code & ec) void NetworkServer::connectionAccepted(std::shared_ptr<NetworkSocket> upcomingConnection, const boost::system::error_code & ec)
{ {
if(ec) if(ec)
@ -50,44 +39,34 @@ void NetworkServer::connectionAccepted(std::shared_ptr<NetworkSocket> upcomingCo
} }
logNetwork->info("We got a new connection! :)"); logNetwork->info("We got a new connection! :)");
auto connection = std::make_shared<NetworkConnection>(upcomingConnection, *this); auto connection = std::make_shared<NetworkConnection>(*this, upcomingConnection);
connections.insert(connection); connections.insert(connection);
connection->start(); connection->start();
listener.onNewConnection(connection); listener.onNewConnection(connection);
startAsyncAccept(); startAsyncAccept();
} }
void NetworkServer::sendPacket(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) void NetworkServer::sendPacket(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
{ {
connection->sendPacket(message); connection->sendPacket(message);
} }
void NetworkServer::closeConnection(const std::shared_ptr<NetworkConnection> & connection) void NetworkServer::closeConnection(const std::shared_ptr<INetworkConnection> & connection)
{ {
assert(connections.count(connection)); assert(connections.count(connection));
connections.erase(connection); connections.erase(connection);
} }
void NetworkServer::onDisconnected(const std::shared_ptr<NetworkConnection> & connection) void NetworkServer::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
{ {
assert(connections.count(connection)); assert(connections.count(connection));
connections.erase(connection); connections.erase(connection);
listener.onDisconnected(connection); listener.onDisconnected(connection);
} }
void NetworkServer::onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) void NetworkServer::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
{ {
listener.onPacketReceived(connection, message); listener.onPacketReceived(connection, message);
} }
void NetworkServer::setTimer(std::chrono::milliseconds duration)
{
auto timer = std::make_shared<NetworkTimer>(*io, duration);
timer->async_wait([this, timer](const boost::system::error_code& error){
if (!error)
listener.onTimer();
});
}
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -10,35 +10,29 @@
#pragma once #pragma once
#include "NetworkDefines.h" #include "NetworkDefines.h"
#include "NetworkListener.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
class NetworkConnection; class NetworkServer : public INetworkConnectionListener, public INetworkServer
class DLL_LINKAGE NetworkServer : boost::noncopyable, public INetworkConnectionListener
{ {
std::shared_ptr<NetworkService> io; std::shared_ptr<NetworkContext> io;
std::shared_ptr<NetworkAcceptor> acceptor; std::shared_ptr<NetworkAcceptor> acceptor;
std::set<std::shared_ptr<NetworkConnection>> connections; std::set<std::shared_ptr<INetworkConnection>> connections;
INetworkServerListener & listener; INetworkServerListener & listener;
void connectionAccepted(std::shared_ptr<NetworkSocket>, const boost::system::error_code & ec); void connectionAccepted(std::shared_ptr<NetworkSocket>, const boost::system::error_code & ec);
void startAsyncAccept(); void startAsyncAccept();
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override; void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override; void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
public: public:
explicit NetworkServer(INetworkServerListener & listener); NetworkServer(INetworkServerListener & listener, const std::shared_ptr<NetworkContext> & context);
void sendPacket(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message); void sendPacket(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) override;
void closeConnection(const std::shared_ptr<NetworkConnection> &); void closeConnection(const std::shared_ptr<INetworkConnection> &) override;
void setTimer(std::chrono::milliseconds duration);
void start(uint16_t port); void start(uint16_t port) override;
void run(std::chrono::milliseconds duration);
void run();
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -14,7 +14,7 @@
#include "BinarySerializer.h" #include "BinarySerializer.h"
#include "../networkPacks/NetPacksBase.h" #include "../networkPacks/NetPacksBase.h"
#include "../network/NetworkConnection.h" #include "../network/NetworkInterface.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@ -55,7 +55,7 @@ int ConnectionPackReader::read(void * data, unsigned size)
return size; return size;
} }
CConnection::CConnection(std::weak_ptr<NetworkConnection> networkConnection) CConnection::CConnection(std::weak_ptr<INetworkConnection> networkConnection)
: networkConnection(networkConnection) : networkConnection(networkConnection)
, packReader(std::make_unique<ConnectionPackReader>()) , packReader(std::make_unique<ConnectionPackReader>())
, packWriter(std::make_unique<ConnectionPackWriter>()) , packWriter(std::make_unique<ConnectionPackWriter>())
@ -100,7 +100,7 @@ CPack * CConnection::retrievePack(const std::vector<uint8_t> & data)
return result; return result;
} }
bool CConnection::isMyConnection(const std::shared_ptr<NetworkConnection> & otherConnection) const bool CConnection::isMyConnection(const std::shared_ptr<INetworkConnection> & otherConnection) const
{ {
return otherConnection != nullptr && networkConnection.lock() == otherConnection; return otherConnection != nullptr && networkConnection.lock() == otherConnection;
} }

View File

@ -14,7 +14,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class BinaryDeserializer; class BinaryDeserializer;
class BinarySerializer; class BinarySerializer;
struct CPack; struct CPack;
class NetworkConnection; class INetworkConnection;
class ConnectionPackReader; class ConnectionPackReader;
class ConnectionPackWriter; class ConnectionPackWriter;
class CGameState; class CGameState;
@ -24,7 +24,7 @@ class CGameState;
class DLL_LINKAGE CConnection : boost::noncopyable 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<INetworkConnection> networkConnection;
std::unique_ptr<ConnectionPackReader> packReader; std::unique_ptr<ConnectionPackReader> packReader;
std::unique_ptr<ConnectionPackWriter> packWriter; std::unique_ptr<ConnectionPackWriter> packWriter;
@ -39,12 +39,12 @@ class DLL_LINKAGE CConnection : boost::noncopyable
void enableSmartVectorMemberSerializatoin(); void enableSmartVectorMemberSerializatoin();
public: public:
bool isMyConnection(const std::shared_ptr<NetworkConnection> & otherConnection) const; bool isMyConnection(const std::shared_ptr<INetworkConnection> & otherConnection) const;
std::string uuid; std::string uuid;
int connectionID; int connectionID;
CConnection(std::weak_ptr<NetworkConnection> networkConnection); CConnection(std::weak_ptr<INetworkConnection> networkConnection);
~CConnection(); ~CConnection();
void sendPack(const CPack * pack); void sendPack(const CPack * pack);

View File

@ -13,8 +13,6 @@
#include "LobbyDatabase.h" #include "LobbyDatabase.h"
#include "../lib/JsonNode.h" #include "../lib/JsonNode.h"
#include "../lib/network/NetworkConnection.h"
#include "../lib/network/NetworkServer.h"
#include <boost/uuid/uuid_generators.hpp> #include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_io.hpp>
@ -199,11 +197,6 @@ void LobbyServer::sendChatMessage(const NetworkConnectionPtr & target, const std
sendMessage(target, reply); sendMessage(target, reply);
} }
void LobbyServer::onTimer()
{
// no-op
}
void LobbyServer::onNewConnection(const NetworkConnectionPtr & connection) void LobbyServer::onNewConnection(const NetworkConnectionPtr & connection)
{ {
// no-op - waiting for incoming data // no-op - waiting for incoming data
@ -544,7 +537,8 @@ LobbyServer::~LobbyServer() = default;
LobbyServer::LobbyServer(const boost::filesystem::path & databasePath) LobbyServer::LobbyServer(const boost::filesystem::path & databasePath)
: database(new LobbyDatabase(databasePath)) : database(new LobbyDatabase(databasePath))
, networkServer(new NetworkServer(*this)) , networkHandler(INetworkHandler::createHandler())
, networkServer(networkHandler->createServerTCP(*this))
{ {
} }
@ -555,5 +549,5 @@ void LobbyServer::start(uint16_t port)
void LobbyServer::run() void LobbyServer::run()
{ {
networkServer->run(); networkHandler->run();
} }

View File

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "../lib/network/NetworkListener.h" #include "../lib/network/NetworkInterface.h"
#include "LobbyDefines.h" #include "LobbyDefines.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@ -35,12 +35,12 @@ class LobbyServer : public INetworkServerListener
{ {
std::string accountID; std::string accountID;
std::string roomID; std::string roomID;
std::weak_ptr<NetworkConnection> accountConnection; std::weak_ptr<INetworkConnection> accountConnection;
std::weak_ptr<NetworkConnection> roomConnection; std::weak_ptr<INetworkConnection> roomConnection;
}; };
/// list of connected proxies. All messages received from (key) will be redirected to (value) connection /// list of connected proxies. All messages received from (key) will be redirected to (value) connection
std::map<NetworkConnectionPtr, std::weak_ptr<NetworkConnection>> activeProxies; std::map<NetworkConnectionPtr, std::weak_ptr<INetworkConnection>> activeProxies;
/// list of half-established proxies from server that are still waiting for client to connect /// list of half-established proxies from server that are still waiting for client to connect
std::vector<AwaitingProxyState> awaitingProxies; std::vector<AwaitingProxyState> awaitingProxies;
@ -52,7 +52,8 @@ class LobbyServer : public INetworkServerListener
std::map<NetworkConnectionPtr, GameRoomState> activeGameRooms; std::map<NetworkConnectionPtr, GameRoomState> activeGameRooms;
std::unique_ptr<LobbyDatabase> database; std::unique_ptr<LobbyDatabase> database;
std::unique_ptr<NetworkServer> networkServer; std::unique_ptr<INetworkHandler> networkHandler;
std::unique_ptr<INetworkServer> networkServer;
std::string sanitizeChatMessage(const std::string & inputString) const; std::string sanitizeChatMessage(const std::string & inputString) const;
bool isAccountNameValid(const std::string & accountName); bool isAccountNameValid(const std::string & accountName);
@ -63,7 +64,6 @@ class LobbyServer : public INetworkServerListener
void onNewConnection(const NetworkConnectionPtr & connection) override; void onNewConnection(const NetworkConnectionPtr & connection) override;
void onDisconnected(const NetworkConnectionPtr & connection) override; void onDisconnected(const NetworkConnectionPtr & connection) override;
void onPacketReceived(const NetworkConnectionPtr & connection, const std::vector<uint8_t> & message) override; void onPacketReceived(const NetworkConnectionPtr & connection, const std::vector<uint8_t> & message) override;
void onTimer() override;
void sendMessage(const NetworkConnectionPtr & target, const JsonNode & json); void sendMessage(const NetworkConnectionPtr & target, const JsonNode & json);

View File

@ -36,8 +36,6 @@
#include "CGameHandler.h" #include "CGameHandler.h"
#include "processors/PlayerMessageProcessor.h" #include "processors/PlayerMessageProcessor.h"
#include "../lib/mapping/CMapInfo.h" #include "../lib/mapping/CMapInfo.h"
#include "../lib/network/NetworkServer.h"
#include "../lib/network/NetworkClient.h"
#include "../lib/GameConstants.h" #include "../lib/GameConstants.h"
#include "../lib/logging/CBasicLogConfigurator.h" #include "../lib/logging/CBasicLogConfigurator.h"
#include "../lib/CConfigHandler.h" #include "../lib/CConfigHandler.h"
@ -164,14 +162,15 @@ CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts)
port = cmdLineOptions["port"].as<uint16_t>(); port = cmdLineOptions["port"].as<uint16_t>();
logNetwork->info("Port %d will be used", port); logNetwork->info("Port %d will be used", port);
networkServer = std::make_unique<NetworkServer>(*this); networkHandler = INetworkHandler::createHandler();
networkServer = networkHandler->createServerTCP(*this);
networkServer->start(port); networkServer->start(port);
logNetwork->info("Listening for connections at port %d", port); logNetwork->info("Listening for connections at port %d", port);
} }
CVCMIServer::~CVCMIServer() = default; CVCMIServer::~CVCMIServer() = default;
void CVCMIServer::onNewConnection(const std::shared_ptr<NetworkConnection> & connection) void CVCMIServer::onNewConnection(const std::shared_ptr<INetworkConnection> & connection)
{ {
if (activeConnections.empty()) if (activeConnections.empty())
establishOutgoingConnection(); establishOutgoingConnection();
@ -187,7 +186,7 @@ void CVCMIServer::onNewConnection(const std::shared_ptr<NetworkConnection> & con
} }
} }
void CVCMIServer::onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) void CVCMIServer::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
{ {
std::shared_ptr<CConnection> c = findConnection(connection); std::shared_ptr<CConnection> c = findConnection(connection);
auto pack = c->retrievePack(message); auto pack = c->retrievePack(message);
@ -201,7 +200,7 @@ void CVCMIServer::onConnectionFailed(const std::string & errorMessage)
//TODO: handle failure to connect to lobby //TODO: handle failure to connect to lobby
} }
void CVCMIServer::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) void CVCMIServer::onConnectionEstablished(const std::shared_ptr<INetworkConnection> &)
{ {
//TODO: handle connection to lobby - login? //TODO: handle connection to lobby - login?
} }
@ -216,7 +215,7 @@ EServerState CVCMIServer::getState() const
return state; return state;
} }
std::shared_ptr<CConnection> CVCMIServer::findConnection(const std::shared_ptr<NetworkConnection> & netConnection) std::shared_ptr<CConnection> CVCMIServer::findConnection(const std::shared_ptr<INetworkConnection> & netConnection)
{ {
for (auto const & gameConnection : activeConnections) for (auto const & gameConnection : activeConnections)
{ {
@ -236,7 +235,7 @@ void CVCMIServer::run()
vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "onServerReady"); vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "onServerReady");
} }
#endif #endif
networkServer->run(); networkHandler->run();
} }
void CVCMIServer::onTimer() void CVCMIServer::onTimer()
@ -258,7 +257,7 @@ void CVCMIServer::onTimer()
if (msDelta.count()) if (msDelta.count())
gh->tick(msDelta.count()); gh->tick(msDelta.count());
networkServer->setTimer(serverUpdateInterval); networkHandler->createTimer(*this, serverUpdateInterval);
} }
void CVCMIServer::establishOutgoingConnection() void CVCMIServer::establishOutgoingConnection()
@ -269,7 +268,7 @@ void CVCMIServer::establishOutgoingConnection()
std::string hostname = settings["lobby"]["hostname"].String(); std::string hostname = settings["lobby"]["hostname"].String();
int16_t port = settings["lobby"]["port"].Integer(); int16_t port = settings["lobby"]["port"].Integer();
outgoingConnection = std::make_unique<NetworkClient>(*this); outgoingConnection = networkHandler->createClientTCP(*this);
outgoingConnection->start(hostname, port); outgoingConnection->start(hostname, port);
} }
@ -370,7 +369,7 @@ void CVCMIServer::startGameImmediately()
onTimer(); onTimer();
} }
void CVCMIServer::onDisconnected(const std::shared_ptr<NetworkConnection> & connection) void CVCMIServer::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
{ {
logNetwork->error("Network error receiving a pack. Connection has been closed"); logNetwork->error("Network error receiving a pack. Connection has been closed");
@ -998,7 +997,8 @@ static void handleCommandOptions(int argc, const char * argv[], boost::program_o
("help,h", "display help and exit") ("help,h", "display help and exit")
("version,v", "display version information and exit") ("version,v", "display version information and exit")
("run-by-client", "indicate that server launched by client on same machine") ("run-by-client", "indicate that server launched by client on same machine")
("port", po::value<ui16>(), "port at which server will listen to connections from client"); ("port", po::value<ui16>(), "port at which server will listen to connections from client")
("lobby", "start server in lobby mode in which server connects to a global lobby");
if(argc > 1) if(argc > 1)
{ {

View File

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "../lib/network/NetworkListener.h" #include "../lib/network/NetworkInterface.h"
#include "../lib/StartInfo.h" #include "../lib/StartInfo.h"
#include <boost/program_options/variables_map.hpp> #include <boost/program_options/variables_map.hpp>
@ -47,13 +47,15 @@ enum class EServerState : ui8
SHUTDOWN SHUTDOWN
}; };
class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkClientListener class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkClientListener, public INetworkTimerListener
{ {
std::unique_ptr<INetworkHandler> networkHandler;
/// Network server instance that receives and processes incoming connections on active socket /// Network server instance that receives and processes incoming connections on active socket
std::unique_ptr<NetworkServer> networkServer; std::unique_ptr<INetworkServer> networkServer;
/// Outgoing connection established by this server to game lobby for proxy mode (only in lobby game) /// Outgoing connection established by this server to game lobby for proxy mode (only in lobby game)
std::unique_ptr<NetworkClient> outgoingConnection; std::unique_ptr<INetworkClient> outgoingConnection;
std::chrono::steady_clock::time_point gameplayStartTime; std::chrono::steady_clock::time_point gameplayStartTime;
std::chrono::steady_clock::time_point lastTimerUpdateTime; std::chrono::steady_clock::time_point lastTimerUpdateTime;
@ -70,16 +72,16 @@ private:
EServerState state; EServerState state;
// INetworkListener impl // INetworkListener impl
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override; void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override; void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
void onNewConnection(const std::shared_ptr<NetworkConnection> &) override; void onNewConnection(const std::shared_ptr<INetworkConnection> &) override;
void onConnectionFailed(const std::string & errorMessage) override; void onConnectionFailed(const std::string & errorMessage) override;
void onConnectionEstablished(const std::shared_ptr<NetworkConnection> &) override; void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
void onTimer() override; void onTimer() override;
void establishOutgoingConnection(); void establishOutgoingConnection();
std::shared_ptr<CConnection> findConnection(const std::shared_ptr<NetworkConnection> &); std::shared_ptr<CConnection> findConnection(const std::shared_ptr<INetworkConnection> &);
int currentClientId; int currentClientId;
ui8 currentPlayerId; ui8 currentPlayerId;