add clock, change exceptions, add network exceptions, fix some crashes

This commit is contained in:
Eduardo Bart 2011-12-01 20:25:32 -02:00
parent 4afbe43e6f
commit d5e15d1f06
54 changed files with 442 additions and 274 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/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<std::chrono::milliseconds>(timeNow - m_startupTime).count();
return m_currentTicks;
}
void Clock::sleep(int ms)
{
usleep(ms * 1000);
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/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

View File

@ -20,14 +20,14 @@
* THE SOFTWARE.
*/
#include "configs.h"
#include "configmanager.h"
#include "resourcemanager.h"
#include <framework/otml/otml.h>
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) {

View File

@ -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<std::string, std::string> m_confsMap;
};
extern Configs g_configs;
extern ConfigManager g_configs;
#endif

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/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"

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/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

View File

@ -22,44 +22,42 @@
#include "eventdispatcher.h"
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
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);

View File

@ -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:

View File

@ -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()

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -30,6 +30,7 @@
#include <cassert>
#include <ctime>
#include <cmath>
#include <unistd.h>
// common STL headers
#include <iostream>
@ -53,6 +54,7 @@
#include <iomanip>
#include <unordered_map>
#include <random>
#include <chrono>
// boost utilities
#include <boost/algorithm/string.hpp>

View File

@ -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();

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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

View File

@ -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());
}
}

View File

@ -25,7 +25,7 @@
#include <framework/ui/ui.h>
#include <framework/net/protocol.h>
#include <framework/core/eventdispatcher.h>
#include <framework/core/configs.h>
#include <framework/core/configmanager.h>
#include <framework/platform/platform.h>
#include <framework/otml/otml.h>
#include <framework/graphics/graphics.h>
@ -152,10 +152,10 @@ void LuaInterface::registerFunctions()
g_lua.registerClass<Protocol>();
// ConfigManager
g_lua.registerClass<Configs>();
g_lua.bindClassStaticFunction<Configs>("set", std::bind(&Configs::set, &g_configs, _1, _2));
g_lua.bindClassStaticFunction<Configs>("get", std::bind(&Configs::get, &g_configs, _1));
g_lua.bindClassStaticFunction<Configs>("exists", std::bind(&Configs::exists, &g_configs, _1));
g_lua.registerClass<ConfigManager>();
g_lua.bindClassStaticFunction<ConfigManager>("set", std::bind(&ConfigManager::set, &g_configs, _1, _2));
g_lua.bindClassStaticFunction<ConfigManager>("get", std::bind(&ConfigManager::get, &g_configs, _1));
g_lua.bindClassStaticFunction<ConfigManager>("exists", std::bind(&ConfigManager::exists, &g_configs, _1));
// Logger
g_lua.registerClass<Logger>();

View File

@ -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);

View File

@ -168,7 +168,7 @@ bool luavalue_cast(int index, std::function<void(Args...)>& 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<Ret(Args...)>& 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();

View File

@ -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");
}

View File

@ -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;

View File

@ -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

View File

@ -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");
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -24,7 +24,7 @@
#include "uitranslator.h"
#include <framework/graphics/font.h>
#include <framework/otml/otmlnode.h>
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
#include <framework/graphics/graphics.h>
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;

View File

@ -24,6 +24,7 @@
#include <framework/graphics/font.h>
#include <framework/graphics/graphics.h>
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
#include <framework/otml/otmlnode.h>
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();
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,19 @@
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include <exception>
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

View File

@ -29,22 +29,11 @@
#include <sstream>
#include <exception>
#include <cxxabi.h>
#include <chrono>
#include <unistd.h>
#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<std::chrono::milliseconds>(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<class T, class R>
void setWhat() {
m_what = mkstr("failed to cast value of type '", demangleType<T>(),
@ -217,7 +206,7 @@ template<typename R, typename T>
R safeCast(const T& t) {
R r;
if(!cast(t, r)) {
BadCast e;
CastException e;
e.setWhat<T,R>();
throw e;
}
@ -231,7 +220,7 @@ template<typename R, typename T>
R unsafeCast(const T& t, R def = R()) {
try {
return safeCast<R,T>(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<typename... T>
void throwException(const T&... args) {
throw Exception(Fw::mkstr(args...));
}
}
// shortcut for Fw::dump

View File

@ -27,16 +27,16 @@
#include "tile.h"
#include "item.h"
#include <framework/platform/platform.h>
#include <framework/graphics/graphics.h>
#include <framework/core/eventdispatcher.h>
#include <framework/core/clock.h>
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)

View File

@ -24,7 +24,7 @@
#include "thingstype.h"
#include "map.h"
#include "tile.h"
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
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();

View File

@ -24,12 +24,12 @@
#include "thingstype.h"
#include "spritemanager.h"
#include "thing.h"
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
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);

View File

@ -24,7 +24,7 @@
#include "thingstype.h"
#include "map.h"
#include "tile.h"
#include <framework/platform/platform.h>
#include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
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();

View File

@ -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;
}
}

View File

@ -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];
}

View File

@ -27,6 +27,13 @@
struct ThingType
{
ThingType() {
// fill default values
dimensions.fill(0);
properties.fill(false);
parameters.fill(0);
}
enum Dimensions {
Width = 0,
Height,

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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();
}

View File

@ -23,17 +23,17 @@
#include "otclient.h"
#include <framework/core/modulemanager.h>
#include <framework/core/configs.h>
#include <framework/core/configmanager.h>
#include <framework/core/resourcemanager.h>
#include <framework/core/eventdispatcher.h>
#include <framework/core/clock.h>
#include <framework/luascript/luainterface.h>
#include <framework/platform/platform.h>
#include <framework/graphics/graphics.h>
#include <framework/graphics/fontmanager.h>
#include <framework/ui/uimanager.h>
#include <framework/ui/uiwidget.h>
#include <framework/net/connection.h>
#include <framework/platform/platform.h>
#include <otclient/net/protocolgame.h>
#include <otclient/core/game.h>
#include <otclient/core/map.h>
@ -79,9 +79,6 @@ void OTClient::init(std::vector<std::string> 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<std::string> 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()