mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-21 12:06:49 +02:00
intermediate connection
This commit is contained in:
parent
445f6c8598
commit
d3710b82ad
@ -11,6 +11,7 @@
|
|||||||
//
|
//
|
||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
|
|
||||||
|
#include <enet/enet.h>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <vcmi/scripting/Service.h>
|
#include <vcmi/scripting/Service.h>
|
||||||
@ -251,6 +252,11 @@ int main(int argc, char * argv[])
|
|||||||
console->start();
|
console->start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(enet_initialize() != 0)
|
||||||
|
{
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
const bfs::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Client_log.txt";
|
const bfs::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Client_log.txt";
|
||||||
logConfig = new CBasicLogConfigurator(logPath, console);
|
logConfig = new CBasicLogConfigurator(logPath, console);
|
||||||
logConfig->configureDefault();
|
logConfig->configureDefault();
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "../lib/serializer/Cast.h"
|
#include "../lib/serializer/Cast.h"
|
||||||
|
|
||||||
#include <vcmi/events/EventBus.h>
|
#include <vcmi/events/EventBus.h>
|
||||||
|
#include <enet/enet.h>
|
||||||
|
|
||||||
#ifdef VCMI_WINDOWS
|
#ifdef VCMI_WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -120,13 +121,16 @@ extern std::string NAME;
|
|||||||
CServerHandler::CServerHandler()
|
CServerHandler::CServerHandler()
|
||||||
: state(EClientState::NONE), mx(std::make_shared<boost::recursive_mutex>()), client(nullptr), loadMode(0), campaignStateToSend(nullptr), campaignServerRestartLock(false)
|
: state(EClientState::NONE), mx(std::make_shared<boost::recursive_mutex>()), client(nullptr), loadMode(0), campaignStateToSend(nullptr), campaignServerRestartLock(false)
|
||||||
{
|
{
|
||||||
enetClient = enet_host_create(NULL, 8, 2, 0, 0);
|
enetClient = enet_host_create(NULL, 1, 2, 0, 0);
|
||||||
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
|
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
|
||||||
//read from file to restore last session
|
//read from file to restore last session
|
||||||
if(!settings["server"]["uuid"].isNull() && !settings["server"]["uuid"].String().empty())
|
if(!settings["server"]["uuid"].isNull() && !settings["server"]["uuid"].String().empty())
|
||||||
uuid = settings["server"]["uuid"].String();
|
uuid = settings["server"]["uuid"].String();
|
||||||
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
|
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
|
||||||
registerTypesLobbyPacks(*applier);
|
registerTypesLobbyPacks(*applier);
|
||||||
|
|
||||||
|
threadPollClient = std::make_shared<boost::thread>(&CServerHandler::threadPoll, this);
|
||||||
|
threadPollClient->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
CServerHandler::~CServerHandler()
|
CServerHandler::~CServerHandler()
|
||||||
@ -175,6 +179,49 @@ void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std::
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServerHandler::threadPoll()
|
||||||
|
{
|
||||||
|
ENetEvent event;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
if(enet_host_service(enetClient, &event, 100) > 0)
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case ENET_EVENT_TYPE_CONNECT: {
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
if(c && c->getPeer() == event.peer)
|
||||||
|
{
|
||||||
|
state = EClientState::CONNECTING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ENET_EVENT_TYPE_RECEIVE: {
|
||||||
|
if(c && c->getPeer() == event.peer)
|
||||||
|
{
|
||||||
|
c->dispatch(event.packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
{
|
||||||
|
if(c && c->getPeer() == event.peer)
|
||||||
|
{
|
||||||
|
c.reset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CServerHandler::startLocalServerAndConnect()
|
void CServerHandler::startLocalServerAndConnect()
|
||||||
{
|
{
|
||||||
/*auto errorMsg = CGI->generaltexth->localizedTexts["server"]["errors"]["existingProcess"].String();
|
/*auto errorMsg = CGI->generaltexth->localizedTexts["server"]["errors"]["existingProcess"].String();
|
||||||
@ -272,7 +319,6 @@ void CServerHandler::startLocalServerAndConnect()
|
|||||||
|
|
||||||
void CServerHandler::justConnectToServer(const std::string & addr, const ui16 port)
|
void CServerHandler::justConnectToServer(const std::string & addr, const ui16 port)
|
||||||
{
|
{
|
||||||
state = EClientState::CONNECTING;
|
|
||||||
while(!c && state != EClientState::CONNECTION_CANCELLED)
|
while(!c && state != EClientState::CONNECTION_CANCELLED)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -296,6 +342,11 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(state != EClientState::CONNECTING)
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||||
|
|
||||||
|
c->init();
|
||||||
|
|
||||||
c->handler = std::make_shared<boost::thread>(&CServerHandler::threadHandleConnection, this);
|
c->handler = std::make_shared<boost::thread>(&CServerHandler::threadHandleConnection, this);
|
||||||
|
|
||||||
if(!addr.empty() && addr != getHostAddress())
|
if(!addr.empty() && addr != getHostAddress())
|
||||||
@ -781,9 +832,11 @@ void CServerHandler::threadHandleConnection()
|
|||||||
{
|
{
|
||||||
setThreadName("CServerHandler::threadHandleConnection");
|
setThreadName("CServerHandler::threadHandleConnection");
|
||||||
c->enterLobbyConnectionMode();
|
c->enterLobbyConnectionMode();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
while(!c->isOpen())
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||||
|
|
||||||
sendClientConnecting();
|
sendClientConnecting();
|
||||||
while(c->connected)
|
while(c->connected)
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,7 @@ class CServerHandler : public IServerAPI, public LobbyInfo
|
|||||||
|
|
||||||
void threadHandleConnection();
|
void threadHandleConnection();
|
||||||
void threadRunServer();
|
void threadRunServer();
|
||||||
|
void threadPoll();
|
||||||
void onServerFinished();
|
void onServerFinished();
|
||||||
void sendLobbyPack(const CPackForLobby & pack) const override;
|
void sendLobbyPack(const CPackForLobby & pack) const override;
|
||||||
|
|
||||||
@ -103,6 +104,7 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<CStopWatch> th;
|
std::unique_ptr<CStopWatch> th;
|
||||||
std::shared_ptr<boost::thread> threadRunLocalServer;
|
std::shared_ptr<boost::thread> threadRunLocalServer;
|
||||||
|
std::shared_ptr<boost::thread> threadPollClient;
|
||||||
|
|
||||||
std::shared_ptr<CConnection> c;
|
std::shared_ptr<CConnection> c;
|
||||||
CClient * client;
|
CClient * client;
|
||||||
|
@ -46,6 +46,8 @@ void CConnection::init()
|
|||||||
std::string pom;
|
std::string pom;
|
||||||
//we got connection
|
//we got connection
|
||||||
oser & std::string("Aiya!\n") & name & uuid & myEndianess; //identify ourselves
|
oser & std::string("Aiya!\n") & name & uuid & myEndianess; //identify ourselves
|
||||||
|
enet_host_flush(client);
|
||||||
|
|
||||||
iser & pom & pom & contactUuid & contactEndianess;
|
iser & pom & pom & contactUuid & contactEndianess;
|
||||||
logNetwork->info("Established connection with %s. UUID: %s", pom, contactUuid);
|
logNetwork->info("Established connection with %s. UUID: %s", pom, contactUuid);
|
||||||
mutexRead = std::make_shared<boost::mutex>();
|
mutexRead = std::make_shared<boost::mutex>();
|
||||||
@ -55,13 +57,13 @@ void CConnection::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CConnection::CConnection(ENetHost * _client, ENetPeer * _peer, std::string Name, std::string UUID)
|
CConnection::CConnection(ENetHost * _client, ENetPeer * _peer, std::string Name, std::string UUID)
|
||||||
: client(_client), peer(_peer), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0)
|
: client(_client), peer(_peer), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false)
|
||||||
{
|
{
|
||||||
init();
|
//init();
|
||||||
}
|
}
|
||||||
|
|
||||||
CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::string Name, std::string UUID)
|
CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::string Name, std::string UUID)
|
||||||
: client(_client), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0)
|
: client(_client), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false)
|
||||||
{
|
{
|
||||||
ENetAddress address;
|
ENetAddress address;
|
||||||
enet_address_set_host(&address, host.c_str());
|
enet_address_set_host(&address, host.c_str());
|
||||||
@ -73,7 +75,7 @@ CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::s
|
|||||||
throw std::runtime_error("Can't establish connection :(");
|
throw std::runtime_error("Can't establish connection :(");
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetEvent event;
|
/*ENetEvent event;
|
||||||
if(enet_host_service(client, &event, 10000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT)
|
if(enet_host_service(client, &event, 10000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT)
|
||||||
{
|
{
|
||||||
logNetwork->info("Connection succeded");
|
logNetwork->info("Connection succeded");
|
||||||
@ -82,39 +84,47 @@ CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::s
|
|||||||
{
|
{
|
||||||
enet_peer_reset(peer);
|
enet_peer_reset(peer);
|
||||||
throw std::runtime_error("Connection refused by server");
|
throw std::runtime_error("Connection refused by server");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//init();
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
void CConnection::dispatch(ENetPacket * packet)
|
||||||
|
{
|
||||||
|
packets.push_back(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ENetPeer * CConnection::getPeer() const
|
||||||
|
{
|
||||||
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CConnection::write(const void * data, unsigned size)
|
int CConnection::write(const void * data, unsigned size)
|
||||||
{
|
{
|
||||||
ENetPacket * packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket * packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(peer, 0, packet);
|
enet_peer_send(peer, 0, packet);
|
||||||
enet_host_flush(client);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
int CConnection::read(void * data, unsigned size)
|
int CConnection::read(void * data, unsigned size)
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
|
||||||
while(bufferSize < size)
|
while(bufferSize < size)
|
||||||
{
|
{
|
||||||
if(enet_host_service(client, &event, 100) <= 0)
|
if(packets.empty())
|
||||||
|
{
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(20));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(event.type == ENET_EVENT_TYPE_CONNECT)
|
|
||||||
throw std::runtime_error("Connectin event receieved while package expected");
|
|
||||||
|
|
||||||
if(event.type == ENET_EVENT_TYPE_RECEIVE)
|
|
||||||
{
|
|
||||||
if(event.packet->dataLength > 0)
|
|
||||||
{
|
|
||||||
memcpy(buffer + bufferSize, event.packet->data, event.packet->dataLength);
|
|
||||||
bufferSize += event.packet->dataLength;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_packet_destroy(event.packet);
|
auto * packet = packets.front();
|
||||||
|
packets.pop_front();
|
||||||
|
|
||||||
|
if(packet->dataLength > 0)
|
||||||
|
{
|
||||||
|
memcpy(buffer + bufferSize, packet->data, packet->dataLength);
|
||||||
|
bufferSize += packet->dataLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_packet_destroy(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bufferSize == size);
|
assert(bufferSize == size);
|
||||||
@ -122,7 +132,7 @@ int CConnection::read(void * data, unsigned size)
|
|||||||
unsigned ret = std::min(size, bufferSize);
|
unsigned ret = std::min(size, bufferSize);
|
||||||
memcpy(data, buffer, ret);
|
memcpy(data, buffer, ret);
|
||||||
if(ret < bufferSize)
|
if(ret < bufferSize)
|
||||||
memcpy(buffer, buffer + ret, bufferSize);
|
memcpy(buffer, buffer + ret, bufferSize - ret);
|
||||||
bufferSize -= ret;
|
bufferSize -= ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -135,6 +145,9 @@ CConnection::~CConnection()
|
|||||||
if(handler)
|
if(handler)
|
||||||
handler->join();
|
handler->join();
|
||||||
|
|
||||||
|
for(auto * packet : packets)
|
||||||
|
enet_packet_destroy(packet);
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,22 +162,7 @@ CConnection & CConnection::operator&(const T &t) {
|
|||||||
|
|
||||||
void CConnection::close()
|
void CConnection::close()
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
|
||||||
enet_peer_disconnect(peer, 0);
|
enet_peer_disconnect(peer, 0);
|
||||||
|
|
||||||
while(enet_host_service(client, & event, 100) > 0)
|
|
||||||
{
|
|
||||||
switch (event.type)
|
|
||||||
{
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
|
||||||
enet_packet_destroy(event.packet);
|
|
||||||
break;
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* We've arrived here, so the disconnect attempt didn't */
|
|
||||||
/* succeed yet. Force the connection down. */
|
|
||||||
enet_peer_reset(peer);
|
enet_peer_reset(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +203,7 @@ void CConnection::sendPack(const CPack * pack)
|
|||||||
boost::unique_lock<boost::mutex> lock(*mutexWrite);
|
boost::unique_lock<boost::mutex> lock(*mutexWrite);
|
||||||
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
||||||
oser & pack;
|
oser & pack;
|
||||||
|
enet_host_flush(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnection::disableStackSendingByID()
|
void CConnection::disableStackSendingByID()
|
||||||
|
@ -23,12 +23,12 @@ struct CPack;
|
|||||||
class DLL_LINKAGE CConnection
|
class DLL_LINKAGE CConnection
|
||||||
: public IBinaryReader, public IBinaryWriter, public std::enable_shared_from_this<CConnection>
|
: public IBinaryReader, public IBinaryWriter, public std::enable_shared_from_this<CConnection>
|
||||||
{
|
{
|
||||||
void init();
|
|
||||||
void reportState(vstd::CLoggerBase * out) override;
|
void reportState(vstd::CLoggerBase * out) override;
|
||||||
|
|
||||||
int write(const void * data, unsigned size) override;
|
int write(const void * data, unsigned size) override;
|
||||||
int read(void * data, unsigned size) override;
|
int read(void * data, unsigned size) override;
|
||||||
|
|
||||||
|
std::list<ENetPacket*> packets;
|
||||||
ENetPeer * peer = nullptr;
|
ENetPeer * peer = nullptr;
|
||||||
ENetHost * client = nullptr;
|
ENetHost * client = nullptr;
|
||||||
char * buffer;
|
char * buffer;
|
||||||
@ -51,6 +51,9 @@ public:
|
|||||||
|
|
||||||
CConnection(ENetHost * client, ENetPeer * peer, std::string Name, std::string UUID);
|
CConnection(ENetHost * client, ENetPeer * peer, std::string Name, std::string UUID);
|
||||||
CConnection(ENetHost * client, std::string host, ui16 port, std::string Name, std::string UUID);
|
CConnection(ENetHost * client, std::string host, ui16 port, std::string Name, std::string UUID);
|
||||||
|
void init(); //must be called from outside after connection message received
|
||||||
|
void dispatch(ENetPacket * packet);
|
||||||
|
const ENetPeer * getPeer() const;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
bool isOpen() const;
|
bool isOpen() const;
|
||||||
|
@ -174,10 +174,10 @@ void CVCMIServer::run()
|
|||||||
if(!lobbyConnectionsThread)
|
if(!lobbyConnectionsThread)
|
||||||
lobbyConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::startAsyncAccept, this);
|
lobbyConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::startAsyncAccept, this);
|
||||||
|
|
||||||
if(!remoteConnectionsThread && cmdLineOptions.count("lobby"))
|
/*if(!remoteConnectionsThread && cmdLineOptions.count("lobby"))
|
||||||
{
|
{
|
||||||
remoteConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::establishRemoteConnections, this);
|
remoteConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::establishRemoteConnections, this);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#if defined(VCMI_ANDROID)
|
#if defined(VCMI_ANDROID)
|
||||||
CAndroidVMHelper vmHelper;
|
CAndroidVMHelper vmHelper;
|
||||||
@ -322,27 +322,45 @@ void CVCMIServer::startGameImmidiately()
|
|||||||
void CVCMIServer::startAsyncAccept()
|
void CVCMIServer::startAsyncAccept()
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
ENetHost * client = enet_host_create(NULL, 8, 2, 0, 0);
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(enet_host_service(server, &event, 1000) > 0)
|
if(enet_host_service(server, &event, 100) > 0)
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case ENET_EVENT_TYPE_CONNECT: {
|
case ENET_EVENT_TYPE_CONNECT: {
|
||||||
|
if(state == EServerState::LOBBY)
|
||||||
|
{
|
||||||
auto c = std::make_shared<CConnection>(server, event.peer, SERVER_NAME, uuid);
|
auto c = std::make_shared<CConnection>(server, event.peer, SERVER_NAME, uuid);
|
||||||
|
c->init();
|
||||||
connections.insert(c);
|
connections.insert(c);
|
||||||
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
|
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
|
||||||
|
}
|
||||||
enet_packet_destroy(event.packet);
|
enet_packet_destroy(event.packet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
case ENET_EVENT_TYPE_RECEIVE: {
|
||||||
|
|
||||||
|
bool receiverFound = false;
|
||||||
|
for(auto & c : connections)
|
||||||
|
{
|
||||||
|
if(c->getPeer() == event.peer)
|
||||||
|
{
|
||||||
|
c->dispatch(event.packet);
|
||||||
|
receiverFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!receiverFound)
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enet_host_destroy(client);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
|
/*void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user