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 "customservers.h"
24 #include "configuration/doomseekerconfig.h"
25 #include "plugins/engineplugin.h"
26 #include "plugins/pluginloader.h"
27 #include "serverapi/server.h"
28 #include "log.h"
29 #include <QHostInfo>
30 #include <QUrl>
31 #include <cassert>
32 
33 CustomServerInfo CustomServerInfo::fromServer(const Server *server)
34 {
35  assert(server != NULL);
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  {
88  customServerInfo.enabled = entryList[3].toInt() != 0;
89  }
90 
91  bool ok = false;
92  int port = QString(entryList[2]).toInt(&ok);
93  if (ok && port >= 1 && port <= 65535)
94  {
95  customServerInfo.port = port;
96  }
97  else if (engineIndex >= 0)
98  {
99  const PluginLoader::Plugin* pPlugin = gPlugins->plugin(engineIndex);
100  customServerInfo.port = pPlugin->info()->data()->defaultServerPort;
101  }
102  else
103  {
104  customServerInfo.port = 1;
105  }
106 
107  outCustomServerInfoList << customServerInfo;
108  } // end of if
109  } // end of else if
110  } // end of for
111 }
112 
113 bool CustomServers::isServerPinned(const CustomServerInfo &serverInfo)
114 {
115  foreach (const CustomServerInfo &knownPinned, gConfig.doomseeker.customServers)
116  {
117  if (knownPinned.isSameServer(serverInfo))
118  {
119  return knownPinned.enabled;
120  }
121  }
122  return false;
123 }
124 
125 bool CustomServers::hasSameServer(const Server *otherServer) const
126 {
127  CustomServerInfo otherServerInfo = CustomServerInfo::fromServer(otherServer);
128  foreach (ServerCPtr knownServer, servers())
129  {
130  if (CustomServerInfo::fromServer(knownServer.data()).isSameServer(otherServerInfo))
131  return true;
132  }
133  return false;
134 }
135 
136 QList<ServerPtr> CustomServers::readConfig()
137 {
138  return setServers(gConfig.doomseeker.customServers.toList());
139 }
140 
141 void CustomServers::setServerPinned(const CustomServerInfo &serverInfo, bool pinned)
142 {
143  // Check if the server has already been memorized.
144  for (int serverIdx = 0; serverIdx < gConfig.doomseeker.customServers.size(); ++serverIdx)
145  {
146  CustomServerInfo &knownPinned = gConfig.doomseeker.customServers[serverIdx];
147  if (knownPinned.isSameServer(serverInfo))
148  {
149  knownPinned.enabled = pinned;
150  return;
151  }
152  }
153  // Server is not yet on the memorized servers list.
154  // If we're about to pin it, just add it to the list.
155  if (pinned)
156  {
157  gConfig.doomseeker.customServers << serverInfo;
158  }
159 }
160 
161 QList<ServerPtr> CustomServers::setServers(const QList<CustomServerInfo>& serverDefs)
162 {
163  emptyServerList();
164 
165  QList<ServerPtr> servers;
166  foreach (const CustomServerInfo& customServerInfo, serverDefs)
167  {
168  if (!customServerInfo.enabled)
169  continue;
170  if (customServerInfo.engineIndex < 0)
171  {
172  // Unknown engine.
173  gLog << tr("Unknown game for custom server %1:%2")
174  .arg(customServerInfo.host).arg(customServerInfo.port);
175  continue;
176  }
177 
178  QHostAddress address;
179  if (!address.setAddress(customServerInfo.host))
180  {
181  QHostInfo hostInfo(QHostInfo::fromName(customServerInfo.host));
182  if (hostInfo.addresses().size() == 0)
183  {
184  // Can't decipher address.
185  gLog << tr("Failed to resolve address for custom server %1:%2")
186  .arg(customServerInfo.host).arg(customServerInfo.port);
187  continue;
188  }
189  address = hostInfo.addresses().first();
190  }
191 
192  const EnginePlugin* pInterface = gPlugins->plugin(customServerInfo.engineIndex)->info();
193  ServerPtr p = pInterface->server(address, customServerInfo.port);
194  if(p == NULL)
195  {
196  gLog << tr("Plugin returned NULL \"Server*\" for custom server %1:%2. "
197  "This is a problem with the plugin.")
198  .arg(customServerInfo.host).arg(customServerInfo.port);
199  continue;
200  }
201  p->setCustom(true);
202 
203  registerNewServer(p);
204  servers << p;
205  }
206  return servers;
207 }
bool hasSameServer(const Server *otherServer) const
QList< ServerPtr > setServers(const QList< CustomServerInfo > &serverDefs)
virtual EnginePlugin * plugin() const =0
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()
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