add chat panel, send text messages, guard forbidden functions with an ifdef
This commit is contained in:
parent
6d6479e4a9
commit
b216b00a32
|
@ -7,6 +7,7 @@ SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
|
||||||
OPTION(USE_PCH "Use precompiled header" ON)
|
OPTION(USE_PCH "Use precompiled header" ON)
|
||||||
OPTION(NO_CONSOLE "Disable console window on Windows" OFF)
|
OPTION(NO_CONSOLE "Disable console window on Windows" OFF)
|
||||||
OPTION(HANDLE_EXCEPTIONS "Generate crash reports" OFF)
|
OPTION(HANDLE_EXCEPTIONS "Generate crash reports" OFF)
|
||||||
|
OPTION(FORBIDDEN_FUNCTIONS "Enable forbidden lua functions" ON)
|
||||||
|
|
||||||
# find needed packages
|
# find needed packages
|
||||||
SET(Boost_USE_STATIC_LIBS ON)
|
SET(Boost_USE_STATIC_LIBS ON)
|
||||||
|
@ -141,6 +142,10 @@ IF(HANDLE_EXCEPTIONS)
|
||||||
ADD_DEFINITIONS(-DHANDLE_EXCEPTIONS)
|
ADD_DEFINITIONS(-DHANDLE_EXCEPTIONS)
|
||||||
ENDIF(HANDLE_EXCEPTIONS)
|
ENDIF(HANDLE_EXCEPTIONS)
|
||||||
|
|
||||||
|
IF(FORBIDDEN_FUNCTIONS)
|
||||||
|
ADD_DEFINITIONS(-DFORBIDDEN_FUNCTIONS)
|
||||||
|
ENDIF(FORBIDDEN_FUNCTIONS)
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(SOURCES ${SOURCES} src/framework/platform/win32platform.cpp)
|
SET(SOURCES ${SOURCES} src/framework/platform/win32platform.cpp)
|
||||||
SET(ADDITIONAL_LIBRARIES ws2_32)
|
SET(ADDITIONAL_LIBRARIES ws2_32)
|
||||||
|
|
|
@ -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 })
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -8,7 +8,7 @@ RectPanel
|
||||||
opacity: 216
|
opacity: 216
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
UIWidget
|
Panel
|
||||||
id: consoleBuffer
|
id: consoleBuffer
|
||||||
layout: verticalBox
|
layout: verticalBox
|
||||||
focusable: false
|
focusable: false
|
||||||
|
|
|
@ -18,9 +18,8 @@ function connect(object, signalsAndSlots)
|
||||||
object[signal] = slot
|
object[signal] = slot
|
||||||
elseif type(object[signal]) == 'function' then
|
elseif type(object[signal]) == 'function' then
|
||||||
object[signal] = { object[signal], slot }
|
object[signal] = { object[signal], slot }
|
||||||
elseif type(signal) == 'table' then
|
elseif type(object[signal]) == 'table' then
|
||||||
table.insert(object[signal], slot)
|
table.insert(object[signal], #object[signal]+1, slot)
|
||||||
else
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,20 +15,23 @@ local function onGameKeyPress(self, keyCode, keyChar, keyboardModifiers)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- public functions
|
-- public functions
|
||||||
function Game.create()
|
function Game.createInterface()
|
||||||
|
Background.hide()
|
||||||
|
CharacterList.destroyLoadBox()
|
||||||
Game.gameUi = loadUI('/game/ui/gameinterface.otui', UI.root)
|
Game.gameUi = loadUI('/game/ui/gameinterface.otui', UI.root)
|
||||||
Game.gameMapPanel = Game.gameUi:getChildById('mapPanel')
|
Game.gameMapPanel = Game.gameUi:getChildById('mapPanel')
|
||||||
Game.gameRightPanel = Game.gameUi:getChildById('rightPanel')
|
Game.gameRightPanel = Game.gameUi:getChildById('rightPanel')
|
||||||
|
Game.gameBottomPanel = Game.gameUi:getChildById('bottomPanel')
|
||||||
Game.gameUi.onKeyPress = onGameKeyPress
|
Game.gameUi.onKeyPress = onGameKeyPress
|
||||||
|
|
||||||
TextMessage.create()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Game.destroy()
|
function Game.destroyInterface()
|
||||||
if Game.gameUi then
|
if Game.gameUi then
|
||||||
Game.gameUi:destroy()
|
Game.gameUi:destroy()
|
||||||
Game.gameUi = nil
|
Game.gameUi = nil
|
||||||
end
|
end
|
||||||
|
Background.show()
|
||||||
|
CharacterList.show()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Game.show()
|
function Game.show()
|
||||||
|
@ -42,12 +45,6 @@ function Game.hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- hooked events
|
-- hooked events
|
||||||
function Game.onLogin()
|
|
||||||
Background.hide()
|
|
||||||
CharacterList.destroyLoadBox()
|
|
||||||
Game.show()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Game.onLoginError(message)
|
function Game.onLoginError(message)
|
||||||
CharacterList.destroyLoadBox()
|
CharacterList.destroyLoadBox()
|
||||||
local errorBox = displayErrorBox("Login Error", "Login error: " .. message)
|
local errorBox = displayErrorBox("Login Error", "Login error: " .. message)
|
||||||
|
@ -60,8 +57,5 @@ function Game.onConnectionError(message)
|
||||||
errorBox.onOk = CharacterList.show
|
errorBox.onOk = CharacterList.show
|
||||||
end
|
end
|
||||||
|
|
||||||
function Game.onLogout()
|
connect(Game, { onLogin = Game.createInterface,
|
||||||
Game.hide()
|
onLogout = Game.destroyInterface })
|
||||||
Background.show()
|
|
||||||
CharacterList.show()
|
|
||||||
end
|
|
||||||
|
|
|
@ -13,7 +13,4 @@ Module
|
||||||
|
|
||||||
onLoad: |
|
onLoad: |
|
||||||
require 'game'
|
require 'game'
|
||||||
require 'textmessage'
|
|
||||||
Game.create()
|
|
||||||
Game.hide()
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -43,4 +43,7 @@ end
|
||||||
function Game.setSkill(id, level, percent)
|
function Game.setSkill(id, level, percent)
|
||||||
local skillPanel = skillWindow:getChildById('skillPanel')
|
local skillPanel = skillWindow:getChildById('skillPanel')
|
||||||
local levelLabel = skillPanel:getChildById('skillLevel' .. id)
|
local levelLabel = skillPanel:getChildById('skillLevel' .. id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
connect(Game, { onLogin = Skills.create,
|
||||||
|
onLogout = Skills.destroy })
|
|
@ -9,10 +9,6 @@ Module
|
||||||
|
|
||||||
onLoad: |
|
onLoad: |
|
||||||
require 'skills'
|
require 'skills'
|
||||||
Skills.create()
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
onUnload:
|
|
||||||
Skills.destroy()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,3 +44,6 @@ function Game.onVipStateChange(id, online)
|
||||||
|
|
||||||
label.vipOnline = online
|
label.vipOnline = online
|
||||||
end
|
end
|
||||||
|
|
||||||
|
connect(Game, { onLogin = VipList.create,
|
||||||
|
onLogout = VipList.destroy })
|
||||||
|
|
|
@ -9,10 +9,6 @@ Module
|
||||||
|
|
||||||
onLoad: |
|
onLoad: |
|
||||||
require 'viplist'
|
require 'viplist'
|
||||||
VipList.create()
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
onUnload:
|
|
||||||
VipList.destroy()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ UILineEdit::UILineEdit()
|
||||||
m_startRenderPos = 0;
|
m_startRenderPos = 0;
|
||||||
m_textHorizontalMargin = 0;
|
m_textHorizontalMargin = 0;
|
||||||
m_textHidden = false;
|
m_textHidden = false;
|
||||||
|
m_alwaysFocused = false;
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ void UILineEdit::render()
|
||||||
g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||||
|
|
||||||
// render cursor
|
// render cursor
|
||||||
if(isExplicitlyEnabled() && isActive() && m_cursorPos >= 0) {
|
if(isExplicitlyEnabled() && (isActive() || m_alwaysFocused) && m_cursorPos >= 0) {
|
||||||
assert(m_cursorPos <= textLength);
|
assert(m_cursorPos <= textLength);
|
||||||
// draw every 333ms
|
// draw every 333ms
|
||||||
const int delay = 333;
|
const int delay = 333;
|
||||||
|
@ -384,6 +385,8 @@ void UILineEdit::onStyleApply(const OTMLNodePtr& styleNode)
|
||||||
setTextHidden(node->value<bool>());
|
setTextHidden(node->value<bool>());
|
||||||
} else if(node->tag() == "text margin") {
|
} else if(node->tag() == "text margin") {
|
||||||
m_textHorizontalMargin = node->value<int>();
|
m_textHorizontalMargin = node->value<int>();
|
||||||
|
} 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)
|
void UILineEdit::onFocusChange(bool focused, Fw::FocusReason reason)
|
||||||
{
|
{
|
||||||
if(focused) {
|
if(focused && !m_alwaysFocused) {
|
||||||
if(reason == Fw::TabFocusReason)
|
if(reason == Fw::TabFocusReason)
|
||||||
setCursorPos(m_text.length());
|
setCursorPos(m_text.length());
|
||||||
else
|
else
|
||||||
|
@ -420,8 +423,10 @@ bool UILineEdit::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
||||||
else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier)
|
else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier)
|
||||||
appendText(g_platform.getClipboardText());
|
appendText(g_platform.getClipboardText());
|
||||||
else if(keyCode == Fw::KeyTab) {
|
else if(keyCode == Fw::KeyTab) {
|
||||||
if(UIWidgetPtr parent = getParent())
|
if(!m_alwaysFocused) {
|
||||||
parent->focusNextChild(Fw::TabFocusReason);
|
if(UIWidgetPtr parent = getParent())
|
||||||
|
parent->focusNextChild(Fw::TabFocusReason);
|
||||||
|
}
|
||||||
} else if(keyChar != 0)
|
} else if(keyChar != 0)
|
||||||
appendCharacter(keyChar);
|
appendCharacter(keyChar);
|
||||||
else
|
else
|
||||||
|
|
|
@ -71,6 +71,7 @@ private:
|
||||||
int m_cursorTicks;
|
int m_cursorTicks;
|
||||||
int m_textHorizontalMargin;
|
int m_textHorizontalMargin;
|
||||||
bool m_textHidden;
|
bool m_textHidden;
|
||||||
|
bool m_alwaysFocused;
|
||||||
|
|
||||||
std::vector<Rect> m_glyphsCoords;
|
std::vector<Rect> m_glyphsCoords;
|
||||||
std::vector<Rect> m_glyphsTexCoords;
|
std::vector<Rect> m_glyphsTexCoords;
|
||||||
|
|
|
@ -63,9 +63,13 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindClassStaticFunction<Game>("logout", std::bind(&Game::logout, &g_game, _1));
|
g_lua.bindClassStaticFunction<Game>("logout", std::bind(&Game::logout, &g_game, _1));
|
||||||
g_lua.bindClassStaticFunction<Game>("cancelLogin", std::bind(&Game::cancelLogin, &g_game));
|
g_lua.bindClassStaticFunction<Game>("cancelLogin", std::bind(&Game::cancelLogin, &g_game));
|
||||||
g_lua.bindClassStaticFunction<Game>("isOnline", std::bind(&Game::isOnline, &g_game));
|
g_lua.bindClassStaticFunction<Game>("isOnline", std::bind(&Game::isOnline, &g_game));
|
||||||
g_lua.bindClassStaticFunction<Game>("talkChannel", std::bind(&Game::talkChannel, &g_game, _1, _2, _3));
|
g_lua.bindClassStaticFunction<Game>("isOnline", std::bind(&Game::isOnline, &g_game));
|
||||||
g_lua.bindClassStaticFunction<Game>("talkPrivate", std::bind(&Game::talkPrivate, &g_game, _1, _2, _3));
|
|
||||||
|
|
||||||
g_lua.registerClass<UIMap, UIWidget>();
|
g_lua.registerClass<UIMap, UIWidget>();
|
||||||
g_lua.bindClassStaticFunction<UIMap>("create", &UIWidget::create<UIMap>);
|
g_lua.bindClassStaticFunction<UIMap>("create", &UIWidget::create<UIMap>);
|
||||||
|
|
||||||
|
#ifdef FORBIDDEN_FUNCTIONS
|
||||||
|
g_lua.bindClassStaticFunction<Game>("talkChannel", std::bind(&Game::talkChannel, &g_game, _1, _2, _3));
|
||||||
|
g_lua.bindClassStaticFunction<Game>("talkPrivate", std::bind(&Game::talkPrivate, &g_game, _1, _2, _3));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <otclient/core/game.h>
|
#include <otclient/core/game.h>
|
||||||
#include <framework/otml/otml.h>
|
#include <framework/otml/otml.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
#include <framework/ui/uilineedit.h>
|
||||||
|
|
||||||
void UIMap::setup()
|
void UIMap::setup()
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,8 @@ void UIMap::render()
|
||||||
|
|
||||||
bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
||||||
{
|
{
|
||||||
|
UILineEditPtr chatLineEdit = std::dynamic_pointer_cast<UILineEdit>(getParent()->recursiveGetChildById("chatLineEdit"));
|
||||||
|
|
||||||
if(keyboardModifiers == Fw::KeyboardNoModifier) {
|
if(keyboardModifiers == Fw::KeyboardNoModifier) {
|
||||||
if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) {
|
if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) {
|
||||||
g_game.walk(Otc::North);
|
g_game.walk(Otc::North);
|
||||||
|
@ -71,6 +74,28 @@ bool UIMap::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
||||||
} else if(keyCode == Fw::KeyNumpad7) {
|
} else if(keyCode == Fw::KeyNumpad7) {
|
||||||
g_game.walk(Otc::NorthWest);
|
g_game.walk(Otc::NorthWest);
|
||||||
return true;
|
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) {
|
} else if(keyboardModifiers == Fw::KeyboardCtrlModifier) {
|
||||||
if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) {
|
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);
|
g_game.turn(Otc::West);
|
||||||
return true;
|
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);
|
return UIWidget::onKeyPress(keyCode, keyChar, keyboardModifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue