serverstructs.cpp
1 //------------------------------------------------------------------------------
2 // serverstructs.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "serverstructs.h"
24 #include "wadseeker/entities/checksum.h"
25 #include "wadseeker/entities/hash.h"
26 #include "wadseeker/entities/modfile.h"
27 #include <QRegularExpression>
28 #include <QVector>
29 
30 
31 static QString coerceInternalName(const QString &name)
32 {
33  return name.toLower().remove(QRegularExpression("[^a-z0-9]"));
34 }
35 
36 
37 DClass<DMFlag>
38 {
39 public:
40  QString name;
41  unsigned value;
42  QString internalName;
43 
44  void setInternalName(const QString &name)
45  {
46  internalName = coerceInternalName(name);
47  }
48 };
49 
50 DPointered(DMFlag)
51 
52 DMFlag::DMFlag()
53 {
54  d->value = 0;
55 }
56 
57 DMFlag::DMFlag(const QString &internalName, unsigned value)
58 {
59  d->name = internalName;
60  d->setInternalName(internalName);
61  d->value = value;
62 }
63 
64 DMFlag::DMFlag(const QString &internalName, unsigned value, const QString &name)
65 {
66  d->name = name;
67  d->setInternalName(internalName);
68  d->value = value;
69 }
70 
71 DMFlag::DMFlag(const DMFlag &other)
72 {
73  this->d = other.d;
74 }
75 
76 DMFlag::~DMFlag()
77 {
78 }
79 
80 DMFlag &DMFlag::operator=(const DMFlag &other)
81 {
82  if (this != &other)
83  this->d = other.d;
84  return *this;
85 }
86 
87 const QString &DMFlag::internalName() const
88 {
89  return d->internalName;
90 }
91 
92 bool DMFlag::isValid() const
93 {
94  return value() > 0;
95 }
96 
97 const QString &DMFlag::name() const
98 {
99  return d->name;
100 }
101 
102 unsigned DMFlag::value() const
103 {
104  return d->value;
105 }
106 
108 
109 DClass<DMFlagsSection>
110 {
111 public:
112  QString name;
113  QString internalName;
114  QVector<DMFlag> flags;
115 
116  void setInternalName(const QString &name)
117  {
118  internalName = coerceInternalName(name);
119  }
120 };
121 
122 DPointered(DMFlagsSection)
123 
125 {
126 }
127 
128 DMFlagsSection::DMFlagsSection(const QString &internalName)
129 {
130  d->name = internalName;
131  d->setInternalName(internalName);
132 }
133 
134 DMFlagsSection::DMFlagsSection(const QString &internalName, const QString &name)
135 {
136  d->name = name;
137  d->setInternalName(internalName);
138 }
139 
140 DMFlagsSection::DMFlagsSection(const DMFlagsSection &other)
141 {
142  this->d = other.d;
143 }
144 
145 DMFlagsSection::~DMFlagsSection()
146 {
147 }
148 
149 DMFlagsSection &DMFlagsSection::operator=(const DMFlagsSection &other)
150 {
151  if (this != &other)
152  this->d = other.d;
153  return *this;
154 }
155 
156 void DMFlagsSection::add(const DMFlag &flag)
157 {
158  d->flags << flag;
159 }
160 
162 {
163  unsigned result = 0;
164  for (const DMFlag &flag : d->flags)
165  {
166  result |= flag.value();
167  }
168  return result;
169 }
170 
172 {
173  DMFlagsSection copy = *this;
174  copy.d->flags.clear();
175  return copy;
176 }
177 
179 {
180  return d->flags.count();
181 }
182 
183 const QString &DMFlagsSection::internalName() const
184 {
185  return d->internalName;
186 }
187 
189 {
190  return count() == 0;
191 }
192 
193 const QString &DMFlagsSection::name() const
194 {
195  return d->name;
196 }
197 
198 const DMFlag &DMFlagsSection::operator[](int index) const
199 {
200  return d->flags[index];
201 }
202 
204 {
205  return d->flags[index];
206 }
207 
208 QList<DMFlagsSection> DMFlagsSection::removedBySection(
209  const QList<DMFlagsSection> &original,
210  const QList<DMFlagsSection> &removals)
211 {
212  QList<DMFlagsSection> copy;
213  for (const DMFlagsSection &section : original)
214  {
215  bool removed = false;
216  for (const DMFlagsSection &removal : removals)
217  {
218  if (section.internalName() == removal.internalName())
219  {
220  copy << section.removed(removal);
221  removed = true;
222  break;
223  }
224  }
225  if (!removed)
226  {
227  copy << section;
228  }
229  }
230  return copy;
231 }
232 
234 {
235  DMFlagsSection copy = *this;
236  for (const DMFlag &removal : removals.d->flags)
237  {
238  QMutableVectorIterator<DMFlag> i(copy.d->flags);
239  while (i.hasNext())
240  {
241  DMFlag &flag = i.next();
242  if (flag.value() == removal.value())
243  {
244  i.remove();
245  break;
246  }
247  }
248  }
249  return copy;
250 }
251 
253 
254 DClass<GameCVar>
255 {
256 public:
257  QString command;
258  QString name;
259  QVariant value;
260 };
261 
262 DPointered(GameCVar)
263 
265 {
266 }
267 
268 GameCVar::GameCVar(const QString &name, const QString &command)
269 {
270  d->name = name;
271  d->command = command;
272 }
273 
274 GameCVar::GameCVar(const QString &name, const QString &command, const QVariant &value)
275 {
276  d->name = name;
277  d->command = command;
278  setValue(value);
279 }
280 
281 GameCVar::GameCVar(const GameCVar &other)
282 {
283  this->d = other.d;
284 }
285 
286 GameCVar::~GameCVar()
287 {
288 }
289 
290 GameCVar &GameCVar::operator=(const GameCVar &other)
291 {
292  if (this != &other)
293  this->d = other.d;
294  return *this;
295 }
296 
297 const QString &GameCVar::command() const
298 {
299  return d->command;
300 }
301 
302 bool GameCVar::hasValue() const
303 {
304  return value().isValid();
305 }
306 
307 bool GameCVar::isValid() const
308 {
309  return !command().isEmpty();
310 }
311 
312 const QString &GameCVar::name() const
313 {
314  return d->name;
315 }
316 
317 void GameCVar::setValue(const QVariant &value)
318 {
319  d->value = value;
320 }
321 
322 const QVariant &GameCVar::value() const
323 {
324  return d->value;
325 }
326 
328 
329 DClass<GameCVarProvider>
330 {
331 };
332 
333 DPointeredNoCopy(GameCVarProvider)
334 
336 {
337 }
338 
339 GameCVarProvider::~GameCVarProvider()
340 {
341 }
342 
343 QList<GameCVar> GameCVarProvider::get(const QVariant &context)
344 {
345  Q_UNUSED(context);
346  return QList<GameCVar>();
347 }
348 
350 
351 DClass<GameMode>
352 {
353 public:
354  gamemode_id index;
355  QString name;
356  bool teamgame;
357 };
358 
359 DPointered(GameMode)
360 
362 {
363  d->index = SGM_Unknown;
364  d->teamgame = false;
365 }
366 
367 GameMode::GameMode(gamemode_id index, const QString &name)
368 {
369  d->index = index;
370  d->name = name;
371  d->teamgame = false;
372 }
373 
374 GameMode::GameMode(const GameMode &other)
375 {
376  this->d = other.d;
377 }
378 
379 GameMode::~GameMode()
380 {
381 }
382 
383 GameMode &GameMode::operator=(const GameMode &other)
384 {
385  if (this != &other)
386  this->d = other.d;
387  return *this;
388 }
389 
390 GameMode GameMode::ffaGame(int index, const QString &name)
391 {
392  GameMode result(index, name);
393  result.setTeamGame(false);
394  return result;
395 }
396 
398 {
399  return d->index;
400 }
401 
402 GameMode GameMode::mkCooperative()
403 {
404  return ffaGame(SGM_Cooperative, QObject::tr("Cooperative"));
405 }
406 
407 GameMode GameMode::mkDeathmatch()
408 {
409  return ffaGame(SGM_Deathmatch, QObject::tr("Deathmatch"));
410 }
411 
412 GameMode GameMode::mkTeamDeathmatch()
413 {
414  return teamGame(SGM_TeamDeathmatch, QObject::tr("Team DM"));
415 }
416 
417 GameMode GameMode::mkCaptureTheFlag()
418 {
419  return teamGame(SGM_CTF, QObject::tr("CTF"));
420 }
421 
422 GameMode GameMode::mkUnknown()
423 {
424  return ffaGame(SGM_Unknown, QObject::tr("Unknown"));
425 }
426 
427 const QString &GameMode::name() const
428 {
429  return d->name;
430 }
431 
433 {
434  return d->teamgame;
435 }
436 
437 bool GameMode::isValid() const
438 {
439  return !d->name.isEmpty();
440 }
441 
442 void GameMode::setTeamGame(bool b)
443 {
444  d->teamgame = b;
445 }
446 
447 GameMode GameMode::teamGame(int index, const QString &name)
448 {
449  GameMode result(index, name);
450  result.setTeamGame(true);
451  return result;
452 }
453 
455 
456 DClass<PWad>
457 {
458 public:
459  QString name;
460  bool optional;
461  QList<Checksum> checksums;
462 };
463 
464 DPointered(PWad)
465 
466 PWad::PWad(const QString &name, bool optional, const QList<Checksum> &checksums)
467 {
468  d->name = name;
469  d->optional = optional;
470  d->checksums = checksums;
471 }
472 
473 PWad::PWad(const QString &name, bool optional)
474 {
475  d->name = name;
476  d->optional = optional;
477 }
478 
479 PWad::PWad(const ModFile &modFile)
480 {
481  d->name = modFile.fileName();
482  d->optional = false;
483  d->checksums = modFile.checksums();
484 }
485 
486 PWad::PWad(const PWad &other)
487 {
488  this->d = other.d;
489 }
490 
491 PWad::~PWad()
492 {
493 }
494 
495 PWad &PWad::operator=(const PWad &other)
496 {
497  if (this != &other)
498  this->d = other.d;
499  return *this;
500 }
501 
502 PWad::operator ModFile()
503 {
504  ModFile modFile(d->name);
505  modFile.setChecksums(d->checksums);
506  return modFile;
507 }
508 
509 bool PWad::isOptional() const
510 {
511  return d->optional;
512 }
513 
514 const QString &PWad::name() const
515 {
516  return d->name;
517 }
518 
519 const QList<Checksum> PWad::checksums() const
520 {
521  return d->checksums;
522 }
523 
524 void PWad::addChecksum(const QByteArray &hash, const QCryptographicHash::Algorithm &algorithm)
525 {
526  d->checksums.append(Checksum(hash, algorithm));
527 }
528 
529 bool PWad::validFile(const QString &path) const
530 {
531  for (const Checksum checksum : d->checksums)
532  {
533  if (Hash::hashFile(path, checksum.algorithm()) != checksum.hash())
534  {
535  return false;
536  }
537  }
538  return true;
539 }