Implement saving account list to file

Currently it only saves when accounts are added or removed. We'll have
to fix this, but we need signals for when account objects change first.
This commit is contained in:
Andrew 2013-11-19 12:53:30 -06:00
parent a9a0b65358
commit 928e0d0b15
4 changed files with 133 additions and 3 deletions

View File

@ -150,6 +150,7 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
// and accounts // and accounts
m_accounts.reset(new MojangAccountList(this)); m_accounts.reset(new MojangAccountList(this));
QLOG_INFO() << "Loading accounts..."; QLOG_INFO() << "Loading accounts...";
m_accounts->setListFilePath("accounts.json", true);
m_accounts->loadList(); m_accounts->loadList();
// init the http meta cache // init the http meta cache

View File

@ -19,6 +19,8 @@
#include <QUuid> #include <QUuid>
#include <logger/QsLog.h>
MojangAccount::MojangAccount(const QString& username, QObject* parent) : MojangAccount::MojangAccount(const QString& username, QObject* parent) :
QObject(parent) QObject(parent)
{ {
@ -113,6 +115,34 @@ void MojangAccount::loadProfiles(const ProfileList& profiles)
m_profiles.append(profile); m_profiles.append(profile);
} }
MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject& object)
{
// The JSON object must at least have a username for it to be valid.
if (!object.value("username").isString())
{
QLOG_ERROR() << "Can't load Mojang account info from JSON object. Username field is missing or of the wrong type.";
return nullptr;
}
QString username = object.value("username").toString("");
QString clientToken = object.value("clientToken").toString("");
QString accessToken = object.value("accessToken").toString("");
// TODO: Load profiles?
return MojangAccountPtr(new MojangAccount(username, clientToken, accessToken));
}
QJsonObject MojangAccount::saveToJson()
{
QJsonObject json;
json.insert("username", username());
json.insert("clientToken", clientToken());
json.insert("accessToken", accessToken());
// TODO: Save profiles?
return json;
}
AccountProfile::AccountProfile(const QString& id, const QString& name) AccountProfile::AccountProfile(const QString& id, const QString& name)
{ {

View File

@ -27,8 +27,6 @@
#include "logic/auth/MojangAccount.h" #include "logic/auth/MojangAccount.h"
#define DEFAULT_ACCOUNT_LIST_FILE "accounts.json"
#define ACCOUNT_LIST_FORMAT_VERSION 1 #define ACCOUNT_LIST_FORMAT_VERSION 1
MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent) MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent)
@ -57,6 +55,7 @@ void MojangAccountList::addAccount(const MojangAccountPtr account)
beginResetModel(); beginResetModel();
m_accounts.append(account); m_accounts.append(account);
endResetModel(); endResetModel();
onListChanged();
} }
void MojangAccountList::removeAccount(const QString& username) void MojangAccountList::removeAccount(const QString& username)
@ -71,6 +70,16 @@ void MojangAccountList::removeAccount(const QString& username)
} }
} }
endResetModel(); endResetModel();
onListChanged();
}
void MojangAccountList::onListChanged()
{
if (m_autosave)
// TODO: Alert the user if this fails.
saveList();
emit listChanged();
} }
@ -163,7 +172,12 @@ void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
bool MojangAccountList::loadList(const QString& filePath) bool MojangAccountList::loadList(const QString& filePath)
{ {
QString path = filePath; QString path = filePath;
if (path.isEmpty()) path = DEFAULT_ACCOUNT_LIST_FILE; if (path.isEmpty()) path = m_listFilePath;
if (path.isEmpty())
{
QLOG_ERROR() << "Can't load Mojang account list. No file path given and no default set.";
return false;
}
QFile file(path); QFile file(path);
@ -233,3 +247,64 @@ bool MojangAccountList::loadList(const QString& filePath)
return true; return true;
} }
bool MojangAccountList::saveList(const QString& filePath)
{
QString path(filePath);
if (path.isEmpty()) path = m_listFilePath;
if (path.isEmpty())
{
QLOG_ERROR() << "Can't save Mojang account list. No file path given and no default set.";
return false;
}
QLOG_INFO() << "Writing account list to \"" << path << "\"...";
QLOG_DEBUG() << "Building JSON data structure.";
// Build the JSON document to write to the list file.
QJsonObject root;
root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION);
// Build a list of accounts.
QLOG_DEBUG() << "Building account array.";
QJsonArray accounts;
for (MojangAccountPtr account : m_accounts)
{
QJsonObject accountObj = account->saveToJson();
accounts.append(accountObj);
}
// Insert the account list into the root object.
root.insert("accounts", accounts);
// Create a JSON document object to convert our JSON to bytes.
QJsonDocument doc(root);
// Now that we're done building the JSON object, we can write it to the file.
QLOG_DEBUG() << "Writing account list to file.";
QFile file(path);
// Try to open the file and fail if we can't.
// TODO: We should probably report this error to the user.
if (!file.open(QIODevice::WriteOnly))
{
QLOG_ERROR() << "Failed to read the account list file (" << path << ").";
return false;
}
// Write the JSON to the file.
file.write(doc.toJson());
file.close();
QLOG_INFO() << "Saved account list to \"" << path << "\".";
return true;
}
void MojangAccountList::setListFilePath(QString path, bool autosave)
{
m_listFilePath = path;
autosave = autosave;
}

View File

@ -79,6 +79,15 @@ public:
* one doesn't exist. * one doesn't exist.
*/ */
virtual MojangAccountPtr findAccount(const QString &username); virtual MojangAccountPtr findAccount(const QString &username);
/*!
* Sets the default path to save the list file to.
* If autosave is true, this list will automatically save to the given path whenever it changes.
* THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
* after calling this function to ensure an autosaved change doesn't overwrite the list you intended
* to load.
*/
virtual void setListFilePath(QString path, bool autosave=false);
/*! /*!
* \brief Loads the account list from the given file path. * \brief Loads the account list from the given file path.
@ -102,8 +111,23 @@ signals:
void listChanged(); void listChanged();
protected: protected:
/*!
* Called whenever the list changes.
* This emits the listChanged() signal and autosaves the list (if autosave is enabled).
*/
void onListChanged();
QList<MojangAccountPtr> m_accounts; QList<MojangAccountPtr> m_accounts;
//! Path to the account list file. Empty string if there isn't one.
QString m_listFilePath;
/*!
* If true, the account list will automatically save to the account list path when it changes.
* Ignored if m_listFilePath is blank.
*/
bool m_autosave;
protected protected
slots: slots:
/*! /*!