summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/configuration.cpp202
-rw-r--r--src/configuration.h119
-rw-r--r--src/dalstorage.cpp2
-rw-r--r--src/dalstoragesql.h2
-rw-r--r--src/main.cpp27
6 files changed, 352 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e40dc501..a649b984 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -46,7 +46,9 @@ tmwserv_SOURCES = main.cpp \
utils/cipher.h \
utils/cipher.cpp \
utils/logger.h \
- utils/logger.cpp
+ utils/logger.cpp \
+ configuration.h \
+ configuration.cpp
if BUILD_MYSQL
tmwserv_SOURCES += dal/mysqldataprovider.h \
diff --git a/src/configuration.cpp b/src/configuration.cpp
new file mode 100644
index 00000000..703d2c20
--- /dev/null
+++ b/src/configuration.cpp
@@ -0,0 +1,202 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+
+#include "configuration.h"
+//#include "log.h"
+//#include "main.h"
+
+#include <math.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlwriter.h>
+#include "utils/logger.h"
+
+// MSVC libxml2 at the moment doesn't work right when using MinGW, missing this
+// function at link time.
+#ifdef WIN32
+#undef xmlFree
+#define xmlFree(x) ;
+#endif
+
+ConfigListener::~ConfigListener()
+{
+}
+
+void Configuration::init(const std::string &filename)
+{
+ configPath = filename;
+
+ // Do not attempt to read config from non-existant file
+ FILE *testFile = fopen(configPath.c_str(), "r");
+ if (!testFile) {
+ return;
+ }
+ else {
+ fclose(testFile);
+ }
+
+ xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
+
+ if (!doc) return;
+
+ xmlNodePtr node = xmlDocGetRootElement(doc);
+
+ if (!node || !xmlStrEqual(node->name, BAD_CAST "configuration")) {
+ LOG_WARN("Warning: No configuration file (" << filename.c_str() << ")")
+ return;
+ }
+
+ for (node = node->xmlChildrenNode; node != NULL; node = node->next)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "option"))
+ {
+ xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+ xmlChar *value = xmlGetProp(node, BAD_CAST "value");
+
+ if (name && value) {
+ options[std::string((const char*)name)] =
+ std::string((const char*)value);
+ }
+
+ if (name) xmlFree(name);
+ if (value) xmlFree(value);
+ }
+ }
+
+ xmlFreeDoc(doc);
+}
+
+void Configuration::write()
+{
+ // Do not attempt to write to file that cannot be opened for writing
+ FILE *testFile = fopen(configPath.c_str(), "w");
+ if (!testFile) {
+ return;
+ }
+ else {
+ fclose(testFile);
+ }
+
+ xmlTextWriterPtr writer = xmlNewTextWriterFilename(configPath.c_str(), 0);
+
+ if (writer)
+ {
+ xmlTextWriterSetIndent(writer, 1);
+ xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
+ xmlTextWriterStartElement(writer, BAD_CAST "configuration");
+
+ std::map<std::string, std::string>::iterator iter;
+
+ for (iter = options.begin(); iter != options.end(); iter++)
+ {
+ //logger->log("Configuration::write(%s, \"%s\")",
+ //iter->first.c_str(), iter->second.c_str());
+
+ xmlTextWriterStartElement(writer, BAD_CAST "option");
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "name", BAD_CAST iter->first.c_str());
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "value", BAD_CAST iter->second.c_str());
+ xmlTextWriterEndElement(writer);
+ }
+
+ xmlTextWriterEndDocument(writer);
+ xmlFreeTextWriter(writer);
+ }
+}
+
+void Configuration::setValue(const std::string &key, std::string value)
+{
+#ifdef __DEBUG
+ std::cout << "Configuration::setValue(" << key << ", " << value << ")\n";
+#endif
+ options[key] = value;
+
+ // Notify listeners
+ std::map<std::string, std::list<ConfigListener*> >::iterator list =
+ listeners.find(key);
+
+ if (list != listeners.end()) {
+ std::list<ConfigListener*>::iterator listener = (*list).second.begin();
+
+ while (listener != (*list).second.end())
+ {
+ (*listener)->optionChanged(key);
+ listener++;
+ }
+ }
+}
+
+void Configuration::setValue(const std::string &key, float value)
+{
+ std::stringstream ss;
+ if (value == floor(value)) {
+ ss << (int)value;
+ } else {
+ ss << value;
+ }
+ setValue(key, ss.str());
+}
+
+std::string Configuration::getValue(const std::string &key, std::string deflt)
+{
+ std::map<std::string, std::string>::iterator iter = options.find(key);
+ if (iter != options.end()) {
+ return (*iter).second;
+ }
+ return deflt;
+}
+
+float Configuration::getValue(const std::string &key, float deflt)
+{
+ std::map<std::string, std::string>::iterator iter = options.find(key);
+ if (iter != options.end()) {
+ return atof((*iter).second.c_str());
+ }
+ return deflt;
+}
+
+void Configuration::addListener(
+ const std::string &key, ConfigListener *listener)
+{
+ listeners[key].push_front(listener);
+}
+
+void Configuration::removeListener(
+ const std::string &key, ConfigListener *listener)
+{
+ std::list<ConfigListener*>::iterator i = listeners[key].begin();
+
+ while (i != listeners[key].end())
+ {
+ if ((*i) == listener) {
+ listeners[key].erase(i);
+ return;
+ }
+ i++;
+ }
+}
diff --git a/src/configuration.h b/src/configuration.h
new file mode 100644
index 00000000..75699f30
--- /dev/null
+++ b/src/configuration.h
@@ -0,0 +1,119 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef __INIREAD_H
+#define __INIREAD_H
+
+#include <map>
+#include <list>
+#include <string>
+
+
+/**
+ * The listener interface for receiving notifications about changes to
+ * configuration options.
+ *
+ * \ingroup CORE
+ */
+class ConfigListener
+{
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ConfigListener();
+
+ /**
+ * Called when an option changed. The config listener will have to be
+ * registered to the option name first.
+ */
+ virtual void optionChanged(const std::string &name) = 0;
+};
+
+/**
+ * INI configuration handler for reading (and writing).
+ *
+ * \ingroup CORE
+ */
+class Configuration
+{
+ public:
+ /**
+ * \brief Reads INI file and parse all options into memory.
+ * \param filename Full path to INI file (~/.manaworld/tmw.ini)
+ */
+ void init(const std::string &filename);
+
+ /**
+ * \brief Writes the current settings back to an ini-file.
+ * \param filename Full path to INI file (~/.manaworld/tmw.ini)
+ */
+ void write();
+
+ /**
+ * \brief Sets an option using a string value.
+ * \param key Option identifier.
+ * \param value Value.
+ */
+ void setValue(const std::string &key, std::string value);
+
+ /**
+ * \brief Sets an option using a numeric value.
+ * \param key Option identifier.
+ * \param value Value.
+ */
+ void setValue(const std::string &key, float value);
+
+ /**
+ * \brief Gets a value as string.
+ * \param key Option identifier.
+ * \param deflt Default option if not there or error.
+ */
+ std::string getValue(const std::string &key, std::string deflt);
+
+ /**
+ * \brief Gets a value as numeric (float).
+ * \param key Option identifier.
+ * \param deflt Default option if not there or error.
+ */
+ float getValue(const std::string &key, float deflt);
+
+ /**
+ * Adds a listener to the listen list of the specified config option.
+ */
+ void addListener(const std::string &key, ConfigListener *listener);
+
+ /**
+ * Removes a listener from the listen list of the specified config
+ * option.
+ */
+ void removeListener(const std::string &key, ConfigListener *listener);
+
+ private:
+ std::map<std::string, std::string> options;
+ std::map<std::string, std::list<ConfigListener*> > listeners;
+
+ std::string configPath; /**< Location of config file */
+};
+
+#endif
diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp
index 4e633718..2a491564 100644
--- a/src/dalstorage.cpp
+++ b/src/dalstorage.cpp
@@ -90,7 +90,7 @@ DALStorage::open(void)
try {
// open a connection to the database.
-#if defined (MYSQL_SUPPORT) || defined (POSTGRE_SUPPORT)
+#if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT)
mDb->connect(getName(), getUser(), getPassword());
#else // SQLITE_SUPPORT
// create the database file name.
diff --git a/src/dalstoragesql.h b/src/dalstoragesql.h
index 26a3e455..fd8e7661 100644
--- a/src/dalstoragesql.h
+++ b/src/dalstoragesql.h
@@ -25,7 +25,7 @@
#define _TMWSERV_DALSTORAGE_SQL_H_
-#if !defined (MYSQL_SUPPORT) && !defined (SQLITE_SUPPORT) && !defined (POSTGRE_SUPPORT)
+#if !defined (MYSQL_SUPPORT) && !defined (SQLITE_SUPPORT) && !defined (POSTGRESQL_SUPPORT)
#error "(dalstorage.h) no database backend defined"
#endif
diff --git a/src/main.cpp b/src/main.cpp
index d83b87e9..4b6ec0d8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -28,15 +28,19 @@
#include <SDL.h>
#include <SDL_net.h>
+#include <cstdlib>
+
#include "netsession.h"
#include "connectionhandler.h"
#include "accounthandler.h"
#include "storage.h"
+#include "configuration.h"
#include "skill.h"
#include "utils/logger.h"
+
// Scripting
#ifdef SCRIPT_SUPPORT
@@ -68,6 +72,7 @@ bool running = true; /**< Determines if server keeps running */
Skill skillTree("base"); /**< Skill tree */
+Configuration config; /**< XML config reader */
/**
* SDL timer callback, sends a <code>TMW_WORLD_TICK</code> event.
@@ -123,6 +128,17 @@ void initialize()
script = new ScriptSquirrel("main.nut");
}
#endif
+
+ // initialize configuration
+ // initialize configuration defaults
+ config.setValue("dbuser", "");
+ config.setValue("dbpass", "");
+ config.setValue("dbhost", "");
+
+ char *home = getenv("HOME");
+ std::string configPath = home;
+ configPath += "/.tmwserv.xml";
+ config.init(configPath);
}
@@ -131,6 +147,9 @@ void initialize()
*/
void deinitialize()
{
+ // Write configuration file
+ config.write();
+
// Stop world timer
SDL_RemoveTimer(worldTimerID);
@@ -183,7 +202,13 @@ int main(int argc, char *argv[])
using namespace tmwserv;
- //Storage& store = Storage::instance("tmw");
+ // create storage wrapper
+ Storage& store = Storage::instance("tmw");
+ store.setUser(config.getValue("dbuser", ""));
+ store.setPassword(config.getValue("dbpass", ""));
+ store.close();
+ store.open();
+ //
SDL_Event event;