added more import options
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
@ -44,7 +44,7 @@
|
||||
CapeChange::CapeChange(QString token, QString cape) : NetRequest(), m_capeId(cape), m_token(token)
|
||||
{
|
||||
logCat = taskMCSkinsLogC;
|
||||
};
|
||||
}
|
||||
|
||||
QNetworkReply* CapeChange::getReply(QNetworkRequest& request)
|
||||
{
|
||||
|
@ -42,7 +42,7 @@
|
||||
SkinDelete::SkinDelete(QString token) : NetRequest(), m_token(token)
|
||||
{
|
||||
logCat = taskMCSkinsLogC;
|
||||
};
|
||||
}
|
||||
|
||||
QNetworkReply* SkinDelete::getReply(QNetworkRequest& request)
|
||||
{
|
||||
|
@ -85,8 +85,6 @@ bool SkinList::update()
|
||||
} catch (const Exception& e) {
|
||||
qCritical() << "Couldn't load skins json:" << e.cause();
|
||||
}
|
||||
} else {
|
||||
newSkins = loadMinecraftSkins();
|
||||
}
|
||||
|
||||
bool needsSave = false;
|
||||
@ -108,7 +106,7 @@ bool SkinList::update()
|
||||
auto path = m_dir.absoluteFilePath(name);
|
||||
if (skinTexture.loadFromData(skin.data, "PNG") && skinTexture.save(path)) {
|
||||
SkinModel s(path);
|
||||
s.setModel(SkinModel::CLASSIC); // maybe better model detection
|
||||
s.setModel(skin.variant == "slim" ? SkinModel::SLIM : SkinModel::CLASSIC);
|
||||
s.setCapeId(m_acct->accountData()->minecraftProfile.currentCape);
|
||||
s.setURL(skin.url);
|
||||
newSkins << s;
|
||||
@ -116,6 +114,7 @@ bool SkinList::update()
|
||||
}
|
||||
} else {
|
||||
nskin->setCapeId(m_acct->accountData()->minecraftProfile.currentCape);
|
||||
nskin->setModel(skin.variant == "slim" ? SkinModel::SLIM : SkinModel::CLASSIC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,14 +206,14 @@ bool SkinList::dropMimeData(const QMimeData* data,
|
||||
// files dropped from outside?
|
||||
if (data->hasUrls()) {
|
||||
auto urls = data->urls();
|
||||
QStringList iconFiles;
|
||||
QStringList skinFiles;
|
||||
for (auto url : urls) {
|
||||
// only local files may be dropped...
|
||||
if (!url.isLocalFile())
|
||||
continue;
|
||||
iconFiles += url.toLocalFile();
|
||||
skinFiles << url.toLocalFile();
|
||||
}
|
||||
installSkins(iconFiles);
|
||||
installSkins(skinFiles);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -261,20 +260,26 @@ int SkinList::rowCount(const QModelIndex& parent) const
|
||||
void SkinList::installSkins(const QStringList& iconFiles)
|
||||
{
|
||||
for (QString file : iconFiles)
|
||||
installSkin(file, {});
|
||||
installSkin(file);
|
||||
}
|
||||
|
||||
void SkinList::installSkin(const QString& file, const QString& name)
|
||||
QString SkinList::installSkin(const QString& file, const QString& name)
|
||||
{
|
||||
if (file.isEmpty())
|
||||
return tr("Path is empty.");
|
||||
QFileInfo fileinfo(file);
|
||||
if (!fileinfo.isReadable() || !fileinfo.isFile())
|
||||
return;
|
||||
|
||||
if (!fileinfo.exists())
|
||||
return tr("File doesn't exist.");
|
||||
if (!fileinfo.isFile())
|
||||
return tr("Not a file.");
|
||||
if (!fileinfo.isReadable())
|
||||
return tr("File is not readable.");
|
||||
if (fileinfo.suffix() != "png" && !SkinModel(fileinfo.absoluteFilePath()).isValid())
|
||||
return;
|
||||
return tr("Skin images must be 64x64 or 64x32 pixel PNG files.");
|
||||
|
||||
QString target = FS::PathCombine(m_dir.absolutePath(), name.isEmpty() ? fileinfo.fileName() : name);
|
||||
QFile::copy(file, target);
|
||||
|
||||
return QFile::copy(file, target) ? "" : tr("Unable to copy file");
|
||||
}
|
||||
|
||||
int SkinList::getSkinIndex(const QString& key) const
|
||||
@ -311,10 +316,12 @@ bool SkinList::deleteSkin(const QString& key, const bool trash)
|
||||
if (trash) {
|
||||
if (FS::trash(s.getPath(), nullptr)) {
|
||||
m_skin_list.remove(idx);
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
} else if (QFile::remove(s.getPath())) {
|
||||
m_skin_list.remove(idx);
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -361,33 +368,22 @@ bool SkinList::setData(const QModelIndex& idx, const QVariant& value, int role)
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<SkinModel> SkinList::loadMinecraftSkins()
|
||||
void SkinList::updateSkin(SkinModel s)
|
||||
{
|
||||
QString partialPath;
|
||||
#if defined(Q_OS_OSX)
|
||||
partialPath = FS::PathCombine(QDir::homePath(), "Library/Application Support");
|
||||
#elif defined(Q_OS_WIN32)
|
||||
partialPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", "");
|
||||
#else
|
||||
partialPath = QDir::homePath();
|
||||
#endif
|
||||
QVector<SkinModel> newSkins;
|
||||
auto path = FS::PathCombine(partialPath, ".minecraft", "launcher_custom_skins.json");
|
||||
auto manifestInfo = QFileInfo(path);
|
||||
if (!manifestInfo.exists())
|
||||
return {};
|
||||
try {
|
||||
auto doc = Json::requireDocument(manifestInfo.absoluteFilePath(), "SkinList JSON file");
|
||||
const auto root = doc.object();
|
||||
auto skins = Json::ensureObject(root, "customSkins");
|
||||
for (auto key : skins.keys()) {
|
||||
SkinModel s(m_dir, Json::ensureObject(skins, key));
|
||||
if (s.isValid()) {
|
||||
newSkins << s;
|
||||
}
|
||||
auto done = false;
|
||||
for (auto i = 0; i < m_skin_list.size(); i++) {
|
||||
if (m_skin_list[i].getPath() == s.getPath()) {
|
||||
m_skin_list[i].setCapeId(s.getCapeId());
|
||||
m_skin_list[i].setModel(s.getModel());
|
||||
m_skin_list[i].setURL(s.getURL());
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
} catch (const Exception& e) {
|
||||
qCritical() << "Couldn't load minecraft skins json:" << e.cause();
|
||||
}
|
||||
return newSkins;
|
||||
if (!done) {
|
||||
beginInsertRows(QModelIndex(), m_skin_list.count(), m_skin_list.count() + 1);
|
||||
m_skin_list.append(s);
|
||||
endInsertRows();
|
||||
}
|
||||
save();
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class SkinList : public QAbstractListModel {
|
||||
bool deleteSkin(const QString& key, const bool trash);
|
||||
|
||||
void installSkins(const QStringList& iconFiles);
|
||||
void installSkin(const QString& file, const QString& name);
|
||||
QString installSkin(const QString& file, const QString& name = {});
|
||||
|
||||
const SkinModel* skin(const QString& key) const;
|
||||
SkinModel* skin(const QString& key);
|
||||
@ -58,14 +58,14 @@ class SkinList : public QAbstractListModel {
|
||||
void save();
|
||||
int getSelectedAccountSkin();
|
||||
|
||||
void updateSkin(SkinModel s);
|
||||
|
||||
private:
|
||||
// hide copy constructor
|
||||
SkinList(const SkinList&) = delete;
|
||||
// hide assign op
|
||||
SkinList& operator=(const SkinList&) = delete;
|
||||
|
||||
QVector<SkinModel> loadMinecraftSkins();
|
||||
|
||||
protected slots:
|
||||
void directoryChanged(const QString& path);
|
||||
void fileChanged(const QString& path);
|
||||
|
@ -31,28 +31,12 @@ SkinModel::SkinModel(QDir skinDir, QJsonObject obj)
|
||||
: m_cape_id(Json::ensureString(obj, "capeId")), m_model(Model::CLASSIC), m_url(Json::ensureString(obj, "url"))
|
||||
{
|
||||
auto name = Json::ensureString(obj, "name");
|
||||
auto skinImage = Json::ensureString(obj, "skinImage");
|
||||
if (!skinImage.isEmpty()) { // minecraft skin model
|
||||
skinImage = skinImage.mid(22);
|
||||
m_texture.loadFromData(QByteArray::fromBase64(skinImage.toUtf8()), "PNG");
|
||||
auto textureId = Json::ensureString(obj, "textureId");
|
||||
if (name.isEmpty()) {
|
||||
name = textureId;
|
||||
}
|
||||
if (Json::ensureBoolean(obj, "slim", false)) {
|
||||
m_model = Model::SLIM;
|
||||
}
|
||||
} else {
|
||||
if (auto model = Json::ensureString(obj, "model"); model == "SLIM") {
|
||||
m_model = Model::SLIM;
|
||||
}
|
||||
|
||||
if (auto model = Json::ensureString(obj, "model"); model == "SLIM") {
|
||||
m_model = Model::SLIM;
|
||||
}
|
||||
m_path = skinDir.absoluteFilePath(name) + ".png";
|
||||
if (!QFileInfo(m_path).exists() && isValid()) {
|
||||
m_texture.save(m_path, "PNG");
|
||||
} else {
|
||||
m_texture = QPixmap(m_path);
|
||||
}
|
||||
m_texture = QPixmap(m_path);
|
||||
}
|
||||
|
||||
QString SkinModel::name() const
|
||||
@ -92,37 +76,3 @@ bool SkinModel::isValid() const
|
||||
{
|
||||
return !m_texture.isNull() && (m_texture.size().height() == 32 || m_texture.size().height() == 64) && m_texture.size().width() == 64;
|
||||
}
|
||||
|
||||
QPixmap SkinModel::renderFrontBody() const
|
||||
{
|
||||
auto isSlim = m_model == SLIM;
|
||||
auto slimOffset = isSlim ? 1 : 0;
|
||||
auto isOldSkin = m_texture.height() < 64;
|
||||
|
||||
auto head = m_texture.copy(QRect(8, 8, 16, 16));
|
||||
auto torso = m_texture.copy(QRect(20, 20, 28, 32));
|
||||
auto rightArm = m_texture.copy(QRect(44, 20, 48 - slimOffset, 32));
|
||||
auto rightLeg = m_texture.copy(QRect(4, 20, 8, 32));
|
||||
QPixmap leftArm, leftLeg;
|
||||
|
||||
if (isOldSkin) {
|
||||
leftArm = rightArm.transformed(QTransform().scale(-1, 1));
|
||||
leftLeg = rightLeg.transformed(QTransform().scale(-1, 1));
|
||||
} else {
|
||||
leftArm = m_texture.copy(QRect(36, 52, 40 - slimOffset, 64));
|
||||
leftLeg = m_texture.copy(QRect(20, 52, 24, 64));
|
||||
}
|
||||
QPixmap output(16, 32);
|
||||
output.fill(Qt::black);
|
||||
QPainter p;
|
||||
if (!p.begin(&output))
|
||||
return {};
|
||||
p.drawPixmap(QPoint(4, 0), head);
|
||||
p.drawPixmap(QPoint(4, 8), torso);
|
||||
p.drawPixmap(QPoint(12, 8), leftArm);
|
||||
p.drawPixmap(QPoint(slimOffset, 8), rightArm);
|
||||
p.drawPixmap(QPoint(8, 20), leftLeg);
|
||||
p.drawPixmap(QPoint(4, 20), leftArm);
|
||||
|
||||
return output.scaled(128, 128, Qt::KeepAspectRatioByExpanding, Qt::FastTransformation);
|
||||
}
|
@ -26,6 +26,7 @@ class SkinModel {
|
||||
public:
|
||||
enum Model { CLASSIC, SLIM };
|
||||
|
||||
SkinModel() = default;
|
||||
SkinModel(QString path);
|
||||
SkinModel(QDir skinDir, QJsonObject obj);
|
||||
virtual ~SkinModel() = default;
|
||||
@ -47,8 +48,6 @@ class SkinModel {
|
||||
|
||||
QJsonObject toJSON() const;
|
||||
|
||||
QPixmap renderFrontBody() const;
|
||||
|
||||
private:
|
||||
QString m_path;
|
||||
QPixmap m_texture;
|
||||
|
@ -44,8 +44,8 @@
|
||||
|
||||
SkinUpload::SkinUpload(QString token, SkinModel* skin) : NetRequest(), m_skin(skin), m_token(token)
|
||||
{
|
||||
logCat = taskUploadLogC;
|
||||
};
|
||||
logCat = taskMCSkinsLogC;
|
||||
}
|
||||
|
||||
QNetworkReply* SkinUpload::getReply(QNetworkRequest& request)
|
||||
{
|
||||
|
Reference in New Issue
Block a user