keeblarcraft_installer/mainwindow.cpp

180 lines
5.5 KiB
C++

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QMessageBox>
#include <QProgressBar>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <filesystem>
#include <sstream>
#include <QFileDialog>
#ifdef _WIN64
#include <Windows.h>
#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);
}