2022-05-26 22:18:54 +01:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
/*
|
|
|
|
* PolyMC - Minecraft Launcher
|
|
|
|
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, version 3.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following copyright and
|
|
|
|
* permission notice:
|
|
|
|
*
|
|
|
|
* Copyright 2013-2021 MultiMC Contributors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2016-05-12 21:51:25 +01:00
|
|
|
#include <QFileDialog>
|
2023-08-02 17:35:35 +01:00
|
|
|
#include <QFileInfo>
|
2021-08-20 00:34:32 +01:00
|
|
|
#include <QPainter>
|
|
|
|
|
2016-05-12 21:51:25 +01:00
|
|
|
#include <FileSystem.h>
|
2021-11-20 15:22:22 +00:00
|
|
|
|
|
|
|
#include <minecraft/services/CapeChange.h>
|
2023-08-02 17:35:35 +01:00
|
|
|
#include <minecraft/services/SkinUpload.h>
|
2021-08-20 00:34:32 +01:00
|
|
|
#include <tasks/SequentialTask.h>
|
|
|
|
|
2023-08-02 17:35:35 +01:00
|
|
|
#include "CustomMessageBox.h"
|
|
|
|
#include "ProgressDialog.h"
|
2016-05-12 21:51:25 +01:00
|
|
|
#include "SkinUploadDialog.h"
|
|
|
|
#include "ui_SkinUploadDialog.h"
|
|
|
|
|
|
|
|
void SkinUploadDialog::on_buttonBox_rejected()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinUploadDialog::on_buttonBox_accepted()
|
|
|
|
{
|
2018-02-14 23:40:23 +00:00
|
|
|
QString fileName;
|
|
|
|
QString input = ui->skinPathTextBox->text();
|
2022-07-15 02:35:03 +01:00
|
|
|
ProgressDialog prog(this);
|
|
|
|
SequentialTask skinUpload;
|
|
|
|
|
|
|
|
if (!input.isEmpty()) {
|
|
|
|
QRegularExpression urlPrefixMatcher(QRegularExpression::anchoredPattern("^([a-z]+)://.+$"));
|
|
|
|
bool isLocalFile = false;
|
|
|
|
// it has an URL prefix -> it is an URL
|
2023-08-02 17:35:35 +01:00
|
|
|
if (urlPrefixMatcher.match(input).hasMatch()) {
|
2022-07-15 02:35:03 +01:00
|
|
|
QUrl fileURL = input;
|
2023-08-02 17:35:35 +01:00
|
|
|
if (fileURL.isValid()) {
|
2022-07-15 02:35:03 +01:00
|
|
|
// local?
|
2023-08-02 17:35:35 +01:00
|
|
|
if (fileURL.isLocalFile()) {
|
2022-07-15 02:35:03 +01:00
|
|
|
isLocalFile = true;
|
|
|
|
fileName = fileURL.toLocalFile();
|
2023-08-02 17:35:35 +01:00
|
|
|
} else {
|
|
|
|
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Using remote URLs for setting skins is not implemented yet."),
|
|
|
|
QMessageBox::Warning)
|
|
|
|
->exec();
|
2022-07-15 02:35:03 +01:00
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2023-08-02 17:35:35 +01:00
|
|
|
} else {
|
|
|
|
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("You cannot use an invalid URL for uploading skins."),
|
|
|
|
QMessageBox::Warning)
|
|
|
|
->exec();
|
2018-02-14 23:40:23 +00:00
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2023-08-02 17:35:35 +01:00
|
|
|
} else {
|
2022-07-15 02:35:03 +01:00
|
|
|
// just assume it's a path then
|
|
|
|
isLocalFile = true;
|
|
|
|
fileName = ui->skinPathTextBox->text();
|
|
|
|
}
|
2023-08-02 17:35:35 +01:00
|
|
|
if (isLocalFile && !QFile::exists(fileName)) {
|
2022-07-15 02:35:03 +01:00
|
|
|
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec();
|
2018-02-14 23:40:23 +00:00
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2022-07-15 02:35:03 +01:00
|
|
|
SkinUpload::Model model = SkinUpload::STEVE;
|
2023-08-02 17:35:35 +01:00
|
|
|
if (ui->steveBtn->isChecked()) {
|
2022-07-15 02:35:03 +01:00
|
|
|
model = SkinUpload::STEVE;
|
2023-08-02 17:35:35 +01:00
|
|
|
} else if (ui->alexBtn->isChecked()) {
|
2022-07-15 02:35:03 +01:00
|
|
|
model = SkinUpload::ALEX;
|
|
|
|
}
|
|
|
|
skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, m_acct->accessToken(), FS::read(fileName), model)));
|
2018-02-14 23:40:23 +00:00
|
|
|
}
|
2022-07-15 02:35:03 +01:00
|
|
|
|
2021-08-20 00:34:32 +01:00
|
|
|
auto selectedCape = ui->capeCombo->currentData().toString();
|
2023-08-02 17:35:35 +01:00
|
|
|
if (selectedCape != m_acct->accountData()->minecraftProfile.currentCape) {
|
2021-12-04 00:18:05 +00:00
|
|
|
skinUpload.addTask(shared_qobject_ptr<CapeChange>(new CapeChange(this, m_acct->accessToken(), selectedCape)));
|
2021-08-20 00:34:32 +01:00
|
|
|
}
|
2023-08-02 17:35:35 +01:00
|
|
|
if (prog.execWithTask(&skinUpload) != QDialog::Accepted) {
|
2018-02-14 23:40:23 +00:00
|
|
|
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec();
|
2016-05-12 21:51:25 +01:00
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2018-02-14 23:40:23 +00:00
|
|
|
CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Success"), QMessageBox::Information)->exec();
|
2016-05-12 21:51:25 +01:00
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinUploadDialog::on_skinBrowseBtn_clicked()
|
|
|
|
{
|
2022-05-08 00:16:55 +01:00
|
|
|
auto filter = QMimeDatabase().mimeTypeForName("image/png").filterString();
|
|
|
|
QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), filter);
|
2023-08-02 17:35:35 +01:00
|
|
|
if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) {
|
2016-05-12 21:51:25 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-12-03 18:21:04 +00:00
|
|
|
QString cooked_path = FS::NormalizePath(raw_path);
|
2016-05-12 21:51:25 +01:00
|
|
|
ui->skinPathTextBox->setText(cooked_path);
|
|
|
|
}
|
|
|
|
|
2023-08-02 17:35:35 +01:00
|
|
|
SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent) : QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
|
2016-05-12 21:51:25 +01:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2021-08-20 00:34:32 +01:00
|
|
|
|
|
|
|
// FIXME: add a model for this, download/refresh the capes on demand
|
2023-08-02 17:35:35 +01:00
|
|
|
auto& data = *acct->accountData();
|
2021-08-20 00:34:32 +01:00
|
|
|
int index = 0;
|
|
|
|
ui->capeCombo->addItem(tr("No Cape"), QVariant());
|
|
|
|
auto currentCape = data.minecraftProfile.currentCape;
|
2023-08-02 17:35:35 +01:00
|
|
|
if (currentCape.isEmpty()) {
|
2021-08-20 00:34:32 +01:00
|
|
|
ui->capeCombo->setCurrentIndex(index);
|
|
|
|
}
|
|
|
|
|
2023-08-02 17:35:35 +01:00
|
|
|
for (auto& cape : data.minecraftProfile.capes) {
|
2021-08-20 00:34:32 +01:00
|
|
|
index++;
|
2023-08-02 17:35:35 +01:00
|
|
|
if (cape.data.size()) {
|
2021-08-20 00:34:32 +01:00
|
|
|
QPixmap capeImage;
|
2023-08-02 17:35:35 +01:00
|
|
|
if (capeImage.loadFromData(cape.data, "PNG")) {
|
2021-08-20 00:34:32 +01:00
|
|
|
QPixmap preview = QPixmap(10, 16);
|
|
|
|
QPainter painter(&preview);
|
|
|
|
painter.drawPixmap(0, 0, capeImage.copy(1, 1, 10, 16));
|
|
|
|
ui->capeCombo->addItem(capeImage, cape.alias, cape.id);
|
2023-08-02 17:35:35 +01:00
|
|
|
if (currentCape == cape.id) {
|
2021-08-20 00:34:32 +01:00
|
|
|
ui->capeCombo->setCurrentIndex(index);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ui->capeCombo->addItem(cape.alias, cape.id);
|
2023-08-02 17:35:35 +01:00
|
|
|
if (currentCape == cape.id) {
|
2021-08-20 00:34:32 +01:00
|
|
|
ui->capeCombo->setCurrentIndex(index);
|
|
|
|
}
|
|
|
|
}
|
2016-05-12 21:51:25 +01:00
|
|
|
}
|