tAddition of new "A_DONEFIGHT" ability; conforming clients now send the server a C_DONE message to indicate that the user has read any relevant messages, closed dialogs, etc. and is ready to move on. - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 82bd31408cf47e0d219c71fddeb6ba780ae26fea
 (DIR) parent 4e2abfa579b8dff0f346479002e8fc06436594e7
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Sat, 13 Apr 2002 16:35:45 +0000
       
       Addition of new "A_DONEFIGHT" ability; conforming clients now send the
       server a C_DONE message to indicate that the user has read any relevant
       messages, closed dialogs, etc. and is ready to move on.
       
       
       Diffstat:
         M ChangeLog                           |       2 ++
         M doc/protocol.html                   |      28 +++++++++++++++++++++-------
         M src/AIPlayer.c                      |       1 +
         M src/curses_client/curses_client.c   |       3 +++
         M src/dopewars.h                      |       4 +++-
         M src/gui_client/gtk_client.c         |       3 +++
         M src/message.c                       |       1 +
         M src/serverside.c                    |      34 +++++++++++++++++++++++--------
       
       8 files changed, 59 insertions(+), 17 deletions(-)
       ---
 (DIR) diff --git a/ChangeLog b/ChangeLog
       t@@ -1,4 +1,6 @@
        cvs
       +    - On fight termination the player is now allowed to close the "Fight"
       +      dialog before any new dialogs pop up
            - Incorrect handling of WM_CLOSE under Win32 fixed
            - Unix server now fails "gracefully" if it cannot create the Unix domain
              socket for admin connections
 (DIR) diff --git a/doc/protocol.html b/doc/protocol.html
       t@@ -396,7 +396,7 @@ C_REQUESTJET or C_FIGHTACT message<p /></dd>
        
        <dt><a name="abilities"><b>C_ABILITIES</b></a> ('<tt>r</tt>')</dt>
        <dd>Negotiates protocol extensions between client and server<br />
       -<tt>data</tt> = <tt>(playerid)(drugvalue)(newfight)(tstring)</tt>
       +<tt>data</tt> = <tt>(playerid)(drugvalue)(newfight)(tstring)(donefight)</tt>
        
        <p><a name="playerid"><tt>playerid</tt></a> = '1' if we use player IDs rather
        than player names to identify players in network messages ('0' otherwise). It is
       t@@ -424,7 +424,20 @@ sent in the <a href="i18n.html">translated string</a> (tstring) notation;
        only necessary if you are supporting non-English languages. Ability name
        in dopewars code: <b>A_TSTRING</b></p>
        
       -e.g. "^^Ar1010" (N.B. the double ^ is a feature of the "old" protocol)</dd>
       +<p><a name="donefight"><tt>donefight</tt></a> = '1' if, when a fight finishes,
       +the client is expected to send a C_DONE message to instruct the server to
       +move on. (This is to allow the user to close the fight dialog before any
       +new dialogs pop up.) Ability name in dopewars code: <b>A_DONEFIGHT</b></p>
       +
       +<p><b>N.B.</b> Only five abilities are listed here. Older servers or clients
       +may not only not support some of these abilities, they may not even know
       +of their existence (conversely, newer versions may add new abilities). Thus
       +all servers and clients, if passed an unexpectedly short abilities string,
       +should pad it out with zeroes. If passed a long string, it should be truncated.
       +This will cause these extra (or unspecified) abilities to be unsupported.
       +(The order of the abilities string should never change.)</p>
       +
       +e.g. "^^Ar10100" (N.B. the double ^ is a feature of the "old" protocol)</dd>
        
        </dl>
        
       t@@ -541,11 +554,12 @@ no C_ABILITIES reply message will be sent, and the client should assume that
        after the C_ABILITIES message to be compliant with these abilities.</p>
        
        e.g.<br />
       -- client sends "1110" (supports everything except
       +- client sends "11101" (supports everything except
        <a href="#tstring">A_TSTRING</a>)<br />
       -- server responds with "1011" (supports everything except
       -<a href="#drugvalue">A_DRUGVALUE</a>)<br />
       -- client should adopt the abilities "1010" (
       +- server responds with "10110" (supports everything except
       +<a href="#drugvalue">A_DRUGVALUE</a> and
       +<a href="#donefight">A_DONEFIGHT</a>)<br />
       +- client should adopt the abilities "10100" (
        <a href="#playerid">A_PLAYERID</a> and <a href="#newfight">A_NEWFIGHT</a>)</dd>
        
        </dl>
       t@@ -558,7 +572,7 @@ e.g.<br />
          </ul>
        </li>
        </ul>
       -<p>Last update: <b>29-10-2001</b></p>
       +<p>Last update: <b>13-04-2002</b></p>
        
        </body>
        </html>
 (DIR) diff --git a/src/AIPlayer.c b/src/AIPlayer.c
       t@@ -81,6 +81,7 @@ static void AIStartGame(Player *AIPlay)
        {
          Client = Network = TRUE;
          InitAbilities(AIPlay);
       +  SetAbility(AIPlay, A_DONEFIGHT, FALSE);
          SendAbilities(AIPlay);
        
          AISetName(AIPlay);
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -2321,6 +2321,9 @@ static void Curses_DoGame(Player *Play)
              switch (c) {
              case 'D':
                DisplayMode = DM_STREET;
       +        if (!(Play->Flags & FIGHTING) && HaveAbility(Play, A_DONEFIGHT)) {
       +          SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       +        }
                break;
              case 'R':
                if (RunHere) {
 (DIR) diff --git a/src/dopewars.h b/src/dopewars.h
       t@@ -64,6 +64,8 @@ typedef enum {
          A_NEWFIGHT,                   /* Use new unified fighting code */
          A_TSTRING,                    /* We understand the %Txx (tstring)
                                         * notation */
       +  A_DONEFIGHT,                  /* A fight is only considered over once the
       +                                 * client sends the server a C_DONE message */
          A_NUM                         /* N.B. Must be last */
        } AbilType;
        
       t@@ -125,7 +127,7 @@ typedef enum {
          E_FINISH = 100,
        
          E_OUTOFSYNC = 120,
       -  E_FIGHT, E_FIGHTASK, E_DOCTOR,
       +  E_FIGHT, E_FIGHTASK, E_DOCTOR, E_WAITDONE,
          E_MAXOOS
        } EventCode;
        
 (DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
       t@@ -791,6 +791,9 @@ static void FightCallback(GtkWidget *widget, gpointer data)
          switch (Answer) {
          case 'D':
            gtk_widget_hide(FightDialog);
       +    if (!(Play->Flags & FIGHTING) && HaveAbility(Play, A_DONEFIGHT)) {
       +      SendClientMessage(Play, C_NONE, C_DONE, NULL, NULL);
       +    }
            break;
          case 'R':
            if (CanRunHere) {
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -244,6 +244,7 @@ void InitAbilities(Player *Play)
          Play->Abil.Local[A_NEWFIGHT] = TRUE;
          Play->Abil.Local[A_DRUGVALUE] = (DrugValue ? TRUE : FALSE);
          Play->Abil.Local[A_TSTRING] = TRUE;
       +  Play->Abil.Local[A_DONEFIGHT] = TRUE;
        
          if (!Network)
            for (i = 0; i < A_NUM; i++) {
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -469,6 +469,10 @@ void HandleServerMessage(gchar *buf, Player *Play)
              } else {
                RunFromCombat(Play, i);
              }
       +      if (Play->EventNum == E_WAITDONE) {
       +        Play->EventNum = Play->ResyncNum;
       +        SendEvent(Play);
       +      }
            }
            if (NumTurns > 0 && Play->Turn >= NumTurns
                && Play->EventNum != E_FINISH) {
       t@@ -534,7 +538,10 @@ void HandleServerMessage(gchar *buf, Player *Play)
            HandleAnswer(Play, To, Data);
            break;
          case C_DONE:
       -    if (Play->EventNum != E_NONE && Play->EventNum < E_OUTOFSYNC) {
       +    if (Play->EventNum == E_WAITDONE) {
       +      Play->EventNum = Play->ResyncNum;
       +      SendEvent(Play);
       +    } else if (Play->EventNum != E_NONE && Play->EventNum < E_OUTOFSYNC) {
              Play->EventNum++;
              SendEvent(Play);
            }
       t@@ -2529,6 +2536,19 @@ void DoReturnFire(Player *Play)
          }
        }
        
       +/*
       + * Puts the given player into the "fight ended" state.
       + */
       +static void WaitForFightDone(Player *Play)
       +{
       +  if (HaveAbility(Play, A_DONEFIGHT)) {
       +    Play->EventNum = E_WAITDONE;
       +  } else {
       +    Play->EventNum = Play->ResyncNum;
       +    SendEvent(Play);
       +  }
       +}
       +
        /* 
         * Withdraws player "Play" from combat, and levies any penalties on
         * the player for this cowardly act, if applicable. If "ToLocation"
       t@@ -2570,8 +2590,7 @@ void RunFromCombat(Player *Play, int ToLocation)
            Play->IsAt = ToLocation;
            WithdrawFromCombat(Play);
            Play->IsAt = BackupAt;
       -    Play->EventNum = Play->ResyncNum;
       -    SendEvent(Play);
       +    WaitForFightDone(Play);
          } else {
            SendFightMessage(Play, NULL, 0, F_FAILFLEE, (price_t)0, TRUE, NULL);
            AllowNextShooter(Play);
       t@@ -2878,8 +2897,7 @@ void WithdrawFromCombat(Player *Play)
                SendQuestion(NULL, C_ASKSEW, Defend, text);
                g_free(text);
              } else {
       -        Defend->EventNum = Defend->ResyncNum;
       -        SendEvent(Defend);
       +        WaitForFightDone(Defend);
              }
            }
            g_ptr_array_free(Play->FightArray, TRUE);
       t@@ -3239,8 +3257,7 @@ void HandleAnswer(Player *From, Player *To, char *answer)
                From->Health = 100;
                SendPlayerData(From);
              }
       -      From->EventNum = From->ResyncNum;
       -      SendEvent(From);
       +      WaitForFightDone(From);
              break;
            default:
              break;
       t@@ -3276,8 +3293,7 @@ void HandleAnswer(Player *From, Player *To, char *answer)
              SendEvent(From);
              break;
            case E_DOCTOR:
       -      From->EventNum = From->ResyncNum;
       -      SendEvent(From);
       +      WaitForFightDone(From);
              break;
            case E_HIREBITCH:
            case E_GUNSHOP: