mirror of https://github.com/OpenTTD/OpenTTD
(svn r8170) -Backport from trunk (r7984, r8118, r8167, r8168):
- out-of-bounds read access on _clients array (Quark) (r7984) - change the ordering of the network list (r8118) - (FS#556): a network client crashes, due to a division by zero (r8167) - ParseConnectionstring didn't use the port parameter if a player was also specified (r8168)release/0.5
parent
70920944d8
commit
b57b2224e9
|
@ -756,6 +756,11 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
|||
ParseConnectionString(&player, &port, ip);
|
||||
|
||||
IConsolePrintF(_icolour_def, "Connecting to %s...", ip);
|
||||
if (port != NULL) {
|
||||
rport = atoi(port);
|
||||
IConsolePrintF(_icolour_def, " port: %s", port);
|
||||
}
|
||||
|
||||
if (player != NULL) {
|
||||
_network_playas = atoi(player);
|
||||
IConsolePrintF(_icolour_def, " player-no: %d", _network_playas);
|
||||
|
@ -767,10 +772,6 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
|||
if (!IsValidPlayer(_network_playas)) return false;
|
||||
}
|
||||
}
|
||||
if (port != NULL) {
|
||||
rport = atoi(port);
|
||||
IConsolePrintF(_icolour_def, " port: %s", port);
|
||||
}
|
||||
|
||||
NetworkClientConnectGame(ip, rport);
|
||||
|
||||
|
|
31
network.c
31
network.c
|
@ -82,7 +82,7 @@ NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index)
|
|||
{
|
||||
NetworkClientState *cs;
|
||||
|
||||
for (cs = _clients; cs != &_clients[MAX_CLIENT_INFO]; cs++) {
|
||||
for (cs = _clients; cs != endof(_clients); cs++) {
|
||||
if (cs->index == client_index) return cs;
|
||||
}
|
||||
|
||||
|
@ -513,24 +513,25 @@ unsigned long NetworkResolveHost(const char *hostname)
|
|||
return ip;
|
||||
}
|
||||
|
||||
// Converts a string to ip/port/player
|
||||
// Format: IP#player:port
|
||||
//
|
||||
// connection_string will be re-terminated to seperate out the hostname, and player and port will
|
||||
// be set to the player and port strings given by the user, inside the memory area originally
|
||||
// occupied by connection_string.
|
||||
/** Converts a string to ip/port/player
|
||||
* Format: IP#player:port
|
||||
*
|
||||
* connection_string will be re-terminated to seperate out the hostname, and player and port will
|
||||
* be set to the player and port strings given by the user, inside the memory area originally
|
||||
* occupied by connection_string. */
|
||||
void ParseConnectionString(const char **player, const char **port, char *connection_string)
|
||||
{
|
||||
char *p;
|
||||
for (p = connection_string; *p != '\0'; p++) {
|
||||
if (*p == '#') {
|
||||
*p = '\0';
|
||||
*player = ++p;
|
||||
while (IsValidChar(*p, CS_NUMERAL)) p++;
|
||||
if (*p == '\0') break;
|
||||
} else if (*p == ':') {
|
||||
*port = p + 1;
|
||||
*p = '\0';
|
||||
switch (*p) {
|
||||
case '#':
|
||||
*player = p + 1;
|
||||
*p = '\0';
|
||||
break;
|
||||
case ':':
|
||||
*port = p + 1;
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -467,9 +467,18 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
|
|||
|
||||
_frame_counter = _frame_counter_server = _frame_counter_max = NetworkRecv_uint32(MY_CLIENT, p);
|
||||
|
||||
_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
|
||||
_network_join_kbytes = 0;
|
||||
_network_join_kbytes_total = NetworkRecv_uint32(MY_CLIENT, p) / 1024;
|
||||
|
||||
/* If the network connection has been closed due to loss of connection
|
||||
* or when _network_join_kbytes_total is 0, the join status window will
|
||||
* do a division by zero. When the connection is lost, we just return
|
||||
* that. If kbytes_total is 0, the packet must be malformed as a
|
||||
* savegame less than 1 kilobyte is practically impossible. */
|
||||
if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
|
||||
if (_network_join_kbytes_total == 0) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
|
||||
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
||||
|
||||
// The first packet does not contain any more data
|
||||
|
|
|
@ -141,10 +141,17 @@ static int CDECL NGameAllowedSorter(const void *a, const void *b)
|
|||
{
|
||||
const NetworkGameList *cmp1 = *(const NetworkGameList**)a;
|
||||
const NetworkGameList *cmp2 = *(const NetworkGameList**)b;
|
||||
/* Reverse default as we are interested in compatible clients first */
|
||||
int r = cmp2->info.compatible - cmp1->info.compatible;
|
||||
|
||||
/* The servers we do not know anything about (the ones that did not reply) should be at the bottom) */
|
||||
int r = (cmp1->info.server_revision[0] == '\0') - (cmp2->info.server_revision[0] == '\0');
|
||||
|
||||
/* Reverse default as we are interested in version-compatible clients first */
|
||||
if (r == 0) r = cmp2->info.version_compatible - cmp1->info.version_compatible;
|
||||
/* The version-compatible ones are then sorted with NewGRF compatible first, incompatible last */
|
||||
if (r == 0) r = cmp2->info.compatible - cmp1->info.compatible;
|
||||
/* Passworded servers should be below unpassworded servers */
|
||||
if (r == 0) r = cmp1->info.use_password - cmp2->info.use_password;
|
||||
/* Finally sort on the name of the server */
|
||||
if (r == 0) r = strcasecmp(cmp1->info.server_name, cmp2->info.server_name);
|
||||
|
||||
return _internal_sort_order ? -r : r;
|
||||
|
@ -1409,7 +1416,7 @@ static void NetworkJoinStatusWindowWndProc(Window *w, WindowEvent *e)
|
|||
DrawStringCentered(125, 46, STR_NETWORK_CONNECTING_DOWNLOADING, 14);
|
||||
/* Fallthrough */
|
||||
default: /* Waiting is 15%, so the resting receivement of map is maximum 70% */
|
||||
progress = 15 + _network_join_kbytes * (100 - 15) / _network_join_kbytes_total;
|
||||
progress = 15 + _network_join_kbytes * (100 - 15) / (_network_join_kbytes_total+1);
|
||||
}
|
||||
|
||||
/* Draw nice progress bar :) */
|
||||
|
|
Loading…
Reference in New Issue