mirror of
https://github.com/minetest/minetest.git
synced 2024-11-26 17:43:45 +01:00
Add register dialog to separate login/register (#12185)
New users find Minetest's account system confusing. This change moves username/password to a new dialog, with login and register buttons added to the Join Game tab. The old registration confirmation dialog is removed in favour of the new dialog. Fixes #8138
This commit is contained in:
parent
21323ef1ff
commit
03d86ea0b4
@ -67,6 +67,12 @@ appgurueu:
|
||||
erlehmann, Warr1024, rollerozxa:
|
||||
textures/base/pack/no_screenshot.png
|
||||
|
||||
kilbith:
|
||||
textures/base/pack/server_favorite.png
|
||||
|
||||
SmallJoker
|
||||
textures/base/pack/server_favorite_delete.png (based on server_favorite.png)
|
||||
|
||||
License of Minetest source code
|
||||
-------------------------------
|
||||
|
||||
|
123
builtin/mainmenu/dlg_register.lua
Normal file
123
builtin/mainmenu/dlg_register.lua
Normal file
@ -0,0 +1,123 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2022 rubenwardy
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function register_formspec(dialogdata)
|
||||
local title = fgettext("Joining $1", dialogdata.server and dialogdata.server.name or dialogdata.address)
|
||||
local buttons_y = 4 + 1.3
|
||||
if dialogdata.error then
|
||||
buttons_y = buttons_y + 0.8
|
||||
end
|
||||
|
||||
local retval = {
|
||||
"formspec_version[4]",
|
||||
"size[8,", tostring(buttons_y + 1.175), "]",
|
||||
"set_focus[", (dialogdata.name ~= "" and "password" or "name"), "]",
|
||||
"label[0.375,0.8;", title, "]",
|
||||
"field[0.375,1.575;7.25,0.8;name;", core.formspec_escape(fgettext("Name")), ";",
|
||||
core.formspec_escape(dialogdata.name), "]",
|
||||
"pwdfield[0.375,2.875;7.25,0.8;password;", core.formspec_escape(fgettext("Password")), "]",
|
||||
"pwdfield[0.375,4.175;7.25,0.8;password_2;", core.formspec_escape(fgettext("Confirm Password")), "]"
|
||||
}
|
||||
|
||||
if dialogdata.error then
|
||||
table.insert_all(retval, {
|
||||
"box[0.375,", tostring(buttons_y - 0.9), ";7.25,0.6;darkred]",
|
||||
"label[0.625,", tostring(buttons_y - 0.6), ";", core.formspec_escape(dialogdata.error), "]",
|
||||
})
|
||||
end
|
||||
|
||||
table.insert_all(retval, {
|
||||
"container[0.375,", tostring(buttons_y), "]",
|
||||
"button[0,0;2.5,0.8;dlg_register_confirm;", fgettext("Register"), "]",
|
||||
"button[4.75,0;2.5,0.8;dlg_register_cancel;", fgettext("Cancel"), "]",
|
||||
"container_end[]",
|
||||
})
|
||||
|
||||
return table.concat(retval, "")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function register_buttonhandler(this, fields)
|
||||
this.data.name = fields.name
|
||||
this.data.error = nil
|
||||
|
||||
if fields.dlg_register_confirm or fields.key_enter then
|
||||
if fields.name == "" then
|
||||
this.data.error = fgettext("Missing name")
|
||||
return true
|
||||
end
|
||||
if fields.password ~= fields.password_2 then
|
||||
this.data.error = fgettext("Passwords do not match")
|
||||
return true
|
||||
end
|
||||
|
||||
gamedata.playername = fields.name
|
||||
gamedata.password = fields.password
|
||||
gamedata.address = this.data.address
|
||||
gamedata.port = this.data.port
|
||||
gamedata.allow_login_or_register = "register"
|
||||
gamedata.selected_world = 0
|
||||
|
||||
assert(gamedata.address and gamedata.port)
|
||||
|
||||
local server = this.data.server
|
||||
if server then
|
||||
serverlistmgr.add_favorite(server)
|
||||
gamedata.servername = server.name
|
||||
gamedata.serverdescription = server.description
|
||||
else
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
||||
serverlistmgr.add_favorite({
|
||||
address = gamedata.address,
|
||||
port = gamedata.port,
|
||||
})
|
||||
end
|
||||
|
||||
core.settings:set("name", fields.name)
|
||||
core.settings:set("address", gamedata.address)
|
||||
core.settings:set("remote_port", gamedata.port)
|
||||
|
||||
core.start()
|
||||
end
|
||||
|
||||
if fields["dlg_register_cancel"] then
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function create_register_dialog(address, port, server)
|
||||
assert(address)
|
||||
assert(type(port) == "number")
|
||||
|
||||
local retval = dialog_create("dlg_register",
|
||||
register_formspec,
|
||||
register_buttonhandler,
|
||||
nil)
|
||||
retval.data.address = address
|
||||
retval.data.port = port
|
||||
retval.data.server = server
|
||||
retval.data.name = core.settings:get("name") or ""
|
||||
return retval
|
||||
end
|
@ -17,6 +17,7 @@
|
||||
|
||||
mt_color_grey = "#AAAAAA"
|
||||
mt_color_blue = "#6389FF"
|
||||
mt_color_lightblue = "#99CCFF"
|
||||
mt_color_green = "#72FF63"
|
||||
mt_color_dark_green = "#25C191"
|
||||
mt_color_orange = "#FF8800"
|
||||
@ -43,6 +44,7 @@ dofile(menupath .. DIR_DELIM .. "dlg_contentstore.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||
|
||||
local tabs = {}
|
||||
|
@ -87,27 +87,34 @@ local function get_formspec(tabview, name, tabdata)
|
||||
"field[4.25,0.5;1.25,0.75;te_port;;" ..
|
||||
core.formspec_escape(core.settings:get("remote_port")) .. "]" ..
|
||||
|
||||
-- Name / Password
|
||||
"label[0.25,1.55;" .. fgettext("Name") .. "]" ..
|
||||
"label[3,1.55;" .. fgettext("Password") .. "]" ..
|
||||
"field[0.25,1.75;2.75,0.75;te_name;;" ..
|
||||
core.formspec_escape(core.settings:get("name")) .. "]" ..
|
||||
"pwdfield[3,1.75;2.5,0.75;te_pwd;]" ..
|
||||
|
||||
-- Description Background
|
||||
"label[0.25,2.75;" .. fgettext("Server Description") .. "]" ..
|
||||
"box[0.25,3;5.25,2.75;#999999]"..
|
||||
"label[0.25,1.6;" .. fgettext("Server Description") .. "]" ..
|
||||
"box[0.25,1.85;5.25,2.7;#999999]"..
|
||||
|
||||
-- Name / Password
|
||||
"container[0,4.8]" ..
|
||||
"label[0.25,0;" .. fgettext("Name") .. "]" ..
|
||||
"label[3,0;" .. fgettext("Password") .. "]" ..
|
||||
"field[0.25,0.2;2.625,0.75;te_name;;" .. core.formspec_escape(core.settings:get("name")) .. "]" ..
|
||||
"pwdfield[2.875,0.2;2.625,0.75;te_pwd;]" ..
|
||||
"container_end[]" ..
|
||||
|
||||
-- Connect
|
||||
"button[3,6;2.5,0.75;btn_mp_connect;" .. fgettext("Connect") .. "]"
|
||||
"button[3,6;2.5,0.75;btn_mp_login;" .. fgettext("Login") .. "]"
|
||||
|
||||
if core.settings:get_bool("enable_split_login_register") then
|
||||
retval = retval .. "button[0.25,6;2.5,0.75;btn_mp_register;" .. fgettext("Register") .. "]"
|
||||
end
|
||||
|
||||
if tabdata.selected then
|
||||
if gamedata.fav then
|
||||
retval = retval .. "button[0.25,6;2.5,0.75;btn_delete_favorite;" ..
|
||||
fgettext("Del. Favorite") .. "]"
|
||||
retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]"
|
||||
retval = retval .. "style[btn_delete_favorite;padding=6]"
|
||||
retval = retval .. "image_button[5,1.3;0.5,0.5;" .. defaulttexturedir ..
|
||||
"server_favorite_delete.png;btn_delete_favorite;]"
|
||||
end
|
||||
if gamedata.serverdescription then
|
||||
retval = retval .. "textarea[0.25,3;5.25,2.75;;;" ..
|
||||
retval = retval .. "textarea[0.25,1.85;5.2,2.75;;;" ..
|
||||
core.formspec_escape(gamedata.serverdescription) .. "]"
|
||||
end
|
||||
end
|
||||
@ -339,12 +346,15 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
return true
|
||||
end
|
||||
|
||||
if (fields.btn_mp_connect or fields.key_enter)
|
||||
if (fields.btn_mp_login or fields.key_enter)
|
||||
and fields.te_address ~= "" and fields.te_port then
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.password = fields.te_pwd
|
||||
gamedata.address = fields.te_address
|
||||
gamedata.port = tonumber(fields.te_port)
|
||||
|
||||
local enable_split_login_register = core.settings:get_bool("enable_split_login_register")
|
||||
gamedata.allow_login_or_register = enable_split_login_register and "login" or "any"
|
||||
gamedata.selected_world = 0
|
||||
|
||||
local idx = core.get_table_index("servers")
|
||||
@ -381,6 +391,25 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.btn_mp_register and fields.te_address ~= "" and fields.te_port then
|
||||
local idx = core.get_table_index("servers")
|
||||
local server = idx and tabdata.lookup[idx]
|
||||
if server and (server.address ~= fields.te_address or server.port ~= tonumber(fields.te_port)) then
|
||||
server = nil
|
||||
end
|
||||
|
||||
if server and not is_server_protocol_compat_or_error(
|
||||
server.proto_min, server.proto_max) then
|
||||
return true
|
||||
end
|
||||
|
||||
local dlg = create_register_dialog(fields.te_address, tonumber(fields.te_port), server)
|
||||
dlg:set_parent(tabview)
|
||||
tabview:hide()
|
||||
dlg:show()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -1033,9 +1033,9 @@ serverlist_file (Serverlist file) string favoriteservers.json
|
||||
# 0 to disable queueing and -1 to make the queue size unlimited.
|
||||
max_out_chat_queue_size (Maximum size of the out chat queue) int 20
|
||||
|
||||
# Enable register confirmation when connecting to server.
|
||||
# If disabled, new account will be registered automatically.
|
||||
enable_register_confirmation (Enable register confirmation) bool true
|
||||
# If enabled, account registration is separate from login in the UI.
|
||||
# If disabled, new accounts will be registered automatically when logging in.
|
||||
enable_split_login_register (Enable split login/register) bool true
|
||||
|
||||
[*Advanced]
|
||||
|
||||
|
@ -100,7 +100,8 @@ Client::Client(
|
||||
MtEventManager *event,
|
||||
RenderingEngine *rendering_engine,
|
||||
bool ipv6,
|
||||
GameUI *game_ui
|
||||
GameUI *game_ui,
|
||||
ELoginRegister allow_login_or_register
|
||||
):
|
||||
m_tsrc(tsrc),
|
||||
m_shsrc(shsrc),
|
||||
@ -124,7 +125,8 @@ Client::Client(
|
||||
m_media_downloader(new ClientMediaDownloader()),
|
||||
m_state(LC_Created),
|
||||
m_game_ui(game_ui),
|
||||
m_modchannel_mgr(new ModChannelMgr())
|
||||
m_modchannel_mgr(new ModChannelMgr()),
|
||||
m_allow_login_or_register(allow_login_or_register)
|
||||
{
|
||||
// Add local player
|
||||
m_env.setLocalPlayer(new LocalPlayer(this, playername));
|
||||
@ -396,10 +398,6 @@ void Client::step(float dtime)
|
||||
initial_step = false;
|
||||
}
|
||||
else if(m_state == LC_Created) {
|
||||
if (m_is_registration_confirmation_state) {
|
||||
// Waiting confirmation
|
||||
return;
|
||||
}
|
||||
float &counter = m_connection_reinit_timer;
|
||||
counter -= dtime;
|
||||
if(counter <= 0.0) {
|
||||
@ -1078,18 +1076,6 @@ void Client::sendInit(const std::string &playerName)
|
||||
Send(&pkt);
|
||||
}
|
||||
|
||||
void Client::promptConfirmRegistration(AuthMechanism chosen_auth_mechanism)
|
||||
{
|
||||
m_chosen_auth_mech = chosen_auth_mechanism;
|
||||
m_is_registration_confirmation_state = true;
|
||||
}
|
||||
|
||||
void Client::confirmRegistration()
|
||||
{
|
||||
m_is_registration_confirmation_state = false;
|
||||
startAuth(m_chosen_auth_mech);
|
||||
}
|
||||
|
||||
void Client::startAuth(AuthMechanism chosen_auth_mechanism)
|
||||
{
|
||||
m_chosen_auth_mech = chosen_auth_mechanism;
|
||||
|
@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mesh_generator_thread.h"
|
||||
#include "network/address.h"
|
||||
#include "network/peerhandler.h"
|
||||
#include "gameparams.h"
|
||||
#include <fstream>
|
||||
|
||||
#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
|
||||
@ -127,7 +128,8 @@ public:
|
||||
MtEventManager *event,
|
||||
RenderingEngine *rendering_engine,
|
||||
bool ipv6,
|
||||
GameUI *game_ui
|
||||
GameUI *game_ui,
|
||||
ELoginRegister allow_login_or_register
|
||||
);
|
||||
|
||||
~Client();
|
||||
@ -347,8 +349,7 @@ public:
|
||||
u16 getProtoVersion()
|
||||
{ return m_proto_ver; }
|
||||
|
||||
void confirmRegistration();
|
||||
bool m_is_registration_confirmation_state = false;
|
||||
ELoginRegister m_allow_login_or_register = ELoginRegister::Any;
|
||||
bool m_simple_singleplayer_mode;
|
||||
|
||||
float mediaReceiveProgress();
|
||||
@ -460,7 +461,6 @@ private:
|
||||
static AuthMechanism choseAuthMech(const u32 mechs);
|
||||
|
||||
void sendInit(const std::string &playerName);
|
||||
void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
|
||||
void startAuth(AuthMechanism chosen_auth_mechanism);
|
||||
void sendDeletedBlocks(std::vector<v3s16> &blocks);
|
||||
void sendGotBlocks(const std::vector<v3s16> &blocks);
|
||||
|
@ -451,6 +451,7 @@ bool ClientLauncher::launch_game(std::string &error_message,
|
||||
start_data.name = menudata.name;
|
||||
start_data.password = menudata.password;
|
||||
start_data.address = std::move(menudata.address);
|
||||
start_data.allow_login_or_register = menudata.allow_login_or_register;
|
||||
server_name = menudata.servername;
|
||||
server_description = menudata.serverdescription;
|
||||
|
||||
|
@ -43,7 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "gameparams.h"
|
||||
#include "gettext.h"
|
||||
#include "gui/guiChatConsole.h"
|
||||
#include "gui/guiConfirmRegistration.h"
|
||||
#include "gui/guiFormSpecMenu.h"
|
||||
#include "gui/guiKeyChangeMenu.h"
|
||||
#include "gui/guiPasswordChange.h"
|
||||
@ -1480,7 +1479,8 @@ bool Game::connectToServer(const GameStartData &start_data,
|
||||
start_data.password, start_data.address,
|
||||
*draw_control, texture_src, shader_src,
|
||||
itemdef_manager, nodedef_manager, sound, eventmgr,
|
||||
m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
|
||||
m_rendering_engine, connect_address.isIPv6(), m_game_ui.get(),
|
||||
start_data.allow_login_or_register);
|
||||
client->migrateModStorage();
|
||||
} catch (const BaseException &e) {
|
||||
*error_message = fmtgettext("Error creating client: %s", e.what());
|
||||
@ -1543,28 +1543,16 @@ bool Game::connectToServer(const GameStartData &start_data,
|
||||
break;
|
||||
}
|
||||
|
||||
if (client->m_is_registration_confirmation_state) {
|
||||
if (registration_confirmation_shown) {
|
||||
// Keep drawing the GUI
|
||||
m_rendering_engine->draw_menu_scene(guienv, dtime, true);
|
||||
} else {
|
||||
registration_confirmation_shown = true;
|
||||
(new GUIConfirmRegistration(guienv, guienv->getRootGUIElement(), -1,
|
||||
&g_menumgr, client, start_data.name, start_data.password,
|
||||
connection_aborted, texture_src))->drop();
|
||||
}
|
||||
} else {
|
||||
wait_time += dtime;
|
||||
// Only time out if we aren't waiting for the server we started
|
||||
if (!start_data.address.empty() && wait_time > 10) {
|
||||
*error_message = gettext("Connection timed out.");
|
||||
errorstream << *error_message << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// Update status
|
||||
showOverlayMessage(N_("Connecting to server..."), dtime, 20);
|
||||
wait_time += dtime;
|
||||
// Only time out if we aren't waiting for the server we started
|
||||
if (!start_data.address.empty() && wait_time > 10) {
|
||||
*error_message = gettext("Connection timed out.");
|
||||
errorstream << *error_message << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// Update status
|
||||
showOverlayMessage(N_("Connecting to server..."), dtime, 20);
|
||||
}
|
||||
} catch (con::PeerNotFoundException &e) {
|
||||
// TODO: Should something be done here? At least an info/error
|
||||
|
@ -64,7 +64,7 @@ void set_default_settings()
|
||||
settings->setDefault("enable_client_modding", "false");
|
||||
settings->setDefault("max_out_chat_queue_size", "20");
|
||||
settings->setDefault("pause_on_lost_focus", "false");
|
||||
settings->setDefault("enable_register_confirmation", "true");
|
||||
settings->setDefault("enable_split_login_register", "true");
|
||||
settings->setDefault("chat_weblink_color", "#8888FF");
|
||||
|
||||
// Keymap
|
||||
|
@ -20,8 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
|
||||
struct SubgameSpec;
|
||||
#include "content/subgames.h"
|
||||
|
||||
// Information provided from "main"
|
||||
struct GameParams
|
||||
@ -34,6 +33,12 @@ struct GameParams
|
||||
bool is_dedicated_server;
|
||||
};
|
||||
|
||||
enum class ELoginRegister {
|
||||
Any = 0,
|
||||
Login,
|
||||
Register
|
||||
};
|
||||
|
||||
// Information processed by main menu
|
||||
struct GameStartData : GameParams
|
||||
{
|
||||
@ -46,6 +51,8 @@ struct GameStartData : GameParams
|
||||
std::string address;
|
||||
bool local_server;
|
||||
|
||||
ELoginRegister allow_login_or_register = ELoginRegister::Any;
|
||||
|
||||
// "world_path" must be kept in sync!
|
||||
WorldSpec world_spec;
|
||||
};
|
||||
|
@ -11,7 +11,6 @@ set(gui_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp
|
||||
|
@ -1,266 +0,0 @@
|
||||
/*
|
||||
Minetest
|
||||
Copyright (C) 2018 srifqi, Muhammad Rifqi Priyo Susanto
|
||||
<muhammadrifqipriyosusanto@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "guiConfirmRegistration.h"
|
||||
#include "client/client.h"
|
||||
#include "guiButton.h"
|
||||
#include <IGUICheckBox.h>
|
||||
#include <IGUIButton.h>
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIFont.h>
|
||||
#include "guiEditBoxWithScrollbar.h"
|
||||
#include "porting.h"
|
||||
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
#include "client/renderingengine.h"
|
||||
#endif
|
||||
|
||||
#include "gettext.h"
|
||||
|
||||
// Continuing from guiPasswordChange.cpp
|
||||
const int ID_confirmPassword = 262;
|
||||
const int ID_confirm = 263;
|
||||
const int ID_intotext = 264;
|
||||
const int ID_cancel = 265;
|
||||
const int ID_message = 266;
|
||||
|
||||
GUIConfirmRegistration::GUIConfirmRegistration(gui::IGUIEnvironment *env,
|
||||
gui::IGUIElement *parent, s32 id, IMenuManager *menumgr, Client *client,
|
||||
const std::string &playername, const std::string &password,
|
||||
bool *aborted, ISimpleTextureSource *tsrc) :
|
||||
GUIModalMenu(env, parent, id, menumgr),
|
||||
m_client(client), m_playername(playername), m_password(password),
|
||||
m_aborted(aborted), m_tsrc(tsrc)
|
||||
{
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
m_touchscreen_visible = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUIConfirmRegistration::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
acceptInput();
|
||||
removeAllChildren();
|
||||
|
||||
/*
|
||||
Calculate new sizes and positions
|
||||
*/
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2;
|
||||
#else
|
||||
const float s = m_gui_scale;
|
||||
#endif
|
||||
DesiredRect = core::rect<s32>(
|
||||
screensize.X / 2 - 600 * s / 2,
|
||||
screensize.Y / 2 - 360 * s / 2,
|
||||
screensize.X / 2 + 600 * s / 2,
|
||||
screensize.Y / 2 + 360 * s / 2
|
||||
);
|
||||
recalculateAbsolutePosition(false);
|
||||
|
||||
v2s32 size = DesiredRect.getSize();
|
||||
v2s32 topleft_client(0, 0);
|
||||
|
||||
const wchar_t *text;
|
||||
|
||||
/*
|
||||
Add stuff
|
||||
*/
|
||||
s32 ypos = 30 * s;
|
||||
{
|
||||
core::rect<s32> rect2(0, 0, 540 * s, 180 * s);
|
||||
rect2 += topleft_client + v2s32(30 * s, ypos);
|
||||
static const std::string info_text_template = strgettext(
|
||||
"You are about to join this server with the name \"%s\" for the "
|
||||
"first time.\n"
|
||||
"If you proceed, a new account using your credentials will be "
|
||||
"created on this server.\n"
|
||||
"Please retype your password and click 'Register and Join' to "
|
||||
"confirm account creation, or click 'Cancel' to abort.");
|
||||
char info_text_buf[1024];
|
||||
porting::mt_snprintf(info_text_buf, sizeof(info_text_buf),
|
||||
info_text_template.c_str(), m_playername.c_str());
|
||||
|
||||
std::wstring info_text_w = utf8_to_wide(info_text_buf);
|
||||
gui::IGUIEditBox *e = new GUIEditBoxWithScrollBar(info_text_w.c_str(),
|
||||
true, Environment, this, ID_intotext, rect2, false, true);
|
||||
e->drop();
|
||||
e->setMultiLine(true);
|
||||
e->setWordWrap(true);
|
||||
e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
|
||||
}
|
||||
|
||||
ypos += 200 * s;
|
||||
{
|
||||
core::rect<s32> rect2(0, 0, 540 * s, 30 * s);
|
||||
rect2 += topleft_client + v2s32(30 * s, ypos);
|
||||
gui::IGUIEditBox *e = Environment->addEditBox(m_pass_confirm.c_str(),
|
||||
rect2, true, this, ID_confirmPassword);
|
||||
e->setPasswordBox(true);
|
||||
Environment->setFocus(e);
|
||||
}
|
||||
|
||||
ypos += 50 * s;
|
||||
{
|
||||
core::rect<s32> rect2(0, 0, 230 * s, 35 * s);
|
||||
rect2 = rect2 + v2s32(size.X / 2 - 220 * s, ypos);
|
||||
text = wgettext("Register and Join");
|
||||
GUIButton::addButton(Environment, rect2, m_tsrc, this, ID_confirm, text);
|
||||
delete[] text;
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect2(0, 0, 120 * s, 35 * s);
|
||||
rect2 = rect2 + v2s32(size.X / 2 + 70 * s, ypos);
|
||||
text = wgettext("Cancel");
|
||||
GUIButton::addButton(Environment, rect2, m_tsrc, this, ID_cancel, text);
|
||||
delete[] text;
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect2(0, 0, 500 * s, 40 * s);
|
||||
rect2 += topleft_client + v2s32(30 * s, ypos + 40 * s);
|
||||
text = wgettext("Passwords do not match!");
|
||||
IGUIElement *e = Environment->addStaticText(
|
||||
text, rect2, false, true, this, ID_message);
|
||||
e->setVisible(false);
|
||||
delete[] text;
|
||||
}
|
||||
}
|
||||
|
||||
void GUIConfirmRegistration::drawMenu()
|
||||
{
|
||||
gui::IGUISkin *skin = Environment->getSkin();
|
||||
if (!skin)
|
||||
return;
|
||||
video::IVideoDriver *driver = Environment->getVideoDriver();
|
||||
|
||||
video::SColor bgcolor(140, 0, 0, 0);
|
||||
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
|
||||
|
||||
gui::IGUIElement::draw();
|
||||
#ifdef __ANDROID__
|
||||
getAndroidUIInput();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUIConfirmRegistration::closeMenu(bool goNext)
|
||||
{
|
||||
if (goNext) {
|
||||
m_client->confirmRegistration();
|
||||
} else {
|
||||
*m_aborted = true;
|
||||
infostream << "Connect aborted [Escape]" << std::endl;
|
||||
}
|
||||
quitMenu();
|
||||
}
|
||||
|
||||
void GUIConfirmRegistration::acceptInput()
|
||||
{
|
||||
gui::IGUIElement *e;
|
||||
e = getElementFromId(ID_confirmPassword);
|
||||
if (e)
|
||||
m_pass_confirm = e->getText();
|
||||
}
|
||||
|
||||
bool GUIConfirmRegistration::processInput()
|
||||
{
|
||||
if (utf8_to_wide(m_password) != m_pass_confirm) {
|
||||
gui::IGUIElement *e = getElementFromId(ID_message);
|
||||
if (e)
|
||||
e->setVisible(true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GUIConfirmRegistration::OnEvent(const SEvent &event)
|
||||
{
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT) {
|
||||
// clang-format off
|
||||
if ((event.KeyInput.Key == KEY_ESCAPE ||
|
||||
event.KeyInput.Key == KEY_CANCEL) &&
|
||||
event.KeyInput.PressedDown) {
|
||||
closeMenu(false);
|
||||
return true;
|
||||
}
|
||||
// clang-format on
|
||||
if (event.KeyInput.Key == KEY_RETURN && event.KeyInput.PressedDown) {
|
||||
acceptInput();
|
||||
if (processInput())
|
||||
closeMenu(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.EventType != EET_GUI_EVENT)
|
||||
return Parent ? Parent->OnEvent(event) : false;
|
||||
|
||||
if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) {
|
||||
if (!canTakeFocus(event.GUIEvent.Element)) {
|
||||
infostream << "GUIConfirmRegistration: Not allowing focus change."
|
||||
<< std::endl;
|
||||
// Returning true disables focus change
|
||||
return true;
|
||||
}
|
||||
} else if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) {
|
||||
switch (event.GUIEvent.Caller->getID()) {
|
||||
case ID_confirm:
|
||||
acceptInput();
|
||||
if (processInput())
|
||||
closeMenu(true);
|
||||
return true;
|
||||
case ID_cancel:
|
||||
closeMenu(false);
|
||||
return true;
|
||||
}
|
||||
} else if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
|
||||
switch (event.GUIEvent.Caller->getID()) {
|
||||
case ID_confirmPassword:
|
||||
acceptInput();
|
||||
if (processInput())
|
||||
closeMenu(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool GUIConfirmRegistration::getAndroidUIInput()
|
||||
{
|
||||
if (!hasAndroidUIInput() || m_jni_field_name != "password")
|
||||
return false;
|
||||
|
||||
// still waiting
|
||||
if (porting::getInputDialogState() == -1)
|
||||
return true;
|
||||
|
||||
m_jni_field_name.clear();
|
||||
|
||||
gui::IGUIElement *e = getElementFromId(ID_confirmPassword);
|
||||
|
||||
if (!e || e->getType() != irr::gui::EGUIET_EDIT_BOX)
|
||||
return false;
|
||||
|
||||
std::string text = porting::getInputDialogValue();
|
||||
e->setText(utf8_to_wide(text).c_str());
|
||||
return false;
|
||||
}
|
||||
#endif
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
Minetest
|
||||
Copyright (C) 2018 srifqi, Muhammad Rifqi Priyo Susanto
|
||||
<muhammadrifqipriyosusanto@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "modalMenu.h"
|
||||
#include <string>
|
||||
|
||||
class Client;
|
||||
class ISimpleTextureSource;
|
||||
|
||||
class GUIConfirmRegistration : public GUIModalMenu
|
||||
{
|
||||
public:
|
||||
GUIConfirmRegistration(gui::IGUIEnvironment *env, gui::IGUIElement *parent,
|
||||
s32 id, IMenuManager *menumgr, Client *client,
|
||||
const std::string &playername, const std::string &password,
|
||||
bool *aborted, ISimpleTextureSource *tsrc);
|
||||
/*
|
||||
Remove and re-add (or reposition) stuff
|
||||
*/
|
||||
void regenerateGui(v2u32 screensize);
|
||||
|
||||
void drawMenu();
|
||||
|
||||
void closeMenu(bool goNext);
|
||||
|
||||
void acceptInput();
|
||||
|
||||
bool processInput();
|
||||
|
||||
bool OnEvent(const SEvent &event);
|
||||
#ifdef __ANDROID__
|
||||
bool getAndroidUIInput();
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::wstring getLabelByID(s32 id) { return L""; }
|
||||
std::string getNameByID(s32 id) { return "password"; }
|
||||
|
||||
Client *m_client = nullptr;
|
||||
const std::string &m_playername;
|
||||
const std::string &m_password;
|
||||
bool *m_aborted = nullptr;
|
||||
std::wstring m_pass_confirm = L"";
|
||||
ISimpleTextureSource *m_tsrc;
|
||||
};
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "gameparams.h"
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
@ -50,5 +51,7 @@ struct MainMenuData {
|
||||
// Data to be passed to the script
|
||||
MainMenuDataForScript script_data;
|
||||
|
||||
ELoginRegister allow_login_or_register = ELoginRegister::Any;
|
||||
|
||||
MainMenuData() = default;
|
||||
};
|
||||
|
@ -101,11 +101,20 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
|
||||
|
||||
// Authenticate using that method, or abort if there wasn't any method found
|
||||
if (chosen_auth_mechanism != AUTH_MECHANISM_NONE) {
|
||||
if (chosen_auth_mechanism == AUTH_MECHANISM_FIRST_SRP &&
|
||||
!m_simple_singleplayer_mode &&
|
||||
!getServerAddress().isLocalhost() &&
|
||||
g_settings->getBool("enable_register_confirmation")) {
|
||||
promptConfirmRegistration(chosen_auth_mechanism);
|
||||
bool is_register = chosen_auth_mechanism == AUTH_MECHANISM_FIRST_SRP;
|
||||
ELoginRegister mode = is_register ? ELoginRegister::Register : ELoginRegister::Login;
|
||||
if (m_allow_login_or_register != ELoginRegister::Any &&
|
||||
m_allow_login_or_register != mode) {
|
||||
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
|
||||
m_access_denied = true;
|
||||
if (m_allow_login_or_register == ELoginRegister::Login) {
|
||||
m_access_denied_reason =
|
||||
gettext("Name is not registered. To create an account on this server, click 'Register'");
|
||||
} else {
|
||||
m_access_denied_reason =
|
||||
gettext("Name is taken. Please choose another name");
|
||||
}
|
||||
m_con->Disconnect();
|
||||
} else {
|
||||
startAuth(chosen_auth_mechanism);
|
||||
}
|
||||
|
@ -139,6 +139,14 @@ int ModApiMainMenu::l_start(lua_State *L)
|
||||
data->password = getTextData(L,"password");
|
||||
data->address = getTextData(L,"address");
|
||||
data->port = getTextData(L,"port");
|
||||
|
||||
const auto val = getTextData(L, "allow_login_or_register");
|
||||
if (val == "login")
|
||||
data->allow_login_or_register = ELoginRegister::Login;
|
||||
else if (val == "register")
|
||||
data->allow_login_or_register = ELoginRegister::Register;
|
||||
else
|
||||
data->allow_login_or_register = ELoginRegister::Any;
|
||||
}
|
||||
data->serverdescription = getTextData(L,"serverdescription");
|
||||
data->servername = getTextData(L,"servername");
|
||||
|
BIN
textures/base/pack/server_favorite_delete.png
Normal file
BIN
textures/base/pack/server_favorite_delete.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 748 B |
Loading…
Reference in New Issue
Block a user