diff --git a/docs/reference/wmud/wmud-docs.sgml b/docs/reference/wmud/wmud-docs.sgml index 02f2355..967edd1 100644 --- a/docs/reference/wmud/wmud-docs.sgml +++ b/docs/reference/wmud/wmud-docs.sgml @@ -25,6 +25,7 @@ + diff --git a/docs/reference/wmud/wmud-sections.txt b/docs/reference/wmud/wmud-sections.txt index ce587d2..2da1e62 100644 --- a/docs/reference/wmud/wmud-sections.txt +++ b/docs/reference/wmud/wmud-sections.txt @@ -79,6 +79,11 @@ wmud_player_auth wmud_player_exists +
+ +menu +
+
world diff --git a/wmud/Makefile.am b/wmud/Makefile.am index acbf9da..2ac09b8 100644 --- a/wmud/Makefile.am +++ b/wmud/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = wmud AM_CPPFLAGS = -DWMUD_STATEDIR=\""$(localstatedir)"\" -DWMUD_CONFDIR=\""$(sysconfdir)"\" $(MEMCACHED_CFLAGS) $(GLIB_CFLAGS) $(GIO_CFLAGS) $(GTHREAD_CFLAGS) $(SQLITE3_CFLAGS) -wmud_SOURCES = main.c game-networking.c interpreter.c db.c players.c maintenance.c game.c configuration.c world.c +wmud_SOURCES = main.c game-networking.c interpreter.c db.c players.c maintenance.c game.c configuration.c world.c menu.c wmud_LDADD = $(MEMCACHED_LIBS) $(GLIB_LIBS) $(GIO_LIBS) $(GTHREAD_LIBS) $(SQLITE3_LIBS) diff --git a/wmud/db.c b/wmud/db.c index 0196a88..35294d5 100644 --- a/wmud/db.c +++ b/wmud/db.c @@ -25,6 +25,7 @@ #include "db.h" #include "players.h" #include "configuration.h" +#include "menu.h" /** * SECTION:db @@ -550,3 +551,59 @@ wmud_db_load_planet_planes(GSList **planet_planes, GError **err) return TRUE; } +gboolean +wmud_db_load_menu(GSList **menu_items, GError **err) +{ + sqlite3_stmt *sth = NULL; + int sqlite_code; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Loading menu items"); + 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, menuchar, need_active_char, placement, display_text, fnctn FROM menu", -1, &sth, NULL)) != SQLITE_OK) + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Bad query in wmud_db_load_menu(): %s", sqlite3_errmsg(dbh)); + + return FALSE; + } + + while (1) + { + sqlite_code = sqlite3_step(sth); + if (sqlite_code == SQLITE_ROW) + { + wmudMenu *menu_item = g_new0(wmudMenu, 1); + menu_item->id = sqlite3_column_int(sth, 0); + menu_item->menuchar = *(sqlite3_column_text(sth, 1)); + menu_item->need_active_char = (sqlite3_column_int(sth, 2) != 0); + menu_item->placement = sqlite3_column_int(sth, 4); + menu_item->text = g_strdup((gchar *)sqlite3_column_text(sth, 5)); + menu_item->func = g_strdup((gchar *)sqlite3_column_text(sth, 6)); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Loaded menu item %s(%d)", menu_item->text, menu_item->id); + + *menu_items = g_slist_prepend(*menu_items, menu_item); + } + else if (sqlite_code == SQLITE_DONE) + { + break; + } + else + { + g_set_error(err, WMUD_DB_ERROR, WMUD_DB_ERROR_BADQUERY, "Query error in wmud_db_load_menu_items(): %s", sqlite3_errmsg(dbh)); + sqlite3_finalize(sth); + return FALSE; + } + } + + sqlite3_finalize(sth); + + return TRUE; + return FALSE; +} diff --git a/wmud/db.h b/wmud/db.h index 4c09377..4eede14 100644 --- a/wmud/db.h +++ b/wmud/db.h @@ -50,6 +50,7 @@ gboolean wmud_db_load_areas(GSList **areas, GError **err); gboolean wmud_db_load_rooms(GSList **rooms, GError **err); gboolean wmud_db_load_exits(GSList **exits, GError **err); gboolean wmud_db_load_planet_planes(GSList **planet_planes, GError **err); +gboolean wmud_db_load_menu(GSList **menu_items, GError **err); #endif /* __WMUD__DB_H__ */ diff --git a/wmud/main.c b/wmud/main.c index e9fa6d6..3f1b1bd 100644 --- a/wmud/main.c +++ b/wmud/main.c @@ -136,6 +136,7 @@ main(int argc, char **argv) GError *err = NULL; GThread *game_thread; GMainContext *game_context; + GSList *game_menu; /* Initialize the thread and type system */ g_thread_init(NULL); @@ -182,9 +183,16 @@ main(int argc, char **argv) return 1; } + if (!wmud_menu_init(&game_menu)) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "An error occured during menu loading."); + + return 1; + } + /* Initialization ends here */ - wmud_game_init(&game_thread, &game_context); + wmud_game_init(&game_thread, &game_context, game_menu); g_clear_error(&err); if (!wmud_networking_init(active_config->port, game_context, &err)) diff --git a/wmud/menu.c b/wmud/menu.c new file mode 100644 index 0000000..1ad683a --- /dev/null +++ b/wmud/menu.c @@ -0,0 +1,112 @@ +/* wMUD - Yet another MUD codebase by W00d5t0ck + * Copyright (C) 2012 - Gergely POLONKAI + * + * menu.c: menu handling routines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "menu.h" +#include "db.h" + +#include "menu.h" + +/** + * SECTION:menu + * @short_description: Menu handling + * @title: Menu handling routines + * + */ + +GQuark +wmud_menu_error_quark() +{ + return g_quark_from_static_string("wmud-menu-error"); +} + +gboolean +wmud_menu_items_check(GSList *menu_items, GError **err) +{ + /* TODO: Check for duplicate menuchars */ + /* TODO: Check for duplicate menu texts */ + /* TODO: Check for duplicate placements */ + return TRUE; +} + +void +menu_item_free(wmudMenu *menu_item) +{ + if (menu_item->text) + g_free(menu_item->text); + if (menu_item->display_text) + g_free(menu_item->display_text); + if (menu_item->display_text_ansi) + g_free(menu_item->display_text_ansi); + if (menu_item->func) + g_free(menu_item->func); + + g_free(menu_item); +} + +void +wmud_menu_items_free(GSList **menu_items) +{ + if (menu_items) + { +#if GLIB_CHECK_VERSION(2, 28, 0) + g_slist_free_full(*menu_items, (GDestroyNotify)menu_item_free); +#else + g_slist_foreach(*menu_items, (GFunc)menu_item_free, NULL); + g_slist_free(*menu_items); +#endif + *menu_items = NULL; + } +} + +gboolean +wmud_menu_init(GSList **menu) +{ + GSList *menu_items = NULL; + GError *in_err = NULL; + + if (!wmud_db_load_menu(&menu_items, &in_err)) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "Unable to load menu items from the database: %s", in_err->message); + wmud_menu_items_free(&menu_items); + + return FALSE; + } + + if (!menu_items) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "No menu items were found in the database!"); + + return FALSE; + } + + if (!wmud_menu_items_check(menu_items, &in_err)) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "Menu items pre-flight check error: %s", in_err->message); + wmud_menu_items_free(&menu_items); + + return FALSE; + } + + *menu = menu_items; + + return TRUE; +} + diff --git a/wmud/menu.h b/wmud/menu.h new file mode 100644 index 0000000..85f8860 --- /dev/null +++ b/wmud/menu.h @@ -0,0 +1,58 @@ +/* wMUD - Yet another MUD codebase by W00d5t0ck + * Copyright (C) 2012 - Gergely POLONKAI + * + * menu.h: menu handling routines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __WMUD_MENU_H__ +#define __WMUD_MENU_H__ + +#include + +/** + * wmudMenu: + * @id: The databas ID of the menu item + * @menuchar: The highlighted character of the menu item. Players must enter it + * in the menu to activate the menu item + * @need_active_char: If %TRUE, the menu item will be displayed only if the + * player has a character selected + * @placement: The order number of the menu item. The whole menu is sorted + * based on this field + * @text: The text to be displayed to the player. It gets processed by + * wmud_menu_process_item() to highlight the menuchar + * @display_text: The actual text that gets displayed to the player + * @display_text_ansi: The actual text that gets displayed to the player when + * ANSI colour mode is enabled + * @func: the menu item's function. See menu.c for the list of possible values. + */ +typedef struct _wmudMenu { + guint id; + gchar menuchar; + gboolean need_active_char; + guint placement; + gchar *text; + gchar *display_text; + gchar *display_text_ansi; + gchar *func; +} wmudMenu; + +#define WMUD_MENU_ERROR wmud_menu_error_quark() +GQuark wmud_menu_error_quark(); +gboolean wmud_menu_init(GSList **menu); +gboolean wmud_menu_items_check(GSList *menu_items, GError **err); +void wmud_menu_items_free(GSList **menu_items); + +#endif /* __WMUD_MENU_H__ */ +