summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp1104
1 files changed, 17 insertions, 1087 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 8d5cbf84..5ed1c4ec 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,496 +21,15 @@
#include "main.h"
-#include "configuration.h"
-#include "emoteshortcut.h"
-#include "game.h"
-#include "graphics.h"
-#include "itemshortcut.h"
-#include "keyboardconfig.h"
-#include "localplayer.h"
-#include "log.h"
-#ifdef USE_OPENGL
-#include "openglgraphics.h"
-#endif
-#include "playerrelations.h"
-#include "sound.h"
-#include "statuseffect.h"
-#include "units.h"
-
-#include "gui/changeemaildialog.h"
-#include "gui/changepassworddialog.h"
-#include "gui/charselectdialog.h"
-#include "gui/connectiondialog.h"
-#include "gui/gui.h"
-#include "gui/skin.h"
-#include "gui/login.h"
-#include "gui/okdialog.h"
-#include "gui/palette.h"
-#include "gui/quitdialog.h"
-#include "gui/register.h"
-#include "gui/sdlinput.h"
-#include "gui/serverdialog.h"
-#include "gui/setup.h"
-#include "gui/unregisterdialog.h"
-#include "gui/updatewindow.h"
-#include "gui/worldselectdialog.h"
-
-#include "gui/widgets/button.h"
-#include "gui/widgets/desktop.h"
-
-#include "net/charhandler.h"
-#include "net/gamehandler.h"
-#include "net/generalhandler.h"
-#include "net/logindata.h"
-#include "net/loginhandler.h"
-#include "net/net.h"
-#include "net/worldinfo.h"
-
-#include "resources/colordb.h"
-#include "resources/emotedb.h"
-#include "resources/image.h"
-#include "resources/itemdb.h"
-#include "resources/monsterdb.h"
-#include "resources/npcdb.h"
-#include "resources/resourcemanager.h"
-
#include "utils/gettext.h"
-#include "utils/stringutils.h"
-#include <SDL_image.h>
+#include "client.h"
#include <libxml/parser.h>
-#ifdef WIN32
-#include <SDL_syswm.h>
-#else
-#include <cerrno>
-#include <sys/stat.h>
-#endif
-
#include <getopt.h>
#include <iostream>
#include <physfs.h>
-#include <unistd.h>
-#include <vector>
-
-#ifdef __APPLE__
-#include <CoreFoundation/CFBundle.h>
-#endif
-
-#ifdef __MINGW32__
-#include <windows.h>
-#define usleep(usec) (Sleep ((usec) / 1000), 0)
-#endif
-
-namespace
-{
- class SetupListener : public gcn::ActionListener
- {
- public:
- /**
- * Called when receiving actions from widget.
- */
- void action(const gcn::ActionEvent &event);
- } listener;
-}
-
-static const int defaultSfxVolume = 100;
-static const int defaultMusicVolume = 60;
-
-Graphics *graphics;
-Game *game = 0;
-
-State state = STATE_START;
-std::string errorMessage;
-ErrorListener errorListener;
-
-Sound sound;
-Music *bgm;
-
-Configuration config; /**< XML file configuration reader */
-Configuration branding; /**< XML branding information reader */
-Logger *logger; /**< Log object */
-KeyboardConfig keyboard;
-
-LoginData loginData;
-
-Palette *guiPalette;
-
-// This anonymous namespace hides whatever is inside from other modules.
-namespace {
-
-std::string homeDir;
-std::string updateHost;
-std::string updatesDir;
-
-SDL_Surface *icon;
-
-/**
- * A structure holding the values of various options that can be passed from
- * the command line.
- */
-struct Options
-{
- /**
- * Constructor.
- */
- Options():
- printHelp(false),
- printVersion(false),
- skipUpdate(false),
- chooseDefault(false),
- noOpenGL(false),
- serverPort(0)
- {}
-
- bool printHelp;
- bool printVersion;
- bool skipUpdate;
- bool chooseDefault;
- bool noOpenGL;
- std::string username;
- std::string password;
- std::string character;
- std::string configPath;
- std::string updateHost;
- std::string dataPath;
- std::string homeDir;
- std::string screenshotDir;
-
- std::string serverName;
- short serverPort;
-
-};
-
-/**
- * Parse the update host and determine the updates directory
- * Then verify that the directory exists (creating if needed).
- */
-static void setUpdatesDir()
-{
- std::stringstream updates;
-
- // If updatesHost is currently empty, fill it from config file
- if (updateHost.empty())
- {
- updateHost =
- config.getValue("updatehost", "http://updates.themanaworld.org/");
- }
-
- // Remove any trailing slash at the end of the update host
- if (updateHost.at(updateHost.size() - 1) == '/')
- updateHost.resize(updateHost.size() - 1);
-
- // Parse out any "http://" or "ftp://", and set the updates directory
- size_t pos;
- pos = updateHost.find("://");
- if (pos != updateHost.npos)
- {
- if (pos + 3 < updateHost.length())
- {
- updates << "updates/" << updateHost.substr(pos + 3);
- updatesDir = updates.str();
- }
- else
- {
- logger->log("Error: Invalid update host: %s", updateHost.c_str());
- errorMessage = strprintf(_("Invalid update host: %s"), updateHost.c_str());
- state = STATE_ERROR;
- }
- }
- else
- {
- logger->log("Warning: no protocol was specified for the update host");
- updates << "updates/" << updateHost;
- updatesDir = updates.str();
- }
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- // Verify that the updates directory exists. Create if necessary.
- if (!resman->isDirectory("/" + updatesDir))
- {
- if (!resman->mkdir("/" + updatesDir))
- {
-#if defined WIN32
- std::string newDir = homeDir + "\\" + updatesDir;
- std::string::size_type loc = newDir.find("/", 0);
-
- while (loc != std::string::npos)
- {
- newDir.replace(loc, 1, "\\");
- loc = newDir.find("/", loc);
- }
-
- if (!CreateDirectory(newDir.c_str(), 0) &&
- GetLastError() != ERROR_ALREADY_EXISTS)
- {
- logger->log("Error: %s can't be made, but doesn't exist!",
- newDir.c_str());
- errorMessage = _("Error creating updates directory!");
- state = STATE_ERROR;
- }
-#else
- logger->log("Error: %s/%s can't be made, but doesn't exist!",
- homeDir.c_str(), updatesDir.c_str());
- errorMessage = _("Error creating updates directory!");
- state = STATE_ERROR;
-#endif
- }
- }
-}
-
-/**
- * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On
- * Windows and other systems we use the current working directory.
- */
-static void initHomeDir(const Options &options)
-{
- homeDir = options.homeDir;
-
- if (homeDir.empty())
- {
-#ifdef __APPLE__
- // Use Application Directory instead of .mana
- homeDir = std::string(PHYSFS_getUserDir()) +
- "/Library/Application Support/" +
- branding.getValue("appName", "Mana");
-#else
- homeDir = std::string(PHYSFS_getUserDir()) +
- "/." + branding.getValue("appShort", "mana");
-#endif
- }
-#if defined WIN32
- if (!CreateDirectory(homeDir.c_str(), 0) &&
- GetLastError() != ERROR_ALREADY_EXISTS)
-#else
- // Create home directory if it doesn't exist already
- if ((mkdir(homeDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) &&
- (errno != EEXIST))
-#endif
- {
- logger->error(strprintf(_("%s doesn't exist and can't be created! "
- "Exiting."), homeDir.c_str()));
- }
-}
-
-/**
- * Initialize configuration.
- */
-static void initConfiguration(const Options &options)
-{
- // Fill configuration with defaults
- logger->log("Initializing configuration...");
- std::string defaultHost = branding.getValue("defaultServer",
- "server.themanaworld.org");
- int defaultPort = (int)branding.getValue("defaultPort", DEFAULT_PORT);
- config.setValue("port", defaultPort);
- config.setValue("hwaccel", false);
-#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
- config.setValue("opengl", true);
-#else
- config.setValue("opengl", false);
-#endif
- config.setValue("screen", false);
- config.setValue("sound", true);
- config.setValue("guialpha", 0.8f);
- config.setValue("remember", true);
- config.setValue("sfxVolume", 100);
- config.setValue("musicVolume", 60);
- config.setValue("fpslimit", 60);
- std::string defaultUpdateHost = branding.getValue("defaultUpdateHost",
- "http://updates.themanaworld.org");
- config.setValue("updatehost", defaultUpdateHost);
- config.setValue("customcursor", true);
- config.setValue("ChatLogLength", 128);
-
- // Checking if the configuration file exists... otherwise create it with
- // default options.
- FILE *configFile = 0;
- std::string configPath = options.configPath;
-
- if (configPath.empty())
- configPath = homeDir + "/config.xml";
-
- configFile = fopen(configPath.c_str(), "r");
-
- // If we can't read it, it doesn't exist !
- if (configFile == NULL)
- {
- // We reopen the file in write mode and we create it
- configFile = fopen(configPath.c_str(), "wt");
- }
- if (configFile == NULL)
- {
- logger->log("Can't create %s. Using defaults.", configPath.c_str());
- }
- else
- {
- fclose(configFile);
- config.init(configPath);
- }
-}
-
-/**
- * Do all initialization stuff.
- */
-static void initEngine(const Options &options)
-{
- // Initialize SDL
- logger->log("Initializing SDL...");
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
- {
- logger->error(strprintf("Could not initialize SDL: %s",
- SDL_GetError()));
- }
- atexit(SDL_Quit);
-
- SDL_EnableUNICODE(1);
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-
- SDL_WM_SetCaption(branding.getValue("appName", "Mana").c_str(), NULL);
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- if (!resman->setWriteDir(homeDir))
- {
- logger->error(strprintf("%s couldn't be set as home directory! "
- "Exiting.", homeDir.c_str()));
- }
-
- // Add the user's homedir to PhysicsFS search path
- resman->addToSearchPath(homeDir, false);
-
- // Add the main data directories to our PhysicsFS search path
- if (!options.dataPath.empty())
- resman->addToSearchPath(options.dataPath, true);
- resman->addToSearchPath("data", true);
-#if defined __APPLE__
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
- char path[PATH_MAX];
- if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path,
- PATH_MAX))
- {
- fprintf(stderr, "Can't find Resources directory\n");
- }
- CFRelease(resourcesURL);
- strncat(path, "/data", PATH_MAX - 1);
- resman->addToSearchPath(path, true);
-#else
- resman->addToSearchPath(PKG_DATADIR "data", true);
-#endif
-
-#ifdef WIN32
- static SDL_SysWMinfo pInfo;
- SDL_GetWMInfo(&pInfo);
- HICON icon = LoadIcon(GetModuleHandle(NULL), "A");
- if (icon)
- {
- SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
- }
-#else
- icon = IMG_Load(resman->getPath(branding.getValue("appIcon", "data/icons/mana.png")).c_str());
- if (icon)
- {
- SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
- SDL_WM_SetIcon(icon, NULL);
- }
-#endif
-
-#ifdef USE_OPENGL
- bool useOpenGL = !options.noOpenGL && (config.getValue("opengl", 0) == 1);
-
- // Setup image loading for the right image format
- Image::setLoadAsOpenGL(useOpenGL);
-
- // Create the graphics context
- graphics = useOpenGL ? new OpenGLGraphics : new Graphics;
-#else
- // Create the graphics context
- graphics = new Graphics;
-#endif
-
- const int width = (int) config.getValue("screenwidth", defaultScreenWidth);
- const int height = (int) config.getValue("screenheight", defaultScreenHeight);
- const int bpp = 0;
- const bool fullscreen = ((int) config.getValue("screen", 0) == 1);
- const bool hwaccel = ((int) config.getValue("hwaccel", 0) == 1);
-
- // Try to set the desired video mode
- if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
- {
- logger->error(strprintf("Couldn't set %dx%dx%d video mode: %s",
- width, height, bpp, SDL_GetError()));
- }
-
- // Initialize for drawing
- graphics->_beginDraw();
-
- // Initialize the item shortcuts.
- itemShortcut = new ItemShortcut;
-
- // Initialize the emote shortcuts.
- emoteShortcut = new EmoteShortcut;
-
- gui = new Gui(graphics);
-
- // Initialize sound engine
- try
- {
- if (config.getValue("sound", 0) == 1)
- sound.init();
-
- sound.setSfxVolume((int) config.getValue("sfxVolume",
- defaultSfxVolume));
- sound.setMusicVolume((int) config.getValue("musicVolume",
- defaultMusicVolume));
- }
- catch (const char *err)
- {
- state = STATE_ERROR;
- errorMessage = err;
- logger->log("Warning: %s", err);
- }
-
- // Initialize keyboard
- keyboard.init();
-
- // Initialise player relations
- player_relations.init();
-}
-
-/** Clear the engine */
-static void exitEngine()
-{
- // Before config.write() since it writes the shortcuts to the config
- delete itemShortcut;
- delete emoteShortcut;
-
- config.write();
-
- delete gui;
- delete graphics;
-
- // Shutdown libxml
- xmlCleanupParser();
-
- // Shutdown sound
- sound.close();
-
- // Unload XML databases
- ColorDB::unload();
- EmoteDB::unload();
- ItemDB::unload();
- MonsterDB::unload();
- NPCDB::unload();
- StatusEffect::unload();
-
- ResourceManager::deleteInstance();
-
- SDL_FreeSurface(icon);
-}
static void printHelp()
{
@@ -544,7 +63,7 @@ static void printVersion()
std::cout << strprintf("Mana client %s", FULL_VERSION) << std::endl;
}
-static void parseOptions(int argc, char *argv[], Options &options)
+static void parseOptions(int argc, char *argv[], Client::Options &options)
{
const char *optstring = "hvud:U:P:Dc:s:p:C:H:S:Oi:";
@@ -626,58 +145,9 @@ static void parseOptions(int argc, char *argv[], Options &options)
}
}
-class AccountListener : public gcn::ActionListener
-{
-public:
- void action(const gcn::ActionEvent &)
- {
- state = STATE_CHAR_SELECT;
- }
-} accountListener;
-
-class LoginListener : public gcn::ActionListener
-{
-public:
- void action(const gcn::ActionEvent &)
- {
- state = STATE_LOGIN;
- }
-} loginListener;
-
-} // namespace
-
-void ErrorListener::action(const gcn::ActionEvent &)
-{
- state = STATE_CHOOSE_SERVER;
-}
-
-const std::string &getHomeDirectory()
-{
- return homeDir;
-}
-
-// TODO Find some nice place for these functions
-static void accountLogin(LoginData *loginData)
-{
- logger->log("Username is %s", loginData->username.c_str());
-
- // Send login infos
- if (loginData->registerLogin)
- Net::getLoginHandler()->registerAccount(loginData);
- else
- Net::getLoginHandler()->loginAccount(loginData);
-
- // Clear the password, avoids auto login when returning to login
- loginData->password = "";
-
- // TODO This is not the best place to save the config, but at least better
- // than the login gui window
- if (loginData->remember)
- config.setValue("username", loginData->username);
- config.setValue("remember", loginData->remember);
-}
-
+#ifdef WIN32
extern "C" char const *_nl_locale_name_default(void);
+#endif
static void initInternationalization()
{
@@ -711,16 +181,18 @@ static void initXML()
xmlSetGenericErrorFunc(NULL, xmlNullLogger);
}
-/** Main */
+
int main(int argc, char *argv[])
{
#if defined(DEBUG) && defined(WIN32)
- // load mingw crash handler. Won't fail if dll is not present.
+ // Load mingw crash handler. Won't fail if dll is not present.
LoadLibrary("exchndl.dll");
#endif
+
// Parse command line options
- Options options;
+ Client::Options options;
parseOptions(argc, argv, options);
+
if (options.printHelp)
{
printHelp();
@@ -735,557 +207,15 @@ int main(int argc, char *argv[])
initInternationalization();
// Initialize PhysicsFS
- PHYSFS_init(argv[0]);
-
- initXML();
-
- // Load branding information
- branding.init("data/branding.xml");
-
- initHomeDir(options);
-
- setScreenshotDir(options.screenshotDir);
-
- // Configure logger
- logger = new Logger;
- logger->setLogFile(homeDir + std::string("/mana.log"));
-
- // Log the mana version
- logger->log("Mana %s", FULL_VERSION);
-
- initConfiguration(options);
- logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
-
- initEngine(options);
-
- // Needs to be created in main, as the updater uses it
- guiPalette = new Palette;
-
- Window *currentDialog = 0;
- QuitDialog *quitDialog = 0;
- setupWindow = new Setup;
-
- gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
- Desktop *desktop = 0;
- Button *setupButton = 0;
-
- sound.playMusic(branding.getValue("loginMusic", "Magick - Real.ogg"));
-
- // Initialize default server
- ServerInfo currentServer;
- currentServer.hostname = options.serverName;
- currentServer.port = options.serverPort;
- loginData.username = options.username;
- loginData.password = options.password;
- loginData.remember = config.getValue("remember", 0);
- loginData.registerLogin = false;
-
- if (currentServer.hostname.empty())
- {
- currentServer.hostname = branding.getValue("defaultServer",
- "server.themanaworld.org").c_str();
- }
- if (options.serverPort == 0)
- {
- currentServer.port = (short) branding.getValue("defaultPort",
- DEFAULT_PORT);
- }
- if (loginData.username.empty() && loginData.remember)
- loginData.username = config.getValue("username", "");
-
- if (state != STATE_ERROR)
- state = STATE_CHOOSE_SERVER;
- State oldstate = STATE_START; // We start with a status change
-
- SDL_Event event;
-
- while (state != STATE_EXIT)
- {
- bool handledEvents = false;
-
- // Handle SDL events
- while (SDL_PollEvent(&event))
- {
- handledEvents = true;
-
- switch (event.type)
- {
- case SDL_QUIT:
- state = STATE_EXIT;
- break;
-
- case SDL_KEYDOWN:
- break;
- }
-
- guiInput->pushInput(event);
- }
-
- if (Net::getGeneralHandler())
- Net::getGeneralHandler()->flushNetwork();
-
- gui->logic();
- gui->draw();
- graphics->updateScreen();
-
- // TODO: Add connect timeouts
- if (state == STATE_CONNECT_GAME &&
- Net::getGameHandler()->isConnected())
- {
- Net::getLoginHandler()->disconnect();
- }
- else if (state == STATE_CONNECT_SERVER && oldstate == STATE_CHOOSE_SERVER)
- {
- Net::connectToServer(currentServer);
- }
- else if (state == STATE_CONNECT_SERVER &&
- oldstate != STATE_CHOOSE_SERVER &&
- Net::getLoginHandler()->isConnected())
- {
- state = STATE_LOGIN;
- }
- else if (state == STATE_WORLD_SELECT && oldstate == STATE_UPDATE)
- {
- if (Net::getLoginHandler()->getWorlds().size() < 2)
- {
- state = STATE_LOGIN;
- }
- }
- else if (oldstate == STATE_START || oldstate == STATE_GAME)
- {
- desktop = new Desktop;
- top->add(desktop);
- setupButton = new Button(_("Setup"), "Setup", &listener);
- setupButton->setPosition(top->getWidth() - setupButton->getWidth()
- - 3, 3);
- top->add(setupButton);
-
- int screenWidth = (int) config.getValue("screenwidth",
- defaultScreenWidth);
- int screenHeight = (int) config.getValue("screenheight",
- defaultScreenHeight);
-
- desktop->setSize(screenWidth, screenHeight);
- }
-
- if (state == STATE_SWITCH_LOGIN && oldstate == STATE_GAME)
- {
- Net::getGameHandler()->disconnect();
- }
-
- if (state != oldstate)
- {
- oldstate = state;
-
- // Get rid of the dialog of the previous state
- if (currentDialog)
- {
- delete currentDialog;
- currentDialog = NULL;
- }
- // State has changed, while the quitDialog was active, it might
- // not be correct anymore
- if (quitDialog)
- quitDialog->scheduleDelete();
-
- switch (state)
- {
- case STATE_CHOOSE_SERVER:
- logger->log("State: CHOOSE SERVER");
-
- // Allow changing this using a server choice dialog
- // We show the dialog box only if the command-line
- // options weren't set.
- if (options.serverName.empty() && options.serverPort == 0)
- {
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- currentDialog = new ServerDialog(&currentServer,
- homeDir);
- }
- else
- {
- state = STATE_CONNECT_SERVER;
-
- // Reset options so that cancelling or connect
- // timeout will show the server dialog.
- options.serverName.clear();
- options.serverPort = 0;
- }
- break;
-
- case STATE_CONNECT_SERVER:
- logger->log("State: CONNECT SERVER");
- currentDialog = new ConnectionDialog(
- _("Connecting to server"), STATE_SWITCH_SERVER);
- break;
-
- case STATE_LOGIN:
- logger->log("State: LOGIN");
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- if (options.username.empty()
- || options.password.empty())
- {
- currentDialog = new LoginDialog(&loginData);
- }
- else
- {
- state = STATE_LOGIN_ATTEMPT;
- // Clear the password so that when login fails, the
- // dialog will show up next time.
- options.password.clear();
- }
- break;
-
- case STATE_LOGIN_ATTEMPT:
- logger->log("State: LOGIN ATTEMPT");
- accountLogin(&loginData);
- currentDialog = new ConnectionDialog(
- _("Logging in"), STATE_SWITCH_SERVER);
- break;
-
- case STATE_WORLD_SELECT:
- logger->log("State: WORLD SELECT");
- {
- Worlds worlds = Net::getLoginHandler()->getWorlds();
-
- if (worlds.size() == 0)
- {
- // Trust that the netcode knows what it's doing
- state = STATE_UPDATE;
- }
- else if (worlds.size() == 1)
- {
- Net::getLoginHandler()->chooseServer(0);
- state = STATE_UPDATE;
- }
- else
- {
- currentDialog = new WorldSelectDialog(worlds);
- if (options.chooseDefault)
- {
- ((WorldSelectDialog*) currentDialog)->action(
- gcn::ActionEvent(NULL, "ok"));
- }
- }
- }
- break;
-
- case STATE_WORLD_SELECT_ATTEMPT:
- logger->log("State: WORLD SELECT ATTEMPT");
- currentDialog = new ConnectionDialog(
- _("Entering game world"), STATE_WORLD_SELECT);
- break;
-
- case STATE_UPDATE:
-
- // Determine which source to use for the update host
- if (!options.updateHost.empty())
- updateHost = options.updateHost;
- else
- updateHost = loginData.updateHost;
- setUpdatesDir();
-
- if (options.skipUpdate)
- {
- state = STATE_LOAD_DATA;
- }
- else
- {
- logger->log("State: UPDATE");
- currentDialog = new UpdaterWindow(updateHost,
- homeDir + "/" + updatesDir,options.dataPath.empty());
- }
- break;
-
- case STATE_LOAD_DATA:
- logger->log("State: LOAD DATA");
-
- // If another data path has been set,
- // we don't load any other files...
- if (options.dataPath.empty())
- {
- // Add customdata directory
- ResourceManager::getInstance()->searchAndAddArchives(
- "customdata/",
- "zip",
- false);
- }
-
- // Load XML databases
- ColorDB::load();
- ItemDB::load();
- Being::load(); // Hairstyles
- MonsterDB::load();
- NPCDB::load();
- EmoteDB::load();
- StatusEffect::load();
- Units::loadUnits();
-
- desktop->reloadWallpaper();
-
- state = STATE_GET_CHARACTERS;
- break;
-
- case STATE_GET_CHARACTERS:
- logger->log("State: GET CHARACTERS");
- Net::getCharHandler()->requestCharacters();
- currentDialog = new ConnectionDialog(
- _("Requesting characters"),
- STATE_SWITCH_SERVER);
- break;
-
- case STATE_CHAR_SELECT:
- logger->log("State: CHAR SELECT");
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- currentDialog = new CharSelectDialog(&loginData);
-
- if (!((CharSelectDialog*) currentDialog)->selectByName(
- options.character, CharSelectDialog::Choose))
- {
- ((CharSelectDialog*) currentDialog)->selectByName(
- config.getValue("lastCharacter", ""),
- options.chooseDefault ?
- CharSelectDialog::Choose :
- CharSelectDialog::Focus);
- }
-
- break;
-
- case STATE_CONNECT_GAME:
- logger->log("State: CONNECT GAME");
-
- Net::getGameHandler()->connect();
- currentDialog = new ConnectionDialog(
- _("Connecting to the game server"),
- STATE_SWITCH_CHARACTER);
- break;
-
- case STATE_GAME:
- logger->log("Memorizing selected character %s",
- player_node->getName().c_str());
- config.setValue("lastCharacter", player_node->getName());
-
- Net::getGameHandler()->inGame();
-
- // Fade out logon-music here too to give the desired effect
- // of "flowing" into the game.
- sound.fadeOutMusic(1000);
-
- // Allow any alpha opacity
- SkinLoader::instance()->setMinimumOpacity(-1.0f);
-
- delete setupButton;
- delete desktop;
- setupButton = NULL;
- desktop = NULL;
-
- currentDialog = NULL;
-
- logger->log("State: GAME");
- game = new Game;
- game->exec();
- delete game;
- game = 0;
-
- if (state == STATE_GAME)
- state = STATE_EXIT;
-
- break;
-
- case STATE_LOGIN_ERROR:
- logger->log("State: LOGIN ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&loginListener);
- currentDialog = NULL; // OkDialog deletes itself
- break;
-
- case STATE_ACCOUNTCHANGE_ERROR:
- logger->log("State: ACCOUNT CHANGE ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
- break;
-
- case STATE_REGISTER_PREP:
- logger->log("State: REGISTER_PREP");
- Net::getLoginHandler()->getRegistrationDetails();
- currentDialog = new ConnectionDialog(
- _("Requesting registration details"), STATE_LOGIN);
- break;
-
- case STATE_REGISTER:
- logger->log("State: REGISTER");
- currentDialog = new RegisterDialog(&loginData);
- break;
-
- case STATE_REGISTER_ATTEMPT:
- logger->log("Username is %s", loginData.username.c_str());
- Net::getLoginHandler()->registerAccount(&loginData);
- break;
-
- case STATE_CHANGEPASSWORD:
- logger->log("State: CHANGE PASSWORD");
- currentDialog = new ChangePasswordDialog(&loginData);
- break;
-
- case STATE_CHANGEPASSWORD_ATTEMPT:
- logger->log("State: CHANGE PASSWORD ATTEMPT");
- Net::getLoginHandler()->changePassword(loginData.username,
- loginData.password,
- loginData.newPassword);
- break;
-
- case STATE_CHANGEPASSWORD_SUCCESS:
- logger->log("State: CHANGE PASSWORD SUCCESS");
- currentDialog = new OkDialog(_("Password Change"),
- _("Password changed successfully!"));
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
- loginData.password = loginData.newPassword;
- loginData.newPassword = "";
- break;
-
- case STATE_CHANGEEMAIL:
- logger->log("State: CHANGE EMAIL");
- currentDialog = new ChangeEmailDialog(&loginData);
- break;
-
- case STATE_CHANGEEMAIL_ATTEMPT:
- logger->log("State: CHANGE EMAIL ATTEMPT");
- Net::getLoginHandler()->changeEmail(loginData.email);
- break;
-
- case STATE_CHANGEEMAIL_SUCCESS:
- logger->log("State: CHANGE EMAIL SUCCESS");
- currentDialog = new OkDialog(_("Email Change"),
- _("Email changed successfully!"));
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
- break;
-
- case STATE_UNREGISTER:
- logger->log("State: UNREGISTER");
- currentDialog = new UnRegisterDialog(&loginData);
- break;
-
- case STATE_UNREGISTER_ATTEMPT:
- logger->log("State: UNREGISTER ATTEMPT");
- Net::getLoginHandler()->unregisterAccount(
- loginData.username, loginData.password);
- break;
-
- case STATE_UNREGISTER_SUCCESS:
- logger->log("State: UNREGISTER SUCCESS");
- Net::getLoginHandler()->disconnect();
-
- currentDialog = new OkDialog(_("Unregister Successful"),
- _("Farewell, come back any time..."));
- loginData.clear();
- //The errorlistener sets the state to STATE_CHOOSE_SERVER
- currentDialog->addActionListener(&errorListener);
- currentDialog = NULL; // OkDialog deletes itself
- break;
-
- case STATE_SWITCH_SERVER:
- logger->log("State: SWITCH SERVER");
-
- Net::getLoginHandler()->disconnect();
- Net::getGameHandler()->disconnect();
-
- state = STATE_CHOOSE_SERVER;
- break;
-
- case STATE_SWITCH_LOGIN:
- logger->log("State: SWITCH LOGIN");
-
- Net::getLoginHandler()->logout();
-
- state = STATE_LOGIN;
- break;
-
- case STATE_SWITCH_CHARACTER:
- logger->log("State: SWITCH CHARACTER");
-
- // Done with game
- Net::getGameHandler()->disconnect();
-
- Net::getCharHandler()->requestCharacters();
- break;
-
- case STATE_LOGOUT_ATTEMPT:
- logger->log("State: LOGOUT ATTEMPT");
- // TODO
- break;
-
- case STATE_WAIT:
- logger->log("State: WAIT");
- break;
-
- case STATE_EXIT:
- logger->log("State: EXIT");
- Net::unload();
- break;
-
- case STATE_FORCE_QUIT:
- logger->log("State: FORCE QUIT");
- if (Net::getGeneralHandler())
- Net::getGeneralHandler()->unload();
- state = STATE_EXIT;
- break;
-
- case STATE_ERROR:
- logger->log("State: ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&errorListener);
- currentDialog = NULL; // OkDialog deletes itself
- Net::getGameHandler()->disconnect();
- break;
-
- default:
- state = STATE_FORCE_QUIT;
- break;
- }
- }
-
- /*
- * This loop can really stress the CPU, for no reason since it's
- * just constantly redrawing the wallpaper. Added the following
- * usleep to limit it to 40 FPS during the login sequence
- */
- if (!handledEvents)
- usleep(25000);
+ if (!PHYSFS_init(argv[0])) {
+ std::cout << "Error while initializing PhysFS: "
+ << PHYSFS_getLastError() << std::endl;
+ return 1;
}
+ atexit((void(*)()) PHYSFS_deinit);
- delete guiPalette;
-
- logger->log("Quitting");
- exitEngine();
- PHYSFS_deinit();
- delete logger;
-
- return 0;
-}
-
-void SetupListener::action(const gcn::ActionEvent &event)
-{
- Window *window = NULL;
-
- if (event.getId() == "Setup")
- window = setupWindow;
+ initXML();
- if (window)
- {
- window->setVisible(!window->isVisible());
- if (window->isVisible())
- window->requestMoveToTop();
- }
+ Client client(options);
+ return client.exec();
}