customservers.cpp
1 //------------------------------------------------------------------------------
2 // customservers.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) 2009 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "configuration/doomseekerconfig.h"
24 #include "customservers.h"
25 #include "log.h"
26 #include "plugins/engineplugin.h"
27 #include "plugins/pluginloader.h"
28 #include "serverapi/server.h"
29 #include <cassert>
30 #include <QHostInfo>
31 #include <QUrl>
32 
33 CustomServerInfo CustomServerInfo::fromServer(const Server *server)
34 {
35  assert(server != nullptr);
36  CustomServerInfo obj;
37  obj.engine = server->plugin()->data()->name;
38  obj.engineIndex = gPlugins->pluginIndexFromName(obj.engine);
39  obj.host = server->address().toString();
40  obj.port = server->port();
41  obj.enabled = true;
42  return obj;
43 }
44 
46 {
47  return engine == other.engine
48  && port == other.port
49  && host == other.host;
50 }
51 
53 
54 void CustomServers::decodeConfigEntries(const QString &str, QList<CustomServerInfo> &outCustomServerInfoList)
55 {
56  outCustomServerInfoList.clear();
57 
58  int openingBracketIndex = 0;
59  int closingBracketIndex = 0;
60  bool bSeekClosingBracket = false;
61  for (int charIdx = 0; charIdx < str.length(); ++charIdx)
62  {
63  if (!bSeekClosingBracket && str[charIdx] == '(')
64  {
65  openingBracketIndex = charIdx;
66  bSeekClosingBracket = true;
67  }
68  else if (bSeekClosingBracket && str[charIdx] == ')')
69  {
70  closingBracketIndex = charIdx;
71  bSeekClosingBracket = false;
72 
73  QString entry = str.mid(openingBracketIndex + 1, closingBracketIndex - (openingBracketIndex + 1));
74  QStringList entryList = entry.split(";");
75 
76  if (entryList.size() >= 3)
77  {
78  CustomServerInfo customServerInfo;
79  customServerInfo.engine = QUrl::fromPercentEncoding(entryList[0].toUtf8());
80 
81  int engineIndex = gPlugins->pluginIndexFromName(customServerInfo.engine);
82  customServerInfo.engineIndex = engineIndex;
83 
84  customServerInfo.host = QUrl::fromPercentEncoding(entryList[1].toUtf8());
85  customServerInfo.enabled = true;
86  if (entryList.size() >= 4)
87  customServerInfo.enabled = entryList[3].toInt() != 0;
88 
89  bool ok = false;
90  int port = QString(entryList[2]).toInt(&ok);
91  if (ok && port >= 1 && port <= 65535)
92  customServerInfo.port = port;
93  else if (engineIndex >= 0)
94  {
95  const PluginLoader::Plugin *pPlugin = gPlugins->plugin(engineIndex);
96  customServerInfo.port = pPlugin->info()->data()->defaultServerPort;
97  }
98  else
99  customServerInfo.port = 1;
100 
101  outCustomServerInfoList << customServerInfo;
102  } // end of if
103  } // end of else if
104  } // end of for
105 }
106 
107 bool CustomServers::isServerPinned(const CustomServerInfo &serverInfo)
108 {
109  for (const CustomServerInfo &knownPinned : gConfig.doomseeker.customServers)
110  {
111  if (knownPinned.isSameServer(serverInfo))
112  return knownPinned.enabled;
113  }
114  return false;
115 }
116 
117 bool CustomServers::hasSameServer(const Server *otherServer) const
118 {
119  CustomServerInfo otherServerInfo = CustomServerInfo::fromServer(otherServer);
120  for (ServerCPtr knownServer : servers())
121  {
122  if (CustomServerInfo::fromServer(knownServer.data()).isSameServer(otherServerInfo))
123  return true;
124  }
125  return false;
126 }
127 
128 QList<ServerPtr> CustomServers::readConfig()
129 {
130  return setServers(gConfig.doomseeker.customServers.toList());
131 }
132 
133 void CustomServers::setServerPinned(const CustomServerInfo &serverInfo, bool pinned)
134 {
135  // Check if the server has already been memorized.
136  for (int serverIdx = 0; serverIdx < gConfig.doomseeker.customServers.size(); ++serverIdx)
137  {
138  CustomServerInfo &knownPinned = gConfig.doomseeker.customServers[serverIdx];
139  if (knownPinned.isSameServer(serverInfo))
140  {
141  knownPinned.enabled = pinned;
142  return;
143  }
144  }
145  // Server is not yet on the memorized servers list.
146  // If we're about to pin it, just add it to the list.
147  if (pinned)
148  gConfig.doomseeker.customServers << serverInfo;
149 }
150 
151 QList<ServerPtr> CustomServers::setServers(const QList<CustomServerInfo> &serverDefs)
152 {
153  emptyServerList();
154 
155  QList<ServerPtr> servers;
156  for (const CustomServerInfo &customServerInfo : serverDefs)
157  {
158  if (!customServerInfo.enabled)
159  continue;
160  if (customServerInfo.engineIndex < 0)
161  {
162  // Unknown engine.
163  gLog << tr("Unknown game for custom server %1:%2")
164  .arg(customServerInfo.host).arg(customServerInfo.port);
165  continue;
166  }
167 
168  QHostAddress address;
169  if (!address.setAddress(customServerInfo.host))
170  {
171  QHostInfo hostInfo(QHostInfo::fromName(customServerInfo.host));
172  if (hostInfo.addresses().size() == 0)
173  {
174  // Can't decipher address.
175  gLog << tr("Failed to resolve address for custom server %1:%2")
176  .arg(customServerInfo.host).arg(customServerInfo.port);
177  continue;
178  }
179  address = hostInfo.addresses().first();
180  }
181 
182  const EnginePlugin *pInterface = gPlugins->plugin(customServerInfo.engineIndex)->info();
183  ServerPtr p = pInterface->server(address, customServerInfo.port);
184  if (p == nullptr)
185  {
186  gLog << tr("Plugin returned nullptr \"Server*\" for custom server %1:%2. "
187  "This is a problem with the plugin.")
188  .arg(customServerInfo.host).arg(customServerInfo.port);
189  continue;
190  }
191  p->setCustom(true);
192 
193  registerNewServer(p);
194  servers << p;
195  }
196  return servers;
197 }
bool hasSameServer(const Server *otherServer) const
QList< ServerPtr > setServers(const QList< CustomServerInfo > &serverDefs)
A representation of a server for a given game.
Definition: server.h:93
static void decodeConfigEntries(const QString &str, QList< CustomServerInfo > &outCustomServerInfoList)
bool isSameServer(const CustomServerInfo &other) const
virtual ServerPtr server(const QHostAddress &address, unsigned short port) const
Creates an instance of server object from this plugin.
EnginePlugin * info() const
Main plugin interface.
QList< ServerPtr > readConfig()
virtual EnginePlugin * plugin() const =0
unsigned short port() const
Network port on which this server is hosted.
Definition: server.cpp:468
const QHostAddress & address() const
Address of this server.
Definition: server.cpp:193