Allow using NETbeginEncode()/NETend() with tmp queues.

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.
master
Cyp 2012-03-16 14:49:50 +01:00
parent 2b3362bd0e
commit 2d67521f84
3 changed files with 45 additions and 13 deletions

View File

@ -1239,8 +1239,9 @@ 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)
@ -1248,7 +1249,25 @@ bool NETsend(uint8_t player, NetMessage const *message)
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)
{
@ -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)
@ -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);
}
}
}
}
@ -1338,8 +1360,7 @@ 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)
@ -1347,6 +1368,14 @@ void NETflush()
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
{
@ -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);
}
}
}

View File

@ -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.

View File

@ -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();
}