* PROTOCOL: Fill some missing possible error occurrences.
* TODO: Check off INVITE, ACCEPT, ERROR COMMAND, ERROR NO_USER
* src/ttt-server.h:
* src/ttt-server.c: (ttt_server_verify_username):
* src/ttt-client.c: (_ttt_client_execute_help),
(_ttt_client_execute_invite), (_ttt_client_execute_accept):
Implement INVITE, ACCEPT
+2005-12-05 Richard D. Worth <richard@theworths.org>
+
+ * PROTOCOL: Fill some missing possible error occurrences.
+
+ * TODO: Check off INVITE, ACCEPT, ERROR COMMAND, ERROR NO_USER
+
+ * src/ttt-server.h:
+ * src/ttt-server.c: (ttt_server_verify_username):
+ * src/ttt-client.c: (_ttt_client_execute_help),
+ (_ttt_client_execute_invite), (_ttt_client_execute_accept):
+ Implement INVITE, ACCEPT
+
2005-12-05 Richard D. Worth <richard@theworths.org>
* src/ttt-curses-client.c: (mvprintstr), (mvwprintstr), (wprint),
INVITE
- Possible errors: NO_USER, BUSY, NO_NAME_SET
+ Possible errors: NO_NAME_SET, NO_USER, BUSY
1.3.2. Accepting an invitation
ACCEPT
- Possible errors: NO_USER, NO_NAME_SET
+ Possible errors: NO_NAME_SET, NO_USER
1.3.3. Retracting an invitiation
RETRACT
- Possible errors: NO_USER, NO_NAME_SET
+ Possible errors: NO_NAME_SET, NO_USER
1.3.3. Declining an invitation
DECLINE
- Possible errors: NO_USER, NO_NAME_SET
+ Possible errors: NO_NAME_SET, NO_USER
1.4. In-game commands
6|7|8
Possible errors: NO_NAME_SET, NO_GAME, NOT_IN_GAME,
- NOT_YOUR_MOVE, NOT_GRID
+ NOT_PLAYING, NOT_YOUR_MOVE, NOT_GRID
2. Asynchronous notification.
'helo' must be sent before any command other than 'help',
'version', 'quit'.
- Possibly returned by: WHO MESSAGE INVITE ACCEPT SHOW PART MOVE
+ Possibly returned by: WHO, STATISTICS, MESSAGE, INVITE,
+ ACCEPT, RETRACT, DECLINE, SHOW, PART, MOVE
3.1.2. Invalid name
ERROR INVALID_NAME
- All names must be of non-zero length and must be unique.
+ All names must be of non-zero length and must be unique,
+ though case-insensitive.
Possibly returned by: HELO
ERROR COMMAND
- An invalid command was specified
-
+ An invalid command was specified.
+
3.2.2. Syntax
ERROR SYNTAX
- A syntax error was detected
+ A syntax error was detected.
3.2.3. Not number
ERROR NOT_NUMBER
- A non-numeric value was supplied where a number was required
+ A non-numeric value was supplied where a number was required.
+ Possibly returned by: MOVE
+
3.2.4. Not a grid number
ERROR NOT_GRID
- The number specified in the command was not a valid grid number
+ The number specified in the command was not a valid grid
+ number.
+
+ Possibly returned by: MOVE
3.3. Global command errors.
- There are no errors from any of the global commands
+ There are no global command errors from any of the global
+ commands.
3.4. Game management errors.
ERROR NO_GAME
- A game name was provided that does not exist.
+ A game id was provided that does not exist.
+
+ Possibly returned by: SHOW, PART, MOVE
3.5. User information errors
A user name was provided that does not exist.
+ Possibly returned by: STATISTICS, INVITE, ACCEPT, RETRACT,
+ DECLINE
+
3.6. In-game errors
3.6.1. Global game errors
- 3.6.1.1. Not in game
-
- ERROR NOT_IN_GAME
-
- A game playing command was made, but the user is not a
- particpant of any game.
-
- Possibly returned by: MOVE
-
- 3.6.1.2. Not playing
+ 3.6.1.1. Not playing
ERROR NOT_PLAYING
A command was executed by a watching user that is
- permitted only to players
+ permitted only to players.
+
+ Possibly returned by: MOVE
3.6.2. Moving errors
ERROR NOT_YOUR_TURN
- A move was submitted during the other player's turn
+ A move was submitted during the other player's turn.
Possibly returned by: MOVE
✓ 1.2.5. QUIT
✓ 1.2.6. VERSION
1.3. Game management commands
- 1.3.1. INVITE
- 1.3.2. ACCEPT
+✓ 1.3.1. INVITE
+✓ 1.3.2. ACCEPT
1.3.3. RETRACT
1.3.4. DECLINE
1.4. In-game commands
✓ 2.1.1. NOTICE USER <username>
✓ 2.1.2. NOTICE QUIT <username>
2.1.3. Game Invitation
- 2.1.3.1. NOTICE INVITE <username1> <username2>
- 2.1.3.2. NOTICE ACCEPT <usernmae2> <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.4. NOTICE NEWGAME <game> <username> <username>
✓ 3.1.1. ERROR NO_NAME_SET
✓ 3.1.2. ERROR INVALID_NAME
3.2. Command format errors
- 3.2.1. ERROR COMMAND
+✓ 3.2.1. ERROR COMMAND
✓ 3.2.2. ERROR SYNTAX
3.2.3. ERROR NOT_NUMBER
3.2.4. ERROR NOT_GRID
3.4. Game management errors.
3.4.1. ERROR NO_GAME
3.5. User information errors
- 3.5.1. ERROR NO_USER
+✓ 3.5.1. ERROR NO_USER
3.6. In-game errors
3.6.1. Global game errors
- 3.6.1.1. ERROR NOT_IN_GAME
- 3.6.1.2. ERROR NOT_PLAYING
+ 3.6.1.1. ERROR NOT_PLAYING
3.6.2. Moving errors
3.6.2.1. ERROR NOT_YOUR_TURN
char **args,
int num_args);
+static ttt_error_t
+_ttt_client_execute_invite (ttt_client_t *client,
+ char **args,
+ int num_args);
+
+static ttt_error_t
+_ttt_client_execute_accept (ttt_client_t *client,
+ char **args,
+ int num_args);
+
typedef struct _ttt_command_description {
const char *command;
int args_min;
{"HELP", 0, 1, _ttt_client_execute_help,
"HELP <command> ", "Display help for a command."},
+ {"INVITE", 1, 1, _ttt_client_execute_invite,
+ "INVITE <username> ", "Invite a player to play a game."},
+
+ {"ACCEPT", 1, 1, _ttt_client_execute_accept,
+ "ACCEPT <username> ", "Accept a game invitation."},
+
{"MESSAGE", 1, 1, _ttt_client_execute_message,
"MESSAGE <message> ", "Send a message to everyone."},
static ttt_error_t
_ttt_client_execute_help (ttt_client_t *client,
- char **args,
- int num_args)
+ char **args,
+ int num_args)
{
char *response;
char *command;
return TTT_ERROR_QUIT_REQUESTED;
}
+static ttt_error_t
+_ttt_client_execute_invite (ttt_client_t *client,
+ char **args,
+ int num_args)
+{
+ const char *username;
+ char *response;
+ char *notice;
+ ttt_error_t error;
+
+ assert (num_args == 1);
+
+ username = args[0];
+
+ if (!client->registered)
+ return TTT_ERROR_NO_NAME_SET;
+
+ error = ttt_server_verify_username (client->server, username);
+ if (error)
+ return error;
+
+ xasprintf (&response, "INVITE\r\n");
+ ttt_client_send (client, response);
+
+ xasprintf (¬ice, "NOTICE INVITE %s %s\r\n",
+ client->username,
+ username);
+ ttt_server_broadcast (client->server, notice);
+
+ free (notice);
+ free (response);
+
+ return TTT_ERROR_NONE;
+}
+
+static ttt_error_t
+_ttt_client_execute_accept (ttt_client_t *client,
+ char **args,
+ int num_args)
+{
+ const char *username;
+ char *response;
+ char *notice;
+ ttt_error_t error;
+
+ assert (num_args == 1);
+
+ username = args[0];
+
+ if (!client->registered)
+ return TTT_ERROR_NO_NAME_SET;
+
+ error = ttt_server_verify_username (client->server, username);
+ if (error)
+ return error;
+
+ xasprintf (&response, "ACCEPT\r\n");
+ ttt_client_send (client, response);
+
+ xasprintf (¬ice, "NOTICE ACCEPT %s %s\r\n",
+ client->username,
+ username);
+ ttt_server_broadcast (client->server, notice);
+
+ /* XXX: Start a new game */
+
+ free (notice);
+ free (response);
+
+ return TTT_ERROR_NONE;
+}
+
static void
_free_request (ttt_client_t *client);
return TTT_ERROR_NONE;
}
+/* Exported: See ttt-server.h for documentation. */
+ttt_error_t
+ttt_server_verify_username (ttt_server_t *server, const char *username)
+{
+ ttt_bool_t usernamefound = FALSE;
+ char *client_username;
+ 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)
+ usernamefound = TRUE;
+ }
+
+ pthread_mutex_unlock (&server->mutex);
+
+ if (!usernamefound)
+ return TTT_ERROR_NO_USER;
+
+ return TTT_ERROR_NONE;
+}
+
/* Exported: See ttt-server.h for documentation. */
const char*
ttt_server_get_host (ttt_server_t *server)
const char *username,
char **response);
+/* Checks to see if the username is registered. If the username exists
+ * will return TTT_ERROR_NONE, else TTT_ERROR_NO_USER.
+ *
+ * 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_verify_username (ttt_server_t *server,
+ const char *username);
+
/* Gets the server hostname.
*
*/