Skip to content

Commit

Permalink
Fixed: Issues enumerating and connecting to server
Browse files Browse the repository at this point in the history
Beacon catches exceptions thrown when parsing an invalid beacon message
(e.g., server not fully initialized yet).

The serverinfo received via a Beacon or by asking directly does not
contain a valid address, so now ServerLink and ServerFinder make sure
it is updated.

When a local server is running, "net connect 0" will now work without
manually searching first, because the shell's ServerFinder is
automatically providing local servers.

Fixed a problem with converting remote users to shell users, where
the remote user wasn't removed from ServerSystem's list because the
signal was emitted by QObject and by that time the remote user's Id
had been destroyed.

Cleaned up log messages printed when disconnecting ServerLink.
  • Loading branch information
skyjake committed Feb 21, 2013
1 parent 39e3497 commit ee2c8c9
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 34 deletions.
2 changes: 2 additions & 0 deletions doomsday/client/include/network/serverlink.h
Expand Up @@ -67,6 +67,8 @@ class ServerLink : public de::shell::AbstractLink

bool foundServerInfo(de::Address const &host, serverinfo_t *info) const;

bool foundServerInfo(int index, serverinfo_t *info) const;

signals:
void serversDiscovered();

Expand Down
14 changes: 6 additions & 8 deletions doomsday/client/src/network/net_main.cpp
Expand Up @@ -1335,15 +1335,13 @@ D_CMD(Net)
return false;
}

Net_ServerLink().connectDomain(argv[2], 5);

//idx = strtol(argv[2], NULL, 10); // ignored!
//CmdReturnValue = success = N_Connect();
/*
if(success)
int index = strtoul(argv[2], 0, 10);
serverinfo_t info;
if(Net_ServerLink().foundServerInfo(index, &info))
{
Con_Message("Connected.\n");
}*/
Net_PrintServerInfo(index, &info);
Net_ServerLink().connectDomain(de::String("%1:%2").arg(info.address).arg(info.port), 5);
}
}
else if(!stricmp(argv[1], "mconnect"))
{
Expand Down
39 changes: 31 additions & 8 deletions doomsday/client/src/network/serverlink.cpp
Expand Up @@ -103,6 +103,10 @@ DENG2_PIMPL(ServerLink)

LOG_DEBUG("Discovered server at ") << svAddress;

// Update with the correct address.
strncpy(svInfo.address, svAddress.host().toString().toAscii(),
sizeof(svInfo.address) - 1);

discovered.insert(svAddress, svInfo);

// Show the information in the console.
Expand Down Expand Up @@ -162,12 +166,16 @@ DENG2_PIMPL(ServerLink)
Servers all = discovered;

// Append the ones from the server finder.
foreach(Address host, finder.foundServers())
foreach(Address sv, finder.foundServers())
{
serverinfo_t info;
if(host.isLocal()) host.setHost(QHostAddress::LocalHost);
Net_RecordToServerInfo(finder.messageFromServer(host), &info);
all.insert(host, info);
Net_RecordToServerInfo(finder.messageFromServer(sv), &info);

// Update the address in the info, which is missing because this
// information didn't come from the master.
strncpy(info.address, sv.host().toString().toAscii(), sizeof(info.address) - 1);

all.insert(sv, info);
}

return all;
Expand Down Expand Up @@ -211,10 +219,13 @@ void ServerLink::connectHost(Address const &address)
void ServerLink::linkDisconnected()
{
LOG_AS("ServerLink");
LOG_INFO("Connection to server was disconnected");
if(d->state != None)
{
LOG_INFO("Connection to server was disconnected");

// Update our state and notify the game.
disconnect();
// Update our state and notify the game.
disconnect();
}
}

void ServerLink::disconnect()
Expand All @@ -225,6 +236,8 @@ void ServerLink::disconnect()

if(d->state == InGame)
{
d->state = None;

// Tell the Game that a disconnection is about to happen.
if(gx.NetDisconnect)
gx.NetDisconnect(true);
Expand All @@ -241,10 +254,11 @@ void ServerLink::disconnect()
}
else
{
d->state = None;

LOG_INFO("Connection attempts aborted");
AbstractLink::disconnect();
}
d->state = None;
}

void ServerLink::discover(String const &domain)
Expand All @@ -270,6 +284,15 @@ QList<Address> ServerLink::foundServers() const
return d->allFound().keys();
}

bool ServerLink::foundServerInfo(int index, serverinfo_t *info) const
{
Instance::Servers all = d->allFound();
QList<Address> listed = all.keys();
if(index < 0 || index >= listed.size()) return false;
memcpy(info, &all[listed[index]], sizeof(*info));
return true;
}

bool ServerLink::foundServerInfo(Address const &host, serverinfo_t *info) const
{
Instance::Servers all = d->allFound();
Expand Down
21 changes: 14 additions & 7 deletions doomsday/libdeng2/src/net/beacon.cpp
Expand Up @@ -203,15 +203,22 @@ void Beacon::readDiscoveryReply()
if(block == discoveryMessage)
continue;

// Remove the service listening port from the beginning.
duint16 listenPort = 0;
Reader(block) >> listenPort;
block.remove(0, 2);
try
{
// Remove the service listening port from the beginning.
duint16 listenPort = 0;
Reader(block) >> listenPort;
block.remove(0, 2);

Address host(from, listenPort);
d->found.insert(host, block);
Address host(from, listenPort);
d->found.insert(host, block);

emit found(host, block);
emit found(host, block);
}
catch(Error const &)
{
// Bogus message, ignore.
}
}
}

Expand Down
14 changes: 8 additions & 6 deletions doomsday/libshell/src/abstractlink.cpp
Expand Up @@ -185,14 +185,16 @@ void AbstractLink::socketDisconnected()
}
d->socket->setQuiet(false);
}

if(!d->peerAddress.isNull())
{
LOG_INFO("Disconnected from %s") << d->peerAddress;
}
else
{
LOG_INFO("Disconnected");
if(!d->peerAddress.isNull())
{
LOG_INFO("Disconnected from %s") << d->peerAddress;
}
else
{
LOG_INFO("Disconnected");
}
}

d->status = Disconnected;
Expand Down
3 changes: 3 additions & 0 deletions doomsday/server/include/remoteuser.h
Expand Up @@ -76,6 +76,9 @@ class RemoteUser : public QObject, public de::Transmitter
// Implements Transmitter.
void send(de::IByteArray const &data);

signals:
void destroyed();

public slots:
void handleIncomingPackets();

Expand Down
2 changes: 1 addition & 1 deletion doomsday/server/include/serversystem.h
Expand Up @@ -90,7 +90,7 @@ class ServerSystem : public QObject, public de::System

protected slots:
void handleIncomingConnection();
void userDestroyed(QObject *);
void userDestroyed();

private:
DENG2_PRIVATE(d)
Expand Down
4 changes: 3 additions & 1 deletion doomsday/server/src/remoteuser.cpp
Expand Up @@ -216,7 +216,9 @@ RemoteUser::RemoteUser(Socket *socket) : d(new Instance(this, socket))

RemoteUser::~RemoteUser()
{
d->disconnect();
emit destroyed();

d->disconnect();
delete d;
}

Expand Down
12 changes: 9 additions & 3 deletions doomsday/server/src/serversystem.cpp
Expand Up @@ -260,7 +260,11 @@ bool ServerSystem::isUserAllowedToJoin(RemoteUser &/*user*/) const

void ServerSystem::convertToShellUser(RemoteUser *user)
{
LOG_AS("convertToShellUser");

Socket *socket = user->takeSocket();

LOG_DEBUG("Remote user %s converted to shell user") << user->id();
user->deleteLater();

d->shellUsers.add(new ShellUser(socket));
Expand All @@ -286,22 +290,24 @@ void ServerSystem::handleIncomingConnection()
if(!sock) break;

RemoteUser *user = new RemoteUser(sock);
connect(user, SIGNAL(destroyed(QObject*)), this, SLOT(userDestroyed(QObject*)));
connect(user, SIGNAL(destroyed()), this, SLOT(userDestroyed()));
d->users.insert(user->id(), user);

// Immediately handle pending messages, if there are any.
user->handleIncomingPackets();
}
}

void ServerSystem::userDestroyed(QObject *ob)
void ServerSystem::userDestroyed()
{
RemoteUser *u = static_cast<RemoteUser *>(ob);
RemoteUser *u = static_cast<RemoteUser *>(sender());

LOG_AS("ServerSystem");
LOG_VERBOSE("Removing user %s") << u->id();

d->users.remove(u->id());

LOG_DEBUG("%i remote users remain") << d->users.size();
}

void ServerSystem::printStatus()
Expand Down

0 comments on commit ee2c8c9

Please sign in to comment.