From c5674d10bae17533d2f0ba8e22d7179628a61c2d Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 21 Jun 2012 20:58:18 -0300 Subject: [PATCH] some refactoring --- modules/corelib/settings.lua | 2 +- src/framework/CMakeLists.txt | 4 + src/framework/core/configmanager.cpp | 6 +- src/framework/core/configmanager.h | 2 +- src/framework/core/eventdispatcher.cpp | 1 + src/framework/core/eventdispatcher.h | 86 +---------- src/framework/core/filestream.cpp | 199 +++++++++--------------- src/framework/core/filestream.h | 34 ++-- src/framework/luafunctions.cpp | 2 +- src/framework/sound/oggsoundfile.cpp | 15 +- src/framework/sound/soundbuffer.cpp | 2 +- src/otclient/core/animatedtext.h | 2 +- src/otclient/core/item.cpp | 18 ++- src/otclient/core/item.h | 4 + src/otclient/core/map.cpp | 22 +-- src/otclient/core/spritemanager.cpp | 1 + src/otclient/core/statictext.h | 4 +- src/otclient/core/thing.cpp | 1 - src/otclient/core/thing.h | 2 - src/otclient/core/thingtypemanager.cpp | 206 +++++++++++++------------ src/otclient/core/thingtypemanager.h | 1 + src/otclient/core/thingtypeotb.cpp | 24 ++- src/otclient/core/thingtypeotb.h | 3 +- 23 files changed, 276 insertions(+), 365 deletions(-) diff --git a/modules/corelib/settings.lua b/modules/corelib/settings.lua index b7a92aee..79e4f7f4 100644 --- a/modules/corelib/settings.lua +++ b/modules/corelib/settings.lua @@ -2,7 +2,7 @@ Settings = {} Settings.exists = g_configs.exists Settings.setNode = g_configs.setNode -Settings.addNode = g_configs.addNode +Settings.mergeNode = g_configs.mergeNode Settings.getNode = g_configs.getNode Settings.remove = g_configs.remove Settings.setList = g_configs.setList diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index bbc04fdb..d8bba581 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -173,6 +173,8 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/core/configmanager.cpp ${CMAKE_CURRENT_LIST_DIR}/core/configmanager.h ${CMAKE_CURRENT_LIST_DIR}/core/declarations.h + ${CMAKE_CURRENT_LIST_DIR}/core/event.h + ${CMAKE_CURRENT_LIST_DIR}/core/event.cpp ${CMAKE_CURRENT_LIST_DIR}/core/eventdispatcher.cpp ${CMAKE_CURRENT_LIST_DIR}/core/eventdispatcher.h ${CMAKE_CURRENT_LIST_DIR}/core/filestream.cpp @@ -186,6 +188,8 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/core/modulemanager.h ${CMAKE_CURRENT_LIST_DIR}/core/resourcemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/core/resourcemanager.h + ${CMAKE_CURRENT_LIST_DIR}/core/scheduledevent.h + ${CMAKE_CURRENT_LIST_DIR}/core/scheduledevent.cpp ${CMAKE_CURRENT_LIST_DIR}/core/timer.cpp ${CMAKE_CURRENT_LIST_DIR}/core/timer.h diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index 69de564d..f88be11d 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -45,7 +45,7 @@ bool ConfigManager::load(const std::string& file) m_confsDoc = confsDoc; return true; } catch(stdext::exception& e) { - g_logger.error(stdext::format("Unable to parse configuration file '%s'", e.what())); + g_logger.error(stdext::format("Unable to parse configuration file '%s': ", e.what())); return false; } } @@ -121,10 +121,10 @@ void ConfigManager::remove(const std::string& key) void ConfigManager::setNode(const std::string& key, const OTMLNodePtr& node) { remove(key); - addNode(key, node); + mergeNode(key, node); } -void ConfigManager::addNode(const std::string& key, const OTMLNodePtr& node) +void ConfigManager::mergeNode(const std::string& key, const OTMLNodePtr& node) { OTMLNodePtr clone = node->clone(); node->setTag(key); diff --git a/src/framework/core/configmanager.h b/src/framework/core/configmanager.h index 12667ce0..08104c76 100644 --- a/src/framework/core/configmanager.h +++ b/src/framework/core/configmanager.h @@ -40,7 +40,7 @@ public: std::vector getList(const std::string& key); void setNode(const std::string& key, const OTMLNodePtr& node); - void addNode(const std::string& key, const OTMLNodePtr& node); + void mergeNode(const std::string& key, const OTMLNodePtr& node); OTMLNodePtr getNode(const std::string& key); bool exists(const std::string& key); diff --git a/src/framework/core/eventdispatcher.cpp b/src/framework/core/eventdispatcher.cpp index 99c37616..f67f1ec1 100644 --- a/src/framework/core/eventdispatcher.cpp +++ b/src/framework/core/eventdispatcher.cpp @@ -27,6 +27,7 @@ EventDispatcher g_eventDispatcher; + void EventDispatcher::flush() { while(!m_eventList.empty()) diff --git a/src/framework/core/eventdispatcher.h b/src/framework/core/eventdispatcher.h index 937a9d37..1fb724bb 100644 --- a/src/framework/core/eventdispatcher.h +++ b/src/framework/core/eventdispatcher.h @@ -23,92 +23,8 @@ #ifndef EVENTDISPATCHER_H #define EVENTDISPATCHER_H -#include "declarations.h" #include "clock.h" -#include - -class Event : public LuaObject -{ -public: - Event(const std::function& callback) : m_callback(callback), m_canceled(false), m_executed(false) { } - virtual ~Event() { - // assure that we lost callback refs - //assert(m_callback == nullptr); - } - - virtual void execute() { - if(!m_canceled && !m_executed && m_callback) { - m_callback(); - m_executed = true; - } - - // reset callback to free object refs - m_callback = nullptr; - } - void cancel() { - m_canceled = true; - m_callback = nullptr; - } - - bool isCanceled() { return m_canceled; } - bool isExecuted() { return m_executed; } - -protected: - std::function m_callback; - bool m_canceled; - bool m_executed; -}; - -class ScheduledEvent : public Event -{ -public: - ScheduledEvent(const std::function& callback, int delay, int maxCycles) : Event(callback) { - m_ticks = g_clock.millis() + delay; - m_delay = delay; - m_maxCycles = maxCycles; - m_cyclesExecuted = 0; - } - - void execute() { - if(!m_canceled && m_callback && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) { - m_callback(); - m_executed = true; - // callback may be used in the next cycle - } else { - // reset callback to free object refs - m_callback = nullptr; - } - m_cyclesExecuted++; - } - - bool nextCycle() { - if(m_callback && !m_canceled && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) { - m_ticks += m_delay; - return true; - } - // reset callback to free object refs - m_callback = nullptr; - return false; - } - - int ticks() { return m_ticks; } - int reamaningTicks() { return m_ticks - g_clock.millis(); } - int delay() { return m_delay; } - int cyclesExecuted() { return m_cyclesExecuted; } - int maxCycles() { return m_maxCycles; } - -private: - ticks_t m_ticks; - int m_delay; - int m_maxCycles; - int m_cyclesExecuted; -}; - -struct lessScheduledEvent : std::binary_function { - bool operator()(const ScheduledEventPtr& a, const ScheduledEventPtr& b) { - return b->ticks() < a->ticks(); - } -}; +#include "scheduledevent.h" class EventDispatcher { diff --git a/src/framework/core/filestream.cpp b/src/framework/core/filestream.cpp index e7e06f5d..ff03657a 100644 --- a/src/framework/core/filestream.cpp +++ b/src/framework/core/filestream.cpp @@ -21,118 +21,101 @@ */ #include "filestream.h" +#include #include FileStream::FileStream(const std::string& name, PHYSFS_File *fileHandle) { m_name = name; + m_pos = 0; m_fileHandle = fileHandle; - m_cacheReadPos = 0; } FileStream::~FileStream() { + assert(!g_app.isTermianted()); close(); } void FileStream::cache() { if(!m_fileHandle) - g_logger.traceError("no file handle to cache"); + return; - // cache entire file into cache buffer - m_cacheReadPos = PHYSFS_tell(m_fileHandle); + // cache entire file into data buffer + m_pos = PHYSFS_tell(m_fileHandle); PHYSFS_seek(m_fileHandle, 0); int size = PHYSFS_fileLength(m_fileHandle); - m_cacheBuffer.resize(size); - int res = PHYSFS_read(m_fileHandle, &m_cacheBuffer[0], size, 1); + m_data.resize(size); + int res = PHYSFS_read(m_fileHandle, &m_data[0], size, 1); if(res == -1) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("unable to read file data"); - PHYSFS_close(m_fileHandle); - m_fileHandle = nullptr; + close(); } -bool FileStream::close() +void FileStream::close() { if(m_fileHandle) { - if(PHYSFS_isInit() && PHYSFS_close(m_fileHandle) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); - + if(!PHYSFS_close(m_fileHandle)) + throwError("close failed"); m_fileHandle = nullptr; - return true; } else { - m_cacheBuffer.clear(); - m_cacheReadPos = 0; - return true; + m_data.clear(); + m_pos = 0; } } -bool FileStream::flush() +void FileStream::flush() { - if(!m_fileHandle) - return false; - - if(PHYSFS_flush(m_fileHandle) == 0) { - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); - return false; - } - return true; + if(m_fileHandle && PHYSFS_flush(m_fileHandle) == 0) + throwError("flush failed"); } -int FileStream::read(void *buffer, int size, int nmemb) +int FileStream::read(void *buffer, uint32 size, uint32 nmemb) { if(m_fileHandle) { int res = PHYSFS_read(m_fileHandle, buffer, size, nmemb); - if(res == -1) { - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); - return 0; - } + if(res == -1) + throwError("read failed"); return res; } else { - uint maxReadPos = m_cacheBuffer.size()-1; + uint maxReadPos = m_data.size()-1; int writePos = 0; uint8 *outBuffer = (uint8*)buffer; - for(int i=0;i maxReadPos) + for(uint i=0;i maxReadPos) return i; - for(int j=0;j (int)m_cacheBuffer.size() || pos < 0) { - g_logger.traceError(stdext::format("operation failed on '%s': seek pos cannot be greater than file length", m_name)); - return false; - } - m_cacheReadPos = pos; + if(pos > m_data.size()) + throwError("seek failed"); + m_pos = pos; } - return true; +} + +void FileStream::skip(uint len) +{ + seek(tell() + len); } int FileStream::size() @@ -140,7 +123,7 @@ int FileStream::size() if(m_fileHandle) return PHYSFS_fileLength(m_fileHandle); else - return m_cacheBuffer.size(); + return m_data.size(); } int FileStream::tell() @@ -148,7 +131,7 @@ int FileStream::tell() if(m_fileHandle) return PHYSFS_tell(m_fileHandle); else - return m_cacheReadPos; + return m_pos; } uint8 FileStream::getU8() @@ -156,15 +139,13 @@ uint8 FileStream::getU8() uint8 v = 0; if(m_fileHandle) { if(PHYSFS_read(m_fileHandle, &v, 1, 1) != 1) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("read failed"); } else { - if(m_cacheReadPos+1 > m_cacheBuffer.size()) { - g_logger.traceError(stdext::format("operation failed on '%s': reached file eof", m_name)); - return 0; - } + if(m_pos+1 > m_data.size()) + throwError("read failed"); - v = m_cacheBuffer[m_cacheReadPos]; - m_cacheReadPos += 1; + v = m_data[m_pos]; + m_pos += 1; } return v; } @@ -174,15 +155,13 @@ uint16 FileStream::getU16() uint16 v = 0; if(m_fileHandle) { if(PHYSFS_readULE16(m_fileHandle, &v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("read failed"); } else { - if(m_cacheReadPos+2 > m_cacheBuffer.size()) { - g_logger.traceError(stdext::format("operation failed on '%s': reached file eof", m_name)); - return 0; - } + if(m_pos+2 > m_data.size()) + throwError("read failed"); - v = stdext::readLE16(&m_cacheBuffer[m_cacheReadPos]); - m_cacheReadPos += 2; + v = stdext::readLE16(&m_data[m_pos]); + m_pos += 2; } return v; } @@ -192,15 +171,13 @@ uint32 FileStream::getU32() uint32 v = 0; if(m_fileHandle) { if(PHYSFS_readULE32(m_fileHandle, &v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("read failed"); } else { - if(m_cacheReadPos+4 > m_cacheBuffer.size()) { - g_logger.traceError(stdext::format("operation failed on '%s': reached file eof", m_name)); - return 0; - } + if(m_pos+4 > m_data.size()) + throwError("read failed"); - v = stdext::readLE32(&m_cacheBuffer[m_cacheReadPos]); - m_cacheReadPos += 4; + v = stdext::readLE32(&m_data[m_pos]); + m_pos += 4; } return v; } @@ -210,15 +187,12 @@ uint64 FileStream::getU64() uint64 v = 0; if(m_fileHandle) { if(PHYSFS_readULE64(m_fileHandle, (PHYSFS_uint64*)&v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("read failed"); } else { - if(m_cacheReadPos+8 > m_cacheBuffer.size()) { - g_logger.traceError(stdext::format("operation failed on '%s': reached file eof", m_name)); - return 0; - } - - v = stdext::readLE64(&m_cacheBuffer[m_cacheReadPos]); - m_cacheReadPos += 8; + if(m_pos+8 > m_data.size()) + throwError("read failed"); + v = stdext::readLE64(&m_data[m_pos]); + m_pos += 8; } return v; } @@ -235,66 +209,47 @@ std::string FileStream::getString() else str = std::string(buffer, len); } else { - if(m_cacheReadPos+len > m_cacheBuffer.size()) { + if(m_pos+len > m_data.size()) { g_logger.traceError(stdext::format("operation failed on '%s': reached file eof", m_name)); return 0; } - str = std::string((char*)&m_cacheBuffer[m_cacheReadPos], len); - m_cacheReadPos += len; + str = std::string((char*)&m_data[m_pos], len); + m_pos += len; } } else { - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); } return str; } -uint8 FileStream::readFirstNode(uint32& type) -{ - dump << "first"; - uint8 node = getU8(); - if(node != NODE_START) - stdext::throw_exception("failed to read first node"); - type = getU32(); - return node; -} - -uint8 FileStream::readNextNode(uint8 oldNode, uint32& type) -{ - dump << "next"; - // end of old node - if(getU8() != NODE_END) - stdext::throw_exception("node not ended"); - - // next node - uint8 node = getU8(); - if(oldNode != NODE_START) - stdext::throw_exception("invalid node start"); - - type = getU32(); - return node; -} - void FileStream::addU8(uint8 v) { if(PHYSFS_write(m_fileHandle, &v, 1, 1) != 1) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("write failed"); } void FileStream::addU16(uint8 v) { if(PHYSFS_writeULE16(m_fileHandle, v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("write failed"); } void FileStream::addU32(uint8 v) { if(PHYSFS_writeULE32(m_fileHandle, v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("write failed"); } void FileStream::addU64(uint8 v) { if(PHYSFS_writeULE64(m_fileHandle, v) == 0) - g_logger.traceError(stdext::format("operation failed on '%s': %s", m_name, PHYSFS_getLastError())); + throwError("write failed"); +} + +void FileStream::throwError(const std::string& message) +{ + std::string completeMessage = stdext::format("in file '%s': %s", m_name, message); + if(m_fileHandle) + completeMessage += std::string(": ") + PHYSFS_getLastError(); + stdext::throw_exception(completeMessage); } diff --git a/src/framework/core/filestream.h b/src/framework/core/filestream.h index 523f7bc0..0af9c2f0 100644 --- a/src/framework/core/filestream.h +++ b/src/framework/core/filestream.h @@ -29,26 +29,17 @@ struct PHYSFS_File; class FileStream { - enum { - NODE_START = 0xFE, - NODE_END = 0xFF, - ESCAPE_CHAR = 0xFD, - }; - -protected: - FileStream(const std::string& name, PHYSFS_File *fileHandle); - - friend class ResourceManager; - public: + FileStream(const std::string& name, PHYSFS_File *fileHandle); ~FileStream(); void cache(); - bool close(); - bool flush(); - bool write(void *buffer, int count); - int read(void *buffer, int size, int nmemb = 1); - bool seek(int pos); + void close(); + void flush(); + void write(void *buffer, uint count); + int read(void *buffer, uint size, uint nmemb = 1); + void seek(uint pos); + void skip(uint len); int size(); int tell(); std::string name() { return m_name; } @@ -60,20 +51,21 @@ public: uint32 getU32(); uint64 getU64(); std::string getString(); + void addU8(uint8 v); void addU16(uint8 v); void addU32(uint8 v); void addU64(uint8 v); - uint8 readFirstNode(uint32& type); - uint8 readNextNode(uint8 oldNode, uint32& type); - private: + void checkWrite(); + void throwError(const std::string& message); + std::string m_name; PHYSFS_File *m_fileHandle; - std::vector m_cacheBuffer; - uint m_cacheReadPos; + std::vector m_data; + uint m_pos; }; #endif diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 9633d8c3..fa485cfe 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -521,7 +521,7 @@ void Application::registerLuaFunctions() g_lua.bindSingletonFunction("g_configs", "exists", &ConfigManager::exists, &g_configs); g_lua.bindSingletonFunction("g_configs", "remove", &ConfigManager::remove, &g_configs); g_lua.bindSingletonFunction("g_configs", "setNode", &ConfigManager::setNode, &g_configs); - g_lua.bindSingletonFunction("g_configs", "addNode", &ConfigManager::addNode, &g_configs); + g_lua.bindSingletonFunction("g_configs", "mergeNode", &ConfigManager::mergeNode, &g_configs); g_lua.bindSingletonFunction("g_configs", "getNode", &ConfigManager::getNode, &g_configs); // PlatformWindow diff --git a/src/framework/sound/oggsoundfile.cpp b/src/framework/sound/oggsoundfile.cpp index 30ef4978..a38fd41c 100644 --- a/src/framework/sound/oggsoundfile.cpp +++ b/src/framework/sound/oggsoundfile.cpp @@ -87,17 +87,14 @@ int OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence) FileStream *file = static_cast(source); switch(whence) { case SEEK_SET: - if(file->seek(offset)) - return 0; - break; + file->seek(offset); + return 0; case SEEK_CUR: - if(file->seek(file->tell() + offset)) - return 0; - break; + file->seek(file->tell() + offset); + return 0; case SEEK_END: - if(file->seek(file->size() + offset)) - return 0; - break; + file->seek(file->size() + offset); + return 0; } return -1; } diff --git a/src/framework/sound/soundbuffer.cpp b/src/framework/sound/soundbuffer.cpp index 249972d7..30a45e9f 100644 --- a/src/framework/sound/soundbuffer.cpp +++ b/src/framework/sound/soundbuffer.cpp @@ -46,7 +46,7 @@ bool SoundBuffer::fillBuffer(const SoundFilePtr& soundFile) DataBuffer samples(soundFile->getSize()); int read = soundFile->read(&samples[0], soundFile->getSize()); - if(read <= 0) { + if(read == 0) { g_logger.error(stdext::format("unable to fill audio buffer data for '%s'", soundFile->getName())); return false; } diff --git a/src/otclient/core/animatedtext.h b/src/otclient/core/animatedtext.h index 2a1cd1aa..4b373bad 100644 --- a/src/otclient/core/animatedtext.h +++ b/src/otclient/core/animatedtext.h @@ -28,7 +28,7 @@ #include #include -class AnimatedText : public Thing +class AnimatedText { public: AnimatedText(); diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index f932e882..27d2be7c 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -37,6 +37,7 @@ Item::Item() : Thing() m_id = 0; m_countOrSubType = 1; m_shaderProgram = g_shaders.getDefaultItemShader(); + m_otbType = g_things.getNullOtbType(); } ItemPtr Item::create(int id) @@ -46,6 +47,13 @@ ItemPtr Item::create(int id) return item; } +ItemPtr Item::createFromOtb(int id) +{ + ItemPtr item = ItemPtr(new Item); + item->setOtbId(id); + return item; +} + void Item::draw(const Point& dest, float scaleFactor, bool animate) { if(m_id == 0) @@ -177,7 +185,15 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) void Item::setId(uint32 id) { m_datType = g_things.getDatType(id, DatItemCategory); - m_id = id; + m_otbType = g_things.findOtbForClientId(id); + m_id = m_datType->getId(); +} + +void Item::setOtbId(uint16 id) +{ + m_otbType = g_things.getOtbType(id); + m_datType = g_things.getDatType(m_otbType->getClientId(), DatItemCategory); + m_id = m_datType->getId(); } bool Item::unserializeAttr(FileStreamPtr fin) diff --git a/src/otclient/core/item.h b/src/otclient/core/item.h index 103e0a87..c39a2531 100644 --- a/src/otclient/core/item.h +++ b/src/otclient/core/item.h @@ -25,6 +25,7 @@ #include #include "thing.h" +#include "thingtypeotb.h" enum AttrTypes_t { ATTR_END = 0, @@ -73,10 +74,12 @@ public: Item(); static ItemPtr create(int id); + static ItemPtr createFromOtb(int id); void draw(const Point& dest, float scaleFactor, bool animate); void setId(uint32 id); + void setOtbId(uint16 id); void setCountOrSubType(int value) { m_countOrSubType = value; } void setCount(int count) { m_countOrSubType = count; } void setSubType(int subType) { m_countOrSubType = subType; } @@ -108,6 +111,7 @@ private: uint32 m_actionId, m_uniqueId; std::string m_name, m_text, m_description; PainterShaderProgramPtr m_shaderProgram; + ThingTypeOtbPtr m_otbType; }; #endif diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index 26ad6c3d..6a93f00e 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -60,6 +60,7 @@ void Map::notificateTileUpdateToMapViews(const Position& pos) bool Map::loadOtbm(const std::string& fileName) { +#if 0 FileStreamPtr fin = g_resources.openFile(fileName); if (!fin) { g_logger.error(stdext::format("Unable to load map '%s'", fileName)); @@ -72,7 +73,8 @@ bool Map::loadOtbm(const std::string& fileName) } uint32 type = 0; - uint8 root = fin->readFirstNode(type); + uint8 root = 0; + root = fin->readNode(root, type); uint32 headerVersion = fin->getU32(); if (!headerVersion || headerVersion > 3) { @@ -95,7 +97,7 @@ bool Map::loadOtbm(const std::string& fileName) if (headerMinorItems > g_things.getOtbMinorVersion()) g_logger.warning("This map needs an updated OTB."); - uint8 node = fin->readNextNode(root, type); + uint8 node = fin->readNode(root, type); if (type != OTBM_MAP_DATA) { g_logger.error("Could not read data node."); return false; @@ -128,7 +130,7 @@ bool Map::loadOtbm(const std::string& fileName) uint8 nodeMapData; do { - nodeMapData = fin->readNextNode(node, type); + nodeMapData = fin->readNode(node, type); if (type == OTBM_TILE_AREA) { uint16 baseX = fin->getU16(), baseY = fin->getU16(); @@ -136,7 +138,7 @@ bool Map::loadOtbm(const std::string& fileName) uint8 nodeTile; do { - nodeTile = fin->readNextNode(nodeMapData, type); + nodeTile = fin->readNode(nodeMapData, type); if (type == OTBM_TILE || type == OTBM_HOUSETILE) { TilePtr tile = 0; @@ -174,7 +176,7 @@ bool Map::loadOtbm(const std::string& fileName) flags |= TILESTATE_REFRESH; break; } case OTBM_ATTR_ITEM: { - ItemPtr item = Item::create(fin->getU16()); + ItemPtr item = Item::createFromOtb(fin->getU16()); if (!item) { g_logger.error(stdext::format("failed to create new item at tile pos %d, %d, %d", px, py, pz)); return false; @@ -198,10 +200,10 @@ bool Map::loadOtbm(const std::string& fileName) uint8 nodeItem; do { - nodeItem = fin->readNextNode(nodeTile, type); + nodeItem = fin->readNode(nodeTile, type); if (type == OTBM_ITEM) { - ItemPtr item = Item::create(fin->getU16()); + ItemPtr item = Item::createFromOtb(fin->getU16()); if (!item) { g_logger.error(stdext::format("failed to create new item at pos %d, %d, %d", px, py, pz)); return false; @@ -246,7 +248,7 @@ bool Map::loadOtbm(const std::string& fileName) } else if (type == OTBM_TOWNS) { uint8 nodeTown; do { - nodeTown = fin->readNextNode(nodeMapData, type); + nodeTown = fin->readNode(nodeMapData, type); if (type == OTBM_TOWN) { uint32 townId = fin->getU32(); @@ -261,7 +263,7 @@ bool Map::loadOtbm(const std::string& fileName) } else if (type == OTBM_WAYPOINTS && headerVersion > 1) { uint8 nodeWaypoint; do { - nodeWaypoint = fin->readNextNode(nodeMapData, type); + nodeWaypoint = fin->readNode(nodeMapData, type); if (type == OTBM_WAYPOINT) { std::string name = fin->getString(); @@ -276,6 +278,8 @@ bool Map::loadOtbm(const std::string& fileName) // TODO: Load house & spawns. return true; +#endif + return false; } bool Map::loadOtcm(const std::string& fileName) diff --git a/src/otclient/core/spritemanager.cpp b/src/otclient/core/spritemanager.cpp index eb98d373..ad6474b6 100644 --- a/src/otclient/core/spritemanager.cpp +++ b/src/otclient/core/spritemanager.cpp @@ -62,6 +62,7 @@ void SpriteManager::unload() { m_spritesCount = 0; m_signature = 0; + m_spritesFile = nullptr; } ImagePtr SpriteManager::getSpriteImage(int id) diff --git a/src/otclient/core/statictext.h b/src/otclient/core/statictext.h index 0036dbcc..1950093c 100644 --- a/src/otclient/core/statictext.h +++ b/src/otclient/core/statictext.h @@ -23,12 +23,12 @@ #ifndef STATICTEXT_H #define STATICTEXT_H -#include "thing.h" #include #include #include +#include -class StaticText : public Thing +class StaticText : public LuaObject { public: StaticText(); diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index adb96778..d603a954 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -31,7 +31,6 @@ Thing::Thing() { m_datType = g_things.getNullDatType(); - m_otbType = g_things.getNullOtbType(); } int Thing::getStackPriority() diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index f2ab6aea..ad57cb8b 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -25,7 +25,6 @@ #include "declarations.h" #include "thingtypedat.h" -#include "thingtypeotb.h" #include struct Light @@ -135,7 +134,6 @@ public: protected: Position m_position; ThingTypeDatPtr m_datType; - ThingTypeOtbPtr m_otbType; }; #endif diff --git a/src/otclient/core/thingtypemanager.cpp b/src/otclient/core/thingtypemanager.cpp index 8246cf01..8082de41 100644 --- a/src/otclient/core/thingtypemanager.cpp +++ b/src/otclient/core/thingtypemanager.cpp @@ -94,6 +94,7 @@ bool ThingTypeManager::loadDat(const std::string& file) bool ThingTypeManager::loadOtb(const std::string& file) { + /* try { FileStreamPtr fin = g_resources.openFile(file); if (!fin) @@ -102,21 +103,19 @@ bool ThingTypeManager::loadOtb(const std::string& file) m_otbVersion = fin->getU32(); uint32 type = 0; - uint8 node = fin->readFirstNode(type); + uint8 node = 0; + fin->readNode(node, type); fin->getU32(); // flags - uint8 version = fin->getU8(); - if(fin->getU8() == 0x01) { // version - fin->getU8(); // length - m_otbMajorVersion = fin->getU32(); - m_otbMinorVersion = fin->getU32(); - fin->getU32(); // build number - } + m_otbMajorVersion = fin->getU32(); + m_otbMinorVersion = fin->getU32(); + fin->getU32(); // build number + fin->skip(128); - while((node = fin->readNextNode(node, type))) { + while(fin->readNode(node, type)) { ThingTypeOtbPtr otbType(new ThingTypeOtb); - otbType->unserialize((OtbCategory)type, fin); + otbType->unserialize(fin); addOtbType(otbType); } @@ -126,109 +125,115 @@ 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) { /* - TiXmlDocument doc(name.c_str()); - if (!doc.LoadFile()) { - g_logger.error(stdext::format("failed to load xml '%s'", name)); - return false; - } - - TiXmlElement* root = doc.FirstChildElement(); - if (!root) { - g_logger.error("invalid xml root"); - return false; - } + try { + TiXmlDocument doc(file.c_str()); + if (!doc.LoadFile()) { + g_logger.error(stdext::format("failed to load xml '%s'", file)); + return false; + } - if (root->ValueTStr() != "items") { - g_logger.error("invalid xml tag name, should be 'items'"); - return false; - } + TiXmlElement* root = doc.FirstChildElement(); + if (!root) { + g_logger.error("invalid xml root"); + return false; + } - for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { - if (element->ValueTStr() != "item") - continue; - - std::string name = element->Attribute("id"); - if (name.empty()) - continue; - - uint16 id = stdext::unsafe_cast(element->Attribute("id")); - uint16 idEx = 0; - if (!id) { - bool found = false; - // fallback into reading fromid and toid - uint16 fromid = stdext::unsafe_cast(element->Attribute("fromid")); - uint16 toid = stdext::unsafe_cast(element->Attribute("toid")); - ThingTypeOtbPtr iType; - for (int __id = fromid; __id < toid; ++__id) { - if (!(iType = getType(__id))) - continue; + if (root->ValueTStr() != "items") { + g_logger.error("invalid xml tag name, should be 'items'"); + return false; + } - iType->name = name; - idEx = iType->id == fromid ? fromid : toid; - found = true; - } + for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { + if (element->ValueTStr() != "item") + continue; - if (!found) + std::string name = element->Attribute("id"); + if (name.empty()) continue; - } - ThingTypeOtbPtr iType = getType(id); - if (!iType) { - iType = ThingTypeOtbPtr(new ItemData); - iType->id = idEx ? idEx : id; - iType->name = name; - addType(iType->id, iType); - } + uint16 id = stdext::unsafe_cast(element->Attribute("id")); + uint16 idEx = 0; + if (!id) { + bool found = false; + // fallback into reading fromid and toid + uint16 fromid = stdext::unsafe_cast(element->Attribute("fromid")); + uint16 toid = stdext::unsafe_cast(element->Attribute("toid")); + ThingTypeOtbPtr iType; + for (int __id = fromid; __id < toid; ++__id) { + if (!(iType = getType(__id))) + continue; + + iType->name = name; + idEx = iType->id == fromid ? fromid : toid; + found = true; + } + + if (!found) + continue; + } - iType->name = name; + ThingTypeOtbPtr otbType = getType(id); + if (!otbType) { + otbType = ThingTypeOtbPtr(new ItemData); + otbType->id = idEx ? idEx : id; + otbType->name = name; + addType(otbType->id, otbType); + } - for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) { - if (attr->ValueTStr() != "attribute") - continue; + otbType->name = name; + + for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) { + if (attr->ValueTStr() != "attribute") + continue; - std::string key = attr->Attribute("key"); - std::string value = attr->Attribute("value"); - if (key == "type") { - if (value == "magicfield") - iType->category = IsMagicField; - else if (value == "key") - iType->category = IsKey; - else if (value == "depot") - iType->isDepot = true; - else if (value == "teleport") - iType->category = IsTeleport; - else if (value == "bed") - iType->isBed = true; - else if (value == "door") - iType->category = IsDoor; - } else if (key == "name") { - iType->name = value; - } else if (key == "description") { - iType->description = value; - } else if (key == "weight") { - iType->weight = stdext::unsafe_cast(stdext::unsafe_cast(value) / 100.f); - } else if (key == "containerSize") { - int containerSize = stdext::unsafe_cast(value); - if (containerSize) - iType->containerSize = containerSize; - iType->category = IsContainer; - } else if (key == "writeable") { - if (!value.empty()) - iType->category = IsWritable; - } else if (key == "maxTextLen") { - iType->maxTextLength = stdext::unsafe_cast(value); - } else if (key == "charges") { - iType->charges = stdext::unsafe_cast(value); + std::string key = attr->Attribute("key"); + std::string value = attr->Attribute("value"); + if (key == "type") { + if (value == "magicfield") + otbType->category = IsMagicField; + else if (value == "key") + otbType->category = IsKey; + else if (value == "depot") + otbType->isDepot = true; + else if (value == "teleport") + otbType->category = IsTeleport; + else if (value == "bed") + otbType->isBed = true; + else if (value == "door") + otbType->category = IsDoor; + } else if (key == "name") { + otbType->name = value; + } else if (key == "description") { + otbType->description = value; + } else if (key == "weight") { + otbType->weight = stdext::unsafe_cast(stdext::unsafe_cast(value) / 100.f); + } else if (key == "containerSize") { + int containerSize = stdext::unsafe_cast(value); + if (containerSize) + otbType->containerSize = containerSize; + otbType->category = IsContainer; + } else if (key == "writeable") { + if (!value.empty()) + otbType->category = IsWritable; + } else if (key == "maxTextLen") { + otbType->maxTextLength = stdext::unsafe_cast(value); + } else if (key == "charges") { + otbType->charges = stdext::unsafe_cast(value); + } } } - } - doc.Clear(); + doc.Clear(); + } catch(stdext::exception& e) { + + } return true; */ return false; @@ -242,6 +247,15 @@ void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType) m_otbTypes[id] = otbType; } +ThingTypeOtbPtr ThingTypeManager::findOtbForClientId(uint16 id) +{ + for(const ThingTypeOtbPtr& otbType : m_otbTypes) { + if(otbType->getClientId() == id) + return otbType; + } + return m_nullOtbType; +} + ThingTypeDatPtr ThingTypeManager::getDatType(uint16 id, DatCategory category) { if(category >= DatLastCategory || id >= m_datTypes[category].size()) { diff --git a/src/otclient/core/thingtypemanager.h b/src/otclient/core/thingtypemanager.h index 177fff75..4556984b 100644 --- a/src/otclient/core/thingtypemanager.h +++ b/src/otclient/core/thingtypemanager.h @@ -40,6 +40,7 @@ public: bool loadXml(const std::string& file); void addOtbType(const ThingTypeOtbPtr& otbType); + ThingTypeOtbPtr findOtbForClientId(uint16 id); ThingTypeDatPtr& getNullDatType() { return m_nullDatType; } ThingTypeOtbPtr& getNullOtbType() { return m_nullOtbType; } diff --git a/src/otclient/core/thingtypeotb.cpp b/src/otclient/core/thingtypeotb.cpp index 116522aa..0edd4567 100644 --- a/src/otclient/core/thingtypeotb.cpp +++ b/src/otclient/core/thingtypeotb.cpp @@ -28,37 +28,45 @@ ThingTypeOtb::ThingTypeOtb() { m_category = OtbInvalidCateogry; + m_serverId = 0; + m_clientId = 0; } -void ThingTypeOtb::unserialize(OtbCategory category, const FileStreamPtr& fin) +void ThingTypeOtb::unserialize(const FileStreamPtr& fin) { m_null = false; - m_category = category; + + uint8 zero = fin->getU8(); + assert(zero == 0); + m_category = (OtbCategory)fin->getU8(); + fin->getU32(); // skip flags bool done = false; for(int i=0;igetU8(); - if(attr == 0) { done = true; break; + } else if(attr == 0xFF) { + fin->seek(fin->tell() - 1); + done = true; + break; } - uint16 len = fin->getU16(); + int len = fin->getU16(); switch(attr) { case OtbAttribServerId: m_serverId = fin->getU16(); + assert(len == 2); break; case OtbAttribClientId: m_clientId = fin->getU16(); - break; - case OtbAttribSpeed: - fin->getU16(); // skip speed + assert(len == 2); break; default: - fin->seek(len); // skip attribute + fin->skip(len); // skip attribute break; } } diff --git a/src/otclient/core/thingtypeotb.h b/src/otclient/core/thingtypeotb.h index 0407c6d2..39e12d5b 100644 --- a/src/otclient/core/thingtypeotb.h +++ b/src/otclient/core/thingtypeotb.h @@ -84,7 +84,8 @@ class ThingTypeOtb : public LuaObject public: ThingTypeOtb(); - void unserialize(OtbCategory category, const FileStreamPtr& fin); + void unserialize(const FileStreamPtr& fin); + void unserializeXML(); uint16 getServerId() { return m_serverId; } uint16 getClientId() { return m_clientId; }