summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accountserver.cbp2
-rw-r--r--docs/manaserv.xml.example9
-rw-r--r--example/maps.xml5
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/account-server/mapmanager.cpp61
-rw-r--r--src/account-server/mapmanager.h42
-rw-r--r--src/account-server/serverhandler.cpp28
-rw-r--r--src/common/defines.h12
-rw-r--r--src/common/manaserv_protocol.h2
-rw-r--r--src/game-server/accountconnection.cpp11
-rw-r--r--src/game-server/main-game.cpp12
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) **/