Version 0.95 BETA

This commit is contained in:
OTCv8
2019-10-02 03:38:52 +02:00
parent 9219c78f15
commit 5220a3bdd2
501 changed files with 38097 additions and 2 deletions

View File

@@ -0,0 +1,373 @@
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()
-- proxies for not http login users
if charInfo.worldHost == "0.0.0.0" and g_proxy then
g_proxy.clear()
-- g_proxy.addProxy(localPort, proxyHost, proxyPort, proxyPriority)
g_proxy.addProxy(tonumber(charInfo.worldPort), "51.158.184.57", 7162, 0)
g_proxy.addProxy(tonumber(charInfo.worldPort), "54.39.190.20", 7162, 0)
g_proxy.addProxy(tonumber(charInfo.worldPort), "51.83.226.109", 7162, 0)
g_proxy.addProxy(tonumber(charInfo.worldPort), "35.247.201.100", 443, 0)
end
g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName, G.authenticatorToken, G.sessionKey)
g_logger.info("Login to " .. charInfo.worldHost .. ":" .. charInfo.worldPort)
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
local status = ''
if account.status == AccountStatus.Frozen then
status = tr(' (Frozen)')
elseif account.status == AccountStatus.Suspended then
status = tr(' (Suspended)')
end
if account.subStatus == SubscriptionStatus.Free then
accountStatusLabel:setText(('%s%s'):format(tr('Free Account'), status))
elseif account.subStatus == SubscriptionStatus.Premium then
if account.premDays == 0 or account.premDays == 65535 then
accountStatusLabel:setText(('%s%s'):format(tr('Gratis Premium Account'), status))
else
accountStatusLabel:setText(('%s%s'):format(tr('Premium Account (%s) days left', account.premDays), status))
end
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

View File

@@ -0,0 +1,134 @@
CharacterWidget < UIWidget
height: 14
background-color: alpha
&updateOnStates: |
function(self)
local children = self:getChildren()
for i=1,#children do
children[i]:setOn(self:isFocused())
end
end
@onFocusChange: self:updateOnStates()
@onSetup: self:updateOnStates()
$focus:
background-color: #ffffff22
Label
id: name
color: #bbbbbb
anchors.top: parent.top
anchors.left: parent.left
font: verdana-11px-monochrome
text-auto-resize: true
background-color: alpha
text-offset: 2 0
$on:
color: #ffffff
Label
id: worldName
color: #bbbbbb
anchors.top: parent.top
anchors.right: parent.right
margin-right: 5
font: verdana-11px-monochrome
text-auto-resize: true
background-color: alpha
&baseText: '(%s)'
$on:
color: #ffffff
StaticMainWindow
id: charactersWindow
!text: tr('Character List')
visible: false
@onEnter: CharacterList.doLogin()
@onEscape: CharacterList.hide(true)
@onSetup: |
g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self)
g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self)
if g_game.getFeature(GamePreviewState) then
self:setSize({width = 350, height = 400})
else
self:setSize({width = 250, height = 248})
end
TextList
id: characters
background-color: #565656
anchors.top: parent.top
anchors.left: parent.left
anchors.right: characterListScrollBar.left
anchors.bottom: accountStatusCaption.top
margin-bottom: 5
padding: 1
focusable: false
vertical-scrollbar: characterListScrollBar
auto-focus: first
VerticalScrollBar
id: characterListScrollBar
anchors.top: parent.top
anchors.bottom: accountStatusCaption.top
anchors.right: parent.right
margin-bottom: 5
step: 14
pixels-scroll: true
Label
id: accountStatusCaption
!text: tr('Account Status') .. ':'
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 1
Label
id: accountStatusLabel
!text: tr('Free Account')
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: separator.top
margin-bottom: 5
text-auto-resize: true
$on:
color: #FF0000
HorizontalSeparator
id: separator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 10
//CheckBox
// id: charAutoLoginBox
// !text: tr('Auto login')
// !tooltip: tr('Auto login selected character on next charlist load')
// anchors.left: parent.left
// anchors.right: parent.right
// anchors.bottom: next.top
// margin-bottom: 6
// margin-left: 18
// margin-right: 18
Button
id: buttonOk
!text: tr('Ok')
width: 64
anchors.right: next.left
anchors.bottom: parent.bottom
margin-right: 10
@onClick: CharacterList.doLogin()
Button
id: buttonCancel
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: CharacterList.hide(true)

View File

@@ -0,0 +1,495 @@
EnterGame = { }
-- private variables
local loadBox
local enterGame
local enterGameButton
local clientBox
local protocolLogin
local server = nil
local versionsFound = false
local newLogin = nil
local newLoginUrl = nil
local newLoginEvent
local customServerSelectorPanel
local serverSelectorPanel
local serverSelector
local clientVersionSelector
local serverHostTextEdit
local rememberPasswordBox
local protos = {"740", "760", "772", "800", "810", "854", "860", "1090", "1096", "1099"}
-- private functions
local function onProtocolError(protocol, message, errorCode)
if errorCode then
return EnterGame.onError(message)
end
return EnterGame.onLoginError(message)
end
local function onSessionKey(protocol, sessionKey)
G.sessionKey = sessionKey
end
local function onCharacterList(protocol, characters, account, otui)
if rememberPasswordBox:isChecked() then
local account = g_crypt.encrypt(G.account)
local password = g_crypt.encrypt(G.password)
g_settings.set('account', account)
g_settings.set('password', password)
else
EnterGame.clearAccountFields()
end
for _, characterInfo in pairs(characters) do
if characterInfo.previewState and characterInfo.previewState ~= PreviewState.Default then
characterInfo.worldName = characterInfo.worldName .. ', Preview'
end
end
if loadBox then
loadBox:destroy()
loadBox = nil
end
CharacterList.create(characters, account, otui)
CharacterList.show()
g_settings.save()
end
local function onUpdateNeeded(protocol, signature)
return EnterGame.onError(tr('Your client needs updating, try redownloading it.'))
end
local function parseFeatures(features)
for feature_id, value in pairs(features) do
if value == "1" or value == "true" or value == true then
g_game.enableFeature(feature_id)
else
g_game.disableFeature(feature_id)
end
end
end
local function validateThings(things)
local incorrectThings = ""
if things ~= nil then
local thingsNode = {}
for thingtype, thingdata in pairs(things) do
thingsNode[thingtype] = thingdata[1]
if not g_resources.fileExists("/data/things/" .. thingdata[1]) then
correctThings = false
incorrectThings = incorrectThings .. "Missing file: " .. thingdata[1] .. "\n"
end
local localChecksum = g_resources.fileChecksum("/data/things/" .. thingdata[1]):lower()
if localChecksum ~= thingdata[2]:lower() and #thingdata[2] > 1 then
if g_resources.isLoadedFromArchive() then -- ignore checksum if it's test/debug version
incorrectThings = incorrectThings .. "Invalid checksum of file: " .. thingdata[1] .. " (is " .. localChecksum .. ", should be " .. thingdata[2]:lower() .. ")\n"
end
end
end
g_settings.setNode("things", thingsNode)
else
g_settings.setNode("things", {})
end
return incorrectThings
end
local function onHTTPResult(data, err)
if err then
return EnterGame.onError(err)
end
if data['error'] and #data['error'] > 0 then
return EnterGame.onLoginError(data['error'])
end
local characters = data["characters"]
local account = data["account"]
local session = data["session"]
local version = data["version"]
local things = data["things"]
local customProtocol = data["customProtocol"]
local features = data["features"]
local settings = data["settings"]
local rsa = data["rsa"]
local proxies = data["proxies"]
local incorrectThings = validateThings(things)
if #incorrectThings > 0 then
g_logger.info(incorrectThings)
if Updater then
return Updater.updateThings(things, incorrectThings)
else
return EnterGame.onError(incorrectThings)
end
end
-- custom protocol
g_game.setCustomProtocolVersion(0)
if customProtocol ~= nil then
customProtocol = tonumber(customProtocol)
if customProtocol ~= nil and customProtocol > 0 then
g_game.setCustomProtocolVersion(customProtocol)
end
end
-- force player settings
if settings ~= nil then
for option, value in pairs(settings) do
modules.client_options.setOption(option, value, true)
end
end
-- version
G.clientVersion = version
g_game.setClientVersion(version)
g_game.setProtocolVersion(g_game.getClientProtocolVersion(version))
g_game.setCustomOs(-1) -- disable
if rsa ~= nil then
g_game.setRsa(rsa)
end
if features ~= nil then
parseFeatures(features)
end
if session ~= nil and session:len() > 0 then
onSessionKey(nil, session)
end
-- proxies
if g_proxy then
g_proxy.clear()
if proxies then
for i, proxy in ipairs(proxies) do
g_proxy.addProxy(tonumber(proxy["localPort"]), proxy["host"], tonumber(proxy["port"]), tonumber(proxy["priority"]))
end
end
end
onCharacterList(nil, characters, account, nil)
end
-- public functions
function EnterGame.init()
enterGame = g_ui.displayUI('entergame')
newLogin = g_ui.displayUI('entergame_new')
serverSelectorPanel = enterGame:getChildById('serverSelectorPanel')
customServerSelectorPanel = enterGame:getChildById('customServerSelectorPanel')
serverSelector = serverSelectorPanel:getChildById('serverSelector')
rememberPasswordBox = enterGame:getChildById('rememberPasswordBox')
serverHostTextEdit = customServerSelectorPanel:getChildById('serverHostTextEdit')
clientVersionSelector = customServerSelectorPanel:getChildById('clientVersionSelector')
if Servers ~= nil then
for name,server in pairs(Servers) do
serverSelector:addOption(name)
end
end
if serverSelector:getOptionsCount() == 0 or ALLOW_CUSTOM_SERVERS then
serverSelector:addOption(tr("Another"))
end
for i,proto in pairs(protos) do
clientVersionSelector:addOption(proto)
end
if serverSelector:getOptionsCount() == 1 then
enterGame:setHeight(enterGame:getHeight() - serverSelectorPanel:getHeight())
serverSelectorPanel:setOn(false)
end
local account = g_crypt.decrypt(g_settings.get('account'))
local password = g_crypt.decrypt(g_settings.get('password'))
local server = g_settings.get('server')
local host = g_settings.get('host')
local clientVersion = g_settings.get('client-version')
local hdSprites = g_settings.getBoolean('hdSprites', false)
if serverSelector:isOption(server) then
serverSelector:setCurrentOption(server, false)
if Servers == nil or Servers[server] == nil then
serverHostTextEdit:setText(host)
end
clientVersionSelector:setOption(clientVersion)
else
server = ""
host = ""
end
enterGame:getChildById('accountPasswordTextEdit'):setText(password)
enterGame:getChildById('accountNameTextEdit'):setText(account)
rememberPasswordBox:setChecked(#account > 0)
if enterGame.hdSprites then
enterGame.hdSprites:setChecked(hdSprites)
end
g_keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow)
if g_game.isOnline() then
return EnterGame.hide()
end
scheduleEvent(function()
EnterGame.show()
end, 100)
end
function EnterGame.terminate()
g_keyboard.unbindKeyDown('Ctrl+G')
removeEvent(newLoginEvent)
enterGame:destroy()
if newLogin then
newLogin:destroy()
end
if loadBox then
loadBox:destroy()
loadBox = nil
end
if protocolLogin then
protocolLogin:cancelLogin()
protocolLogin = nil
end
EnterGame = nil
end
function EnterGame.show()
if Updater and Updater.isVisible() or g_game.isOnline() then
return EnterGame.hide()
end
enterGame:show()
enterGame:raise()
enterGame:focus()
enterGame:getChildById('accountNameTextEdit'):focus()
EnterGame.checkNewLogin()
end
function EnterGame.hide()
enterGame:hide()
newLogin:hide()
end
function EnterGame.openWindow()
if g_game.isOnline() then
CharacterList.show()
elseif not g_game.isLogging() and not CharacterList.isVisible() then
EnterGame.show()
end
end
function EnterGame.clearAccountFields()
enterGame:getChildById('accountNameTextEdit'):clearText()
enterGame:getChildById('accountPasswordTextEdit'):clearText()
--enterGame:getChildById('authenticatorTokenTextEdit'):clearText()
enterGame:getChildById('accountNameTextEdit'):focus()
g_settings.remove('account')
g_settings.remove('password')
end
function EnterGame.hideNewLogin()
newLogin:hide()
newLoginUrl = nil
end
function EnterGame.checkNewLoginEvent()
newLoginEvent = scheduleEvent(function() EnterGame.checkNewLoginEvent() end, 1000)
EnterGame.checkNewLogin()
end
function EnterGame.checkNewLogin()
if not newLoginUrl then
return
end
local url = newLoginUrl
HTTP.postJSON(newLoginUrl, { quick = 1 }, function(data, err)
if url ~= newLoginUrl then return end
if err then return end
if not data["qrcode"] then return end
if newLogin:isHidden() then
newLogin:show()
enterGame:raise()
end
newLogin.qrcode:setImageSourceBase64(data["qrcode"])
newLogin.code:setText(data["code"])
end)
end
function EnterGame.onServerChange()
server = serverSelector:getText()
EnterGame.hideNewLogin()
if server == tr("Another") then
if not customServerSelectorPanel:isOn() then
serverHostTextEdit:setText("")
customServerSelectorPanel:setOn(true)
enterGame:setHeight(enterGame:getHeight() + customServerSelectorPanel:getHeight())
end
elseif customServerSelectorPanel:isOn() then
enterGame:setHeight(enterGame:getHeight() - customServerSelectorPanel:getHeight())
customServerSelectorPanel:setOn(false)
end
if Servers and Servers[server] ~= nil then
serverHostTextEdit:setText(Servers[server])
newLoginUrl = Servers[server]
EnterGame.checkNewLogin()
end
end
function EnterGame.doLogin()
if Updater and Updater.isVisible() then
return
end
if g_game.isOnline() then
local errorBox = displayErrorBox(tr('Login Error'), tr('Cannot login while already in game.'))
connect(errorBox, { onOk = EnterGame.show })
return
end
G.account = enterGame:getChildById('accountNameTextEdit'):getText()
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
--G.authenticatorToken = enterGame:getChildById('authenticatorTokenTextEdit'):getText()
G.authenticatorToken = ""
G.hdSprites = enterGame.hdSprites and enterGame.hdSprites:isChecked()
G.stayLogged = true
G.server = serverSelector:getText():trim()
G.host = serverHostTextEdit:getText()
G.clientVersion = tonumber(clientVersionSelector:getText())
if not rememberPasswordBox:isChecked() then
g_settings.set('account', G.account)
g_settings.set('password', G.password)
end
g_settings.set('host', G.host)
g_settings.set('server', G.server)
g_settings.set('client-version', G.clientVersion)
g_settings.set('hdSprites', G.hdSprites)
g_settings.save()
if G.host:find("http") ~= nil then
return EnterGame.doLoginHttp()
end
local server_params = G.host:split(":")
if #server_params < 2 then
return EnterGame.onError("Invalid server, it should be in format IP:PORT or it should be http url to login script")
end
local server_ip = server_params[1]
local server_port = tonumber(server_params[2])
if #server_params >= 3 then
G.clientVersion = tonumber(server_params[3])
end
if not server_port or not G.clientVersion then
return EnterGame.onError("Invalid server, it should be in format IP:PORT or it should be http url to login script")
end
local things = {
data = {G.clientVersion .. "/Tibia.dat", ""},
sprites = {G.clientVersion .. "/Tibia.spr", ""},
}
if G.hdSprites then
things.sprites_hd = {G.clientVersion .. "/Tibia_hd.spr", ""}
end
local incorrectThings = validateThings(things)
if #incorrectThings > 0 then
g_logger.info(incorrectThings)
if Updater then
return Updater.updateThings(things, incorrectThings)
else
return EnterGame.onError(incorrectThings)
end
end
protocolLogin = ProtocolLogin.create()
protocolLogin.onLoginError = onProtocolError
protocolLogin.onSessionKey = onSessionKey
protocolLogin.onCharacterList = onCharacterList
protocolLogin.onUpdateNeeded = onUpdateNeeded
EnterGame.hide()
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to login server...'))
connect(loadBox, { onCancel = function(msgbox)
loadBox = nil
protocolLogin:cancelLogin()
EnterGame.show()
end })
-- if you have custom rsa or protocol edit it here
g_game.setClientVersion(G.clientVersion)
g_game.setProtocolVersion(g_game.getClientProtocolVersion(G.clientVersion))
g_game.setCustomProtocolVersion(0)
g_game.chooseRsa(G.host)
g_game.setCustomOs(2) -- windows
-- you can add custom features here
g_game.enableFeature(GameBot)
-- proxies
if g_proxy then
g_proxy.clear()
end
if modules.game_things.isLoaded() then
g_logger.info("Connection to: " .. server_ip .. ":" .. server_port)
protocolLogin:login(server_ip, server_port, G.account, G.password, G.authenticatorToken, G.stayLogged)
else
loadBox:destroy()
loadBox = nil
EnterGame.show()
end
end
function EnterGame.doLoginHttp()
if G.host == nil or G.host:len() < 10 then
return EnterGame.onError("Invalid server url: " .. G.host)
end
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to login server...'))
connect(loadBox, { onCancel = function(msgbox)
loadBox = nil
EnterGame.show()
end })
local data = {
account = G.account,
password = G.password,
token = G.authenticatorToken,
hdSprites = G.hdSprites,
version = APP_VERSION,
uid = G.UUID
}
HTTP.postJSON(G.host, data, onHTTPResult)
EnterGame.hide()
end
function EnterGame.onError(err)
if loadBox then
loadBox:destroy()
loadBox = nil
end
local errorBox = displayErrorBox(tr('Login Error'), err)
errorBox.onOk = EnterGame.show
end
function EnterGame.onLoginError(err)
if loadBox then
loadBox:destroy()
loadBox = nil
end
local errorBox = displayErrorBox(tr('Login Error'), err)
errorBox.onOk = EnterGame.show
EnterGame.clearAccountFields()
end

View File

@@ -0,0 +1,9 @@
Module
name: client_entergame
description: Manages enter game and character list windows
author: edubart & otclient.ovh
website: https://github.com/edubart/otclient
scripts: [ entergame, characterlist ]
@onLoad: EnterGame.init() CharacterList.init()
@onUnload: EnterGame.terminate() CharacterList.terminate()

View File

@@ -0,0 +1,176 @@
EnterGameWindow < StaticMainWindow
!text: tr('Enter Game')
size: 240 310
EnterGameWindow
id: enterGame
@onEnter: EnterGame.doLogin()
MenuLabel
!text: tr('Account name')
anchors.left: parent.left
anchors.top: parent.top
text-auto-resize: true
TextEdit
id: accountNameTextEdit
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 2
MenuLabel
!text: tr('Password')
anchors.left: prev.left
anchors.top: prev.bottom
margin-top: 8
text-auto-resize: true
PasswordTextEdit
id: accountPasswordTextEdit
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 2
Panel
id: serverSelectorPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
height: 52
on: true
focusable: false
$on:
visible: true
margin-top: 0
$!on:
visible: false
margin-top: -52
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
margin-top: 10
MenuLabel
id: serverLabel
!text: tr('Server')
anchors.left: parent.left
anchors.top: prev.bottom
text-auto-resize: true
margin-top: 5
ComboBox
id: serverSelector
anchors.left: prev.left
anchors.right: parent.right
anchors.top: serverLabel.bottom
margin-top: 2
margin-right: 3
menu-scroll: true
menu-height: 125
menu-scroll-step: 25
text-offset: 5 2
@onOptionChange: EnterGame.onServerChange()
Panel
id: customServerSelectorPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
height: 52
on: true
focusable: true
$on:
visible: true
margin-top: 0
$!on:
visible: false
margin-top: -52
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
margin-top: 8
MenuLabel
id: serverLabel
!text: tr('IP:PORT or url')
anchors.left: prev.left
anchors.top: prev.bottom
margin-top: 8
text-auto-resize: true
TextEdit
id: serverHostTextEdit
!tooltip: tr('Make sure that your client uses\nthe correct game client version')
anchors.left: parent.left
anchors.top: serverLabel.bottom
margin-top: 2
width: 130
MenuLabel
id: clientLabel
!text: tr('Version')
anchors.left: serverHostTextEdit.right
anchors.top: serverLabel.top
text-auto-resize: true
margin-left: 10
ComboBox
id: clientVersionSelector
anchors.top: serverHostTextEdit.top
anchors.bottom: serverHostTextEdit.bottom
anchors.left: prev.left
anchors.right: parent.right
menu-scroll: true
menu-height: 125
menu-scroll-step: 25
margin-right: 3
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 10
CheckBox
id: rememberPasswordBox
!text: tr('Remember password')
!tooltip: tr('Remember account and password when starts client')
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 9
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 9
Button
!text: tr('Login')
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 10
margin-left: 50
margin-right: 50
@onClick: EnterGame.doLogin()
Label
id: serverInfoLabel
font: verdana-11px-rounded
anchors.top: prev.top
anchors.left: parent.left
margin-top: 5
color: green
text-auto-resize: true

View File

@@ -0,0 +1,48 @@
StaticWindow
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
margin-right: 20
id: newLoginPanel
width: 230
height: 330
!text: tr('Quick Login & Registration')
Label
id: qrcode
width: 200
height: 180
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin-top: 5
Label
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
text-align: center
text-auto-resize: true
!text: tr("Scan QR code or process\nbellow code to register or login")
height: 40
margin-top: 10
margin-bottom: 5
Label
id: code
height: 20
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
text-align: center
font: sans-bold-16px
margin-top: 10
text: XXXXXX
Label
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
text-align: center
!text: tr("Click to get Android/iOS app")
height: 20
margin-top: 10
color: #FFFFFF

View File

@@ -0,0 +1,44 @@
MainWindow
id: waitingWindow
!text: tr('Waiting List')
size: 260 180
@onEscape: CharacterList.cancelWait()
Label
id: infoLabel
anchors.top: parent.top
anchors.bottom: progressBar.top
anchors.left: parent.left
anchors.right: parent.right
text-wrap: true
ProgressBar
id: progressBar
height: 15
background-color: #4444ff
anchors.bottom: timeLabel.top
anchors.left: parent.left
anchors.right: parent.right
margin-bottom: 10
Label
id: timeLabel
anchors.bottom: separator.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-bottom: 10
HorizontalSeparator
id: separator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 10
Button
id: buttonCancel
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: CharacterList.cancelWait()