Merge lp:~widelands-dev/widelands/bug-1797702-spaces-in-names-clean-start into lp:widelands
- bug-1797702-spaces-in-names-clean-start
- Merge into trunk
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 |
Related bugs: |
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()
Description of the change
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 |