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