mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Simplified networking API
This commit is contained in:
parent
9fb7d2817a
commit
709905b1a0
@ -138,9 +138,8 @@ CServerHandler::~CServerHandler()
|
||||
CServerHandler::CServerHandler()
|
||||
: state(EClientState::NONE)
|
||||
, networkHandler(INetworkHandler::createHandler())
|
||||
, networkClient(networkHandler->createClientTCP(*this))
|
||||
, applier(std::make_unique<CApplier<CBaseForLobbyApply>>())
|
||||
, lobbyClient(std::make_unique<GlobalLobbyClient>(networkHandler))
|
||||
, lobbyClient(std::make_unique<GlobalLobbyClient>())
|
||||
, client(nullptr)
|
||||
, loadMode(0)
|
||||
, campaignStateToSend(nullptr)
|
||||
@ -268,7 +267,7 @@ void CServerHandler::connectToServer(const std::string & addr, const ui16 port)
|
||||
serverPort->Integer() = port;
|
||||
}
|
||||
|
||||
networkClient->start(addr, port);
|
||||
networkHandler->connectToRemote(*this, addr, port);
|
||||
}
|
||||
|
||||
void CServerHandler::onConnectionFailed(const std::string & errorMessage)
|
||||
@ -296,11 +295,13 @@ void CServerHandler::onTimer()
|
||||
}
|
||||
|
||||
assert(isServerLocal());
|
||||
networkClient->start(getLocalHostname(), getLocalPort());
|
||||
networkHandler->connectToRemote(*this, getLocalHostname(), getLocalPort());
|
||||
}
|
||||
|
||||
void CServerHandler::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & netConnection)
|
||||
{
|
||||
networkConnection = netConnection;
|
||||
|
||||
logNetwork->info("Connection established");
|
||||
c = std::make_shared<CConnection>(netConnection);
|
||||
c->uuid = uuid;
|
||||
@ -868,8 +869,11 @@ void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection>
|
||||
}
|
||||
}
|
||||
|
||||
void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> &)
|
||||
void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
assert(networkConnection == connection);
|
||||
networkConnection.reset();
|
||||
|
||||
if(state == EClientState::DISCONNECTING)
|
||||
{
|
||||
logNetwork->info("Successfully closed connection to server, ending listening thread!");
|
||||
|
@ -86,8 +86,7 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien
|
||||
{
|
||||
friend class ApplyOnLobbyHandlerNetPackVisitor;
|
||||
|
||||
std::unique_ptr<INetworkHandler> networkHandler;
|
||||
std::unique_ptr<INetworkClient> networkClient;
|
||||
std::shared_ptr<INetworkConnection> networkConnection;
|
||||
std::unique_ptr<GlobalLobbyClient> lobbyClient;
|
||||
std::unique_ptr<CApplier<CBaseForLobbyApply>> applier;
|
||||
std::shared_ptr<CMapInfo> mapToStart;
|
||||
@ -113,6 +112,8 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien
|
||||
bool isServerLocal() const;
|
||||
|
||||
public:
|
||||
std::unique_ptr<INetworkHandler> networkHandler;
|
||||
|
||||
std::shared_ptr<CConnection> c;
|
||||
|
||||
std::atomic<EClientState> state;
|
||||
|
@ -17,17 +17,15 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../CServerHandler.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/MetaString.h"
|
||||
#include "../../lib/TextOperations.h"
|
||||
|
||||
GlobalLobbyClient::GlobalLobbyClient() = default;
|
||||
GlobalLobbyClient::~GlobalLobbyClient() = default;
|
||||
|
||||
GlobalLobbyClient::GlobalLobbyClient(const std::unique_ptr<INetworkHandler> & handler)
|
||||
: networkClient(handler->createClientTCP(*this))
|
||||
{}
|
||||
|
||||
static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
|
||||
{
|
||||
// FIXME: better/unified way to format date
|
||||
@ -149,8 +147,10 @@ void GlobalLobbyClient::receiveActiveAccounts(const JsonNode & json)
|
||||
//}
|
||||
}
|
||||
|
||||
void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> &)
|
||||
void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
networkConnection = connection;
|
||||
|
||||
JsonNode toSend;
|
||||
|
||||
std::string accountID = settings["lobby"]["accountID"].String();
|
||||
@ -189,8 +189,11 @@ void GlobalLobbyClient::onConnectionFailed(const std::string & errorMessage)
|
||||
loginWindowPtr->onConnectionFailed(errorMessage);
|
||||
}
|
||||
|
||||
void GlobalLobbyClient::onDisconnected(const std::shared_ptr<INetworkConnection> &)
|
||||
void GlobalLobbyClient::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
assert(connection == networkConnection);
|
||||
networkConnection.reset();
|
||||
|
||||
GH.windows().popWindows(1);
|
||||
CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
|
||||
}
|
||||
@ -205,19 +208,19 @@ void GlobalLobbyClient::sendMessage(const JsonNode & data)
|
||||
|
||||
std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
|
||||
|
||||
networkClient->sendPacket(payloadBuffer);
|
||||
networkConnection->sendPacket(payloadBuffer);
|
||||
}
|
||||
|
||||
void GlobalLobbyClient::connect()
|
||||
{
|
||||
std::string hostname = settings["lobby"]["hostname"].String();
|
||||
int16_t port = settings["lobby"]["port"].Integer();
|
||||
networkClient->start(hostname, port);
|
||||
CSH->networkHandler->connectToRemote(*this, hostname, port);
|
||||
}
|
||||
|
||||
bool GlobalLobbyClient::isConnected()
|
||||
{
|
||||
return networkClient->isConnected();
|
||||
return networkConnection != nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<GlobalLobbyLoginWindow> GlobalLobbyClient::createLoginWindow()
|
||||
|
@ -20,7 +20,7 @@ class GlobalLobbyWindow;
|
||||
|
||||
class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
|
||||
{
|
||||
std::unique_ptr<INetworkClient> networkClient;
|
||||
std::shared_ptr<INetworkConnection> networkConnection;
|
||||
|
||||
std::weak_ptr<GlobalLobbyLoginWindow> loginWindow;
|
||||
std::weak_ptr<GlobalLobbyWindow> lobbyWindow;
|
||||
@ -42,7 +42,7 @@ class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
|
||||
void receiveActiveAccounts(const JsonNode & json);
|
||||
|
||||
public:
|
||||
explicit GlobalLobbyClient(const std::unique_ptr<INetworkHandler> & handler);
|
||||
explicit GlobalLobbyClient();
|
||||
~GlobalLobbyClient();
|
||||
|
||||
void sendMessage(const JsonNode & data);
|
||||
|
@ -124,7 +124,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/modding/IdentifierStorage.cpp
|
||||
${MAIN_LIB_DIR}/modding/ModUtility.cpp
|
||||
|
||||
${MAIN_LIB_DIR}/network/NetworkClient.cpp
|
||||
${MAIN_LIB_DIR}/network/NetworkConnection.cpp
|
||||
${MAIN_LIB_DIR}/network/NetworkHandler.cpp
|
||||
${MAIN_LIB_DIR}/network/NetworkServer.cpp
|
||||
@ -476,7 +475,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/modding/ModUtility.h
|
||||
${MAIN_LIB_DIR}/modding/ModVerificationInfo.h
|
||||
|
||||
${MAIN_LIB_DIR}/network/NetworkClient.h
|
||||
${MAIN_LIB_DIR}/network/NetworkConnection.h
|
||||
${MAIN_LIB_DIR}/network/NetworkDefines.h
|
||||
${MAIN_LIB_DIR}/network/NetworkHandler.h
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* NetworkClient.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 "NetworkClient.h"
|
||||
#include "NetworkConnection.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
NetworkClient::NetworkClient(INetworkClientListener & listener, const std::shared_ptr<NetworkContext> & context)
|
||||
: io(context)
|
||||
, socket(std::make_shared<NetworkSocket>(*context))
|
||||
, listener(listener)
|
||||
{
|
||||
}
|
||||
|
||||
void NetworkClient::start(const std::string & host, uint16_t port)
|
||||
{
|
||||
if (isConnected())
|
||||
throw std::runtime_error("Attempting to connect while already connected!");
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(*io);
|
||||
auto endpoints = resolver.resolve(host, std::to_string(port));
|
||||
|
||||
boost::asio::async_connect(*socket, endpoints, std::bind(&NetworkClient::onConnected, this, _1));
|
||||
}
|
||||
|
||||
void NetworkClient::onConnected(const boost::system::error_code & ec)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
listener.onConnectionFailed(ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
connection = std::make_shared<NetworkConnection>(*this, socket);
|
||||
connection->start();
|
||||
|
||||
listener.onConnectionEstablished(connection);
|
||||
}
|
||||
|
||||
bool NetworkClient::isConnected() const
|
||||
{
|
||||
return connection != nullptr;
|
||||
}
|
||||
|
||||
void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
|
||||
{
|
||||
connection->sendPacket(message);
|
||||
}
|
||||
|
||||
void NetworkClient::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
this->connection.reset();
|
||||
listener.onDisconnected(connection);
|
||||
}
|
||||
|
||||
void NetworkClient::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
|
||||
{
|
||||
listener.onPacketReceived(connection, message);
|
||||
}
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* NetworkClient.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 NetworkConnection;
|
||||
|
||||
class NetworkClient : public INetworkConnectionListener, public INetworkClient
|
||||
{
|
||||
std::shared_ptr<NetworkContext> io;
|
||||
std::shared_ptr<NetworkSocket> socket;
|
||||
std::shared_ptr<NetworkConnection> connection;
|
||||
|
||||
INetworkClientListener & listener;
|
||||
|
||||
void onConnected(const boost::system::error_code & ec);
|
||||
|
||||
void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
|
||||
void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
||||
|
||||
public:
|
||||
NetworkClient(INetworkClientListener & listener, const std::shared_ptr<NetworkContext> & context);
|
||||
|
||||
bool isConnected() const override;
|
||||
|
||||
void sendPacket(const std::vector<uint8_t> & message) override;
|
||||
|
||||
void start(const std::string & host, uint16_t port) override;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -10,8 +10,8 @@
|
||||
#include "StdInc.h"
|
||||
#include "NetworkHandler.h"
|
||||
|
||||
#include "NetworkClient.h"
|
||||
#include "NetworkServer.h"
|
||||
#include "NetworkConnection.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -29,9 +29,23 @@ std::unique_ptr<INetworkServer> NetworkHandler::createServerTCP(INetworkServerLi
|
||||
return std::make_unique<NetworkServer>(listener, io);
|
||||
}
|
||||
|
||||
std::unique_ptr<INetworkClient> NetworkHandler::createClientTCP(INetworkClientListener & listener)
|
||||
void NetworkHandler::connectToRemote(INetworkClientListener & listener, const std::string & host, uint16_t port)
|
||||
{
|
||||
return std::make_unique<NetworkClient>(listener, io);
|
||||
auto socket = std::make_shared<NetworkSocket>(*io);
|
||||
boost::asio::ip::tcp::resolver resolver(*io);
|
||||
auto endpoints = resolver.resolve(host, std::to_string(port));
|
||||
boost::asio::async_connect(*socket, endpoints, [socket, &listener](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
listener.onConnectionFailed(error.message());
|
||||
return;
|
||||
}
|
||||
auto connection = std::make_shared<NetworkConnection>(listener, socket);
|
||||
connection->start();
|
||||
|
||||
listener.onConnectionEstablished(connection);
|
||||
});
|
||||
}
|
||||
|
||||
void NetworkHandler::run()
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
NetworkHandler();
|
||||
|
||||
std::unique_ptr<INetworkServer> createServerTCP(INetworkServerListener & listener) override;
|
||||
std::unique_ptr<INetworkClient> createClientTCP(INetworkClientListener & listener) override;
|
||||
void connectToRemote(INetworkClientListener & listener, const std::string & host, uint16_t port) override;
|
||||
void createTimer(INetworkTimerListener & listener, std::chrono::milliseconds duration) override;
|
||||
|
||||
void run() override;
|
||||
|
@ -30,7 +30,6 @@ public:
|
||||
|
||||
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
|
||||
@ -91,9 +90,13 @@ public:
|
||||
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;
|
||||
/// On success: INetworkTimerListener::onConnectionEstablished() will be called, established connection provided as parameter
|
||||
/// On failure: INetworkTimerListener::onConnectionFailed will be called with human-readable error message
|
||||
virtual void connectToRemote(INetworkClientListener & listener, const std::string & host, uint16_t port) = 0;
|
||||
|
||||
/// Creates a timer that will be called once, after specified interval has passed
|
||||
/// On success: INetworkTimerListener::onTimer() will be called
|
||||
/// On failure: no-op
|
||||
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
|
||||
|
@ -15,11 +15,10 @@
|
||||
|
||||
GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner)
|
||||
: owner(owner)
|
||||
, networkClient(owner.networkHandler->createClientTCP(*this))
|
||||
{
|
||||
std::string hostname = settings["lobby"]["hostname"].String();
|
||||
int16_t port = settings["lobby"]["port"].Integer();
|
||||
networkClient->start(hostname, port);
|
||||
owner.networkHandler->connectToRemote(*this, hostname, port);
|
||||
logGlobal->info("Connecting to lobby server");
|
||||
}
|
||||
|
||||
@ -38,6 +37,9 @@ void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnec
|
||||
if(json["type"].String() == "loginSuccess")
|
||||
return receiveLoginSuccess(json);
|
||||
|
||||
if(json["type"].String() == "accountJoinsRoom")
|
||||
return receiveAccountJoinsRoom(json);
|
||||
|
||||
throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String());
|
||||
}
|
||||
|
||||
@ -52,13 +54,19 @@ void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
|
||||
logGlobal->info("Succesfully connected to lobby server");
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
|
||||
{
|
||||
// TODO: establish new connection to lobby, login, and transfer connection to our owner
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::onConnectionFailed(const std::string & errorMessage)
|
||||
{
|
||||
throw std::runtime_error("Failed to connect to a lobby server!");
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetworkConnection> &)
|
||||
void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
controlConnection = connection;
|
||||
logGlobal->info("Connection to lobby server established");
|
||||
|
||||
JsonNode toSend;
|
||||
@ -78,5 +86,5 @@ void GlobalLobbyProcessor::sendMessage(const JsonNode & data)
|
||||
|
||||
std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
|
||||
|
||||
networkClient->sendPacket(payloadBuffer);
|
||||
controlConnection->sendPacket(payloadBuffer);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ class GlobalLobbyProcessor : public INetworkClientListener
|
||||
|
||||
std::shared_ptr<INetworkConnection> controlConnection;
|
||||
// std::set<std::shared_ptr<INetworkConnection>> proxyConnections;
|
||||
std::unique_ptr<INetworkClient> networkClient;
|
||||
|
||||
void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
|
||||
void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
||||
@ -34,6 +33,7 @@ class GlobalLobbyProcessor : public INetworkClientListener
|
||||
|
||||
void receiveLoginFailed(const JsonNode & json);
|
||||
void receiveLoginSuccess(const JsonNode & json);
|
||||
void receiveAccountJoinsRoom(const JsonNode & json);
|
||||
public:
|
||||
GlobalLobbyProcessor(CVCMIServer & owner);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user