#include "mainwindow.h" #include "./ui_mainwindow.h" #include #include #include #include #include #include #include #include #ifdef _WIN64 #include #endif namespace { constexpr uint8_t MAX_INSTALL_STAGES = 3; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); UpdateOSAgnosticInformation(); net = new QNetworkAccessManager(this); PreInstallMode(); QWidget::setWindowTitle("Keeblarcraft Mod Installer"); // ui->centralwidget->setStyleSheet("background-image:url(background.png); background-position: center;"); // Needs work } MainWindow::~MainWindow() { delete ui; delete net; delete reply; } void MainWindow::on_install_update_button_clicked() { QNetworkRequest request(downloadUrl); reply = net->get(request); // connect(reply, SIGNAL(&QNetworkReply::errorOccurred), this, SLOT(Error(QNetworkReply::NetworkError))); connect(reply, &QNetworkReply::errorOccurred, this, [this](QNetworkReply::NetworkError) { reply->deleteLater(); QMessageBox::warning(nullptr, "Error", reply->errorString()); }); connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(UpdateProgress(qint64, qint64))); connect(reply, SIGNAL(finished()), this, SLOT(FinishedDownloading())); } void MainWindow::UpdateProgress(qint64 read, qint64 total) { ui->mf_progress_bar->setMaximum(total); ui->mf_progress_bar->setValue(read); } void MainWindow::FinishedDownloading() { QByteArray data = reply->readAll(); QFile file(downloadLocation); if (file.open(QIODevice::WriteOnly)) { qint64 bytesWritten = file.write(data); } else { QMessageBox::warning(nullptr, "Error", file.errorString()); } reply->deleteLater(); // Update button to not be pressable again. Will probably stick this on a timer in the future ui->install_update_button->setEnabled(false); ui->install_update_button->show(); ui->install_update_button->setText(QString("Unzipping...")); // Unzip Install(); } std::string MainWindow::BuildUnzipCmd() { std::stringstream ss; #ifdef WIN64 ss << "tar -xf " << downloadLocation.toStdString() << " -C " << modsDir.toStdString(); #elif __unix__ ss << "unzip " << downloadLocation.toStdString() << " -d " << modsDir.toStdString(); #endif return ss.str(); } // Installation step covers everything from unzipping to installing the mods to making sure fabric is installed void MainWindow::Install() { uint8_t installStage = 1; ui->mf_progress_bar->setValue(installStage++); ui->mf_progress_bar->setMaximum(MAX_INSTALL_STAGES); // COND 1: If mods dir exists we need to nuke it // COND 2: If mods dir exists & it was our install location do NOT nuke it! if (std::filesystem::is_directory(modsDir.toStdString().append("mods")) && modsDir != downloadLocation) { modsDir.append("mods"); std::filesystem::remove_all(modsDir.toStdString()); } ui->mf_progress_bar->setValue(installStage++); system(BuildUnzipCmd().c_str()); ui->mf_progress_bar->setValue(installStage++); QMessageBox::information(nullptr, "Completed", "The installer has successfully finished. You may now close the installer and launch Minecraft!"); PostInstallMode(); } void MainWindow::Error(QNetworkReply::NetworkError code) { reply->deleteLater(); QMessageBox::warning(nullptr, "Error", reply->errorString()); } void MainWindow::PreInstallMode() { ui->mf_progress_bar->setEnabled(false); ui->install_update_button->setText("Update / Install"); ui->install_update_button->setVisible(true); ui->close_launcher->setEnabled(false); ui->close_launcher->setVisible(false); } void MainWindow::PostInstallMode() { ui->mf_progress_bar->setEnabled(false); ui->install_update_button->setEnabled(false); ui->install_update_button->setVisible(false); ui->close_launcher->setEnabled(true); ui->close_launcher->setVisible(true); } void MainWindow::UpdateOSAgnosticInformation() { #ifdef _WIN64 isLinux = false; char* appDataLoc = std::getenv("APPDATA"); if (appDataLoc) { std::filesystem::path execPath(appDataLoc); downloadLocation = QString::fromStdString(execPath.string()); // Stick the mods inside the roaming directory; but not the .minecraft directory itself. modsDir = downloadLocation + "\\.minecraft\\"; downloadLocation.append("\\mods.zip"); // Should point to %APPDATA%\mods.zip } #elif __unix__ isLinux = true; downloadLocation = getenv("HOME"); modsDir = downloadLocation + "/.minecraft/"; // Default value ui->mcInstallDir->setText(modsDir); // Tell the user the default location for their .minecraft folder. #endif // Update the UI to reflect the default values correctly ui->sf_dl_server->setPlainText(downloadUrl.toString()); } void MainWindow::on_close_launcher_clicked() { delete reply; delete net; QApplication::quit(); } // unused void MainWindow::on_changeInstallPathButton_triggered(QAction *arg1){} void MainWindow::on_changeInstallPathButton_clicked() { QString directory = QFileDialog::getExistingDirectory(this, tr("Find Files"), QDir::currentPath()); if (!directory.isEmpty()) { // We will trust the user that this is the .minecraft folder and do 0 error checking. modsDir = directory; } ui->mcInstallDir->setText(modsDir); }