From b216b00a32605d00f9427aea88a5c751cd44dc67 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 3 Nov 2011 18:54:53 -0200 Subject: [PATCH] add chat panel, send text messages, guard forbidden functions with an ifdef --- CMakeLists.txt | 5 ++++ modules/chat/chat.lua | 19 +++++++++++++ modules/chat/chat.otmod | 14 ++++++++++ modules/chat/chat.otui | 30 +++++++++++++++++++++ modules/console/console.otui | 2 +- modules/core/util.lua | 5 ++-- modules/game/game.lua | 24 +++++++---------- modules/game/game.otmod | 3 --- modules/skills/skills.lua | 5 +++- modules/skills/skills.otmod | 4 --- modules/viplist/viplist.lua | 3 +++ modules/viplist/viplist.otmod | 4 --- src/framework/ui/uilineedit.cpp | 13 ++++++--- src/framework/ui/uilineedit.h | 1 + src/otclient/otclientluafunctions.cpp | 8 ++++-- src/otclient/ui/uimap.cpp | 39 +++++++++++++++++++++++++++ 16 files changed, 142 insertions(+), 37 deletions(-) create mode 100644 modules/chat/chat.lua create mode 100644 modules/chat/chat.otmod create mode 100644 modules/chat/chat.otui diff --git a/CMakeLists.txt b/CMakeLists.txt index c7e2b8ec..6d847d10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") OPTION(USE_PCH "Use precompiled header" ON) OPTION(NO_CONSOLE "Disable console window on Windows" OFF) OPTION(HANDLE_EXCEPTIONS "Generate crash reports" OFF) +OPTION(FORBIDDEN_FUNCTIONS "Enable forbidden lua functions" ON) # find needed packages SET(Boost_USE_STATIC_LIBS ON) @@ -141,6 +142,10 @@ IF(HANDLE_EXCEPTIONS) ADD_DEFINITIONS(-DHANDLE_EXCEPTIONS) ENDIF(HANDLE_EXCEPTIONS) +IF(FORBIDDEN_FUNCTIONS) + ADD_DEFINITIONS(-DFORBIDDEN_FUNCTIONS) +ENDIF(FORBIDDEN_FUNCTIONS) + IF(WIN32) SET(SOURCES ${SOURCES} src/framework/platform/win32platform.cpp) SET(ADDITIONAL_LIBRARIES ws2_32) diff --git a/modules/chat/chat.lua b/modules/chat/chat.lua new file mode 100644 index 00000000..cafa9778 --- /dev/null +++ b/modules/chat/chat.lua @@ -0,0 +1,19 @@ +Chat = {} + +-- private variables +local chatPanel + +-- public functions +function Chat.create() + chatPanel = loadUI("/chat/chat.otui", Game.gameBottomPanel) +end + +function Chat.destroy() + chatPanel:destroy() + chatPanel = nil +end + +-- hooked events + +connect(Game, { onLogin = Chat.create, + onLogout = Chat.destroy }) \ No newline at end of file diff --git a/modules/chat/chat.otmod b/modules/chat/chat.otmod new file mode 100644 index 00000000..401582b2 --- /dev/null +++ b/modules/chat/chat.otmod @@ -0,0 +1,14 @@ +Module + name: chat + description: Manage chat window + author: OTClient team + website: https://github.com/edubart/otclient + autoLoad: true + dependencies: + - game + + onLoad: | + require 'chat' + return true + + diff --git a/modules/chat/chat.otui b/modules/chat/chat.otui new file mode 100644 index 00000000..7753dca3 --- /dev/null +++ b/modules/chat/chat.otui @@ -0,0 +1,30 @@ +ChatLabel < UILabel + font: verdana-11px-monochrome + height: 16 + +Panel + id: chatPanel + anchors.fill: parent + + Panel + id: chatBuffer + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: next.top + margin.right: 6 + margin.left: 6 + margin.bottom: 2 + margin.top: 6 + layout: verticalBox + focusable: false + + LineEdit + id: chatLineEdit + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + margin.right: 6 + margin.left: 6 + margin.bottom: 6 + always focused: true \ No newline at end of file diff --git a/modules/console/console.otui b/modules/console/console.otui index 94935c1f..46e9b92a 100644 --- a/modules/console/console.otui +++ b/modules/console/console.otui @@ -8,7 +8,7 @@ RectPanel opacity: 216 anchors.fill: parent - UIWidget + Panel id: consoleBuffer layout: verticalBox focusable: false diff --git a/modules/core/util.lua b/modules/core/util.lua index 6db522b0..e1ea9157 100644 --- a/modules/core/util.lua +++ b/modules/core/util.lua @@ -18,9 +18,8 @@ function connect(object, signalsAndSlots) object[signal] = slot elseif type(object[signal]) == 'function' then object[signal] = { object[signal], slot } - elseif type(signal) == 'table' then - table.insert(object[signal], slot) - else + elseif type(object[signal]) == 'table' then + table.insert(object[signal], #object[signal]+1, slot) end end end diff --git a/modules/game/game.lua b/modules/game/game.lua index f583dfdd..af23dc9c 100644 --- a/modules/game/game.lua +++ b/modules/game/game.lua @@ -15,20 +15,23 @@ local function onGameKeyPress(self, keyCode, keyChar, keyboardModifiers) end -- public functions -function Game.create() +function Game.createInterface() + Background.hide() + CharacterList.destroyLoadBox() Game.gameUi = loadUI('/game/ui/gameinterface.otui', UI.root) Game.gameMapPanel = Game.gameUi:getChildById('mapPanel') Game.gameRightPanel = Game.gameUi:getChildById('rightPanel') + Game.gameBottomPanel = Game.gameUi:getChildById('bottomPanel') Game.gameUi.onKeyPress = onGameKeyPress - - TextMessage.create() end -function Game.destroy() +function Game.destroyInterface() if Game.gameUi then Game.gameUi:destroy() Game.gameUi = nil end + Background.show() + CharacterList.show() end function Game.show() @@ -42,12 +45,6 @@ function Game.hide() end -- hooked events -function Game.onLogin() - Background.hide() - CharacterList.destroyLoadBox() - Game.show() -end - function Game.onLoginError(message) CharacterList.destroyLoadBox() local errorBox = displayErrorBox("Login Error", "Login error: " .. message) @@ -60,8 +57,5 @@ function Game.onConnectionError(message) errorBox.onOk = CharacterList.show end -function Game.onLogout() - Game.hide() - Background.show() - CharacterList.show() -end +connect(Game, { onLogin = Game.createInterface, + onLogout = Game.destroyInterface }) diff --git a/modules/game/game.otmod b/modules/game/game.otmod index c1efc1df..c16c6676 100644 --- a/modules/game/game.otmod +++ b/modules/game/game.otmod @@ -13,7 +13,4 @@ Module onLoad: | require 'game' - require 'textmessage' - Game.create() - Game.hide() return true diff --git a/modules/skills/skills.lua b/modules/skills/skills.lua index c73f6b7c..9c733d80 100644 --- a/modules/skills/skills.lua +++ b/modules/skills/skills.lua @@ -43,4 +43,7 @@ end function Game.setSkill(id, level, percent) local skillPanel = skillWindow:getChildById('skillPanel') local levelLabel = skillPanel:getChildById('skillLevel' .. id) -end \ No newline at end of file +end + +connect(Game, { onLogin = Skills.create, + onLogout = Skills.destroy }) \ No newline at end of file diff --git a/modules/skills/skills.otmod b/modules/skills/skills.otmod index fd9152d9..2bbf3694 100644 --- a/modules/skills/skills.otmod +++ b/modules/skills/skills.otmod @@ -9,10 +9,6 @@ Module onLoad: | require 'skills' - Skills.create() return true - onUnload: - Skills.destroy() - diff --git a/modules/viplist/viplist.lua b/modules/viplist/viplist.lua index 01651c81..9df157fd 100644 --- a/modules/viplist/viplist.lua +++ b/modules/viplist/viplist.lua @@ -44,3 +44,6 @@ function Game.onVipStateChange(id, online) label.vipOnline = online end + +connect(Game, { onLogin = VipList.create, + onLogout = VipList.destroy }) diff --git a/modules/viplist/viplist.otmod b/modules/viplist/viplist.otmod index cde05e4f..7f995c5d 100644 --- a/modules/viplist/viplist.otmod +++ b/modules/viplist/viplist.otmod @@ -9,10 +9,6 @@ Module onLoad: | require 'viplist' - VipList.create() return true - onUnload: - VipList.destroy() - diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index 59ba975f..7797272d 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -33,6 +33,7 @@ UILineEdit::UILineEdit() m_startRenderPos = 0; m_textHorizontalMargin = 0; m_textHidden = false; + m_alwaysFocused = false; blinkCursor(); } @@ -50,7 +51,7 @@ void UILineEdit::render() g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); // render cursor - if(isExplicitlyEnabled() && isActive() && m_cursorPos >= 0) { + if(isExplicitlyEnabled() && (isActive() || m_alwaysFocused) && m_cursorPos >= 0) { assert(m_cursorPos <= textLength); // draw every 333ms const int delay = 333; @@ -384,6 +385,8 @@ void UILineEdit::onStyleApply(const OTMLNodePtr& styleNode) setTextHidden(node->value()); } else if(node->tag() == "text margin") { m_textHorizontalMargin = node->value(); + } else if(node->tag() == "always focused") { + m_alwaysFocused = true; } } } @@ -395,7 +398,7 @@ void UILineEdit::onGeometryUpdate(const Rect& oldRect, const Rect& newRect) void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason) { - if(focused) { + if(focused && !m_alwaysFocused) { if(reason == Fw::TabFocusReason) setCursorPos(m_text.length()); else @@ -420,8 +423,10 @@ bool UILineEdit::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier) appendText(g_platform.getClipboardText()); else if(keyCode == Fw::KeyTab) { - if(UIWidgetPtr parent = getParent()) - parent->focusNextChild(Fw::TabFocusReason); + if(!m_alwaysFocused) { + if(UIWidgetPtr parent = getParent()) + parent->focusNextChild(Fw::TabFocusReason); + } } else if(keyChar != 0) appendCharacter(keyChar); else diff --git a/src/framework/ui/uilineedit.h b/src/framework/ui/uilineedit.h index e29eb391..12a33ffd 100644 --- a/src/framework/ui/uilineedit.h +++ b/src/framework/ui/uilineedit.h @@ -71,6 +71,7 @@ private: int m_cursorTicks; int m_textHorizontalMargin; bool m_textHidden; + bool m_alwaysFocused; std::vector m_glyphsCoords; std::vector m_glyphsTexCoords; diff --git a/src/otclient/otclientluafunctions.cpp b/src/otclient/otclientluafunctions.cpp index 47b7c7fd..f2c83238 100644 --- a/src/otclient/otclientluafunctions.cpp +++ b/src/otclient/otclientluafunctions.cpp @@ -63,9 +63,13 @@ void OTClient::registerLuaFunctions() g_lua.bindClassStaticFunction("logout", std::bind(&Game::logout, &g_game, _1)); g_lua.bindClassStaticFunction("cancelLogin", std::bind(&Game::cancelLogin, &g_game)); g_lua.bindClassStaticFunction("isOnline", std::bind(&Game::isOnline, &g_game)); - g_lua.bindClassStaticFunction("talkChannel", std::bind(&Game::talkChannel, &g_game, _1, _2, _3)); - g_lua.bindClassStaticFunction("talkPrivate", std::bind(&Game::talkPrivate, &g_game, _1, _2, _3)); + g_lua.bindClassStaticFunction("isOnline", std::bind(&Game::isOnline, &g_game)); g_lua.registerClass(); g_lua.bindClassStaticFunction("create", &UIWidget::create); + +#ifdef FORBIDDEN_FUNCTIONS + g_lua.bindClassStaticFunction("talkChannel", std::bind(&Game::talkChannel, &g_game, _1, _2, _3)); + g_lua.bindClassStaticFunction("talkPrivate", std::bind(&Game::talkPrivate, &g_game, _1, _2, _3)); +#endif } diff --git a/src/otclient/ui/uimap.cpp b/src/otclient/ui/uimap.cpp index 3554d68b..99f0906f 100644 --- a/src/otclient/ui/uimap.cpp +++ b/src/otclient/ui/uimap.cpp @@ -25,6 +25,7 @@ #include #include #include +#include void UIMap::setup() { @@ -46,6 +47,8 @@ void UIMap::render() bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) { + UILineEditPtr chatLineEdit = std::dynamic_pointer_cast(getParent()->recursiveGetChildById("chatLineEdit")); + if(keyboardModifiers == Fw::KeyboardNoModifier) { if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) { g_game.walk(Otc::North); @@ -71,6 +74,28 @@ bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) } else if(keyCode == Fw::KeyNumpad7) { g_game.walk(Otc::NorthWest); return true; + } else if(keyCode == Fw::KeyReturn || keyCode == Fw::KeyEnter) { + g_game.talkChannel(1, 0, chatLineEdit->getText()); + chatLineEdit->clearText(); + return true; + } else if(keyCode == Fw::KeyDelete) { + chatLineEdit->removeCharacter(true); + return true; + } else if(keyCode == Fw::KeyBackspace) { + chatLineEdit->removeCharacter(false); + return true; + } else if(keyCode == Fw::KeyRight) { + chatLineEdit->moveCursor(true); + return true; + } else if(keyCode == Fw::KeyLeft) { + chatLineEdit->moveCursor(false); + return true; + } else if(keyCode == Fw::KeyHome) { + chatLineEdit->setCursorPos(0); + return true; + } else if(keyCode == Fw::KeyEnd) { + chatLineEdit->setCursorPos(chatLineEdit->getText().length()); + return true; } } else if(keyboardModifiers == Fw::KeyboardCtrlModifier) { if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) { @@ -86,7 +111,21 @@ bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) g_game.turn(Otc::West); return true; } + } else if(keyboardModifiers == Fw::KeyboardShiftModifier) { + if(keyCode == Fw::KeyRight || keyCode == Fw::KeyNumpad6) { + chatLineEdit->moveCursor(true); + return true; + } else if(keyCode == Fw::KeyLeft || keyCode == Fw::KeyNumpad4) { + chatLineEdit->moveCursor(false); + return true; + } } + + if(keyChar != 0) { + chatLineEdit->appendText(std::string(1, keyChar)); + return true; + } + return UIWidget::onKeyPress(keyCode, keyChar, keyboardModifiers); }