login/logout/ctrl+g working correctly

This commit is contained in:
Eduardo Bart 2011-08-29 15:38:01 -03:00
parent 8b2cb410c2
commit f41fd0576c
12 changed files with 131 additions and 36 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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