Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3553,9 +3553,10 @@ function LoginHttp.create() end
---@param port integer
---@param email string
---@param password string
---@param token string
---@param requestId integer
---@param httpLogin boolean
function LoginHttp:httpLogin(host, path, port, email, password, requestId, httpLogin) end
function LoginHttp:httpLogin(host, path, port, email, password, token, requestId, httpLogin) end

--------------------------------
------------ g_http ------------
Expand Down
61 changes: 59 additions & 2 deletions modules/client_entergame/entergame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,39 @@ local function onError(protocol, message, errorCode)
})
end

local function onTokenRequired(protocol)
if loadBox then
loadBox:destroy()
loadBox = nil
end

local function promptForToken()
displayInputBox(
tr('Authenticator Required'),
tr('Please enter your authenticator token:'),
function(text)
local token = text and text:trim() or ''
G.authenticatorToken = token

local tokenEdit = enterGame and enterGame:getChildById('authenticatorTokenTextEdit')
if tokenEdit then
tokenEdit:setText(token)
end

EnterGame.doLogin()
end,
function()
G.authenticatorToken = ''
EnterGame.show()
end,
G.authenticatorToken or '',
8
)
end

promptForToken()
end

local function onMotd(protocol, motd)
G.motdNumber = tonumber(motd:sub(0, motd:find('\n')))
G.motdMessage = motd:sub(motd:find('\n') + 1, #motd)
Expand Down Expand Up @@ -462,6 +495,12 @@ function EnterGame.show()
return
end

local tokenEdit = enterGame and enterGame:getChildById('authenticatorTokenTextEdit')
if tokenEdit then
tokenEdit:setText('')
end
G.authenticatorToken = ''

enterGame:show()
enterGame:raise()
enterGame:focus()
Expand Down Expand Up @@ -633,7 +672,7 @@ function EnterGame.tryHttpLogin(clientVersion, httpLogin)
G.requestId = math.random(1)

local http = LoginHttp.create()
http:httpLogin(host, path, G.port, G.account, G.password, G.requestId, httpLogin)
http:httpLogin(host, path, G.port, G.account, G.password, G.authenticatorToken or '', G.requestId, httpLogin)
connect(loadBox, {
onCancel = function(msgbox)
loadBox = nil
Expand Down Expand Up @@ -716,17 +755,34 @@ function EnterGame.loginFailed(requestId, msg, result)
if G.requestId ~= requestId then
return
end

local shouldRequestToken = false

if msg then
local lowerMsg = msg:lower()
if lowerMsg:find('two%-factor') then
shouldRequestToken = true
end
end

if shouldRequestToken then
G.authenticatorToken = ''
onTokenRequired(nil)
else
onError(nil, msg, result)
end
end

function EnterGame.doLogin()
G.account = enterGame:getChildById('accountNameTextEdit'):getText()
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
G.authenticatorToken = enterGame:getChildById('authenticatorTokenTextEdit'):getText()
local initialToken = enterGame:getChildById('authenticatorTokenTextEdit'):getText()
G.authenticatorToken = initialToken and initialToken:trim() or ''
G.stayLogged = enterGame:getChildById('stayLoggedBox'):isChecked()
G.host = enterGame:getChildById('serverHostTextEdit'):getText()
G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText())
local clientVersion = tonumber(clientBox:getText())
G.clientVersion = clientVersion
local httpLogin = enterGame:getChildById('httpLoginBox'):isChecked()
EnterGame.hide()

Expand All @@ -751,6 +807,7 @@ function EnterGame.doLogin()
protocolLogin.onSessionKey = onSessionKey
protocolLogin.onCharacterList = onCharacterList
protocolLogin.onUpdateNeeded = onUpdateNeeded
protocolLogin.onTokenRequired = onTokenRequired

loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to login server...'))
connect(loadBox, {
Expand Down
30 changes: 30 additions & 0 deletions modules/corelib/ui/uiinputbox.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,33 @@ function displayNumberInputBox(title, label, okCallback, cancelCallback, min, ma
inputBox:addSpinBox(label, min, max, value, step)
inputBox:display()
end

function displayInputBox(title, message, okCallback, cancelCallback, defaultText, maxLength)
local function handleOk(...)
if okCallback then
okCallback(...)
end
end

local function handleCancel()
if cancelCallback then
cancelCallback()
end
end

local inputBox = UIInputBox.create(title, handleOk, handleCancel)

if message and message ~= '' then
inputBox:addLabel(message)
end

local lineEdit = inputBox:addLineEdit(nil, defaultText, maxLength)

inputBox:display()

if lineEdit and lineEdit.focus then
lineEdit:focus()
end

return inputBox
end
3 changes: 1 addition & 2 deletions modules/gamelib/protocollogin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,8 @@ function ProtocolLogin:onRecv(msg)
elseif opcode == LoginServerTokenSuccess then
local unknown = msg:getU8()
elseif opcode == LoginServerTokenError then
-- TODO: prompt for token here
local unknown = msg:getU8()
signalcall(self.onLoginError, self, tr('Invalid authentification token.'))
signalcall(self.onTokenRequired, self)
elseif opcode == LoginServerCharacterList then
self:parseCharacterList(msg)
elseif opcode == LoginServerExtendedCharacterList then
Expand Down
1 change: 1 addition & 0 deletions src/client/protocolgamesend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void ProtocolGame::sendLoginPacket(const uint32_t challengeTimestamp, const uint
if (g_game.getFeature(Otc::GameSessionKey)) {
msg->addString(m_sessionKey);
msg->addString(m_characterName);

} else {
if (g_game.getFeature(Otc::GameAccountNames))
msg->addString(m_accountName);
Expand Down
34 changes: 24 additions & 10 deletions src/framework/net/httplogin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,17 @@ std::string LoginHttp::getSession() { return this->session; }

void LoginHttp::httpLogin(const std::string& host, const std::string& path,
uint16_t port, const std::string& email,
const std::string& password, int request_id,
bool httpLogin) {
const std::string& password, const std::string& token,
int request_id, bool httpLogin) {
#ifndef __EMSCRIPTEN__
g_asyncDispatcher.detach_task(
[this, host, path, port, email, password, request_id, httpLogin] {
[this, host, path, port, email, password, token, request_id, httpLogin] {
if (cancelled.load()) return;
httplib::Result result =
this->loginHttpsJson(host, path, port, email, password);
this->loginHttpsJson(host, path, port, email, password, token);
if (httpLogin && (!result || result->status != Success)) {
if (cancelled.load()) return;
result = loginHttpJson(host, path, port, email, password);
result = loginHttpJson(host, path, port, email, password, token);
}

if (cancelled.load()) return;
Expand Down Expand Up @@ -154,7 +154,7 @@ void LoginHttp::httpLogin(const std::string& host, const std::string& path,
});
#else
g_asyncDispatcher.detach_task(
[this, host, path, port, email, password, request_id, httpLogin] {
[this, host, path, port, email, password, token, request_id, httpLogin] {
if (cancelled.load()) return;
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
Expand All @@ -166,6 +166,10 @@ void LoginHttp::httpLogin(const std::string& host, const std::string& path,
attr.requestHeaders = headers;
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS;
json body = json{ {"email", email}, {"password", password}, {"stayloggedin", true}, {"type", "login"} };
if (!token.empty()) {
body["token"] = token;
body["authenticatorToken"] = token;
}
std::string bodyStr = body.dump(1);
attr.requestData = bodyStr.data();
attr.requestDataSize = bodyStr.length();
Expand Down Expand Up @@ -224,7 +228,8 @@ httplib::Result LoginHttp::loginHttpsJson(const std::string& host,
const std::string& path,
const uint16_t port,
const std::string& email,
const std::string& password) {
const std::string& password,
const std::string& token) {
httplib::SSLClient client(host, port);

client.set_logger(
Expand All @@ -234,7 +239,11 @@ httplib::Result LoginHttp::loginHttpsJson(const std::string& host,
client.enable_server_certificate_verification(false);
client.enable_server_hostname_verification(false);

const json body = { {"email", email}, {"password", password}, {"stayloggedin", true}, {"type", "login"} };
json body = { {"email", email}, {"password", password}, {"stayloggedin", true}, {"type", "login"} };
if (!token.empty()) {
body["token"] = token;
body["authenticatorToken"] = token;
}
const httplib::Headers headers = { {"User-Agent", "Mozilla/5.0"} };

httplib::Result response =
Expand All @@ -261,13 +270,18 @@ httplib::Result LoginHttp::loginHttpJson(const std::string& host,
const std::string& path,
const uint16_t port,
const std::string& email,
const std::string& password) {
const std::string& password,
const std::string& token) {
httplib::Client client(host, port);
client.set_logger(
[this](const auto& req, const auto& res) { LoginHttp::Logger(req, res); });

const httplib::Headers headers = { {"User-Agent", "Mozilla/5.0"} };
const json body = { {"email", email}, {"password", password}, {"stayloggedin", true}, {"type", "login"} };
json body = { {"email", email}, {"password", password}, {"stayloggedin", true}, {"type", "login"} };
if (!token.empty()) {
body["token"] = token;
body["authenticatorToken"] = token;
}

httplib::Result response =
client.Post(path, headers, body.dump(), "application/json");
Expand Down
9 changes: 6 additions & 3 deletions src/framework/net/httplogin.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,20 @@ class LoginHttp final : public LuaObject

void httpLogin(const std::string& host, const std::string& path,
uint16_t port, const std::string& email,
const std::string& password, int request_id, bool httpLogin);
const std::string& password, const std::string& token,
int request_id, bool httpLogin);

httplib::Result loginHttpsJson(const std::string& host,
const std::string& path, uint16_t port,
const std::string& email,
const std::string& password);
const std::string& password,
const std::string& token);

httplib::Result loginHttpJson(const std::string& host,
const std::string& path, uint16_t port,
const std::string& email,
const std::string& password);
const std::string& password,
const std::string& token);

void cancel();

Expand Down
Loading