summaryrefslogtreecommitdiffstats
path: root/source3/lib/namearray.c
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2014-05-25 11:31:44 +1000
committerMichael Adam <obnox@samba.org>2014-06-20 23:38:09 +0200
commit4a5ded2b69b7538688da59423bd1b53df1d6c77a (patch)
treeb77865ac999a1366cdcd5babd0a4b0ef9e40ea79 /source3/lib/namearray.c
parentcd7f401744e1fa65d309c7c9b8e68eb7c6faf2bc (diff)
downloadsamba-4a5ded2b69b7538688da59423bd1b53df1d6c77a.tar.gz
samba-4a5ded2b69b7538688da59423bd1b53df1d6c77a.tar.xz
samba-4a5ded2b69b7538688da59423bd1b53df1d6c77a.zip
wafsamba: allow samba_dist.dist() to be called from a different directory.
Up to now it assumed to be called from the top level srcdir. Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/lib/namearray.c')
0 files changed, 0 insertions, 0 deletions
119' href='#n119'>119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
/*
 *  The Mana World Server
 *  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 <cstdlib>
#include <getopt.h>
#include <iostream>
#include <signal.h>
#include <physfs.h>
#include <enet/enet.h>

#if (defined __USE_UNIX98 || defined __FreeBSD__)
#include "../config.h"
#endif

#include "configuration.h"
#include "resourcemanager.h"
#include "skill.h"
#include "game-server/accountconnection.hpp"
#include "game-server/gamehandler.hpp"
#include "game-server/itemmanager.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/state.hpp"
#include "net/connectionhandler.hpp"
#include "net/messageout.hpp"
#include "utils/logger.h"
#include "utils/stringfilter.h"
#include "utils/timer.h"
#include "utils/mathutils.h"

// Scripting
#ifdef SCRIPT_SUPPORT

extern "C" void Init_Tmw();

#if defined (SQUIRREL_SUPPORT)
std::string scriptLanguage = "squirrel";
#elif defined (RUBY_SUPPORT)
#include <ruby.h>
int rubyStatus;
std::string scriptLanguage = "ruby";
#elif defined (LUA_SUPPORT)
std::string scriptLanguage = "lua";
#else
#error "Scripting enabled, but no language selected"
#endif

#else
std::string scriptLanugage = "none";
#endif // SCRIPT_SUPPORT

// Default options that automake should be able to override.
#define DEFAULT_LOG_FILE        "tmwserv.log"
#define DEFAULT_CONFIG_FILE     "tmwserv.xml"
#define DEFAULT_ITEMSDB_FILE    "items.xml"
#define DEFAULT_MAPSDB_FILE     "maps.xml"

utils::Timer worldTimer(100, false);   /**< Timer for world tics set to 100 ms */
int worldTime = 0;              /**< Current world time in 100ms ticks */
bool running = true;            /**< Determines if server keeps running */

Skill skillTree("base");        /**< Skill tree */

Configuration config;           /**< XML config reader */

utils::StringFilter *stringFilter; /**< Slang's Filter */

/** Item manager */
ItemManager *itemManager;

/** Map manager */
MapManager *mapManager;

/** Core game message handler */
GameHandler *gameHandler;

/** Account server message handler */
AccountConnection *accountHandler;

/** Global game state */
State *gameState;

/** Callback used when SIGQUIT signal is received. */
void closeGracefully(int dummy)
{
    running = false;
}

/**
 * Initializes the server.
 */
void initialize()
{
    // Reset to default segmentation fault handling for debugging purposes
    signal(SIGSEGV, SIG_DFL);

    // Used to close via process signals
#if (defined __USE_UNIX98 || defined __FreeBSD__)
    signal(SIGQUIT, closeGracefully);
#endif
    signal(SIGINT, closeGracefully);

    /*
     * If the path values aren't defined, we set the default
     * depending on the platform.
     */
    // The config path
#if defined CONFIG_FILE
    std::string configPath = CONFIG_FILE;
#else

#if (defined __USE_UNIX98 || defined __FreeBSD__)
    std::string configPath = getenv("HOME");
    configPath += "/.";
    configPath += DEFAULT_CONFIG_FILE;
#else // Win32, ...
    std::string configPath = DEFAULT_CONFIG_FILE;
#endif

#endif // defined CONFIG_FILE

    // The log path
#if defined LOG_FILE
    std::string logPath = LOG_FILE;
#else

#if (defined __USE_UNIX98 || defined __FreeBSD__)
    std::string logPath = getenv("HOME");
    logPath += "/.";
    logPath += DEFAULT_LOG_FILE;
#else // Win32, ...
    std::string logPath = DEFAULT_LOG_FILE;
#endif

#endif // defined LOG_FILE

    // Initialize PhysicsFS
    PHYSFS_init("");

    // Initialize the logger.
    using namespace utils;
    Logger::setLogFile(logPath);

    // Write the messages to both the screen and the log file.
    Logger::setTeeMode(true);

    config.init(configPath);
    LOG_INFO("Using config file: " << configPath);
    LOG_INFO("Using log file: " << logPath);

    // --- Initialize the managers
    // Initialize the slang's and double quotes filter.
    stringFilter = new StringFilter(&config);
    // Initialize the map manager
    mapManager = new MapManager(DEFAULT_MAPSDB_FILE);
    // Initialize the item manager
    itemManager = new ItemManager(DEFAULT_ITEMSDB_FILE);

    // --- Initialize the global handlers
    // FIXME: Make the global handlers global vars or part of a bigger
    // singleton or a local variable in the event-loop
    gameHandler = new GameHandler();
    accountHandler = new AccountConnection();

    // --- Initialize enet.
    if (enet_initialize() != 0) {
        LOG_FATAL("An error occurred while initializing ENet");
        exit(2);
    }

    // Set enet to quit on exit.
    atexit(enet_deinitialize);

    // --- Initialize scripting subsystem.
#ifdef RUBY_SUPPORT
    LOG_INFO("Script language: " << scriptLanguage);

    // Initialize ruby
    ruby_init();
    ruby_init_loadpath();
    ruby_script("tmw");

    // Initialize bindings
    Init_Tmw();

    // Run test script
    rb_load_file("scripts/init.rb");
    rubyStatus = ruby_exec();
#else
    LOG_WARN("No scripting language support.");
#endif

    // Pre-calulate the needed trigomic function values
    utils::math::init();
}


/**
 * Deinitializes the server.
 */
void deinitialize()
{
    // Write configuration file
    config.write();

    // Stop world timer
    worldTimer.stop();

#ifdef RUBY_SUPPORT
    // Finish up ruby
    ruby_finalize();
    ruby_cleanup(rubyStatus);
#endif

    // Destroy message handlers
    delete gameHandler;
    delete accountHandler;

    // Destroy Managers
    delete stringFilter;
    delete itemManager;
    delete mapManager;

    PHYSFS_deinit();
}


/**
 * Show command line arguments
 */
void printHelp()
{
    std::cout << "tmwserv" << std::endl << std::endl
              << "Options: " << std::endl
              << "  -h --help          : Display this help" << std::endl
              << "     --verbosity <n> : Set the verbosity level" << std::endl
              << "     --port <n>      : Set the default port to listen on" << std::endl;
    exit(0);
}

/**
 * Parse the command line arguments
 */
void parseOptions(int argc, char *argv[])
{
    const char *optstring = "h";

    const struct option long_options[] = {
        { "help",       no_argument, 0, 'h' },
        { "verbosity",  required_argument, 0, 'v' },
        { "port",       required_argument, 0, 'p' },
        { 0 }
    };

    while (optind < argc) {
        int result = getopt_long(argc, argv, optstring, long_options, NULL);

        if (result == -1) {
            break;
        }

        switch (result) {
            default: // Unknown option
            case 'h':
                // Print help
                printHelp();
                break;
            case 'v':
                // Set Verbosity to level
                unsigned short verbosityLevel;
                verbosityLevel = atoi(optarg);
                utils::Logger::setVerbosity(utils::Logger::Level(verbosityLevel));
                LOG_INFO("Setting log verbosity level to " << verbosityLevel);
                break;
            case 'p':
                // Change the port to listen on.
                unsigned short portToListenOn;
                portToListenOn = atoi(optarg);
                config.setValue("gameServerPort", portToListenOn);
                LOG_INFO("Setting default port to " << portToListenOn);
                break;
        }
    }
}


/**
 * Main function, initializes and runs server.
 */
int main(int argc, char *argv[])
{
    int elapsedWorldTicks;

    LOG_INFO("The Mana World Game Server v" << PACKAGE_VERSION);

    // Parse command line options
    parseOptions(argc, argv);

    // General initialization
    initialize();

    if (!accountHandler->start()) {
        LOG_FATAL("Unable to create a connection to an account server.");
        return 3;
    }

    int gameServerPort =
        (int) config.getValue("gameServerPort", DEFAULT_SERVER_PORT + 3);

    if (!gameHandler->startListen(gameServerPort))
    {
        LOG_FATAL("Unable to create an ENet server host.");
        return 3;
    }

    // Create state machine
    gameState = new State;

    // Initialize world timer
    worldTimer.start();

    while (running) {
        elapsedWorldTicks = worldTimer.poll();
        if (elapsedWorldTicks > 0) {
            worldTime += elapsedWorldTicks;

            if (elapsedWorldTicks > 1)
            {
                LOG_WARN(elapsedWorldTicks -1 << " World Tick(s) skipped "
                        "because of insufficient time. Please buy a faster "
                        "machine ;-)");
            };

            // Print world time at 10 second intervals to show we're alive
            if (worldTime % 100 == 0) {
                LOG_INFO("World time: " << worldTime);
            }

            // Handle all messages that are in the message queues
            accountHandler->process();
            gameHandler->process();
            // Update all active objects/beings
            gameState->update();
            // Send potentially urgent outgoing messages
            gameHandler->flush();
        }
        worldTimer.sleep();
    }

    LOG_INFO("Received: Quit signal, closing down...");
    gameHandler->stopListen();
    accountHandler->stop();
    delete gameState;
    deinitialize();
}