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:
parent
476a05fed3
commit
80e960bc8e
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -130,8 +130,11 @@ 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));
|
||||||
|
|
||||||
pos.w = config["width"].Integer();
|
// load only if set
|
||||||
pos.h = config["height"].Integer();
|
if (!config["width"].isNull())
|
||||||
|
pos.w = config["width"].Integer();
|
||||||
|
if (!config["height"].isNull())
|
||||||
|
pos.h = config["height"].Integer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterfaceObjectConfigurable::addConditional(const std::string & name, bool active)
|
void InterfaceObjectConfigurable::addConditional(const std::string & name, bool active)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
57
lib/network/NetworkHandler.cpp
Normal file
57
lib/network/NetworkHandler.cpp
Normal 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
|
31
lib/network/NetworkHandler.h
Normal file
31
lib/network/NetworkHandler.h
Normal 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
|
104
lib/network/NetworkInterface.h
Normal file
104
lib/network/NetworkInterface.h
Normal 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
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user