swift
server.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/network/server.h"
5 
6 #include <Qt>
7 #include <QtGlobal>
8 
10 #include "misc/logcategories.h"
11 #include "misc/obfuscation.h"
12 #include "misc/propertyindexref.h"
13 #include "misc/statusmessage.h"
14 #include "misc/stringutils.h"
15 #include "misc/verify.h"
16 
17 SWIFT_DEFINE_VALUEOBJECT_MIXINS(swift::misc::network, CServer)
18 
19 namespace swift::misc::network
20 {
21  CServer::CServer(const QString &name, const QString &description, const QString &address, int port,
22  const CUser &user, const CFsdSetup &fsdSetup, const CEcosystem &ecosytem,
23  bool isAcceptingConnections)
24  : m_name(CObfuscation::decode(name)), m_description(CObfuscation::decode(description)),
25  m_address(CObfuscation::decode(address)), m_port(port), m_user(user), m_ecosystem(ecosytem),
26  m_isAcceptingConnections(isAcceptingConnections), m_fsdSetup(fsdSetup)
27  {}
28 
29  CServer::CServer(const QString &address, int port, const CUser &user)
30  : m_name("no name"), m_description("min.configuration"), m_address(address), m_port(port), m_user(user)
31  {}
32 
33  CServer::CServer(const CEcosystem &ecosystem) { this->setEcosystem(ecosystem); }
34 
36  {
37  return QStringLiteral("%1 %2 %3:%4 %5 %6 accepting: %7 FSD: %8 con.since: %9")
38  .arg(m_name, m_description, m_address)
39  .arg(m_port)
40  .arg(m_user.toQString(i18n), m_ecosystem.getSystemString(), boolToYesNo(m_isAcceptingConnections),
41  m_fsdSetup.toQString(i18n), this->isConnected() ? this->getFormattedUtcTimestampHms() : "not con.");
42  }
43 
45  {
46  static const CServer fsc = [] {
47  CServer s = CServer("FSC", "FSC e.V.", "OBF:AwJIKfgkQDJEIRnno29DJlB+UK0=", 6809, CUser(), CFsdSetup(),
50  return s;
51  }();
52  return fsc;
53  }
54 
56  {
57  static const CServer s = CServer("ES Tower", "Euroscope Tower view", "localhost", 6809, CUser(),
59  return s;
60  }
61 
62  bool CServer::matchesName(const QString &name) const
63  {
64  return m_name.length() == name.length() && m_name.startsWith(name, Qt::CaseInsensitive);
65  }
66 
67  bool CServer::matchesAddressPort(const CServer &server) const
68  {
69  return server.getPort() == this->getPort() && server.matchesAddress(this->getAddress());
70  }
71 
72  bool CServer::matchesAddress(const QString &address) const
73  {
74  return m_address.length() == address.length() && m_address.startsWith(address, Qt::CaseInsensitive);
75  }
76 
77  void CServer::setEcosystem(const CEcosystem &ecosystem) { m_ecosystem = ecosystem; }
78 
80  {
81  return m_user.hasCredentials() && this->hasAddressAndPort() && this->isAcceptingConnections();
82  }
83 
84  bool CServer::hasAddressAndPort() const { return m_port > 0 && !m_address.isEmpty(); }
85 
86  bool CServer::isConnected() const { return m_timestampMSecsSinceEpoch >= 0; }
87 
88  bool CServer::isNull() const { return m_ecosystem.isUnspecified() && !this->hasName() && m_port < 0; }
89 
91  {
92  static const CLogCategoryList cats(CLogCategoryList(this).withValidation());
93  CStatusMessageList msgs;
94  if (this->getName().isEmpty())
95  {
97  }
98  if (this->getAddress().isEmpty())
99  {
100  msgs.push_back(CStatusMessage(CStatusMessage::SeverityError, u"Missing address"));
101  }
102  if (this->getDescription().isEmpty())
103  {
104  msgs.push_back(CStatusMessage(CStatusMessage::SeverityWarning, u"Missing description"));
105  }
106  if (this->getPort() < 1 || this->getPort() > 65535)
107  {
109  }
110  msgs.push_back(this->getUser().validate());
111  msgs.push_back(this->getFsdSetup().validate());
112  msgs.addCategories(cats);
113  msgs.sortBySeverity();
114  return msgs;
115  }
116 
117  QString CServer::getServerSessionId(bool onlyConnected) const
118  {
119  const bool isConnected = this->isConnected();
120  if (onlyConnected && !isConnected) { return {}; }
121  static const QString session("%1 %2 %3:%4 [%5] %6 %7");
122  return session.arg(isConnected ? u"connected" : u"disconnected")
123  .arg(this->getName(), this->getAddress())
124  .arg(this->getPort())
125  .arg(this->getEcosystem().getSystemString(), this->getUser().getRealName(),
127  }
128 
130  {
131  if (index.isMyself()) { return QVariant::fromValue(*this); }
133 
134  const auto i = index.frontCasted<ColumnIndex>();
135  switch (i)
136  {
137  case IndexAddress: return QVariant::fromValue(m_address);
138  case IndexDescription: return QVariant::fromValue(m_description);
139  case IndexName: return QVariant::fromValue(m_name);
140  case IndexPort: return QVariant::fromValue(m_port);
141  case IndexUser: return m_user.propertyByIndex(index.copyFrontRemoved());
142  case IndexFsdSetup: return m_fsdSetup.propertyByIndex(index.copyFrontRemoved());
143  case IndexEcosystem: return m_ecosystem.propertyByIndex(index.copyFrontRemoved());
144  case IndexIsAcceptingConnections: return QVariant::fromValue(m_isAcceptingConnections);
145  default: return CValueObject::propertyByIndex(index);
146  }
147  }
148 
150  {
151  if (index.isMyself())
152  {
153  (*this) = variant.value<CServer>();
154  return;
155  }
157  {
158  ITimestampBased::setPropertyByIndex(index, variant);
159  return;
160  }
161 
162  const auto i = index.frontCasted<ColumnIndex>();
163  switch (i)
164  {
165  case IndexAddress: this->setAddress(variant.value<QString>()); break;
166  case IndexPort: this->setPort(variant.value<qint32>()); break;
167  case IndexDescription: this->setDescription(variant.value<QString>()); break;
168  case IndexName: this->setName(variant.value<QString>()); break;
169  case IndexUser: m_user.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
170  case IndexFsdSetup: m_fsdSetup.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
171  case IndexEcosystem: m_ecosystem.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
172  case IndexIsAcceptingConnections: this->setIsAcceptingConnections(variant.value<bool>()); break;
173  default: CValueObject::setPropertyByIndex(index, variant); break;
174  }
175  }
176 
177  int CServer::comparePropertyByIndex(CPropertyIndexRef index, const CServer &compareValue) const
178  {
179  if (index.isMyself()) { return this->getName().compare(compareValue.getName()); }
181  {
182  return ITimestampBased::comparePropertyByIndex(index, compareValue);
183  }
184  const auto i = index.frontCasted<ColumnIndex>();
185  switch (i)
186  {
187  case IndexAddress: return this->getAddress().compare(compareValue.getAddress(), Qt::CaseInsensitive);
188  case IndexDescription:
189  return this->getDescription().compare(compareValue.getDescription(), Qt::CaseInsensitive);
190  case IndexFsdSetup:
191  return m_fsdSetup.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getFsdSetup());
192  case IndexName: return this->getName().compare(compareValue.getName(), Qt::CaseInsensitive);
193  case IndexPort: return Compare::compare(this->getPort(), compareValue.getPort());
194  case IndexUser: return this->getUser().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getUser());
195  case IndexEcosystem:
196  return this->getEcosystem().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getEcosystem());
197  case IndexIsAcceptingConnections:
198  return Compare::compare(this->isAcceptingConnections(), compareValue.isAcceptingConnections());
199  default: break;
200  }
201  SWIFT_VERIFY_X(false, Q_FUNC_INFO, qUtf8Printable("No comparison for index " + index.toQString()));
202  return 0;
203  }
204 
205  void CServer::setAddress(const QString &address) { m_address = CObfuscation::decode(address); }
206 
207  void CServer::setName(const QString &name) { m_name = CObfuscation::decode(name); }
208 
209  void CServer::setDescription(const QString &description)
210  {
211  m_description = CObfuscation::decode(description).simplified();
212  }
213 } // namespace swift::misc::network
A sequence of log categories.
Utility class to obfuscate strings in the source code to make them unreadable.
Definition: obfuscation.h:19
static QString decode(const QString &inString, bool trimmed=true)
Decode string if it has the prefix, otherwise do nothing with it.
Definition: obfuscation.cpp:12
Non-owning reference to a CPropertyIndex with a subset of its features.
Q_REQUIRED_RESULT CPropertyIndexRef copyFrontRemoved() const
Copy with first element removed.
QString toQString(bool i18n=false) const
Cast as QString.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
Streamable status message, e.g.
constexpr static auto SeverityError
Status severities.
constexpr static auto SeverityWarning
Status severities.
Status messages, e.g. from Core -> GUI.
void addCategories(const CLogCategoryList &categories)
Add some categories to all messages in the list.
void sortBySeverity()
Sort by severity, lowest first.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
int comparePropertyByIndex(CPropertyIndexRef index, const ITimestampBased &compareValue) const
Compare for index.
static bool canHandleIndex(CPropertyIndexRef index)
Can given index be handled.
qint64 m_timestampMSecsSinceEpoch
timestamp value
QString getFormattedUtcTimestampHms() const
As hh:mm:ss.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
ColumnIndex
Base class enums.
Definition: mixinindex.h:44
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:158
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:165
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:74
Ecosystem of server belonging together.
Definition: ecosystem.h:21
bool isUnspecified() const
Unknown system?
Definition: ecosystem.h:49
int comparePropertyByIndex(CPropertyIndexRef index, const CEcosystem &compareValue) const
Compare for index.
Definition: ecosystem.cpp:82
static const CEcosystem & vatsim()
VATSIM eco system.
Definition: ecosystem.cpp:26
void setPropertyByIndex(swift::misc::CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: ecosystem.cpp:67
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
Definition: ecosystem.cpp:55
static const CEcosystem & privateFsd()
FSD private.
Definition: ecosystem.cpp:32
const QString & getSystemString() const
Get the system string.
Definition: ecosystem.cpp:38
Value object for a FSD setup.
Definition: fsdsetup.h:24
static const CFsdSetup & vatsimStandard()
Standard FSD setup for official VATSIM servers.
Definition: fsdsetup.cpp:76
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: fsdsetup.cpp:110
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: fsdsetup.cpp:98
int comparePropertyByIndex(CPropertyIndexRef index, const CFsdSetup &compareValue) const
Compare for index.
Definition: fsdsetup.cpp:126
@ AllInterimPositions
all interim positions
Definition: fsdsetup.h:53
Value object encapsulating information of a FSD server.
Definition: server.h:28
bool hasAddressAndPort() const
Address and port?
Definition: server.cpp:84
void setName(const QString &name)
Set name.
Definition: server.cpp:207
void setDescription(const QString &description)
Set description.
Definition: server.cpp:209
void setAddress(const QString &address)
Set address (e.g. myserver.foo.com)
Definition: server.cpp:205
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: server.cpp:129
QString convertToQString(bool i18n=false) const
Cast as QString.
Definition: server.cpp:35
const QString & getDescription() const
Get description.
Definition: server.h:87
bool matchesAddress(const QString &address) const
Same address?
Definition: server.cpp:72
bool hasName() const
Has name?
Definition: server.h:72
static const CServer & esTowerView()
ES tower server.
Definition: server.cpp:55
int getPort() const
Get port.
Definition: server.h:93
bool isConnected() const
Is connected?
Definition: server.cpp:86
bool matchesName(const QString &name) const
Matches server name?
Definition: server.cpp:62
CStatusMessageList validate() const
Validate, provide details about issues.
Definition: server.cpp:90
bool matchesAddressPort(const CServer &server) const
Same address and port?
Definition: server.cpp:67
CServer()=default
Default constructor.
bool isValidForLogin() const
Is valid for login?
Definition: server.cpp:79
const QString & getName() const
Get name.
Definition: server.h:69
const CFsdSetup & getFsdSetup() const
Get FSD setup.
Definition: server.h:117
void setIsAcceptingConnections(bool value)
Set whether server is accepting connections (allows to disable server temporarily or generally)
Definition: server.h:108
int comparePropertyByIndex(CPropertyIndexRef index, const CServer &compareValue) const
Compare for index.
Definition: server.cpp:177
const QString & getAddress() const
Get address.
Definition: server.h:57
void setPort(int port)
Set port.
Definition: server.h:96
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: server.cpp:149
const CEcosystem & getEcosystem() const
Get the ecosystem.
Definition: server.h:99
void removeSendReceiveDetails(CFsdSetup::SendReceiveDetails sendReceive)
Remove send / receive details.
Definition: server.h:129
static const CServer & fscFsdServer()
FSC server.
Definition: server.cpp:44
bool isAcceptingConnections() const
Server is accepting connections (allows to disable server temporarily or generally)
Definition: server.h:105
const CUser & getUser() const
Get user.
Definition: server.h:63
bool isNull() const
NULL?
Definition: server.cpp:88
void setEcosystem(const CEcosystem &ecosystem)
Set the ecosystem.
Definition: server.cpp:77
QString getServerSessionId(bool onlyConnected) const
Identifying a session, if not connected empty.
Definition: server.cpp:117
Value object encapsulating information of a user.
Definition: user.h:28
int comparePropertyByIndex(CPropertyIndexRef index, const CUser &compareValue) const
Compare for index.
Definition: user.cpp:281
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: user.cpp:241
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: user.cpp:259
bool hasCredentials() const
Valid credentials?
Definition: user.h:77
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
QString arg(Args &&... args) const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool isEmpty() const const
qsizetype length() const const
QString simplified() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseInsensitive
QVariant fromValue(T &&value)
T value() const &const
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26