login/logout/ctrl+g working correctly

master
Eduardo Bart 13 years ago
parent 8b2cb410c2
commit f41fd0576c

@ -1,3 +1,6 @@
-- private variables
local showCharacterListOnLogout = true
-- private functions -- private functions
local function onGameKeyPress(self, keyCode, keyChar, keyboardModifiers) local function onGameKeyPress(self, keyCode, keyChar, keyboardModifiers)
if keyboardModifiers == KeyboardCtrlModifier then if keyboardModifiers == KeyboardCtrlModifier then
@ -22,14 +25,28 @@ local function destroyMainInterface()
end end
end end
-- public functions
function Game.onLogin() function Game.onLogin()
MainMenu.hide() MainMenu.hide()
CharacterList.destroyLoadBox() CharacterList.destroyLoadBox()
createMainInterface() createMainInterface()
end end
function Game.onConnectionError(message)
CharacterList.destroyLoadBox()
local errorBox = displayErrorBox("Login Error", "Connection error: " .. message)
errorBox.onOk = CharacterList.show
showCharacterListOnLogout = false
end
function Game.onLogout() function Game.onLogout()
MainMenu.show() MainMenu.show()
CharacterList.show()
if showCharacterListOnLogout then
CharacterList.show()
else
showCharacterListOnLogout = true
end
destroyMainInterface() destroyMainInterface()
end end

@ -17,6 +17,27 @@ local function onCharactersWindowKeyPress(self, keyCode, keyChar, keyboardModifi
return false return false
end end
local function tryLogin(charInfo)
CharacterList.hide()
if Game.isOnline() then
Game.logout()
scheduleEvent(function() tryLogin(charInfo) end, 250)
return
end
Game.loginWorld(EnterGame.account, EnterGame.password, charInfo.worldHost, charInfo.worldPort, charInfo.characterName)
loadBox = displayCancelBox('Please wait', 'Connecting to game server...')
function loadBox.onCancel()
Game.cancelLogin()
CharacterList.show()
end
-- save last used character
Configs.set('lastUsedCharacter', charInfo.characterName)
end
-- public functions -- public functions
function CharacterList.create(characters, premDays) function CharacterList.create(characters, premDays)
if charactersWindow then if charactersWindow then
@ -65,21 +86,10 @@ end
function CharacterList.doLogin() function CharacterList.doLogin()
local selected = charactersWindow:getChildById('characterList'):getFocusedChild() local selected = charactersWindow:getChildById('characterList'):getFocusedChild()
if selected then if selected then
--if Game.isOnline() then local charInfo = { worldHost = selected.worldHost,
-- Game.logout() worldPort = selected.worldPort,
--end characterName = selected.characterName }
tryLogin(charInfo)
Game.loginWorld(EnterGame.account, EnterGame.password, selected.worldHost, selected.worldPort, selected.characterName)
CharacterList.hide()
loadBox = displayCancelBox('Please wait', 'Connecting to game server...')
function loadBox.onCancel()
Game.logout()
CharacterList.show()
end
-- save last used character
Configs.set('lastUsedCharacter', selected.characterName)
else else
displayErrorBox('Error', 'You must select a character to login!') displayErrorBox('Error', 'You must select a character to login!')
end end

@ -34,6 +34,7 @@ Connection::Connection() :
m_socket(g_ioService) m_socket(g_ioService)
{ {
m_connected = false; m_connected = false;
m_connecting = false;
} }
void Connection::poll() void Connection::poll()
@ -50,6 +51,7 @@ void Connection::terminate()
void Connection::connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback) void Connection::connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback)
{ {
m_connected = false; m_connected = false;
m_connecting = true;
m_connectCallback = connectCallback; m_connectCallback = connectCallback;
asio::ip::tcp::resolver::query query(host, Fw::unsafeCast<std::string>(port)); asio::ip::tcp::resolver::query query(host, Fw::unsafeCast<std::string>(port));
@ -61,22 +63,23 @@ void Connection::connect(const std::string& host, uint16 port, const SimpleCallb
void Connection::close() void Connection::close()
{ {
if(!m_connected) if(!m_connected && !m_connecting)
return; return;
m_connecting = false;
m_connected = false; m_connected = false;
m_connectCallback = nullptr;
m_errorCallback = nullptr;
m_recvCallback = nullptr;
m_readTimer.cancel(); m_readTimer.cancel();
m_writeTimer.cancel(); m_writeTimer.cancel();
if(m_socket.is_open()) { if(m_socket.is_open()) {
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both); boost::system::error_code ec;
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
m_socket.close(); m_socket.close();
} }
m_connectCallback = nullptr;
m_errorCallback = nullptr;
m_recvCallback = nullptr;
} }
void Connection::write(uint8* buffer, uint16 size) void Connection::write(uint8* buffer, uint16 size)
@ -129,9 +132,10 @@ void Connection::onConnect(const boost::system::error_code& error)
{ {
m_readTimer.cancel(); m_readTimer.cancel();
m_connected = true; m_connecting = false;
if(!error) { if(!error) {
m_connected = true;
if(m_connectCallback) if(m_connectCallback)
g_dispatcher.addEvent(m_connectCallback); g_dispatcher.addEvent(m_connectCallback);
} else } else
@ -174,7 +178,7 @@ void Connection::handleError(const boost::system::error_code& error)
if(error != asio::error::operation_aborted) { if(error != asio::error::operation_aborted) {
if(m_errorCallback) if(m_errorCallback)
g_dispatcher.addEvent(std::bind(m_errorCallback, error)); g_dispatcher.addEvent(std::bind(m_errorCallback, error));
if(m_connected) if(m_connected || m_connecting)
close(); close();
} }
} }

@ -51,6 +51,7 @@ public:
void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; } void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; }
bool isConnecting() const { return m_connecting; }
bool isConnected() const { return m_connected; } bool isConnected() const { return m_connected; }
private: private:
@ -73,6 +74,7 @@ private:
uint8 m_recvBuffer[65538]; uint8 m_recvBuffer[65538];
uint16 m_recvSize; uint16 m_recvSize;
bool m_connected; bool m_connected;
bool m_connecting;
}; };
#endif #endif

@ -44,6 +44,20 @@ void Protocol::disconnect()
} }
} }
bool Protocol::isConnected()
{
if(m_connection && m_connection->isConnected())
return true;
return false;
}
bool Protocol::isConnecting()
{
if(m_connection && m_connection->isConnecting())
return true;
return false;
}
void Protocol::send(OutputMessage& outputMessage) void Protocol::send(OutputMessage& outputMessage)
{ {
// encrypt // encrypt

@ -37,6 +37,9 @@ public:
void connect(const std::string& host, uint16 port); void connect(const std::string& host, uint16 port);
void disconnect(); void disconnect();
bool isConnected();
bool isConnecting();
void send(OutputMessage& outputMessage); void send(OutputMessage& outputMessage);
void recv(); void recv();

@ -374,8 +374,7 @@ void UIWidget::insertChild(int index, const UIWidgetPtr& child)
void UIWidget::removeChild(const UIWidgetPtr& child) void UIWidget::removeChild(const UIWidgetPtr& child)
{ {
// remove from children list // remove from children list
auto it = std::find(m_children.begin(), m_children.end(), child); if(hasChild(child)) {
if(it != m_children.end()) {
// defocus if needed // defocus if needed
bool focusAnother = false; bool focusAnother = false;
if(m_focusedChild == child) { if(m_focusedChild == child) {
@ -383,9 +382,10 @@ void UIWidget::removeChild(const UIWidgetPtr& child)
focusAnother = true; focusAnother = true;
} }
// unlock child if it was locked if(isChildLocked(child))
unlockChild(child); unlockChild(child);
auto it = std::find(m_children.begin(), m_children.end(), child);
m_children.erase(it); m_children.erase(it);
// reset child parent // reset child parent
@ -397,7 +397,7 @@ void UIWidget::removeChild(const UIWidgetPtr& child)
// update child states // update child states
child->updateStates(); child->updateStates();
if(focusAnother) if(focusAnother && !m_focusedChild)
focusPreviousChild(Fw::ActiveFocusReason); focusPreviousChild(Fw::ActiveFocusReason);
} else } else
logError("attempt to remove an unknown child from a UIWidget"); logError("attempt to remove an unknown child from a UIWidget");
@ -474,7 +474,8 @@ void UIWidget::lockChild(const UIWidgetPtr& child)
assert(hasChild(child)); assert(hasChild(child));
// prevent double locks // prevent double locks
unlockChild(child); if(isChildLocked(child))
unlockChild(child);
// disable all other children // disable all other children
for(const UIWidgetPtr& otherChild : m_children) { for(const UIWidgetPtr& otherChild : m_children) {
@ -488,7 +489,7 @@ void UIWidget::lockChild(const UIWidgetPtr& child)
// lock child focus // lock child focus
if(child->isFocusable()) if(child->isFocusable())
focusChild(child, Fw::ActiveFocusReason); focusChild(child, Fw::ActiveFocusReason);
moveChildToTop(child); moveChildToTop(child);
} }
@ -506,10 +507,12 @@ void UIWidget::unlockChild(const UIWidgetPtr& child)
m_lockedChildren.erase(it); m_lockedChildren.erase(it);
// find new chick to lock // find new child to lock
UIWidgetPtr lockedChild; UIWidgetPtr lockedChild;
if(m_lockedChildren.size() > 0) if(m_lockedChildren.size() > 0) {
lockedChild = m_lockedChildren.front(); lockedChild = m_lockedChildren.front();
assert(hasChild(lockedChild));
}
for(const UIWidgetPtr& otherChild : m_children) { for(const UIWidgetPtr& otherChild : m_children) {
// lock new child // lock new child
@ -523,6 +526,19 @@ void UIWidget::unlockChild(const UIWidgetPtr& child)
else else
otherChild->setEnabled(true); otherChild->setEnabled(true);
} }
if(lockedChild) {
if(lockedChild->isFocusable())
focusChild(lockedChild, Fw::ActiveFocusReason);
moveChildToTop(lockedChild);
}
}
bool UIWidget::isChildLocked(const UIWidgetPtr& child)
{
auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child);
return it != m_lockedChildren.end();
} }
void UIWidget::updateParentLayout() void UIWidget::updateParentLayout()

@ -135,6 +135,7 @@ public:
void moveChildToTop(const UIWidgetPtr& child); void moveChildToTop(const UIWidgetPtr& child);
void lockChild(const UIWidgetPtr& child); void lockChild(const UIWidgetPtr& child);
void unlockChild(const UIWidgetPtr& child); void unlockChild(const UIWidgetPtr& child);
bool isChildLocked(const UIWidgetPtr& child);
void updateParentLayout(); void updateParentLayout();
void updateLayout(); void updateLayout();

@ -43,26 +43,52 @@ void Game::loginWorld(const std::string& account, const std::string& password, c
m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName); m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName);
} }
void Game::cancelLogin()
{
if(m_protocolGame->isConnected()) {
logout();
} else if(m_protocolGame->isConnecting()) {
m_protocolGame->disconnect();
m_protocolGame.reset();
}
}
void Game::logout() void Game::logout()
{ {
m_protocolGame->sendLogout(); m_protocolGame->sendLogout();
processLogout(); }
void Game::processConnectionError(const boost::system::error_code& error)
{
// connection errors only have meaning if we still have a protocol
if(m_protocolGame) {
g_lua.callGlobalField("Game", "onConnectionError", error.message());
if(m_online)
processLogout();
// disconnect isn't needed, we are already disconnected
m_protocolGame.reset();
}
} }
void Game::processLogin(const LocalPlayerPtr& localPlayer) void Game::processLogin(const LocalPlayerPtr& localPlayer)
{ {
m_localPlayer = localPlayer; m_localPlayer = localPlayer;
m_online = true; m_online = true;
g_lua.callGlobalField("Game", "onLogin", m_localPlayer); g_lua.callGlobalField("Game", "onLogin", m_localPlayer);
} }
void Game::processLogout() void Game::processLogout()
{ {
g_lua.callGlobalField("Game", "onLogout", m_localPlayer); g_lua.callGlobalField("Game", "onLogout", m_localPlayer);
if(m_protocolGame) { if(m_protocolGame) {
m_protocolGame->disconnect(); m_protocolGame->disconnect();
m_protocolGame.reset(); m_protocolGame.reset();
} }
m_localPlayer.reset(); m_localPlayer.reset();
m_online = false; m_online = false;
} }

@ -39,6 +39,7 @@ public:
void cancelLogin(); void cancelLogin();
void logout(); void logout();
void processConnectionError(const boost::system::error_code& error);
void processLogin(const LocalPlayerPtr& localPlayer); void processLogin(const LocalPlayerPtr& localPlayer);
void processLogout(); void processLogout();

@ -70,7 +70,6 @@ void ProtocolGame::onRecv(InputMessage& inputMessage)
void ProtocolGame::onError(const boost::system::error_code& error) void ProtocolGame::onError(const boost::system::error_code& error)
{ {
// already disconnected, just fire onLogout g_game.processConnectionError(error);
g_game.processLogout();
} }

@ -61,6 +61,8 @@ void OTClient::registerLuaFunctions()
g_lua.registerClass<Game>(); g_lua.registerClass<Game>();
g_lua.bindClassStaticFunction<Game>("loginWorld", std::bind(&Game::loginWorld, &g_game, _1, _2, _3, _4, _5)); g_lua.bindClassStaticFunction<Game>("loginWorld", std::bind(&Game::loginWorld, &g_game, _1, _2, _3, _4, _5));
g_lua.bindClassStaticFunction<Game>("logout", std::bind(&Game::logout, &g_game)); g_lua.bindClassStaticFunction<Game>("logout", std::bind(&Game::logout, &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.registerClass<UIMap, UIWidget>(); g_lua.registerClass<UIMap, UIWidget>();
g_lua.bindClassStaticFunction<UIMap>("create", &UIWidget::create<UIMap>); g_lua.bindClassStaticFunction<UIMap>("create", &UIWidget::create<UIMap>);

Loading…
Cancel
Save