mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Prototype is ready
This commit is contained in:
parent
d3710b82ad
commit
fedeb3db7a
@ -184,7 +184,7 @@ void CServerHandler::threadPoll()
|
||||
ENetEvent event;
|
||||
while(true)
|
||||
{
|
||||
if(enet_host_service(enetClient, &event, 100) > 0)
|
||||
if(enet_host_service(enetClient, &event, 10) > 0)
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
@ -211,6 +211,7 @@ void CServerHandler::threadPoll()
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
{
|
||||
enet_packet_destroy(event.packet);
|
||||
if(c && c->getPeer() == event.peer)
|
||||
{
|
||||
c.reset();
|
||||
@ -335,18 +336,18 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
if(state == EClientState::CONNECTION_CANCELLED)
|
||||
{
|
||||
logNetwork->info("Connection aborted by player!");
|
||||
return;
|
||||
}
|
||||
|
||||
while(state != EClientState::CONNECTING)
|
||||
{
|
||||
if(state == EClientState::CONNECTION_CANCELLED)
|
||||
{
|
||||
logNetwork->info("Connection aborted by player!");
|
||||
return;
|
||||
}
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||
}
|
||||
|
||||
c->init();
|
||||
|
||||
c->handler = std::make_shared<boost::thread>(&CServerHandler::threadHandleConnection, this);
|
||||
|
||||
if(!addr.empty() && addr != getHostAddress())
|
||||
@ -831,14 +832,15 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
|
||||
void CServerHandler::threadHandleConnection()
|
||||
{
|
||||
setThreadName("CServerHandler::threadHandleConnection");
|
||||
c->enterLobbyConnectionMode();
|
||||
try
|
||||
{
|
||||
while(!c->isOpen())
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||
|
||||
|
||||
c->enterLobbyConnectionMode();
|
||||
sendClientConnecting();
|
||||
while(c->connected)
|
||||
|
||||
while(c->isOpen())
|
||||
{
|
||||
while(state == EClientState::STARTING)
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||
@ -963,6 +965,7 @@ void CServerHandler::onServerFinished()
|
||||
|
||||
void CServerHandler::sendLobbyPack(const CPackForLobby & pack) const
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*mx);
|
||||
if(state != EClientState::STARTING)
|
||||
c->sendPack(&pack);
|
||||
}
|
||||
|
@ -31,8 +31,6 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void CConnection::init()
|
||||
{
|
||||
buffer = new char[4096];
|
||||
bufferSize = 0;
|
||||
enableSmartPointerSerialization();
|
||||
disableStackSendingByID();
|
||||
registerTypes(iser);
|
||||
@ -42,28 +40,26 @@ void CConnection::init()
|
||||
#else
|
||||
myEndianess = false;
|
||||
#endif
|
||||
connected = true;
|
||||
std::string pom;
|
||||
|
||||
//we got connection
|
||||
oser & std::string("Aiya!\n") & name & uuid & myEndianess; //identify ourselves
|
||||
enet_host_flush(client);
|
||||
|
||||
iser & pom & pom & contactUuid & contactEndianess;
|
||||
logNetwork->info("Established connection with %s. UUID: %s", pom, contactUuid);
|
||||
mutexRead = std::make_shared<boost::mutex>();
|
||||
mutexWrite = std::make_shared<boost::mutex>();
|
||||
|
||||
connected = true;
|
||||
iser.fileVersion = SERIALIZATION_VERSION;
|
||||
}
|
||||
|
||||
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), connected(false)
|
||||
: client(_client), peer(_peer), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false), channel(1)
|
||||
{
|
||||
//init();
|
||||
}
|
||||
|
||||
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), connected(false)
|
||||
: client(_client), iser(this), oser(this), name(Name), uuid(UUID), connectionID(0), connected(false), channel(0)
|
||||
{
|
||||
ENetAddress address;
|
||||
enet_address_set_host(&address, host.c_str());
|
||||
@ -74,23 +70,11 @@ CConnection::CConnection(ENetHost * _client, std::string host, ui16 port, std::s
|
||||
{
|
||||
throw std::runtime_error("Can't establish connection :(");
|
||||
}
|
||||
|
||||
/*ENetEvent event;
|
||||
if(enet_host_service(client, &event, 10000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT)
|
||||
{
|
||||
logNetwork->info("Connection succeded");
|
||||
}
|
||||
else
|
||||
{
|
||||
enet_peer_reset(peer);
|
||||
throw std::runtime_error("Connection refused by server");
|
||||
}*/
|
||||
|
||||
//init();
|
||||
}
|
||||
|
||||
void CConnection::dispatch(ENetPacket * packet)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutexRead);
|
||||
packets.push_back(packet);
|
||||
}
|
||||
|
||||
@ -101,47 +85,37 @@ const ENetPeer * CConnection::getPeer() const
|
||||
|
||||
int CConnection::write(const void * data, unsigned size)
|
||||
{
|
||||
if(size == 0)
|
||||
return 0;
|
||||
boost::unique_lock<boost::mutex> lock(mutexWrite);
|
||||
ENetPacket * packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(peer, 0, packet);
|
||||
enet_peer_send(peer, channel, packet);
|
||||
return size;
|
||||
}
|
||||
int CConnection::read(void * data, unsigned size)
|
||||
{
|
||||
while(bufferSize < size)
|
||||
const int timout = 1000;
|
||||
if(size == 0)
|
||||
return 0;
|
||||
for(int i = 0; packets.empty() && (i < timout || connected); ++i)
|
||||
{
|
||||
if(packets.empty())
|
||||
{
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(20));
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||
}
|
||||
boost::unique_lock<boost::mutex> lock(mutexRead);
|
||||
auto * packet = packets.front();
|
||||
packets.pop_front();
|
||||
|
||||
assert(bufferSize == size);
|
||||
|
||||
unsigned ret = std::min(size, bufferSize);
|
||||
memcpy(data, buffer, ret);
|
||||
if(ret < bufferSize)
|
||||
memcpy(buffer, buffer + ret, bufferSize - ret);
|
||||
bufferSize -= ret;
|
||||
if(packet->dataLength > 0)
|
||||
memcpy(data, packet->data, packet->dataLength);
|
||||
int ret = packet->dataLength;
|
||||
assert(ret == size);
|
||||
enet_packet_destroy(packet);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CConnection::~CConnection()
|
||||
{
|
||||
delete[] buffer;
|
||||
|
||||
if(handler)
|
||||
handler->join();
|
||||
|
||||
@ -162,6 +136,7 @@ CConnection & CConnection::operator&(const T &t) {
|
||||
|
||||
void CConnection::close()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutexWrite);
|
||||
enet_peer_disconnect(peer, 0);
|
||||
enet_peer_reset(peer);
|
||||
}
|
||||
@ -184,7 +159,6 @@ void CConnection::reportState(vstd::CLoggerBase * out)
|
||||
CPack * CConnection::retrievePack()
|
||||
{
|
||||
CPack * pack = nullptr;
|
||||
boost::unique_lock<boost::mutex> lock(*mutexRead);
|
||||
iser & pack;
|
||||
logNetwork->trace("Received CPack of type %s", (pack ? typeid(*pack).name() : "nullptr"));
|
||||
if(pack == nullptr)
|
||||
@ -200,10 +174,8 @@ CPack * CConnection::retrievePack()
|
||||
|
||||
void CConnection::sendPack(const CPack * pack)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*mutexWrite);
|
||||
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
|
||||
oser & pack;
|
||||
enet_host_flush(client);
|
||||
}
|
||||
|
||||
void CConnection::disableStackSendingByID()
|
||||
|
@ -29,18 +29,19 @@ class DLL_LINKAGE CConnection
|
||||
int read(void * data, unsigned size) override;
|
||||
|
||||
std::list<ENetPacket*> packets;
|
||||
int channel;
|
||||
ENetPeer * peer = nullptr;
|
||||
ENetHost * client = nullptr;
|
||||
char * buffer;
|
||||
unsigned bufferSize;
|
||||
|
||||
public:
|
||||
BinaryDeserializer iser;
|
||||
BinarySerializer oser;
|
||||
|
||||
std::shared_ptr<boost::mutex> mutexRead;
|
||||
std::shared_ptr<boost::mutex> mutexWrite;
|
||||
|
||||
bool connected;
|
||||
boost::mutex mutexRead;
|
||||
boost::mutex mutexWrite;
|
||||
|
||||
public:
|
||||
|
||||
bool myEndianess, contactEndianess; //true if little endian, if endianness is different we'll have to revert received multi-byte vars
|
||||
std::string contactUuid;
|
||||
std::string name; //who uses this connection
|
||||
|
@ -2743,7 +2743,6 @@ void CGameHandler::sendMessageTo(std::shared_ptr<CConnection> c, const std::stri
|
||||
{
|
||||
SystemMessage sm;
|
||||
sm.text = message;
|
||||
boost::unique_lock<boost::mutex> lock(*c->mutexWrite);
|
||||
*(c.get()) << &sm;
|
||||
}
|
||||
|
||||
|
@ -191,14 +191,16 @@ void CVCMIServer::run()
|
||||
}
|
||||
|
||||
while(state == EServerState::LOBBY || state == EServerState::GAMEPLAY_STARTING)
|
||||
{
|
||||
connectionAccepted();
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||
|
||||
logNetwork->info("Thread handling connections ended");
|
||||
}
|
||||
|
||||
if(state == EServerState::GAMEPLAY)
|
||||
{
|
||||
gh->run(si->mode == StartInfo::LOAD_GAME);
|
||||
}
|
||||
|
||||
while(state == EServerState::GAMEPLAY_ENDED)
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||
}
|
||||
@ -246,12 +248,6 @@ void CVCMIServer::threadAnnounceLobby()
|
||||
announcePack(std::move(announceQueue.front()));
|
||||
announceQueue.pop_front();
|
||||
}
|
||||
|
||||
/*if(acceptor)
|
||||
{
|
||||
io->reset();
|
||||
io->poll();
|
||||
}*/
|
||||
}
|
||||
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||
@ -322,19 +318,17 @@ void CVCMIServer::startGameImmidiately()
|
||||
void CVCMIServer::startAsyncAccept()
|
||||
{
|
||||
ENetEvent event;
|
||||
while(true)
|
||||
while(state != EServerState::SHUTDOWN)
|
||||
{
|
||||
if(enet_host_service(server, &event, 100) > 0)
|
||||
if(enet_host_service(server, &event, 10) > 0)
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT: {
|
||||
if(state == EServerState::LOBBY)
|
||||
{
|
||||
auto c = std::make_shared<CConnection>(server, event.peer, SERVER_NAME, uuid);
|
||||
c->init();
|
||||
connections.insert(c);
|
||||
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
|
||||
upcomingConnection = std::make_shared<CConnection>(server, event.peer, SERVER_NAME, uuid);
|
||||
connections.insert(upcomingConnection);
|
||||
}
|
||||
enet_packet_destroy(event.packet);
|
||||
break;
|
||||
@ -358,39 +352,34 @@ void CVCMIServer::startAsyncAccept()
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT: {
|
||||
enet_packet_destroy(event.packet);
|
||||
for(auto & c : connections)
|
||||
{
|
||||
if(c->getPeer() == event.peer)
|
||||
{
|
||||
clientDisconnected(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
|
||||
void CVCMIServer::connectionAccepted()
|
||||
{
|
||||
if(ec)
|
||||
if(upcomingConnection)
|
||||
{
|
||||
if(state != EServerState::SHUTDOWN)
|
||||
logNetwork->info("Something wrong during accepting: %s", ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if(state == EServerState::LOBBY || !hangingConnections.empty())
|
||||
{
|
||||
logNetwork->info("We got a new connection! :)");
|
||||
auto c = std::make_shared<CConnection>(upcomingConnection, SERVER_NAME, uuid);
|
||||
upcomingConnection.reset();
|
||||
connections.insert(c);
|
||||
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
|
||||
}
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
logNetwork->error("Failure processing new connection! %s", e.what());
|
||||
upcomingConnection->init();
|
||||
upcomingConnection->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, upcomingConnection);
|
||||
upcomingConnection.reset();
|
||||
}
|
||||
|
||||
startAsyncAccept();
|
||||
}*/
|
||||
}
|
||||
|
||||
void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
{
|
||||
@ -401,7 +390,7 @@ void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
try
|
||||
{
|
||||
#endif
|
||||
while(c->connected)
|
||||
while(c->isOpen())
|
||||
{
|
||||
CPack * pack;
|
||||
|
||||
@ -451,7 +440,7 @@ void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
|
||||
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
||||
// if(state != ENDING_AND_STARTING_GAME)
|
||||
if(c->connected)
|
||||
if(c->isOpen())
|
||||
{
|
||||
auto lcd = vstd::make_unique<LobbyClientDisconnected>();
|
||||
lcd->c = c;
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
std::atomic<int> currentClientId;
|
||||
std::atomic<ui8> currentPlayerId;
|
||||
std::shared_ptr<CConnection> hostClient;
|
||||
std::shared_ptr<CConnection> upcomingConnection;
|
||||
|
||||
CVCMIServer(boost::program_options::variables_map & opts);
|
||||
~CVCMIServer();
|
||||
@ -78,7 +79,7 @@ public:
|
||||
void establishRemoteConnections();
|
||||
void connectToRemote(const std::string & addr, int port);
|
||||
void startAsyncAccept();
|
||||
//void connectionAccepted();
|
||||
void connectionAccepted();
|
||||
void threadHandleClient(std::shared_ptr<CConnection> c);
|
||||
void threadAnnounceLobby();
|
||||
void handleReceivedPack(std::unique_ptr<CPackForLobby> pack);
|
||||
|
@ -53,7 +53,6 @@ bool LobbyClientConnected::checkClientPermissions(CVCMIServer * srv) const
|
||||
if(c && c->isOpen())
|
||||
{
|
||||
c->close();
|
||||
c->connected = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -132,7 +131,6 @@ bool LobbyClientDisconnected::applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
srv->clientDisconnected(c);
|
||||
c->close();
|
||||
c->connected = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -140,9 +138,7 @@ void LobbyClientDisconnected::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
{
|
||||
if(c && c->isOpen())
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c->mutexWrite);
|
||||
c->close();
|
||||
c->connected = false;
|
||||
}
|
||||
|
||||
if(shutdownServer)
|
||||
|
Loading…
Reference in New Issue
Block a user