<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40549 >

I separated out the stdinhand part of 40534 and added some more
fixes for bugs I found during testing:

- Sometimes the observe command would not send player info.
- The take command would not send player info about the other
  players whose usernames were cleared.
- The take command did not update pconn correctly if the value
  of 'was_observing_this' was TRUE.
- The detach command did not send player info when it cleared
  a player's username.
- detach_command() is made extern (used in 40534).


The whole {detach,take,observe}_command evil triumvirate along
with associated functions need a deep cleanup which I will get
to soon enough. For now, this minimal patch should restore
decent behaviour.


-----------------------------------------------------------------------
おはあああああああああああああああああ!!!
diff --git a/server/stdinhand.c b/server/stdinhand.c
index dd97aab..c16ffb9 100644
--- a/server/stdinhand.c
+++ b/server/stdinhand.c
@@ -92,7 +92,6 @@ static bool set_away(struct connection *caller, char *name, bool check);
 
 static bool observe_command(struct connection *caller, char *name, bool check);
 static bool take_command(struct connection *caller, char *name, bool check);
-static bool detach_command(struct connection *caller, char *name, bool check);
 static bool end_command(struct connection *caller, char *str, bool check);
 static bool surrender_command(struct connection *caller, char *str, bool check);
 
@@ -3148,7 +3147,7 @@ static bool observe_command(struct connection *caller, char *str, bool check)
   enum m_pre_result result;
   struct connection *pconn = NULL;
   struct player *pplayer = NULL;
-  bool res = FALSE, player_changed = FALSE;
+  bool res = FALSE;
   
   /******** PART I: fill pconn and pplayer ********/
 
@@ -3269,9 +3268,9 @@ static bool observe_command(struct connection *caller, char *str, bool check)
 
   /* attach pconn to new player as an observer */
   if (pplayer) {
-    player_changed = attach_connection_to_player(pconn, pplayer, TRUE);
+    attach_connection_to_player(pconn, pplayer, TRUE);
   } else {
-    player_changed = detach_connection_to_player(pconn, TRUE);
+    detach_connection_to_player(pconn, TRUE);
   }
 
   if (S_S_RUNNING == server_state()) {
@@ -3285,9 +3284,7 @@ static bool observe_command(struct connection *caller, char *str, bool check)
     /* we already know existing connections */
   }
   /* redundant self to self cannot be avoided */
-  if (player_changed) {
-    send_player_info(pplayer, NULL);
-  }
+  send_player_info(pplayer, NULL);
   send_conn_info(pconn->self, game.est_connections);
 
   if (pplayer) {
@@ -3465,6 +3462,7 @@ static bool take_command(struct connection *caller, char *str, bool check)
   players_iterate(aplayer) {
     if (strncmp(aplayer->username, pconn->username, MAX_LEN_NAME) == 0) {
       sz_strlcpy(aplayer->username, ANON_USER_NAME);
+      send_player_info_c(aplayer, NULL);
     }
   } players_iterate_end;
 
@@ -3479,6 +3477,10 @@ static bool take_command(struct connection *caller, char *str, bool check)
   if (res) {
     /* Successfully attached */
     pplayer = pconn->playing; /* In case pplayer was NULL. */
+    if (was_observing_this) {
+      pconn->observer = FALSE;
+      sz_strlcpy(pplayer->username, pconn->username);
+    }
 
     /* inform about the status before changes */
     cmd_reply(CMD_TAKE, caller, C_OK, _("%s now controls %s (%s, %s)"),
@@ -3537,7 +3539,7 @@ static bool take_command(struct connection *caller, char *str, bool check)
   If called for a global observer connection (where pconn->playing is NULL)
   then it will correctly detach from observing mode.
 **************************************************************************/
-static bool detach_command(struct connection *caller, char *str, bool check)
+bool detach_command(struct connection *caller, char *str, bool check)
 {
   int i = 0, ntokens = 0;
   char buf[MAX_LEN_CONSOLE_LINE], *arg[1];
@@ -3646,14 +3648,21 @@ static bool detach_command(struct connection *caller, char *str, bool check)
   cancel_connection_votes(pconn);
 
   if (pplayer && !pplayer->is_connected) {
+    bool player_changed = FALSE;
+
     /* aitoggle the player if no longer connected. */
     if (game.info.auto_ai_toggle && !pplayer->ai.control) {
       toggle_ai_player_direct(NULL, pplayer);
-      send_player_info_c(pplayer, game.est_connections);
+      player_changed = TRUE;
     }
     /* reset username if in pregame. */
     if (is_newgame) {
       sz_strlcpy(pplayer->username, ANON_USER_NAME);
+      player_changed = TRUE;
+    }
+
+    if (player_changed) {
+      send_player_info_c(pplayer, NULL);
     }
   }
 
diff --git a/server/stdinhand.h b/server/stdinhand.h
index 33aa18b..bfaa3ac 100644
--- a/server/stdinhand.h
+++ b/server/stdinhand.h
@@ -35,6 +35,7 @@ void show_players(struct connection *caller);
 bool load_command(struct connection *caller,
 		  const char *filename, bool check);
 bool start_command(struct connection *caller, bool check, bool notify);
+bool detach_command(struct connection *caller, char *str, bool check);
 
 void toggle_ai_player_direct(struct connection *caller,
 			     struct player *pplayer);
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to