GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* The ManaPlus Client |
||
3 |
* Copyright (C) 2004-2009 The Mana World Development Team |
||
4 |
* Copyright (C) 2009-2010 The Mana Developers |
||
5 |
* Copyright (C) 2011-2019 The ManaPlus Developers |
||
6 |
* Copyright (C) 2019-2021 Andrei Karas |
||
7 |
* |
||
8 |
* This file is part of The ManaPlus Client. |
||
9 |
* |
||
10 |
* This program is free software; you can redistribute it and/or modify |
||
11 |
* it under the terms of the GNU General Public License as published by |
||
12 |
* the Free Software Foundation; either version 2 of the License, or |
||
13 |
* any later version. |
||
14 |
* |
||
15 |
* This program is distributed in the hope that it will be useful, |
||
16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 |
* GNU General Public License for more details. |
||
19 |
* |
||
20 |
* You should have received a copy of the GNU General Public License |
||
21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
22 |
*/ |
||
23 |
|||
24 |
#include "gui/windows/serverdialog.h" |
||
25 |
|||
26 |
#include "chatlogger.h" |
||
27 |
#include "client.h" |
||
28 |
#include "configuration.h" |
||
29 |
#include "main.h" |
||
30 |
#include "settings.h" |
||
31 |
|||
32 |
#include "net/download.h" |
||
33 |
|||
34 |
#include "fs/paths.h" |
||
35 |
|||
36 |
#include "gui/widgets/checkbox.h" |
||
37 |
#include "gui/widgets/createwidget.h" |
||
38 |
#include "gui/widgets/desktop.h" |
||
39 |
#include "gui/windows/editserverdialog.h" |
||
40 |
#include "gui/windows/logindialog.h" |
||
41 |
#include "gui/windows/serverinfowindow.h" |
||
42 |
|||
43 |
#include "gui/widgets/button.h" |
||
44 |
#include "gui/widgets/label.h" |
||
45 |
#include "gui/widgets/layout.h" |
||
46 |
#include "gui/widgets/serverslistbox.h" |
||
47 |
#include "gui/widgets/scrollarea.h" |
||
48 |
|||
49 |
#include "utils/delete2.h" |
||
50 |
#include "utils/foreach.h" |
||
51 |
#include "utils/langs.h" |
||
52 |
|||
53 |
#include "debug.h" |
||
54 |
|||
55 |
#ifdef WIN32 |
||
56 |
#undef ERROR |
||
57 |
#endif // WIN32 |
||
58 |
|||
59 |
static const int MAX_SERVERLIST = 15; |
||
60 |
|||
61 |
static std::string serverTypeToString(const ServerTypeT type) |
||
62 |
{ |
||
63 |
switch (type) |
||
64 |
{ |
||
65 |
case ServerType::TMWATHENA: |
||
66 |
#ifdef TMWA_SUPPORT |
||
67 |
return "TmwAthena"; |
||
68 |
#else // TMWA_SUPPORT |
||
69 |
|||
70 |
return ""; |
||
71 |
#endif // TMWA_SUPPORT |
||
72 |
|||
73 |
case ServerType::EATHENA: |
||
74 |
return "eAthena"; |
||
75 |
case ServerType::EVOL2: |
||
76 |
return "Evol2"; |
||
77 |
default: |
||
78 |
case ServerType::UNKNOWN: |
||
79 |
return ""; |
||
80 |
} |
||
81 |
} |
||
82 |
|||
83 |
static uint16_t defaultPortForServerType(const ServerTypeT type) |
||
84 |
{ |
||
85 |
✓✗✗✗ |
30 |
switch (type) |
86 |
{ |
||
87 |
default: |
||
88 |
case ServerType::EATHENA: |
||
89 |
case ServerType::EVOL2: |
||
90 |
return 6900; |
||
91 |
case ServerType::UNKNOWN: |
||
92 |
case ServerType::TMWATHENA: |
||
93 |
return 6901; |
||
94 |
} |
||
95 |
} |
||
96 |
|||
97 |
2 |
ServerDialog::ServerDialog(ServerInfo *const serverInfo, |
|
98 |
2 |
const std::string &dir) : |
|
99 |
// TRANSLATORS: servers dialog name |
||
100 |
2 |
Window(_("Choose Your Server"), Modal_false, nullptr, "server.xml"), |
|
101 |
ActionListener(), |
||
102 |
KeyListener(), |
||
103 |
SelectionListener(), |
||
104 |
mMutex(), |
||
105 |
mServers(ServerInfos()), |
||
106 |
mDir(dir), |
||
107 |
✓✗✓✗ |
4 |
mDescription(new Label(this, std::string())), |
108 |
// TRANSLATORS: servers dialog button |
||
109 |
✓✗✓✗ |
4 |
mQuitButton(new Button(this, _("Quit"), "quit", BUTTON_SKIN, this)), |
110 |
// TRANSLATORS: servers dialog button |
||
111 |
2 |
mConnectButton(new Button(this, _("Connect"), "connect", |
|
112 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
113 |
// TRANSLATORS: servers dialog button |
||
114 |
✓✗✓✗ |
4 |
mAddEntryButton(new Button(this, _("Add"), "addEntry", BUTTON_SKIN, this)), |
115 |
// TRANSLATORS: servers dialog button |
||
116 |
2 |
mEditEntryButton(new Button(this, _("Edit"), "editEntry", |
|
117 |
✓✗✓✗ |
2 |
BUTTON_SKIN, this)), |
118 |
// TRANSLATORS: servers dialog button |
||
119 |
✓✗✓✗ |
4 |
mDeleteButton(new Button(this, _("Delete"), "remove", BUTTON_SKIN, this)), |
120 |
// TRANSLATORS: servers dialog button |
||
121 |
✓✗✓✗ |
4 |
mLoadButton(new Button(this, _("Load"), "load", BUTTON_SKIN, this)), |
122 |
// TRANSLATORS: servers dialog button |
||
123 |
✓✗✓✗ |
4 |
mInfoButton(new Button(this, _("Info"), "info", BUTTON_SKIN, this)), |
124 |
✓✗✓✗ |
2 |
mServersListModel(new ServersListModel(&mServers, this)), |
125 |
✓✗✓✗ ✓✗ |
2 |
mServersList(CREATEWIDGETR(ServersListBox, this, mServersListModel)), |
126 |
mDownload(nullptr), |
||
127 |
mServerInfo(serverInfo), |
||
128 |
mPersistentIPCheckBox(nullptr), |
||
129 |
mDownloadProgress(-1.0F), |
||
130 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
130 |
mDownloadStatus(ServerDialogDownloadStatus::UNKNOWN) |
131 |
{ |
||
132 |
✗✓ | 2 |
if (isSafeMode) |
133 |
{ |
||
134 |
// TRANSLATORS: servers dialog name |
||
135 |
setCaption(_("Choose Your Server *** SAFE MODE ***")); |
||
136 |
} |
||
137 |
#ifdef USE_OPENGL |
||
138 |
✓✗✓✗ ✓✗ |
8 |
else if (config.getIntValue("opengl") == RENDER_SOFTWARE) |
139 |
{ |
||
140 |
// TRANSLATORS: servers dialog name |
||
141 |
✓✗ | 10 |
setCaption(_("Choose Your Server *** SOFTWARE RENDER MODE ***")); |
142 |
} |
||
143 |
#endif // USE_OPENGL |
||
144 |
|||
145 |
✓✗ | 10 |
setWindowName("ServerDialog"); |
146 |
|||
147 |
✓✗ | 2 |
setCloseButton(true); |
148 |
|||
149 |
2 |
mPersistentIPCheckBox = new CheckBox(this, |
|
150 |
// TRANSLATORS: servers dialog checkbox |
||
151 |
2 |
_("Use same ip for game sub servers"), |
|
152 |
✓✗✓✗ |
8 |
config.getBoolValue("usePersistentIP"), |
153 |
✓✗✓✗ ✓✗✓✗ |
16 |
this, "persitent ip"); |
154 |
|||
155 |
✓✗ | 2 |
loadCustomServers(); |
156 |
|||
157 |
✓✗ | 2 |
mServersList->addMouseListener(this); |
158 |
|||
159 |
2 |
ScrollArea *const usedScroll = new ScrollArea(this, mServersList, |
|
160 |
✓✗✓✗ ✗✓ |
8 |
fromBool(getOptionBool("showbackground", false), Opaque), |
161 |
✓✗✓✗ ✓✗ |
10 |
"server_background.xml"); |
162 |
✓✗ | 2 |
usedScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); |
163 |
|||
164 |
✓✗ | 2 |
mServersList->addSelectionListener(this); |
165 |
✓✗ | 2 |
usedScroll->setVerticalScrollAmount(0); |
166 |
|||
167 |
✓✗ | 4 |
place(0, 0, usedScroll, 8, 5).setPadding(3); |
168 |
✓✗ | 2 |
place(0, 5, mDescription, 8, 1); |
169 |
✓✗ | 2 |
place(0, 6, mPersistentIPCheckBox, 8, 1); |
170 |
✓✗ | 2 |
place(0, 7, mInfoButton, 1, 1); |
171 |
✓✗ | 2 |
place(1, 7, mAddEntryButton, 1, 1); |
172 |
✓✗ | 2 |
place(2, 7, mEditEntryButton, 1, 1); |
173 |
✓✗ | 2 |
place(3, 7, mLoadButton, 1, 1); |
174 |
✓✗ | 2 |
place(4, 7, mDeleteButton, 1, 1); |
175 |
✓✗ | 2 |
place(6, 7, mQuitButton, 1, 1); |
176 |
✓✗ | 2 |
place(7, 7, mConnectButton, 1, 1); |
177 |
|||
178 |
// Make sure the list has enough height |
||
179 |
✓✗✓✗ |
2 |
getLayout().setRowHeight(0, 80); |
180 |
|||
181 |
// Do this manually instead of calling reflowLayout so we can enforce a |
||
182 |
// minimum width. |
||
183 |
2 |
int width = 500; |
|
184 |
2 |
int height = 350; |
|
185 |
|||
186 |
✓✗✓✗ |
2 |
getLayout().reflow(width, height); |
187 |
✓✗ | 2 |
setContentSize(width, height); |
188 |
|||
189 |
✓✗ | 2 |
setMinWidth(310); |
190 |
✓✗ | 2 |
setMinHeight(220); |
191 |
✓✗ | 6 |
setDefaultSize(getWidth(), getHeight(), ImagePosition::CENTER, 0, 0); |
192 |
|||
193 |
✓✗ | 2 |
setResizable(true); |
194 |
✓✗ | 2 |
addKeyListener(this); |
195 |
|||
196 |
✓✗ | 2 |
loadWindowState(); |
197 |
2 |
} |
|
198 |
|||
199 |
2 |
void ServerDialog::postInit() |
|
200 |
{ |
||
201 |
2 |
Window::postInit(); |
|
202 |
2 |
setVisible(Visible_true); |
|
203 |
|||
204 |
2 |
mConnectButton->requestFocus(); |
|
205 |
|||
206 |
2 |
loadServers(true); |
|
207 |
|||
208 |
2 |
mServersList->setSelected(0); // Do this after for the Delete button |
|
209 |
|||
210 |
✓✓ | 2 |
if (needUpdateServers()) |
211 |
1 |
downloadServerList(); |
|
212 |
else |
||
213 |
1 |
logger->log("Skipping servers list update"); |
|
214 |
2 |
} |
|
215 |
|||
216 |
14 |
ServerDialog::~ServerDialog() |
|
217 |
{ |
||
218 |
✓✓ | 2 |
if (mDownload != nullptr) |
219 |
{ |
||
220 |
1 |
mDownload->cancel(); |
|
221 |
✓✗ | 1 |
delete2(mDownload) |
222 |
} |
||
223 |
✓✗ | 4 |
delete2(mServersListModel) |
224 |
4 |
} |
|
225 |
|||
226 |
void ServerDialog::connectToSelectedServer() |
||
227 |
{ |
||
228 |
if (client->getState() == State::CONNECT_SERVER) |
||
229 |
return; |
||
230 |
|||
231 |
const int index = mServersList->getSelected(); |
||
232 |
if (index < 0) |
||
233 |
return; |
||
234 |
|||
235 |
if (mDownload != nullptr) |
||
236 |
mDownload->cancel(); |
||
237 |
|||
238 |
mQuitButton->setEnabled(false); |
||
239 |
mConnectButton->setEnabled(false); |
||
240 |
mLoadButton->setEnabled(false); |
||
241 |
|||
242 |
ServerInfo server = mServers.at(index); |
||
243 |
mServerInfo->hostname = server.hostname; |
||
244 |
mServerInfo->althostname = server.althostname; |
||
245 |
mServerInfo->port = server.port; |
||
246 |
mServerInfo->type = server.type; |
||
247 |
mServerInfo->name = server.name; |
||
248 |
mServerInfo->description = server.description; |
||
249 |
mServerInfo->registerUrl = server.registerUrl; |
||
250 |
mServerInfo->onlineListUrl = server.onlineListUrl; |
||
251 |
mServerInfo->supportUrl = server.supportUrl; |
||
252 |
mServerInfo->defaultHostName = server.defaultHostName; |
||
253 |
mServerInfo->save = true; |
||
254 |
mServerInfo->persistentIp = server.persistentIp; |
||
255 |
mServerInfo->freeType = server.freeType; |
||
256 |
mServerInfo->updateMirrors = server.updateMirrors; |
||
257 |
mServerInfo->packetVersion = server.packetVersion; |
||
258 |
mServerInfo->updateHosts = server.updateHosts; |
||
259 |
mServerInfo->freeSources = server.freeSources; |
||
260 |
mServerInfo->nonFreeSources = server.nonFreeSources; |
||
261 |
mServerInfo->docs = server.docs; |
||
262 |
mServerInfo->serverUrl = server.serverUrl; |
||
263 |
|||
264 |
settings.persistentIp = mServerInfo->persistentIp; |
||
265 |
settings.supportUrl = mServerInfo->supportUrl; |
||
266 |
settings.updateMirrors = mServerInfo->updateMirrors; |
||
267 |
|||
268 |
if (chatLogger != nullptr) |
||
269 |
chatLogger->setServerName(mServerInfo->hostname); |
||
270 |
|||
271 |
saveCustomServers(*mServerInfo, |
||
272 |
-1); |
||
273 |
|||
274 |
if (!LoginDialog::savedPasswordKey.empty()) |
||
275 |
{ |
||
276 |
if (mServerInfo->hostname != LoginDialog::savedPasswordKey) |
||
277 |
{ |
||
278 |
LoginDialog::savedPassword.clear(); |
||
279 |
if (desktop != nullptr) |
||
280 |
desktop->reloadWallpaper(); |
||
281 |
} |
||
282 |
} |
||
283 |
|||
284 |
config.setValue("usePersistentIP", |
||
285 |
mPersistentIPCheckBox->isSelected()); |
||
286 |
client->setState(State::CONNECT_SERVER); |
||
287 |
} |
||
288 |
|||
289 |
void ServerDialog::action(const ActionEvent &event) |
||
290 |
{ |
||
291 |
const std::string &eventId = event.getId(); |
||
292 |
if (eventId == "connect") |
||
293 |
{ |
||
294 |
connectToSelectedServer(); |
||
295 |
} |
||
296 |
else if (eventId == "quit") |
||
297 |
{ |
||
298 |
close(); |
||
299 |
} |
||
300 |
else if (eventId == "load") |
||
301 |
{ |
||
302 |
downloadServerList(); |
||
303 |
} |
||
304 |
else if (eventId == "addEntry") |
||
305 |
{ |
||
306 |
CREATEWIDGET(EditServerDialog, this, ServerInfo(), -1); |
||
307 |
} |
||
308 |
else if (eventId == "editEntry") |
||
309 |
{ |
||
310 |
const int index = mServersList->getSelected(); |
||
311 |
if (index >= 0) |
||
312 |
{ |
||
313 |
CREATEWIDGET(EditServerDialog, |
||
314 |
this, |
||
315 |
mServers.at(index), |
||
316 |
index); |
||
317 |
} |
||
318 |
} |
||
319 |
else if (eventId == "remove") |
||
320 |
{ |
||
321 |
const int index = mServersList->getSelected(); |
||
322 |
if (index >= 0) |
||
323 |
{ |
||
324 |
mServersList->setSelected(0); |
||
325 |
mServers.erase(mServers.begin() + index); |
||
326 |
saveCustomServers(ServerInfo(), |
||
327 |
-1); |
||
328 |
} |
||
329 |
} |
||
330 |
else if (eventId == "info") |
||
331 |
{ |
||
332 |
const int index = mServersList->getSelected(); |
||
333 |
if (index >= 0) |
||
334 |
{ |
||
335 |
if (serverInfoWindow != nullptr) |
||
336 |
serverInfoWindow->scheduleDelete(); |
||
337 |
serverInfoWindow = CREATEWIDGETR(ServerInfoWindow, |
||
338 |
mServers.at(index)); |
||
339 |
} |
||
340 |
} |
||
341 |
} |
||
342 |
|||
343 |
void ServerDialog::keyPressed(KeyEvent &event) |
||
344 |
{ |
||
345 |
PRAGMA45(GCC diagnostic push) |
||
346 |
PRAGMA45(GCC diagnostic ignored "-Wswitch-enum") |
||
347 |
switch (event.getActionId()) |
||
348 |
{ |
||
349 |
case InputAction::GUI_CANCEL: |
||
350 |
event.consume(); |
||
351 |
client->setState(State::EXIT); |
||
352 |
return; |
||
353 |
|||
354 |
case InputAction::GUI_SELECT: |
||
355 |
case InputAction::GUI_SELECT2: |
||
356 |
event.consume(); |
||
357 |
action(ActionEvent(nullptr, |
||
358 |
mConnectButton->getActionEventId())); |
||
359 |
return; |
||
360 |
|||
361 |
case InputAction::GUI_INSERT: |
||
362 |
CREATEWIDGET(EditServerDialog, this, ServerInfo(), -1); |
||
363 |
return; |
||
364 |
|||
365 |
case InputAction::GUI_DELETE: |
||
366 |
{ |
||
367 |
const int index = mServersList->getSelected(); |
||
368 |
if (index >= 0) |
||
369 |
{ |
||
370 |
mServersList->setSelected(0); |
||
371 |
mServers.erase(mServers.begin() + index); |
||
372 |
saveCustomServers(ServerInfo(), |
||
373 |
-1); |
||
374 |
} |
||
375 |
return; |
||
376 |
} |
||
377 |
|||
378 |
case InputAction::GUI_BACKSPACE: |
||
379 |
{ |
||
380 |
const int index = mServersList->getSelected(); |
||
381 |
if (index >= 0) |
||
382 |
{ |
||
383 |
CREATEWIDGET(EditServerDialog, this, mServers.at(index), |
||
384 |
index); |
||
385 |
} |
||
386 |
return; |
||
387 |
} |
||
388 |
|||
389 |
default: |
||
390 |
break; |
||
391 |
} |
||
392 |
PRAGMA45(GCC diagnostic pop) |
||
393 |
if (!event.isConsumed()) |
||
394 |
mServersList->keyPressed(event); |
||
395 |
} |
||
396 |
|||
397 |
4 |
void ServerDialog::valueChanged(const SelectionEvent &event A_UNUSED) |
|
398 |
{ |
||
399 |
8 |
const int index = mServersList->getSelected(); |
|
400 |
✗✓ | 4 |
if (index == -1) |
401 |
{ |
||
402 |
mDeleteButton->setEnabled(false); |
||
403 |
return; |
||
404 |
} |
||
405 |
4 |
mDeleteButton->setEnabled(true); |
|
406 |
} |
||
407 |
|||
408 |
void ServerDialog::mouseClicked(MouseEvent &event) |
||
409 |
{ |
||
410 |
if (event.getButton() == MouseButton::LEFT) |
||
411 |
{ |
||
412 |
event.consume(); |
||
413 |
if (event.getClickCount() == 2 && |
||
414 |
event.getSource() == mServersList) |
||
415 |
{ |
||
416 |
action(ActionEvent(mConnectButton, |
||
417 |
mConnectButton->getActionEventId())); |
||
418 |
} |
||
419 |
} |
||
420 |
} |
||
421 |
|||
422 |
void ServerDialog::logic() |
||
423 |
{ |
||
424 |
BLOCK_START("ServerDialog::logic") |
||
425 |
{ |
||
426 |
MutexLocker tempLock(&mMutex); |
||
427 |
if (mDownloadStatus == ServerDialogDownloadStatus::COMPLETE) |
||
428 |
{ |
||
429 |
loadServers(true); |
||
430 |
mDownloadStatus = ServerDialogDownloadStatus::OVER; |
||
431 |
mDescription->setCaption(std::string()); |
||
432 |
logger->log("Servers list updated"); |
||
433 |
} |
||
434 |
else if (mDownloadStatus == ServerDialogDownloadStatus::IN_PROGRESS) |
||
435 |
{ |
||
436 |
// TRANSLATORS: servers dialog label |
||
437 |
mDescription->setCaption(strprintf(_("Downloading server list..." |
||
438 |
"%2.2f%%"), static_cast<double>(mDownloadProgress * 100))); |
||
439 |
} |
||
440 |
else if (mDownloadStatus == ServerDialogDownloadStatus::IDLE) |
||
441 |
{ |
||
442 |
// TRANSLATORS: servers dialog label |
||
443 |
mDescription->setCaption(_("Waiting for server...")); |
||
444 |
} |
||
445 |
else if (mDownloadStatus == ServerDialogDownloadStatus::PREPARING) |
||
446 |
{ |
||
447 |
// TRANSLATORS: servers dialog label |
||
448 |
mDescription->setCaption(_("Preparing download")); |
||
449 |
} |
||
450 |
else if (mDownloadStatus == ServerDialogDownloadStatus::ERROR) |
||
451 |
{ |
||
452 |
// TRANSLATORS: servers dialog label |
||
453 |
mDescription->setCaption(_("Error retreiving server list!")); |
||
454 |
logger->log("Error: servers list updating error"); |
||
455 |
} |
||
456 |
} |
||
457 |
|||
458 |
Window::logic(); |
||
459 |
BLOCK_END("ServerDialog::logic") |
||
460 |
} |
||
461 |
|||
462 |
1 |
void ServerDialog::downloadServerList() |
|
463 |
{ |
||
464 |
// Try to load the configuration value for the onlineServerList |
||
465 |
✓✗ | 5 |
std::string listFile = branding.getStringValue("onlineServerList"); |
466 |
✓✗✓✗ |
5 |
std::string listFile2 = branding.getStringValue("onlineServerList2"); |
467 |
|||
468 |
// Fall back to manaplus.org when neither branding |
||
469 |
// nor config set it |
||
470 |
✗✓ | 1 |
if (listFile.empty()) |
471 |
listFile = "http://manaplus.org/serverlist.xml"; |
||
472 |
|||
473 |
✗✓ | 1 |
if (mDownload != nullptr) |
474 |
{ |
||
475 |
mDownload->cancel(); |
||
476 |
delete2(mDownload) |
||
477 |
} |
||
478 |
|||
479 |
1 |
mDownload = new Net::Download(this, listFile, |
|
480 |
✓✗✓✗ |
1 |
&downloadUpdate, false, false, true); |
481 |
✓✗ | 4 |
mDownload->setFile(pathJoin(mDir, |
482 |
✓✗✓✗ |
5 |
branding.getStringValue("onlineServerFile")), |
483 |
✓✗ | 1 |
-1); |
484 |
✓✗ | 1 |
if (!listFile2.empty()) |
485 |
1 |
mDownload->addMirror(listFile2); |
|
486 |
✓✗ | 1 |
mDownload->start(); |
487 |
|||
488 |
✓✗✓✗ ✓✗ |
5 |
config.setValue("serverslistupdate", getDateString()); |
489 |
1 |
} |
|
490 |
|||
491 |
2 |
static void loadHostsGroup(XmlNodeConstPtr node, |
|
492 |
ServerInfo &server) |
||
493 |
{ |
||
494 |
4 |
HostsGroup group; |
|
495 |
✓✗✓✗ |
10 |
group.name = XML::langProperty(node, |
496 |
"name", |
||
497 |
// TRANSLATORS: unknown hosts group name |
||
498 |
4 |
_("Unknown")); |
|
499 |
✓✓ | 8 |
for_each_xml_child_node(hostNode, node) |
500 |
{ |
||
501 |
✓✗✓✓ ✓✗✓✓ |
14 |
if (!xmlNameEqual(hostNode, "host") || |
502 |
✓✗ | 4 |
!XmlHaveChildContent(hostNode)) |
503 |
{ |
||
504 |
4 |
continue; |
|
505 |
} |
||
506 |
✓✗ | 8 |
const std::string host = XmlChildContent(hostNode); |
507 |
✓✗ | 2 |
if (host.empty()) |
508 |
continue; |
||
509 |
✓✗✗✓ |
2 |
if (!checkPath(host)) |
510 |
{ |
||
511 |
logger->log1("Warning: incorrect update server name"); |
||
512 |
continue; |
||
513 |
} |
||
514 |
|||
515 |
✓✗ | 2 |
group.hosts.push_back(host); |
516 |
} |
||
517 |
✓✗ | 2 |
if (!group.hosts.empty()) |
518 |
✓✗ | 2 |
server.updateHosts.push_back(group); |
519 |
2 |
} |
|
520 |
|||
521 |
static void loadServerSourcesList(XmlNodeConstPtr node, |
||
522 |
STD_VECTOR<ServerUrlInfo> &list) |
||
523 |
{ |
||
524 |
for_each_xml_child_node(urlNode, node) |
||
525 |
{ |
||
526 |
if (!xmlNameEqual(urlNode, "url") || |
||
527 |
!XmlHaveChildContent(urlNode)) |
||
528 |
{ |
||
529 |
continue; |
||
530 |
} |
||
531 |
const std::string name = XML::langProperty(urlNode, |
||
532 |
"name", |
||
533 |
""); |
||
534 |
if (name.empty()) |
||
535 |
continue; |
||
536 |
const std::string url = XmlChildContent(urlNode); |
||
537 |
if (url.empty()) |
||
538 |
continue; |
||
539 |
list.push_back(ServerUrlInfo(name, url)); |
||
540 |
} |
||
541 |
} |
||
542 |
|||
543 |
static void loadServerSources(XmlNodeConstPtr node, |
||
544 |
ServerInfo &server) |
||
545 |
{ |
||
546 |
for_each_xml_child_node(subNode, node) |
||
547 |
{ |
||
548 |
if (xmlNameEqual(subNode, "free")) |
||
549 |
{ |
||
550 |
loadServerSourcesList(subNode, server.freeSources); |
||
551 |
} |
||
552 |
else if (xmlNameEqual(subNode, "nonfree")) |
||
553 |
{ |
||
554 |
loadServerSourcesList(subNode, server.nonFreeSources); |
||
555 |
} |
||
556 |
} |
||
557 |
} |
||
558 |
|||
559 |
2 |
void ServerDialog::loadServers(const bool addNew) |
|
560 |
{ |
||
561 |
✓✗ | 8 |
XML::Document doc(pathJoin(mDir, |
562 |
✓✗ | 8 |
branding.getStringValue("onlineServerFile")), |
563 |
UseVirtFs_false, |
||
564 |
✓✗ | 6 |
SkipError_true); |
565 |
✓✗ | 2 |
XmlNodeConstPtr rootNode = doc.rootNode(); |
566 |
|||
567 |
✓✗✗✓ ✗✓ |
4 |
if (rootNode == nullptr || |
568 |
✓✗ | 2 |
!xmlNameEqual(rootNode, "serverlist")) |
569 |
{ |
||
570 |
logger->log1("Error loading server list!"); |
||
571 |
return; |
||
572 |
} |
||
573 |
|||
574 |
✓✗ | 2 |
const int ver = XML::getProperty(rootNode, "version", 0); |
575 |
✗✓ | 2 |
if (ver != 1) |
576 |
{ |
||
577 |
logger->log("Error: unsupported online server list version: %d", |
||
578 |
ver); |
||
579 |
return; |
||
580 |
} |
||
581 |
|||
582 |
✓✗ | 4 |
const std::string lang = getLangShort(); |
583 |
✓✗ | 4 |
const std::string description2("description_" + lang); |
584 |
|||
585 |
✓✓ | 36 |
for_each_xml_child_node(serverNode, rootNode) |
586 |
{ |
||
587 |
✓✗✓✓ |
34 |
if (!xmlNameEqual(serverNode, "server")) |
588 |
20 |
continue; |
|
589 |
|||
590 |
const std::string type = XML::getProperty( |
||
591 |
✓✗✓✗ |
70 |
serverNode, "type", "unknown"); |
592 |
28 |
ServerInfo server; |
|
593 |
✓✗ | 14 |
server.type = ServerInfo::parseType(type); |
594 |
const std::string licenseType = XML::getProperty( |
||
595 |
✓✗✓✗ |
70 |
serverNode, "licenseType", "notset"); |
596 |
✓✗ | 14 |
server.freeType = ServerInfo::parseFreeType(licenseType); |
597 |
|||
598 |
// Ignore unknown server types |
||
599 |
✗✓ | 14 |
if (server.type == ServerType::UNKNOWN) |
600 |
{ |
||
601 |
logger->log("Ignoring server entry with unknown type: %s", |
||
602 |
type.c_str()); |
||
603 |
continue; |
||
604 |
} |
||
605 |
|||
606 |
✓✗ | 42 |
server.name = XML::getProperty(serverNode, "name", std::string()); |
607 |
std::string version = XML::getProperty(serverNode, "minimumVersion", |
||
608 |
✓✗ | 42 |
std::string()); |
609 |
|||
610 |
✓✗✓✗ |
56 |
const bool meetsMinimumVersion = (compareStrI(version, SMALL_VERSION) |
611 |
14 |
<= 0); |
|
612 |
|||
613 |
// For display in the list |
||
614 |
✓✗ | 14 |
if (meetsMinimumVersion) |
615 |
version.clear(); |
||
616 |
else if (version.empty()) |
||
617 |
{ |
||
618 |
// TRANSLATORS: servers dialog label |
||
619 |
version = _("requires a newer version"); |
||
620 |
} |
||
621 |
else |
||
622 |
{ |
||
623 |
// TRANSLATORS: servers dialog label |
||
624 |
version = strprintf(_("requires v%s"), version.c_str()); |
||
625 |
} |
||
626 |
|||
627 |
28 |
const Font *const font = gui->getFont(); |
|
628 |
|||
629 |
✓✓ | 524 |
for_each_xml_child_node(subNode, serverNode) |
630 |
{ |
||
631 |
✓✗✓✓ |
510 |
if (xmlNameEqual(subNode, "connection")) |
632 |
{ |
||
633 |
✓✗✓✗ |
70 |
server.hostname = XML::getProperty(subNode, "hostname", ""); |
634 |
✓✗✓✗ |
70 |
server.althostname = XML::getProperty( |
635 |
14 |
subNode, "althostname", ""); |
|
636 |
14 |
server.port = CAST_U16( |
|
637 |
✓✗ | 14 |
XML::getProperty(subNode, "port", 0)); |
638 |
✓✗ | 14 |
server.packetVersion = XML::getProperty(subNode, |
639 |
"packetVersion", 0); |
||
640 |
|||
641 |
✗✓ | 14 |
if (server.port == 0) |
642 |
{ |
||
643 |
// If no port is given, use the default for the given type |
||
644 |
server.port = defaultPortForServerType(server.type); |
||
645 |
} |
||
646 |
} |
||
647 |
✓✓✓✗ |
496 |
else if (XmlHaveChildContent(subNode)) |
648 |
{ |
||
649 |
✓✗✓✓ |
464 |
if ((xmlNameEqual(subNode, "description") |
650 |
✓✓✗✓ ✓✗ |
464 |
&& server.description.empty()) || (!lang.empty() |
651 |
✓✗✓✓ |
218 |
&& xmlNameEqual(subNode, description2.c_str()))) |
652 |
{ |
||
653 |
26 |
server.description = XmlChildContent(subNode); |
|
654 |
} |
||
655 |
✓✗✓✓ |
206 |
else if (xmlNameEqual(subNode, "registerurl")) |
656 |
{ |
||
657 |
2 |
server.registerUrl = XmlChildContent(subNode); |
|
658 |
} |
||
659 |
✓✗✓✓ |
204 |
else if (xmlNameEqual(subNode, "onlineListUrl")) |
660 |
{ |
||
661 |
2 |
server.onlineListUrl = XmlChildContent(subNode); |
|
662 |
} |
||
663 |
✓✗✓✓ |
202 |
else if (xmlNameEqual(subNode, "support")) |
664 |
{ |
||
665 |
10 |
server.supportUrl = XmlChildContent(subNode); |
|
666 |
} |
||
667 |
✓✗✗✓ |
192 |
else if (xmlNameEqual(subNode, "persistentIp")) |
668 |
{ |
||
669 |
std::string text = XmlChildContent(subNode); |
||
670 |
server.persistentIp = (text == "1" || text == "true"); |
||
671 |
} |
||
672 |
✓✗✓✓ |
192 |
else if (xmlNameEqual(subNode, "updateMirror")) |
673 |
{ |
||
674 |
✓✗ | 40 |
server.updateMirrors.push_back(XmlChildContent(subNode)); |
675 |
} |
||
676 |
✓✗✓✓ |
184 |
else if (xmlNameEqual(subNode, "site")) |
677 |
{ |
||
678 |
14 |
server.serverUrl = XmlChildContent(subNode); |
|
679 |
} |
||
680 |
} |
||
681 |
✓✗✓✓ |
510 |
if (xmlNameEqual(subNode, "updates")) |
682 |
{ |
||
683 |
✓✗ | 2 |
loadHostsGroup(subNode, server); |
684 |
} |
||
685 |
✓✗✓✓ |
508 |
else if (xmlNameEqual(subNode, "defaultUpdateHost")) |
686 |
{ |
||
687 |
✓✗✓✗ |
10 |
server.defaultHostName = XML::langProperty( |
688 |
// TRANSLATORS: default hosts group name |
||
689 |
4 |
subNode, "name", _("default")); |
|
690 |
} |
||
691 |
✓✗✗✓ |
506 |
else if (xmlNameEqual(subNode, "sources")) |
692 |
{ |
||
693 |
loadServerSources(subNode, server); |
||
694 |
} |
||
695 |
✓✗✗✓ |
506 |
else if (xmlNameEqual(subNode, "docs")) |
696 |
{ |
||
697 |
loadServerSourcesList(subNode, server.docs); |
||
698 |
} |
||
699 |
} |
||
700 |
|||
701 |
✓✗ | 14 |
server.version.first = font->getWidth(version); |
702 |
14 |
server.version.second = version; |
|
703 |
|||
704 |
42 |
MutexLocker tempLock(&mMutex); |
|
705 |
// Add the server to the local list if it's not already present |
||
706 |
14 |
bool found = false; |
|
707 |
56 |
for (unsigned int i = 0, fsz = CAST_U32( |
|
708 |
✓✓ | 28 |
mServers.size()); i < fsz; i++) |
709 |
{ |
||
710 |
✗✓ | 84 |
if (mServers[i] == server) |
711 |
{ |
||
712 |
// Use the name listed in the server list |
||
713 |
mServers[i].name = server.name; |
||
714 |
mServers[i].type = server.type; |
||
715 |
mServers[i].freeType = server.freeType; |
||
716 |
mServers[i].version = server.version; |
||
717 |
mServers[i].description = server.description; |
||
718 |
mServers[i].registerUrl = server.registerUrl; |
||
719 |
mServers[i].onlineListUrl = server.onlineListUrl; |
||
720 |
mServers[i].supportUrl = server.supportUrl; |
||
721 |
mServers[i].serverUrl = server.serverUrl; |
||
722 |
mServers[i].althostname = server.althostname; |
||
723 |
mServers[i].persistentIp = server.persistentIp; |
||
724 |
mServers[i].updateMirrors = server.updateMirrors; |
||
725 |
mServers[i].defaultHostName = server.defaultHostName; |
||
726 |
mServers[i].updateHosts = server.updateHosts; |
||
727 |
mServers[i].packetVersion = server.packetVersion; |
||
728 |
mServers[i].freeSources = server.freeSources; |
||
729 |
mServers[i].nonFreeSources = server.nonFreeSources; |
||
730 |
mServers[i].docs = server.docs; |
||
731 |
mServersListModel->setVersionString(i, version); |
||
732 |
found = true; |
||
733 |
break; |
||
734 |
} |
||
735 |
} |
||
736 |
✓✗ | 14 |
if (!found && addNew) |
737 |
✓✗ | 14 |
mServers.push_back(server); |
738 |
} |
||
739 |
✓✗ | 4 |
if (mServersList->getSelected() < 0) |
740 |
✓✗ | 2 |
mServersList->setSelected(0); |
741 |
} |
||
742 |
|||
743 |
2 |
void ServerDialog::loadCustomServers() |
|
744 |
{ |
||
745 |
✓✓ | 32 |
for (int i = 0; i < MAX_SERVERLIST; ++i) |
746 |
{ |
||
747 |
30 |
const std::string index = toString(i); |
|
748 |
✓✗ | 30 |
const std::string nameKey("MostUsedServerDescName" + index); |
749 |
✓✗ | 30 |
const std::string descKey("MostUsedServerDescription" + index); |
750 |
✓✗ | 30 |
const std::string hostKey("MostUsedServerName" + index); |
751 |
✓✗ | 30 |
const std::string typeKey("MostUsedServerType" + index); |
752 |
✓✗ | 30 |
const std::string portKey("MostUsedServerPort" + index); |
753 |
const std::string onlineListUrlKey |
||
754 |
✓✗ | 30 |
("MostUsedServerOnlineList" + index); |
755 |
✓✗ | 30 |
const std::string persistentIpKey("persistentIp" + index); |
756 |
const std::string packetVersionKey |
||
757 |
✓✗ | 30 |
("MostUsedServerPacketVersion" + index); |
758 |
|||
759 |
30 |
ServerInfo server; |
|
760 |
✓✗✓✗ |
150 |
server.name = config.getValue(nameKey, ""); |
761 |
✓✗✓✗ |
150 |
server.description = config.getValue(descKey, ""); |
762 |
✓✗✓✗ |
150 |
server.onlineListUrl = config.getValue(onlineListUrlKey, ""); |
763 |
✓✗✓✗ |
150 |
server.hostname = config.getValue(hostKey, ""); |
764 |
✓✗✓✗ ✓✗ |
150 |
server.type = ServerInfo::parseType(config.getValue(typeKey, "")); |
765 |
✓✗ | 60 |
server.persistentIp = config.getValue( |
766 |
30 |
persistentIpKey, 0) != 0 ? true : false; |
|
767 |
✓✗ | 30 |
server.packetVersion = config.getValue(packetVersionKey, 0); |
768 |
|||
769 |
60 |
const int defaultPort = defaultPortForServerType(server.type); |
|
770 |
30 |
server.port = CAST_U16( |
|
771 |
✓✗ | 30 |
config.getValue(portKey, defaultPort)); |
772 |
|||
773 |
// skip invalid server |
||
774 |
✗✓ | 30 |
if (!server.isValid()) |
775 |
30 |
continue; |
|
776 |
|||
777 |
server.save = true; |
||
778 |
mServers.push_back(server); |
||
779 |
} |
||
780 |
2 |
} |
|
781 |
|||
782 |
void ServerDialog::saveCustomServers(const ServerInfo ¤tServer, |
||
783 |
const int index) |
||
784 |
{ |
||
785 |
// Make sure the current server is mentioned first |
||
786 |
if (currentServer.isValid()) |
||
787 |
{ |
||
788 |
if (index >= 0 && CAST_SIZE(index) < mServers.size()) |
||
789 |
{ |
||
790 |
mServers[index] = currentServer; |
||
791 |
} |
||
792 |
else |
||
793 |
{ |
||
794 |
FOR_EACH (ServerInfos::iterator, i, mServers) |
||
795 |
{ |
||
796 |
if (*i == currentServer) |
||
797 |
{ |
||
798 |
mServers.erase(i); |
||
799 |
break; |
||
800 |
} |
||
801 |
} |
||
802 |
mServers.insert(mServers.begin(), currentServer); |
||
803 |
} |
||
804 |
} |
||
805 |
|||
806 |
int savedServerCount = 0; |
||
807 |
|||
808 |
for (unsigned i = 0, fsz = CAST_U32(mServers.size()); |
||
809 |
i < fsz && savedServerCount < MAX_SERVERLIST; ++ i) |
||
810 |
{ |
||
811 |
const ServerInfo &server = mServers.at(i); |
||
812 |
|||
813 |
// Only save servers that were loaded from settings |
||
814 |
if (!(server.save && server.isValid())) |
||
815 |
continue; |
||
816 |
|||
817 |
const std::string num = toString(savedServerCount); |
||
818 |
const std::string nameKey("MostUsedServerDescName" + num); |
||
819 |
const std::string descKey("MostUsedServerDescription" + num); |
||
820 |
const std::string hostKey("MostUsedServerName" + num); |
||
821 |
const std::string typeKey("MostUsedServerType" + num); |
||
822 |
const std::string portKey("MostUsedServerPort" + num); |
||
823 |
const std::string onlineListUrlKey |
||
824 |
("MostUsedServerOnlineList" + num); |
||
825 |
const std::string persistentIpKey("persistentIp" + num); |
||
826 |
const std::string packetVersionKey |
||
827 |
("MostUsedServerPacketVersion" + num); |
||
828 |
|||
829 |
config.setValue(nameKey, server.name); |
||
830 |
config.setValue(descKey, server.description); |
||
831 |
config.setValue(onlineListUrlKey, server.onlineListUrl); |
||
832 |
config.setValue(hostKey, server.hostname); |
||
833 |
config.setValue(typeKey, serverTypeToString(server.type)); |
||
834 |
config.setValue(portKey, toString(server.port)); |
||
835 |
config.setValue(persistentIpKey, server.persistentIp); |
||
836 |
config.setValue(packetVersionKey, server.packetVersion); |
||
837 |
++ savedServerCount; |
||
838 |
} |
||
839 |
|||
840 |
// Insert an invalid entry at the end to make the loading stop there |
||
841 |
if (savedServerCount < MAX_SERVERLIST) |
||
842 |
config.setValue("MostUsedServerName" + toString(savedServerCount), ""); |
||
843 |
} |
||
844 |
|||
845 |
int ServerDialog::downloadUpdate(void *ptr, |
||
846 |
const DownloadStatusT status, |
||
847 |
size_t total, |
||
848 |
const size_t remaining) |
||
849 |
{ |
||
850 |
if ((ptr == nullptr) || status == DownloadStatus::Cancelled) |
||
851 |
return -1; |
||
852 |
|||
853 |
ServerDialog *const sd = reinterpret_cast<ServerDialog*>(ptr); |
||
854 |
bool finished = false; |
||
855 |
|||
856 |
if (sd->mDownload == nullptr) |
||
857 |
return -1; |
||
858 |
|||
859 |
if (status == DownloadStatus::Complete) |
||
860 |
{ |
||
861 |
finished = true; |
||
862 |
} |
||
863 |
else if (CAST_S32(status) < 0) |
||
864 |
{ |
||
865 |
logger->log("Error retreiving server list: %s\n", |
||
866 |
sd->mDownload->getError()); |
||
867 |
sd->mDownloadStatus = ServerDialogDownloadStatus::ERROR; |
||
868 |
} |
||
869 |
else |
||
870 |
{ |
||
871 |
float progress = static_cast<float>(remaining); |
||
872 |
if (total != 0U) |
||
873 |
progress /= static_cast<float>(total); |
||
874 |
|||
875 |
if (progress != progress || progress < 0.0F) |
||
876 |
progress = 0.0F; |
||
877 |
else if (progress > 1.0F) |
||
878 |
progress = 1.0F; |
||
879 |
|||
880 |
MutexLocker lock1(&sd->mMutex); |
||
881 |
sd->mDownloadStatus = ServerDialogDownloadStatus::IN_PROGRESS; |
||
882 |
sd->mDownloadProgress = progress; |
||
883 |
} |
||
884 |
|||
885 |
if (finished) |
||
886 |
{ |
||
887 |
MutexLocker lock1(&sd->mMutex); |
||
888 |
sd->mDownloadStatus = ServerDialogDownloadStatus::COMPLETE; |
||
889 |
} |
||
890 |
|||
891 |
return 0; |
||
892 |
} |
||
893 |
|||
894 |
void ServerDialog::updateServer(const ServerInfo &server, const int index) |
||
895 |
{ |
||
896 |
saveCustomServers(server, index); |
||
897 |
} |
||
898 |
|||
899 |
2 |
bool ServerDialog::needUpdateServers() const |
|
900 |
{ |
||
901 |
✓✗✓✗ ✓✗✓✓ ✓✗✓✗ ✓✓✗✗ |
16 |
if (mServers.empty() || config.getStringValue("serverslistupdate") |
902 |
✓✗✗✓ ✗✗ |
8 |
!= getDateString()) |
903 |
{ |
||
904 |
return true; |
||
905 |
} |
||
906 |
|||
907 |
1 |
return false; |
|
908 |
} |
||
909 |
|||
910 |
void ServerDialog::close() |
||
911 |
{ |
||
912 |
if (mDownload != nullptr) |
||
913 |
mDownload->cancel(); |
||
914 |
client->setState(State::FORCE_QUIT); |
||
915 |
Window::close(); |
||
916 |
✓✗✓✗ |
3 |
} |
Generated by: GCOVR (Version 3.3) |