main-account.cpp

Go to the documentation of this file.
00001 /*
00002  *  The Mana World Server
00003  *  Copyright 2004 The Mana World Development Team
00004  *
00005  *  This file is part of The Mana World.
00006  *
00007  *  The Mana World  is free software; you can redistribute  it and/or modify it
00008  *  under the terms of the GNU General  Public License as published by the Free
00009  *  Software Foundation; either version 2 of the License, or any later version.
00010  *
00011  *  The Mana  World is  distributed in  the hope  that it  will be  useful, but
00012  *  WITHOUT ANY WARRANTY; without even  the implied warranty of MERCHANTABILITY
00013  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
00014  *  more details.
00015  *
00016  *  You should  have received a  copy of the  GNU General Public  License along
00017  *  with The Mana  World; if not, write to the  Free Software Foundation, Inc.,
00018  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019  *
00020  *  $Id: main-account.cpp 3175 2007-03-11 00:39:29Z rogier_polak $
00021  */
00022 
00023 #include <cstdlib>
00024 #include <getopt.h>
00025 #include <signal.h>
00026 #include <iostream>
00027 #include <physfs.h>
00028 #include <enet/enet.h>
00029 
00030 #if (defined __USE_UNIX98 || defined __FreeBSD__)
00031 #include "../config.h"
00032 #endif
00033 
00034 #include "configuration.h"
00035 #include "resourcemanager.h"
00036 #include "skill.h"
00037 #include "account-server/accounthandler.hpp"
00038 #include "account-server/serverhandler.hpp"
00039 #include "account-server/storage.hpp"
00040 #include "chat-server/chatchannelmanager.hpp"
00041 #include "chat-server/chathandler.hpp"
00042 #include "net/connectionhandler.hpp"
00043 #include "net/messageout.hpp"
00044 #include "utils/logger.h"
00045 #include "utils/processorutils.hpp"
00046 #include "utils/stringfilter.h"
00047 
00048 // Default options that automake should be able to override.
00049 #define DEFAULT_LOG_FILE        "tmwserv-account.log"
00050 #define DEFAULT_CONFIG_FILE     "tmwserv.xml"
00051 #define DEFAULT_ITEMSDB_FILE    "items.xml"
00052 
00053 bool running = true;            
00055 Skill skillTree("base");        
00057 Configuration config;           
00059 utils::StringFilter *stringFilter; 
00062 AccountHandler *accountHandler;
00063 
00065 ChatHandler *chatHandler;
00066 
00068 ServerHandler *serverHandler;
00069 
00071 ChatChannelManager *chatChannelManager;
00072 
00074 void closeGracefully(int dummy)
00075 {
00076     running = false;
00077 }
00078 
00082 void initialize()
00083 {
00084 
00085     // Reset to default segmentation fault handling for debugging purposes
00086     signal(SIGSEGV, SIG_DFL);
00087 
00088     // Used to close via process signals
00089 #if (defined __USE_UNIX98 || defined __FreeBSD__)
00090     signal(SIGQUIT, closeGracefully);
00091 #endif
00092     signal(SIGINT, closeGracefully);
00093 
00094     // Set enet to quit on exit.
00095     atexit(enet_deinitialize);
00096 
00097     /*
00098      * If the path values aren't defined, we set the default
00099      * depending on the platform.
00100      */
00101     // The config path
00102 #if defined CONFIG_FILE
00103     std::string configPath = CONFIG_FILE;
00104 #else
00105 
00106 #if (defined __USE_UNIX98 || defined __FreeBSD__)
00107     std::string configPath = getenv("HOME");
00108     configPath += "/.";
00109     configPath += DEFAULT_CONFIG_FILE;
00110 #else // Win32, ...
00111     std::string configPath = DEFAULT_CONFIG_FILE;
00112 #endif
00113 
00114 #endif // defined CONFIG_FILE
00115 
00116     // The log path
00117 #if defined LOG_FILE
00118     std::string logPath = LOG_FILE;
00119 #else
00120 
00121 #if (defined __USE_UNIX98 || defined __FreeBSD__)
00122     std::string logPath = getenv("HOME");
00123     logPath += "/.";
00124     logPath += DEFAULT_LOG_FILE;
00125 #else // Win32, ...
00126     std::string logPath = DEFAULT_LOG_FILE;
00127 #endif
00128 
00129 #endif // defined LOG_FILE
00130 
00131     // Initialize PhysicsFS
00132     PHYSFS_init("");
00133 
00134     // Initialize the logger.
00135     using namespace utils;
00136     Logger::setLogFile(logPath);
00137 
00138     // write the messages to both the screen and the log file.
00139     Logger::setTeeMode(true);
00140 
00141     config.init(configPath);
00142     LOG_INFO("Using Config File: " << configPath);
00143     LOG_INFO("Using Log File: " << logPath);
00144 
00145     // --- Initialize the managers
00146     // Initialize the slang's and double quotes filter.
00147     stringFilter = new StringFilter(&config);
00148     // Initialize the Chat channels manager
00149     chatChannelManager = new ChatChannelManager();
00150 
00151     // --- Initialize the global handlers
00152     // FIXME: Make the global handlers global vars or part of a bigger
00153     // singleton or a local variable in the event-loop
00154     accountHandler = new AccountHandler();
00155     chatHandler = new ChatHandler();
00156     serverHandler = new ServerHandler();
00157 
00158     // --- Initialize enet.
00159     if (enet_initialize() != 0) {
00160         LOG_FATAL("An error occurred while initializing ENet");
00161         exit(2);
00162     }
00163 
00164 
00165 #if defined (MYSQL_SUPPORT)
00166     LOG_INFO("Using MySQL DB Backend.");
00167 #elif defined (POSTGRESQL_SUPPORT)
00168     LOG_INFO("Using PostGreSQL DB Backend.");
00169 #elif defined (SQLITE_SUPPORT)
00170     LOG_INFO("Using SQLite DB Backend.");
00171 #else
00172     LOG_WARN("No Database Backend Support.");
00173 #endif
00174 
00175     // Initialize configuration defaults
00176     config.setValue("dbuser", "");
00177     config.setValue("dbpass", "");
00178     config.setValue("dbhost", "");
00179 
00180     // Initialize the processor utility functions
00181     utils::processor::init();
00182 
00183     // Seed the random number generator
00184     std::srand( time(NULL) );
00185 }
00186 
00187 
00191 void deinitialize()
00192 {
00193     delete stringFilter;
00194     // Write configuration file
00195     config.write();
00196 
00197     // Quit ENet
00198     enet_deinitialize();
00199 
00200     // Destroy message handlers
00201     delete serverHandler;
00202     delete chatHandler;
00203     delete accountHandler;
00204 
00205     // Destroy Managers
00206     delete chatChannelManager;
00207 
00208     // Get rid of persistent data storage
00209     Storage::destroy();
00210 
00211     PHYSFS_deinit();
00212 }
00213 
00214 
00218 void printHelp()
00219 {
00220     std::cout << "tmwserv" << std::endl << std::endl
00221               << "Options: " << std::endl
00222               << "  -h --help          : Display this help" << std::endl
00223               << "     --verbosity <n> : Set the verbosity level" << std::endl
00224               << "     --port <n>      : Set the default port to listen on" << std::endl;
00225     exit(0);
00226 }
00227 
00231 void parseOptions(int argc, char *argv[])
00232 {
00233     const char *optstring = "h";
00234 
00235     const struct option long_options[] = {
00236         { "help",       no_argument, 0, 'h' },
00237         { "verbosity",  required_argument, 0, 'v' },
00238         { "port",       required_argument, 0, 'p' },
00239         { 0 }
00240     };
00241 
00242     while (optind < argc) {
00243         int result = getopt_long(argc, argv, optstring, long_options, NULL);
00244 
00245         if (result == -1) {
00246             break;
00247         }
00248 
00249         switch (result) {
00250             default: // Unknown option
00251             case 'h':
00252                 // Print help
00253                 printHelp();
00254                 break;
00255             case 'v':
00256                 // Set Verbosity to level
00257                 unsigned short verbosityLevel;
00258                 verbosityLevel = atoi(optarg);
00259                 utils::Logger::setVerbosity(utils::Logger::Level(verbosityLevel));
00260                 LOG_INFO("Setting Log Verbosity Level to " << verbosityLevel);
00261                 break;
00262             case 'p':
00263                 // Change the port to listen on.
00264                 unsigned short portToListenOn;
00265                 portToListenOn = atoi(optarg);
00266                 config.setValue("ListenOnPort", portToListenOn);
00267                 LOG_INFO("Setting Default Port to " << portToListenOn);
00268                 break;
00269         }
00270     }
00271 }
00272 
00273 
00277 int main(int argc, char *argv[])
00278 {
00279     LOG_INFO("The Mana World Account+Chat Server v" << PACKAGE_VERSION);
00280 
00281     // Parse Command Line Options
00282     parseOptions(argc, argv);
00283 
00284     // General Initialization
00285     initialize();
00286 
00287     int port = int(config.getValue("accountServerPort", DEFAULT_SERVER_PORT));
00288     if (!accountHandler->startListen(port) ||
00289         !serverHandler->startListen(port + 1) ||
00290         !chatHandler->startListen(port + 2))
00291     {
00292         LOG_FATAL("Unable to create an ENet server host.");
00293         return 3;
00294     }
00295 
00296     // Create storage wrapper
00297     Storage& store = Storage::instance("tmw");
00298     store.setUser(config.getValue("dbuser", ""));
00299     store.setPassword(config.getValue("dbpass", ""));
00300     store.close();
00301     store.open();
00302 
00303     while (running) {
00304         accountHandler->process(50);
00305         chatHandler->process(50);
00306         serverHandler->process(50);
00307     }
00308 
00309     LOG_INFO("Received: Quit signal, closing down...");
00310     serverHandler->stopListen();
00311     chatHandler->stopListen();
00312     accountHandler->stopListen();
00313     deinitialize();
00314 }

Generated on Fri Mar 30 15:39:16 2007 for TMW Server by  doxygen 1.3.9.1