diff options
-rw-r--r-- | accountserver.cbp | 2 | ||||
-rw-r--r-- | docs/manaserv.xml.example | 9 | ||||
-rw-r--r-- | example/maps.xml | 5 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/account-server/mapmanager.cpp | 61 | ||||
-rw-r--r-- | src/account-server/mapmanager.h | 42 | ||||
-rw-r--r-- | src/account-server/serverhandler.cpp | 28 | ||||
-rw-r--r-- | src/common/defines.h | 12 | ||||
-rw-r--r-- | src/common/manaserv_protocol.h | 2 | ||||
-rw-r--r-- | src/game-server/accountconnection.cpp | 11 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 12 |
11 files changed, 155 insertions, 31 deletions
diff --git a/accountserver.cbp b/accountserver.cbp index 8704c492..3b387a3d 100644 --- a/accountserver.cbp +++ b/accountserver.cbp @@ -148,6 +148,8 @@ <Unit filename="src/account-server/character.cpp" /> <Unit filename="src/account-server/character.h" /> <Unit filename="src/account-server/main-account.cpp" /> + <Unit filename="src/account-server/mapmanager.cpp" /> + <Unit filename="src/account-server/mapmanager.h" /> <Unit filename="src/account-server/serverhandler.cpp" /> <Unit filename="src/account-server/serverhandler.h" /> <Unit filename="src/account-server/storage.cpp" /> diff --git a/docs/manaserv.xml.example b/docs/manaserv.xml.example index ef220a6b..97ee1704 100644 --- a/docs/manaserv.xml.example +++ b/docs/manaserv.xml.example @@ -161,6 +161,15 @@ <!-- needed to set when hosting behind router or in situations where you cannot bind the server to the public url --> <!-- <option name="net_publicGameHost" value="mydomain.org"/> --> + + <!-- + Usually the first game server activates all maps. To prevent this you need to + set a name for the server and set this name in the maps.xml (see documentation + there). + --> + <!-- + <option name="net_gameServerName" value="myServer" /> + --> <!-- Update host url: E.g.: "http://updates.manasource.org/" diff --git a/example/maps.xml b/example/maps.xml index 94673852..8d1889f2 100644 --- a/example/maps.xml +++ b/example/maps.xml @@ -1,4 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <maps> + <!-- + id: unique id of map(> 0) + name: the name of the maps (without .tmx extension) + [optional] servername: the name of the server that should run this map + --> <map id="1" name="desert" /> </maps> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c8752fbc..629df5ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -153,6 +153,8 @@ SET(SRCS_MANASERVACCOUNT account-server/character.h account-server/character.cpp account-server/flooritem.h + account-server/mapmanager.h + account-server/mapmanager.cpp account-server/serverhandler.h account-server/serverhandler.cpp account-server/storage.h diff --git a/src/account-server/mapmanager.cpp b/src/account-server/mapmanager.cpp new file mode 100644 index 00000000..148c5434 --- /dev/null +++ b/src/account-server/mapmanager.cpp @@ -0,0 +1,61 @@ +/* + * The Mana Server + * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2013 The Mana 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 "account-server/mapmanager.h" + +#include "utils/logger.h" +#include "utils/xml.h" + +#include <map> + +static std::map<int, std::string> maps; + +void MapManager::initialize(const std::string &mapReferenceFile) +{ + maps.clear(); + + XML::Document doc(mapReferenceFile); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "maps")) + { + LOG_ERROR("Map Manager: Error while parsing map database (" + << mapReferenceFile << ")!"); + return; + } + LOG_INFO("Loading map reference: " << mapReferenceFile); + for_each_xml_child_node(node, rootNode) + { + if (!xmlStrEqual(node->name, BAD_CAST "map")) + continue; + + int id = XML::getProperty(node, "id", 0); + std::string name = XML::getProperty(node, "servername", std::string()); + + if (id > 0) + maps[id] = name; + } +} + +std::map<int, std::string> &MapManager::getMaps() +{ + return maps; +} diff --git a/src/account-server/mapmanager.h b/src/account-server/mapmanager.h new file mode 100644 index 00000000..67426415 --- /dev/null +++ b/src/account-server/mapmanager.h @@ -0,0 +1,42 @@ +/* + * The Mana Server + * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2013 The Mana 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/>. + */ + +#ifndef MAPMANAGER_H +#define MAPMANAGER_H + +#include <string> +#include <map> + +namespace MapManager +{ + /** + * Loads map reference file + */ + void initialize(const std::string &mapReferenceFile); + + /** + * Returns a map of all maps + * @return a map of mapid + name of reserved server. + */ + std::map<int, std::string> &getMaps(); +} + +#endif // MAPMANAGER_H diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index 04fd1e23..3260f44d 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -28,10 +28,12 @@ #include "account-server/accounthandler.h" #include "account-server/character.h" #include "account-server/flooritem.h" +#include "account-server/mapmanager.h" #include "account-server/storage.h" #include "chat-server/chathandler.h" #include "chat-server/post.h" #include "common/configuration.h" +#include "common/defines.h" #include "common/manaserv_protocol.h" #include "common/transaction.h" #include "net/connectionhandler.h" @@ -59,6 +61,7 @@ struct GameServer: NetComputer { GameServer(ENetPeer *peer): NetComputer(peer), server(0), port(0) {} + std::string name; std::string address; NetComputer *server; ServerStatistics maps; @@ -97,6 +100,7 @@ static ServerHandler *serverHandler; bool GameServerHandler::initialize(int port, const std::string &host) { + MapManager::initialize(DEFAULT_MAPSDB_FILE); serverHandler = new ServerHandler; LOG_INFO("Game server handler started:"); return serverHandler->startListen(port, host); @@ -180,6 +184,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) { LOG_DEBUG("GAMSG_REGISTER"); // TODO: check the credentials of the game server + server->name = msg.readString(); server->address = msg.readString(); server->port = msg.readInt16(); const std::string password = msg.readString(); @@ -220,31 +225,30 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) } else { - LOG_INFO("The password given by " << server->address << ':' << server->port << " was bad."); + LOG_INFO("The password given by " << server->address << ':' + << server->port << " was bad."); outMsg.writeInt16(PASSWORD_BAD); comp->disconnect(outMsg); break; } LOG_INFO("Game server " << server->address << ':' << server->port - << " wants to register " << (msg.getUnreadLength() / 2) - << " maps."); + << " asks for maps to activate."); - while (msg.getUnreadLength()) + const std::map<int, std::string> &maps = MapManager::getMaps(); + for (std::map<int, std::string>::const_iterator it = maps.begin(), + it_end = maps.end(); it != it_end; ++it) { - int id = msg.readInt16(); - LOG_INFO("Registering map " << id << '.'); - if (GameServer *s = getGameServerFromMap(id)) - { - LOG_ERROR("Server Handler: map is already registered by " - << s->address << ':' << s->port << '.'); - } - else + int id = it->first; + const std::string &reservedServer = it->second; + if (reservedServer == server->name) { MessageOut outMsg(AGMSG_ACTIVE_MAP); // Map variables outMsg.writeInt16(id); + LOG_DEBUG("Issued server '" << server->name << "' " + << "to enable map " << id); std::map<std::string, std::string> variables; variables = storage->getAllWorldStateVars(id); diff --git a/src/common/defines.h b/src/common/defines.h index d572df1f..4ba77a1c 100644 --- a/src/common/defines.h +++ b/src/common/defines.h @@ -29,6 +29,18 @@ // World tick time in miliseconds. #define WORLD_TICK_MS 100 +// Files +#define DEFAULT_MAPSDB_FILE "maps.xml" +#define DEFAULT_ITEMSDB_FILE "items.xml" +#define DEFAULT_EQUIPDB_FILE "equip.xml" +#define DEFAULT_SKILLSDB_FILE "skills.xml" +#define DEFAULT_ATTRIBUTEDB_FILE "attributes.xml" +#define DEFAULT_MONSTERSDB_FILE "monsters.xml" +#define DEFAULT_STATUSDB_FILE "status-effects.xml" +#define DEFAULT_PERMISSION_FILE "permissions.xml" +#define DEFAULT_SPECIALSDB_FILE "specials.xml" +#define DEFAULT_EMOTESDB_FILE "emotes.xml" + /** * Exit value codes are thrown back at servers exit to reflect their exit state. */ diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h index 1fc85ba6..835f2455 100644 --- a/src/common/manaserv_protocol.h +++ b/src/common/manaserv_protocol.h @@ -250,7 +250,7 @@ enum { PCMSG_KICK_USER = 0x0466, // W channel id, S name // Inter-server - GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }* + GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value } AGMSG_ACTIVE_MAP = 0x0502, // W map id, W Number of mapvar_key mapvar_value sent, { S mapvar_key, S mapvar_value }, W Number of map items, { D item Id, W amount, W posX, W posY } AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 3b58e347..0507eb09 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -77,6 +77,8 @@ bool AccountConnection::start(int gameServerPort) LOG_INFO("Connection established to the account server."); + const std::string gameServerName = + Configuration::getValue("net_gameServerName", "server1"); const std::string gameServerAddress = Configuration::getValue("net_publicGameHost", Configuration::getValue("net_gameHost", @@ -84,18 +86,13 @@ bool AccountConnection::start(int gameServerPort) const std::string password = Configuration::getValue("net_password", "changeMe"); - // Register with the account server and send the list of maps we handle + // Register with the account server MessageOut msg(GAMSG_REGISTER); + msg.writeString(gameServerName); msg.writeString(gameServerAddress); msg.writeInt16(gameServerPort); msg.writeString(password); msg.writeInt32(itemManager->getDatabaseVersion()); - const MapManager::Maps &m = MapManager::getMaps(); - for (MapManager::Maps::const_iterator i = m.begin(), i_end = m.end(); - i != i_end; ++i) - { - msg.writeInt16(i->first); - } send(msg); // initialize sync buffer diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index f76189f9..2533a16b 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -20,6 +20,7 @@ */ #include "common/configuration.h" +#include "common/defines.h" #include "common/permissionmanager.h" #include "common/resourcemanager.h" #include "game-server/accountconnection.h" @@ -64,19 +65,8 @@ using utils::Logger; -// Default options that automake should be able to override. #define DEFAULT_LOG_FILE "manaserv-game.log" -#define DEFAULT_ITEMSDB_FILE "items.xml" -#define DEFAULT_EQUIPDB_FILE "equip.xml" -#define DEFAULT_SKILLSDB_FILE "skills.xml" -#define DEFAULT_ATTRIBUTEDB_FILE "attributes.xml" -#define DEFAULT_MAPSDB_FILE "maps.xml" -#define DEFAULT_MONSTERSDB_FILE "monsters.xml" -#define DEFAULT_STATUSDB_FILE "status-effects.xml" -#define DEFAULT_PERMISSION_FILE "permissions.xml" #define DEFAULT_MAIN_SCRIPT_FILE "scripts/main.lua" -#define DEFAULT_SPECIALSDB_FILE "specials.xml" -#define DEFAULT_EMOTESDB_FILE "emotes.xml" static int const WORLD_TICK_SKIP = 2; /** tolerance for lagging behind in world calculation) **/ |