--- a/console_cmds.c Mon Mar 19 19:22:26 2007 +0000
+++ b/console_cmds.c Mon Mar 19 19:34:44 2007 +0000
@@ -529,6 +529,7 @@
{
static const char* const stat_str[] = {
"inactive",
+ "authorizing",
"authorized",
"waiting",
"loading map",
--- a/currency.c Mon Mar 19 19:22:26 2007 +0000
+++ b/currency.c Mon Mar 19 19:34:44 2007 +0000
@@ -168,7 +168,7 @@
StringID* BuildCurrencyDropdown(void)
{
/* Allow room for all currencies, plus a terminator entry */
- static StringID names[CUSTOM_CURRENCY_ID];
+ static StringID names[NUM_CURRENCY + 1];
uint i;
/* Add each name */
--- a/economy.c Mon Mar 19 19:22:26 2007 +0000
+++ b/economy.c Mon Mar 19 19:34:44 2007 +0000
@@ -362,6 +362,40 @@
MarkWholeScreenDirty();
}
+static void ChangeNetworkOwner(PlayerID current_player, PlayerID new_player)
+{
+#ifdef ENABLE_NETWORK
+ if (!_networking) return;
+
+ if (current_player == _local_player) {
+ _network_playas = new_player;
+ SetLocalPlayer(new_player);
+ }
+
+ if (!_network_server) return;
+
+ /* The server has to handle all administrative issues, for example
+ * updating and notifying all clients of what has happened */
+ NetworkClientState *cs;
+ NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
+
+ /* The server has just changed from player */
+ if (current_player == ci->client_playas) {
+ ci->client_playas = new_player;
+ NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
+ }
+
+ /* Find all clients that were in control of this company, and mark them as new_player */
+ FOR_ALL_CLIENTS(cs) {
+ ci = DEREF_CLIENT_INFO(cs);
+ if (current_player == ci->client_playas) {
+ ci->client_playas = new_player;
+ NetworkUpdateClientInfo(ci->client_index);
+ }
+ }
+#endif /* ENABLE_NETWORK */
+}
+
static void PlayersCheckBankrupt(Player *p)
{
PlayerID owner;
@@ -419,35 +453,9 @@
p->bankrupt_asked = 0xFF;
p->bankrupt_timeout = 0x456;
break;
- } else if (owner == _local_player) {
- _network_playas = PLAYER_SPECTATOR;
- SetLocalPlayer(PLAYER_SPECTATOR);
}
-#ifdef ENABLE_NETWORK
- /* The server has to handle all administrative issues, for example
- * updating and notifying all clients of what has happened */
- if (_network_server) {
- const NetworkClientState *cs;
- NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-
- /* The server has just gone belly-up, mark it as spectator */
- if (owner == ci->client_playas) {
- ci->client_playas = PLAYER_SPECTATOR;
- NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
- }
-
- /* Find all clients that were in control of this company,
- * and mark them as spectator; broadcast this message to everyone */
- FOR_ALL_CLIENTS(cs) {
- ci = DEREF_CLIENT_INFO(cs);
- if (ci->client_playas == owner) {
- ci->client_playas = PLAYER_SPECTATOR;
- NetworkUpdateClientInfo(ci->client_index);
- }
- }
- }
-#endif /* ENABLE_NETWORK */
+ ChangeNetworkOwner(owner, PLAYER_SPECTATOR);
}
/* Remove the player */
@@ -1572,6 +1580,7 @@
// original code does this a little bit differently
pi = p->index;
+ ChangeNetworkOwner(pi, _current_player);
ChangeOwnershipOfPlayerItems(pi, _current_player);
if (p->bankrupt_value == 0) {
--- a/network_data.h Mon Mar 19 19:22:26 2007 +0000
+++ b/network_data.h Mon Mar 19 19:34:44 2007 +0000
@@ -49,6 +49,7 @@
typedef enum {
STATUS_INACTIVE,
+ STATUS_AUTHORIZING, // This means that the client is authorizing
STATUS_AUTH, // This means that the client is authorized
STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map
STATUS_MAP,
--- a/network_server.c Mon Mar 19 19:22:26 2007 +0000
+++ b/network_server.c Mon Mar 19 19:34:44 2007 +0000
@@ -215,7 +215,14 @@
// uint8: Type of password
//
- Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
+ Packet *p;
+
+ /* Invalid packet when status is AUTH or higher */
+ if (cs->status >= STATUS_AUTH) return;
+
+ cs->status = STATUS_AUTHORIZING;
+
+ p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
NetworkSend_uint8(p, type);
NetworkSend_Packet(p, cs);
}
@@ -694,7 +701,7 @@
type = NetworkRecv_uint8(cs, p);
NetworkRecv_string(cs, p, password, sizeof(password));
- if (cs->status == STATUS_INACTIVE && type == NETWORK_GAME_PASSWORD) {
+ if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) {
// Check game-password
if (strcmp(password, _network_game_info.server_password) != 0) {
// Password is invalid
@@ -712,7 +719,7 @@
// Valid password, allow user
SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
return;
- } else if (cs->status == STATUS_INACTIVE && type == NETWORK_COMPANY_PASSWORD) {
+ } else if (cs->status == STATUS_AUTHORIZING && type == NETWORK_COMPANY_PASSWORD) {
ci = DEREF_CLIENT_INFO(cs);
if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
@@ -1534,6 +1541,12 @@
IConsolePrintF(_icolour_err,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->index, _network_max_join_time);
NetworkCloseClient(cs);
}
+ } else if (cs->status == STATUS_INACTIVE) {
+ int lag = NetworkCalculateLag(cs);
+ if (lag > 4 * DAY_TICKS) {
+ IConsolePrintF(_icolour_err,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->index, 4 * DAY_TICKS);
+ NetworkCloseClient(cs);
+ }
}
if (cs->status >= STATUS_PRE_ACTIVE) {