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