remoteconsole.cpp
1 //------------------------------------------------------------------------------
2 // remoteconsole.h
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 Braden "Blzut3" Obrzut <admin@maniacsvault.net>
22 //------------------------------------------------------------------------------
23 
24 #include "plugins/engineplugin.h"
25 #include "rconpassworddialog.h"
26 #include "remoteconsole.h"
27 #include "serverapi/rconprotocol.h"
28 #include "serverapi/server.h"
29 #include "strings.hpp"
30 #include "ui_remoteconsole.h"
31 #include "widgets/serverconsole.h"
32 
33 #include <QKeyEvent>
34 #include <QMessageBox>
35 #include <QScopedPointer>
36 #include <QString>
37 
38 DClass<RemoteConsole> : public Ui::RemoteConsole
39 {
40 public:
41  RConProtocol *protocol;
42  ServerConsole *serverConsole;
43  ServerPtr server;
44 };
45 
46 DPointered(RemoteConsole)
47 
48 RemoteConsole::RemoteConsole(QWidget *parent) : QMainWindow(parent)
49 {
50  construct();
51  show();
52 
53  // Prompt for connection info & password.
54  auto dlg = new RconPasswordDialog(this, true);
55  connect(dlg, SIGNAL(rejected()), this, SLOT(close()));
56  while (d->protocol == nullptr)
57  {
58  int ret = dlg->exec();
59  if (ret == QDialog::Accepted)
60  {
61  QString address;
62  unsigned short port;
63  Strings::translateServerAddress(dlg->serverAddress(), address, port, QString("localhost:%1").arg(dlg->selectedEngine()->data()->defaultServerPort));
64 
65  ServerPtr server = dlg->selectedEngine()->server(QHostAddress(address), port);
66  if (!server->hasRcon())
67  {
68  QMessageBox::critical(this, RemoteConsole::tr("No RCon support"), RemoteConsole::tr("The selected source port has no RCon support."));
69  continue;
70  }
71  d->protocol = server->rcon();
72 
73  if (d->protocol != nullptr)
74  {
75  d->server = server;
76  setWindowIcon(d->server->icon());
77  standardInit();
78 
79  d->protocol->sendPassword(dlg->connectPassword());
80  }
81  else
82  {
83  QMessageBox::critical(this, RemoteConsole::tr("RCon failure"), RemoteConsole::tr("Failed to create RCon protocol for the server."));
84  continue;
85  }
86  }
87  else
88  break;
89  }
90  delete dlg;
91 }
92 
93 RemoteConsole::RemoteConsole(ServerPtr server, QWidget *parent)
94  : QMainWindow(parent)
95 {
96  construct();
97  d->protocol = server->rcon();
98  d->server = server;
99 
100  setWindowIcon(server->icon());
101  changeServerName(server->name());
102 
103  if (d->protocol != nullptr)
104  {
105  standardInit();
106  showPasswordDialog();
107  }
108  else
109  {
110  QMessageBox::critical(parent, tr("RCon Failure"),
111  tr("Failed to connect RCon to server %1:%2").arg(
112  server->address().toString()).arg(server->port()));
113  }
114 }
115 
116 RemoteConsole::~RemoteConsole()
117 {
118 }
119 
120 void RemoteConsole::construct()
121 {
122  d->setupUi(this);
123  d->protocol = nullptr;
124  d->serverConsole = new ServerConsole();
125  d->console->layout()->addWidget(d->serverConsole);
126  connect(d->actionDisconnect, SIGNAL(triggered()), this, SLOT(disconnectFromServer()));
127 
128  // delete ourself on close
129  setAttribute(Qt::WA_DeleteOnClose);
130 }
131 
132 void RemoteConsole::changeServerName(const QString &name)
133 {
134  setWindowTitle(name + tr(" - Remote Console"));
135 }
136 
137 void RemoteConsole::closeEvent(QCloseEvent *event)
138 {
139  if (d->protocol && d->protocol->isConnected())
140  d->protocol->disconnectFromServer();
141  event->accept();
142 }
143 
144 void RemoteConsole::invalidPassword()
145 {
146  QMessageBox::critical(this, tr("Invalid Password"), tr("The password you entered appears to be invalid."));
147  showPasswordDialog();
148 }
149 
150 void RemoteConsole::disconnectFromServer()
151 {
152  if (d->protocol)
153  d->protocol->disconnectFromServer();
154  else
155  close();
156 }
157 
158 void RemoteConsole::showPasswordDialog()
159 {
160  // Prompt for password.
161  auto dlg = new RconPasswordDialog(this);
162  connect(dlg, SIGNAL(rejected()), this, SLOT(close()));
163  int ret = dlg->exec();
164  if (ret == QDialog::Accepted)
165  d->protocol->sendPassword(dlg->connectPassword());
166  delete dlg;
167 
168  // Set/Restore focus to the cmd line input.
169  d->serverConsole->setFocus();
170 }
171 
172 void RemoteConsole::standardInit()
173 {
174  show();
175  connect(d->serverConsole, SIGNAL(messageSent(const QString&)), d->protocol, SLOT(sendCommand(const QString&)));
176  connect(d->protocol, SIGNAL(disconnected()), this, SLOT(close()));
177  connect(d->protocol, SIGNAL(messageReceived(const QString&)), d->serverConsole, SLOT(appendMessage(const QString&)));
178  connect(d->protocol, SIGNAL(invalidPassword()), this, SLOT(invalidPassword()));
179  connect(d->protocol, SIGNAL(playerListUpdated()), this, SLOT(updatePlayerList()));
180  connect(d->protocol, SIGNAL(serverNameChanged(const QString&)), this, SLOT(changeServerName(const QString&)));
181 }
182 
183 void RemoteConsole::updatePlayerList()
184 {
185  const QList<Player> &list = d->protocol->players();
186 
187  d->playerTable->setRowCount(list.size());
188  for (int i = 0; i < list.size(); ++i)
189  {
190  QString name = list[i].nameFormatted();
191  auto newItem = new QTableWidgetItem(name);
192  d->playerTable->setItem(i, 0, newItem);
193  }
194 }