mirror of
https://github.com/edubart/otclient.git
synced 2025-04-30 17:49:21 +02:00

When trying to logout in battle the player would not logout and tryLogin would be called, so the next time you tryed to login it will still be trying to login
355 lines
9.6 KiB
Lua
355 lines
9.6 KiB
Lua
CharacterList = { }
|
|
|
|
-- private variables
|
|
local charactersWindow
|
|
local loadBox
|
|
local characterList
|
|
local errorBox
|
|
local waitingWindow
|
|
local updateWaitEvent
|
|
local resendWaitEvent
|
|
local loginEvent
|
|
|
|
-- private functions
|
|
local function tryLogin(charInfo, tries)
|
|
tries = tries or 1
|
|
|
|
if tries > 50 then
|
|
return
|
|
end
|
|
|
|
if g_game.isOnline() then
|
|
if tries == 1 then
|
|
g_game.safeLogout()
|
|
end
|
|
loginEvent = scheduleEvent(function() tryLogin(charInfo, tries+1) end, 100)
|
|
return
|
|
end
|
|
|
|
CharacterList.hide()
|
|
|
|
g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName, G.authenticatorToken, G.sessionKey)
|
|
|
|
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
|
|
connect(loadBox, { onCancel = function()
|
|
loadBox = nil
|
|
g_game.cancelLogin()
|
|
CharacterList.show()
|
|
end })
|
|
|
|
-- save last used character
|
|
g_settings.set('last-used-character', charInfo.characterName)
|
|
g_settings.set('last-used-world', charInfo.worldName)
|
|
end
|
|
|
|
local function updateWait(timeStart, timeEnd)
|
|
if waitingWindow then
|
|
local time = g_clock.seconds()
|
|
if time <= timeEnd then
|
|
local percent = ((time - timeStart) / (timeEnd - timeStart)) * 100
|
|
local timeStr = string.format("%.0f", timeEnd - time)
|
|
|
|
local progressBar = waitingWindow:getChildById('progressBar')
|
|
progressBar:setPercent(percent)
|
|
|
|
local label = waitingWindow:getChildById('timeLabel')
|
|
label:setText(tr('Trying to reconnect in %s seconds.', timeStr))
|
|
|
|
updateWaitEvent = scheduleEvent(function() updateWait(timeStart, timeEnd) end, 1000 * progressBar:getPercentPixels() / 100 * (timeEnd - timeStart))
|
|
return true
|
|
end
|
|
end
|
|
|
|
if updateWaitEvent then
|
|
updateWaitEvent:cancel()
|
|
updateWaitEvent = nil
|
|
end
|
|
end
|
|
|
|
local function resendWait()
|
|
if waitingWindow then
|
|
waitingWindow:destroy()
|
|
waitingWindow = nil
|
|
|
|
if updateWaitEvent then
|
|
updateWaitEvent:cancel()
|
|
updateWaitEvent = nil
|
|
end
|
|
|
|
if charactersWindow then
|
|
local selected = characterList:getFocusedChild()
|
|
if selected then
|
|
local charInfo = { worldHost = selected.worldHost,
|
|
worldPort = selected.worldPort,
|
|
worldName = selected.worldName,
|
|
characterName = selected.characterName }
|
|
tryLogin(charInfo)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function onLoginWait(message, time)
|
|
CharacterList.destroyLoadBox()
|
|
|
|
waitingWindow = g_ui.displayUI('waitinglist')
|
|
|
|
local label = waitingWindow:getChildById('infoLabel')
|
|
label:setText(message)
|
|
|
|
updateWaitEvent = scheduleEvent(function() updateWait(g_clock.seconds(), g_clock.seconds() + time) end, 0)
|
|
resendWaitEvent = scheduleEvent(resendWait, time * 1000)
|
|
end
|
|
|
|
function onGameLoginError(message)
|
|
CharacterList.destroyLoadBox()
|
|
errorBox = displayErrorBox(tr("Login Error"), message)
|
|
errorBox.onOk = function()
|
|
errorBox = nil
|
|
CharacterList.showAgain()
|
|
end
|
|
end
|
|
|
|
function onGameLoginToken(unknown)
|
|
CharacterList.destroyLoadBox()
|
|
-- TODO: make it possible to enter a new token here / prompt token
|
|
errorBox = displayErrorBox(tr("Two-Factor Authentification"), 'A new authentification token is required.\nPlease login again.')
|
|
errorBox.onOk = function()
|
|
errorBox = nil
|
|
EnterGame.show()
|
|
end
|
|
end
|
|
|
|
function onGameConnectionError(message, code)
|
|
CharacterList.destroyLoadBox()
|
|
local text = translateNetworkError(code, g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting(), message)
|
|
errorBox = displayErrorBox(tr("Connection Error"), text)
|
|
errorBox.onOk = function()
|
|
errorBox = nil
|
|
CharacterList.showAgain()
|
|
end
|
|
end
|
|
|
|
function onGameUpdateNeeded(signature)
|
|
CharacterList.destroyLoadBox()
|
|
errorBox = displayErrorBox(tr("Update needed"), tr('Enter with your account again to update your client.'))
|
|
errorBox.onOk = function()
|
|
errorBox = nil
|
|
CharacterList.showAgain()
|
|
end
|
|
end
|
|
|
|
-- public functions
|
|
function CharacterList.init()
|
|
connect(g_game, { onLoginError = onGameLoginError })
|
|
connect(g_game, { onLoginToken = onGameLoginToken })
|
|
connect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
|
|
connect(g_game, { onConnectionError = onGameConnectionError })
|
|
connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
|
|
connect(g_game, { onLoginWait = onLoginWait })
|
|
connect(g_game, { onGameEnd = CharacterList.showAgain })
|
|
|
|
if G.characters then
|
|
CharacterList.create(G.characters, G.characterAccount)
|
|
end
|
|
end
|
|
|
|
function CharacterList.terminate()
|
|
disconnect(g_game, { onLoginError = onGameLoginError })
|
|
disconnect(g_game, { onLoginToken = onGameLoginToken })
|
|
disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
|
|
disconnect(g_game, { onConnectionError = onGameConnectionError })
|
|
disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox })
|
|
disconnect(g_game, { onLoginWait = onLoginWait })
|
|
disconnect(g_game, { onGameEnd = CharacterList.showAgain })
|
|
|
|
if charactersWindow then
|
|
characterList = nil
|
|
charactersWindow:destroy()
|
|
charactersWindow = nil
|
|
end
|
|
|
|
if loadBox then
|
|
g_game.cancelLogin()
|
|
loadBox:destroy()
|
|
loadBox = nil
|
|
end
|
|
|
|
if waitingWindow then
|
|
waitingWindow:destroy()
|
|
waitingWindow = nil
|
|
end
|
|
|
|
if updateWaitEvent then
|
|
removeEvent(updateWaitEvent)
|
|
updateWaitEvent = nil
|
|
end
|
|
|
|
if resendWaitEvent then
|
|
removeEvent(resendWaitEvent)
|
|
resendWaitEvent = nil
|
|
end
|
|
|
|
if loginEvent then
|
|
removeEvent(loginEvent)
|
|
loginEvent = nil
|
|
end
|
|
|
|
CharacterList = nil
|
|
end
|
|
|
|
function CharacterList.create(characters, account, otui)
|
|
if not otui then otui = 'characterlist' end
|
|
|
|
if charactersWindow then
|
|
charactersWindow:destroy()
|
|
end
|
|
|
|
charactersWindow = g_ui.displayUI(otui)
|
|
characterList = charactersWindow:getChildById('characters')
|
|
|
|
-- characters
|
|
G.characters = characters
|
|
G.characterAccount = account
|
|
|
|
characterList:destroyChildren()
|
|
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
|
|
|
|
local focusLabel
|
|
for i,characterInfo in ipairs(characters) do
|
|
local widget = g_ui.createWidget('CharacterWidget', characterList)
|
|
for key,value in pairs(characterInfo) do
|
|
local subWidget = widget:getChildById(key)
|
|
if subWidget then
|
|
if key == 'outfit' then -- it's an exception
|
|
subWidget:setOutfit(value)
|
|
else
|
|
local text = value
|
|
if subWidget.baseText and subWidget.baseTranslate then
|
|
text = tr(subWidget.baseText, text)
|
|
elseif subWidget.baseText then
|
|
text = string.format(subWidget.baseText, text)
|
|
end
|
|
subWidget:setText(text)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- these are used by login
|
|
widget.characterName = characterInfo.name
|
|
widget.worldName = characterInfo.worldName
|
|
widget.worldHost = characterInfo.worldIp
|
|
widget.worldPort = characterInfo.worldPort
|
|
|
|
connect(widget, { onDoubleClick = function () CharacterList.doLogin() return true end } )
|
|
|
|
if i == 1 or (g_settings.get('last-used-character') == widget.characterName and g_settings.get('last-used-world') == widget.worldName) then
|
|
focusLabel = widget
|
|
end
|
|
end
|
|
|
|
if focusLabel then
|
|
characterList:focusChild(focusLabel, KeyboardFocusReason)
|
|
addEvent(function() characterList:ensureChildVisible(focusLabel) end)
|
|
end
|
|
|
|
-- account
|
|
if account.premDays > 0 and account.premDays < 65535 then
|
|
accountStatusLabel:setText(tr("Premium Account (%s) days left", account.premDays))
|
|
elseif account.premDays >= 65535 then
|
|
accountStatusLabel:setText(tr("Lifetime Premium Account"))
|
|
else
|
|
accountStatusLabel:setText(tr('Free Account'))
|
|
end
|
|
|
|
if account.premDays > 0 and account.premDays <= 7 then
|
|
accountStatusLabel:setOn(true)
|
|
else
|
|
accountStatusLabel:setOn(false)
|
|
end
|
|
end
|
|
|
|
function CharacterList.destroy()
|
|
CharacterList.hide(true)
|
|
|
|
if charactersWindow then
|
|
characterList = nil
|
|
charactersWindow:destroy()
|
|
charactersWindow = nil
|
|
end
|
|
end
|
|
|
|
function CharacterList.show()
|
|
if loadBox or errorBox or not charactersWindow then return end
|
|
charactersWindow:show()
|
|
charactersWindow:raise()
|
|
charactersWindow:focus()
|
|
end
|
|
|
|
function CharacterList.hide(showLogin)
|
|
showLogin = showLogin or false
|
|
charactersWindow:hide()
|
|
|
|
if showLogin and EnterGame and not g_game.isOnline() then
|
|
EnterGame.show()
|
|
end
|
|
end
|
|
|
|
function CharacterList.showAgain()
|
|
if characterList and characterList:hasChildren() then
|
|
CharacterList.show()
|
|
end
|
|
end
|
|
|
|
function CharacterList.isVisible()
|
|
if charactersWindow and charactersWindow:isVisible() then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function CharacterList.doLogin()
|
|
local selected = characterList:getFocusedChild()
|
|
if selected then
|
|
local charInfo = { worldHost = selected.worldHost,
|
|
worldPort = selected.worldPort,
|
|
worldName = selected.worldName,
|
|
characterName = selected.characterName }
|
|
charactersWindow:hide()
|
|
if loginEvent then
|
|
removeEvent(loginEvent)
|
|
loginEvent = nil
|
|
end
|
|
tryLogin(charInfo)
|
|
else
|
|
displayErrorBox(tr('Error'), tr('You must select a character to login!'))
|
|
end
|
|
end
|
|
|
|
function CharacterList.destroyLoadBox()
|
|
if loadBox then
|
|
loadBox:destroy()
|
|
loadBox = nil
|
|
end
|
|
end
|
|
|
|
function CharacterList.cancelWait()
|
|
if waitingWindow then
|
|
waitingWindow:destroy()
|
|
waitingWindow = nil
|
|
end
|
|
|
|
if updateWaitEvent then
|
|
removeEvent(updateWaitEvent)
|
|
updateWaitEvent = nil
|
|
end
|
|
|
|
if resendWaitEvent then
|
|
removeEvent(resendWaitEvent)
|
|
resendWaitEvent = nil
|
|
end
|
|
|
|
CharacterList.destroyLoadBox()
|
|
CharacterList.showAgain()
|
|
end
|