diff --git a/TODO b/TODO index 43d0df66..3bce50d2 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,7 @@ [bart] create a class for reading binary files [bart] rework lua/c++ logger [bart] save lists on config manager +[bart] make protocol class compatible with old tibia protocols == Graphics [bart] use CoordsBuffer in font @@ -16,13 +17,15 @@ == Lua [bart] make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) -[bart] bind every global lua function in a static classes +[bart] bind every global lua function in static classes == Platform [bart] implement fullscreen, maximize and minsize for win32 +[bart] port to MacOs and iphone == UI [bart] tab widgets +[bart] add anchors API [bart] scrollbar [bart] scrollable widgets [bart] grid layout @@ -64,6 +67,7 @@ [bart] draw lights using shaders [bart] chat with tabs [bart] limit FPS in options +[baxnie] do lua game event calls from Game instead from GameProtocol [baxnie] trade window [baxnie] auto walk [baxnie] hotkeys window diff --git a/src/framework/luascript/luainterface.cpp b/src/framework/luascript/luainterface.cpp index 57ae62cc..a57096e7 100644 --- a/src/framework/luascript/luainterface.cpp +++ b/src/framework/luascript/luainterface.cpp @@ -28,9 +28,11 @@ LuaInterface g_lua; -LuaInterface::LuaInterface() : - L(NULL), m_weakTableRef(0) +LuaInterface::LuaInterface() { + L = nullptr; + m_cppCallbackDepth = 0; + m_weakTableRef = 0; } LuaInterface::~LuaInterface() @@ -529,7 +531,9 @@ int LuaInterface::luaCppFunctionCallback(lua_State* L) // do the call try { + g_lua.m_cppCallbackDepth++; numRets = (*(funcPtr->get()))(&g_lua); + g_lua.m_cppCallbackDepth--; assert(numRets == g_lua.stackSize()); } catch(LuaException &e) { logError("lua cpp callback failed: ", e.what()); diff --git a/src/framework/luascript/luainterface.h b/src/framework/luascript/luainterface.h index 58aa4f68..1338b507 100644 --- a/src/framework/luascript/luainterface.h +++ b/src/framework/luascript/luainterface.h @@ -181,6 +181,8 @@ public: template R callGlobalField(const std::string& global, const std::string& field, const T&... args); + bool isInCppCallback() { return m_cppCallbackDepth != 0; } + private: /// Load scripts requested by lua 'require' static int luaScriptLoader(lua_State* L); @@ -311,6 +313,7 @@ public: private: lua_State* L; int m_weakTableRef; + int m_cppCallbackDepth; }; extern LuaInterface g_lua; diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 18473c8f..4003e9a2 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -785,6 +785,15 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode) m_loadingStyle = true; onStyleApply(styleNode->tag(), styleNode); callLuaField("onStyleApply", styleNode->tag(), styleNode); + + if(m_firstOnStyle) { + callLuaField("onSetup"); + // always focus new child + if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) + focus(); + } + m_firstOnStyle = false; + m_loadingStyle = false; } catch(Exception& e) { logError("Failed to apply style to widget '", m_id, "' style: ", e.what()); @@ -1156,15 +1165,6 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty luaSetField(fieldName); } } - - if(m_firstOnStyle) { - callLuaField("onSetup"); - // always focus new child - if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) - focus(); - } - - m_firstOnStyle = false; } void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect) diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 68a1cb4c..01aa2cc8 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -106,7 +106,7 @@ void Game::processInventoryChange(int slot, const ItemPtr& item) void Game::walk(Otc::Direction direction) { - if(!m_online || !m_localPlayer->canWalk(direction) || (!g_ui.isOnInputEvent() && m_localPlayer->getNextWalkDirection() == Otc::InvalidDirection)) + if(!m_online || !m_localPlayer->canWalk(direction) || !checkBotProtection()) return; cancelFollow(); @@ -164,7 +164,7 @@ void Game::turn(Otc::Direction direction) void Game::look(const ThingPtr& thing) { - if(!m_online || !thing || !g_ui.isOnInputEvent()) + if(!m_online || !thing || !checkBotProtection()) return; int stackpos = getThingStackpos(thing); @@ -174,7 +174,7 @@ void Game::look(const ThingPtr& thing) void Game::use(const ThingPtr& thing) { - if(!m_online || !thing || !g_ui.isOnInputEvent()) + if(!m_online || !thing || !checkBotProtection()) return; int stackpos = getThingStackpos(thing); @@ -184,7 +184,7 @@ void Game::use(const ThingPtr& thing) void Game::attack(const CreaturePtr& creature) { - if(!m_online || !creature || !g_ui.isOnInputEvent()) + if(!m_online || !creature || !checkBotProtection()) return; if(m_attackingCreature) @@ -215,7 +215,7 @@ void Game::onAttackCancelled() void Game::follow(const CreaturePtr& creature) { - if(!m_online || !creature || !g_ui.isOnInputEvent()) + if(!m_online || !creature || !checkBotProtection()) return; if(m_followingCreature) @@ -238,7 +238,7 @@ void Game::cancelFollow() void Game::rotate(const ThingPtr& thing) { - if(!m_online || !thing || !g_ui.isOnInputEvent()) + if(!m_online || !thing || !checkBotProtection()) return; int stackpos = getThingStackpos(thing); @@ -260,7 +260,7 @@ int Game::getThingStackpos(const ThingPtr& thing) void Game::talkChannel(int channelType, int channelId, const std::string& message) { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendTalk(channelType, channelId, "", message); @@ -268,7 +268,7 @@ void Game::talkChannel(int channelType, int channelId, const std::string& messag void Game::talkPrivate(int channelType, const std::string& receiver, const std::string& message) { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendTalk(channelType, 0, receiver, message); @@ -276,7 +276,7 @@ void Game::talkPrivate(int channelType, const std::string& receiver, const std:: void Game::inviteToParty(int creatureId) { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendInviteToParty(creatureId); @@ -284,7 +284,7 @@ void Game::inviteToParty(int creatureId) void Game::openOutfitWindow() { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendGetOutfit(); @@ -292,7 +292,7 @@ void Game::openOutfitWindow() void Game::setOutfit(const Outfit& outfit) { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendSetOutfit(outfit); @@ -300,7 +300,7 @@ void Game::setOutfit(const Outfit& outfit) void Game::addVip(const std::string& name) { - if(!m_online || name.empty() || !g_ui.isOnInputEvent()) + if(!m_online || name.empty() || !checkBotProtection()) return; m_protocolGame->sendAddVip(name); @@ -308,8 +308,19 @@ void Game::addVip(const std::string& name) void Game::removeVip(int playerId) { - if(!m_online || !g_ui.isOnInputEvent()) + if(!m_online || !checkBotProtection()) return; m_protocolGame->sendRemoveVip(playerId); } + +bool Game::checkBotProtection() +{ +#ifndef DISABLE_BOT_PROTECTION + if(g_lua.isInCppCallback() && !g_ui.isOnInputEvent()) { + logError("cought a lua call to a bot protected game function, the call was canceled"); + return false; + } +#endif + return true; +} diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 67bc07f1..fe9828a5 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -65,6 +65,8 @@ public: int getThingStackpos(const ThingPtr& thing); void onAttackCancelled(); + bool checkBotProtection(); + CreaturePtr getAttackingCreature() { return m_attackingCreature; } CreaturePtr getFollowingCreature() { return m_followingCreature; }