|
@@ -10,8 +10,11 @@
|
|
|
#include <QtSql/QSqlQuery>
|
|
|
#include <QCryptographicHash>
|
|
|
#include <QHostAddress>
|
|
|
+#include <QThreadPool>
|
|
|
#include "SshClient.h"
|
|
|
+#include "ActiveClient.h"
|
|
|
#include "ServerQueryThread.h"
|
|
|
+#include "Settings.h"
|
|
|
|
|
|
App::App(int &argc, char **argv) :
|
|
|
QCoreApplication(argc, argv),
|
|
@@ -32,6 +35,19 @@ App::App(int &argc, char **argv) :
|
|
|
myClientsFrameTimerID = startTimer(0);
|
|
|
|
|
|
myQWNETSshClient->connectToHost("stomp", "b4r.org");
|
|
|
+
|
|
|
+ QThreadPool::globalInstance()->setMaxThreadCount(Settings::globalInstance()->maxThreads());
|
|
|
+
|
|
|
+ loadServerList();
|
|
|
+
|
|
|
+ Settings::globalInstance()->save();
|
|
|
+}
|
|
|
+
|
|
|
+App::~App()
|
|
|
+{
|
|
|
+ Settings::globalInstance()->save();
|
|
|
+ cleanup();
|
|
|
+ delete myServer;
|
|
|
}
|
|
|
|
|
|
void App::onNewConnection()
|
|
@@ -43,7 +59,7 @@ void App::onNewConnection()
|
|
|
if(mySocket->state() != QTcpSocket::UnconnectedState)
|
|
|
mySocket->waitForDisconnected();
|
|
|
mySocketConnectedFlag = false;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
mySocket = myServer->nextPendingConnection();
|
|
|
mySocketConnectedFlag = true;
|
|
@@ -72,12 +88,38 @@ void App::onDisconnection()
|
|
|
mySocket->deleteLater();
|
|
|
}
|
|
|
|
|
|
-void App::loadClients()
|
|
|
+void App::loadServerList()
|
|
|
+{
|
|
|
+ QStringList list = Settings::globalInstance()->serverList();
|
|
|
+ QString sv;
|
|
|
+
|
|
|
+ foreach(sv, list)
|
|
|
+ {
|
|
|
+ ActiveClient* ac = new ActiveClient(this);
|
|
|
+ QStringList parms = sv.split(':');
|
|
|
+ ac->setAddressAndStartThread(QHostAddress(parms.at(0)), parms.at(1).toUShort());
|
|
|
+ ac->client()->setQuakeFolder(Settings::globalInstance()->quakeFolder().toAscii().data());
|
|
|
+ ac->client()->setName(Settings::globalInstance()->botName().toAscii().data());
|
|
|
+ ac->client()->setSpectator(Settings::globalInstance()->botSpectator());
|
|
|
+ ac->client()->setPing(Settings::globalInstance()->botPing());
|
|
|
+ ac->client()->setColor(Settings::globalInstance()->botTopColor(), Settings::globalInstance()->botBottomColor());
|
|
|
+
|
|
|
+ myClients.push_back(ac);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void App::saveServerList()
|
|
|
{
|
|
|
+ QStringList list;
|
|
|
+ ActiveClient* ac;
|
|
|
+
|
|
|
+ foreach(ac, myClients)
|
|
|
+ list.push_back(ac->serverAddressString());
|
|
|
|
|
|
+ Settings::globalInstance()->setServerList(list);
|
|
|
}
|
|
|
|
|
|
-void App::connectToServer(const QString &args)
|
|
|
+void App::parseAddClientCommand(const QString &args)
|
|
|
{
|
|
|
if(!args.size())
|
|
|
{
|
|
@@ -104,7 +146,7 @@ void App::connectToServer(const QString &args)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void App::disconnectFromServer(const QString &args)
|
|
|
+void App::parseRemoveClientCommand(const QString &args)
|
|
|
{
|
|
|
if(!args.size())
|
|
|
{
|
|
@@ -154,15 +196,15 @@ void App::onDataArrival()
|
|
|
QString cmd = regex.capturedTexts().at(2);
|
|
|
QString args = regex.capturedTexts().at(3).trimmed();
|
|
|
|
|
|
- if(cmd == "connect")
|
|
|
+ if(cmd == "add")
|
|
|
{
|
|
|
- connectToServer(args);
|
|
|
+ parseAddClientCommand(args);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if(cmd == "disconnect")
|
|
|
+ if(cmd == "remove")
|
|
|
{
|
|
|
- disconnectFromServer(args);
|
|
|
+ parseRemoveClientCommand(args);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -324,13 +366,17 @@ void App::addClient(const QString &host, quint16 port)
|
|
|
ac->client()->setSocket(mySocket);
|
|
|
}
|
|
|
}
|
|
|
- ac->setAddress(ha, port);
|
|
|
- ac->client()->setQuakeFolder(mySettings.value("quakeFolder", App::applicationDirPath()).toString().toAscii().data());
|
|
|
- ac->client()->setName(mySettings.value("botName", "cimsbot").toString().toAscii().data());
|
|
|
- ac->client()->setSpectator(true);
|
|
|
- ac->client()->setPing(120);
|
|
|
- ac->client()->setColor(11, 13);
|
|
|
+ ac->setAddressAndStartThread(ha, port);
|
|
|
+ ac->client()->setQuakeFolder(Settings::globalInstance()->quakeFolder().toAscii().data());
|
|
|
+ ac->client()->setName(Settings::globalInstance()->botName().toAscii().data());
|
|
|
+ ac->client()->setSpectator(Settings::globalInstance()->botSpectator());
|
|
|
+ ac->client()->setPing(Settings::globalInstance()->botPing());
|
|
|
+ ac->client()->setColor(Settings::globalInstance()->botTopColor(), Settings::globalInstance()->botBottomColor());
|
|
|
myClients.push_back(ac);
|
|
|
+
|
|
|
+ saveServerList();
|
|
|
+
|
|
|
+ print("Client added to watch list.\n");
|
|
|
}
|
|
|
|
|
|
void App::removeClient(const QString &host, quint16 port)
|
|
@@ -340,14 +386,15 @@ void App::removeClient(const QString &host, quint16 port)
|
|
|
|
|
|
foreach(ac, myClients)
|
|
|
{
|
|
|
- if(QString(ac->client()->host()) == ha.toString() && ac->client()->port() == port)
|
|
|
+ if(ac->serverAddressString() == QString(ha.toString() + ':' + QString::number(port)))
|
|
|
{
|
|
|
ac->client()->disconnect();
|
|
|
delete ac;
|
|
|
myClients.removeAll(ac);
|
|
|
|
|
|
+ saveServerList();
|
|
|
|
|
|
- print("Client removed.\n");
|
|
|
+ print("Client removed from watch list.\n");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -402,9 +449,7 @@ void App::listClients()
|
|
|
ActiveClient* ac;
|
|
|
foreach(ac, myClients)
|
|
|
{
|
|
|
- QString reply(ac->client()->host());
|
|
|
- reply.append(":" + QString::number(ac->client()->port()) + "\n");
|
|
|
- print(reply.toAscii().data());
|
|
|
+ print(QString(ac->serverAddressString() + '\n'));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -443,8 +488,6 @@ void App::timerEvent(QTimerEvent *e)
|
|
|
|
|
|
void App::requestBroadcast(const QString &type, const QString &user, const QString &server, const QString &message)
|
|
|
{
|
|
|
- //REQ_BC QDEV,-dev-,qw://123.123,'testuser','test, with '',``twists''$ hehe'
|
|
|
- qDebug() << "REQ_BC QDEV,-" + type + "-,qw://" + server + ",'" + user + "','" + message + "'";
|
|
|
myQWNETSshClient->write("REQ_BC QDEV,-" + type + "-,qw://" + server + ",'" + user + "','" + message + "'\n");
|
|
|
}
|
|
|
|
|
@@ -455,7 +498,6 @@ void App::broadcast(const QString &msg)
|
|
|
|
|
|
void App::broadcast(const QString &msg, int *serverCount, int *userCount)
|
|
|
{
|
|
|
- qDebug() << "Broadcasting" << msg;
|
|
|
say(msg, serverCount, userCount);
|
|
|
}
|
|
|
|
|
@@ -469,12 +511,6 @@ void App::cleanup()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-App::~App()
|
|
|
-{
|
|
|
- cleanup();
|
|
|
- delete myServer;
|
|
|
-}
|
|
|
-
|
|
|
void App::setReplyHash(const QString &serverAddress, const QString &hash)
|
|
|
{
|
|
|
ActiveClient* ac;
|
|
@@ -488,132 +524,16 @@ void App::setReplyHash(const QString &serverAddress, const QString &hash)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void App::incrementReplyCounters(const QString &hash, int userCount, int serverCount)
|
|
|
+void App::incrementReplyCounters(const QString &hash, int userCount, int channelCount, int playerCount, int serverCount)
|
|
|
{
|
|
|
ActiveClient* ac;
|
|
|
foreach(ac, myClients)
|
|
|
{
|
|
|
if(ac->replyHash() == hash)
|
|
|
{
|
|
|
- ac->incrementReplyCounters(userCount, serverCount);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//========================================================================
|
|
|
-
|
|
|
-App::ActiveClient::ActiveClient(App *app):
|
|
|
- myApp(app),
|
|
|
- myClient(new Client(app)),
|
|
|
- myQueryThread(new ServerQueryThread()),
|
|
|
- myBroadcastReplyTimer(new QTimer()),
|
|
|
- myUniqueUserCount(0),
|
|
|
- myUniqueServerCount(0)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-App::ActiveClient::~ActiveClient()
|
|
|
-{
|
|
|
- delete myClient;
|
|
|
-
|
|
|
- if(queryThread()->isRunning())
|
|
|
- queryThread()->stopQueryThread();
|
|
|
- while(queryThread()->isRunning());
|
|
|
-
|
|
|
- delete myQueryThread;
|
|
|
- delete myBroadcastReplyTimer;
|
|
|
-}
|
|
|
-
|
|
|
-Client* App::ActiveClient::client()
|
|
|
-{
|
|
|
- return myClient;
|
|
|
-}
|
|
|
-
|
|
|
-ServerQueryThread* App::ActiveClient::queryThread()
|
|
|
-{
|
|
|
- return myQueryThread;
|
|
|
-}
|
|
|
-
|
|
|
-void App::ActiveClient::setAddress(const QHostAddress &address, quint16 port)
|
|
|
-{
|
|
|
- queryThread()->setAddress(address, port);
|
|
|
-}
|
|
|
-
|
|
|
-void App::ActiveClient::run()
|
|
|
-{
|
|
|
- /* If the client is disconnect check if there is at least one player connected to the server */
|
|
|
- if(client()->state() == Client::DisconnectedState)
|
|
|
- {
|
|
|
- if(!queryThread()->isRunning())
|
|
|
- {
|
|
|
- queryThread()->startQueryThread();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- int playerCount = queryThread()->playerCount();
|
|
|
- if(playerCount != 255 && playerCount > 0 && myDisconnectTime.elapsed() > 10000)
|
|
|
- {
|
|
|
- myApp->print("Players online on server " + queryThread()->serverAddress().toString() + ":" + QString::number(queryThread()->serverPort()) + ". Joining...\n");
|
|
|
- client()->connect(queryThread()->serverAddress().toString().toAscii(), queryThread()->serverPort());
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* If the client is connected and left alone on the server, disconnect yourself */
|
|
|
- if(client()->state() == Client::ConnectedState)
|
|
|
- {
|
|
|
- int playerCount = queryThread()->playerCount();
|
|
|
- if(playerCount == 1 && client()->isOnServer())
|
|
|
- {
|
|
|
- myApp->print("I was left alone on " + queryThread()->serverAddress().toString() + ":" + QString::number(queryThread()->serverPort()) + ". Leaving...\n");
|
|
|
- client()->disconnect();
|
|
|
- myDisconnectTime.restart();
|
|
|
+ ac->incrementReplyCounters(userCount, channelCount, playerCount, serverCount);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /* Say the broadcast count */
|
|
|
- if(!myBroadcastReplyTimer->isActive() && myReplyTimerWasActive)
|
|
|
- {
|
|
|
- myApp->activeClientsReplyCounters(&myUniqueServerCount, &myUniqueUserCount); //add my internal counter to the list
|
|
|
-
|
|
|
- client()->say("::cims:: Sent to " + QString::number(myUniqueServerCount) + " channels, " + QString::number(myUniqueUserCount) + " unique users.");
|
|
|
- myUniqueServerCount = myUniqueUserCount = 0;
|
|
|
- }
|
|
|
- myReplyTimerWasActive = myBroadcastReplyTimer->isActive();
|
|
|
-
|
|
|
- client()->run();
|
|
|
-}
|
|
|
-
|
|
|
-const QString App::ActiveClient::serverAddressString()
|
|
|
-{
|
|
|
- return QString(queryThread()->serverAddress().toString() + ':' + QString::number(queryThread()->serverPort()));
|
|
|
-}
|
|
|
-
|
|
|
-void App::ActiveClient::setReplyHash(const QString &hash)
|
|
|
-{
|
|
|
- myReplyHash = hash;
|
|
|
-
|
|
|
- /* Wait for 5 seconds */
|
|
|
- myBroadcastReplyTimer->setSingleShot(true);
|
|
|
- myBroadcastReplyTimer->start(5000);
|
|
|
-}
|
|
|
-
|
|
|
-const QString& App::ActiveClient::replyHash() const
|
|
|
-{
|
|
|
- return myReplyHash;
|
|
|
}
|
|
|
|
|
|
-bool App::ActiveClient::isWaitingReply() const
|
|
|
-{
|
|
|
- return myBroadcastReplyTimer->isActive();
|
|
|
-}
|
|
|
-
|
|
|
-void App::ActiveClient::incrementReplyCounters(int userCount, int serverCount)
|
|
|
-{
|
|
|
- if(!myBroadcastReplyTimer->isActive())
|
|
|
- return;
|
|
|
- myUniqueUserCount += userCount;
|
|
|
- myUniqueServerCount += serverCount;
|
|
|
-}
|