diff --git a/CMakeLists.txt b/CMakeLists.txt index fc8abf20..d990ea49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ FIND_PACKAGE(PCHSupport REQUIRED) # choose a default build type if not specified IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE ReleaseWithDebInfo) + SET(CMAKE_BUILD_TYPE Debug) ENDIF(NOT CMAKE_BUILD_TYPE) MESSAGE(STATUS "BUILD TYPE: " ${CMAKE_BUILD_TYPE}) @@ -43,7 +43,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX) SET(CMAKE_CXX_FLAGS "-std=gnu++0x -pipe ${CXX_WARNS}") SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline") SET(CMAKE_CXX_FLAGS_RELEASE "-O2") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-inline") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -ggdb -fno-inline") SET(CMAKE_CXX_LINK_FLAGS "-static-libgcc -static-libstdc++ -Wl,--as-needed") ENDIF(CMAKE_COMPILER_IS_GNUCXX) @@ -112,12 +112,14 @@ SET(SOURCES # framework core src/framework/core/logger.cpp - src/framework/core/configs.cpp + src/framework/core/clock.cpp + src/framework/core/configmanager.cpp src/framework/core/resourcemanager.cpp src/framework/core/eventdispatcher.cpp src/framework/core/modulemanager.cpp src/framework/core/module.cpp src/framework/core/engine.cpp + src/framework/core/clock.cpp # framework graphics src/framework/graphics/font.cpp diff --git a/cmake/FindOpenGLES.cmake b/cmake/FindOpenGLES.cmake deleted file mode 100644 index 34afa737..00000000 --- a/cmake/FindOpenGLES.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# Try to find the OpenGLES librairy -# OPENGLES_FOUND - system has OpenGLES -# OPENGLES_INCLUDE_DIR - the OpenGLES include directory -# OPENGLES_LIBRARY - the OpenGLES library - -FIND_PATH(OPENGLES_INCLUDE_DIR gl2.h PATH_SUFFIXES GLES2) -FIND_LIBRARY(OPENGLES_LIBRARY NAMES GLESv2) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES DEFAULT_MSG OPENGLES_LIBRARY OPENGLES_INCLUDE_DIR) -MARK_AS_ADVANCED(OPENGLES_LIBRARY OPENGLES_INCLUDE_DIR) \ No newline at end of file diff --git a/modules/entergame/characterlist.lua b/modules/entergame/characterlist.lua index c9dc7388..17f00414 100644 --- a/modules/entergame/characterlist.lua +++ b/modules/entergame/characterlist.lua @@ -47,7 +47,7 @@ local function tryLogin(charInfo, tries) end -- save last used character - Configs.set('lastUsedCharacter', charInfo.characterName) + ConfigManager.set('lastUsedCharacter', charInfo.characterName) end -- public functions @@ -75,7 +75,7 @@ function CharacterList.create(characters, premDays) label.worldHost = worldHost label.worldPort = worldIp - if i == 1 or Configs.get('lastUsedCharacter') == characterName then + if i == 1 or ConfigManager.get('lastUsedCharacter') == characterName then characterList:focusChild(label, ActiveFocusReason) end end diff --git a/modules/entergame/entergame.lua b/modules/entergame/entergame.lua index 8336940b..3d0fcbad 100644 --- a/modules/entergame/entergame.lua +++ b/modules/entergame/entergame.lua @@ -11,8 +11,8 @@ local function clearAccountFields() enterGame:getChildById('accountNameLineEdit'):clearText() enterGame:getChildById('accountPasswordLineEdit'):clearText() enterGame:getChildById('accountNameLineEdit'):focus() - Configs.set('account', nil) - Configs.set('password', nil) + ConfigManager.set('account', nil) + ConfigManager.set('password', nil) end local function onError(protocol, error) @@ -30,9 +30,9 @@ end local function onCharacterList(protocol, characters, premDays) if enterGame:getChildById('rememberPasswordBox'):isChecked() then - Configs.set('account', EnterGame.account) - Configs.set('password', EnterGame.password) - Configs.set('autologin', tostring(enterGame:getChildById('autoLoginBox'):isChecked())) + ConfigManager.set('account', EnterGame.account) + ConfigManager.set('password', EnterGame.password) + ConfigManager.set('autologin', tostring(enterGame:getChildById('autoLoginBox'):isChecked())) else clearAccountFields() end @@ -40,9 +40,9 @@ local function onCharacterList(protocol, characters, premDays) loadBox:destroy() CharacterList.create(characters, premDays) - local lastMotdNumber = tonumber(Configs.get("motd")) + local lastMotdNumber = tonumber(ConfigManager.get("motd")) if motdNumber and motdNumber ~= lastMotdNumber then - Configs.set("motd", motdNumber) + ConfigManager.set("motd", motdNumber) local motdBox = displayInfoBox("Message of the day", motdMessage) motdBox.onOk = CharacterList.show CharacterList.hide() @@ -53,11 +53,11 @@ end function EnterGame.create() enterGame = UI.display('entergame.otui') - local account = Configs.get('account') - local password = Configs.get('password') - local host = Configs.get('host') - local port = tonumber(Configs.get('port')) - local autologin = toboolean(Configs.get('autologin')) + local account = ConfigManager.get('account') + local password = ConfigManager.get('password') + local host = ConfigManager.get('host') + local port = tonumber(ConfigManager.get('port')) + local autologin = toboolean(ConfigManager.get('autologin')) enterGame:getChildById('accountNameLineEdit'):setText(account) enterGame:getChildById('accountPasswordLineEdit'):setText(password) @@ -93,8 +93,8 @@ function EnterGame.doLogin() EnterGame.port = enterGame:getChildById('serverPortLineEdit'):getText() EnterGame.hide() - Configs.set('host', EnterGame.host) - Configs.set('port', EnterGame.port) + ConfigManager.set('host', EnterGame.host) + ConfigManager.set('port', EnterGame.port) local protocolLogin = ProtocolLogin.create() protocolLogin.onError = onError diff --git a/modules/options/options.lua b/modules/options/options.lua index b1517666..ec2d1b48 100644 --- a/modules/options/options.lua +++ b/modules/options/options.lua @@ -6,8 +6,8 @@ local fpsEnabled = false local vsyncEnabled = false function getConfig(name, default) - if Configs.exists(name) then - local val = string.trim(Configs.get(name)) + if ConfigManager.exists(name) then + local val = string.trim(ConfigManager.get(name)) if val == 'true' or val == 'false' then return toboolean(val) else @@ -15,7 +15,7 @@ function getConfig(name, default) end else if default ~= nil then - Configs.set(name, default) + ConfigManager.set(name, default) return default else return nil @@ -24,7 +24,7 @@ function getConfig(name, default) end function setConfig(name, value) - Configs.set(name, tostring(value)) + ConfigManager.set(name, tostring(value)) end -- private functions diff --git a/src/framework/core/clock.cpp b/src/framework/core/clock.cpp new file mode 100644 index 00000000..e8e93e0f --- /dev/null +++ b/src/framework/core/clock.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010-2011 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 "clock.h" + +Clock g_clock; + +Clock::Clock() +{ + m_startupTime = std::chrono::high_resolution_clock::now(); +} + +int Clock::updateTicks() +{ + auto timeNow = std::chrono::high_resolution_clock::now(); + m_currentTicks = std::chrono::duration_cast(timeNow - m_startupTime).count(); + return m_currentTicks; +} + +void Clock::sleep(int ms) +{ + usleep(ms * 1000); +} diff --git a/src/framework/core/clock.h b/src/framework/core/clock.h new file mode 100644 index 00000000..5926f5d2 --- /dev/null +++ b/src/framework/core/clock.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2011 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 CLOCK_H +#define CLOCK_H + +#include "declarations.h" + +class Clock +{ +public: + Clock(); + + int updateTicks(); + void sleep(int ms); + + int ticks() { return m_currentTicks; } + int ticksElapsed(int prevTicks) { return ticks() - prevTicks; } + int ticksFor(int delay) { return ticks() + delay; } + +private: + int m_currentTicks; + std::chrono::system_clock::time_point m_startupTime; +}; + +extern Clock g_clock; + +#endif + diff --git a/src/framework/core/configs.cpp b/src/framework/core/configmanager.cpp similarity index 92% rename from src/framework/core/configs.cpp rename to src/framework/core/configmanager.cpp index eba1e67b..83b3cbf8 100644 --- a/src/framework/core/configs.cpp +++ b/src/framework/core/configmanager.cpp @@ -20,14 +20,14 @@ * THE SOFTWARE. */ -#include "configs.h" +#include "configmanager.h" #include "resourcemanager.h" #include -Configs g_configs; +ConfigManager g_configs; -bool Configs::load(const std::string& file) +bool ConfigManager::load(const std::string& file) { m_fileName = file; @@ -39,13 +39,13 @@ bool Configs::load(const std::string& file) for(const OTMLNodePtr& child : doc->children()) m_confsMap[child->tag()] = child->value(); return true; - } catch(std::exception& e) { + } catch(Exception& e) { logError("could not load configurations: ", e.what()); return false; } } -bool Configs::save() +bool ConfigManager::save() { OTMLDocumentPtr doc = OTMLDocument::create(); for(auto it : m_confsMap) { diff --git a/src/framework/core/configs.h b/src/framework/core/configmanager.h similarity index 96% rename from src/framework/core/configs.h rename to src/framework/core/configmanager.h index 496b9ece..75635bf6 100644 --- a/src/framework/core/configs.h +++ b/src/framework/core/configmanager.h @@ -25,7 +25,7 @@ #include "declarations.h" -class Configs +class ConfigManager { public: bool load(const std::string& file); @@ -40,6 +40,6 @@ private: std::map m_confsMap; }; -extern Configs g_configs; +extern ConfigManager g_configs; #endif diff --git a/src/framework/core/engine.cpp b/src/framework/core/engine.cpp new file mode 100644 index 00000000..4023427f --- /dev/null +++ b/src/framework/core/engine.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 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 "engine.h" + diff --git a/src/framework/core/engine.h b/src/framework/core/engine.h new file mode 100644 index 00000000..64b28a72 --- /dev/null +++ b/src/framework/core/engine.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010-2011 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 ENGINE_H +#define ENGINE_H + +#include "declarations.h" + +class Engine +{ +}; + +#endif + diff --git a/src/framework/core/eventdispatcher.cpp b/src/framework/core/eventdispatcher.cpp index c88a2f33..a2692113 100644 --- a/src/framework/core/eventdispatcher.cpp +++ b/src/framework/core/eventdispatcher.cpp @@ -22,44 +22,42 @@ #include "eventdispatcher.h" -#include +#include EventDispatcher g_dispatcher; -void EventDispatcher::init() +void EventDispatcher::flush() { - // nothing to do -} + poll(); -void EventDispatcher::terminate() -{ - // clean scheduled events + m_eventList.clear(); while(!m_scheduledEventList.empty()) m_scheduledEventList.pop(); } void EventDispatcher::poll() { - while(!m_eventList.empty()) { - m_eventList.front()(); - m_eventList.pop_front(); - } - while(!m_scheduledEventList.empty()) { - if(g_platform.getTicks() < m_scheduledEventList.top().ticks) + if(g_clock.ticks() < m_scheduledEventList.top().ticks) break; SimpleCallback callback = std::move(m_scheduledEventList.top().callback); m_scheduledEventList.pop(); callback(); } + + while(!m_eventList.empty()) { + m_eventList.front()(); + m_eventList.pop_front(); + } } void EventDispatcher::scheduleEvent(const SimpleCallback& callback, int delay) { - m_scheduledEventList.push(ScheduledEvent(g_platform.getTicks() + delay, callback)); + assert(delay >= 0); + m_scheduledEventList.push(ScheduledEvent(g_clock.ticksFor(delay), callback)); } -void EventDispatcher::addEvent(const SimpleCallback& callback, bool pushFront /* = false */) +void EventDispatcher::addEvent(const SimpleCallback& callback, bool pushFront) { if(pushFront) m_eventList.push_front(callback); diff --git a/src/framework/core/eventdispatcher.h b/src/framework/core/eventdispatcher.h index 2cee89a7..03de23ad 100644 --- a/src/framework/core/eventdispatcher.h +++ b/src/framework/core/eventdispatcher.h @@ -35,19 +35,10 @@ struct ScheduledEvent { class EventDispatcher { public: - /// Initialize dispatcher - void init(); - - /// Cleanup scheduled events - void terminate(); - - /// Execute scheduled events + void flush(); void poll(); - /// Add an event void addEvent(const SimpleCallback& callback, bool pushFront = false); - - /// Schedule an event void scheduleEvent(const SimpleCallback& callback, int delay); private: diff --git a/src/framework/core/module.cpp b/src/framework/core/module.cpp index b6956116..3719891d 100644 --- a/src/framework/core/module.cpp +++ b/src/framework/core/module.cpp @@ -57,28 +57,29 @@ void Module::discover(const OTMLNodePtr& moduleNode) bool Module::load() { - try { - for(const std::string& depName : m_dependencies) { - ModulePtr dep = g_modules.getModule(depName); - if(!dep) - throw std::runtime_error(Fw::mkstr("could not find module dependency '", depName ,"'")); - - if(!dep->isLoaded() && !dep->load()) - throw std::runtime_error(Fw::mkstr("dependency '", depName, "' has failed to load")); + for(const std::string& depName : m_dependencies) { + ModulePtr dep = g_modules.getModule(depName); + if(!dep) { + logError("Unable to load module '", m_name, "' because dependency '", depName, "' was not found"); + return false; } - if(m_loadCallback) { - m_loaded = m_loadCallback(); - if(!m_loaded) - throw std::runtime_error("module onLoad event returned false"); + if(!dep->isLoaded() && !dep->load()) { + logError("Unable to load module '", m_name, "' because dependency '", depName, "' has failed to laod"); + return false; } - - logInfo("Loaded module '", m_name, "'"); - return true; - } catch(std::exception& e) { - logError("failed to load module '", m_name, "': ", e.what()); - return false; } + + if(m_loadCallback) { + m_loaded = m_loadCallback(); + if(!m_loaded) { + logError("Unable to load module '", m_name, "' because its onLoad event returned false"); + return false; + } + } + + logInfo("Loaded module '", m_name, "'"); + return true; } void Module::unload() diff --git a/src/framework/core/module.h b/src/framework/core/module.h index 2efb18cf..6d988ef9 100644 --- a/src/framework/core/module.h +++ b/src/framework/core/module.h @@ -36,14 +36,14 @@ public: bool load(); void unload(); - bool isLoaded() const { return m_loaded; } + bool isLoaded() { return m_loaded; } - std::string getDescription() const { return m_description; } - std::string getName() const { return m_name; } - std::string getAuthor() const { return m_author; } - std::string getWebsite() const { return m_website; } - std::string getVersion() const { return m_version; } - bool autoLoad() const { return m_autoLoad; } + std::string getDescription() { return m_description; } + std::string getName() { return m_name; } + std::string getAuthor() { return m_author; } + std::string getWebsite() { return m_website; } + std::string getVersion() { return m_version; } + bool autoLoad() { return m_autoLoad; } private: bool m_loaded; diff --git a/src/framework/core/modulemanager.cpp b/src/framework/core/modulemanager.cpp index cd09bedf..a9154347 100644 --- a/src/framework/core/modulemanager.cpp +++ b/src/framework/core/modulemanager.cpp @@ -56,13 +56,13 @@ bool ModuleManager::discoverModule(const std::string& file) std::string name = moduleNode->valueAt("name"); if(getModule(name)) - throw OTMLException(moduleNode, "a module with the same name is already discovered, did you duplicate module names?"); + Fw::throwException("module '", name, "' already exists, cannot have duplicate module names"); module = ModulePtr(new Module(name)); module->discover(moduleNode); m_modules.push_back(module); - } catch(std::exception& e) { - logError("failed to load module from '", file, "': ", e.what()); + } catch(Exception& e) { + logError("Unable to discover module from file '", file, "': ", e.what()); return false; } return true; diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp index 3dd2539e..148cfc23 100644 --- a/src/framework/core/resourcemanager.cpp +++ b/src/framework/core/resourcemanager.cpp @@ -107,7 +107,7 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out) PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str()); if(!file) { out.clear(std::ios::failbit); - throw std::runtime_error(Fw::mkstr("failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError())); + Fw::throwException("failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError()); } else { int fileSize = PHYSFS_fileLength(file); if(fileSize > 0) { diff --git a/src/framework/global.h b/src/framework/global.h index 2d8e874a..9821b6b1 100644 --- a/src/framework/global.h +++ b/src/framework/global.h @@ -30,6 +30,7 @@ #include #include #include +#include // common STL headers #include @@ -53,6 +54,7 @@ #include #include #include +#include // boost utilities #include diff --git a/src/framework/graphics/borderimage.cpp b/src/framework/graphics/borderimage.cpp index a27a2081..2fa82dca 100644 --- a/src/framework/graphics/borderimage.cpp +++ b/src/framework/graphics/borderimage.cpp @@ -79,8 +79,6 @@ BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode) // load texture std::string source = borderImageNode->at("source")->value(); TexturePtr texture = g_textures.getTexture(source); - if(!texture) - throw OTMLException(borderImageNode, "could not load border-image texture"); // load basic border confs size = texture->getSize(); diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index abe0d820..20d2fa20 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -37,8 +37,6 @@ void Font::load(const OTMLNodePtr& fontNode) // load font texture m_texture = g_textures.getTexture(textureName); - if(!m_texture) - throw std::runtime_error("failed to load texture for font"); if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) { for(int glyph = m_firstGlyph; glyph < 256; ++glyph) diff --git a/src/framework/graphics/fontmanager.cpp b/src/framework/graphics/fontmanager.cpp index b1cb04ce..9137b2c6 100644 --- a/src/framework/graphics/fontmanager.cpp +++ b/src/framework/graphics/fontmanager.cpp @@ -44,7 +44,7 @@ bool FontManager::importFont(std::string fontFile) std::string name = fontNode->valueAt("name"); if(fontExists(name)) - throw std::runtime_error("a font with the same name is already imported, did you duplicate font names?"); + Fw::throwException("font '", name, "' already exists, cannot have duplicate font names"); FontPtr font(new Font(name)); font->load(fontNode); @@ -55,8 +55,8 @@ bool FontManager::importFont(std::string fontFile) m_defaultFont = font; return true; - } catch(std::exception& e) { - logError("could not load font from '", fontFile, "': ", e.what()); + } catch(Exception& e) { + logError("Unable to load font from file '", fontFile, "': ", e.what()); return false; } } diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp index 0eb4a003..146f0016 100644 --- a/src/framework/graphics/image.cpp +++ b/src/framework/graphics/image.cpp @@ -43,8 +43,6 @@ void Image::loadFromOTML(const OTMLNodePtr& imageNode) // load texture m_texture = g_textures.getTexture(source); - if(!m_texture) - throw OTMLException(imageNode, "could not load image texture"); m_textureCoords = imageNode->valueAt("coords", Rect(Point(0,0),m_texture->getSize())); // enable texture bilinear filter diff --git a/src/framework/graphics/texturemanager.cpp b/src/framework/graphics/texturemanager.cpp index 2caa3b67..d78732ed 100644 --- a/src/framework/graphics/texturemanager.cpp +++ b/src/framework/graphics/texturemanager.cpp @@ -46,14 +46,14 @@ TexturePtr TextureManager::getTexture(const std::string& textureFile) try { // currently only png textures are supported if(!boost::ends_with(textureFile, ".png")) - throw std::runtime_error("texture file format no supported"); + Fw::throwException("texture file format no supported"); // load texture file data std::stringstream fin; g_resources.loadFile(textureFile, fin); texture = loadPNG(fin); - } catch(std::exception& e) { - logError("unable to load texture '",textureFile,"': ", e.what()); + } catch(Exception& e) { + Fw::throwException("unable to load texture '", textureFile, "': ", e.what()); } } diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index 6a7d321b..44822c7f 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -152,10 +152,10 @@ void LuaInterface::registerFunctions() g_lua.registerClass(); // ConfigManager - g_lua.registerClass(); - g_lua.bindClassStaticFunction("set", std::bind(&Configs::set, &g_configs, _1, _2)); - g_lua.bindClassStaticFunction("get", std::bind(&Configs::get, &g_configs, _1)); - g_lua.bindClassStaticFunction("exists", std::bind(&Configs::exists, &g_configs, _1)); + g_lua.registerClass(); + g_lua.bindClassStaticFunction("set", std::bind(&ConfigManager::set, &g_configs, _1, _2)); + g_lua.bindClassStaticFunction("get", std::bind(&ConfigManager::get, &g_configs, _1)); + g_lua.bindClassStaticFunction("exists", std::bind(&ConfigManager::exists, &g_configs, _1)); // Logger g_lua.registerClass(); diff --git a/src/framework/luascript/luainterface.cpp b/src/framework/luascript/luainterface.cpp index bf91a2e8..80f47135 100644 --- a/src/framework/luascript/luainterface.cpp +++ b/src/framework/luascript/luainterface.cpp @@ -545,7 +545,7 @@ void LuaInterface::createLuaState() // creates lua state L = luaL_newstate(); if(!L) - throw std::runtime_error("failed to create lua state"); + logFatal("Unable to create lua state"); // load lua standard libraries luaL_openlibs(L); diff --git a/src/framework/luascript/luavaluecasts.h b/src/framework/luascript/luavaluecasts.h index 124f6f40..99c97325 100644 --- a/src/framework/luascript/luavaluecasts.h +++ b/src/framework/luascript/luavaluecasts.h @@ -168,7 +168,7 @@ bool luavalue_cast(int index, std::function& func) { throw LuaException("attempt to call an expired lua function from C++," "did you forget to hold a reference for that function?", 0); } - } catch(std::exception& e) { + } catch(LuaException& e) { logError("lua function callback failed: ", e.what()); } }; @@ -202,7 +202,7 @@ luavalue_cast(int index, std::function& func) { throw LuaException("attempt to call an expired lua function from C++," "did you forget to hold a reference for that function?", 0); } - } catch(std::exception& e) { + } catch(LuaException& e) { logError("lua function callback failed: ", e.what()); } return Ret(); diff --git a/src/framework/net/inputmessage.cpp b/src/framework/net/inputmessage.cpp index 9b86218f..d0b37c90 100644 --- a/src/framework/net/inputmessage.cpp +++ b/src/framework/net/inputmessage.cpp @@ -35,7 +35,7 @@ void InputMessage::reset() uint8 InputMessage::getU8(bool peek) { - assert(canRead(1)); + checkRead(1); uint8 v = m_buffer[m_readPos]; if(!peek) @@ -46,7 +46,7 @@ uint8 InputMessage::getU8(bool peek) uint16 InputMessage::getU16(bool peek) { - assert(canRead(2)); + checkRead(2); uint16 v = *(uint16_t*)(m_buffer + m_readPos); if(!peek) @@ -57,7 +57,7 @@ uint16 InputMessage::getU16(bool peek) uint32 InputMessage::getU32(bool peek) { - assert(canRead(4)); + checkRead(4); uint32 v = *(uint32*)(m_buffer + m_readPos); if(!peek) @@ -68,7 +68,7 @@ uint32 InputMessage::getU32(bool peek) uint64 InputMessage::getU64(bool peek) { - assert(canRead(8)); + checkRead(8); uint64 v = *(uint64*)(m_buffer + m_readPos); if(!peek) @@ -80,7 +80,7 @@ uint64 InputMessage::getU64(bool peek) std::string InputMessage::getString() { uint16 stringLength = getU16(); - assert(canRead(stringLength)); + checkRead(stringLength); char* v = (char*)(m_buffer + m_readPos); m_readPos += stringLength; return std::string(v, stringLength); @@ -92,3 +92,10 @@ bool InputMessage::canRead(int bytes) return false; return true; } + +void InputMessage::checkRead(int bytes) +{ + if(!canRead(bytes)) + throw NetworkException("InputMessage eof reached"); +} + diff --git a/src/framework/net/inputmessage.h b/src/framework/net/inputmessage.h index f8f02148..8746cbf1 100644 --- a/src/framework/net/inputmessage.h +++ b/src/framework/net/inputmessage.h @@ -24,6 +24,7 @@ #define INPUTMESSAGE_H #include "declarations.h" +#include "networkexception.h" class InputMessage { @@ -56,6 +57,7 @@ public: private: bool canRead(int bytes); + void checkRead(int bytes); uint16 m_readPos; uint16 m_messageSize; diff --git a/src/framework/net/networkexception.h b/src/framework/net/networkexception.h new file mode 100644 index 00000000..c96a20da --- /dev/null +++ b/src/framework/net/networkexception.h @@ -0,0 +1,12 @@ +#ifndef NETWORKEXCEPTION_H +#define NETWORKEXCEPTION_H + +#include "declarations.h" + +class NetworkException : public Exception +{ +public: + NetworkException(const std::string& what) : Exception(what) { } +}; + +#endif diff --git a/src/framework/net/outputmessage.cpp b/src/framework/net/outputmessage.cpp index 95a6b1fa..c1164ccc 100644 --- a/src/framework/net/outputmessage.cpp +++ b/src/framework/net/outputmessage.cpp @@ -35,7 +35,7 @@ void OutputMessage::reset() void OutputMessage::addU8(uint8 value) { - assert(canWrite(1)); + checkWrite(1); m_buffer[m_writePos] = value; m_writePos += 1; m_messageSize += 1; @@ -43,7 +43,7 @@ void OutputMessage::addU8(uint8 value) void OutputMessage::addU16(uint16 value) { - assert(canWrite(2)); + checkWrite(2); *(uint16_t*)(m_buffer + m_writePos) = value; m_writePos += 2; m_messageSize += 2; @@ -51,7 +51,7 @@ void OutputMessage::addU16(uint16 value) void OutputMessage::addU32(uint32 value) { - assert(canWrite(4)); + checkWrite(4); *(uint32*)(m_buffer + m_writePos) = value; m_writePos += 4; m_messageSize += 4; @@ -59,7 +59,7 @@ void OutputMessage::addU32(uint32 value) void OutputMessage::addU64(uint64 value) { - assert(canWrite(8)); + checkWrite(8); *(uint64*)(m_buffer + m_writePos) = value; m_writePos += 8; m_messageSize += 8; @@ -68,7 +68,9 @@ void OutputMessage::addU64(uint64 value) void OutputMessage::addString(const char* value) { size_t stringLength = strlen(value); - assert(stringLength < 0xFFFF && canWrite(stringLength + 2)); + if(stringLength > 65535) + throw NetworkException("[OutputMessage::addString] string length > 65535"); + checkWrite(stringLength + 2); addU16(stringLength); strcpy((char*)(m_buffer + m_writePos), value); m_writePos += stringLength; @@ -82,7 +84,9 @@ void OutputMessage::addString(const std::string &value) void OutputMessage::addPaddingBytes(int bytes, uint8 byte) { - assert(canWrite(bytes) && bytes >= 0); + if(bytes <= 0) + return; + checkWrite(bytes); memset((void*)&m_buffer[m_writePos], byte, bytes); m_writePos += bytes; m_messageSize += bytes; @@ -94,3 +98,9 @@ bool OutputMessage::canWrite(int bytes) return false; return true; } + +void OutputMessage::checkWrite(int bytes) +{ + if(!canWrite(bytes)) + throw NetworkException("OutputMessage max buffer size reached"); +} diff --git a/src/framework/net/outputmessage.h b/src/framework/net/outputmessage.h index 0b5e7b53..bfcb8b93 100644 --- a/src/framework/net/outputmessage.h +++ b/src/framework/net/outputmessage.h @@ -24,6 +24,7 @@ #define OUTPUTMESSAGE_H #include "declarations.h" +#include "networkexception.h" class OutputMessage { @@ -56,6 +57,7 @@ public: private: bool canWrite(int bytes); + void checkWrite(int bytes); uint16 m_writePos; uint16 m_messageSize; diff --git a/src/framework/net/protocol.cpp b/src/framework/net/protocol.cpp index 014b6b20..afa904df 100644 --- a/src/framework/net/protocol.cpp +++ b/src/framework/net/protocol.cpp @@ -107,14 +107,15 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size) if(m_checksumEnabled) { uint32 checksum = getAdlerChecksum(m_inputMessage.getBuffer() + InputMessage::DATA_POS, m_inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH); if(m_inputMessage.getU32() != checksum) { - // error - logError("got a network message with invalid checksum"); + logTraceError("got a network message with invalid checksum"); return; } } - if(m_xteaEncryptionEnabled) - xteaDecrypt(m_inputMessage); + if(m_xteaEncryptionEnabled) { + if(!xteaDecrypt(m_inputMessage)) + return; + } onRecv(m_inputMessage); } @@ -133,7 +134,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage) { uint16 messageSize = inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH; if(messageSize % 8 != 0) { - logError("invalid encrypted network message"); + logTraceError("invalid encrypted network message"); return false; } @@ -156,7 +157,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage) int tmp = inputMessage.getU16(); if(tmp > inputMessage.getMessageSize() - 4) { - logError("invalid decrypted a network message"); + logTraceError("invalid decrypted a network message"); return false; } diff --git a/src/framework/net/rsa.cpp b/src/framework/net/rsa.cpp index 910f0661..a69c297b 100644 --- a/src/framework/net/rsa.cpp +++ b/src/framework/net/rsa.cpp @@ -65,9 +65,11 @@ void Rsa::setKey(const char* p, const char* q, const char* d) mpz_clear(pm1); mpz_clear(qm1); + + m_keySet = true; } -bool Rsa::encrypt(char* msg, int32_t size, const char* key) +void Rsa::encrypt(char* msg, int32_t size, const char* key) { mpz_t plain, c; mpz_init2(plain, 1024); @@ -92,11 +94,13 @@ bool Rsa::encrypt(char* msg, int32_t size, const char* key) mpz_clear(plain); mpz_clear(e); mpz_clear(mod); - return true; } bool Rsa::decrypt(char* msg, int32_t size) { + if(!m_keySet) + return false; + mpz_t c,v1,v2,u2,tmp; mpz_init2(c, 1024); mpz_init2(v1, 1024); @@ -130,6 +134,5 @@ bool Rsa::decrypt(char* msg, int32_t size) mpz_clear(v2); mpz_clear(u2); mpz_clear(tmp); - return true; } diff --git a/src/framework/net/rsa.h b/src/framework/net/rsa.h index 7029e1a6..b7a97a6f 100644 --- a/src/framework/net/rsa.h +++ b/src/framework/net/rsa.h @@ -34,7 +34,7 @@ public: void setKey(const char* p, const char* q, const char* d); bool decrypt(char* msg, int32_t size); - static bool encrypt(char* msg, int32_t size, const char* key); + static void encrypt(char* msg, int32_t size, const char* key); protected: bool m_keySet; diff --git a/src/framework/platform/platform.h b/src/framework/platform/platform.h index 1ac0020f..c6e892b0 100644 --- a/src/framework/platform/platform.h +++ b/src/framework/platform/platform.h @@ -36,11 +36,6 @@ public: /// Poll platform input/window events void poll(); - void updateTicks(); - - /// Get current time in milliseconds since last application init - int getTicks() { return m_lastTicks; } - /// Sleep in current thread void sleep(ulong ms); @@ -84,9 +79,6 @@ public: std::string getAppUserDir(); void displayFatalError(const std::string& message); - -private: - int m_lastTicks; }; extern Platform g_platform; diff --git a/src/framework/platform/x11platform.cpp b/src/framework/platform/x11platform.cpp index b375587b..7e0180cb 100644 --- a/src/framework/platform/x11platform.cpp +++ b/src/framework/platform/x11platform.cpp @@ -370,9 +370,6 @@ void Platform::init(PlatformListener* platformListener, const char *appName) x11.atomWindowState = XInternAtom(x11.display, "_NET_WM_STATE", False); x11.atomWindowMaximizedVert = XInternAtom(x11.display, "_NET_WM_STATE_MAXIMIZED_VERT", False); x11.atomWindowMaximizedHorz = XInternAtom(x11.display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); - - // force first tick - updateTicks(); } void Platform::terminate() @@ -585,26 +582,6 @@ void Platform::poll() } } -void Platform::updateTicks() -{ - static timeval tv; - static ulong firstTick = 0; - - gettimeofday(&tv, 0); - if(!firstTick) - firstTick = tv.tv_sec; - - m_lastTicks = ((tv.tv_sec - firstTick) * 1000) + (tv.tv_usec / 1000); -} - -void Platform::sleep(ulong miliseconds) -{ - timespec tv; - tv.tv_sec = miliseconds / 1000; - tv.tv_nsec = (miliseconds % 1000) * 1000000; - nanosleep(&tv, NULL); -} - bool Platform::createWindow(int x, int y, int width, int height, int minWidth, int minHeight, bool maximized) { static int attrList[] = { @@ -729,11 +706,11 @@ void Platform::setWindowIcon(const std::string& pngIcon) Atom property = XInternAtom(x11.display, "_NET_WM_ICON", 0); if(!XChangeProperty(x11.display, x11.window, property, XA_CARDINAL, 32, PropModeReplace, (const unsigned char*)&iconData[0], iconData.size())) - logError("could not set app icon"); + logError("Couldn't set app icon"); free_apng(&apng); } else - logError("could not load app icon"); + logError("Couldn't load app icon"); } void Platform::destroyWindow() @@ -835,7 +812,7 @@ const char *Platform::getClipboardText() XFlush(x11.display); // hack to wait SelectioNotify event, otherwise we will get wrong clipboard pastes - sleep(100); + usleep(100 * 1000); // check for data Atom type; diff --git a/src/framework/ui/uiframecounter.cpp b/src/framework/ui/uiframecounter.cpp index 0df02ab8..33bc404c 100644 --- a/src/framework/ui/uiframecounter.cpp +++ b/src/framework/ui/uiframecounter.cpp @@ -24,7 +24,7 @@ #include "uitranslator.h" #include #include -#include +#include #include UIFrameCounter::UIFrameCounter() @@ -32,7 +32,7 @@ UIFrameCounter::UIFrameCounter() m_focusable = false; m_phantom = true; m_align = Fw::AlignLeft; - m_lastFrameTicks = g_platform.getTicks(); + m_lastFrameTicks = g_clock.ticks(); m_frameCount = 0; } @@ -40,7 +40,7 @@ void UIFrameCounter::render() { UIWidget::render(); - int now = g_platform.getTicks(); + int now = g_clock.ticks(); if(now - m_lastFrameTicks >= 1000) { m_fpsText = Fw::mkstr("FPS: ", m_frameCount); m_lastFrameTicks = now; diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index 62b71372..7e8cf097 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include UILineEdit::UILineEdit() @@ -55,7 +56,7 @@ void UILineEdit::render() assert(m_cursorPos <= textLength); // draw every 333ms const int delay = 333; - int ticks = g_platform.getTicks(); + int ticks = g_clock.ticks(); if(ticks - m_cursorTicks <= delay) { Rect cursorRect; // when cursor is at 0 or is the first visible element @@ -447,5 +448,5 @@ bool UILineEdit::onMousePress(const Point& mousePos, Fw::MouseButton button) void UILineEdit::blinkCursor() { - m_cursorTicks = g_platform.getTicks(); + m_cursorTicks = g_clock.ticks(); } diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index 492bd980..2725a8fa 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -110,8 +110,8 @@ bool UIManager::importStyles(const std::string& file) for(const OTMLNodePtr& styleNode : doc->children()) importStyleFromOTML(styleNode); return true; - } catch(std::exception& e) { - logError("failed to import ui styles from '", file, "':\n", e.what()); + } catch(Exception& e) { + logError("Failed to import UI styles from '", file, "': ", e.what()); return false; } } @@ -153,8 +153,11 @@ OTMLNodePtr UIManager::getStyle(const std::string& styleName) } auto it = m_styles.find(styleName); - if(it == m_styles.end()) - throw std::runtime_error(Fw::mkstr("style '", styleName, "' is not a defined style")); + if(it == m_styles.end()) { + logError("Unable to retrive style '", styleName, "': not a defined style"); + return nullptr; + } + return m_styles[styleName]; } @@ -171,14 +174,14 @@ UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent importStyleFromOTML(node); else { if(widget) - throw std::runtime_error("cannot have multiple main widgets in .otui files"); + Fw::throwException("cannot have multiple main widgets in otui files"); widget = loadWidgetFromOTML(node, parent); } } return widget; - } catch(std::exception& e) { - logError("failed to load ui from '", file, "':\n", e.what()); + } catch(Exception& e) { + logError("Failed to load UI from '", file, "': ", e.what()); return nullptr; } } diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 165bb3cf..2ed4f8c1 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -142,6 +142,8 @@ void UIWidget::setFocusable(bool focusable) void UIWidget::setStyle(const std::string& styleName) { OTMLNodePtr styleNode = g_ui.getStyle(styleName); + if(!styleNode) + return; applyStyle(styleNode); m_style = styleNode; updateStyle(); @@ -331,7 +333,7 @@ UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id) void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason) { if(child && !hasChild(child)) { - logError("attempt to focus an unknown child in a UIWidget"); + logError("Attempt to focus an unknown child in a UIWidget"); return; } @@ -440,7 +442,7 @@ void UIWidget::removeChild(const UIWidgetPtr& child) if(focusAnother && !m_focusedChild) focusPreviousChild(Fw::ActiveFocusReason); } else - logError("attempt to remove an unknown child from a UIWidget"); + logError("Attempt to remove an unknown child from a UIWidget"); } void UIWidget::focusNextChild(Fw::FocusReason reason) @@ -774,8 +776,8 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode) try { onStyleApply(styleNode); callLuaField("onStyleApply", styleNode); - } catch(std::exception& e) { - logError("failed to apply widget '", m_id, "' style: ", e.what()); + } catch(Exception& e) { + logError("Failed to apply style to widget '", m_id, "' style: ", e.what()); } } diff --git a/src/framework/util/exception.h b/src/framework/util/exception.h new file mode 100644 index 00000000..c0561670 --- /dev/null +++ b/src/framework/util/exception.h @@ -0,0 +1,19 @@ +#ifndef EXCEPTION_H +#define EXCEPTION_H + +#include + +class Exception : public std::exception +{ +public: + Exception() { } + Exception(const std::string& what) : m_what(what) { } + virtual ~Exception() throw() { }; + + virtual const char* what() const throw() { return m_what.c_str(); } + +protected: + std::string m_what; +}; + +#endif diff --git a/src/framework/util/tools.h b/src/framework/util/tools.h index bb1b3579..159cd1fc 100644 --- a/src/framework/util/tools.h +++ b/src/framework/util/tools.h @@ -29,22 +29,11 @@ #include #include #include -#include -#include #include "types.h" +#include "exception.h" namespace Fw { -inline int getTicks() { - static auto firstTick = std::chrono::high_resolution_clock::now(); - auto tickNow = std::chrono::high_resolution_clock::now(); - return std::chrono::duration_cast(tickNow - firstTick).count(); -} - -inline void sleep(int ms) { - usleep(ms); -} - // read utilities for istream inline uint8 getU8(std::istream& in) { uint8 tmp; @@ -197,9 +186,9 @@ inline bool cast(const bool& in, std::string& out) { } // used by safe_cast -class BadCast : public std::bad_cast { +class CastException : public Exception { public: - virtual ~BadCast() throw() { } + virtual ~CastException() throw() { } template void setWhat() { m_what = mkstr("failed to cast value of type '", demangleType(), @@ -217,7 +206,7 @@ template R safeCast(const T& t) { R r; if(!cast(t, r)) { - BadCast e; + CastException e; e.setWhat(); throw e; } @@ -231,7 +220,7 @@ template R unsafeCast(const T& t, R def = R()) { try { return safeCast(t); - } catch(BadCast& e) { + } catch(CastException& e) { println("CAST ERROR: ", e.what()); return def; } @@ -268,6 +257,11 @@ inline std::string ip2str(uint32 ip) { return std::string(host); } +template +void throwException(const T&... args) { + throw Exception(Fw::mkstr(args...)); +} + } // shortcut for Fw::dump diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 55c606b9..2b574f30 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -27,16 +27,16 @@ #include "tile.h" #include "item.h" -#include #include #include - +#include Creature::Creature() : Thing() { m_healthPercent = 0; m_showSquareColor = false; m_direction = Otc::South; + m_walkTimePerPixel = 1000.0/32.0; m_walking = false; @@ -201,7 +201,7 @@ void Creature::walk(const Position& position, bool inverse) m_walkTimePerPixel = walkTime / 32.0; if(!sameWalk) - m_walkStartTicks = g_platform.getTicks(); + m_walkStartTicks = g_clock.ticks(); updateWalk(); } } @@ -210,7 +210,7 @@ void Creature::updateWalk() { const ThingType& type = getType(); if(m_walking) { - int elapsedTicks = g_platform.getTicks() - m_walkStartTicks; + int elapsedTicks = g_clock.ticks() - m_walkStartTicks; int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32); if(m_inverseWalking) { @@ -240,7 +240,10 @@ void Creature::updateWalk() } int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5; - m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1; + if(type.dimensions[ThingType::AnimationPhases] > 0) + m_animation = (g_clock.ticks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1; + else + m_animation = 0; g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel); if(totalPixelsWalked == 32) @@ -250,17 +253,19 @@ void Creature::updateWalk() void Creature::cancelWalk(Otc::Direction direction) { + if(m_walking) { + auto self = asCreature(); + g_dispatcher.scheduleEvent([=]() { + if(!self->m_walking) + self->m_animation = 0; + }, m_walkTimePerPixel * 2); + } + m_walking = false; m_walkStartTicks = 0; m_walkOffset.x = 0; m_walkOffset.y = 0; m_direction = direction; - - auto self = asCreature(); - g_dispatcher.scheduleEvent([=]() { - if(!self->m_walking) - self->m_animation = 0; - }, m_walkTimePerPixel * 2); } void Creature::setName(const std::string& name) diff --git a/src/otclient/core/effect.cpp b/src/otclient/core/effect.cpp index e75c51c7..33a3aca8 100644 --- a/src/otclient/core/effect.cpp +++ b/src/otclient/core/effect.cpp @@ -24,7 +24,7 @@ #include "thingstype.h" #include "map.h" #include "tile.h" -#include +#include #include Effect::Effect() : Thing() @@ -34,7 +34,7 @@ Effect::Effect() : Thing() void Effect::draw(const Point& p) { - int animationPhase = (g_platform.getTicks() - m_animationStartTicks) / TICKS_PER_FRAME; + int animationPhase = (g_clock.ticks() - m_animationStartTicks) / TICKS_PER_FRAME; if(animationPhase < getAnimationPhases()) { m_animation = animationPhase; @@ -44,7 +44,7 @@ void Effect::draw(const Point& p) void Effect::startAnimation() { - m_animationStartTicks = g_platform.getTicks(); + m_animationStartTicks = g_clock.ticks(); // schedule removal auto self = asEffect(); diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index ad825566..6f55f3ee 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -24,12 +24,12 @@ #include "thingstype.h" #include "spritemanager.h" #include "thing.h" -#include +#include Item::Item() : Thing() { m_data = 0; - m_lastTicks = g_platform.getTicks(); + m_lastTicks = g_clock.ticks(); } void Item::draw(const Point& p) @@ -37,7 +37,7 @@ void Item::draw(const Point& p) const ThingType& type = getType(); if(type.dimensions[ThingType::AnimationPhases] > 1) - m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME; + m_animation = (g_clock.ticks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME; for(int b = 0; b < type.dimensions[ThingType::Layers]; b++) internalDraw(p, b); diff --git a/src/otclient/core/missile.cpp b/src/otclient/core/missile.cpp index ea9ead9d..7eac599c 100644 --- a/src/otclient/core/missile.cpp +++ b/src/otclient/core/missile.cpp @@ -24,7 +24,7 @@ #include "thingstype.h" #include "map.h" #include "tile.h" -#include +#include #include Missile::Missile() : Thing() @@ -34,7 +34,7 @@ Missile::Missile() : Thing() void Missile::draw(const Point& p) { - float time = (g_platform.getTicks() - m_startTicks) / m_duration; + float time = (g_clock.ticks() - m_startTicks) / m_duration; internalDraw(p + Point(m_positionDelta.x * time, m_positionDelta.y * time), 0); } @@ -108,7 +108,7 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition) m_positionDelta.x *= 32; m_positionDelta.y *= 32; - m_startTicks = g_platform.getTicks(); + m_startTicks = g_clock.ticks(); // schedule removal auto self = asMissile(); diff --git a/src/otclient/core/spritemanager.cpp b/src/otclient/core/spritemanager.cpp index 149791eb..076572a6 100644 --- a/src/otclient/core/spritemanager.cpp +++ b/src/otclient/core/spritemanager.cpp @@ -40,8 +40,8 @@ bool SpriteManager::load(const std::string& file) m_spritesCount = Fw::getU16(m_fin); m_sprites.resize(m_spritesCount); return true; - } catch(std::exception& e) { - logError("faile to load sprites from '", file, "': ", e.what()); + } catch(Exception& e) { + logError("Failed to load sprites from '", file, "': ", e.what()); return false; } } diff --git a/src/otclient/core/thingstype.cpp b/src/otclient/core/thingstype.cpp index 6f591a0b..dbcb88f3 100644 --- a/src/otclient/core/thingstype.cpp +++ b/src/otclient/core/thingstype.cpp @@ -48,8 +48,8 @@ bool ThingsType::load(const std::string& file) } return true; - } catch(std::exception& e) { - logError("failed to load dat from '", file, "': ", e.what()); + } catch(Exception& e) { + logError("Failed to load dat from '", file, "': ", e.what()); return false; } } @@ -116,7 +116,14 @@ ThingType& ThingsType::getThingType(uint16 id, Categories category) if(category == Item) id -= 100; - assert(id < m_things[category].size()); + //assert(id < m_things[category].size()); + + // assert wrokground + if(id >= m_things[category].size()) { + //logTraceErrorOnce("got an invalid type"); + static ThingType emptyType; + return emptyType; + } return m_things[category][id]; } diff --git a/src/otclient/core/thingtype.h b/src/otclient/core/thingtype.h index 46dd515a..56cafdf4 100644 --- a/src/otclient/core/thingtype.h +++ b/src/otclient/core/thingtype.h @@ -27,6 +27,13 @@ struct ThingType { + ThingType() { + // fill default values + dimensions.fill(0); + properties.fill(false); + parameters.fill(0); + } + enum Dimensions { Width = 0, Height, diff --git a/src/otclient/luascript/luafunctions.cpp b/src/otclient/luascript/luafunctions.cpp index 37d6b53e..8b3b1472 100644 --- a/src/otclient/luascript/luafunctions.cpp +++ b/src/otclient/luascript/luafunctions.cpp @@ -43,8 +43,6 @@ void OTClient::registerLuaFunctions() { - using namespace std::placeholders; - g_lua.bindGlobalFunction("exit", std::bind(&OTClient::exit, &g_client)); g_lua.bindGlobalFunction("setOnClose", std::bind(&OTClient::setOnClose, &g_client, _1)); g_lua.bindGlobalFunction("importDat", std::bind(&ThingsType::load, &g_thingsType, _1)); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index dbef2856..28ea4d88 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -35,11 +35,11 @@ void ProtocolGame::parseMessage(InputMessage& msg) { - while(!msg.eof()) { - uint8 opt = msg.getU8(); - //dump << "protocol id:" << (int)opt; + try { + while(!msg.eof()) { + uint8 opt = msg.getU8(); - switch(opt) { + switch(opt) { case Otc::GameServerInitGame: parsePlayerLogin(msg); break; @@ -251,9 +251,12 @@ void ProtocolGame::parseMessage(InputMessage& msg) //case Otc::GameServerObjectInfo: //case Otc::GameServerPlayerInventory: default: - logError("UNKNOWN PACKET OPT BYTE: 0x", std::hex, opt); + Fw::throwException("unknown opt byte ", opt); break; + } } + } catch(Exception& e) { + logTraceError(e.what()); } } @@ -738,7 +741,7 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg) case Otc::SpeakPrivateRed: break; default: - logTraceDebug("Unknown speak type.", (int)type); + logTraceError("unknown speak type ", type); break; } @@ -811,7 +814,7 @@ void ProtocolGame::parseCancelWalk(InputMessage& msg) void ProtocolGame::parseFloorChangeUp(InputMessage& msg) { - logDebug("[ProtocolGame::parseFloorChangeUp]: This function has never been tested."); + logTraceDebug("this function has never been tested."); Position pos = g_map.getCentralPosition(); pos.z--; @@ -830,7 +833,7 @@ void ProtocolGame::parseFloorChangeUp(InputMessage& msg) void ProtocolGame::parseFloorChangeDown(InputMessage& msg) { - logDebug("[ProtocolGame::parseFloorChangeDown]: This function has never been tested."); + logTraceDebug("this function has never been tested."); Position pos = g_map.getCentralPosition(); pos.z++; @@ -982,13 +985,13 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position) g_map.cleanTile(position); int stackPos = 0; - while(1){ + while(true) { uint16 inspectTileId = msg.getU16(true); if(inspectTileId >= 0xFF00) return; else { if(stackPos >= 10) - logWarning("Too many things!"); + logTraceWarning("too many things"); ThingPtr thing = internalGetThing(msg); g_map.addThing(thing, position, 255); diff --git a/src/otclient/net/protocolgamesend.cpp b/src/otclient/net/protocolgamesend.cpp index 3df83f04..ebd4b914 100644 --- a/src/otclient/net/protocolgamesend.cpp +++ b/src/otclient/net/protocolgamesend.cpp @@ -52,8 +52,7 @@ void ProtocolGame::sendLoginPacket(uint32 timestamp, uint8 unknown) oMsg.addPaddingBytes(128 - (29 + m_accountName.length() + m_characterName.length() + m_accountPassword.length())); // encrypt with RSA - if(!Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA)) - return; + Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA); send(oMsg); diff --git a/src/otclient/net/protocollogin.cpp b/src/otclient/net/protocollogin.cpp index 5ac4313d..bbd4bb3d 100644 --- a/src/otclient/net/protocollogin.cpp +++ b/src/otclient/net/protocollogin.cpp @@ -53,22 +53,29 @@ void ProtocolLogin::onConnect() void ProtocolLogin::onRecv(InputMessage& inputMessage) { - while(!inputMessage.eof()) { - uint8 opt = inputMessage.getU8(); - switch(opt) { - case Otc::LoginServerError: - parseError(inputMessage); - break; - case Otc::LoginServerMotd: - parseMOTD(inputMessage); - break; - case Otc::LoginServerUpdateNeeded: - callLuaField("onError", "Client needs update."); - break; - case Otc::LoginServerCharacterList: - parseCharacterList(inputMessage); - break; + try { + while(!inputMessage.eof()) { + uint8 opt = inputMessage.getU8(); + switch(opt) { + case Otc::LoginServerError: + parseError(inputMessage); + break; + case Otc::LoginServerMotd: + parseMOTD(inputMessage); + break; + case Otc::LoginServerUpdateNeeded: + callLuaField("onError", "Client needs update."); + break; + case Otc::LoginServerCharacterList: + parseCharacterList(inputMessage); + break; + default: + Fw::throwException("unknown opt byte ", opt); + break; + } } + } catch(Exception& e) { + logTraceError(e.what()); } disconnect(); } @@ -104,14 +111,10 @@ void ProtocolLogin::sendLoginPacket() // complete the 128 bytes for rsa encryption with zeros oMsg.addPaddingBytes(128 - (21 + m_accountName.length() + m_accountPassword.length())); - - if(!Rsa::encrypt((char*)oMsg.getBuffer() + InputMessage::DATA_POS + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA)) - return; + Rsa::encrypt((char*)oMsg.getBuffer() + InputMessage::DATA_POS + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA); send(oMsg); - enableXteaEncryption(); - recv(); } diff --git a/src/otclient/otclient.cpp b/src/otclient/otclient.cpp index 80d31a24..5a392e18 100644 --- a/src/otclient/otclient.cpp +++ b/src/otclient/otclient.cpp @@ -23,17 +23,17 @@ #include "otclient.h" #include -#include +#include #include #include +#include #include -#include #include #include #include #include #include - +#include #include #include #include @@ -79,9 +79,6 @@ void OTClient::init(std::vector args) // initialize graphics g_graphics.init(); - // initialize event dispatcher - g_dispatcher.init(); - // initialize the ui g_ui.init(); @@ -105,7 +102,7 @@ void OTClient::init(std::vector args) void OTClient::run() { - int frameTicks = g_platform.getTicks(); + int frameTicks = g_clock.ticks(); int lastPollTicks = frameTicks; int frameCount = 0; @@ -113,7 +110,7 @@ void OTClient::run() m_running = true; if(g_ui.getRootWidget()->getChildCount() == 0) { - logError("there is no root widgets to display, the app will close"); + logError("There is no root widgets to display, the app will close"); m_stopping = true; } @@ -122,8 +119,7 @@ void OTClient::run() while(!m_stopping) { //g_platform.sleep(150); - g_platform.updateTicks(); - frameTicks = g_platform.getTicks(); + frameTicks = g_clock.updateTicks(); // poll events every POLL_CYCLE_DELAY // this delay exists to avoid massive polling thus increasing framerate @@ -147,7 +143,7 @@ void OTClient::run() g_platform.swapBuffers(); } else { // sleeps until next poll to avoid massive cpu usage - Fw::sleep(POLL_CYCLE_DELAY+1); + g_clock.sleep(POLL_CYCLE_DELAY+1); } } @@ -177,8 +173,8 @@ void OTClient::terminate() // terminate network Connection::terminate(); - // terminate dispatcher - g_dispatcher.terminate(); + // flush remaining dispatcher events + g_dispatcher.flush(); // terminate graphics g_graphics.terminate(); @@ -257,7 +253,7 @@ void OTClient::saveConfigurations() // saves user configuration if(!g_configs.save()) - logError("configurations are lost because it couldn't be saved"); + logError("Configurations are lost because it couldn't be saved"); } void OTClient::onClose()