summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-01-02 22:41:02 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-01-02 22:41:02 +0000
commit6b7441516002d6e7cca424416bb67c6bc7d7c9d2 (patch)
tree6ce7822b0ca6e0abdfbbd938575a3c5bcf7b5614 /src
parent59df651232df73c56b5dae587fa68e1e9f824755 (diff)
downloadmanaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.gz
manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.bz2
manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.xz
manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.zip
Simplified MapReader interface and code. Fixed some memory leaks.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/game-server/mapmanager.cpp2
-rw-r--r--src/game-server/mapreader.cpp262
-rw-r--r--src/game-server/mapreader.hpp43
-rw-r--r--src/map.h5
-rw-r--r--src/mapreader.cpp380
-rw-r--r--src/mapreader.h109
-rw-r--r--src/properties.h77
-rw-r--r--src/utils/zlib.cpp114
-rw-r--r--src/utils/zlib.hpp35
10 files changed, 462 insertions, 577 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7b4e27ee..759927e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,6 @@ tmwserv_account_SOURCES = \
player.h \
player.cpp \
point.h \
- properties.h \
resourcemanager.h \
resourcemanager.cpp \
skill.h \
@@ -86,14 +85,11 @@ tmwserv_game_SOURCES = \
item.cpp \
map.h \
map.cpp \
- mapreader.h \
- mapreader.cpp \
object.h \
object.cpp \
player.h \
player.cpp \
point.h \
- properties.h \
resourcemanager.h \
resourcemanager.cpp \
skill.h \
@@ -108,6 +104,8 @@ tmwserv_game_SOURCES = \
game-server/mapcomposite.cpp \
game-server/mapmanager.hpp \
game-server/mapmanager.cpp \
+ game-server/mapreader.hpp \
+ game-server/mapreader.cpp \
game-server/state.hpp \
game-server/state.cpp \
game-server/testing.cpp \
@@ -134,8 +132,10 @@ tmwserv_game_SOURCES = \
utils/stringfilter.cpp \
utils/timer.h \
utils/timer.cpp \
- utils/xml.h \
- utils/xml.cpp
+ utils/xml.hpp \
+ utils/xml.cpp \
+ utils/zlib.hpp \
+ utils/zlib.cpp
if BUILD_MYSQL
tmwserv_account_SOURCES += \
diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp
index 1cef6281..d3f431b2 100644
--- a/src/game-server/mapmanager.cpp
+++ b/src/game-server/mapmanager.cpp
@@ -24,9 +24,9 @@
#include <cassert>
#include "map.h"
-#include "mapreader.h"
#include "resourcemanager.h"
#include "game-server/mapmanager.hpp"
+#include "game-server/mapreader.hpp"
#include "utils/logger.h"
#include "utils/xml.hpp"
diff --git a/src/game-server/mapreader.cpp b/src/game-server/mapreader.cpp
new file mode 100644
index 00000000..d3a49a3c
--- /dev/null
+++ b/src/game-server/mapreader.cpp
@@ -0,0 +1,262 @@
+/*
+ * The Mana World
+ * 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 "map.h"
+#include "resourcemanager.h"
+#include "game-server/mapreader.hpp"
+#include "utils/base64.h"
+#include "utils/logger.h"
+#include "utils/xml.hpp"
+#include "utils/zlib.hpp"
+
+static std::vector< int > tilesetFirstGids;
+
+static Map* readMap(xmlNodePtr node, std::string const &path);
+static void readLayer(xmlNodePtr node, Map *map);
+static void setTileWithGid(Map *map, int x, int y, int gid);
+
+Map *MapReader::readMap(const std::string &filename)
+{
+ // Load the file through resource manager.
+ ResourceManager *resman = ResourceManager::getInstance();
+ int fileSize;
+ char *buffer = (char *)resman->loadFile(filename, fileSize);
+
+ if (buffer == NULL)
+ {
+ LOG_ERROR("Error: Map file not found (" << filename.c_str() << ")", 0);
+ return NULL;
+ }
+
+ // Inflate the gzipped map data.
+ char *inflated;
+ unsigned inflatedSize = 0;
+ bool ret = inflateMemory(buffer, fileSize, inflated, inflatedSize);
+ free(buffer);
+
+ xmlDocPtr doc = NULL;
+
+ if (ret)
+ {
+ doc = xmlParseMemory(inflated, inflatedSize);
+ free(inflated);
+ }
+
+ if (!doc)
+ {
+ LOG_ERROR("Error while parsing map file (" << filename << ")!", 0);
+ return NULL;
+ }
+
+ Map *map = NULL;
+ xmlNodePtr node = xmlDocGetRootElement(doc);
+
+ // Parse the inflated map data.
+ if (node && xmlStrEqual(node->name, BAD_CAST "map"))
+ {
+ map = ::readMap(node, filename);
+ }
+ else
+ {
+ LOG_ERROR("Error: Not a map file (" << filename << ")!", 0);
+ }
+
+ xmlFreeDoc(doc);
+ return map;
+}
+
+static Map *readMap(xmlNodePtr node, std::string const &path)
+{
+ // Take the filename off the path
+ std::string pathDir = path.substr(0, path.rfind("/") + 1);
+
+ int w = XML::getProperty(node, "width", 0);
+ int h = XML::getProperty(node, "height", 0);
+ // We only support tile width of 32 at the moment
+ //int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
+ //int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
+ int layerNr = 0;
+ Map* map = new Map(w, h);
+
+ for (node = node->xmlChildrenNode; node != NULL; node = node->next)
+ {
+ /* // Properties are useless server-side.
+ if (xmlStrEqual(node->name, BAD_CAST "property"))
+ {
+ // Example: <property name="name" value="value"/>
+
+ xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+ xmlChar *value = xmlGetProp(node, BAD_CAST "value");
+
+ if (name && value)
+ {
+ map->setProperty((const char*)name, (const char*)value);
+ }
+
+ if (name) xmlFree(name);
+ if (value) xmlFree(value);
+ }
+ else
+ */
+ if (xmlStrEqual(node->name, BAD_CAST "tileset"))
+ {
+ if (xmlHasProp(node, BAD_CAST "source"))
+ {
+ LOG_WARN("Warning: External tilesets not supported yet.", 0);
+ }
+ else
+ {
+ tilesetFirstGids.push_back(XML::getProperty(node, "firstgid", 0));
+ }
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "layer"))
+ {
+ // Layer 3 is collision layer.
+ if (layerNr++ == 3)
+ {
+ readLayer(node, map);
+ }
+ }
+ }
+
+ // Clean up tilesets
+ tilesetFirstGids.clear();
+
+ return map;
+}
+
+static void readLayer(xmlNodePtr node, Map *map)
+{
+ node = node->xmlChildrenNode;
+ int h = map->getHeight();
+ int w = map->getWidth();
+ int x = 0;
+ int y = 0;
+
+ // Load the tile data. Layers are assumed to be map size, with (0,0) as
+ // origin.
+ while (node != NULL)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "data"))
+ {
+ if (XML::getProperty(node, "encoding", std::string()) == "base64")
+ {
+ if (xmlHasProp(node, BAD_CAST "compression"))
+ {
+ LOG_WARN("Warning: no layer compression supported!", 0);
+ return;
+ }
+
+ // Read base64 encoded map file
+ xmlNodePtr dataChild = node->xmlChildrenNode;
+ if (!dataChild) continue;
+
+ int len = strlen((char const *)dataChild->content) + 1;
+ char *charData = new char[len + 1];
+ char const *charStart = (char const *)dataChild->content;
+ char *charIndex = charData;
+
+ while (*charStart)
+ {
+ if (*charStart != ' ' && *charStart != '\t' && *charStart != '\n')
+ {
+ *charIndex = *charStart;
+ ++charIndex;
+ }
+ ++charStart;
+ }
+ *charIndex = '\0';
+
+ int binLen;
+ unsigned char *binData =
+ php_base64_decode((unsigned char *)charData, strlen(charData), &binLen);
+
+ delete[] charData;
+
+ if (binData)
+ {
+ for (int i = 0; i < binLen - 3; i += 4)
+ {
+ int gid = binData[i] |
+ (binData[i + 1] << 8) |
+ (binData[i + 2] << 16) |
+ (binData[i + 3] << 24);
+
+ setTileWithGid(map, x, y, gid);
+
+ if (++x == w)
+ {
+ x = 0;
+ ++y;
+ }
+ }
+ free(binData);
+ }
+ }
+ else
+ {
+ // Read plain XML map file
+ xmlNodePtr n2 = node->xmlChildrenNode;
+
+ while (n2 != NULL)
+ {
+ if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h)
+ {
+ int gid = XML::getProperty(n2, "gid", -1);
+ setTileWithGid(map, x, y, gid);
+
+ if (++x == w)
+ {
+ x = 0;
+ ++y;
+ }
+ }
+
+ n2 = n2->next;
+ }
+ }
+
+ // There can be only one data element
+ break;
+ }
+
+ node = node->next;
+ }
+}
+
+static void setTileWithGid(Map *map, int x, int y, int gid)
+{
+ // Find the tileset with the highest firstGid below/eq to gid
+ int set = gid;
+ for (std::vector< int >::const_iterator i = tilesetFirstGids.begin(),
+ i_end = tilesetFirstGids.end(); i != i_end; ++i)
+ {
+ if (gid < *i)
+ {
+ break;
+ }
+ set = *i;
+ }
+
+ map->setWalk(x, y, gid == set);
+}
diff --git a/src/game-server/mapreader.hpp b/src/game-server/mapreader.hpp
new file mode 100644
index 00000000..ed49b24d
--- /dev/null
+++ b/src/game-server/mapreader.hpp
@@ -0,0 +1,43 @@
+/*
+ * The Mana World
+ * 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$
+ */
+
+#ifndef _INCLUDED_MAPREADER_H
+#define _INCLUDED_MAPREADER_H
+
+#include <string>
+
+class Map;
+
+/**
+ * Reader for XML map files (*.tmx)
+ */
+class MapReader
+{
+ public:
+ /**
+ * Read an XML map from a file.
+ */
+ static Map *readMap(const std::string &filename);
+};
+
+#endif
diff --git a/src/map.h b/src/map.h
index 4998ce6f..a7c1fe2a 100644
--- a/src/map.h
+++ b/src/map.h
@@ -28,8 +28,6 @@
#include <map>
#include <string>
-#include "properties.h"
-
struct PATH_NODE {
PATH_NODE(unsigned short u, unsigned short v)
@@ -85,7 +83,7 @@ class Location
/**
* A tile map.
*/
-class Map : public Properties
+class Map
{
public:
/**
@@ -168,7 +166,6 @@ class Map : public Properties
int width, height;
int tileWidth, tileHeight;
MetaTile *metaTiles;
- std::map<std::string, std::string> properties;
// Pathfinding members
int onClosedList, onOpenList;
diff --git a/src/mapreader.cpp b/src/mapreader.cpp
deleted file mode 100644
index f16886c9..00000000
--- a/src/mapreader.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * The Mana World
- * 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 "mapreader.h"
-
-#include <cassert>
-#include <zlib.h>
-
-#include "map.h"
-#include "resourcemanager.h"
-
-#include "utils/base64.h"
-#include "utils/logger.h"
-
-const unsigned int DEFAULT_TILE_WIDTH = 32;
-const unsigned int DEFAULT_TILE_HEIGHT = 32;
-
-/**
- * Inflates either zlib or gzip deflated memory. The inflated memory is
- * expected to be freed by the caller.
- */
-int
-inflateMemory(
- unsigned char *in, unsigned int inLength,
- unsigned char *&out, unsigned int &outLength)
-{
- int bufferSize = 256 * 1024;
- int ret;
- z_stream strm;
-
- out = (unsigned char*)malloc(bufferSize);
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.next_in = in;
- strm.avail_in = inLength;
- strm.next_out = out;
- strm.avail_out = bufferSize;
-
- ret = inflateInit2(&strm, 15 + 32);
-
- if (ret != Z_OK)
- return ret;
-
- do
- {
- if (strm.next_out == NULL)
- {
- inflateEnd(&strm);
- return Z_MEM_ERROR;
- }
-
- ret = inflate(&strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR);
-
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR;
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void)inflateEnd(&strm);
- return ret;
- }
-
- if (ret != Z_STREAM_END)
- {
- out = (unsigned char*)realloc(out, bufferSize * 2);
-
- if (out == NULL)
- {
- inflateEnd(&strm);
- return Z_MEM_ERROR;
- }
-
- strm.next_out = out + bufferSize;
- strm.avail_out = bufferSize;
- bufferSize *= 2;
- }
- }
- while (ret != Z_STREAM_END);
- assert(strm.avail_in == 0);
-
- outLength = bufferSize - strm.avail_out;
- (void)inflateEnd(&strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-
-std::vector<Tileset*> MapReader::tilesets;
-
-Map *MapReader::readMap(const std::string &filename)
-{
- // Load the file through resource manager
- ResourceManager *resman = ResourceManager::getInstance();
- int fileSize;
- void *buffer = resman->loadFile(filename, fileSize);
-
- if (buffer == NULL)
- {
- LOG_ERROR("Error: Map file not found (" << filename.c_str() << ")", 0);
- return NULL;
- }
-
- // Inflate the gzipped map data
- unsigned char *inflated;
- unsigned int inflatedSize = 0;
- int ret = inflateMemory((unsigned char*)buffer, fileSize,
- inflated, inflatedSize);
- free(buffer);
-
- if (ret == Z_MEM_ERROR)
- {
- LOG_ERROR("Error: Out of memory while decompressing map data!", 0);
- return NULL;
- }
- else if (ret == Z_VERSION_ERROR)
- {
- LOG_ERROR("Error: Incompatible zlib version!", 0);
- return NULL;
- }
- else if (ret == Z_DATA_ERROR)
- {
- LOG_ERROR("Error: Incorrect zlib compressed data!", 0);
- return NULL;
- }
- else if (ret != Z_OK || inflated == NULL)
- {
- LOG_ERROR("Error: Unknown error while decompressing map data!", 0);
- return NULL;
- }
-
- xmlDocPtr doc = xmlParseMemory((char*)inflated, inflatedSize);
- free(inflated);
-
- // Parse the inflated map data
- if (doc) {
- xmlNodePtr node = xmlDocGetRootElement(doc);
-
- if (!node || !xmlStrEqual(node->name, BAD_CAST "map")) {
- LOG_ERROR("Error: Not a map file (" << filename << ")!", 0);
- return NULL;
- }
-
- return readMap(node, filename);
- xmlFreeDoc(doc);
- } else {
- LOG_ERROR("Error while parsing map file (" << filename << ")!", 0);
- }
-
- return NULL;
-}
-
-Map* MapReader::readMap(xmlNodePtr node, const std::string &path)
-{
- xmlChar *prop;
-
- // Take the filename off the path
- std::string pathDir = path.substr(0, path.rfind("/") + 1);
-
- prop = xmlGetProp(node, BAD_CAST "version");
- xmlFree(prop);
-
- int w = getProperty(node, "width", 0);
- int h = getProperty(node, "height", 0);
- // We only support tile width of 32 at the moment
- //int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
- //int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
- int layerNr = 0;
- Map* map = new Map(w, h);
-
- for (node = node->xmlChildrenNode; node != NULL; node = node->next)
- {
- if (xmlStrEqual(node->name, BAD_CAST "property"))
- {
- // Example: <property name="name" value="value"/>
-
- xmlChar *name = xmlGetProp(node, BAD_CAST "name");
- xmlChar *value = xmlGetProp(node, BAD_CAST "value");
-
- if (name && value)
- {
- map->setProperty((const char*)name, (const char*)value);
- }
-
- if (name) xmlFree(name);
- if (value) xmlFree(value);
- }
- else if (xmlStrEqual(node->name, BAD_CAST "tileset"))
- {
- Tileset *tileset = readTileset(node, pathDir, map);
- if (tileset) {
- tilesets.push_back(tileset);
- }
- }
- else if (xmlStrEqual(node->name, BAD_CAST "layer"))
- {
- readLayer(node, map, layerNr);
- layerNr++;
- }
- }
-
- // Clean up tilesets
- // TODO: Dereference them somewhere
- tilesets.clear();
-
- return map;
-}
-
-void MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
-{
- node = node->xmlChildrenNode;
- int h = map->getHeight();
- int w = map->getWidth();
- int x = 0;
- int y = 0;
-
- // Load the tile data. Layers are assumed to be map size, with (0,0) as
- // origin.
- while (node != NULL)
- {
- if (xmlStrEqual(node->name, BAD_CAST "data"))
- {
- xmlChar *encoding = xmlGetProp(node, BAD_CAST "encoding");
- xmlChar *compression = xmlGetProp(node, BAD_CAST "compression");
-
- if (encoding && xmlStrEqual(encoding, BAD_CAST "base64"))
- {
- xmlFree(encoding);
-
- if (compression) {
- LOG_WARN("Warning: no layer compression supported!", 0);
- xmlFree(compression);
- return;
- }
-
- // Read base64 encoded map file
- xmlNodePtr dataChild = node->xmlChildrenNode;
- if (!dataChild) continue;
-
- int len = strlen((const char*)dataChild->content) + 1;
- unsigned char *charData = new unsigned char[len + 1];
- const char *charStart = (const char*)dataChild->content;
- unsigned char *charIndex = charData;
-
- while (*charStart) {
- if (*charStart != ' ' && *charStart != '\t' &&
- *charStart != '\n')
- {
- *charIndex = *charStart;
- charIndex++;
- }
- charStart++;
- }
- *charIndex = '\0';
-
- int binLen;
- unsigned char *binData =
- php_base64_decode(charData, strlen((char*)charData),
- &binLen);
-
- delete[] charData;
-
- if (binData) {
- for (int i = 0; i < binLen - 3; i += 4) {
- int gid = binData[i] |
- binData[i + 1] << 8 |
- binData[i + 2] << 16 |
- binData[i + 3] << 24;
-
- setTileWithGid(map, x, y, layer, gid);
-
- x++;
- if (x == w) {x = 0; y++;}
- }
- free(binData);
- }
- }
- else {
- // Read plain XML map file
- xmlNodePtr n2 = node->xmlChildrenNode;
-
- while (n2 != NULL)
- {
- if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h)
- {
- int gid = getProperty(n2, "gid", -1);
- setTileWithGid(map, x, y, layer, gid);
-
- x++;
- if (x == w) {x = 0; y++;}
- }
-
- n2 = n2->next;
- }
- }
-
- // There can be only one data element
- break;
- }
-
- node = node->next;
- }
-}
-
-Tileset*
-MapReader::readTileset(xmlNodePtr node, const std::string &path, Map *map)
-{
- if (xmlHasProp(node, BAD_CAST "source")) {
- LOG_WARN("Warning: External tilesets not supported yet.", 0);
- return NULL;
- }
-
- int firstGid = getProperty(node, "firstgid", 0);
- int tw = getProperty(node, "tilewidth", map->getTileWidth());
- int th = getProperty(node, "tileheight", map->getTileHeight());
-
- return new Tileset(tw, th, firstGid);
-}
-
-int MapReader::getProperty(xmlNodePtr node, const char* name, int def)
-{
- xmlChar *prop = xmlGetProp(node, BAD_CAST name);
- if (prop) {
- int val = atoi((char*)prop);
- xmlFree(prop);
- return val;
- }
- else {
- return def;
- }
-}
-
-Tileset *MapReader::getTilesetWithGid(int gid)
-{
- std::vector<Tileset*>::iterator i;
- Tileset *set = NULL;
-
- // Find the tileset with the highest firstGid below/eq to gid
- for (i = tilesets.begin(); i != tilesets.end(); ++i)
- {
- if ((*i)->getFirstGid() <= gid) {
- set = (*i);
- }
- else {
- break;
- }
- }
-
- return set;
-}
-
-void MapReader::setTileWithGid(Map *map, int x, int y, int layer, int gid)
-{
- // Only load obstacle layer
- if (layer == 3)
- {
- Tileset *set = getTilesetWithGid(gid);
- map->setWalk(x, y, !set || (gid - set->getFirstGid() == 0));
- }
-}
diff --git a/src/mapreader.h b/src/mapreader.h
deleted file mode 100644
index fe395e35..00000000
--- a/src/mapreader.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * The Mana World
- * 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$
- */
-
-#ifndef _INCLUDED_MAPREADER_H
-#define _INCLUDED_MAPREADER_H
-
-#include <libxml/tree.h>
-#include <vector>
-
-class Map;
-
-
-/**
- * A tileset, which is on the server only used to store a firstgid.
- */
-class Tileset
-{
- public:
- /**
- * Constructor.
- */
- Tileset(int w, int h, int firstGid):
- mFirstGid(firstGid)
- {
- }
-
- /**
- * Returns the first gid.
- */
- int
- getFirstGid() { return mFirstGid; }
-
- private:
- int mFirstGid;
-};
-
-/**
- * Reader for XML map files (*.tmx)
- */
-class MapReader
-{
- public:
- /**
- * Read an XML map from a file.
- */
- static Map *readMap(const std::string &filename);
-
- /**
- * Read an XML map from a parsed XML tree. The path is used to find the
- * location of referenced tileset images.
- */
- static Map *readMap(xmlNodePtr node, const std::string &path);
-
- private:
- /**
- * Reads a map layer.
- */
- static void
- readLayer(xmlNodePtr node, Map *map, int layer);
-
- /**
- * Reads a tile set.
- */
- static Tileset*
- readTileset(xmlNodePtr node, const std::string &path, Map *map);
-
- /**
- * Gets an integer property from an xmlNodePtr.
- */
- static int
- getProperty(xmlNodePtr node, const char* name, int def);
-
- /**
- * Finds the tile set that a tile with the given global id is part of.
- */
- static Tileset*
- getTilesetWithGid(int gid);
-
- /**
- * Sets a tile using a global tile id. Used by the layer loading
- * routine.
- */
- static void
- setTileWithGid(Map *map, int x, int y, int layer, int gid);
-
- static std::vector<Tileset*> tilesets;
-};
-
-#endif
diff --git a/src/properties.h b/src/properties.h
deleted file mode 100644
index 5f8d751d..00000000
--- a/src/properties.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * The Mana World
- * 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$
- */
-
-#ifndef _TMW_PROPERTIES_H_
-#define _TMW_PROPERTIES_H_
-
-#include <map>
-#include <string>
-
-/**
- * A class holding a set of properties.
- */
-class Properties
-{
- public:
- virtual
- ~Properties() {}
-
- /**
- * Get a map property.
- *
- * @return the value of the given property or an empty string when it
- * doesn't exist.
- */
- const std::string&
- getProperty(const std::string &name)
- {
- const static std::string undefined = "";
- PropertyMap::const_iterator i = mProperties.find(name);
-
- return (i != mProperties.end()) ? i->second : undefined;
- }
-
- /**
- * Returns whether a certain property is available.
- */
- bool
- hasProperty(const std::string &name)
- {
- return mProperties.find(name) != mProperties.end();
- }
-
- /**
- * Set a map property.
- */
- void
- setProperty(const std::string &name, const std::string &value)
- {
- mProperties[name] = value;
- }
-
- private:
- typedef std::map<std::string, std::string> PropertyMap;
- PropertyMap mProperties;
-};
-
-#endif
diff --git a/src/utils/zlib.cpp b/src/utils/zlib.cpp
new file mode 100644
index 00000000..b72c70f5
--- /dev/null
+++ b/src/utils/zlib.cpp
@@ -0,0 +1,114 @@
+/*
+ * The Mana World
+ * Copyright 2006 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 <zlib.h>
+
+#include "utils/logger.h"
+#include "utils/zlib.hpp"
+
+static void logZlibError(int error)
+{
+ switch (error)
+ {
+ case Z_MEM_ERROR:
+ LOG_ERROR("Out of memory while decompressing data!", 0);
+ break;
+ case Z_VERSION_ERROR:
+ LOG_ERROR("Incompatible zlib version!", 0);
+ break;
+ case Z_DATA_ERROR:
+ LOG_ERROR("Incorrect zlib compressed data!", 0);
+ break;
+ default:
+ LOG_ERROR("Unknown error while decompressing data!", 0);
+ }
+}
+
+bool inflateMemory(char *in, unsigned inLength,
+ char *&out, unsigned &outLength)
+{
+ int bufferSize = 256 * 1024;
+ int ret;
+ z_stream strm;
+
+ out = (char *)malloc(bufferSize);
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.next_in = (Bytef *)in;
+ strm.avail_in = inLength;
+ strm.next_out = (Bytef *)out;
+ strm.avail_out = bufferSize;
+
+ ret = inflateInit2(&strm, 15 + 32);
+
+ if (ret != Z_OK)
+ {
+ logZlibError(ret);
+ return false;
+ }
+
+ do
+ {
+ ret = inflate(&strm, Z_SYNC_FLUSH);
+
+ switch (ret) {
+ case Z_NEED_DICT:
+ case Z_STREAM_ERROR:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&strm);
+ logZlibError(ret);
+ return false;
+ }
+
+ if (ret != Z_STREAM_END)
+ {
+ out = (char *)realloc(out, bufferSize * 2);
+
+ if (!out)
+ {
+ inflateEnd(&strm);
+ logZlibError(Z_MEM_ERROR);
+ return false;
+ }
+
+ strm.next_out = (Bytef *)(out + bufferSize);
+ strm.avail_out = bufferSize;
+ bufferSize *= 2;
+ }
+ }
+ while (ret != Z_STREAM_END);
+
+ if (strm.avail_in != 0)
+ {
+ logZlibError(Z_DATA_ERROR);
+ return false;
+ }
+
+ outLength = bufferSize - strm.avail_out;
+ inflateEnd(&strm);
+ return true;
+}
diff --git a/src/utils/zlib.hpp b/src/utils/zlib.hpp
new file mode 100644
index 00000000..330dd8ca
--- /dev/null
+++ b/src/utils/zlib.hpp
@@ -0,0 +1,35 @@
+/*
+ * The Mana World
+ * Copyright 2006 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$
+ */
+
+#ifndef _TMWSERV_ZLIB
+#define _TMWSERV_ZLIB
+
+/**
+ * Inflates either zlib or gzip deflated memory. The inflated memory is
+ * expected to be freed by the caller. Returns true if the inflation was
+ * sucessful.
+ */
+bool inflateMemory(char *in, unsigned inLength,
+ char *&out, unsigned &outLength);
+
+#endif