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 }