A Few Bug Fixes

- fixed a bug that prevented the creator of a channel from being
  added to it's member list as the owner.

- fixed a bug that caused the host to open all sub-channels in
  read only mode.

- fixed a bug that caused mod processes to not get called to
  shutdown when the session is closed.

- removed the internal module idle timer, this removed an
  un-needed redundancy. with that, the idle timeout for mod
  processes are now 5 secs while the timeout for cmd processes
  remain at 2 mins.
This commit is contained in:
Maurice ONeal 2020-04-01 11:34:13 -04:00
parent 577784ad6f
commit 629029ebce
12 changed files with 107 additions and 70 deletions

View File

@ -375,7 +375,20 @@ void Session::openSubChannel(const QByteArray &data)
{ {
if (addBlockToBlockset(data.data(), openSubChs, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL)) if (addBlockToBlockset(data.data(), openSubChs, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL))
{ {
auto chId = rd64BitFromBlock(data.data());
auto sub = rd8BitFromBlock(data.data() + 8);
auto level = channelAccessLevel(rdFromBlock(userId, BLKSIZE_USER_ID), chOwnerOverride, chId);
if (!rdOnlyFlagExists(chId, sub, level))
{
addBlockToBlockset(data.data(), openWritableSubChs, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL);
}
containsActiveCh(openSubChs, activeUpdate); containsActiveCh(openSubChs, activeUpdate);
rd8BitFromBlock(activeUpdate);
if (rd8BitFromBlock(activeUpdate))
{
castPeerStat(QByteArray(openSubChs, MAX_OPEN_SUB_CHANNELS * BLKSIZE_SUB_CHANNEL), false);
}
} }
} }

View File

@ -19,16 +19,12 @@
IPCWorker::IPCWorker(const QString &pipe, QObject *parent) : QObject(parent) IPCWorker::IPCWorker(const QString &pipe, QObject *parent) : QObject(parent)
{ {
pipeName = pipe; pipeName = pipe;
idleTimer = new IdleTimer(this);
ipcSocket = new QLocalSocket(this); ipcSocket = new QLocalSocket(this);
flags = 0; flags = 0;
connect(ipcSocket, &QLocalSocket::readyRead, this, &IPCWorker::rdFromIPC); connect(ipcSocket, &QLocalSocket::readyRead, this, &IPCWorker::rdFromIPC);
connect(ipcSocket, &QLocalSocket::disconnected, this, &IPCWorker::ipcClosed); connect(ipcSocket, &QLocalSocket::disconnected, this, &IPCWorker::ipcClosed);
connect(ipcSocket, &QLocalSocket::connected, this, &IPCWorker::ipcOpened); connect(ipcSocket, &QLocalSocket::connected, this, &IPCWorker::ipcOpened);
connect(idleTimer, &IdleTimer::timeout, this, &IPCWorker::termProc);
idleTimer->attach(ipcSocket, 60000); //1min idle timeout
} }
void IPCWorker::rdFromIPC() void IPCWorker::rdFromIPC()
@ -46,7 +42,7 @@ void IPCWorker::rdFromIPC()
} }
else if (ipcSocket->bytesAvailable() >= (FRAME_HEADER_SIZE - 4)) else if (ipcSocket->bytesAvailable() >= (FRAME_HEADER_SIZE - 4))
{ {
QByteArray header = ipcSocket->read(FRAME_HEADER_SIZE - 4); auto header = ipcSocket->read(FRAME_HEADER_SIZE - 4);
ipcTypeId = static_cast<quint8>(header[0]); ipcTypeId = static_cast<quint8>(header[0]);
ipcDataSize = static_cast<quint32>(rdInt(header.mid(1, 3))); ipcDataSize = static_cast<quint32>(rdInt(header.mid(1, 3)));

View File

@ -29,7 +29,6 @@ private slots:
private: private:
IdleTimer *idleTimer;
QLocalSocket *ipcSocket; QLocalSocket *ipcSocket;
quint32 flags; quint32 flags;
quint8 ipcTypeId; quint8 ipcTypeId;

View File

@ -232,8 +232,6 @@ void ModProcess::newIPCLink()
connect(ipcSocket, &QLocalSocket::readyRead, this, &ModProcess::rdFromIPC); connect(ipcSocket, &QLocalSocket::readyRead, this, &ModProcess::rdFromIPC);
connect(ipcSocket, &QLocalSocket::disconnected, this, &ModProcess::ipcDisconnected); connect(ipcSocket, &QLocalSocket::disconnected, this, &ModProcess::ipcDisconnected);
idleTimer->attach(ipcSocket, 120000); //2min idle timeout
onReady(); onReady();
} }
} }
@ -270,6 +268,9 @@ void ModProcess::setSessionParams(QHash<quint16, QString> *uniqueNames,
void ModProcess::onFailToStart() void ModProcess::onFailToStart()
{ {
emit dataToClient(toCmdId32(ASYNC_SYS_MSG, 0), toTEXT("\nerr: A module failed to start so some commands may not have loaded. detailed error information was logged for admin review.\n"), ERR); emit dataToClient(toCmdId32(ASYNC_SYS_MSG, 0), toTEXT("\nerr: A module failed to start so some commands may not have loaded. detailed error information was logged for admin review.\n"), ERR);
emit modProcFinished();
deleteLater();
} }
void ModProcess::err(QProcess::ProcessError error) void ModProcess::err(QProcess::ProcessError error)
@ -278,8 +279,6 @@ void ModProcess::err(QProcess::ProcessError error)
{ {
qDebug() << "err: Module process: " << program() << " failed to start. reason: " << errorString(); qDebug() << "err: Module process: " << program() << " failed to start. reason: " << errorString();
emit finished(1, QProcess::CrashExit);
onFailToStart(); onFailToStart();
} }
} }
@ -356,8 +355,11 @@ void ModProcess::cleanupPipe()
void ModProcess::onReady() void ModProcess::onReady()
{ {
QStringList hostVer = QCoreApplication::applicationVersion().split('.'); idleTimer->attach(ipcSocket, 5000); // 5sec idle timeout
QByteArray verFrame;
auto hostVer = QCoreApplication::applicationVersion().split('.');
QByteArray verFrame;
verFrame.append(wrInt(hostVer[0].toULongLong(), 16)); verFrame.append(wrInt(hostVer[0].toULongLong(), 16));
verFrame.append(wrInt(hostVer[1].toULongLong(), 16)); verFrame.append(wrInt(hostVer[1].toULongLong(), 16));
@ -371,6 +373,8 @@ void ModProcess::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
Q_UNUSED(exitCode) Q_UNUSED(exitCode)
Q_UNUSED(exitStatus) Q_UNUSED(exitStatus)
emit modProcFinished();
cleanupPipe(); cleanupPipe();
deleteLater(); deleteLater();
} }
@ -423,17 +427,25 @@ void CmdProcess::killCmd32(quint32 id32)
void CmdProcess::onReady() void CmdProcess::onReady()
{ {
emit cmdProcReady(cmdId, this); idleTimer->attach(ipcSocket, 120000); // 2min idle timeout
emit cmdProcReady(cmdId);
} }
void CmdProcess::onFailToStart() void CmdProcess::onFailToStart()
{ {
emit dataToClient(cmdId, toTEXT("err: The command failed to start. error details were logged for admin review.\n"), ERR); emit dataToClient(cmdId, toTEXT("err: The command failed to start. error details were logged for admin review.\n"), ERR);
emit dataToClient(cmdId, wrInt(FAILED_TO_START, 16), IDLE); emit dataToClient(cmdId, wrInt(FAILED_TO_START, 16), IDLE);
emit cmdProcFinished(cmdId);
deleteLater();
} }
void CmdProcess::onFinished(int exitCode, QProcess::ExitStatus exitStatus) void CmdProcess::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
{ {
Q_UNUSED(exitCode)
Q_UNUSED(exitStatus)
if (!cmdIdle) if (!cmdIdle)
{ {
emit dataToClient(cmdId, toTEXT("err: The command has stopped unexpectedly or it has failed to send an IDLE frame before exiting.\n"), ERR); emit dataToClient(cmdId, toTEXT("err: The command has stopped unexpectedly or it has failed to send an IDLE frame before exiting.\n"), ERR);
@ -442,7 +454,8 @@ void CmdProcess::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
emit cmdProcFinished(cmdId); emit cmdProcFinished(cmdId);
ModProcess::onFinished(exitCode, exitStatus); cleanupPipe();
deleteLater();
} }
void CmdProcess::rdFromStdErr() void CmdProcess::rdFromStdErr()

View File

@ -31,7 +31,6 @@ private:
QHash<quint16, QString> *cmdRealNames; QHash<quint16, QString> *cmdRealNames;
QHash<quint16, QString> *cmdAppById; QHash<quint16, QString> *cmdAppById;
QList<quint16> *cmdIds; QList<quint16> *cmdIds;
IdleTimer *idleTimer;
quint16 genCmdId(); quint16 genCmdId();
QString makeCmdUnique(const QString &name); QString makeCmdUnique(const QString &name);
@ -47,6 +46,7 @@ protected:
quint32 ipcDataSize; quint32 ipcDataSize;
quint32 hostRank; quint32 hostRank;
quint32 flags; quint32 flags;
IdleTimer *idleTimer;
QLocalServer *ipcServ; QLocalServer *ipcServ;
QLocalSocket *ipcSocket; QLocalSocket *ipcSocket;
@ -92,6 +92,7 @@ public slots:
signals: signals:
void modProcFinished();
void cmdUnloaded(quint16 cmdId); void cmdUnloaded(quint16 cmdId);
void dataToClient(quint32 cmdId, const QByteArray &data, quint8 typeId); void dataToClient(quint32 cmdId, const QByteArray &data, quint8 typeId);
}; };
@ -140,7 +141,7 @@ public:
signals: signals:
void cmdProcFinished(quint32 id); void cmdProcFinished(quint32 id);
void cmdProcReady(quint32 id, CmdProcess *obj); void cmdProcReady(quint32 id);
void pubIPC(quint16 cmdId, const QByteArray &data); void pubIPC(quint16 cmdId, const QByteArray &data);
void privIPC(quint16 cmdId, const QByteArray &data); void privIPC(quint16 cmdId, const QByteArray &data);
void pubIPCWithFeedBack(quint16 cmdId, const QByteArray &data); void pubIPCWithFeedBack(quint16 cmdId, const QByteArray &data);

View File

@ -185,34 +185,34 @@ void LsOpenChannels::procIn(const QByteArray &binIn, quint8 dType)
{ {
QStringList columnData; QStringList columnData;
db.setType(Query::INNER_JOIN_PULL, TABLE_SUB_CHANNELS); db.setType(Query::PULL, TABLE_CHANNELS);
db.addTableColumn(TABLE_SUB_CHANNELS, COLUMN_SUB_CH_NAME); db.addColumn(COLUMN_CHANNEL_NAME);
db.addTableColumn(TABLE_CHANNELS, COLUMN_CHANNEL_NAME);
db.addJoinCondition(COLUMN_CHANNEL_ID, TABLE_CHANNELS);
db.addCondition(COLUMN_CHANNEL_ID, chId); db.addCondition(COLUMN_CHANNEL_ID, chId);
db.exec();
columnData.append(db.getData(COLUMN_CHANNEL_NAME).toString());
db.setType(Query::PULL, TABLE_SUB_CHANNELS);
db.addColumn(COLUMN_SUB_CH_NAME);
db.addCondition(COLUMN_SUB_CH_ID, subId); db.addCondition(COLUMN_SUB_CH_ID, subId);
db.exec(); db.exec();
auto chName = db.getData(COLUMN_CHANNEL_NAME).toString(); columnData.append(db.getData(COLUMN_SUB_CH_NAME).toString());
auto subName = db.getData(COLUMN_SUB_CH_NAME).toString(); columnData.append(QString::number(chId));
columnData.append(QString::number(subId));
QString rdOnly; if (posOfBlock(openSubChs + i, openWritableSubChs, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL) != -1)
{
// the sub-channel id being present in openWritableSubChs mean it is writable and
// therefore is NOT read only.
if (posOfBlock(openSubChs + i, openWritableSubChs, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL) == -1) columnData.append("0");
{
rdOnly = "1";
} }
else else
{ {
rdOnly = "0"; columnData.append("1");
} }
columnData.append(chName);
columnData.append(subName);
columnData.append(QString::number(chId));
columnData.append(QString::number(subId));
columnData.append(rdOnly);
for (int k = 0; k < justLens.size(); ++k) for (int k = 0; k < justLens.size(); ++k)
{ {
if (justLens[k] < columnData[k].size()) justLens[k] = columnData[k].size(); if (justLens[k] < columnData[k].size()) justLens[k] = columnData[k].size();
@ -300,9 +300,9 @@ void AddRDOnlyFlag::procIn(const QByteArray &binIn, quint8 dType)
{ {
errTxt("err: Access denied.\n"); errTxt("err: Access denied.\n");
} }
else if (rdOnlyFlagExists(chName, static_cast<quint8>(subId.toInt()), level.toInt())) else if (rdOnlyFlagExists(chId, static_cast<quint8>(subId.toInt()), level.toUInt()))
{ {
errTxt("err: A read only flag for sub_id: " + QString::number(subId.toInt()) + " level: " + QString::number(level.toInt()) + " already exists.\n"); errTxt("err: A read only flag for sub_id: " + QString::number(subId.toInt()) + " level: " + QString::number(level.toUInt()) + " already exists.\n");
} }
else else
{ {
@ -368,9 +368,9 @@ void RemoveRDOnlyFlag::procIn(const QByteArray &binIn, quint8 dType)
{ {
errTxt("err: Access denied.\n"); errTxt("err: Access denied.\n");
} }
else if (!rdOnlyFlagExists(chName, static_cast<quint8>(subId.toInt()), level.toInt())) else if (!rdOnlyFlagExists(chId, static_cast<quint8>(subId.toUInt()), level.toUInt()))
{ {
errTxt("err: A read only flag for sub_id: " + QString::number(subId.toInt()) + " level: " + QString::number(level.toInt()) + " does not exists.\n"); errTxt("err: A read only flag for sub_id: " + QString::number(subId.toUInt()) + " level: " + QString::number(level.toUInt()) + " does not exists.\n");
} }
else else
{ {

View File

@ -275,8 +275,6 @@ void CreateChannel::procIn(const QByteArray &binIn, uchar dType)
auto args = parseArgs(binIn, 2); auto args = parseArgs(binIn, 2);
auto chName = getParam("-ch_name", args); auto chName = getParam("-ch_name", args);
quint64 chId;
retCode = INVALID_PARAMS; retCode = INVALID_PARAMS;
if (chName.isEmpty()) if (chName.isEmpty())
@ -287,7 +285,7 @@ void CreateChannel::procIn(const QByteArray &binIn, uchar dType)
{ {
errTxt("err: Invalid channel name. it must be between 4-32 chars long and contain no spaces.\n"); errTxt("err: Invalid channel name. it must be between 4-32 chars long and contain no spaces.\n");
} }
else if (channelExists(chName, &chId)) else if (channelExists(chName))
{ {
errTxt("err: Channel name '" + chName + "' already exists.\n"); errTxt("err: Channel name '" + chName + "' already exists.\n");
} }
@ -301,6 +299,12 @@ void CreateChannel::procIn(const QByteArray &binIn, uchar dType)
db.addColumn(COLUMN_CHANNEL_NAME, chName); db.addColumn(COLUMN_CHANNEL_NAME, chName);
db.exec(); db.exec();
db.setType(Query::PULL, TABLE_CHANNELS);
db.addColumn(COLUMN_CHANNEL_ID);
db.addCondition(COLUMN_CHANNEL_NAME, chName);
db.exec();
auto chId = db.getData(COLUMN_CHANNEL_ID).toUInt();
auto uId = rdFromBlock(userId, BLKSIZE_USER_ID); auto uId = rdFromBlock(userId, BLKSIZE_USER_ID);
auto uName = rdStringFromBlock(userName, BLKSIZE_USER_NAME); auto uName = rdStringFromBlock(userName, BLKSIZE_USER_NAME);
auto dName = rdStringFromBlock(displayName, BLKSIZE_DISP_NAME); auto dName = rdStringFromBlock(displayName, BLKSIZE_DISP_NAME);

View File

@ -421,14 +421,14 @@ bool modExists(const QString &modPath)
return db.rows(); return db.rows();
} }
bool rdOnlyFlagExists(const QString &chName, uchar subId, int level) bool rdOnlyFlagExists(quint64 chId, quint8 subId, quint32 level)
{ {
Query db; Query db;
db.setType(Query::PULL, TABLE_RDONLY_CAST); db.setType(Query::PULL, TABLE_RDONLY_CAST);
db.addColumn(COLUMN_ACCESS_LEVEL); db.addColumn(COLUMN_ACCESS_LEVEL);
db.addCondition(COLUMN_SUB_CH_ID, subId); db.addCondition(COLUMN_SUB_CH_ID, subId);
db.addCondition(COLUMN_CHANNEL_NAME, chName); db.addCondition(COLUMN_CHANNEL_ID, chId);
db.addCondition(COLUMN_ACCESS_LEVEL, level); db.addCondition(COLUMN_ACCESS_LEVEL, level);
db.exec(); db.exec();

View File

@ -260,7 +260,7 @@ bool inviteExists(const QByteArray &uId, quint64 chId);
bool channelExists(const QString &chName, quint64 *chId = nullptr); bool channelExists(const QString &chName, quint64 *chId = nullptr);
bool channelSubExists(quint64 chId, const QString &sub, quint8 *subId = nullptr); bool channelSubExists(quint64 chId, const QString &sub, quint8 *subId = nullptr);
bool recoverPWExists(const QByteArray &uId); bool recoverPWExists(const QByteArray &uId);
bool rdOnlyFlagExists(const QString &chName, uchar subId, int level); bool rdOnlyFlagExists(quint64 chId, quint8 subId, quint32 level);
bool isBool(const QString &str); bool isBool(const QString &str);
bool isInt(const QString &str); bool isInt(const QString &str);
bool isLocked(const QByteArray &uId); bool isLocked(const QByteArray &uId);

View File

@ -37,7 +37,7 @@
#include "shell.h" #include "shell.h"
#define APP_NAME "MRCI" #define APP_NAME "MRCI"
#define APP_VER "3.0.0.0" #define APP_VER "3.1.0.0"
#define APP_TARGET "mrci" #define APP_TARGET "mrci"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN

View File

@ -35,6 +35,7 @@ Session::Session(const QString &hostKey, QSslSocket *tcp, QObject *parent) : Mem
tcpPayloadSize = 0; tcpPayloadSize = 0;
tcpFrameType = 0; tcpFrameType = 0;
flags = 0; flags = 0;
activeMods = 0;
} }
void Session::init() void Session::init()
@ -135,10 +136,18 @@ void Session::cmdProcFinished(quint32 cmdId)
} }
} }
void Session::cmdProcStarted(quint32 cmdId, CmdProcess *obj) void Session::modProcFinished()
{ {
cmdProcesses.insert(cmdId, obj); activeMods--;
if (flags & END_SESSION_EMPTY_PROC)
{
endSession();
}
}
void Session::cmdProcStarted(quint32 cmdId)
{
if (frameQueue.contains(cmdId)) if (frameQueue.contains(cmdId))
{ {
for (auto&& frame : frameQueue[cmdId]) for (auto&& frame : frameQueue[cmdId])
@ -152,8 +161,6 @@ void Session::cmdProcStarted(quint32 cmdId, CmdProcess *obj)
void Session::endSession() void Session::endSession()
{ {
emit killMods();
logout("", false); logout("", false);
if (flags & ACTIVE_PAYLOAD) if (flags & ACTIVE_PAYLOAD)
@ -162,7 +169,7 @@ void Session::endSession()
} }
else else
{ {
if (cmdProcesses.isEmpty()) if (cmdProcesses.isEmpty() && (activeMods == 0))
{ {
addIpAction("Session Ended"); addIpAction("Session Ended");
cleanupDbConnection(); cleanupDbConnection();
@ -173,21 +180,17 @@ void Session::endSession()
{ {
flags |= END_SESSION_EMPTY_PROC; flags |= END_SESSION_EMPTY_PROC;
for (auto id : cmdProcesses.keys()) emit killMods();
{
emit killCmd32(id);
}
} }
} }
} }
void Session::startCmdProc(quint32 cmdId) void Session::startCmdProc(quint32 cmdId)
{ {
quint16 cmdId16 = toCmdId16(cmdId); auto cmdId16 = toCmdId16(cmdId);
QString modApp = cmdAppById[cmdId16]; auto modApp = cmdAppById[cmdId16];
QString pipe = rdFromBlock(sessionId, BLKSIZE_USER_ID).toHex() + "-cmd-" + QString::number(cmdId); auto pipe = rdFromBlock(sessionId, BLKSIZE_USER_ID).toHex() + "-cmd-" + QString::number(cmdId);
auto *proc = new CmdProcess(cmdId, cmdRealNames[cmdId16], modApp, sesMemKey, hostMemKey, pipe, this);
auto *proc = new CmdProcess(cmdId, cmdRealNames[cmdId16], modApp, sesMemKey, hostMemKey, pipe, this);
proc->setWorkingDirectory(currentDir); proc->setWorkingDirectory(currentDir);
proc->setSessionParams(sharedMem, sessionId, openWritableSubChs, &hookCmdId32); proc->setSessionParams(sharedMem, sessionId, openWritableSubChs, &hookCmdId32);
@ -202,15 +205,17 @@ void Session::startCmdProc(quint32 cmdId)
connect(this, &Session::killCmd16, proc, &CmdProcess::killCmd16); connect(this, &Session::killCmd16, proc, &CmdProcess::killCmd16);
connect(this, &Session::killCmd32, proc, &CmdProcess::killCmd32); connect(this, &Session::killCmd32, proc, &CmdProcess::killCmd32);
connect(this, &Session::killMods, proc, &CmdProcess::killProc);
cmdProcesses.insert(cmdId, proc);
proc->startCmdProc(); proc->startCmdProc();
} }
ModProcess *Session::initModProc(const QString &modApp) ModProcess *Session::initModProc(const QString &modApp)
{ {
QString pipe = rdFromBlock(sessionId, BLKSIZE_USER_ID).toHex() + "-mod-" + genSerialNumber(); auto pipe = rdFromBlock(sessionId, BLKSIZE_USER_ID).toHex() + "-mod-" + genSerialNumber();
quint32 rnk = rd32BitFromBlock(hostRank); auto rnk = rd32BitFromBlock(hostRank);
auto *proc = new ModProcess(modApp, sesMemKey, hostMemKey, pipe, this); auto *proc = new ModProcess(modApp, sesMemKey, hostMemKey, pipe, this);
proc->setWorkingDirectory(currentDir); proc->setWorkingDirectory(currentDir);
@ -218,9 +223,12 @@ ModProcess *Session::initModProc(const QString &modApp)
connect(proc, &ModProcess::dataToClient, this, &Session::dataToClient); connect(proc, &ModProcess::dataToClient, this, &Session::dataToClient);
connect(proc, &ModProcess::cmdUnloaded, this, &Session::killCmd16); connect(proc, &ModProcess::cmdUnloaded, this, &Session::killCmd16);
connect(proc, &ModProcess::modProcFinished, this, &Session::modProcFinished);
connect(this, &Session::killMods, proc, &ModProcess::killProc); connect(this, &Session::killMods, proc, &ModProcess::killProc);
activeMods++;
return proc; return proc;
} }
@ -255,7 +263,7 @@ void Session::loadCmds()
void Session::dataToCmd(quint32 cmdId, const QByteArray &data, quint8 typeId) void Session::dataToCmd(quint32 cmdId, const QByteArray &data, quint8 typeId)
{ {
quint16 cmdId16 = toCmdId16(cmdId); auto cmdId16 = toCmdId16(cmdId);
if (cmdIds.contains(cmdId16)) if (cmdIds.contains(cmdId16))
{ {
@ -521,15 +529,16 @@ void Session::sendLocalInfo()
dataToClient(ASYNC_SYS_MSG, frame, MY_INFO); dataToClient(ASYNC_SYS_MSG, frame, MY_INFO);
} }
void Session::castPeerStat(const QByteArray &oldSubIds, bool isDisconnecting) void Session::castPeerStat(const QByteArray &targets, bool isDisconnecting)
{ {
if (rd8BitFromBlock(activeUpdate)) if (rd8BitFromBlock(activeUpdate))
{ {
// format: [54bytes(chIds)][1byte(typeId)][rest-of-bytes(PEER_STAT)] // format: [54bytes(chIds)][1byte(typeId)][rest-of-bytes(PEER_STAT)]
QByteArray typeId = wrInt(PEER_STAT, 8); auto typeId = wrInt(PEER_STAT, 8);
QByteArray sesId = rdFromBlock(sessionId, BLKSIZE_SESSION_ID); auto sesId = rdFromBlock(sessionId, BLKSIZE_SESSION_ID);
QByteArray openSubs = rdFromBlock(openSubChs, MAX_OPEN_SUB_CHANNELS * BLKSIZE_SUB_CHANNEL); auto openSubs = rdFromBlock(openSubChs, MAX_OPEN_SUB_CHANNELS * BLKSIZE_SUB_CHANNEL);
QByteArray dc; QByteArray dc;
if (isDisconnecting) if (isDisconnecting)
@ -541,7 +550,7 @@ void Session::castPeerStat(const QByteArray &oldSubIds, bool isDisconnecting)
dc = QByteArray(1, 0x00); dc = QByteArray(1, 0x00);
} }
emit asyncToPeers(ASYNC_LIMITED_CAST, oldSubIds + typeId + sesId + openSubs + dc); emit asyncToPeers(ASYNC_LIMITED_CAST, targets + typeId + sesId + openSubs + dc);
} }
} }

View File

@ -39,6 +39,7 @@ private:
QHash<quint16, QString> cmdRealNames; QHash<quint16, QString> cmdRealNames;
QHash<quint16, QString> cmdAppById; QHash<quint16, QString> cmdAppById;
QList<quint16> cmdIds; QList<quint16> cmdIds;
quint32 activeMods;
quint32 flags; quint32 flags;
quint32 hookCmdId32; quint32 hookCmdId32;
quint32 tcpPayloadSize; quint32 tcpPayloadSize;
@ -55,7 +56,7 @@ private:
void startCmdProc(quint32 cmdId); void startCmdProc(quint32 cmdId);
void startModProc(const QString &modApp); void startModProc(const QString &modApp);
void addIpAction(const QString &action); void addIpAction(const QString &action);
void castPeerStat(const QByteArray &oldSubIds, bool isDisconnecting); void castPeerStat(const QByteArray &targets, bool isDisconnecting);
ModProcess *initModProc(const QString &modApp); ModProcess *initModProc(const QString &modApp);
QByteArray genSessionId(); QByteArray genSessionId();
@ -90,8 +91,9 @@ private slots:
void dataFromClient(); void dataFromClient();
void payloadDeleted(); void payloadDeleted();
void modProcFinished();
void cmdProcFinished(quint32 cmdId); void cmdProcFinished(quint32 cmdId);
void cmdProcStarted(quint32 cmdId, CmdProcess *obj); void cmdProcStarted(quint32 cmdId);
void asyncToClient(quint16 cmdId, const QByteArray &data, quint8 typeId); void asyncToClient(quint16 cmdId, const QByteArray &data, quint8 typeId);
void dataToClient(quint32 cmdId, const QByteArray &data, quint8 typeId); void dataToClient(quint32 cmdId, const QByteArray &data, quint8 typeId);
void dataToCmd(quint32 cmdId, const QByteArray &data, quint8 typeId); void dataToCmd(quint32 cmdId, const QByteArray &data, quint8 typeId);