Advertisement
Guest User

Untitled

a guest
Dec 30th, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.26 KB | None | 0 0
  1. #include "editor.h"
  2. #include "ui_editor.h"
  3. #include <QFileDialog>
  4. #include <QDebug>
  5. #include <QListWidget>
  6. #include <String.h>
  7. #include <iostream>
  8. #include <stdio.h>
  9. #include <QDesktopServices>
  10. #include "editrecent.h"
  11. #include "settings.h"
  12. #include "usernamepasswordgenerator.h"
  13. #include "global.h"
  14. #include "thisapp.h"
  15. #include <QMessageBox>
  16. #include "getkey.h"
  17. #include <QFileSystemModel>
  18. #include <QStandardItem>
  19. #include <QTreeWidgetItem>
  20. #include <QHeaderView>
  21. #include <AES/qaesencryption.h>
  22. #include <QCryptographicHash>
  23. #include <filecreationwizard.h>
  24. #include <newfiletreewizard.h>
  25.  
  26.  
  27. //change this shit later
  28. QString Editor::openedDir = "C:\\Users\\Full_Nitrous\\Desktop\\TestFolder";
  29. QString Editor::key = "";
  30. QString Editor::iv = "";
  31. QFileSystemModel Editor::*globalDirModel;
  32. QMenu Editor::*commandFileContextMenu;
  33. QPoint Editor::lastCommandFilePoint;
  34.  
  35. Editor::Editor(QWidget *parent) : QMainWindow(parent), ui(new Ui::Editor)
  36. {
  37. ui->setupUi(this);
  38. readRecentDotDat();
  39. ui->actionFind->setEnabled(false);
  40. ui->actionUndo->setEnabled(false);
  41. ui->actionRedo->setEnabled(false);
  42. ui->actionSave_Selected_File->setEnabled(false);
  43. ui->actionFullscreen->setEnabled(false);
  44. ui->actionSettings->setEnabled(false);
  45. ui->actionCustom->setEnabled(false);
  46. ui->actionNew_Command_File->setEnabled(false);
  47. ui->actionNew_password_file->setEnabled(false);
  48. ui->actionNew->setEnabled(false);
  49. ui->actionNew_Text_File->setEnabled(false);
  50. ui->actionStart_Menu->setEnabled(false);
  51. ui->label->setPixmap(QPixmap(startPagePicture));
  52. ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
  53. ui->tableWidget->setColumnWidth(1, 60);
  54.  
  55. ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
  56. connect(ui->tableWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
  57. commandFileContextMenu = new QMenu(this);
  58. commandFileContextMenu->addAction(tr("Add New Command"));
  59. commandFileContextMenu->addAction(tr("Remove Command"));
  60. connect(commandFileContextMenu, SIGNAL(triggered(QAction*)), SLOT(editCommandRows(QAction*)));
  61.  
  62.  
  63. readDirectoryToEditor();
  64. return;
  65. }
  66.  
  67. Editor::~Editor()
  68. {
  69. delete ui;
  70. return;
  71. }
  72.  
  73. void Editor::editCommandRows(QAction* action)
  74. {
  75. QString actiontodo = action->text();
  76. if(actiontodo == "Add New Command")
  77. {
  78. ui->tableWidget->insertRow(ui->tableWidget->rowCount());
  79. ui->tableWidget->verticalHeader()->resizeSection(ui->tableWidget->rowCount() - 1, 20);
  80. }
  81. else if(actiontodo == "Remove Command")
  82. {
  83. QModelIndex index = ui->tableWidget->indexAt(lastCommandFilePoint);
  84. ui->tableWidget->removeRow(index.row());
  85. }
  86. return;
  87. }
  88.  
  89. void Editor::customMenuRequested(QPoint pos)
  90. {
  91. lastCommandFilePoint = pos;
  92. commandFileContextMenu->popup(ui->tableWidget->viewport()->mapToGlobal(pos));
  93. return;
  94. }
  95.  
  96. void Editor::enterEditor(QString directory)
  97. {
  98. qDebug() << "entered editor with: " << directory;
  99.  
  100. if(directory == "" || !QDir(directory).exists())
  101. {
  102. QMessageBox messageBox;
  103. messageBox.critical(0,"Error","Invalid directory");
  104. messageBox.setFixedSize(500,200);
  105. }
  106. else
  107. {
  108. openedDir = directory;
  109. promptKey();
  110. }
  111. return;
  112. }
  113.  
  114. QString Editor::promptKey()
  115. {
  116. QString returnValue = "";
  117.  
  118. getKey gk;
  119. gk.setModal(true);
  120. gk.exec();
  121. QObject::connect(&gk, SIGNAL(gotKey(QString)), this, SLOT(continueToEnteringEditor(QString)));
  122. return returnValue;
  123. }
  124.  
  125. void Editor::continueToEnteringEditor(QString keyInput)
  126. {
  127. bool wrongCharacters = false;
  128.  
  129. if(keyInput == "" || wrongCharacters)
  130. {
  131. QMessageBox messageBox;
  132. messageBox.critical(0,"Input Error","Invalid characters and or no characters were used.");
  133. messageBox.setFixedSize(500,200);
  134. }
  135. else
  136. { key = keyInput;
  137. ui->actionNew_password_file->setEnabled(true);
  138. ui->actionNew_Command_File->setEnabled(true);
  139. ui->actionNew_Text_File->setEnabled(true);
  140. ui->actionStart_Menu->setEnabled(true);
  141. ui->actionFind->setEnabled(true);
  142. ui->actionStart_Menu->setEnabled(true);
  143. ui->actionNew->setEnabled(true);
  144. this->setWindowTitle("Editor - " + openedDir);
  145. ui->stackedWidget->setCurrentIndex(1);
  146.  
  147. readDirectoryToEditor();
  148. }
  149. return;
  150. }
  151.  
  152. void Editor::readDirectoryToEditor(void)
  153. {
  154. globalDirModel = new QFileSystemModel(this);
  155. ui->treeView->setModel(globalDirModel);
  156. ui->treeView->setRootIndex(globalDirModel->setRootPath(openedDir + "/DRT/"));
  157.  
  158. ui->treeView->setSelectionMode(QAbstractItemView::SingleSelection);
  159. ui->treeView->setDragDropMode(QAbstractItemView::InternalMove);
  160.  
  161.  
  162.  
  163. ui->treeView->hideColumn(1);
  164. ui->treeView->hideColumn(2);
  165. ui->treeView->hideColumn(3);
  166.  
  167. return;
  168. }
  169.  
  170. void Editor::on_treeView_clicked(const QModelIndex &index)
  171. {
  172. QFileSystemModel *dirModel = new QFileSystemModel(this);
  173. QString path = dirModel->fileInfo(index).absoluteFilePath();
  174. QString extension = dirModel->fileInfo(index).suffix();
  175. bool isDir = dirModel->fileInfo(index).isDir();
  176.  
  177.  
  178. if(isDir)
  179. {
  180. ui->stackedWidget_2->setCurrentIndex(3);
  181. ui->actionSave_Selected_File->setEnabled(false);
  182. }
  183. else if(!isDir)
  184. {
  185. ui->actionSave_Selected_File->setEnabled(true);
  186.  
  187. if(extension == "ea1")
  188. {
  189. QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::CBC);
  190. QByteArray hashKey = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256);
  191. QByteArray hashIV = QCryptographicHash::hash(iv.toLocal8Bit(), QCryptographicHash::Sha256);
  192.  
  193. QFile file(path);
  194. file.open(QIODevice::ReadOnly);
  195. QByteArray encryptedData = file.readAll();
  196.  
  197. QByteArray decodeText = encryption.decode(encryptedData, hashKey, hashIV);
  198.  
  199. int last;
  200. QString container = "";
  201. for(int i = 0; i < decodeText.length(); i++)
  202. {
  203. if(decodeText[i] == '\n')
  204. {
  205. ui->lineEdit_2->setText(container);
  206. container = "";
  207. last = i + 1;
  208. break;
  209. }
  210. else
  211. {
  212. container += decodeText[i];
  213. }
  214. }
  215.  
  216. for(int i = last; i < decodeText.length(); i++)
  217. {
  218. if(decodeText[i] == '\n')
  219. {
  220. ui->lineEdit->setText(container);
  221. container = "";
  222. last = i + 1;
  223. break;
  224. }
  225. else
  226. {
  227. container += decodeText[i];
  228. }
  229. }
  230.  
  231. for(int i = last; i < decodeText.length(); i++)
  232. {
  233. if(decodeText[i] == '\0')
  234. {
  235. break;
  236. }
  237. container += decodeText[i];
  238. }
  239.  
  240. ui->plainTextEdit->setPlainText(container);
  241.  
  242. ui->stackedWidget_2->setCurrentIndex(2);
  243. }
  244. else if(extension == "cmd")
  245. {
  246. ui->tableWidget->setRowCount(0);
  247. QString data = "";
  248. int delay = 0;
  249. char c;
  250. FILE *file;
  251. file = fopen(path.toStdString().c_str(), "r");
  252. while((c = getc(file)) != EOF)
  253. {
  254. ungetc(c, file);
  255.  
  256. delay = getc(file);
  257. delay = (delay << 8) | getc(file);
  258.  
  259. while((c = getc(file)) != EOF)
  260. {
  261. if(c == '\n')
  262. {
  263. ui->tableWidget->insertRow (ui->tableWidget->rowCount());
  264. ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, new QTableWidgetItem(data));
  265. ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 1, new QTableWidgetItem(QString::number(delay)));
  266. ui->tableWidget->verticalHeader()->resizeSection(ui->tableWidget->rowCount() - 1, 20);
  267. data = "";
  268. delay = 0;
  269. break;
  270. }
  271. else
  272. {
  273. data += c;
  274. }
  275. }
  276. }
  277. fclose(file);
  278. ui->stackedWidget_2->setCurrentIndex(1);
  279. }
  280. else if(extension == "txt")
  281. {
  282. ui->stackedWidget_2->setCurrentIndex(0);
  283. QString data = "";
  284. char c;
  285. FILE *file;
  286. file = fopen(path.toStdString().c_str(), "r");
  287. while((c = fgetc(file)) != EOF)
  288. {
  289. data += c;
  290. }
  291. ui->textEdit_2->setText(data);
  292. fclose(file);
  293. }
  294. else
  295. {
  296. ui->stackedWidget_2->setCurrentIndex(3);
  297. }
  298. }
  299. delete dirModel;
  300. return;
  301. }
  302.  
  303. void Editor::readRecentDotDat(void)
  304. {
  305. FILE *file;
  306. file = fopen(recentDirectoriesFilePath, "r");
  307. char c;
  308. std::string container = "";
  309. while((c = getc(file)) != EOF)
  310. {
  311. if(c == '\n')
  312. {
  313. ui->label_3->setText(container.c_str());
  314. container = "";
  315. break;
  316. }
  317. else
  318. {
  319. container += c;
  320. }
  321. }
  322. rewind(file);
  323. while((c = getc(file)) != EOF)
  324. {
  325. if(c == '\n')
  326. {
  327. ui->recentDirectoriesList->addItem(container.c_str());
  328. container = "";
  329. }
  330. else
  331. {
  332. container += c;
  333. }
  334. }
  335. fclose(file);
  336. return;
  337. }
  338.  
  339. void Editor::on_recentDirectoriesList_itemClicked(QListWidgetItem *item)
  340. {
  341. ui->label_3->setText(item->text());
  342. return;
  343. }
  344.  
  345. void Editor::on_recentDirectoriesList_itemDoubleClicked(QListWidgetItem *item)
  346. {
  347. enterEditor(item->text());
  348. return;
  349. }
  350.  
  351. void Editor::on_actionAdd_To_Recent_Directories_triggered()
  352. {
  353. EditRecent er;
  354. QObject::connect(&er, SIGNAL(recentDirectoriesChange()), this, SLOT(reloadRecentDirectories()));
  355. er.setModal(true);
  356. er.exec();
  357. return;
  358. }
  359.  
  360. void Editor::reloadRecentDirectories(void)
  361. {
  362. ui->recentDirectoriesList->clear();
  363. readRecentDotDat();
  364. return;
  365. }
  366.  
  367. void Editor::on_pushButton_clicked()
  368. {
  369. QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  370.  
  371. if(dir != "")
  372. {
  373. std::string addThis = dir.toStdString() + '\n';
  374. bool exists = false;
  375. FILE *file;
  376. file = fopen(recentDirectoriesFilePath, "r");
  377.  
  378. std::string container = "";
  379. char c;
  380. while((c = getc(file)) != EOF)
  381. {
  382. if(c == '\n')
  383. {
  384. if(container + '\n' == addThis)
  385. {
  386. exists = true;
  387. }
  388. container = "";
  389. }
  390. else
  391. {
  392. container += c;
  393. }
  394. }
  395. fclose(file);
  396. if(!exists)
  397. {
  398. file = fopen(recentDirectoriesFilePath, "a");
  399. fwrite(addThis.c_str(), sizeof(char), addThis.length(), file);
  400. fclose(file);
  401. }
  402. emit reloadRecentDirectories();
  403. }
  404.  
  405. enterEditor(dir);
  406.  
  407. return;
  408. }
  409.  
  410. void Editor::on_pushButton_2_clicked()
  411. {
  412. QString a = ui->label_3->text();
  413. enterEditor(a);
  414. return;
  415. }
  416.  
  417. void Editor::on_actionQuit_triggered()
  418. {
  419. qApp->exit();
  420. return;
  421. }
  422.  
  423. void Editor::on_actionDark_triggered()
  424. {
  425. setStyleSheet(
  426. "QMainWindow "
  427. "{"
  428. " background: 'yellow';"
  429. "}"
  430. "QPushButton"
  431. "{"
  432. " background: 'black';"
  433. "}"
  434. "");
  435. return;
  436. }
  437.  
  438. void Editor::on_actionLight_triggered()
  439. {
  440. setStyleSheet("");
  441. return;
  442. }
  443.  
  444. void Editor::on_actionFullscreen_triggered()
  445. {
  446. if(ui->actionFullscreen->text() == "Fullscreen")
  447. {
  448. Editor::showFullScreen();
  449. ui->actionFullscreen->setText("Normalize");
  450. }
  451. else if(ui->actionFullscreen->text() == "Normalize")
  452. {
  453. Editor::showNormal();
  454. ui->actionFullscreen->setText("Fullscreen");
  455. }
  456. return;
  457. }
  458.  
  459. void Editor::on_actionSettings_triggered()
  460. {
  461. Settings settings;
  462. settings.setTab(0);
  463. settings.setModal(true);
  464. settings.exec();
  465. return;
  466. }
  467.  
  468. void Editor::on_actionUsername_and_Password_Generator_triggered()
  469. {
  470. UsernamePasswordGenerator UPGen;
  471. UPGen.setModal(true);
  472. UPGen.exec();
  473. return;
  474. }
  475.  
  476. void Editor::on_actionWebsite_triggered()
  477. {
  478. QString link = "http://www.voidzehn.com";
  479. QDesktopServices::openUrl(QUrl(link));
  480. return;
  481. }
  482.  
  483. void Editor::on_actionThis_Application_triggered()
  484. {
  485. ThisApp ta;
  486. ta.setModal(true);
  487. ta.exec();
  488. return;
  489. }
  490.  
  491. void Editor::on_actionCustom_triggered()
  492. {
  493. Settings settings;
  494. settings.setTab(3);
  495. settings.setModal(true);
  496. settings.exec();
  497. return;
  498. }
  499.  
  500. void Editor::on_actionOffline_Manuals_triggered()
  501. {
  502. QString link = "file:///C://Users//Full_Nitrous//Downloads//pepe_baloon_1_2.pdf";
  503. QDesktopServices::openUrl(QUrl(link));
  504. return;
  505. }
  506.  
  507. void Editor::on_actionOnline_manuals_triggered()
  508. {
  509. QString link = "http://www.voidzehn.com/pdfsomething";
  510. QDesktopServices::openUrl(QUrl(link));
  511. return;
  512. }
  513.  
  514. void Editor::on_actionContact_triggered()
  515. {
  516. QString link = "http://www.voidzehn.com/contact";
  517. QDesktopServices::openUrl(QUrl(link));
  518. return;
  519. }
  520.  
  521.  
  522. //this function has to get moved to a context menu instead of being static control
  523. /*
  524. void Editor::on_pushButton_4_clicked()
  525. {
  526.  
  527. QModelIndex index = ui->treeView->currentIndex();
  528.  
  529. QFileSystemModel *dirModel = new QFileSystemModel(this);
  530.  
  531.  
  532. QString path = dirModel->fileInfo(index).absoluteFilePath();
  533. QString dir = dirModel->fileInfo(index).dir().path();
  534. QString extension = dirModel->fileInfo(index).suffix();
  535. bool isDir = dirModel->fileInfo(index).isDir();
  536.  
  537. if(ui->lineEdit_3->text() == "" || path == "")
  538. {
  539. QMessageBox messageBox;
  540. messageBox.information(0, "Information", "Invalid path and or no new name was given.");
  541. messageBox.setFixedSize(500,200);
  542. }
  543. else
  544. {
  545.  
  546. if(isDir)
  547. {
  548. QString newPath = dir + '/' + ui->lineEdit_3->text();
  549. QDir currentDirectory(path);
  550. currentDirectory.rename(currentDirectory.path(), newPath);
  551.  
  552. }
  553. else
  554. {
  555. QString newPath = dir + '/' + ui->lineEdit_3->text() + '.' + extension;
  556. QFile file(newPath);
  557. if(file.exists())
  558. {
  559. QMessageBox messageBox;
  560. messageBox.information(0, "Information", "File already exists.");
  561. messageBox.setFixedSize(500,200);
  562. file.close();
  563. }
  564. else
  565. {
  566. QFile file(path);
  567. if(file.exists())
  568. {
  569. file.rename(newPath);
  570. }
  571. file.close();
  572. ui->lineEdit_3->setText("");
  573. }
  574. }
  575. }
  576. delete dirModel;
  577. return;
  578. }
  579. */
  580.  
  581. void Editor::on_actionSave_Selected_File_triggered()
  582. {
  583. //get what file is selected
  584. qDebug() << "save";
  585.  
  586. QModelIndex index = ui->treeView->currentIndex();
  587. QFileSystemModel *dirModel = new QFileSystemModel(this);
  588. QString path = dirModel->fileInfo(index).absoluteFilePath();
  589. QString extension = dirModel->fileInfo(index).suffix();
  590.  
  591. if(extension == "ea1")
  592. {
  593. QString username = ui->lineEdit_2->text();
  594. QString password = ui->lineEdit->text();
  595. QString additionalNotes = ui->plainTextEdit->toPlainText();
  596.  
  597. QString combinedData = username + '\n' + password + '\n' + additionalNotes;
  598.  
  599. QAESEncryption encryption2(QAESEncryption::AES_256, QAESEncryption::CBC);
  600. QByteArray hashKey2 = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256);
  601. QByteArray hashIV2 = QCryptographicHash::hash(iv.toLocal8Bit(), QCryptographicHash::Sha256);
  602.  
  603. QByteArray encoded = encryption2.encode(combinedData.toLocal8Bit(), hashKey2, hashIV2);
  604.  
  605. QFile file(path);
  606. file.open(QIODevice::WriteOnly);
  607. file.write(encoded);
  608. file.close();
  609. }
  610. else if(extension == "txt")
  611. {
  612. QByteArray text = ui->textEdit_2->toPlainText().toLocal8Bit();
  613. QFile file(path);
  614. file.open(QIODevice::WriteOnly);
  615. file.write(text);
  616. file.close();
  617. }
  618. else if(extension == "cmd")
  619. {
  620. QByteArray command;
  621. int delay;
  622. QByteArray delayAsBytes;
  623.  
  624. //QFile file(path);
  625. //file.open(QIODevice::WriteOnly);
  626.  
  627. int rows = ui->tableWidget->rowCount();
  628. qDebug() << rows;
  629. bool convertOK;
  630.  
  631. QFile file(path);
  632. file.open(QIODevice::WriteOnly);
  633.  
  634. for(int i = 0; i < rows; i++)
  635. {
  636. command = ui->tableWidget->item(i, 0)->text().toLocal8Bit();
  637. delay = ui->tableWidget->item(i, 1)->text().toInt(&convertOK);
  638.  
  639. delayAsBytes.append((char)((delay >> 8) & 0xFF));
  640. delayAsBytes.append((char)(delay & 0xFF));
  641.  
  642. file.write(delayAsBytes);
  643. file.write(command.append('\n'));
  644.  
  645. qDebug() << "wrote this: " << delayAsBytes;
  646. qDebug() << "wrote this: " << command;
  647.  
  648. delayAsBytes.clear();
  649. }
  650. file.close();
  651.  
  652.  
  653.  
  654. }
  655. delete dirModel;
  656. return;
  657. }
  658.  
  659. void Editor::on_pushButton_3_clicked()
  660. {
  661. NewFileTreeWizard nftwiz;
  662.  
  663. nftwiz.setModal(true);
  664. nftwiz.exec();
  665. return;
  666. }
  667.  
  668. void Editor::on_actionNew_password_file_triggered()
  669. {
  670. createFile(".ea1", "new");
  671. return;
  672. }
  673.  
  674. void Editor::on_actionNew_Command_File_triggered()
  675. {
  676. createFile(".cmd", "new");
  677. return;
  678. }
  679.  
  680. void Editor::on_actionNew_Text_File_triggered()
  681. {
  682. createFile(".txt", "new");
  683. return;
  684. }
  685.  
  686. void Editor::on_actionNew_triggered()
  687. {
  688. FileCreationWizard fwiz;
  689. QObject::connect(&fwiz, SIGNAL(fileCreated(QString, QString)), this, SLOT(createFileFromWizard(QString,QString)));
  690. fwiz.setModal(true);
  691. fwiz.exec();
  692. return;
  693. }
  694.  
  695. void Editor::createFileFromWizard(QString fileType, QString fileName)
  696. {
  697. if(fileType == "AES 256 Encrypted Password and Username file (*.ea1)")
  698. {
  699. createFile(".ea1", fileName);
  700. }
  701. else if(fileType == "Text File (*.txt)")
  702. {
  703. createFile(".txt", fileName);
  704. }
  705. else if(fileType == "Delayed Command File (*.cmd)")
  706. {
  707. createFile(".cmd", fileName);
  708. }
  709. return;
  710. }
  711.  
  712. void Editor::createFile(QString type, QString name)
  713. {
  714. QModelIndex index = ui->treeView->currentIndex();
  715. QFileSystemModel *dirModel = new QFileSystemModel(this);
  716. QString dir = dirModel->fileInfo(index).dir().path();
  717. QString fileName = name;
  718. QString extension = type;
  719.  
  720. //sort of half ass fix for selecting the first file in the treeView
  721. if(dir == ".")
  722. {
  723. dir = openedDir + "/DRT/";
  724. }
  725. //sort of half ass fix for selecting the first file in the treeView
  726.  
  727. int i = 0;
  728. QFile file(dir + '/' + fileName + extension);
  729.  
  730. while(file.exists())
  731. {
  732. i++;
  733. file.setFileName(dir + '/' + fileName + QString::number(i) + extension);
  734. if(i == INT_MAX)
  735. {
  736. break;
  737. }
  738. }
  739. file.open(QIODevice::WriteOnly);
  740. file.close();
  741. delete dirModel;
  742. return;
  743. }
  744.  
  745. void Editor::on_actionStart_Menu_triggered()
  746. {
  747. delete globalDirModel;
  748. ui->stackedWidget->setCurrentIndex(0);
  749. ui->stackedWidget_2->setCurrentIndex(3);
  750. ui->actionStart_Menu->setEnabled(false);
  751. ui->actionNew_Command_File->setEnabled(false);
  752. ui->actionNew_password_file->setEnabled(false);
  753. ui->actionNew->setEnabled(false);
  754. ui->actionNew_Text_File->setEnabled(false);
  755. ui->actionSave_Selected_File->setEnabled(false);
  756. return;
  757. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement