Skip to content

Commit

Permalink
Allow using NETbeginEncode()/NETend() with tmp queues.
Browse files Browse the repository at this point in the history
Clients actually get a game full message instead of a host has dropped connection
message.

Don't double-pop NET_REJECTED messages when joining (which were sent to a random socket
other than the joining client, anyway, due to being attempted to being sent to tmp
queues). To reproduce, apply this patch to the host but not to the client.

Hopefully fixes ticket:3245 and ticket:3300.
  • Loading branch information
Cyp committed Mar 16, 2012
1 parent 2b3362b commit 2d67521
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
52 changes: 42 additions & 10 deletions lib/netplay/netplay.cpp
Expand Up @@ -1239,16 +1239,35 @@ UDWORD NETgetPacketsRecvd(void)

// ////////////////////////////////////////////////////////////////////////
// Send a message to a player, option to guarantee message
bool NETsend(uint8_t player, NetMessage const *message)
bool NETsend(NETQUEUE queue, NetMessage const *message)
{
uint8_t player = queue.index;
ssize_t result = 0;

if(!NetPlay.bComms)
{
return true;
}

if (player >= MAX_CONNECTED_PLAYERS && player != NET_ALL_PLAYERS) return false;
Socket **sockets = connected_bsocket;
bool isTmpQueue = false;
switch (queue.queueType)
{
case QUEUE_BROADCAST:
ASSERT_OR_RETURN(false, player == NET_ALL_PLAYERS, "Wrong queue index.");
break;
case QUEUE_NET:
ASSERT_OR_RETURN(false, player < MAX_CONNECTED_PLAYERS, "Wrong queue index.");
break;
case QUEUE_TMP:
sockets = tmp_socket;
isTmpQueue = true;

ASSERT_OR_RETURN(false, player < MAX_TMP_SOCKETS && NetPlay.isHost, "Wrong queue index.");
break;
default:
ASSERT_OR_RETURN(false, false, "Wrong queue type.");
}

if (NetPlay.isHost)
{
Expand All @@ -1257,11 +1276,11 @@ bool NETsend(uint8_t player, NetMessage const *message)
for (player = firstPlayer; player <= lastPlayer; ++player)
{
// We are the host, send directly to player.
if (connected_bsocket[player] != NULL)
if (sockets[player] != NULL)
{
uint8_t *rawData = message->rawDataDup();
ssize_t rawLen = message->rawLen();
result = writeAll(connected_bsocket[player], rawData, rawLen);
result = writeAll(sockets[player], rawData, rawLen);
delete[] rawData; // Done with the data.

if (result == rawLen)
Expand All @@ -1273,8 +1292,11 @@ bool NETsend(uint8_t player, NetMessage const *message)
{
// Write error, most likely client disconnect.
debug(LOG_ERROR, "Failed to send message: %s", strSockError(getSockErr()));
NETlogEntry("client disconnect?", SYNC_FLAG, player);
NETplayerClientDisconnect(player);
if (!isTmpQueue)
{
NETlogEntry("client disconnect?", SYNC_FLAG, player);
NETplayerClientDisconnect(player);
}
}
}
}
Expand Down Expand Up @@ -1338,15 +1360,22 @@ void NETflush()

if (NetPlay.isHost)
{
int player;
for (player = 0; player < MAX_CONNECTED_PLAYERS; ++player)
for (int player = 0; player < MAX_CONNECTED_PLAYERS; ++player)
{
// We are the host, send directly to player.
if (connected_bsocket[player] != NULL)
{
socketFlush(connected_bsocket[player]);
}
}
for (int player = 0; player < MAX_TMP_SOCKETS; ++player)
{
// We are the host, send directly to player.
if (tmp_socket[player] != NULL)
{
socketFlush(tmp_socket[player]);
}
}
}
else
{
Expand Down Expand Up @@ -2943,8 +2972,11 @@ bool NETjoinGame(const char* host, uint32_t port, const char* playername)
setLobbyError((LOBBY_ERROR_TYPES)rejection);
NETclose();
}

NETpop(queue);
else
{
debug(LOG_ERROR, "Unexpected %s.", messageTypeToString(type));
NETpop(queue);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/netplay/netplay.h
Expand Up @@ -286,7 +286,7 @@ extern char iptoconnect[PATH_MAX]; // holds IP/hostname from command line
// ////////////////////////////////////////////////////////////////////////
// functions available to you.
extern int NETinit(bool bFirstCall); // init
bool NETsend(uint8_t player, NetMessage const *message); ///< send to player, or broadcast if player == NET_ALL_PLAYERS.
bool NETsend(NETQUEUE queue, NetMessage const *message); ///< send to player, or broadcast if player == NET_ALL_PLAYERS.
extern bool NETrecvNet(NETQUEUE *queue, uint8_t *type); ///< recv a message from the net queues if possible.
extern bool NETrecvGame(NETQUEUE *queue, uint8_t *type); ///< recv a message from the game queues which is sceduled to execute by time, if possible.
void NETflush(void); ///< Flushes any data stuck in compression buffers.
Expand Down
4 changes: 2 additions & 2 deletions lib/netplay/nettypes.cpp
Expand Up @@ -473,9 +473,9 @@ bool NETend()
ASSERT(message.type > NET_MIN_TYPE && message.type < NET_MAX_TYPE, "Inserting %s into net queue.", messageTypeToString(message.type));
}

if (queueInfo.queueType == QUEUE_NET || queueInfo.queueType == QUEUE_BROADCAST)
if (queueInfo.queueType == QUEUE_NET || queueInfo.queueType == QUEUE_BROADCAST || queueInfo.queueType == QUEUE_TMP)
{
NETsend(queueInfo.index, &queue->getMessageForNet());
NETsend(queueInfo, &queue->getMessageForNet());
queue->popMessageForNet();
}

Expand Down

0 comments on commit 2d67521

Please sign in to comment.