summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/game-server/mapreader.cpp185
2 files changed, 107 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index e69a02b5..36b3d658 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,8 @@
src/Makefile.am: Added support for remote commands.
* src/game-server/command.cpp: Implemented "warp", "item", "money",
"drop", and "spawn" remote commands.
+ * src/game-server/mapreader.cpp: Added support for uncompressed map
+ files and compressed layers.
2007-08-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
diff --git a/src/game-server/mapreader.cpp b/src/game-server/mapreader.cpp
index 5997ae4f..0033264c 100644
--- a/src/game-server/mapreader.cpp
+++ b/src/game-server/mapreader.cpp
@@ -54,23 +54,30 @@ void MapReader::readMap(const std::string &filename, MapComposite *composite)
return;
}
- // Inflate the gzipped map data.
- char *inflated;
- unsigned inflatedSize = 0;
- bool ret = inflateMemory(buffer, fileSize, inflated, inflatedSize);
- free(buffer);
-
xmlDocPtr doc = NULL;
- if (ret)
+ int l = filename.length();
+ if (l > 3 && filename.substr(l - 3) == ".gz")
+ {
+ // Inflate the gzipped map data.
+ char *inflated;
+ unsigned inflatedSize = 0;
+ bool ret = inflateMemory(buffer, fileSize, inflated, inflatedSize);
+ free(buffer);
+ buffer = ret ? inflated : NULL;
+ fileSize = inflatedSize;
+ }
+
+ if (buffer)
{
- doc = xmlParseMemory(inflated, inflatedSize);
- free(inflated);
+ // Parse the XML document.
+ doc = xmlParseMemory(buffer, fileSize);
+ free(buffer);
}
if (!doc)
{
- LOG_ERROR("Error while parsing map file (" << filename << ")!");
+ LOG_ERROR("Error while parsing map file '" << filename << "'!");
return;
}
@@ -311,7 +318,6 @@ static Map *readMap(xmlNodePtr node, std::string const &path, MapComposite *comp
}
else if (objType == "SCRIPT")
{
- printf("SCRIPT");
Script *s = composite->getScript();
if (!s)
{
@@ -378,91 +384,110 @@ static void readLayer(xmlNodePtr node, Map *map)
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)
+ // Layers are assumed to be map size, with (0,0) as origin.
+ // Find its single "data" element.
+ while (node)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "data")) break;
+ node = node->next;
+ }
+
+ if (!node)
{
- if (xmlStrEqual(node->name, BAD_CAST "data"))
+ LOG_WARN("Layer without any 'data' element.");
+ return;
+ }
+
+ if (XML::getProperty(node, "encoding", std::string()) == "base64")
+ {
+ // Read base64 encoded map file
+ xmlNodePtr dataChild = node->xmlChildrenNode;
+ if (!dataChild)
+ {
+ LOG_WARN("Corrupted layer.");
+ return;
+ }
+
+ 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 (XML::getProperty(node, "encoding", std::string()) == "base64")
+ if (*charStart != ' ' && *charStart != '\t' && *charStart != '\n')
{
- if (xmlHasProp(node, BAD_CAST "compression"))
- {
- LOG_WARN("Warning: no layer compression supported!");
- return;
- }
+ *charIndex = *charStart;
+ ++charIndex;
+ }
+ ++charStart;
+ }
+ *charIndex = '\0';
- // Read base64 encoded map file
- xmlNodePtr dataChild = node->xmlChildrenNode;
- if (!dataChild) continue;
+ int binLen;
+ unsigned char *binData =
+ php_base64_decode((unsigned char *)charData, strlen(charData), &binLen);
- int len = strlen((char const *)dataChild->content) + 1;
- char *charData = new char[len + 1];
- char const *charStart = (char const *)dataChild->content;
- char *charIndex = charData;
+ delete[] charData;
- while (*charStart)
- {
- if (*charStart != ' ' && *charStart != '\t' && *charStart != '\n')
- {
- *charIndex = *charStart;
- ++charIndex;
- }
- ++charStart;
- }
- *charIndex = '\0';
+ if (!binData)
+ {
+ LOG_WARN("Failed to decode base64-encoded layer.");
+ return;
+ }
+
+ if (XML::getProperty(node, "compression", std::string()) == "gzip")
+ {
+ // Inflate the gzipped layer data
+ char *inflated;
+ unsigned inflatedSize;
+ bool res = inflateMemory((char *)binData, binLen, inflated, inflatedSize);
+ free(binData);
- int binLen;
- unsigned char *binData =
- php_base64_decode((unsigned char *)charData, strlen(charData), &binLen);
+ if (!res)
+ {
+ LOG_WARN("Failed to decompress gzipped layer");
+ return;
+ }
- delete[] charData;
+ binData = (unsigned char *)inflated;
+ binLen = inflatedSize;
+ }
- 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);
+ 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);
+ setTileWithGid(map, x, y, gid);
- if (++x == w)
- {
- x = 0;
- ++y;
- }
- }
- free(binData);
- }
- }
- else
+ if (++x == w)
{
- // Read plain XML map file
- xmlNodePtr n2 = node->xmlChildrenNode;
+ x = 0;
+ ++y;
+ }
+ }
+ free(binData);
+ return;
+ }
- while (n2 != NULL)
- {
- if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h)
- {
- int gid = XML::getProperty(n2, "gid", -1);
- setTileWithGid(map, x, y, gid);
+ // Read plain XML map file
+ node = node->xmlChildrenNode;
- if (++x == w)
- {
- x = 0;
- ++y;
- }
- }
+ while (node)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "tile") && y < h)
+ {
+ int gid = XML::getProperty(node, "gid", -1);
+ setTileWithGid(map, x, y, gid);
- n2 = n2->next;
- }
+ if (++x == w)
+ {
+ x = 0;
+ ++y;
}
-
- // There can be only one data element
- break;
}
node = node->next;