widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #16923
[Merge] lp:~widelands-dev/widelands/bug-1797702-spaces-in-names into lp:widelands
Toni Förster has proposed merging lp:~widelands-dev/widelands/bug-1797702-spaces-in-names into lp:widelands.
Commit message:
rework netsetup
- allowed characters are limited
- login with empty username not allowed
- if username ist taken append number
- don't join game with empty username
editbox
- added has_warning()
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1797702 in widelands: "Player names in chat commands can't contain whitespace"
https://bugs.launchpad.net/widelands/+bug/1797702
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1797702-spaces-in-names/+merge/367122
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1797702-spaces-in-names into lp:widelands.
=== modified file 'src/network/gamehost.cc'
--- src/network/gamehost.cc 2019-04-29 16:22:08 +0000
+++ src/network/gamehost.cc 2019-05-08 15:04:09 +0000
@@ -1621,13 +1621,13 @@
// Assign the player a name, preferably the name chosen by the client
if (playername.empty()) // Make sure there is at least a name base.
- playername = _("Player");
+ playername = "Player";
std::string effective_name = playername;
if (has_user_name(effective_name, client.usernum)) {
- uint32_t i = 2;
+ uint32_t i = 1;
do {
- effective_name = (boost::format(_("Player %u")) % i++).str();
+ effective_name = (boost::format("%s%u") % playername % i++).str();
} while (has_user_name(effective_name, client.usernum));
}
=== modified file 'src/network/internet_gaming.cc'
--- src/network/internet_gaming.cc 2019-05-05 22:50:03 +0000
+++ src/network/internet_gaming.cc 2019-05-08 15:04:09 +0000
@@ -487,7 +487,7 @@
InternetGame* ing = new InternetGame();
ing->name = packet.string();
ing->build_id = packet.string();
- ing->connectable = (packet.string() == INTERNET_GAME_SETUP);
+ ing->connectable = packet.string();
gamelist_.push_back(*ing);
bool found = false;
@@ -498,10 +498,13 @@
break;
}
}
- if (!found)
+ if (!found && ing->connectable != INTERNET_GAME_RUNNING &&
+ (ing->build_id == build_id() || (ing->build_id.compare(0, 6, "build-") != 0
+ && build_id().compare(0, 6, "build-") != 0))) {
format_and_add_chat(
- "", "", true,
- (boost::format(_("The game %s is now available")) % ing->name).str());
+ "", "", true,
+ (boost::format(_("The game %s is now available")) % ing->name).str());
+ }
delete ing;
ing = nullptr;
=== modified file 'src/network/internet_gaming.h'
--- src/network/internet_gaming.h 2019-02-23 11:00:49 +0000
+++ src/network/internet_gaming.h 2019-05-08 15:04:09 +0000
@@ -43,7 +43,7 @@
struct InternetGame {
std::string name;
std::string build_id;
- bool connectable;
+ std::string connectable;
};
/**
@@ -178,6 +178,11 @@
return true;
}
+ void format_and_add_chat(const std::string& from,
+ const std::string& to,
+ bool system,
+ const std::string& msg);
+
private:
InternetGaming();
@@ -202,11 +207,6 @@
bool str2bool(std::string);
std::string bool2str(bool);
- void format_and_add_chat(const std::string& from,
- const std::string& to,
- bool system,
- const std::string& msg);
-
/**
* Does the real work of the login.
* \param relogin Whether this is a relogin. Only difference is that
=== modified file 'src/ui_basic/editbox.cc'
--- src/ui_basic/editbox.cc 2019-04-09 16:43:49 +0000
+++ src/ui_basic/editbox.cc 2019-05-08 15:04:09 +0000
@@ -85,7 +85,8 @@
: Panel(parent, x, y, w, h > 0 ? h : text_height(font_size) + 2 * margin_y),
m_(new EditBoxImpl),
history_active_(false),
- history_position_(-1) {
+ history_position_(-1),
+ warning_(false) {
set_thinks(false);
m_->background_style = g_gr->styles().editbox_style(style);
@@ -346,7 +347,7 @@
draw_background(dst, *m_->background_style);
// Draw border.
- if (get_w() >= 2 && get_h() >= 2) {
+ if (get_w() >= 2 && get_h() >= 2 && !warning_) {
static const RGBColor black(0, 0, 0);
// bottom edge
@@ -359,6 +360,25 @@
// left edge
dst.fill_rect(Recti(0, 0, 1, get_h() - 1), black);
dst.fill_rect(Recti(1, 0, 1, get_h() - 2), black);
+
+ } else {
+ // Draw a red border for warnings.
+ static const RGBColor red(255, 22, 22);
+
+ // bottom edge
+ dst.fill_rect(Recti(0, get_h() - 2, get_w(), 2), red);
+ // right edge
+ dst.fill_rect(Recti(get_w() - 2, 0, 2, get_h() -2), red);
+ // top edge
+ dst.fill_rect(Recti(0, 0, get_w() - 1, 1), red);
+ dst.fill_rect(Recti(0, 1, get_w() - 2, 1), red);
+ dst.brighten_rect(Recti(0, 0, get_w() - 1, 1), BUTTON_EDGE_BRIGHT_FACTOR);
+ dst.brighten_rect(Recti(0, 1, get_w() - 2, 1), BUTTON_EDGE_BRIGHT_FACTOR);
+ // left edge
+ dst.fill_rect(Recti(0, 0, 1, get_h() - 1), red);
+ dst.fill_rect(Recti(1, 0, 1, get_h() - 2), red);
+ dst.brighten_rect(Recti(0, 0, 1, get_h() - 1), BUTTON_EDGE_BRIGHT_FACTOR);
+ dst.brighten_rect(Recti(1, 0, 1, get_h() - 2), BUTTON_EDGE_BRIGHT_FACTOR);
}
if (has_focus()) {
=== modified file 'src/ui_basic/editbox.h'
--- src/ui_basic/editbox.h 2019-02-23 11:00:49 +0000
+++ src/ui_basic/editbox.h 2019-05-08 15:04:09 +0000
@@ -72,6 +72,14 @@
void draw(RenderTarget&) override;
+ void set_warning(bool warn) {
+ warning_ = warn;
+ }
+
+ bool has_warning() {
+ return warning_;
+ }
+
private:
std::unique_ptr<EditBoxImpl> m_;
@@ -80,6 +88,7 @@
bool history_active_;
int16_t history_position_;
std::string history_[CHAT_HISTORY_SIZE];
+ bool warning_;
};
} // namespace UI
=== modified file 'src/ui_fsmenu/internet_lobby.cc'
--- src/ui_fsmenu/internet_lobby.cc 2019-05-05 00:22:27 +0000
+++ src/ui_fsmenu/internet_lobby.cc 2019-05-08 15:04:09 +0000
@@ -63,7 +63,7 @@
// Text labels
title(this, get_w() / 2, get_h() / 20, _("Metaserver Lobby"), UI::Align::kCenter),
clients_(this, get_w() * 4 / 125, get_h() * 15 / 100, _("Clients online:")),
- opengames_(this, get_w() * 17 / 25, get_h() * 15 / 100, _("List of games:")),
+ opengames_(this, get_w() * 17 / 25, get_h() * 15 / 100, _("Open Games:")),
servername_(this, get_w() * 17 / 25, get_h() * 63 / 100, _("Name of your server:")),
// Buttons
@@ -223,28 +223,37 @@
// List and button cleanup
opengames_list_.clear();
hostgame_.set_enabled(true);
+ edit_servername_.set_tooltip("");
+ edit_servername_.set_warning(false);
joingame_.set_enabled(false);
std::string localservername = edit_servername_.text();
+ std::string localbuildid = build_id();
if (games != nullptr) { // If no communication error occurred, fill the list.
for (const InternetGame& game : *games) {
const Image* pic;
- if (game.connectable) {
- if (game.build_id == build_id())
- pic = g_gr->images().get("images/ui_basic/continue.png");
- else {
+ if (game.connectable == INTERNET_GAME_SETUP && game.build_id == localbuildid) {
+ // only clients with the same build number are displayed
+ pic = g_gr->images().get("images/ui_basic/continue.png");
+ opengames_list_.add(game.name, game, pic, false, game.build_id);
+ } else if (game.connectable == INTERNET_GAME_SETUP &&
+ game.build_id.compare(0, 6, "build-") != 0 &&
+ localbuildid.compare(0, 6, "build-") != 0) {
+ // only development clients are allowed to see games openend by such
pic = g_gr->images().get("images/ui_basic/different.png");
- }
- } else {
- pic = g_gr->images().get("images/ui_basic/stop.png");
+ opengames_list_.add(game.name, game, pic, false, game.build_id);
}
// If one of the servers has the same name as the local name of the
// clients server, we disable the 'hostgame' button to avoid having more
// than one server with the same name.
if (game.name == localservername) {
hostgame_.set_enabled(false);
+ edit_servername_.set_warning(true);
+ edit_servername_.set_tooltip(
+ (boost::format("%s%s%s%s%s%s%s%s") % _("The game ") % "<font bold=yes color="
+ % UI_FONT_CLR_WARNING.hex_value() % ">" % game.name % "</font>"
+ % _(" is already running. ") % _("Please choose a different name.")).str());
}
- opengames_list_.add(game.name, game, pic, false, game.build_id);
}
}
}
@@ -341,10 +350,8 @@
// remove focus from chat
if (opengames_list_.has_selection()) {
const InternetGame* game = &opengames_list_.get_selected();
- if (game->connectable)
+ if (game->connectable == INTERNET_GAME_SETUP)
joingame_.set_enabled(true);
- else
- joingame_.set_enabled(false);
}
}
@@ -353,7 +360,7 @@
// if the game is open try to connect it, if not do nothing.
if (opengames_list_.has_selection()) {
const InternetGame* game = &opengames_list_.get_selected();
- if (game->connectable)
+ if (game->connectable == INTERNET_GAME_SETUP)
clicked_joingame();
}
}
@@ -362,7 +369,8 @@
void FullscreenMenuInternetLobby::change_servername() {
// Allow client to enter a servername manually
hostgame_.set_enabled(true);
-
+ edit_servername_.set_tooltip("");
+ edit_servername_.set_warning(false);
// Check whether a server of that name is already open.
// And disable 'hostgame' button if yes.
const std::vector<InternetGame>* games = InternetGaming::ref().games();
@@ -370,6 +378,11 @@
for (const InternetGame& game : *games) {
if (game.name == edit_servername_.text()) {
hostgame_.set_enabled(false);
+ edit_servername_.set_warning(true);
+ edit_servername_.set_tooltip(
+ (boost::format("%s%s%s%s%s%s%s%s") % _("The game ") % "<font bold=yes color="
+ % UI_FONT_CLR_WARNING.hex_value() % ">" % game.name % "</font>"
+ % _(" is already running. ") % _("Please choose a different name.")).str());
}
}
}
=== modified file 'src/ui_fsmenu/multiplayer.cc'
--- src/ui_fsmenu/multiplayer.cc 2019-02-23 11:00:49 +0000
+++ src/ui_fsmenu/multiplayer.cc 2019-05-08 15:04:09 +0000
@@ -58,21 +58,46 @@
vbox_.add_inf_space();
vbox_.add(&back, UI::Box::Resizing::kFullSize);
- Section& s = g_options.pull_section("global");
- auto_log_ = s.get_bool("auto_log", false);
- if (auto_log_) {
- showloginbox =
+ showloginbox =
new UI::Button(this, "login_dialog", 0, 0, 0, 0, UI::ButtonStyle::kFsMenuSecondary,
g_gr->images().get("images/ui_basic/continue.png"), _("Show login dialog"));
- showloginbox->sigclicked.connect(
+ showloginbox->sigclicked.connect(
boost::bind(&FullscreenMenuMultiPlayer::show_internet_login, boost::ref(*this)));
- }
layout();
}
/// called if the showloginbox button was pressed
void FullscreenMenuMultiPlayer::show_internet_login() {
- auto_log_ = false;
+ Section& s = g_options.pull_section("global");
+ LoginBox lb(*this);
+ if (lb.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
+ nickname_ = lb.get_nickname();
+ s.set_string("nickname", nickname_);
+ /// NOTE: The password is only stored (in memory and on disk) and transmitted (over the
+ /// network
+ /// to the metaserver) as cryptographic hash. This does NOT mean that the password is
+ /// stored
+ /// securely on the local disk. While the password should be secure while transmitted to
+ /// the
+ /// metaserver (no-one can use the transmitted data to log in as the user) this is not the
+ /// case
+ /// for local storage. The stored hash of the password makes it hard to look at the
+ /// configuration
+ /// file and figure out the plaintext password to, e.g., log in on the forum. However, the
+ /// stored hash can be copied to another system and used to log in as the user on the
+ /// metaserver.
+ // Further note: SHA-1 is considered broken and shouldn't be used anymore. But since the
+ // passwords on the server are protected by SHA-1 we have to use it here, too
+ if (lb.get_password() != "*****") {
+ password_ = crypto::sha1(lb.get_password());
+ s.set_string("password_sha1", password_);
+ }
+
+ register_ = lb.registered();
+ s.set_bool("registered", lb.registered());
+ } else {
+ return;
+ }
internet_login();
}
@@ -90,37 +115,14 @@
*/
void FullscreenMenuMultiPlayer::internet_login() {
Section& s = g_options.pull_section("global");
- if (auto_log_) {
- nickname_ = s.get_string("nickname", _("nobody"));
- password_ = s.get_string("password_sha1", "nobody");
- register_ = s.get_bool("registered", false);
- } else {
- LoginBox lb(*this);
- if (lb.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
- nickname_ = lb.get_nickname();
- /// NOTE: The password is only stored (in memory and on disk) and transmitted (over the
- /// network
- /// to the metaserver) as cryptographic hash. This does NOT mean that the password is
- /// stored
- /// securely on the local disk. While the password should be secure while transmitted to
- /// the
- /// metaserver (no-one can use the transmitted data to log in as the user) this is not the
- /// case
- /// for local storage. The stored hash of the password makes it hard to look at the
- /// configuration
- /// file and figure out the plaintext password to, e.g., log in on the forum. However, the
- /// stored hash can be copied to another system and used to log in as the user on the
- /// metaserver.
- // Further note: SHA-1 is considered broken and shouldn't be used anymore. But since the
- // passwords on the server are protected by SHA-1 we have to use it here, too
- password_ = crypto::sha1(lb.get_password());
- register_ = lb.registered();
-
- s.set_bool("registered", lb.registered());
- s.set_bool("auto_log", lb.set_automaticlog());
- } else {
- return;
- }
+
+ nickname_ = s.get_string("nickname", _(" "));
+ password_ = s.get_string("password_sha1", "nobody");
+ register_ = s.get_bool("registered", false);
+
+ if (nickname_ == " ") {
+ show_internet_login();
+ return;
}
// Try to connect to the metaserver
=== modified file 'src/ui_fsmenu/multiplayer.h'
--- src/ui_fsmenu/multiplayer.h 2019-02-23 11:00:49 +0000
+++ src/ui_fsmenu/multiplayer.h 2019-05-08 15:04:09 +0000
@@ -61,7 +61,6 @@
std::string nickname_;
std::string password_;
bool register_;
- bool auto_log_;
};
#endif // end of include guard: WL_UI_FSMENU_MULTIPLAYER_H
=== modified file 'src/ui_fsmenu/netsetup_lan.cc'
--- src/ui_fsmenu/netsetup_lan.cc 2019-04-09 16:43:49 +0000
+++ src/ui_fsmenu/netsetup_lan.cc 2019-05-08 15:04:09 +0000
@@ -136,6 +136,7 @@
void FullscreenMenuNetSetupLAN::think() {
FullscreenMenuBase::think();
+ change_playername();
discovery.run();
}
@@ -186,7 +187,7 @@
assert(opengames.has_selection());
const NetOpenGame* const game = opengames.get_selected();
// Only join games that are open
- if (game->info.state == LAN_GAME_OPEN) {
+ if (game->info.state == LAN_GAME_OPEN || !playername.has_warning()) {
clicked_joingame();
}
}
@@ -247,6 +248,24 @@
}
void FullscreenMenuNetSetupLAN::change_playername() {
+ playername.set_warning(false);
+ playername.set_tooltip("");
+ hostgame.set_enabled(true);
+
+ if (playername.text().find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.+-_") <= playername.text().size()
+ || playername.text().empty()) {
+ playername.set_warning(true);
+ playername.set_tooltip(_("Enter a valid nickname. This value may contain only "
+ "English letters, numbers, and @ . + - _ characters."));
+ joingame.set_enabled(false);
+ hostgame.set_enabled(false);
+ return;
+ }
+ if (!hostname.text().empty()) {
+ joingame.set_enabled(true);
+ }
+
g_options.pull_section("global").set_string("nickname", playername.text());
}
=== modified file 'src/wui/login_box.cc'
--- src/wui/login_box.cc 2019-02-23 11:00:49 +0000
+++ src/wui/login_box.cc 2019-05-08 15:04:09 +0000
@@ -26,7 +26,7 @@
#include "ui_basic/messagebox.h"
LoginBox::LoginBox(Panel& parent)
- : Window(&parent, "login_box", 0, 0, 500, 220, _("Metaserver login")) {
+ : Window(&parent, "login_box", 0, 0, 500, 260, _("Metaserver login")) {
center_to_parent();
int32_t margin = 10;
@@ -36,59 +36,53 @@
eb_nickname = new UI::EditBox(this, 150, margin, 330, 20, 2, UI::PanelStyle::kWui);
eb_password = new UI::EditBox(this, 150, 40, 330, 20, 2, UI::PanelStyle::kWui);
- pwd_warning =
- new UI::MultilineTextarea(this, margin, 65, 505, 50, UI::PanelStyle::kWui,
- _("WARNING: Password will be shown and saved readable!"));
-
- cb_register = new UI::Checkbox(this, Vector2i(margin, 110), _("Log in to a registered account"),
+ cb_register = new UI::Checkbox(this, Vector2i(margin, 70), _("Log in to a registered account"),
"", get_inner_w() - 2 * margin);
- cb_auto_log = new UI::Checkbox(this, Vector2i(margin, 135),
- _("Automatically use this login information from now on."), "",
- get_inner_w() - 2 * margin);
-
- UI::Button* loginbtn = new UI::Button(
+
+ register_account = new UI::MultilineTextarea(this, margin, 105, 470, 140, UI::PanelStyle::kWui,
+ _("To register an account, please visit our website: \n\n"
+ "https://widelands.org/accounts/register/ \n\n"
+ "Log in to your newly created account and set an \n"
+ "online gaming password on your profile page."));
+
+ loginbtn = new UI::Button(
this, "login",
UI::g_fh->fontset()->is_rtl() ? (get_inner_w() / 2 - 200) / 2 :
(get_inner_w() / 2 - 200) / 2 + get_inner_w() / 2,
get_inner_h() - 20 - margin, 200, 20, UI::ButtonStyle::kWuiPrimary, _("Login"));
- loginbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_ok, boost::ref(*this)));
- UI::Button* cancelbtn = new UI::Button(
+
+ cancelbtn = new UI::Button(
this, "cancel",
UI::g_fh->fontset()->is_rtl() ? (get_inner_w() / 2 - 200) / 2 + get_inner_w() / 2 :
(get_inner_w() / 2 - 200) / 2,
loginbtn->get_y(), 200, 20, UI::ButtonStyle::kWuiSecondary, _("Cancel"));
+
+ loginbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_ok, boost::ref(*this)));
cancelbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_back, boost::ref(*this)));
+ eb_nickname->changed.connect(boost::bind(&LoginBox::change_playername, this));
Section& s = g_options.pull_section("global");
eb_nickname->set_text(s.get_string("nickname", _("nobody")));
cb_register->set_state(s.get_bool("registered", false));
+
+ if (registered()) {
+ eb_password->set_text("*****");
+ } else {
+ eb_password->set_can_focus(false);
+ }
+
eb_nickname->focus();
}
+/// think function of the UI (main loop)
+void LoginBox::think() {
+ verify_input();
+}
+
/**
* called, if "login" is pressed.
*/
void LoginBox::clicked_ok() {
- // Check if all needed input fields are valid
- if (eb_nickname->text().empty()) {
- UI::WLMessageBox mb(
- this, _("Empty Nickname"), _("Please enter a nickname!"), UI::WLMessageBox::MBoxType::kOk);
- mb.run<UI::Panel::Returncodes>();
- return;
- }
- if (eb_nickname->text().find(' ') <= eb_nickname->text().size()) {
- UI::WLMessageBox mb(this, _("Space in Nickname"),
- _("Sorry, but spaces are not allowed in nicknames!"),
- UI::WLMessageBox::MBoxType::kOk);
- mb.run<UI::Panel::Returncodes>();
- return;
- }
- if (eb_password->text().empty() && cb_register->get_state()) {
- UI::WLMessageBox mb(this, _("Empty Password"), _("Please enter your password!"),
- UI::WLMessageBox::MBoxType::kOk);
- mb.run<UI::Panel::Returncodes>();
- return;
- }
end_modal<UI::Panel::Returncodes>(UI::Panel::Returncodes::kOk);
}
@@ -97,6 +91,11 @@
end_modal<UI::Panel::Returncodes>(UI::Panel::Returncodes::kBack);
}
+/// Calles when nickname was changed
+void LoginBox::change_playername() {
+ cb_register->set_state(false);
+}
+
bool LoginBox::handle_key(bool down, SDL_Keysym code) {
if (down) {
switch (code.sym) {
@@ -113,3 +112,43 @@
}
return UI::Panel::handle_key(down, code);
}
+
+void LoginBox::verify_input() {
+ // Check if all needed input fields are valid
+ loginbtn->set_enabled(true);
+ eb_nickname->set_tooltip("");
+ eb_password->set_tooltip("");
+ eb_nickname->set_warning(false);
+ eb_password->set_warning(false);
+
+ if (eb_nickname->text().empty()) {
+ eb_nickname->set_warning(true);
+ eb_nickname->set_tooltip(_("Please enter a nickname!"));
+ loginbtn->set_enabled(false);
+ }
+
+ if (eb_nickname->text().find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.+-_") <= eb_nickname->text().size()) {
+ eb_nickname->set_warning(true);
+ eb_nickname->set_tooltip(_("Enter a valid nickname. This value may contain only "
+ "English letters, numbers, and @ . + - _ characters."));
+ loginbtn->set_enabled(false);
+
+ }
+
+ if (eb_password->text().empty() && cb_register->get_state()) {
+ eb_password->set_warning(true);
+ eb_password->set_tooltip(_("Please enter your password!"));
+ eb_password->focus();
+ loginbtn->set_enabled(false);
+ }
+
+ if (!eb_password->text().empty() && !cb_register->get_state()) {
+ eb_password->set_text("");
+ eb_password->set_can_focus(false);
+ }
+
+ if (eb_password->has_focus() && eb_password->text() == "*****") {
+ eb_password->set_text("");
+ }
+}
=== modified file 'src/wui/login_box.h'
--- src/wui/login_box.h 2019-02-23 11:00:49 +0000
+++ src/wui/login_box.h 2019-05-08 15:04:09 +0000
@@ -29,6 +29,10 @@
struct LoginBox : public UI::Window {
explicit LoginBox(UI::Panel&);
+ void think() override;
+
+ void verify_input();
+
std::string get_nickname() {
return eb_nickname->text();
}
@@ -38,9 +42,6 @@
bool registered() {
return cb_register->get_state();
}
- bool set_automaticlog() {
- return cb_auto_log->get_state();
- }
/// Handle keypresses
bool handle_key(bool down, SDL_Keysym code) override;
@@ -48,14 +49,16 @@
private:
void clicked_back();
void clicked_ok();
+ void change_playername();
+ UI::Button* loginbtn;
+ UI::Button* cancelbtn;
UI::EditBox* eb_nickname;
UI::EditBox* eb_password;
UI::Checkbox* cb_register;
- UI::Checkbox* cb_auto_log;
UI::Textarea* ta_nickname;
UI::Textarea* ta_password;
- UI::MultilineTextarea* pwd_warning;
+ UI::MultilineTextarea* register_account;
};
#endif // end of include guard: WL_WUI_LOGIN_BOX_H
Follow ups