I've discovered why the netcode is so unstable. Everthing just assumes it'll be successful. At one point, there's an infinite loop waiting for an accept message. No possibility of receiving a rejection message, no timeout, nothing. At another point, the host just overwrites an existing player, if the game is full. I've fixed most of the ones I came into contact with, but there are probably many more left.

git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@8938 4a71c877-e1ca-e34f-864e-861f7616d084
master
Guangcong Luo 2010-01-03 10:40:52 +00:00 committed by Git SVN Gateway
parent 495004bc7c
commit f2e9a412ac
3 changed files with 68 additions and 20 deletions

View File

@ -1498,9 +1498,9 @@ void NETBroadcastPlayerInfo(uint32_t index)
NETend();
}
static unsigned int NET_CreatePlayer(const char* name)
static signed int NET_CreatePlayer(const char* name)
{
unsigned int index;
signed int index;
for (index = 0; index < MAX_CONNECTED_PLAYERS; index++)
{
@ -1516,7 +1516,7 @@ static unsigned int NET_CreatePlayer(const char* name)
}
debug(LOG_ERROR, "Could not find place for player %s", name);
return 0;
return -1;
}
static void NET_DestroyPlayer(unsigned int index)
@ -3254,13 +3254,22 @@ static void NETallowJoining(void)
{
char name[64];
uint8_t j;
uint8_t index;
int8_t index;
NETbeginDecode(NET_JOIN);
NETstring(name, sizeof(name));
NETend();
index = NET_CreatePlayer(name);
if (index == -1)
{
// FIXME: No room. Dropping the player without warning since protocol doesn't seem to support rejection for some reason.
delSocket(tmp_socket_set, tmp_socket[i]);
socketClose(tmp_socket[i]);
tmp_socket[i] = NULL;
return;
}
delSocket(tmp_socket_set, tmp_socket[i]);
NET_initBufferedSocket(connected_bsocket[index], tmp_socket[i]);
addSocket(socket_set, connected_bsocket[index]->socket);
@ -3273,7 +3282,7 @@ static void NETallowJoining(void)
gamestruct.desc.dwCurrentPlayers++;
NETbeginEncode(NET_ACCEPTED, index);
NETuint8_t(&index);
NETuint8_t((uint8_t *)&index);
NETend();
MultiPlayerJoin(index);
@ -3291,7 +3300,7 @@ static void NETallowJoining(void)
// Send info about newcomer to all players.
NETbeginEncode(NET_PLAYER_JOINED, NET_ALL_PLAYERS);
NETuint8_t(&index);
NETuint8_t((uint8_t *)&index);
NETend();
for (j = 0; j < MAX_CONNECTED_PLAYERS; ++j)
@ -3668,6 +3677,15 @@ connect_succesfull:
addressToText(cur->ai_addr, NetPlay.games[gameNumber].desc.host, sizeof(NetPlay.games[gameNumber].desc.host));
}
freeaddrinfo(hosts);
if (NetPlay.games[gameNumber].desc.dwCurrentPlayers >= NetPlay.games[gameNumber].desc.dwMaxPlayers)
{
// Shouldn't join; game is full
delSocket(socket_set, tcp_socket);
socketClose(tcp_socket);
free(socket_set);
socket_set = NULL;
return false;
}
// Allocate memory for a new socket
bsocket = NET_createBufferedSocket();
// NOTE: tcp_socket = bsocket->socket now!
@ -3680,6 +3698,7 @@ connect_succesfull:
NETstring((char*)playername, 64);
NETend();
i = SDL_GetTicks();
// Loop until we've been accepted into the game
for (;;)
{
@ -3687,6 +3706,12 @@ connect_succesfull:
NETrecv(&type);
// FIXME: shouldn't there be some sort of rejection message?
if (SDL_GetTicks() > i + 10000)
{
// timeout
return false;
}
if (type == NET_ACCEPTED)
{
uint8_t index;

View File

@ -720,7 +720,7 @@ LOBBY_ERROR_TYPES getLobbyError(void)
void setLobbyError (LOBBY_ERROR_TYPES error_type)
{
LobbyError = error_type;
if (LobbyError <= ERROR_CONNECTION)
if (LobbyError <= ERROR_FULL)
{
disableLobbyRefresh = false;
}
@ -946,10 +946,21 @@ void runGameFind(void )
{
ingame.localOptionsReceived = false; // note we are awaiting options
sstrcpy(game.name, NetPlay.games[gameNumber].name); // store name
joinCampaign(gameNumber,(char*)sPlayer);
changeTitleMode(MULTIOPTION);
if (joinCampaign(gameNumber,(char*)sPlayer))
{
changeTitleMode(MULTIOPTION);
}
else if (NetPlay.games[gameNumber].desc.dwCurrentPlayers >= NetPlay.games[gameNumber].desc.dwMaxPlayers)
{
setLobbyError(ERROR_FULL);
addGames();
}
else
{
setLobbyError(ERROR_CONNECTION);
addGames();
}
}
}
@ -958,10 +969,21 @@ void runGameFind(void )
{
ingame.localOptionsReceived = false; // note we are awaiting options
sstrcpy(game.name, NetPlay.games[gameNumber].name); // store name
joinCampaign(gameNumber,(char*)sPlayer);
changeTitleMode(MULTIOPTION);
if (joinCampaign(gameNumber,(char*)sPlayer))
{
changeTitleMode(MULTIOPTION);
}
else if (NetPlay.games[gameNumber].desc.dwCurrentPlayers >= NetPlay.games[gameNumber].desc.dwMaxPlayers)
{
setLobbyError(ERROR_FULL);
hidePasswordForm();
}
else
{
setLobbyError(ERROR_CONNECTION);
hidePasswordForm();
}
}
else if (id == CON_PASSWORDNO)
{

View File

@ -290,18 +290,19 @@ BOOL joinCampaign(UDWORD gameNumber, char *sPlayer)
if(!ingame.localJoiningInProgress)
{
NETjoinGame(gameNumber, sPlayer); // join
if (!NETjoinGame(gameNumber, sPlayer)) // join
{
return false;
}
ingame.localJoiningInProgress = true;
loadMultiStats(sPlayer,&playerStats);
setMultiStats(selectedPlayer, playerStats, false);
setMultiStats(selectedPlayer, playerStats, true);
return false;
return true;
}
bMultiPlayer = true;
multiMsgOff = 0;
return true;
return false;
}
// ////////////////////////////////////////////////////////////////////////////