Merge lp:~widelands-dev/widelands/bug-1797702-spaces-in-names-clean-start into lp:widelands

Proposed by Toni Förster
Status: Superseded
Proposed branch: lp:~widelands-dev/widelands/bug-1797702-spaces-in-names-clean-start
Merge into: lp:widelands
Diff against target: 664 lines (+234/-121)
11 files modified
src/network/gamehost.cc (+3/-3)
src/network/internet_gaming.cc (+7/-4)
src/network/internet_gaming.h (+6/-6)
src/ui_basic/editbox.cc (+22/-2)
src/ui_basic/editbox.h (+9/-0)
src/ui_fsmenu/internet_lobby.cc (+40/-25)
src/ui_fsmenu/multiplayer.cc (+41/-38)
src/ui_fsmenu/multiplayer.h (+0/-1)
src/ui_fsmenu/netsetup_lan.cc (+20/-1)
src/wui/login_box.cc (+78/-36)
src/wui/login_box.h (+8/-5)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1797702-spaces-in-names-clean-start
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+367313@code.launchpad.net

This proposal has been superseded by a proposal from 2019-05-11.

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()

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/network/gamehost.cc'
2--- src/network/gamehost.cc 2019-05-11 18:50:30 +0000
3+++ src/network/gamehost.cc 2019-05-11 23:01:17 +0000
4@@ -1621,13 +1621,13 @@
5
6 // Assign the player a name, preferably the name chosen by the client
7 if (playername.empty()) // Make sure there is at least a name base.
8- playername = _("Player");
9+ playername = "Player";
10 std::string effective_name = playername;
11
12 if (has_user_name(effective_name, client.usernum)) {
13- uint32_t i = 2;
14+ uint32_t i = 1;
15 do {
16- effective_name = (boost::format(_("Player %u")) % i++).str();
17+ effective_name = (boost::format("%s%u") % playername % i++).str();
18 } while (has_user_name(effective_name, client.usernum));
19 }
20
21
22=== modified file 'src/network/internet_gaming.cc'
23--- src/network/internet_gaming.cc 2019-05-11 18:50:30 +0000
24+++ src/network/internet_gaming.cc 2019-05-11 23:01:17 +0000
25@@ -487,7 +487,7 @@
26 InternetGame* ing = new InternetGame();
27 ing->name = packet.string();
28 ing->build_id = packet.string();
29- ing->connectable = (packet.string() == INTERNET_GAME_SETUP);
30+ ing->connectable = packet.string();
31 gamelist_.push_back(*ing);
32
33 bool found = false;
34@@ -498,10 +498,13 @@
35 break;
36 }
37 }
38- if (!found)
39+ if (!found && ing->connectable != INTERNET_GAME_RUNNING &&
40+ (ing->build_id == build_id() || (ing->build_id.compare(0, 6, "build-") != 0
41+ && build_id().compare(0, 6, "build-") != 0))) {
42 format_and_add_chat(
43- "", "", true,
44- (boost::format(_("The game %s is now available")) % ing->name).str());
45+ "", "", true,
46+ (boost::format(_("The game %s is now available")) % ing->name).str());
47+ }
48
49 delete ing;
50 ing = nullptr;
51
52=== modified file 'src/network/internet_gaming.h'
53--- src/network/internet_gaming.h 2019-05-11 18:50:30 +0000
54+++ src/network/internet_gaming.h 2019-05-11 23:01:17 +0000
55@@ -43,7 +43,7 @@
56 struct InternetGame {
57 std::string name;
58 std::string build_id;
59- bool connectable;
60+ std::string connectable;
61 };
62
63 /**
64@@ -178,6 +178,11 @@
65 return true;
66 }
67
68+ void format_and_add_chat(const std::string& from,
69+ const std::string& to,
70+ bool system,
71+ const std::string& msg);
72+
73 private:
74 InternetGaming();
75
76@@ -202,11 +207,6 @@
77 bool str2bool(std::string);
78 std::string bool2str(bool);
79
80- void format_and_add_chat(const std::string& from,
81- const std::string& to,
82- bool system,
83- const std::string& msg);
84-
85 /**
86 * Does the real work of the login.
87 * \param relogin Whether this is a relogin. Only difference is that
88
89=== modified file 'src/ui_basic/editbox.cc'
90--- src/ui_basic/editbox.cc 2019-05-11 18:50:30 +0000
91+++ src/ui_basic/editbox.cc 2019-05-11 23:01:17 +0000
92@@ -85,7 +85,8 @@
93 : Panel(parent, x, y, w, h > 0 ? h : text_height(font_size) + 2 * margin_y),
94 m_(new EditBoxImpl),
95 history_active_(false),
96- history_position_(-1) {
97+ history_position_(-1),
98+ warning_(false) {
99 set_thinks(false);
100
101 m_->background_style = g_gr->styles().editbox_style(style);
102@@ -346,7 +347,7 @@
103 draw_background(dst, *m_->background_style);
104
105 // Draw border.
106- if (get_w() >= 2 && get_h() >= 2) {
107+ if (get_w() >= 2 && get_h() >= 2 && !warning_) {
108 static const RGBColor black(0, 0, 0);
109
110 // bottom edge
111@@ -359,6 +360,25 @@
112 // left edge
113 dst.fill_rect(Recti(0, 0, 1, get_h() - 1), black);
114 dst.fill_rect(Recti(1, 0, 1, get_h() - 2), black);
115+
116+ } else {
117+ // Draw a red border for warnings.
118+ static const RGBColor red(255, 22, 22);
119+
120+ // bottom edge
121+ dst.fill_rect(Recti(0, get_h() - 2, get_w(), 2), red);
122+ // right edge
123+ dst.fill_rect(Recti(get_w() - 2, 0, 2, get_h() -2), red);
124+ // top edge
125+ dst.fill_rect(Recti(0, 0, get_w() - 1, 1), red);
126+ dst.fill_rect(Recti(0, 1, get_w() - 2, 1), red);
127+ dst.brighten_rect(Recti(0, 0, get_w() - 1, 1), BUTTON_EDGE_BRIGHT_FACTOR);
128+ dst.brighten_rect(Recti(0, 1, get_w() - 2, 1), BUTTON_EDGE_BRIGHT_FACTOR);
129+ // left edge
130+ dst.fill_rect(Recti(0, 0, 1, get_h() - 1), red);
131+ dst.fill_rect(Recti(1, 0, 1, get_h() - 2), red);
132+ dst.brighten_rect(Recti(0, 0, 1, get_h() - 1), BUTTON_EDGE_BRIGHT_FACTOR);
133+ dst.brighten_rect(Recti(1, 0, 1, get_h() - 2), BUTTON_EDGE_BRIGHT_FACTOR);
134 }
135
136 if (has_focus()) {
137
138=== modified file 'src/ui_basic/editbox.h'
139--- src/ui_basic/editbox.h 2019-05-11 18:50:30 +0000
140+++ src/ui_basic/editbox.h 2019-05-11 23:01:17 +0000
141@@ -72,6 +72,14 @@
142
143 void draw(RenderTarget&) override;
144
145+ void set_warning(bool warn) {
146+ warning_ = warn;
147+ }
148+
149+ bool has_warning() {
150+ return warning_;
151+ }
152+
153 private:
154 std::unique_ptr<EditBoxImpl> m_;
155
156@@ -80,6 +88,7 @@
157 bool history_active_;
158 int16_t history_position_;
159 std::string history_[CHAT_HISTORY_SIZE];
160+ bool warning_;
161 };
162 } // namespace UI
163
164
165=== modified file 'src/ui_fsmenu/internet_lobby.cc'
166--- src/ui_fsmenu/internet_lobby.cc 2019-05-11 18:50:30 +0000
167+++ src/ui_fsmenu/internet_lobby.cc 2019-05-11 23:01:17 +0000
168@@ -63,7 +63,7 @@
169 // Text labels
170 title(this, get_w() / 2, get_h() / 20, _("Metaserver Lobby"), UI::Align::kCenter),
171 clients_(this, get_w() * 4 / 125, get_h() * 15 / 100, _("Clients online:")),
172- opengames_(this, get_w() * 17 / 25, get_h() * 15 / 100, _("List of games:")),
173+ opengames_(this, get_w() * 17 / 25, get_h() * 15 / 100, _("Open Games:")),
174 servername_(this, get_w() * 17 / 25, get_h() * 63 / 100, _("Name of your server:")),
175
176 // Buttons
177@@ -198,6 +198,9 @@
178 if (!chat.has_focus()) {
179 chat.unfocus_edit();
180 }
181+ if (edit_servername_.has_focus()) {
182+ change_servername();
183+ }
184 }
185
186 void FullscreenMenuInternetLobby::clicked_ok() {
187@@ -225,26 +228,22 @@
188 hostgame_.set_enabled(true);
189 joingame_.set_enabled(false);
190 std::string localservername = edit_servername_.text();
191+ std::string localbuildid = build_id();
192
193 if (games != nullptr) { // If no communication error occurred, fill the list.
194 for (const InternetGame& game : *games) {
195 const Image* pic;
196- if (game.connectable) {
197- if (game.build_id == build_id())
198- pic = g_gr->images().get("images/ui_basic/continue.png");
199- else {
200+ if (game.connectable == INTERNET_GAME_SETUP && game.build_id == localbuildid) {
201+ // only clients with the same build number are displayed
202+ pic = g_gr->images().get("images/ui_basic/continue.png");
203+ opengames_list_.add(game.name, game, pic, false, game.build_id);
204+ } else if (game.connectable == INTERNET_GAME_SETUP &&
205+ game.build_id.compare(0, 6, "build-") != 0 &&
206+ localbuildid.compare(0, 6, "build-") != 0) {
207+ // only development clients are allowed to see games openend by such
208 pic = g_gr->images().get("images/ui_basic/different.png");
209- }
210- } else {
211- pic = g_gr->images().get("images/ui_basic/stop.png");
212- }
213- // If one of the servers has the same name as the local name of the
214- // clients server, we disable the 'hostgame' button to avoid having more
215- // than one server with the same name.
216- if (game.name == localservername) {
217- hostgame_.set_enabled(false);
218- }
219- opengames_list_.add(game.name, game, pic, false, game.build_id);
220+ opengames_list_.add(game.name, game, pic, false, game.build_id);
221+ }
222 }
223 }
224 }
225@@ -341,10 +340,8 @@
226 // remove focus from chat
227 if (opengames_list_.has_selection()) {
228 const InternetGame* game = &opengames_list_.get_selected();
229- if (game->connectable)
230+ if (game->connectable == INTERNET_GAME_SETUP)
231 joingame_.set_enabled(true);
232- else
233- joingame_.set_enabled(false);
234 }
235 }
236
237@@ -353,7 +350,7 @@
238 // if the game is open try to connect it, if not do nothing.
239 if (opengames_list_.has_selection()) {
240 const InternetGame* game = &opengames_list_.get_selected();
241- if (game->connectable)
242+ if (game->connectable == INTERNET_GAME_SETUP)
243 clicked_joingame();
244 }
245 }
246@@ -362,7 +359,8 @@
247 void FullscreenMenuInternetLobby::change_servername() {
248 // Allow client to enter a servername manually
249 hostgame_.set_enabled(true);
250-
251+ edit_servername_.set_tooltip("");
252+ edit_servername_.set_warning(false);
253 // Check whether a server of that name is already open.
254 // And disable 'hostgame' button if yes.
255 const std::vector<InternetGame>* games = InternetGaming::ref().games();
256@@ -370,6 +368,11 @@
257 for (const InternetGame& game : *games) {
258 if (game.name == edit_servername_.text()) {
259 hostgame_.set_enabled(false);
260+ edit_servername_.set_warning(true);
261+ edit_servername_.set_tooltip((boost::format
262+ (_("The game %s is already running. Please choose a different name."))
263+ % (boost::format("%s%s%s%s%s") %"<font bold=1 color="
264+ % UI_FONT_CLR_WARNING.hex_value() % ">" % game.name % "</font>")).str());
265 }
266 }
267 }
268@@ -415,10 +418,22 @@
269 // Save selected servername as default for next time and during that take care that the name is
270 // not empty.
271 std::string servername_ui = edit_servername_.text();
272- if (servername_ui.empty()) {
273- /** TRANSLATORS: This is shown for multiplayer games when no host */
274- /** TRANSLATORS: server to connect to has been specified yet. */
275- servername_ui = pgettext("server_name", "unnamed");
276+
277+ const std::vector<InternetGame>* games = InternetGaming::ref().games();
278+ if (games != nullptr) {
279+ for (const InternetGame& game : *games) {
280+ if (servername_ui.empty()) {
281+ uint32_t i = 1;
282+ do {
283+ /** TRANSLATORS: This is shown for multiplayer games when no host */
284+ /** TRANSLATORS: server to connect to has been specified yet. */
285+ servername_ui = (boost::format(_("unnamed %u")) % i++).str();
286+ } while (servername_ui == game.name);
287+ } else if (game.name == servername_ui) {
288+ change_servername();
289+ return;
290+ }
291+ }
292 }
293
294 g_options.pull_section("global").set_string("servername", servername_ui);
295
296=== modified file 'src/ui_fsmenu/multiplayer.cc'
297--- src/ui_fsmenu/multiplayer.cc 2019-05-11 18:50:30 +0000
298+++ src/ui_fsmenu/multiplayer.cc 2019-05-11 23:01:17 +0000
299@@ -58,21 +58,46 @@
300 vbox_.add_inf_space();
301 vbox_.add(&back, UI::Box::Resizing::kFullSize);
302
303- Section& s = g_options.pull_section("global");
304- auto_log_ = s.get_bool("auto_log", false);
305- if (auto_log_) {
306- showloginbox =
307+ showloginbox =
308 new UI::Button(this, "login_dialog", 0, 0, 0, 0, UI::ButtonStyle::kFsMenuSecondary,
309 g_gr->images().get("images/ui_basic/continue.png"), _("Show login dialog"));
310- showloginbox->sigclicked.connect(
311+ showloginbox->sigclicked.connect(
312 boost::bind(&FullscreenMenuMultiPlayer::show_internet_login, boost::ref(*this)));
313- }
314 layout();
315 }
316
317 /// called if the showloginbox button was pressed
318 void FullscreenMenuMultiPlayer::show_internet_login() {
319- auto_log_ = false;
320+ Section& s = g_options.pull_section("global");
321+ LoginBox lb(*this);
322+ if (lb.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
323+ nickname_ = lb.get_nickname();
324+ s.set_string("nickname", nickname_);
325+ /// NOTE: The password is only stored (in memory and on disk) and transmitted (over the
326+ /// network
327+ /// to the metaserver) as cryptographic hash. This does NOT mean that the password is
328+ /// stored
329+ /// securely on the local disk. While the password should be secure while transmitted to
330+ /// the
331+ /// metaserver (no-one can use the transmitted data to log in as the user) this is not the
332+ /// case
333+ /// for local storage. The stored hash of the password makes it hard to look at the
334+ /// configuration
335+ /// file and figure out the plaintext password to, e.g., log in on the forum. However, the
336+ /// stored hash can be copied to another system and used to log in as the user on the
337+ /// metaserver.
338+ // Further note: SHA-1 is considered broken and shouldn't be used anymore. But since the
339+ // passwords on the server are protected by SHA-1 we have to use it here, too
340+ if (lb.get_password() != "*****") {
341+ password_ = crypto::sha1(lb.get_password());
342+ s.set_string("password_sha1", password_);
343+ }
344+
345+ register_ = lb.registered();
346+ s.set_bool("registered", lb.registered());
347+ } else {
348+ return;
349+ }
350 internet_login();
351 }
352
353@@ -90,37 +115,15 @@
354 */
355 void FullscreenMenuMultiPlayer::internet_login() {
356 Section& s = g_options.pull_section("global");
357- if (auto_log_) {
358- nickname_ = s.get_string("nickname", _("nobody"));
359- password_ = s.get_string("password_sha1", "nobody");
360- register_ = s.get_bool("registered", false);
361- } else {
362- LoginBox lb(*this);
363- if (lb.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
364- nickname_ = lb.get_nickname();
365- /// NOTE: The password is only stored (in memory and on disk) and transmitted (over the
366- /// network
367- /// to the metaserver) as cryptographic hash. This does NOT mean that the password is
368- /// stored
369- /// securely on the local disk. While the password should be secure while transmitted to
370- /// the
371- /// metaserver (no-one can use the transmitted data to log in as the user) this is not the
372- /// case
373- /// for local storage. The stored hash of the password makes it hard to look at the
374- /// configuration
375- /// file and figure out the plaintext password to, e.g., log in on the forum. However, the
376- /// stored hash can be copied to another system and used to log in as the user on the
377- /// metaserver.
378- // Further note: SHA-1 is considered broken and shouldn't be used anymore. But since the
379- // passwords on the server are protected by SHA-1 we have to use it here, too
380- password_ = crypto::sha1(lb.get_password());
381- register_ = lb.registered();
382-
383- s.set_bool("registered", lb.registered());
384- s.set_bool("auto_log", lb.set_automaticlog());
385- } else {
386- return;
387- }
388+
389+ nickname_ = s.get_string("nickname", "");
390+ password_ = s.get_string("password_sha1", "nobody");
391+ register_ = s.get_bool("registered", false);
392+
393+ if (nickname_.empty() || nickname_.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
394+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.+-_") <= nickname_.size()) {
395+ show_internet_login();
396+ return;
397 }
398
399 // Try to connect to the metaserver
400
401=== modified file 'src/ui_fsmenu/multiplayer.h'
402--- src/ui_fsmenu/multiplayer.h 2019-05-11 18:50:30 +0000
403+++ src/ui_fsmenu/multiplayer.h 2019-05-11 23:01:17 +0000
404@@ -61,7 +61,6 @@
405 std::string nickname_;
406 std::string password_;
407 bool register_;
408- bool auto_log_;
409 };
410
411 #endif // end of include guard: WL_UI_FSMENU_MULTIPLAYER_H
412
413=== modified file 'src/ui_fsmenu/netsetup_lan.cc'
414--- src/ui_fsmenu/netsetup_lan.cc 2019-05-11 18:50:30 +0000
415+++ src/ui_fsmenu/netsetup_lan.cc 2019-05-11 23:01:17 +0000
416@@ -136,6 +136,7 @@
417
418 void FullscreenMenuNetSetupLAN::think() {
419 FullscreenMenuBase::think();
420+ change_playername();
421
422 discovery.run();
423 }
424@@ -186,7 +187,7 @@
425 assert(opengames.has_selection());
426 const NetOpenGame* const game = opengames.get_selected();
427 // Only join games that are open
428- if (game->info.state == LAN_GAME_OPEN) {
429+ if (game->info.state == LAN_GAME_OPEN || !playername.has_warning()) {
430 clicked_joingame();
431 }
432 }
433@@ -247,6 +248,24 @@
434 }
435
436 void FullscreenMenuNetSetupLAN::change_playername() {
437+ playername.set_warning(false);
438+ playername.set_tooltip("");
439+ hostgame.set_enabled(true);
440+
441+ if (playername.text().find_first_not_of("abcdefghijklmnopqrstuvwxyz"
442+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.+-_") <= playername.text().size()
443+ || playername.text().empty()) {
444+ playername.set_warning(true);
445+ playername.set_tooltip(_("Enter a valid nickname. This value may contain only "
446+ "English letters, numbers, and @ . + - _ characters."));
447+ joingame.set_enabled(false);
448+ hostgame.set_enabled(false);
449+ return;
450+ }
451+ if (!hostname.text().empty()) {
452+ joingame.set_enabled(true);
453+ }
454+
455 g_options.pull_section("global").set_string("nickname", playername.text());
456 }
457
458
459=== modified file 'src/wui/login_box.cc'
460--- src/wui/login_box.cc 2019-05-11 18:50:30 +0000
461+++ src/wui/login_box.cc 2019-05-11 23:01:17 +0000
462@@ -26,69 +26,65 @@
463 #include "ui_basic/messagebox.h"
464
465 LoginBox::LoginBox(Panel& parent)
466- : Window(&parent, "login_box", 0, 0, 500, 220, _("Metaserver login")) {
467+ : Window(&parent, "login_box", 0, 0, 500, 280, _("Metaserver login")) {
468 center_to_parent();
469
470 int32_t margin = 10;
471
472 ta_nickname = new UI::Textarea(this, margin, margin, _("Nickname:"));
473- ta_password = new UI::Textarea(this, margin, 40, _("Password:"));
474+ ta_password = new UI::Textarea(this, margin, 70, _("Password:"));
475 eb_nickname = new UI::EditBox(this, 150, margin, 330, 20, 2, UI::PanelStyle::kWui);
476- eb_password = new UI::EditBox(this, 150, 40, 330, 20, 2, UI::PanelStyle::kWui);
477-
478- pwd_warning =
479- new UI::MultilineTextarea(this, margin, 65, 505, 50, UI::PanelStyle::kWui,
480- _("WARNING: Password will be shown and saved readable!"));
481-
482- cb_register = new UI::Checkbox(this, Vector2i(margin, 110), _("Log in to a registered account"),
483+ eb_password = new UI::EditBox(this, 150, 70, 330, 20, 2, UI::PanelStyle::kWui);
484+
485+ cb_register = new UI::Checkbox(this, Vector2i(margin, 40), _("Log in to a registered account."),
486 "", get_inner_w() - 2 * margin);
487- cb_auto_log = new UI::Checkbox(this, Vector2i(margin, 135),
488- _("Automatically use this login information from now on."), "",
489- get_inner_w() - 2 * margin);
490-
491- UI::Button* loginbtn = new UI::Button(
492+
493+ register_account = new UI::MultilineTextarea(this, margin, 105, 470, 140, UI::PanelStyle::kWui,
494+ (boost::format(_("You need an account on the widelands website, to use a registered "
495+ "account. Please visit: %s Log in to your newly created account and set an online "
496+ "gaming password on your profile page."))
497+ % "\n\nhttps://widelands.org/accounts/register/\n\n").str());
498+
499+ loginbtn = new UI::Button(
500 this, "login",
501 UI::g_fh->fontset()->is_rtl() ? (get_inner_w() / 2 - 200) / 2 :
502 (get_inner_w() / 2 - 200) / 2 + get_inner_w() / 2,
503 get_inner_h() - 20 - margin, 200, 20, UI::ButtonStyle::kWuiPrimary, _("Login"));
504- loginbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_ok, boost::ref(*this)));
505- UI::Button* cancelbtn = new UI::Button(
506+
507+ cancelbtn = new UI::Button(
508 this, "cancel",
509 UI::g_fh->fontset()->is_rtl() ? (get_inner_w() / 2 - 200) / 2 + get_inner_w() / 2 :
510 (get_inner_w() / 2 - 200) / 2,
511 loginbtn->get_y(), 200, 20, UI::ButtonStyle::kWuiSecondary, _("Cancel"));
512+
513+ loginbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_ok, boost::ref(*this)));
514 cancelbtn->sigclicked.connect(boost::bind(&LoginBox::clicked_back, boost::ref(*this)));
515+ eb_nickname->changed.connect(boost::bind(&LoginBox::change_playername, this));
516+ cb_register->clickedto.connect(boost::bind(&LoginBox::clicked_register, this));
517
518 Section& s = g_options.pull_section("global");
519 eb_nickname->set_text(s.get_string("nickname", _("nobody")));
520 cb_register->set_state(s.get_bool("registered", false));
521+
522+ if (registered()) {
523+ eb_password->set_text("*****");
524+ } else {
525+ eb_password->set_can_focus(false);
526+ ta_password->set_color(UI_FONT_CLR_DISABLED);
527+ }
528+
529 eb_nickname->focus();
530 }
531
532+/// think function of the UI (main loop)
533+void LoginBox::think() {
534+ verify_input();
535+}
536+
537 /**
538 * called, if "login" is pressed.
539 */
540 void LoginBox::clicked_ok() {
541- // Check if all needed input fields are valid
542- if (eb_nickname->text().empty()) {
543- UI::WLMessageBox mb(
544- this, _("Empty Nickname"), _("Please enter a nickname!"), UI::WLMessageBox::MBoxType::kOk);
545- mb.run<UI::Panel::Returncodes>();
546- return;
547- }
548- if (eb_nickname->text().find(' ') <= eb_nickname->text().size()) {
549- UI::WLMessageBox mb(this, _("Space in Nickname"),
550- _("Sorry, but spaces are not allowed in nicknames!"),
551- UI::WLMessageBox::MBoxType::kOk);
552- mb.run<UI::Panel::Returncodes>();
553- return;
554- }
555- if (eb_password->text().empty() && cb_register->get_state()) {
556- UI::WLMessageBox mb(this, _("Empty Password"), _("Please enter your password!"),
557- UI::WLMessageBox::MBoxType::kOk);
558- mb.run<UI::Panel::Returncodes>();
559- return;
560- }
561 end_modal<UI::Panel::Returncodes>(UI::Panel::Returncodes::kOk);
562 }
563
564@@ -97,6 +93,11 @@
565 end_modal<UI::Panel::Returncodes>(UI::Panel::Returncodes::kBack);
566 }
567
568+/// Calles when nickname was changed
569+void LoginBox::change_playername() {
570+ cb_register->set_state(false);
571+}
572+
573 bool LoginBox::handle_key(bool down, SDL_Keysym code) {
574 if (down) {
575 switch (code.sym) {
576@@ -113,3 +114,44 @@
577 }
578 return UI::Panel::handle_key(down, code);
579 }
580+
581+void LoginBox::clicked_register() {
582+ if (cb_register->get_state()) {
583+ ta_password->set_color(UI_FONT_CLR_DISABLED);
584+ eb_password->set_can_focus(false);
585+ eb_password->set_text("");
586+ } else {
587+ ta_password->set_color(UI_FONT_CLR_FG);
588+ eb_password->set_can_focus(true);
589+ eb_password->focus();
590+ }
591+}
592+
593+void LoginBox::verify_input() {
594+ // Check if all needed input fields are valid
595+ loginbtn->set_enabled(true);
596+ eb_nickname->set_tooltip("");
597+ eb_password->set_tooltip("");
598+ eb_nickname->set_warning(false);
599+
600+ if (eb_nickname->text().empty()) {
601+ eb_nickname->set_warning(true);
602+ eb_nickname->set_tooltip(_("Please enter a nickname!"));
603+ loginbtn->set_enabled(false);
604+ } else if (eb_nickname->text().find_first_not_of("abcdefghijklmnopqrstuvwxyz"
605+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.+-_") <= eb_nickname->text().size()) {
606+ eb_nickname->set_warning(true);
607+ eb_nickname->set_tooltip(_("Enter a valid nickname. This value may contain only "
608+ "English letters, numbers, and @ . + - _ characters."));
609+ loginbtn->set_enabled(false);
610+ }
611+
612+ if (eb_password->text().empty() && cb_register->get_state()) {
613+ eb_password->set_tooltip(_("Please enter your password!"));
614+ loginbtn->set_enabled(false);
615+ }
616+
617+ if (eb_password->has_focus() && eb_password->text() == "*****") {
618+ eb_password->set_text("");
619+ }
620+}
621
622=== modified file 'src/wui/login_box.h'
623--- src/wui/login_box.h 2019-05-11 18:50:30 +0000
624+++ src/wui/login_box.h 2019-05-11 23:01:17 +0000
625@@ -29,6 +29,8 @@
626 struct LoginBox : public UI::Window {
627 explicit LoginBox(UI::Panel&);
628
629+ void think() override;
630+
631 std::string get_nickname() {
632 return eb_nickname->text();
633 }
634@@ -38,24 +40,25 @@
635 bool registered() {
636 return cb_register->get_state();
637 }
638- bool set_automaticlog() {
639- return cb_auto_log->get_state();
640- }
641
642 /// Handle keypresses
643 bool handle_key(bool down, SDL_Keysym code) override;
644
645 private:
646+ void change_playername();
647 void clicked_back();
648 void clicked_ok();
649+ void clicked_register();
650+ void verify_input();
651
652+ UI::Button* loginbtn;
653+ UI::Button* cancelbtn;
654 UI::EditBox* eb_nickname;
655 UI::EditBox* eb_password;
656 UI::Checkbox* cb_register;
657- UI::Checkbox* cb_auto_log;
658 UI::Textarea* ta_nickname;
659 UI::Textarea* ta_password;
660- UI::MultilineTextarea* pwd_warning;
661+ UI::MultilineTextarea* register_account;
662 };
663
664 #endif // end of include guard: WL_WUI_LOGIN_BOX_H

Subscribers

People subscribed via source and target branches

to status/vote changes: