From 5aa4056633b598ed58146239ab2240548c41240d Mon Sep 17 00:00:00 2001 From: "Gergely Polonkai (W00d5t0ck)" Date: Thu, 22 Mar 2012 18:34:39 +0100 Subject: [PATCH] Made this commit on a wrong branch... added basic player handling method (no login yet) --- conf/wmud.conf.example | 1 + src/db.c | 113 ++++++++++++++++++++++++++++++ src/db.h | 4 +- src/main.c | 71 +++++++++++++++++-- src/main.h | 3 + src/networking.c | 152 +++++++++++++++++++++++++++++++++++------ src/networking.h | 4 +- src/players.c | 36 ++++++++++ src/players.h | 4 ++ src/wmud_types.h | 40 +++++++---- 10 files changed, 386 insertions(+), 42 deletions(-) diff --git a/conf/wmud.conf.example b/conf/wmud.conf.example index 0c3a386..333c778 100644 --- a/conf/wmud.conf.example +++ b/conf/wmud.conf.example @@ -1,3 +1,4 @@ [global] world file = iminiru.db port = 4000 +admin email = polesz@w00d5t0ck.info diff --git a/src/db.c b/src/db.c index ff181f2..0f31aa1 100644 --- a/src/db.c +++ b/src/db.c @@ -1,13 +1,126 @@ #include #include +#include "main.h" #include "db.h" +#include "players.h" sqlite3 *dbh = NULL; gboolean wmud_db_init(GError **err) { + GString *db_file = g_string_new(WMUD_STATEDIR); + int sqlite_code; + + g_string_append_printf(db_file, "/%s", database_file); + + if ((sqlite_code = sqlite3_open(db_file->str, &dbh)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_CANTOPEN, "Can not open databsae file (%s): %s", db_file->str, sqlite3_errmsg(dbh)); + + return FALSE; + } + + return TRUE; +} + +gboolean +wmud_db_players_load(GError **err) +{ + sqlite3_stmt *sth = NULL; + int sqlite_code; + + if (dbh == NULL) + { + if (err) + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_NOINIT, "Database backend not initialized"); + + return FALSE; + } + + if ((sqlite_code = sqlite3_prepare_v2(dbh, "SELECT id, login, password, email FROM players", -1, &sth, NULL)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Bad query in wmud_db_players_load(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + while (1) + { + sqlite_code = sqlite3_step(sth); + if (sqlite_code == SQLITE_ROW) + { + wmudPlayer *player = g_new0(wmudPlayer, 1); + player->id = sqlite3_column_int(sth, 0); + player->player_name = g_strdup((gchar *)sqlite3_column_text(sth, 1)); + player->cpassword = g_strdup((gchar *)sqlite3_column_text(sth, 2)); + player->email = g_strdup((gchar *)sqlite3_column_text(sth, 3)); + player->registering = (player->cpassword == NULL); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Loaded player _%s_", player->player_name); + + players = g_slist_prepend(players, player); + } + else if (sqlite_code == SQLITE_DONE) + { + break; + } + else + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Query error in wmud_db_players_load(): %s", sqlite3_errmsg(dbh)); + return FALSE; + } + } + + sqlite3_finalize(sth); + return FALSE; } +gboolean +wmud_db_save_player(wmudPlayer *player, GError **err) +{ + sqlite3_stmt *sth = NULL; + int sqlite_code; + + if (dbh == NULL) + { + if (err) + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_NOINIT, "Database backend not initialized"); + + return FALSE; + } + + if ((sqlite_code = sqlite3_prepare_v2(dbh, "INSERT INTO players (id, login, password, email) VALUES (NULL, ?, NULL, ?)", -1, &sth, NULL)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Bad query in wmud_db_player_save(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + if ((sqlite_code = sqlite3_bind_text(sth, 1, player->player_name, -1, SQLITE_STATIC)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Bad parameter in wmud_db_player_save(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + if ((sqlite_code = sqlite3_bind_text(sth, 2, player->email, -1, SQLITE_STATIC)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Bad parameter in wmud_db_player_save(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + if ((sqlite_code = sqlite3_step(sth)) != SQLITE_DONE) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Statement cannot be executed in wmud_db_player_save(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + g_clear_error(err); + return TRUE; +} + diff --git a/src/db.h b/src/db.h index e11e70a..af77597 100644 --- a/src/db.h +++ b/src/db.h @@ -6,8 +6,8 @@ #include "wmud_types.h" gboolean wmud_db_init(GError **err); -gboolean wmud_load_players(GError **err); -gboolean wmud_save_player(wmudPlayer *player, GError **err); +gboolean wmud_db_players_load(GError **err); +gboolean wmud_db_save_player(wmudPlayer *player, GError **err); #endif /* __WMUD__DB_H__ */ diff --git a/src/main.c b/src/main.c index 030ea3f..f928ef6 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "main.h" #include "networking.h" #include "interpreter.h" +#include "db.h" #define MAX_RECV_LEN 1024 @@ -21,8 +22,10 @@ guint32 elapsed_seconds = 0; guint32 elapsed_cycle = 0; GRand *main_rand = NULL; GQuark WMUD_CONFIG_ERROR = 0; +GQuark WMUD_DB_ERROR = 0; guint port = 0; gchar *database_file = NULL; +gchar *admin_email = NULL; /* rl_sec_elapsed() * @@ -39,6 +42,11 @@ rl_sec_elapsed(gpointer user_data) elapsed_cycle++; } + if (elapsed_seconds % 30 == 0) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Heartbeat"); + } + return TRUE; } @@ -67,6 +75,7 @@ void wmud_type_init(void) { WMUD_CONFIG_ERROR = g_quark_from_string("wmud_config_error"); + WMUD_DB_ERROR = g_quark_from_string("wmud_db_error"); } gboolean @@ -74,7 +83,7 @@ wmud_config_init(GError **err) { GString *config_file = g_string_new(WMUD_CONFDIR); GKeyFile *config; - GError *in_err; + GError *in_err = NULL; g_string_append(config_file, "/wmud.conf"); @@ -91,6 +100,7 @@ wmud_config_init(GError **err) return FALSE; } + g_clear_error(&in_err); port = g_key_file_get_integer(config, "global", "port", &in_err); if (in_err) { @@ -107,16 +117,18 @@ wmud_config_init(GError **err) return FALSE; } - } - g_clear_error(&in_err); + return FALSE; + } + + g_clear_error(&in_err); database_file = g_key_file_get_string(config, "global", "world file", &in_err); if (in_err) { if (g_error_matches(in_err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { g_set_error(err, WMUD_CONFIG_ERROR, WMUD_CONFIG_ERROR_NOWORLD, "Config file (%s) does not contain a world file path", config_file->str); - g_string_free(config_file, TRUE); + g_key_file_free(config); g_string_free(config_file, TRUE); database_file = NULL; @@ -124,6 +136,24 @@ wmud_config_init(GError **err) } } + g_clear_error(&in_err); + admin_email = g_key_file_get_string(config, "global", "admin email", &in_err); + if (in_err) + { + if (g_error_matches(in_err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + { + g_set_error(err, WMUD_CONFIG_ERROR, WMUD_CONFIG_ERROR_NOEMAIL, "Config file (%s) does not contain an admin e-mail address", config_file->str); + g_key_file_free(config); + g_string_free(config_file, TRUE); + admin_email = NULL; + + return FALSE; + } + } + + g_key_file_free(config); + g_string_free(config_file, TRUE); + return TRUE; } @@ -174,7 +204,38 @@ main(int argc, char **argv) g_assert(port != 0); g_assert(database_file != NULL); - wmud_networking_init(port); + + g_clear_error(&err); + if (!wmud_db_init(&err)) + { + if (err) + { + g_critical("Database initialization error: %s", err->message); + } + else + { + g_critical("Database initialization error!"); + } + + return 1; + } + g_clear_error(&err); + if (!wmud_networking_init(port, &err)) + { + if (err) + { + g_critical("Database initialization error: %s", err->message); + } + else + { + g_critical("Database initialization error!"); + } + + return 1; + } + + g_clear_error(&err); + wmud_db_players_load(&err); /* Run the game loop */ g_main_loop_run(game_loop); diff --git a/src/main.h b/src/main.h index 6ef7a50..d64621f 100644 --- a/src/main.h +++ b/src/main.h @@ -6,6 +6,9 @@ extern GMainContext *game_context; extern guint32 elapsed_seconds; extern GRand *main_rand; +extern gchar *database_file; +extern GQuark WMUD_DB_ERROR; +extern gchar *admin_email; #define random_number(a, b) g_rand_int_range(main_rand, (a), (b) + 1) diff --git a/src/networking.c b/src/networking.c index 9b96355..eeaf94a 100644 --- a/src/networking.c +++ b/src/networking.c @@ -7,6 +7,7 @@ #include "networking.h" #include "interpreter.h" #include "players.h" +#include "db.h" #define MAX_RECV_LEN 1024 @@ -17,19 +18,23 @@ struct AcceptData { GSList *clients; +void wmud_client_interpret_newplayer_email(wmudClient *client); +void wmud_client_interpret_newplayer_mailconfirm(wmudClient *client_data); + void -client_close(wmudClient *client, gboolean send_goodbye) +wmud_client_close(wmudClient *client, gboolean send_goodbye) { GError *err = NULL; if (send_goodbye) { - /* TODO: Send some goodbye text */ + wmud_client_send(client, "\r\nHave a nice real-world day!\r\n\r\n"); } - g_print("Connection closed.\n"); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Connection closed."); /* TODO: Error checking */ g_socket_close(client->socket, &err); clients = g_slist_remove(clients, client); + wmud_player_free(&(client->player)); if (client->buffer) g_string_free(client->buffer, TRUE); g_free(client); @@ -42,7 +47,7 @@ client_callback(GSocket *client, GIOCondition condition, wmudClient *client_data if (condition & G_IO_HUP) { - client_close(client_data, FALSE); + wmud_client_close(client_data, FALSE); return FALSE; } else if ((condition & G_IO_IN) || (condition & G_IO_PRI)) @@ -55,7 +60,7 @@ client_callback(GSocket *client, GIOCondition condition, wmudClient *client_data if ((len = g_socket_receive(client, buf, MAX_RECV_LEN, NULL, &err)) == 0) { g_free(buf); - client_close(client_data, FALSE); + wmud_client_close(client_data, FALSE); return FALSE; } @@ -87,10 +92,12 @@ client_callback(GSocket *client, GIOCondition condition, wmudClient *client_data switch (client_data->state) { case WMUD_CLIENT_STATE_FRESH: - wmud_client_start_login(client_data); + if (*(client_data->buffer->str)) + wmud_client_start_login(client_data); break; case WMUD_CLIENT_STATE_PASSWAIT: - wmud_player_auth(client_data); + if (*(client_data->buffer->str)) + wmud_player_auth(client_data); break; case WMUD_CLIENT_STATE_MENU: //wmud_client_interpret_menu_command(client_data); @@ -101,6 +108,15 @@ client_callback(GSocket *client, GIOCondition condition, wmudClient *client_data case WMUD_CLIENT_STATE_QUITWAIT: //wmud_interpret_quit_answer(client_data); break; + case WMUD_CLIENT_STATE_NEWCHAR: + wmud_client_interpret_newplayer_answer(client_data); + break; + case WMUD_CLIENT_STATE_REGISTERING: + wmud_client_interpret_newplayer_email(client_data); + break; + case WMUD_CLIENT_STATE_REGEMAIL_CONFIRM: + wmud_client_interpret_newplayer_mailconfirm(client_data); + break; } g_string_erase(client_data->buffer, 0, -1); @@ -149,20 +165,21 @@ game_source_callback(GSocket *socket, GIOCondition condition, struct AcceptData client_source = g_socket_create_source(client_socket, G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL); g_source_set_callback(client_source, (GSourceFunc)client_callback, client_data, NULL); g_source_attach(client_source, accept_data->context); - g_print("New connection.\n"); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "New connection."); + wmud_client_send(client_data, "By what name shall we call you? "); return TRUE; } gboolean -wmud_networking_init(guint port_number) +wmud_networking_init(guint port_number, GError **err) { struct AcceptData *accept_data; GSocketListener *game_listener; gboolean need_ipv4_socket = TRUE; GSocket *game_socket6, *game_socket4; - GError *err = NULL; + GError *in_err = NULL; GSource *game_net_source4 = NULL, *game_net_source6 = NULL; @@ -172,7 +189,7 @@ wmud_networking_init(guint port_number) /* The following snippet is borrowed from GLib 2.30's gsocketlistener.c * code, to create the necessary sockets to listen on both IPv4 and * IPv6 address */ - if ((game_socket6 = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &err)) != NULL) + if ((game_socket6 = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &in_err)) != NULL) { GInetAddress *inet_address; GSocketAddress *address; @@ -184,15 +201,15 @@ wmud_networking_init(guint port_number) g_socket_set_listen_backlog(game_socket6, 10); - result = g_socket_bind(game_socket6, address, TRUE, &err) - && g_socket_listen(game_socket6, &err); + result = g_socket_bind(game_socket6, address, TRUE, &in_err) + && g_socket_listen(game_socket6, &in_err); g_object_unref(address); if (!result) { g_object_unref(game_socket6); - g_print("Unable to create listener IPv6 socket!\n"); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Unable to create listener IPv6 socket"); return FALSE; } @@ -201,13 +218,13 @@ wmud_networking_init(guint port_number) game_net_source6 = g_socket_create_source(game_socket6, G_IO_IN, NULL); /* TODO: error checking */ - g_socket_listener_add_socket(game_listener, game_socket6, NULL, &err); + g_socket_listener_add_socket(game_listener, game_socket6, NULL, &in_err); } /* TODO: else { error checking } */ if (need_ipv4_socket) { - if ((game_socket4 = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &err)) != NULL) + if ((game_socket4 = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &in_err)) != NULL) { GInetAddress *inet_address; GSocketAddress *address; @@ -219,8 +236,8 @@ wmud_networking_init(guint port_number) g_socket_set_listen_backlog(game_socket4, 10); - result = g_socket_bind(game_socket4, address, TRUE, &err) - && g_socket_listen(game_socket4, &err); + result = g_socket_bind(game_socket4, address, TRUE, &in_err) + && g_socket_listen(game_socket4, &in_err); g_object_unref(address); @@ -230,20 +247,20 @@ wmud_networking_init(guint port_number) if (!game_socket6) g_object_unref(game_socket6); - g_print("Unable to create listener IPv4 socket!\n"); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Unable to create listener IPv4 socket!\n"); return FALSE; } game_net_source4 = g_socket_create_source(game_socket4, G_IO_IN, NULL); /* TODO: error checking */ - g_socket_listener_add_socket(game_listener, game_socket4, NULL, &err); + g_socket_listener_add_socket(game_listener, game_socket4, NULL, &in_err); } /* TODO: else { error checking } */ } else { if (game_socket6 != NULL) - g_clear_error(&err); + g_clear_error(&in_err); else return FALSE; } @@ -284,6 +301,97 @@ wmud_client_send(wmudClient *client, const gchar *fmt, ...) void wmud_client_start_login(wmudClient *client) { - g_print("Trying to login with playername '%s'\n", client->buffer->str); + wmudPlayer *player; + + if ((player = wmud_player_exists(client->buffer->str)) != NULL) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Trying to login with playername '%s'\n", client->buffer->str); + if (player->cpassword == NULL) + { + wmud_client_send(client, "Your registration is not finished yet.\r\n"); + wmud_client_close(client, TRUE); + } + } + else + { + client->player = g_new0(wmudPlayer, 1); + client->player->player_name = g_strdup(client->buffer->str); + client->state = WMUD_CLIENT_STATE_NEWCHAR; + wmud_client_send(client, "Is %s new to this game? [Y/N] ", client->buffer->str); + } +} + +void +wmud_client_interpret_newplayer_answer(wmudClient *client) +{ + if (g_ascii_strcasecmp(client->buffer->str, "n") == 0) + { + wmud_client_send(client, "What is your player-name, then? "); + client->state = WMUD_CLIENT_STATE_FRESH; + } + else if (g_ascii_strcasecmp(client->buffer->str, "y") == 0) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Creating new player\n"); + wmud_client_send(client, "Welcome to this MUD!\r\nPlease enter your e-mail address: "); + client->state = WMUD_CLIENT_STATE_REGISTERING; + } + else + { + wmud_client_send(client, "Sorry, but for this question I only understand 'Y' or 'N'.\r\nIs %s a new player here? [Y/N] ", client->player->player_name); + } +} + +void +wmud_client_interpret_newplayer_email(wmudClient *client) +{ + /* TODO: Error checking */ + GRegex *email_regex = g_regex_new("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$", G_REGEX_CASELESS, 0, NULL); + + if (!*(client->buffer->str)) + { + if (client->bademail) + { + wmud_client_close(client, TRUE); + } + } + + if (g_regex_match(email_regex, client->buffer->str, 0, NULL)) + { + client->player->email = g_strdup(client->buffer->str); + client->state = WMUD_CLIENT_STATE_REGEMAIL_CONFIRM; + wmud_client_send(client, "It seems to be a valid address to me, but could you write it again? "); + } + else + { + wmud_client_send(client, "\r\nSorry, but this e-mail address doesn't seem to be valid to me.\r\n\r\nIf you think this is a valid address, simply press enter to quit, and send an e-mail to %s from that address, so we can fix our e-mail validation code.\r\n\r\nIf you just mistyped your address, type it now: ", admin_email); + if (*(client->buffer->str)) + client->bademail = TRUE; + } +} + +void +wmud_client_interpret_newplayer_mailconfirm(wmudClient *client) +{ + GError *err = NULL; + + if (g_ascii_strcasecmp(client->player->email, client->buffer->str) == 0) + { + if (wmud_db_save_player(client->player, &err)) + wmud_client_send(client, "Good. We will generate the password for this player name, and send it to you\r\nvia e-mail. Please come back to us, if you get that code, so you can log\r\nin.\r\n"); + else + { + g_critical("wmud_db_save_player() error: %s", err->message); + wmud_client_send(client, "There was an error during the database update. Please try again later!\r\n"); + } + wmud_client_close(client, TRUE); + } + else + { + g_free(client->player->email); + client->player->email = NULL; + + wmud_client_send(client, "This is not the same as you entered before.\r\nLet's just try it again: "); + client->state = WMUD_CLIENT_STATE_REGISTERING; + } } diff --git a/src/networking.h b/src/networking.h index 7d7677b..a5e9db3 100644 --- a/src/networking.h +++ b/src/networking.h @@ -7,8 +7,10 @@ extern GSList *clients; -gboolean wmud_networking_init(guint port_number); +gboolean wmud_networking_init(guint port_number, GError **err); void wmud_client_send(wmudClient *client, const gchar *fmt, ...); void wmud_client_start_login(wmudClient *client); +void wmud_client_interpret_newplayer_answer(wmudClient *client); +void wmud_client_interpret_newplayer_email(wmudClient *client); #endif diff --git a/src/players.c b/src/players.c index f3d8a60..b585c43 100644 --- a/src/players.c +++ b/src/players.c @@ -21,8 +21,44 @@ #include "networking.h" #include "players.h" +GSList *players = NULL; + gboolean wmud_player_auth(wmudClient *client) { return FALSE; } + +static gint +find_player_by_name(wmudPlayer *player, gchar *player_name) +{ + return g_ascii_strcasecmp(player->player_name, player_name); +} + +wmudPlayer * +wmud_player_exists(gchar *player_name) +{ + GSList *player_elem; + + if ((player_elem = g_slist_find_custom(players, player_name, (GCompareFunc)find_player_by_name)) == NULL) + return NULL; + + return player_elem->data; + +} + +void +wmud_player_free(wmudPlayer **player) +{ + if (!*player) + return; + if ((*player)->player_name) + g_free((*player)->player_name); + if ((*player)->cpassword) + g_free((*player)->cpassword); + if ((*player)->email) + g_free((*player)->email); + g_free(*player); + *player = NULL; +} + diff --git a/src/players.h b/src/players.h index 0ab6097..a9cdbb9 100644 --- a/src/players.h +++ b/src/players.h @@ -23,6 +23,10 @@ #include "wmud_types.h" +extern GSList *players; + gboolean wmud_player_auth(wmudClient *client); +wmudPlayer *wmud_player_exists(gchar *player_name); +void wmud_player_free(wmudPlayer **player); #endif /* __WMUD_PLAYERS_H__ */ diff --git a/src/wmud_types.h b/src/wmud_types.h index 3a11e7d..beb6073 100644 --- a/src/wmud_types.h +++ b/src/wmud_types.h @@ -5,20 +5,26 @@ #include typedef enum { - WMUD_CLIENT_STATE_FRESH, /* Newly connected clients. We are waiting for - * a player name */ - WMUD_CLIENT_STATE_PASSWAIT, /* Player name entered, waiting for password */ - WMUD_CLIENT_STATE_MENU, /* Logged in players, waiting in the main menu. - * We are waiting for a menu item to be - * chosen.*/ - WMUD_CLIENT_STATE_INGAME, /* Player is in-game */ - WMUD_CLIENT_STATE_QUITWAIT /* Waiting for answer for the quit question */ + WMUD_CLIENT_STATE_FRESH, /* Newly connected clients. We are waiting for + * a player name */ + WMUD_CLIENT_STATE_PASSWAIT, /* Player name entered, waiting for password */ + WMUD_CLIENT_STATE_MENU, /* Logged in players, waiting in the main menu. + * We are waiting for a menu item to be + * chosen.*/ + WMUD_CLIENT_STATE_INGAME, /* Player is in-game */ + WMUD_CLIENT_STATE_QUITWAIT, /* Waiting for answer for the quit question */ + WMUD_CLIENT_STATE_NEWCHAR, /* Waiting for answer for the new + * character question */ + WMUD_CLIENT_STATE_REGISTERING, /* Player registration starts */ + WMUD_CLIENT_STATE_REGEMAIL_CONFIRM /* Waiting for e-mail address confirmation */ } wmudClientState; typedef struct _wmudPlayer { - guint32 id; /* User ID */ - gchar *player_name; /* Player login name */ - gchar *cpassword; /* Crypted password */ + guint32 id; /* User ID */ + gchar *player_name; /* Player login name */ + gchar *cpassword; /* Crypted password */ + gchar *email; /* E-mail address */ + gboolean registering; /* Player is currently registering */ } wmudPlayer; typedef struct _wmudClient { @@ -27,13 +33,23 @@ typedef struct _wmudClient { wmudClientState state; gboolean authenticated; wmudPlayer *player; + gboolean bademail; } wmudClient; enum { WMUD_CONFIG_ERROR_SUCCESS, WMUD_CONFIG_ERROR_NOGLOBAL, WMUD_CONFIG_ERROR_BADPORT, - WMUD_CONFIG_ERROR_NOWORLD + WMUD_CONFIG_ERROR_NOWORLD, + WMUD_CONFIG_ERROR_NOEMAIL }; + +enum { + WMUD_DB_ERROR_SUCCESS, + WMUD_DB_ERROR_CANTOPEN, + WMUD_DB_ERROR_NOINIT, + WMUD_DB_ERROR_BADQUERY +}; + #endif /* __WMUD_TYPES_H__ */