First draft of player faces in the login dialog
This commit is contained in:
parent
be2c7f4515
commit
681d36b232
@ -256,6 +256,8 @@ logic/net/HttpMetaCache.h
|
|||||||
logic/net/HttpMetaCache.cpp
|
logic/net/HttpMetaCache.cpp
|
||||||
logic/net/LoginTask.h
|
logic/net/LoginTask.h
|
||||||
logic/net/LoginTask.cpp
|
logic/net/LoginTask.cpp
|
||||||
|
logic/net/SkinDownload.h
|
||||||
|
logic/net/SkinDownload.cpp
|
||||||
|
|
||||||
# legacy instances
|
# legacy instances
|
||||||
logic/LegacyInstance.h
|
logic/LegacyInstance.h
|
||||||
|
@ -294,6 +294,7 @@ void MultiMC::initHttpMetaCache()
|
|||||||
m_metacache->addBase("versions", QDir("versions").absolutePath());
|
m_metacache->addBase("versions", QDir("versions").absolutePath());
|
||||||
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
||||||
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
||||||
|
m_metacache->addBase("skins", QDir("playerdata/skins").absolutePath());
|
||||||
m_metacache->Load();
|
m_metacache->Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,13 @@
|
|||||||
#include "ui_logindialog.h"
|
#include "ui_logindialog.h"
|
||||||
#include "keyring.h"
|
#include "keyring.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/platform.h"
|
||||||
|
#include "MultiMC.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonParseError>
|
||||||
|
#include "logic/net/HttpMetaCache.h"
|
||||||
#include <logger/QsLog.h>
|
#include <logger/QsLog.h>
|
||||||
|
|
||||||
LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
|
LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
|
||||||
@ -51,6 +58,8 @@ LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
|
|||||||
arg(loginErrMsg));
|
arg(loginErrMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui->lblFace->setVisible(false);
|
||||||
|
|
||||||
resize(minimumSizeHint());
|
resize(minimumSizeHint());
|
||||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
Keyring * k = Keyring::instance();
|
Keyring * k = Keyring::instance();
|
||||||
@ -151,13 +160,54 @@ void LoginDialog::userTextChanged ( const QString& user )
|
|||||||
blockToggles = true;
|
blockToggles = true;
|
||||||
Keyring * k = Keyring::instance();
|
Keyring * k = Keyring::instance();
|
||||||
QStringList sl = k->getStoredAccounts("minecraft");
|
QStringList sl = k->getStoredAccounts("minecraft");
|
||||||
|
bool gotFace = false;
|
||||||
|
|
||||||
if(sl.contains(user))
|
if(sl.contains(user))
|
||||||
{
|
{
|
||||||
ui->rememberUsernameCheckbox->setChecked(true);
|
ui->rememberUsernameCheckbox->setChecked(true);
|
||||||
QString passwd = k->getPassword("minecraft",user);
|
QString passwd = k->getPassword("minecraft",user);
|
||||||
ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty());
|
ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty());
|
||||||
ui->passwordTextBox->setText(passwd);
|
ui->passwordTextBox->setText(passwd);
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
{
|
||||||
|
auto filename = MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
|
||||||
|
QFile listFile(filename);
|
||||||
|
if(!listFile.open(QIODevice::ReadOnly))
|
||||||
|
return;
|
||||||
|
data = listFile.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonParseError jsonError;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
|
||||||
|
QJsonObject root = jsonDoc.object();
|
||||||
|
QJsonObject mappings = root.value("mappings").toObject();
|
||||||
|
|
||||||
|
if(!mappings[user].isUndefined())
|
||||||
|
{
|
||||||
|
QJsonArray usernames = mappings.value(user).toArray();
|
||||||
|
if(!usernames.isEmpty())
|
||||||
|
{
|
||||||
|
QString mapped_username = usernames[0].toString();
|
||||||
|
|
||||||
|
if(!mapped_username.isEmpty())
|
||||||
|
{
|
||||||
|
QFile fskin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
|
||||||
|
if(fskin.exists())
|
||||||
|
{
|
||||||
|
QPixmap skin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
|
||||||
|
QPixmap face = skin.copy(8, 8, 8, 8).scaled(48, 48, Qt::KeepAspectRatio);
|
||||||
|
|
||||||
|
ui->lblFace->setPixmap(face);
|
||||||
|
gotFace = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gotFace) ui->lblFace->setVisible(true);
|
||||||
|
else ui->lblFace->setVisible(false);
|
||||||
blockToggles = false;
|
blockToggles = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,10 +23,34 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="4" rowspan="2">
|
||||||
<widget class="QLabel" name="usernameLabel">
|
<widget class="QLabel" name="lblFace">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>48</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>48</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="sizeIncrement">
|
||||||
|
<size>
|
||||||
|
<width>1</width>
|
||||||
|
<height>1</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Username:</string>
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="../multimc.qrc">:/icons/instances/steve</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -37,6 +61,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="usernameLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Username:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="passwordLabel">
|
<widget class="QLabel" name="passwordLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -54,7 +85,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2" rowspan="2">
|
<item row="0" column="5" rowspan="2">
|
||||||
<widget class="QPushButton" name="forgetButton">
|
<widget class="QPushButton" name="forgetButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
@ -111,7 +142,9 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources>
|
||||||
|
<include location="../multimc.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>loginButtonBox</sender>
|
<sender>loginButtonBox</sender>
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
#include "logic/lists/JavaVersionList.h"
|
#include "logic/lists/JavaVersionList.h"
|
||||||
|
|
||||||
#include "logic/net/LoginTask.h"
|
#include "logic/net/LoginTask.h"
|
||||||
|
#include "logic/net/SkinDownload.h"
|
||||||
|
|
||||||
#include "logic/BaseInstance.h"
|
#include "logic/BaseInstance.h"
|
||||||
#include "logic/InstanceFactory.h"
|
#include "logic/InstanceFactory.h"
|
||||||
#include "logic/MinecraftProcess.h"
|
#include "logic/MinecraftProcess.h"
|
||||||
@ -517,6 +519,42 @@ void MainWindow::onLoginComplete()
|
|||||||
tDialog.exec(updateTask);
|
tDialog.exec(updateTask);
|
||||||
delete updateTask;
|
delete updateTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto download = new SkinDownload(m_activeLogin.player_name);
|
||||||
|
download->start();
|
||||||
|
|
||||||
|
auto filename = MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
|
||||||
|
QFile listFile(filename);
|
||||||
|
|
||||||
|
// Add skin mapping
|
||||||
|
QByteArray data;
|
||||||
|
{
|
||||||
|
if(!listFile.open(QIODevice::ReadWrite))
|
||||||
|
{
|
||||||
|
QLOG_ERROR() << "Failed to open/make skins list JSON";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = listFile.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonParseError jsonError;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
|
||||||
|
QJsonObject root = jsonDoc.object();
|
||||||
|
QJsonObject mappings = root.value("mappings").toObject();
|
||||||
|
QJsonArray usernames = mappings.value(m_activeLogin.username).toArray();
|
||||||
|
|
||||||
|
if(!usernames.contains(m_activeLogin.player_name))
|
||||||
|
{
|
||||||
|
usernames.prepend(m_activeLogin.player_name);
|
||||||
|
mappings[m_activeLogin.username] = usernames;
|
||||||
|
root["mappings"] = mappings;
|
||||||
|
jsonDoc.setObject(root);
|
||||||
|
|
||||||
|
// QJson hack - shouldn't have to clear the file every time a save happens
|
||||||
|
listFile.resize(0);
|
||||||
|
listFile.write(jsonDoc.toJson());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onGameUpdateComplete()
|
void MainWindow::onGameUpdateComplete()
|
||||||
|
60
logic/net/SkinDownload.cpp
Normal file
60
logic/net/SkinDownload.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "MultiMC.h"
|
||||||
|
#include "SkinDownload.h"
|
||||||
|
#include "DownloadJob.h"
|
||||||
|
#include <pathutils.h>
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <logger/QsLog.h>
|
||||||
|
|
||||||
|
SkinDownload::SkinDownload(QString name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_entry = MMC->metacache()->resolveEntry("skins", name + ".png");
|
||||||
|
m_entry->stale = true;
|
||||||
|
m_url = QUrl("http://skins.minecraft.net/MinecraftSkins/" + name + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinDownload::start()
|
||||||
|
{
|
||||||
|
auto job = new DownloadJob("Player skin: " + m_name);
|
||||||
|
|
||||||
|
job->addCacheDownload(m_url, m_entry);
|
||||||
|
m_job.reset(job);
|
||||||
|
|
||||||
|
connect(m_job.get(), SIGNAL(started()), SLOT(downloadStarted()));
|
||||||
|
connect(m_job.get(), SIGNAL(progress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
|
||||||
|
connect(m_job.get(), SIGNAL(succeeded()), SLOT(downloadSucceeded()));
|
||||||
|
connect(m_job.get(), SIGNAL(failed()), SLOT(downloadFailed()));
|
||||||
|
|
||||||
|
m_job->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinDownload::downloadStarted()
|
||||||
|
{
|
||||||
|
//QLOG_INFO() << "Started skin download for " << m_name << ".";
|
||||||
|
|
||||||
|
emit started();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||||
|
{
|
||||||
|
emit progress(bytesReceived, bytesTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinDownload::downloadSucceeded()
|
||||||
|
{
|
||||||
|
//QLOG_INFO() << "Got skin for " << m_name << ", cropping.";
|
||||||
|
|
||||||
|
emit succeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinDownload::downloadFailed()
|
||||||
|
{
|
||||||
|
//QLOG_ERROR() << "Failed to download skin for: " << m_name;
|
||||||
|
|
||||||
|
emit failed();
|
||||||
|
}
|
38
logic/net/SkinDownload.h
Normal file
38
logic/net/SkinDownload.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Download.h"
|
||||||
|
#include "HttpMetaCache.h"
|
||||||
|
#include "DownloadJob.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
class SkinDownload : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SkinDownload(QString name);
|
||||||
|
QString m_name;
|
||||||
|
QUrl m_url;
|
||||||
|
MetaEntryPtr m_entry;
|
||||||
|
DownloadJobPtr m_job;
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void downloadStarted();
|
||||||
|
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||||
|
void downloadSucceeded();
|
||||||
|
void downloadFailed();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void started();
|
||||||
|
void progress(qint64 current, qint64 total);
|
||||||
|
void succeeded();
|
||||||
|
void failed();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<SkinDownload> SkinDownloadPtr;
|
Loading…
Reference in New Issue
Block a user