summaryrefslogblamecommitdiff
path: root/src/game-server/settingsmanager.cpp
blob: d6e5e564e91772863fbd639640bb273c07de45a8 (plain) (tree)


























                                                                            
                                       
                                         
                                    
                                   











                                                            
                             
                                   
                                 
















                                                                                           
                         
                               
                             




























































                                                                                                                         




                                                              




                                                                    
                                                                  
         
                             
                                                                 









































                                                                                     
                              
                                    
                                  




                                  
/*
 *  The Mana Server
 *  Copyright (C) 2013  The Mana World Development Team
 *
 *  This file is part of The Mana Server.
 *
 *  The Mana Server 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 Server 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 Server.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "game-server/settingsmanager.h"
#include "common/defines.h"
#include "utils/logger.h"
#include "utils/xml.h"

#include "common/resourcemanager.h"

#include "game-server/abilitymanager.h"
#include "game-server/attributemanager.h"
#include "game-server/itemmanager.h"
#include "game-server/mapmanager.h"
#include "game-server/monstermanager.h"
#include "game-server/emotemanager.h"
#include "game-server/statusmanager.h"

/**
 * Initialize all managers and load configuration into them.
 *
 * Fatal errors will call exit()
 */
void SettingsManager::initialize()
{
    // initialize all managers in correct order
    MapManager::initialize();
    attributeManager->initialize();
    abilityManager->initialize();
    itemManager->initialize();
    monsterManager->initialize();
    emoteManager->initialize();
    StatusManager::initialize();

    loadFile(mSettingsFile);
    checkStatus();
}

/**
 * Reload managers with new configuration.
 *
 * @note This code is untested, some of the managers didn't even have empty implementations
 *       of reload().
 */
void SettingsManager::reload()
{
    MapManager::reload();
    attributeManager->reload();
    abilityManager->reload();
    itemManager->reload();
    monsterManager->reload();
    emoteManager->reload();
    StatusManager::reload();

    loadFile(mSettingsFile);
    checkStatus();
}

/**
 * Load a configuration file.
 */
void SettingsManager::loadFile(const std::string &filename)
{
    LOG_INFO("Loading game settings from " << filename);

    XML::Document doc(filename);
    xmlNodePtr node = doc.rootNode();

    // add file to include set
    mIncludedFiles.insert(filename);

    // FIXME: check root node's name when bjorn decides it's time
    if (!node /*|| !xmlStrEqual(node->name, BAD_CAST "settings") */)
    {
        LOG_FATAL("Settings Manager: " << filename << " is not a valid database file!");
        exit(EXIT_XML_BAD_PARAMETER);
    }


    // go through every node
    for_each_xml_child_node(childNode, node)
    {
        if (childNode->type != XML_ELEMENT_NODE)
            continue;

        if (xmlStrEqual(childNode->name, BAD_CAST "include"))
        {
            // include an other file
            const std::string includeFile = XML::getProperty(childNode, "file", std::string());

            // check if file property was given
            if (!includeFile.empty())
            {
                // build absolute path path
                const ResourceManager::splittedPath splittedPath = ResourceManager::splitFileNameAndPath(filename);
                const std::string realIncludeFile = ResourceManager::cleanPath(
                        ResourceManager::joinPaths(splittedPath.path, includeFile));

                // check if we're not entering a loop
                if (mIncludedFiles.find(realIncludeFile) != mIncludedFiles.end())
                {
                    LOG_ERROR("Circular include loop detecting while including " << includeFile << " from " << filename);
                }
                else
                {
                    // include that file
                    loadFile(realIncludeFile);
                }
            }
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "map"))
        {
            // map config
            MapManager::readMapNode(childNode);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "attribute"))
        {
            // attribute config
            attributeManager->readAttributeNode(childNode);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "ability"))
        {
            // ability config
            abilityManager->readAbilityNode(childNode, filename);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "slot"))
        {
            // equipement slot config
            itemManager->readEquipSlotNode(childNode);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "item"))
        {
            // item config
            itemManager->readItemNode(childNode, filename);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "monster"))
        {
            // monster config
            monsterManager->readMonsterNode(childNode, filename);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "emote"))
        {
            // emote config
            emoteManager->readEmoteNode(childNode, filename);
        }
        else if (xmlStrEqual(childNode->name, BAD_CAST "status-effect"))
        {
            // status effects config
            StatusManager::readStatusNode(childNode, filename);
        }
        else
        {
            // since the client and server share settings, don't be too strict
//            LOG_WARN("Unexpected tag <" << childNode->name << "> in " << filename);
        }
    }

    // remove this file from include stack
    mIncludedFiles.erase(filename);
}

/**
 * Finalize the configuration loading and check if all managers are happy with it.
 */
void SettingsManager::checkStatus()
{
    MapManager::checkStatus();
    attributeManager->checkStatus();
    abilityManager->checkStatus();
    itemManager->checkStatus();
    monsterManager->checkStatus();
    emoteManager->checkStatus();
    StatusManager::checkStatus();
}