diff --git a/init.lua b/init.lua index 75515ad2..8b5f6e77 100644 --- a/init.lua +++ b/init.lua @@ -46,3 +46,5 @@ g_modules.autoLoadModules(9999) if g_resources.fileExists("/otclientrc.lua") then dofile("/otclientrc.lua") end + +g_things.loadOtb('/items.otb') \ No newline at end of file diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 35baa8df..6ad2271a 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -165,6 +165,8 @@ SET(framework_SOURCES ${framework_SOURCES} # core ${CMAKE_CURRENT_LIST_DIR}/core/adaptativeframecounter.cpp ${CMAKE_CURRENT_LIST_DIR}/core/adaptativeframecounter.h + ${CMAKE_CURRENT_LIST_DIR}/core/binarytree.cpp + ${CMAKE_CURRENT_LIST_DIR}/core/binarytree.h ${CMAKE_CURRENT_LIST_DIR}/core/clock.cpp ${CMAKE_CURRENT_LIST_DIR}/core/clock.h ${CMAKE_CURRENT_LIST_DIR}/core/configmanager.cpp diff --git a/src/framework/core/binarytree.cpp b/src/framework/core/binarytree.cpp new file mode 100644 index 00000000..e2c2eda4 --- /dev/null +++ b/src/framework/core/binarytree.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "binarytree.h" +#include "filestream.h" + +void BinaryTree::unserialize(const FileStreamPtr& fin) +{ + m_type = fin->getU32(); + + while(true) { + uint8 byte = fin->getU8(); + switch(byte) { + case BINARYTREE_NODE_START: { + BinaryTreePtr node(new BinaryTree(shared_from_this())); + m_children.push_back(node); + node->unserialize(fin); + break; + } + case BINARYTREE_NODE_END: + return; + case BINARYTREE_ESCAPE_CHAR: + m_buffer.add(fin->getU8()); + break; + default: + m_buffer.add(byte); + break; + } + } +} + +void BinaryTree::seek(uint pos) +{ + if(pos > m_buffer.size()) + stdext::throw_exception("BinaryTree: seek failed"); + m_pos = pos; +} + +uint8 BinaryTree::getU8() +{ + if(m_pos+1 > m_buffer.size()) + stdext::throw_exception("BinaryTree: getU8 failed"); + uint8 v = m_buffer[m_pos]; + m_pos += 1; + return v; +} + +uint16 BinaryTree::getU16() +{ + if(m_pos+2 > m_buffer.size()) + stdext::throw_exception("BinaryTree: getU16 failed"); + uint16 v = stdext::readLE16(&m_buffer[m_pos]); + m_pos += 2; + return v; +} + +uint32 BinaryTree::getU32() +{ + if(m_pos+4 > m_buffer.size()) + stdext::throw_exception("BinaryTree: getU32 failed"); + uint32 v = stdext::readLE32(&m_buffer[m_pos]); + m_pos += 4; + return v; +} + +uint64 BinaryTree::getU64() +{ + if(m_pos+8 > m_buffer.size()) + stdext::throw_exception("BinaryTree: getu64 failed"); + uint64 v = stdext::readLE64(&m_buffer[m_pos]); + m_pos += 8; + return v; +} diff --git a/src/framework/core/binarytree.h b/src/framework/core/binarytree.h new file mode 100644 index 00000000..a872d344 --- /dev/null +++ b/src/framework/core/binarytree.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef BINARYTREE_H +#define BINARYTREE_H + +#include "declarations.h" +#include + +enum { + BINARYTREE_ESCAPE_CHAR = 0xFD, + BINARYTREE_NODE_START = 0xFE, + BINARYTREE_NODE_END = 0xFF +}; + +class BinaryTree : public std::enable_shared_from_this +{ +public: + BinaryTree(const BinaryTreePtr& parent = nullptr) : m_type(0), m_pos(0), m_parent(parent) { } + + void unserialize(const FileStreamPtr& fin); + + void seek(uint pos); + void skip(uint len) { seek(tell() + len); } + uint tell() { return m_pos; } + uint size() { return m_buffer.size(); } + + uint8 getU8(); + uint16 getU16(); + uint32 getU32(); + uint64 getU64(); + std::string getString(); + + BinaryTreeVec getChildren() { return m_children; } + BinaryTreePtr getParent() { return m_parent.lock(); } + uint32 getType() { return m_type; } + bool canRead() { return m_pos < m_buffer.size(); } + +private: + void setParent(const BinaryTreePtr& parent) { m_parent = parent; } + uint m_type; + uint m_pos; + + BinaryTreeVec m_children; + BinaryTreeWeakPtr m_parent; + DataBuffer m_buffer; +}; + +#endif diff --git a/src/framework/core/declarations.h b/src/framework/core/declarations.h index 3ffe8a87..d13467c3 100644 --- a/src/framework/core/declarations.h +++ b/src/framework/core/declarations.h @@ -31,10 +31,16 @@ class Module; class Event; class ScheduledEvent; class FileStream; +class BinaryTree; typedef std::shared_ptr ModulePtr; typedef std::shared_ptr EventPtr; typedef std::shared_ptr ScheduledEventPtr; typedef std::shared_ptr FileStreamPtr; +typedef std::shared_ptr BinaryTreePtr; + +typedef std::weak_ptr BinaryTreeWeakPtr; + +typedef std::vector BinaryTreeVec; #endif diff --git a/src/framework/core/filestream.cpp b/src/framework/core/filestream.cpp index 18eec432..12216dde 100644 --- a/src/framework/core/filestream.cpp +++ b/src/framework/core/filestream.cpp @@ -21,6 +21,7 @@ */ #include "filestream.h" +#include "binarytree.h" #include #include @@ -246,6 +247,17 @@ std::string FileStream::getString() return str; } +BinaryTreePtr FileStream::getBinaryTree() +{ + BinaryTreePtr root = BinaryTreePtr(new BinaryTree); + uint8 byte = getU8(); + if(byte == BINARYTREE_NODE_START) + root->unserialize(asFileStream()); + else + stdext::throw_exception(stdext::format("failed to read node start (getFirstNode): %d", byte)); + return root; +} + void FileStream::addU8(uint8 v) { if(!m_caching) { diff --git a/src/framework/core/filestream.h b/src/framework/core/filestream.h index 3bab8d08..b55426f8 100644 --- a/src/framework/core/filestream.h +++ b/src/framework/core/filestream.h @@ -52,6 +52,7 @@ public: uint32 getU32(); uint64 getU64(); std::string getString(); + BinaryTreePtr getBinaryTree(); void addU8(uint8 v); void addU16(uint16 v); @@ -59,6 +60,8 @@ public: void addU64(uint64 v); void addString(const std::string& v); + FileStreamPtr asFileStream() { return std::static_pointer_cast(shared_from_this()); } + private: void checkWrite(); void throwError(const std::string& message, bool physfsError = false); diff --git a/src/otclient/core/thingtypemanager.cpp b/src/otclient/core/thingtypemanager.cpp index 6992384e..683d8580 100644 --- a/src/otclient/core/thingtypemanager.cpp +++ b/src/otclient/core/thingtypemanager.cpp @@ -28,6 +28,7 @@ #include #include +#include #define TIXML_USE_STL // use STL strings instead. #include @@ -94,29 +95,27 @@ bool ThingTypeManager::loadDat(const std::string& file) bool ThingTypeManager::loadOtb(const std::string& file) { - /* try { FileStreamPtr fin = g_resources.openFile(file); if (!fin) stdext::throw_exception("unable to open file"); m_otbVersion = fin->getU32(); + if (m_otbVersion != 0x00) + stdext::throw_exception("invalid file version"); - uint32 type = 0; - uint8 node = 0; - fin->readNode(node, type); + BinaryTreePtr root = fin->getBinaryTree(); - fin->getU32(); // flags + root->getU32(); // flags - m_otbMajorVersion = fin->getU32(); - m_otbMinorVersion = fin->getU32(); - fin->getU32(); // build number - fin->skip(128); + m_otbMajorVersion = root->getU32(); + m_otbMinorVersion = root->getU32(); + root->getU32(); // build number + root->skip(128); // description - while(fin->readNode(node, type)) { + for(const BinaryTreePtr& node : root->getChildren()) { ThingTypeOtbPtr otbType(new ThingTypeOtb); - otbType->unserialize(fin); - addOtbType(otbType); + otbType->unserialize(node); } m_otbLoaded = true; @@ -125,8 +124,6 @@ bool ThingTypeManager::loadOtb(const std::string& file) g_logger.error(stdext::format("failed to load otb '%s': %s", file, e.what())); return false; } - */ - return false; } bool ThingTypeManager::loadXml(const std::string& file) diff --git a/src/otclient/core/thingtypeotb.cpp b/src/otclient/core/thingtypeotb.cpp index 0edd4567..1227c2e3 100644 --- a/src/otclient/core/thingtypeotb.cpp +++ b/src/otclient/core/thingtypeotb.cpp @@ -24,6 +24,7 @@ #include "thingtypeotb.h" #include +#include ThingTypeOtb::ThingTypeOtb() { @@ -32,45 +33,34 @@ ThingTypeOtb::ThingTypeOtb() m_clientId = 0; } -void ThingTypeOtb::unserialize(const FileStreamPtr& fin) +void ThingTypeOtb::unserialize(const BinaryTreePtr& node) { m_null = false; - uint8 zero = fin->getU8(); + uint8 zero = node->getU8(); assert(zero == 0); - m_category = (OtbCategory)fin->getU8(); + m_category = (OtbCategory)node->getU8(); - fin->getU32(); // skip flags + node->getU32(); // skip flags - bool done = false; - for(int i=0;igetU8(); - if(attr == 0) { - done = true; + while(node->canRead()) { + uint8 attr = node->getU8(); + if(attr == 0 || attr == 0xFF) break; - } else if(attr == 0xFF) { - fin->seek(fin->tell() - 1); - done = true; - break; - } - - int len = fin->getU16(); + uint16 len = node->getU16(); switch(attr) { case OtbAttribServerId: - m_serverId = fin->getU16(); + m_serverId = node->getU16(); assert(len == 2); break; case OtbAttribClientId: - m_clientId = fin->getU16(); + m_clientId = node->getU16(); assert(len == 2); break; default: - fin->skip(len); // skip attribute + node->skip(len); // skip attribute break; } } - - if(!done) - stdext::throw_exception("failed to unserialize otb type, corrupt otb?"); } diff --git a/src/otclient/core/thingtypeotb.h b/src/otclient/core/thingtypeotb.h index 39e12d5b..20ad5bda 100644 --- a/src/otclient/core/thingtypeotb.h +++ b/src/otclient/core/thingtypeotb.h @@ -84,7 +84,7 @@ class ThingTypeOtb : public LuaObject public: ThingTypeOtb(); - void unserialize(const FileStreamPtr& fin); + void unserialize(const BinaryTreePtr& node); void unserializeXML(); uint16 getServerId() { return m_serverId; }