Merge branch 'master' of git://github.com/peterix/MultiMC5

Conflicts:
	CMakeLists.txt
	gui/mainwindow.cpp
This commit is contained in:
Andrew
2013-03-28 11:37:12 -05:00
43 changed files with 1475 additions and 461 deletions

View File

@ -48,6 +48,12 @@ Instance::Instance(const QString &rootDir, QObject *parent) :
settings().registerSetting(new OverrideSetting("PostExitCommand",
globalSettings->getSetting("PostExitCommand")));
// Window Size
settings().registerSetting(new OverrideSetting("LaunchCompatMode", globalSettings->getSetting("LaunchCompatMode")));
settings().registerSetting(new OverrideSetting("LaunchMaximized", globalSettings->getSetting("LaunchMaximized")));
settings().registerSetting(new OverrideSetting("MinecraftWinWidth", globalSettings->getSetting("MinecraftWinWidth")));
settings().registerSetting(new OverrideSetting("MinecraftWinHeight", globalSettings->getSetting("MinecraftWinHeight")));
// Memory
settings().registerSetting(new OverrideSetting("MinMemAlloc", globalSettings->getSetting("MinMemAlloc")));
settings().registerSetting(new OverrideSetting("MaxMemAlloc", globalSettings->getSetting("MaxMemAlloc")));

View File

@ -15,17 +15,21 @@
#include "include/instancelist.h"
#include "siglist_impl.h"
#include <QDir>
#include <QFile>
#include <QDirIterator>
#include <QThread>
#include <QTextStream>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include "include/instance.h"
#include "include/instanceloader.h"
#include "pathutils.h"
const static int GROUP_FILE_FORMAT_VERSION = 1;
InstanceList::InstanceList(const QString &instDir, QObject *parent) :
QObject(parent), m_instDir("instances")
@ -38,6 +42,104 @@ InstanceList::InstListError InstanceList::loadList()
QDir dir(m_instDir);
QDirIterator iter(dir);
QString groupFileName = m_instDir + "/instgroups.json";
// temporary map from instance ID to group name
QMap<QString, QString> groupMap;
// HACK: this is really an if. breaks after one iteration.
while (QFileInfo(groupFileName).exists())
{
QFile groupFile(groupFileName);
if (!groupFile.open(QIODevice::ReadOnly))
{
// An error occurred. Ignore it.
qDebug("Failed to read instance group file.");
break;
}
QTextStream in(&groupFile);
QString jsonStr = in.readAll();
groupFile.close();
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error);
if (error.error != QJsonParseError::NoError)
{
qWarning(QString("Failed to parse instance group file: %1 at offset %2").
arg(error.errorString(), QString::number(error.offset)).toUtf8());
break;
}
if (!jsonDoc.isObject())
{
qWarning("Invalid group file. Root entry should be an object.");
break;
}
QJsonObject rootObj = jsonDoc.object();
// Make sure the format version matches.
if (rootObj.value("formatVersion").toVariant().toInt() == GROUP_FILE_FORMAT_VERSION)
{
// Get the group list.
if (!rootObj.value("groups").isObject())
{
qWarning("Invalid group list JSON: 'groups' should be an object.");
break;
}
// Iterate through the list.
QJsonObject groupList = rootObj.value("groups").toObject();
for (QJsonObject::iterator iter = groupList.begin();
iter != groupList.end(); iter++)
{
QString groupName = iter.key();
// If not an object, complain and skip to the next one.
if (!iter.value().isObject())
{
qWarning(QString("Group '%1' in the group list should "
"be an object.").arg(groupName).toUtf8());
continue;
}
QJsonObject groupObj = iter.value().toObject();
/*
// Create the group object.
InstanceGroup *group = new InstanceGroup(groupName, this);
groups.push_back(group);
// If 'hidden' isn't a bool value, just assume it's false.
if (groupObj.value("hidden").isBool() && groupObj.value("hidden").toBool())
{
group->setHidden(groupObj.value("hidden").toBool());
}
*/
if (!groupObj.value("instances").isArray())
{
qWarning(QString("Group '%1' in the group list is invalid. "
"It should contain an array "
"called 'instances'.").arg(groupName).toUtf8());
continue;
}
// Iterate through the list of instances in the group.
QJsonArray instancesArray = groupObj.value("instances").toArray();
for (QJsonArray::iterator iter2 = instancesArray.begin();
iter2 != instancesArray.end(); iter2++)
{
groupMap[(*iter2).toString()] = groupName;
}
}
}
break;
}
m_instances.clear();
while (iter.hasNext())
{
QString subDir = iter.next();
@ -75,13 +177,61 @@ InstanceList::InstListError InstanceList::loadList()
else
{
QSharedPointer<Instance> inst(instPtr);
auto iter = groupMap.find(inst->id());
if(iter != groupMap.end())
{
inst->setGroup((*iter));
}
qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8());
inst->setParent(this);
append(QSharedPointer<Instance>(inst));
m_instances.append(inst);
connect(instPtr, SIGNAL(propertiesChanged(Instance*)),this, SLOT(propertiesChanged(Instance*)));
}
}
}
emit invalidated();
return NoError;
}
/// Clear all instances. Triggers notifications.
void InstanceList::clear()
{
m_instances.clear();
emit invalidated();
};
/// Add an instance. Triggers notifications, returns the new index
int InstanceList::add(InstancePtr t)
{
m_instances.append(t);
emit instanceAdded(count() - 1);
return count() - 1;
}
InstancePtr InstanceList::getInstanceById(QString instId)
{
QListIterator<InstancePtr> iter(m_instances);
InstancePtr inst;
while(iter.hasNext())
{
inst = iter.next();
if (inst->id() == instId)
break;
}
if (inst->id() != instId)
return InstancePtr();
else
return iter.peekPrevious();
}
void InstanceList::propertiesChanged(Instance * inst)
{
for(int i = 0; i < m_instances.count(); i++)
{
if(inst == m_instances[i].data())
{
emit instanceChanged(i);
break;
}
}
}

View File

@ -125,22 +125,41 @@ MinecraftProcess::MinecraftProcess(InstancePtr inst, QString user, QString sessi
// console window
void MinecraftProcess::on_stdErr()
{
// if (m_console != nullptr)
// m_console->write(readAllStandardError(), ConsoleWindow::ERROR);
QByteArray data = readAllStandardError();
QString str = m_err_leftover + QString::fromLocal8Bit(data);
m_err_leftover.clear();
QStringList lines = str.split("\n");
bool complete = str.endsWith("\n");
for(int i = 0; i < lines.size() - 1; i++)
{
QString & line = lines[i];
MessageLevel::Enum level = MessageLevel::Error;
if(line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") || line.contains("[FINEST]") )
level = MessageLevel::Message;
if(line.contains("[SEVERE]") || line.contains("[WARNING]") || line.contains("[STDERR]"))
level = MessageLevel::Error;
emit log(lines[i].toLocal8Bit(), level);
}
if(!complete)
m_err_leftover = lines.last();
}
void MinecraftProcess::on_stdOut()
{
// if (m_console != nullptr)
// m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT);
}
void MinecraftProcess::log(QString text)
{
// if (m_console != nullptr)
// m_console->write(text);
// else
qDebug(qPrintable(text));
QByteArray data = readAllStandardOutput();
QString str = m_out_leftover + QString::fromLocal8Bit(data);
m_out_leftover.clear();
QStringList lines = str.split("\n");
bool complete = str.endsWith("\n");
for(int i = 0; i < lines.size() - 1; i++)
{
QString & line = lines[i];
emit log(lines[i].toLocal8Bit(), MessageLevel::Message);
}
if(!complete)
m_out_leftover = lines.last();
}
// exit handler
@ -151,7 +170,7 @@ void MinecraftProcess::finish(int code, ExitStatus status)
//TODO: error handling
}
log("Minecraft exited.");
emit log("Minecraft exited.");
m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code));
@ -191,12 +210,15 @@ void MinecraftProcess::launch()
genArgs();
log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '")));
start(m_instance->settings().get("JavaPath").toString(), m_arguments);
emit log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
QString JavaPath = m_instance->settings().get("JavaPath").toString();
emit log(QString("Java path: '%1'").arg(JavaPath));
emit log(QString("Arguments: '%1'").arg(m_arguments.join("' '")));
start(JavaPath, m_arguments);
if (!waitForStarted())
{
emit log("Could not launch minecraft!");
return;
//TODO: error handling
}