]> git.cworth.org Git - ttt/commitdiff
2005-12-10 Richard D. Worth <richard@theworths.org>
authorRichard Worth <richard@theworths.org>
Sat, 10 Dec 2005 13:43:07 +0000 (13:43 +0000)
committerRichard Worth <richard@theworths.org>
Sat, 10 Dec 2005 13:43:07 +0000 (13:43 +0000)
        * TODO: check off INVITE, RETRACT, DECLINE, Game Invitation
        notices, Connection setup errors, NO_INVITE, User information
        errors.

        * src/ttt-client.c: (_ttt_client_execute_helo),
        (_ttt_client_execute_statistics), (_ttt_client_execute_message),
        (_ttt_client_execute_help), (_ttt_client_execute_version),
        (_ttt_client_execute_quit), (_ttt_client_execute_invite),
        (_ttt_client_execute_accept), (_ttt_client_execute_retract),
        (_ttt_client_execute_decline), (_read_request),
        (_execute_request),
        (_handle_requests_thread): Whitespace changes. Use exported get
        methods (get_username, get_num_wins). Use strcasecmp in place of
        toupper. Finish RETRACT, DECLINE.

        * src/ttt.h:
        * src/ttt-server.h:
        * src/ttt-server.c: (ttt_server_init),
        (ttt_server_register_client), (ttt_server_unregister_client),
        (ttt_server_verify_username),
        (ttt_server_get_client_from_username), (ttt_server_add_invite),
        (ttt_server_remove_invite): Add invite struct. Make username case
        insensitive (missed in register_client). Implement add_invite,
        remove_invite. Moved statistics to ttt-client.c

ChangeLog
TODO
src/ttt-client.c
src/ttt-server.c
src/ttt-server.h
src/ttt.h

index dd3bc913c544843499a3d786483f1b86eb3b306d..edb3e3b4eb19fe71e74cc77c4433037eb72ea119 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2005-12-10  Richard D. Worth  <richard@theworths.org>
+
+       * TODO: check off INVITE, RETRACT, DECLINE, Game Invitation
+       notices, Connection setup errors, NO_INVITE, User information
+       errors.
+
+       * src/ttt-client.c: (_ttt_client_execute_helo),
+       (_ttt_client_execute_statistics), (_ttt_client_execute_message),
+       (_ttt_client_execute_help), (_ttt_client_execute_version),
+       (_ttt_client_execute_quit), (_ttt_client_execute_invite),
+       (_ttt_client_execute_accept), (_ttt_client_execute_retract),
+       (_ttt_client_execute_decline), (_read_request),
+       (_execute_request),
+       (_handle_requests_thread): Whitespace changes. Use exported get
+       methods (get_username, get_num_wins). Use strcasecmp in place of
+       toupper. Finish RETRACT, DECLINE.
+
+       * src/ttt.h:
+       * src/ttt-server.h:
+       * src/ttt-server.c: (ttt_server_init),
+       (ttt_server_register_client), (ttt_server_unregister_client),
+       (ttt_server_verify_username),
+       (ttt_server_get_client_from_username), (ttt_server_add_invite),
+       (ttt_server_remove_invite): Add invite struct. Make username case
+       insensitive (missed in register_client). Implement add_invite,
+       remove_invite. Moved statistics to ttt-client.c
+
 2005-12-09  Carl Worth  <cworth@cworth.org>
 
        * src/ttt-server.c (ttt_server_unregister_client): Move client has
 2005-12-09  Carl Worth  <cworth@cworth.org>
 
        * src/ttt-server.c (ttt_server_unregister_client): Move client has
diff --git a/TODO b/TODO
index b6257c2be7d315f39b7c667222da2002fe3e0895..f54ef6225e00ac4a24f4a22cb7747489340c2b14 100644 (file)
--- a/TODO
+++ b/TODO
@@ -17,10 +17,10 @@ S C
 ✓   1.2.5. QUIT
 ✓   1.2.6. VERSION
     1.3. Game management commands
 ✓   1.2.5. QUIT
 ✓   1.2.6. VERSION
     1.3. Game management commands
-    1.3.1. INVITE
+   1.3.1. INVITE
     1.3.2. ACCEPT
     1.3.2. ACCEPT
-    1.3.3. RETRACT
-    1.3.4. DECLINE
+   1.3.3. RETRACT
+   1.3.4. DECLINE
     1.4. In-game commands
     1.4.1. SHOW
     1.4.2. PART
     1.4. In-game commands
     1.4.1. SHOW
     1.4.2. PART
@@ -29,11 +29,11 @@ S C
     2.1. Global notices
 ✓   2.1.1. NOTICE USER <username>
 ✓   2.1.2. NOTICE QUIT <username>
     2.1. Global notices
 ✓   2.1.1. NOTICE USER <username>
 ✓   2.1.2. NOTICE QUIT <username>
-    2.1.3. Game Invitation
+   2.1.3. Game Invitation
 ✓   2.1.3.1. NOTICE INVITE <username1> <username2>
 ✓   2.1.3.2. NOTICE ACCEPT <username2> <username1>
 ✓   2.1.3.1. NOTICE INVITE <username1> <username2>
 ✓   2.1.3.2. NOTICE ACCEPT <username2> <username1>
-    2.1.3.3. NOTICE RETRACT <username1> <username2>
-    2.1.3.4. NOTICE DECLINE <username2> <username1>
+   2.1.3.3. NOTICE RETRACT <username1> <username2>
+   2.1.3.4. NOTICE DECLINE <username2> <username1>
     2.1.4. NOTICE NEWGAME <game> <username> <username>
     2.1.5. NOTICE DISPOSE <game>
 ✓   2.1.6. NOTICE MESSAGE <username> <text>
     2.1.4. NOTICE NEWGAME <game> <username> <username>
     2.1.5. NOTICE DISPOSE <game>
 ✓   2.1.6. NOTICE MESSAGE <username> <text>
@@ -43,7 +43,7 @@ S C
     2.2.2. Move notices
     2.2.2.1. NOTICE MOVE <game> <username> <number>
     3. Errors
     2.2.2. Move notices
     2.2.2.1. NOTICE MOVE <game> <username> <number>
     3. Errors
-    3.1. Connection setup errors
+   3.1. Connection setup errors
 ✓   3.1.1. ERROR NO_NAME_SET
 ✓   3.1.2. ERROR INVALID_NAME
     3.2. Command format errors
 ✓   3.1.1. ERROR NO_NAME_SET
 ✓   3.1.2. ERROR INVALID_NAME
     3.2. Command format errors
@@ -53,9 +53,9 @@ S C
     3.2.4. ERROR NOT_GRID
     3.3. Global command errors.
     3.4. Game management errors.
     3.2.4. ERROR NOT_GRID
     3.3. Global command errors.
     3.4. Game management errors.
-    3.4.1. ERROR NO_INVITE
+   3.4.1. ERROR NO_INVITE
     3.4.2. ERROR NO_GAME
     3.4.2. ERROR NO_GAME
-    3.5. User information errors
+   3.5. User information errors
 ✓   3.5.1. ERROR NO_USER
     3.6. In-game errors
     3.6.1. Global game errors
 ✓   3.5.1. ERROR NO_USER
     3.6. In-game errors
     3.6.1. Global game errors
index e68f70ca5cbde835021b053814eec7098ec22ff4..c198d3a15cfdb6779bbeea9f40b2ea7ddcfe3dae 100644 (file)
@@ -127,10 +127,10 @@ ttt_command_description_t command_descriptions[] = {
      "ACCEPT <username>       ", "Accept a game invitation."},
 
     {"RETRACT", 1, 1, _ttt_client_execute_retract,
      "ACCEPT <username>       ", "Accept a game invitation."},
 
     {"RETRACT", 1, 1, _ttt_client_execute_retract,
-     "RETRACT <username>       ", "Retract a game invitation."},
+     "RETRACT <username>      ", "Retract a game invitation."},
 
     {"DECLINE", 1, 1, _ttt_client_execute_decline,
 
     {"DECLINE", 1, 1, _ttt_client_execute_decline,
-     "DECLINE <username>       ", "Decline a game invitation."},
+     "DECLINE <username>      ", "Decline a game invitation."},
 
     {"MESSAGE", 1, 1, _ttt_client_execute_message,
      "MESSAGE <message>       ", "Send a message to everyone."},
 
     {"MESSAGE", 1, 1, _ttt_client_execute_message,
      "MESSAGE <message>       ", "Send a message to everyone."},
@@ -155,30 +155,34 @@ _ttt_client_execute_helo (ttt_client_t *client,
                          char         **args,
                          int          num_args)
 {
                          char         **args,
                          int          num_args)
 {
+    char        *response;
+    char        *notice;
     ttt_error_t error;
     ttt_error_t error;
-    char *response;
-    char *notice;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    ttt_client_set_username (client, args[0]);
+    if (!(client->registered))
+    {
+       ttt_client_set_username (client, args[0]);
 
 
-    error = ttt_server_register_client (client->server, client);
-    if (error)
-       return error;
-    client->registered = TRUE;
+       error = ttt_server_register_client (client->server, client);
+       if (error)
+           return error;
+       client->registered = TRUE;
+
+       xasprintf (&notice, "NOTICE USER %s\r\n",
+                  ttt_client_get_username (client));
+       ttt_server_broadcast (client->server, notice);
+
+       free (notice);
+    }
 
     xasprintf (&response, "HELO %s %s %s\r\n",
 
     xasprintf (&response, "HELO %s %s %s\r\n",
-              client->username,
+              ttt_client_get_username (client),
               ttt_server_get_host (client->server),
               ttt_server_get_port (client->server));
     ttt_client_send (client, response);
 
               ttt_server_get_host (client->server),
               ttt_server_get_port (client->server));
     ttt_client_send (client, response);
 
-    xasprintf (&notice, "NOTICE USER %s\r\n",
-              client->username);
-    ttt_server_broadcast (client->server, notice);
-
-    free (notice);
     free (response);
 
     return TTT_ERROR_NONE;
     free (response);
 
     return TTT_ERROR_NONE;
@@ -209,21 +213,30 @@ _ttt_client_execute_statistics (ttt_client_t *client,
                                char         **args,
                                int          num_args)
 {
                                char         **args,
                                int          num_args)
 {
-    char *response;
-    char *username;
-    ttt_error_t error;
+    const char   *argusername;
+    ttt_client_t *argclient;
+    char         *response;
+    ttt_error_t  error;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    username = args[0];
+    argusername = args[0];
 
     if (!client->registered)
        return TTT_ERROR_NO_NAME_SET;
 
 
     if (!client->registered)
        return TTT_ERROR_NO_NAME_SET;
 
-    error = ttt_server_statistics (client->server, username, &response);
+    error = ttt_server_get_client_from_username (client->server,
+                                                argusername,
+                                                &argclient);
     if (error)
        return error;
 
     if (error)
        return error;
 
+    xasprintf (&response, "STATISTICS %s \"\r\n"
+              "TICTACTOE WINS %d\r\n"
+              "\"\r\n",
+              ttt_client_get_username(argclient),
+              ttt_client_get_num_wins(argclient));
+
     ttt_client_send (client, response);
 
     free (response);
     ttt_client_send (client, response);
 
     free (response);
@@ -236,11 +249,14 @@ _ttt_client_execute_message (ttt_client_t  *client,
                             char          **args,
                             int           num_args)
 {
                             char          **args,
                             int           num_args)
 {
-    char *response;
-    char *notice;
+    const char *argmessage;
+    char       *response;
+    char       *notice;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
+    argmessage = args[0];
+
     if (!client->registered)
        return TTT_ERROR_NO_NAME_SET;
 
     if (!client->registered)
        return TTT_ERROR_NO_NAME_SET;
 
@@ -248,8 +264,8 @@ _ttt_client_execute_message (ttt_client_t  *client,
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE MESSAGE %s \"%s\"\r\n",
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE MESSAGE %s \"%s\"\r\n",
-             client->username,
-             args[0]);
+              ttt_client_get_username(client),
+              argmessage);
     ttt_server_broadcast (client->server, notice);
 
     free (notice);
     ttt_server_broadcast (client->server, notice);
 
     free (notice);
@@ -263,11 +279,11 @@ _ttt_client_execute_help (ttt_client_t  *client,
                          char          **args,
                          int           num_args)
 {
                          char          **args,
                          int           num_args)
 {
-    char *response;
-    char *command;
+    char                      *response;
+    char                      *argcommand;
     ttt_command_description_t *desc;
     ttt_command_description_t *desc;
+    ttt_bool_t                is_command = FALSE;
     int i;
     int i;
-    ttt_bool_t is_command = FALSE;
     
     if (num_args == 0) {
        xasprintf (&response, "HELP \"\r\n"
     
     if (num_args == 0) {
        xasprintf (&response, "HELP \"\r\n"
@@ -281,12 +297,10 @@ _ttt_client_execute_help (ttt_client_t  *client,
        }
        xasprintf (&response, "%s\"\r\n", response);
     } else {
        }
        xasprintf (&response, "%s\"\r\n", response);
     } else {
-       command = args[0];
-       for (i = 0; i < strlen (command); i++)
-           command[i] = toupper (command[i]);
+       argcommand = args[0];
        for (i = 0; i < ARRAY_SIZE(command_descriptions); i++) {
            desc = &command_descriptions[i];
        for (i = 0; i < ARRAY_SIZE(command_descriptions); i++) {
            desc = &command_descriptions[i];
-           if (strcmp (desc->command, command) == 0) {
+           if (strcasecmp (desc->command, argcommand) == 0) {
                is_command = TRUE;
                xasprintf (&response, "HELP %s \"\r\n"
                           "%s\r\n"
                is_command = TRUE;
                xasprintf (&response, "HELP %s \"\r\n"
                           "%s\r\n"
@@ -317,20 +331,20 @@ _ttt_client_execute_version (ttt_client_t  *client,
                             int           num_args)
 {
     char *response;
                             int           num_args)
 {
     char *response;
-    char *clientversion;
-    int version;
+    char *argversion;
+    int  version;
     int i;
 
     assert (num_args == 1);
 
     int i;
 
     assert (num_args == 1);
 
-    clientversion = args[0];
+    argversion = args[0];
 
     /* Verify that provided version arg is a positive integer */
 
     /* Verify that provided version arg is a positive integer */
-    for (i = 0; i < strlen(clientversion); i++)
-       if (!isdigit (clientversion[i]))
+    for (i = 0; i < strlen(argversion); i++)
+       if (!isdigit (argversion[i]))
            return TTT_ERROR_SYNTAX;
 
            return TTT_ERROR_SYNTAX;
 
-    version = atoi (clientversion);
+    version = atoi (argversion);
 
     if (version < 1)
        return TTT_ERROR_SYNTAX;
 
     if (version < 1)
        return TTT_ERROR_SYNTAX;
@@ -338,7 +352,8 @@ _ttt_client_execute_version (ttt_client_t  *client,
     if (version > TTT_SERVER_PROTOCOL_VERSION)
        version = TTT_SERVER_PROTOCOL_VERSION;
 
     if (version > TTT_SERVER_PROTOCOL_VERSION)
        version = TTT_SERVER_PROTOCOL_VERSION;
 
-    xasprintf (&response, "VERSION %d\r\n", version);
+    xasprintf (&response, "VERSION %d\r\n",
+              version);
     ttt_client_send (client, response);
 
     free (response);
     ttt_client_send (client, response);
 
     free (response);
@@ -358,7 +373,7 @@ _ttt_client_execute_quit (ttt_client_t *client,
        return TTT_ERROR_QUIT_REQUESTED;
     
     xasprintf (&notice, "NOTICE QUIT %s\r\n",
        return TTT_ERROR_QUIT_REQUESTED;
     
     xasprintf (&notice, "NOTICE QUIT %s\r\n",
-              client->username);
+              ttt_client_get_username(client));
     ttt_server_broadcast (client->server, notice);
     
     free (notice);
     ttt_server_broadcast (client->server, notice);
     
     free (notice);
@@ -371,32 +386,37 @@ _ttt_client_execute_invite (ttt_client_t *client,
                            char         **args,
                            int          num_args)
 {
                            char         **args,
                            int          num_args)
 {
-    const char *username;
-    char *response;
-    char *notice;
-    ttt_error_t error;
+    const char   *invitee_username;
+    ttt_client_t *invitee;
+    char         *response;
+    char         *notice;
+    ttt_error_t  error;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    username = args[0];
+    invitee_username = args[0];
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
-    error = ttt_server_verify_username (client->server,        username);
+    error = ttt_server_get_client_from_username (client->server,
+                                                invitee_username,
+                                                &invitee);
     if (error)
        return error;
 
     if (error)
        return error;
 
+    ttt_server_add_invite (client->server,
+                          client,
+                          invitee);
+
     xasprintf (&response, "INVITE\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE INVITE %s %s\r\n",
     xasprintf (&response, "INVITE\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE INVITE %s %s\r\n",
-              client->username,
-              username);
+              ttt_client_get_username(client),
+              ttt_client_get_username(invitee));
     ttt_server_broadcast (client->server, notice);
 
     ttt_server_broadcast (client->server, notice);
 
-    /* XXX: Store invitation in state */
-
     free (notice);
     free (response);
 
     free (notice);
     free (response);
 
@@ -408,30 +428,37 @@ _ttt_client_execute_accept (ttt_client_t *client,
                            char         **args,
                            int          num_args)
 {
                            char         **args,
                            int          num_args)
 {
-    const char *username;
-    char *response;
-    char *notice;
-    ttt_error_t error;
+    const char   *actor_username;
+    ttt_client_t *actor;
+    char         *response;
+    char         *notice;
+    ttt_error_t  error;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    username = args[0];
+    actor_username = args[0];
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
-    error = ttt_server_verify_username (client->server,        username);
+    error = ttt_server_get_client_from_username (client->server,
+                                                actor_username,
+                                                &actor);
     if (error)
        return error;
 
     if (error)
        return error;
 
-    /* XXX: Verify invitation, else return ERROR NO_INVITE */
+    error = ttt_server_remove_invite (client->server,
+                                     actor,
+                                     client);
+    if (error)
+       return error;
 
     xasprintf (&response, "ACCEPT\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE ACCEPT %s %s\r\n",
 
     xasprintf (&response, "ACCEPT\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE ACCEPT %s %s\r\n",
-              client->username,
-              username);
+              ttt_client_get_username(client),
+              ttt_client_get_username(actor));
     ttt_server_broadcast (client->server, notice);
 
     /* XXX: Start a new game */
     ttt_server_broadcast (client->server, notice);
 
     /* XXX: Start a new game */
@@ -447,34 +474,39 @@ _ttt_client_execute_retract (ttt_client_t *client,
                             char         **args,
                             int          num_args)
 {
                             char         **args,
                             int          num_args)
 {
-    const char *username;
-    char *response;
-    char *notice;
-    ttt_error_t error;
+    const char   *invitee_username;
+    ttt_client_t *invitee;
+    char         *response;
+    char         *notice;
+    ttt_error_t  error;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    username = args[0];
+    invitee_username = args[0];
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
-    error = ttt_server_verify_username (client->server,        username);
+    error = ttt_server_get_client_from_username (client->server,
+                                                invitee_username,
+                                                &invitee);
     if (error)
        return error;
 
     if (error)
        return error;
 
-    /* XXX: Verify invitation, else return ERROR NO_INVITE */
-
+    error = ttt_server_remove_invite (client->server,
+                                     client,
+                                     invitee);
+    if (error)
+       return error;
+    
     xasprintf (&response, "RETRACT\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE RETRACT %s %s\r\n",
     xasprintf (&response, "RETRACT\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE RETRACT %s %s\r\n",
-              client->username,
-              username);
+              ttt_client_get_username(client),
+              ttt_client_get_username(invitee));
     ttt_server_broadcast (client->server, notice);
 
     ttt_server_broadcast (client->server, notice);
 
-    /* XXX: Remove invitiation from state */
-
     free (notice);
     free (response);
 
     free (notice);
     free (response);
 
@@ -486,34 +518,39 @@ _ttt_client_execute_decline (ttt_client_t *client,
                             char         **args,
                             int          num_args)
 {
                             char         **args,
                             int          num_args)
 {
-    const char *username;
-    char *response;
-    char *notice;
-    ttt_error_t error;
+    const char   *actor_username;
+    ttt_client_t *actor;
+    char         *response;
+    char         *notice;
+    ttt_error_t  error;
 
     assert (num_args == 1);
 
 
     assert (num_args == 1);
 
-    username = args[0];
+    actor_username = args[0];
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
 
     if (!client->registered)
         return TTT_ERROR_NO_NAME_SET;
 
-    error = ttt_server_verify_username (client->server,        username);
+    error = ttt_server_get_client_from_username (client->server,
+                                                actor_username,
+                                                &actor);
     if (error)
        return error;
 
     if (error)
        return error;
 
-    /* XXX: Verify invitation, else return ERROR NO_INVITE */
+    error = ttt_server_remove_invite (client->server,
+                                     actor,
+                                     client);
+    if (error)
+       return error;
 
     xasprintf (&response, "DECLINE\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE DECLINE %s %s\r\n",
 
     xasprintf (&response, "DECLINE\r\n");
     ttt_client_send (client, response);
 
     xasprintf (&notice, "NOTICE DECLINE %s %s\r\n",
-              client->username,
-              username);
+              ttt_client_get_username(client),
+              ttt_client_get_username(actor));
     ttt_server_broadcast (client->server, notice);
 
     ttt_server_broadcast (client->server, notice);
 
-    /* XXX: Remove invitation from state */
-
     free (notice);
     free (response);
 
     free (notice);
     free (response);
 
@@ -598,7 +635,7 @@ _free_request (ttt_client_t *client)
 static ttt_status_t
 _read_request (ttt_client_t *client)
 {
 static ttt_status_t
 _read_request (ttt_client_t *client)
 {
-    ttt_token_t token;
+    ttt_token_t      token;
     ttt_token_type_t token_type;
 
     _free_request (client);
     ttt_token_type_t token_type;
 
     _free_request (client);
@@ -627,11 +664,10 @@ _read_request (ttt_client_t *client)
 static ttt_error_t
 _execute_request (ttt_client_t *client)
 {
 static ttt_error_t
 _execute_request (ttt_client_t *client)
 {
-    int i;
-
-    char *command = client->request_strings[0];
-    int num_args = client->num_request_strings-1;
+    char                      *command = client->request_strings[0];
+    int                       num_args = client->num_request_strings - 1;
     ttt_command_description_t *desc;
     ttt_command_description_t *desc;
+    int i;
 
     for (i = 0; i < strlen (command); i++)
        command[i] = toupper (command[i]);
 
     for (i = 0; i < strlen (command); i++)
        command[i] = toupper (command[i]);
@@ -654,11 +690,10 @@ static void *
 _handle_requests_thread (void *closure)
 {
     ttt_status_t status;
 _handle_requests_thread (void *closure)
 {
     ttt_status_t status;
-    ttt_error_t error;
     ttt_client_t *client = closure;
     ttt_client_t *client = closure;
+    ttt_error_t  error;
 
     while (1) {
 
     while (1) {
-
        status = _read_request (client);
        if (status == TTT_STATUS_EOF)
            break;
        status = _read_request (client);
        if (status == TTT_STATUS_EOF)
            break;
index cb28741885721763fd54abd4a8a83b270e07f442..4b29cf2f774d277dc14dd5bc675f4b5a9a25df6d 100644 (file)
 #include "ttt-error.h"
 #include "ttt-socket.h"
 
 #include "ttt-error.h"
 #include "ttt-socket.h"
 
+struct _ttt_invite {
+    ttt_client_t    *actor;
+    ttt_client_t    *invitee;
+};
+
 struct _ttt_server {
     pthread_mutex_t mutex;
 
 struct _ttt_server {
     pthread_mutex_t mutex;
 
-    const char *host;
-    const char *port;
+    const char      *host;
+    const char      *port;
 
 
-    ttt_client_t **clients;
-    int clients_size;
-    int num_clients;
+    ttt_client_t    **clients;
+    int             clients_size;
+    int             num_clients;
+
+    ttt_invite_t    **invites;
+    int             invites_size;
+    int             num_invites;
 };
 
 static void
 };
 
 static void
@@ -48,6 +57,10 @@ ttt_server_init (ttt_server_t *server, const char *host, const char *port)
     server->clients = NULL;
     server->clients_size = 0;
     server->num_clients = 0;
     server->clients = NULL;
     server->clients_size = 0;
     server->num_clients = 0;
+
+    server->invites = NULL;
+    server->invites_size = 0;
+    server->num_invites = 0;
 }
 
 /* Exported: See ttt-server.h for documentation. */
 }
 
 /* Exported: See ttt-server.h for documentation. */
@@ -68,7 +81,7 @@ ttt_server_register_client (ttt_server_t *server, ttt_client_t *client)
        return TTT_ERROR_INVALID_NAME;
 
     for (i = 0; i < server->num_clients; i++) {
        return TTT_ERROR_INVALID_NAME;
 
     for (i = 0; i < server->num_clients; i++) {
-       if (strcmp (ttt_client_get_username (server->clients[i]), username) == 0) {
+       if (strcasecmp (ttt_client_get_username (server->clients[i]), username) == 0) {
            error = TTT_ERROR_INVALID_NAME;
            goto CLEANUP_LOCK;
        }
            error = TTT_ERROR_INVALID_NAME;
            goto CLEANUP_LOCK;
        }
@@ -88,7 +101,7 @@ ttt_server_register_client (ttt_server_t *server, ttt_client_t *client)
                                    server->clients_size * sizeof (ttt_client_t *));
     }
 
                                    server->clients_size * sizeof (ttt_client_t *));
     }
 
-    server->clients [server->num_clients - 1] = client;
+    server->clients[server->num_clients - 1] = client;
 
  CLEANUP_LOCK:
     pthread_mutex_unlock (&server->mutex);
 
  CLEANUP_LOCK:
     pthread_mutex_unlock (&server->mutex);
@@ -100,10 +113,39 @@ ttt_server_register_client (ttt_server_t *server, ttt_client_t *client)
 void
 ttt_server_unregister_client (ttt_server_t *server, ttt_client_t *client)
 {
 void
 ttt_server_unregister_client (ttt_server_t *server, ttt_client_t *client)
 {
+    ttt_invite_t *invite;
+    char         *notice;
+    ttt_bool_t   send_notice = FALSE;
     int i;
 
     pthread_mutex_lock (&server->mutex);
 
     int i;
 
     pthread_mutex_lock (&server->mutex);
 
+    /* Auto-retract and decline pending notices */
+    /* Notices are sent after mutex unlock */
+    for (i = 0; i < server->num_invites; i++)
+    {
+       invite = server->invites[i];
+       if ((invite->actor == client) || (invite->invitee == client))
+       {
+           send_notice = TRUE;
+           if (invite->actor == client)
+               xasprintf (&notice, "%s" "NOTICE RETRACT %s %s\r\n",
+                          notice,
+                          ttt_client_get_username(invite->actor),
+                          ttt_client_get_username(invite->invitee));
+           else
+               xasprintf (&notice, "%s" "NOTICE DECLINE %s %s\r\n",
+                          notice,
+                          ttt_client_get_username(invite->invitee),
+                          ttt_client_get_username(invite->actor));
+
+           memmove (&server->invites[i], &server->invites[i+1],
+                    (server->num_invites - i - 1) * sizeof (ttt_invite_t *));
+           server->num_invites--;
+           i--;
+       }
+    }
+
     for (i = 0; i < server->num_clients; i++)
        if (server->clients[i] == client)
            break;
     for (i = 0; i < server->num_clients; i++)
        if (server->clients[i] == client)
            break;
@@ -118,6 +160,12 @@ ttt_server_unregister_client (ttt_server_t *server, ttt_client_t *client)
     server->num_clients--;
 
     pthread_mutex_unlock (&server->mutex);
     server->num_clients--;
 
     pthread_mutex_unlock (&server->mutex);
+
+    if (send_notice)
+    {
+       ttt_server_broadcast(server, notice);
+       free (notice);
+    }
 }
 
 /* Exported: See ttt-server.h for documentation. */
 }
 
 /* Exported: See ttt-server.h for documentation. */
@@ -159,24 +207,34 @@ ttt_server_who (ttt_server_t *server)
 
 /* Exported: See ttt-server.h for documentation. */
 ttt_error_t
 
 /* Exported: See ttt-server.h for documentation. */
 ttt_error_t
-ttt_server_statistics (ttt_server_t *server, const char *username, char **response)
+ttt_server_verify_username (ttt_server_t *server,
+                           const char   *username)
+{
+    ttt_client_t *client;
+
+    return ttt_server_get_client_from_username (server,
+                                               username,
+                                               &client);
+}
+
+/* Exported: See ttt-server.h for documentation. */
+ttt_error_t
+ttt_server_get_client_from_username (ttt_server_t *server,
+                                    const char   *username,
+                                    ttt_client_t **client)
 {
     ttt_bool_t usernamefound = FALSE;
     const char *client_username;
 {
     ttt_bool_t usernamefound = FALSE;
     const char *client_username;
-    int client_num_wins;
     int i;
 
     pthread_mutex_lock (&server->mutex);
 
     for (i = 0; i < server->num_clients; i++) {
        client_username = ttt_client_get_username (server->clients[i]);
     int i;
 
     pthread_mutex_lock (&server->mutex);
 
     for (i = 0; i < server->num_clients; i++) {
        client_username = ttt_client_get_username (server->clients[i]);
-       if (strcasecmp (username, client_username) == 0) {
+       if (strcasecmp (username, client_username) == 0)
+       {
            usernamefound = TRUE;
            usernamefound = TRUE;
-           client_num_wins = ttt_client_get_num_wins (server->clients[i]);
-           xasprintf (response, "STATISTICS %s \"\r\n"
-                      "TICTACTOE WINS %d\r\n\"\r\n",
-                      client_username,
-                      client_num_wins);
+           *client = server->clients[i];
        }
     }
 
        }
     }
 
@@ -190,28 +248,77 @@ ttt_server_statistics (ttt_server_t *server, const char *username, char **respon
 
 /* Exported: See ttt-server.h for documentation. */
 ttt_error_t
 
 /* Exported: See ttt-server.h for documentation. */
 ttt_error_t
-ttt_server_verify_username (ttt_server_t *server, const char *username)
+ttt_server_add_invite (ttt_server_t *server,
+                      ttt_client_t *actor,
+                      ttt_client_t *invitee)
 {
 {
-    ttt_bool_t usernamefound = FALSE;
-    const char *client_username;
-    int i;
+    ttt_invite_t *invite;
 
     pthread_mutex_lock (&server->mutex);
 
 
     pthread_mutex_lock (&server->mutex);
 
-    for (i = 0; i < server->num_clients; i++) {
-       client_username = ttt_client_get_username (server->clients[i]);
-       if (strcasecmp (username, client_username) == 0)
-           usernamefound = TRUE;
+    invite = xmalloc (sizeof (ttt_invite_t));
+
+    invite->actor = actor;
+    invite->invitee = invitee;
+
+    server->num_invites++;
+
+    if (server->num_invites > server->invites_size) {
+       if (server->invites_size == 0)
+           server->invites_size = 1;
+       else
+           server->invites_size *= 2;
+
+       server->invites = xrealloc (server->invites,
+                                   server->invites_size * sizeof (ttt_invite_t *));
     }
 
     }
 
-    pthread_mutex_unlock (&server->mutex);
+    server->invites[server->num_invites - 1] = invite;
 
 
-    if (!usernamefound)
-       return TTT_ERROR_NO_USER;
+    pthread_mutex_unlock (&server->mutex);
 
     return TTT_ERROR_NONE;
 }
 
 
     return TTT_ERROR_NONE;
 }
 
+/* Exported: See ttt-server.h for documentation. */
+ttt_error_t
+ttt_server_remove_invite (ttt_server_t *server,
+                         ttt_client_t *actor,
+                         ttt_client_t *invitee)
+{
+    ttt_invite_t *invite;
+    ttt_error_t  error;
+    int i;
+
+    pthread_mutex_lock (&server->mutex);
+
+    error = TTT_ERROR_NO_INVITE;
+    for (i = 0; i < server->num_invites; i++)
+    {
+       invite = server->invites[i];
+       if ((invite->actor == actor) && (invite->invitee == invitee))
+       {
+           error = TTT_ERROR_NONE;
+           break;
+       }
+    }
+
+    if (error)
+       goto CLEANUP_LOCK;
+
+    assert (i < server->num_invites);
+
+    memmove (&server->invites[i], &server->invites[i+1],
+            (server->num_invites - i - 1) * sizeof (ttt_invite_t *));
+
+    server->num_invites--;
+
+ CLEANUP_LOCK:
+    pthread_mutex_unlock (&server->mutex);
+
+    return error;
+}
+
 /* Exported: See ttt-server.h for documentation. */
 const char*
 ttt_server_get_host (ttt_server_t *server)
 /* Exported: See ttt-server.h for documentation. */
 const char*
 ttt_server_get_host (ttt_server_t *server)
@@ -237,7 +344,7 @@ static const char *WELCOME_MESSAGE =
 "      telnet %s %s\r\n"
 "\r\n"
 "The TTTP (tic-tac-toe protocol) has been partially implemented.\r\n"
 "      telnet %s %s\r\n"
 "\r\n"
 "The TTTP (tic-tac-toe protocol) has been partially implemented.\r\n"
-"The following commands should work: HELO, HELP, MESSAGE, VERSION, QUIT, WHO.\r\n"
+"The following commands should work: HELO, HELP, INVITE, ACCEPT, RETRACT, DECLINE, MESSAGE, STATISTICS, QUIT, VERSION, WHO.\r\n"
 "\r\n";
 
 static void
 "\r\n";
 
 static void
index 8d0f9c410ac6a9ef69e83ba41aa0e84693ae36c7..80f22bf25b0ffa9ce1884931e59524966fcc5a27 100644 (file)
@@ -73,10 +73,38 @@ ttt_server_broadcast (ttt_server_t *server, const char *message);
 const char*
 ttt_server_who (ttt_server_t *server);
 
 const char*
 ttt_server_who (ttt_server_t *server);
 
-/* Generates the statistics for the user. If the function does not
- * return an error, the response will be allocated in this function
- * and will need to be free'd by the caller.
+/* Checks to see whether a username exists.
  *
  *
+ * Returns: ttt_server_get_client_from_username(server, username)
+ *
+ * Locking: See ttt_server_get_client_from_username
+ *
+ * Errors: See ttt_server_get_client_from_username
+ */
+ttt_error_t
+ttt_server_verify_username (ttt_server_t *server,
+                           const char *username);
+
+/* Points *client to the client with the supplied username, else
+ * leaves *client unhanged.
+ * 
+ * Returns: TTT_ERROR_NONE, else TTT_ERROR_NO_USER if username not
+ * found. 
+ *
+ * Locking: The server mutex will be acquired and held throughout the
+ * execution of this function. Each client mutex may also be acquired
+ * and held by functions called during the execution of this function.
+ *
+ * Errors: If an error such as an IO error occurs, this function will
+ * not return.
+ */
+ttt_error_t
+ttt_server_get_client_from_username (ttt_server_t *server,
+                                    const char   *username,
+                                    ttt_client_t **client);
+
+/* Adds an invitation
+ * 
  * Locking: The server mutex will be acquired and held throughout the
  * execution of this function. Each client mutex may also be acquired
  * and held by functions called during the execution of this function.
  * Locking: The server mutex will be acquired and held throughout the
  * execution of this function. Each client mutex may also be acquired
  * and held by functions called during the execution of this function.
@@ -85,13 +113,15 @@ ttt_server_who (ttt_server_t *server);
  * not return.
  */
 ttt_error_t
  * not return.
  */
 ttt_error_t
-ttt_server_statistics (ttt_server_t *server,
-                      const char *username,
-                      char **response);
+ttt_server_add_invite (ttt_server_t *server,
+                      ttt_client_t *actor,
+                      ttt_client_t *invitee);
 
 
-/* Checks to see if the username is registered. If the username exists
- * will return TTT_ERROR_NONE, else TTT_ERROR_NO_USER.
+/* Removes an invitation
  *
  *
+ * Returns: TTT_ERROR_NONE, else TTT_ERROR_NO_INVITE if no invite
+ * found.
+ * 
  * Locking: The server mutex will be acquired and held throughout the
  * execution of this function. Each client mutex may also be acquired
  * and held by functions called during the execution of this function.
  * Locking: The server mutex will be acquired and held throughout the
  * execution of this function. Each client mutex may also be acquired
  * and held by functions called during the execution of this function.
@@ -100,8 +130,9 @@ ttt_server_statistics (ttt_server_t *server,
  * not return.
  */
 ttt_error_t
  * not return.
  */
 ttt_error_t
-ttt_server_verify_username (ttt_server_t *server,
-                           const char *username);
+ttt_server_remove_invite (ttt_server_t *server,
+                         ttt_client_t *actor,
+                         ttt_client_t *invitee);
 
 /* Gets the server hostname.
  *
 
 /* Gets the server hostname.
  *
index 5c141695b87c6bcc9598b2c12a171ef8ece0cb00..5b4a807fb4f0258a62bc16a48a1601e1b072311b 100644 (file)
--- a/src/ttt.h
+++ b/src/ttt.h
@@ -73,6 +73,7 @@ typedef enum {
 } ttt_status_t;
 
 typedef struct _ttt_server ttt_server_t;
 } ttt_status_t;
 
 typedef struct _ttt_server ttt_server_t;
+typedef struct _ttt_invite ttt_invite_t;
 typedef struct _ttt_client ttt_client_t;
 
 #include "x.h"
 typedef struct _ttt_client ttt_client_t;
 
 #include "x.h"