File indexing completed on 2024-04-28 05:38:03

0001 #include "channellistpanel.h"
0002 #include "ui_channellistpanel.h"
0003 
0004 #include <QCryptographicHash>
0005 #include <QDebug>
0006 #include <QInputDialog>
0007 #include <QJsonArray>
0008 #include <QJsonDocument>
0009 #include <QJsonObject>
0010 #include <QMenu>
0011 
0012 #include "network/channel.h"
0013 #include "network/serverconnection.h"
0014 #include "preferences/preferencesmanager.h"
0015 
0016 ChannelListPanel::ChannelListPanel(NetworkController* ctrl, QWidget* parent)
0017     : QWidget(parent), ui(new Ui::ChannelListPanel), m_ctrl(ctrl), m_currentGroups(VIEWER)
0018 {
0019     ui->setupUi(this);
0020     ui->m_channelView->setModel(m_ctrl->channelModel());
0021     ui->m_channelView->setAlternatingRowColors(true);
0022     ui->m_channelView->setHeaderHidden(true);
0023     ui->m_channelView->setAcceptDrops(true);
0024     ui->m_channelView->setDragEnabled(true);
0025     ui->m_channelView->setDropIndicatorShown(true);
0026     ui->m_channelView->setDefaultDropAction(Qt::MoveAction);
0027     ui->m_channelView->setDragDropMode(QAbstractItemView::InternalMove);
0028 
0029     ui->m_channelView->setContextMenuPolicy(Qt::CustomContextMenu);
0030 
0031     connect(ui->m_channelView, &QTreeView::customContextMenuRequested, this, &ChannelListPanel::showCustomMenu);
0032     connect(m_ctrl->channelModel(), &ChannelModel::localPlayerGMChanged, this,
0033             &ChannelListPanel::CurrentChannelGmIdChanged);
0034 
0035     m_edit= new QAction(tr("Edit Channel"), this);
0036     m_lock= new QAction(tr("Lock/Unlock Channel"), this);
0037     m_join= new QAction(tr("Switch to channel"), this);
0038     m_channelPassword= new QAction(tr("Set/Unset Channel Password"), this);
0039     m_addChannel= new QAction(tr("Add channel"), this);
0040     m_addSubchannel= new QAction(tr("Add subchannel"), this);
0041     m_deleteChannel= new QAction(tr("Delete Channel"), this);
0042     m_setDefault= new QAction(tr("Set Default"), this);
0043     m_admin= new QAction(tr("Log as admin"), this);
0044     m_kick= new QAction(tr("Kick User"), this);
0045     m_ban= new QAction(tr("Ban User"), this);
0046     m_resetChannel= new QAction(tr("Reset Data Channel"), this);
0047     m_moveUserToCurrentChannel= new QAction(tr("Move User"), this);
0048 
0049     connect(m_kick, &QAction::triggered, this, &ChannelListPanel::kickUser);
0050     connect(m_ban, &QAction::triggered, this, &ChannelListPanel::banUser);
0051     connect(m_edit, &QAction::triggered, this, &ChannelListPanel::editChannel);
0052     connect(m_addChannel, &QAction::triggered, this, &ChannelListPanel::addChannelAsSibbling);
0053     connect(m_addSubchannel, &QAction::triggered, this, &ChannelListPanel::addChannel);
0054     connect(m_deleteChannel, &QAction::triggered, this, &ChannelListPanel::deleteChannel);
0055     connect(m_lock, &QAction::triggered, this, &ChannelListPanel::lockChannel);
0056     connect(m_join, &QAction::triggered, this, &ChannelListPanel::joinChannel);
0057     connect(m_admin, &QAction::triggered, this, &ChannelListPanel::logAsAdmin);
0058     connect(m_channelPassword, &QAction::triggered, this, &ChannelListPanel::setPasswordOnChannel);
0059     connect(m_resetChannel, &QAction::triggered, this, &ChannelListPanel::resetChannel);
0060     connect(m_moveUserToCurrentChannel, &QAction::triggered, this, &ChannelListPanel::moveUserToCurrent);
0061 }
0062 
0063 ChannelListPanel::~ChannelListPanel()
0064 {
0065     delete ui;
0066 }
0067 void ChannelListPanel::processMessage(NetworkMessageReader* msg)
0068 {
0069     switch(msg->action())
0070     {
0071     case NetMsg::Goodbye:
0072         break;
0073     case NetMsg::Kicked:
0074         break;
0075     case NetMsg::MoveChannel:
0076         break;
0077     case NetMsg::SetChannelList:
0078     {
0079         QByteArray channelData= msg->byteArray32();
0080         QJsonDocument doc= QJsonDocument::fromJson(channelData);
0081         if(!doc.isEmpty())
0082         {
0083             QJsonObject obj= doc.object();
0084             // m_model->readDataJson(obj);
0085         }
0086     }
0087     break;
0088     case NetMsg::GMStatus:
0089     {
0090         auto isGM= msg->uint8();
0091         if(isGM && (m_currentGroups == VIEWER))
0092         {
0093             setCurrentGroups(m_currentGroups | GAMEMASTER);
0094         }
0095     }
0096     break;
0097     case NetMsg::AdminAuthFail:
0098         setCurrentGroups(VIEWER);
0099         break;
0100     case NetMsg::AdminAuthSucessed:
0101         setCurrentGroups(m_currentGroups | ADMIN);
0102         break;
0103     default:
0104         break;
0105     }
0106 }
0107 
0108 void ChannelListPanel::showCustomMenu(QPoint pos)
0109 {
0110     QMenu menu(this);
0111     enum ClickState
0112     {
0113         Out,
0114         OnChannel,
0115         OnCurrentChannel,
0116         OnUser
0117     };
0118 
0119     ClickState state= Out;
0120     bool isGmChannel= false;
0121     bool isCurrentChannel= false;
0122     bool isOwnUser= false;
0123 
0124     m_index= ui->m_channelView->indexAt(pos);
0125 
0126     if(!m_index.isValid())
0127     {
0128         state= Out;
0129     }
0130     else
0131     {
0132         TreeItem* dataItem= indexToPointer<TreeItem*>(m_index);
0133         if(dataItem->isLeaf())
0134         {
0135             state= OnUser;
0136             isOwnUser= (m_localPlayerId == dataItem->uuid());
0137         }
0138         else
0139         {
0140             state= OnChannel;
0141 
0142             auto channel= dynamic_cast<Channel*>(dataItem);
0143             if(channel)
0144             {
0145                 /*if(!channel->password().isEmpty())
0146                     hasPassword= true;*/
0147                 auto child= channel->getChildById(m_localPlayerId);
0148                 if(child != nullptr)
0149                 {
0150                     isCurrentChannel= true;
0151                     if(isGM())
0152                         isGmChannel= true;
0153                 }
0154             }
0155         }
0156     }
0157 
0158     if(state == OnChannel && !isCurrentChannel)
0159     {
0160         menu.addAction(m_join);
0161         menu.addSeparator();
0162     }
0163 
0164     if(isGM() && isGmChannel)
0165     {
0166         menu.addAction(m_lock);
0167         menu.addAction(m_addSubchannel);
0168         menu.addSeparator();
0169     }
0170 
0171     if(((isGM() && isGmChannel) || isAdmin()) && (state == OnChannel))
0172     {
0173         menu.addAction(m_edit);
0174         menu.addAction(m_resetChannel);
0175         menu.addAction(m_deleteChannel);
0176         menu.addSeparator();
0177     }
0178 
0179     if(isAdmin())
0180     {
0181         if(state == OnChannel)
0182         {
0183             menu.addAction(m_setDefault);
0184             menu.addAction(m_channelPassword);
0185         }
0186         else if(state == OnUser && !isOwnUser)
0187         {
0188             menu.addAction(m_kick);
0189             // menu.addAction(m_ban);
0190         }
0191         menu.addAction(m_addChannel);
0192     }
0193     else
0194     {
0195         menu.addSeparator();
0196         menu.addAction(m_admin);
0197     }
0198     menu.exec(ui->m_channelView->mapToGlobal(pos));
0199 }
0200 bool ChannelListPanel::isAdmin()
0201 {
0202     return (ChannelListPanel::ADMIN & m_currentGroups);
0203 }
0204 
0205 bool ChannelListPanel::isGM()
0206 {
0207     return (ChannelListPanel::GAMEMASTER & m_currentGroups);
0208 }
0209 
0210 void ChannelListPanel::kickUser()
0211 {
0212     if(isAdmin())
0213     {
0214         if(m_index.isValid())
0215         {
0216             ServerConnection* item= getClient(m_index);
0217             if(item == nullptr)
0218                 return;
0219 
0220             QString id= item->uuid();
0221             QString idPlayer= item->playerId();
0222             if(!id.isEmpty())
0223             {
0224                 NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::Kicked);
0225                 msg.string8(id);
0226                 msg.string8(idPlayer);
0227                 msg.sendToServer();
0228             }
0229         }
0230     }
0231 }
0232 void ChannelListPanel::lockChannel()
0233 {
0234     if(!isGM() || !m_index.isValid())
0235         return;
0236 
0237     Channel* item= getChannel(m_index);
0238     if(item == nullptr)
0239         return;
0240     QString id= item->uuid();
0241     if(!id.isEmpty())
0242     {
0243         auto action= item->locked() ? NetMsg::UnlockChannel : NetMsg::LockChannel;
0244         NetworkMessageWriter msg(NetMsg::AdministrationCategory, action);
0245         msg.string8(id);
0246         msg.sendToServer();
0247     }
0248 }
0249 
0250 template <typename T>
0251 T ChannelListPanel::indexToPointer(QModelIndex index)
0252 {
0253     T item= static_cast<T>(index.internalPointer());
0254     return item;
0255 }
0256 
0257 ServerConnection* ChannelListPanel::getClient(QModelIndex index)
0258 {
0259     auto item= indexToPointer<TreeItem*>(index);
0260     if(item->isLeaf())
0261     {
0262         return static_cast<ServerConnection*>(index.internalPointer());
0263     }
0264     return nullptr;
0265 }
0266 
0267 Channel* ChannelListPanel::getChannel(QModelIndex index)
0268 {
0269     auto item= indexToPointer<TreeItem*>(index);
0270     if(!item->isLeaf())
0271     {
0272         return static_cast<Channel*>(index.internalPointer());
0273     }
0274     return nullptr;
0275 }
0276 
0277 void ChannelListPanel::banUser()
0278 {
0279     if(isAdmin())
0280     {
0281         if(m_index.isValid())
0282         {
0283             ServerConnection* item= getClient(m_index); /// static_cast<ServerConnection*>(m_index.internalPointer());
0284             QString id= item->uuid();
0285             QString idPlayer= item->playerId();
0286             if(!id.isEmpty())
0287             {
0288                 NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::BanUser);
0289                 msg.string8(id);
0290                 msg.string8(idPlayer);
0291                 msg.sendToServer();
0292             }
0293         }
0294     }
0295 }
0296 
0297 void ChannelListPanel::logAsAdmin()
0298 {
0299     PreferencesManager* preferences= PreferencesManager::getInstance();
0300 
0301     QString pwadmin= preferences->value(QString("adminPassword_for_%1").arg(m_serverName), QString()).toString();
0302 
0303     if(pwadmin.isEmpty())
0304     {
0305         pwadmin= QInputDialog::getText(this, tr("Admin Password"), tr("Password"), QLineEdit::Password);
0306     }
0307     auto pwA= QCryptographicHash::hash(pwadmin.toUtf8(), QCryptographicHash::Sha3_512);
0308     sendOffLoginAdmin(pwA);
0309 }
0310 
0311 void ChannelListPanel::sendOffLoginAdmin(QByteArray str)
0312 {
0313     if(!str.isEmpty())
0314     {
0315         NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::AdminPassword);
0316         // msg.string8(id);
0317         msg.byteArray32(str);
0318         msg.sendToServer();
0319     }
0320 }
0321 void ChannelListPanel::addChannel()
0322 {
0323     /*  if(isAdmin())
0324       {
0325           Channel* newChannel= new Channel(tr("New Channel"));
0326 
0327           Channel* parent= getChannel(m_index);
0328 
0329           QModelIndex justAdded= m_model->addChannelToIndex(newChannel, m_index);
0330           ui->m_channelView->edit(justAdded);
0331 
0332           if(nullptr != parent)
0333           {
0334               QString parentId= parent->getId();
0335               if(!parentId.isEmpty())
0336               {
0337                   NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::AddChannel);
0338                   msg.string8(parentId);
0339                   newChannel->fill(msg);
0340                   msg.sendToServer();
0341               }
0342           }
0343       }*/
0344 }
0345 void ChannelListPanel::addChannelAsSibbling()
0346 {
0347     /*  if(isAdmin())
0348       {
0349           Channel* newChannel= new Channel(tr("New Channel"));
0350 
0351           auto parentIndex= m_index.parent();
0352 
0353           Channel* parent= nullptr;
0354           QString parentId("");
0355 
0356           if(parentIndex.isValid())
0357           {
0358               parent= getChannel(parentIndex);
0359               parentId= parent->getId();
0360           }
0361 
0362           QModelIndex justAdded= m_model->addChannelToIndex(newChannel, parentIndex);
0363           ui->m_channelView->edit(justAdded);
0364 
0365           NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::AddChannel);
0366           msg.string8(parentId);
0367           newChannel->fill(msg);
0368           msg.sendToServer();
0369       }*/
0370 }
0371 
0372 void ChannelListPanel::editChannel()
0373 {
0374     auto chan= getChannel(m_index);
0375     if(!chan)
0376         return;
0377     bool rightToEdit= isAdmin();
0378 
0379     if(!rightToEdit && isGM())
0380     {
0381         if(nullptr != chan->getChildById(m_localPlayerId))
0382             rightToEdit= true;
0383     }
0384 
0385     if(rightToEdit)
0386     {
0387         ui->m_channelView->edit(m_index);
0388     }
0389 }
0390 
0391 QString ChannelListPanel::serverName() const
0392 {
0393     return m_serverName;
0394 }
0395 
0396 void ChannelListPanel::setServerName(const QString& serverName)
0397 {
0398     m_serverName= serverName;
0399 }
0400 
0401 void ChannelListPanel::setLocalPlayerId(const QString& id)
0402 {
0403     m_localPlayerId= id;
0404     // m_model->setLocalPlayerId(id);
0405 }
0406 
0407 void ChannelListPanel::resetChannel()
0408 {
0409     if(!m_index.isValid())
0410         return;
0411 
0412     if(isAdmin() || isGM())
0413     {
0414         Channel* item= getChannel(m_index);
0415         if(item == nullptr)
0416             return;
0417 
0418         QString id= item->uuid();
0419 
0420         NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::ResetChannel);
0421         msg.string8(id);
0422         msg.sendToServer();
0423     }
0424 }
0425 
0426 void ChannelListPanel::moveUserToCurrent()
0427 {
0428     if(!m_index.isValid())
0429         return;
0430 
0431     auto subject= static_cast<TreeItem*>(m_index.internalPointer());
0432 
0433     if(!subject->isLeaf())
0434         return;
0435 
0436     if(isAdmin() || isGM())
0437     {
0438         /*    auto local= m_model->getServerConnectionById(m_localPlayerId);
0439             if(nullptr == local)
0440                 return;
0441 
0442             auto channel= local->getParentChannel();
0443 
0444             NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::MoveChannel);
0445             msg.string8(subject->getId());
0446             msg.string8(channel->getId());
0447             msg.sendToServer();*/
0448     }
0449 }
0450 
0451 void ChannelListPanel::deleteChannel()
0452 {
0453     if(isAdmin())
0454     {
0455         if(m_index.isValid())
0456         {
0457             Channel* item= getChannel(m_index);
0458             if(nullptr == item)
0459                 return;
0460             QString id= item->uuid();
0461             if(!id.isEmpty())
0462             {
0463                 NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::DeleteChannel);
0464                 msg.string8(id);
0465                 msg.sendToServer();
0466             }
0467         }
0468     }
0469 }
0470 
0471 void ChannelListPanel::setPasswordOnChannel()
0472 {
0473     if(!isAdmin() && !m_index.isValid())
0474         return;
0475 
0476     Channel* item= getChannel(m_index);
0477 
0478     if(nullptr == item)
0479         return;
0480 
0481     auto pw= QInputDialog::getText(this, tr("Channel Password"),
0482                                    tr("Password for channel: %1 - leave empty for no password").arg(item->name()),
0483                                    QLineEdit::Password, item->password());
0484 
0485     if(pw.isEmpty())
0486     {
0487         NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::ResetChannelPassword);
0488         msg.string8(item->uuid());
0489         msg.sendToServer();
0490         return;
0491     }
0492 
0493     NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::ChannelPassword);
0494     msg.string8(item->uuid());
0495     auto pwA= QCryptographicHash::hash(pw.toUtf8(), QCryptographicHash::Sha3_512);
0496     msg.byteArray32(pwA);
0497     msg.sendToServer();
0498 }
0499 
0500 void ChannelListPanel::joinChannel()
0501 {
0502     if(!m_index.isValid())
0503         return;
0504 
0505     Channel* item= getChannel(m_index);
0506     if(nullptr == item)
0507         return;
0508 
0509     QByteArray pw;
0510     if(!item->password().isEmpty())
0511         pw= QInputDialog::getText(this, tr("Channel Password"), tr("Channel %1 required password:").arg(item->name()),
0512                                   QLineEdit::Password)
0513                 .toUtf8();
0514 
0515     QString id= item->uuid();
0516     if(!id.isEmpty())
0517     {
0518         NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::JoinChannel);
0519         msg.string8(id);
0520         msg.string8(m_localPlayerId);
0521         auto pwA= QCryptographicHash::hash(pw, QCryptographicHash::Sha3_512);
0522         msg.byteArray32(pwA);
0523         msg.sendToServer();
0524     }
0525 }
0526 
0527 ChannelListPanel::Groups ChannelListPanel::currentGroups() const
0528 {
0529     return m_currentGroups;
0530 }
0531 
0532 void ChannelListPanel::setCurrentGroups(const Groups& currentGroups)
0533 {
0534     m_currentGroups= currentGroups;
0535 }
0536 void ChannelListPanel::cleanUp()
0537 {
0538     /*   if(nullptr != m_model)
0539            m_model->cleanUp();*/
0540 }