-- OT-MMO (22-oct): «Crear cuenta» reescrita sobre los componentes base (antes: la de MyAAC/Tibia con mundos, -- banners y tooltips grises). Mismas peticiones a server/cuentas (checkemail, checkpassword) y mismo flujo: -- «Siguiente» abre CrearPersonaje en modo 'cuenta', que es quien manda createaccountandcharacter. -- Funciones globales que usa el resto del módulo: createWidgetAccount, destroyCreateAccount, toggleCreateAccount, -- onClickStartPlaying (entergame.otui y entergame.lua). local ventana = nil local valido = { email = false, password = false, repetir = false } local pendiente = {} -- Espejo de los tokens de data/styles/0-vars.otui (Lua no lee $otmmo-*) local OK, BORDE, TEXTO, TEXTO2 = '#52A674', '#39444C', '#E2E5E6', '#9AA7AE' local ESPERA = 500 -- ms entre teclas antes de preguntar al servidor (CHECK_LIMIT de cuentas.py) local function post(cuerpo, callback) HTTP.post(Services.createAccount, json.encode(cuerpo), function(message, err) local parte = not err and message and message:match('{.*}') local ok, r = pcall(json.decode, parte or '') callback(ok and type(r) == 'table' and r or nil) end, false) end local function actualizarBoton() if not ventana then return end ventana.siguiente:setEnabled(valido.email and valido.password and valido.repetir and ventana.reglas:isChecked()) end -- Error de un campo: borde hp ($on del GameInput) y texto debajo. mensaje nil = sin error. local function errorDe(campo, etiqueta, mensaje) campo:setOn(mensaje ~= nil) etiqueta:setText(mensaje or '') etiqueta:setVisible(mensaje ~= nil) end local function tras(clave, fn) if pendiente[clave] then removeEvent(pendiente[clave]) end pendiente[clave] = scheduleEvent(function() pendiente[clave] = nil if ventana then fn() end end, ESPERA) end local function pintarRequisitos(reqs) for _, fila in ipairs(ventana.requisitos:getChildren()) do local cumple = reqs and reqs[fila:getId()] == true fila:getChildById('punto'):setBackgroundColor(cumple and OK or BORDE) fila:getChildById('texto'):setColor(cumple and TEXTO or TEXTO2) end end local function revisarRepetir() local a, b = ventana.password:getText(), ventana.repetir:getText() valido.repetir = #b > 0 and a == b errorDe(ventana.repetir, ventana.repetirError, (#b > 0 and a ~= b) and tr('Las contraseñas no coinciden.') or nil) actualizarBoton() end local function conectar() ventana.email.onTextChange = function(_, texto) valido.email = false errorDe(ventana.email, ventana.emailError, nil) actualizarBoton() if #texto == 0 then return end tras('email', function() post({ type = 'checkemail', Email = texto }, function(r) if not ventana or ventana.email:getText() ~= texto then return end if not r then errorDe(ventana.email, ventana.emailError, tr('No se pudo contactar al servidor.')) return end valido.email = r.IsValid == true errorDe(ventana.email, ventana.emailError, not valido.email and (r.errorMessage or tr('Email no válido.')) or nil) actualizarBoton() end) end) end ventana.password.onTextChange = function(_, texto) valido.password = false ventana.password:setOn(false) revisarRepetir() if #texto == 0 then pintarRequisitos(nil) return end tras('password', function() post({ type = 'checkpassword', Password1 = texto }, function(r) if not ventana or ventana.password:getText() ~= texto or not r then return end pintarRequisitos(r.PasswordRequirements) valido.password = r.PasswordValid == true actualizarBoton() end) end) end ventana.repetir.onTextChange = revisarRepetir ventana.reglas.onCheckChange = actualizarBoton end function createWidgetAccount() if not ventana then ventana = g_ui.displayUI('createAccount') valido = { email = false, password = false, repetir = false } for _, fila in ipairs(ventana.requisitos:getChildren()) do fila:getChildById('texto'):setText(fila.etiqueta) end conectar() end EnterGame.hide() ventana:show() ventana:raise() ventana.email:focus() ensableBtnCreateNewAccount() end function destroyCreateAccount() for clave, ev in pairs(pendiente) do removeEvent(ev) pendiente[clave] = nil end if ventana then ventana:destroy() ventana = nil end end -- true = volver a «Iniciar sesión» function toggleCreateAccount(volver) if volver then destroyCreateAccount() EnterGame.show() else createWidgetAccount() end end -- «Siguiente»: lleva a la pantalla completa de crear personaje; ella manda createaccountandcharacter. function onClickStartPlaying() if not ventana or not ventana.siguiente:isEnabled() then return end local email, clave = ventana.email:getText():trim():lower(), ventana.password:getText() ventana:hide() CrearPersonaje.abrir({ modo = 'cuenta', email = email, password = clave, alVolver = function() if ventana then ventana:show() ventana:raise() end end, alCrear = function() EnterGame.setAccountName(g_crypt.encrypt(email)) EnterGame.setPassword(g_crypt.encrypt(clave)) destroyCreateAccount() EnterGame.doLogin() end, }) end