NOISSUE implement mainJar support in OneSix format

This allows customizing the main jar like any other library.
This commit is contained in:
Petr Mrázek 2017-04-13 09:28:25 +02:00
parent db7357d008
commit be53eb66f8
8 changed files with 94 additions and 81 deletions

View File

@ -517,6 +517,19 @@ void MinecraftProfile::applyLibrary(LibraryPtr library)
} }
} }
const LibraryPtr MinecraftProfile::getMainJar() const
{
return m_mainJar;
}
void MinecraftProfile::applyMainJar(LibraryPtr jar)
{
if(jar)
{
m_mainJar = jar;
}
}
void MinecraftProfile::applyProblemSeverity(ProblemSeverity severity) void MinecraftProfile::applyProblemSeverity(ProblemSeverity severity)
{ {
if (m_problemSeverity < severity) if (m_problemSeverity < severity)
@ -595,7 +608,7 @@ const QList<LibraryPtr> & MinecraftProfile::getNativeLibraries() const
return m_nativeLibraries; return m_nativeLibraries;
} }
void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList& jars, QStringList& nativeJars, const QString& overridePath) const void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList& jars, QStringList& nativeJars, const QString& overridePath, const QString& tempPath) const
{ {
QStringList native32, native64; QStringList native32, native64;
jars.clear(); jars.clear();
@ -604,6 +617,20 @@ void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList&
{ {
lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath); lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
} }
// NOTE: order is important here, add main jar last to the lists
if(m_mainJar)
{
// FIXME: HACK!! jar modding is weird and unsystematic!
if(m_jarMods.size())
{
QDir tempDir(tempPath);
jars.append(tempDir.absoluteFilePath("minecraft.jar"));
}
else
{
m_mainJar->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
}
}
for (auto lib : getNativeLibraries()) for (auto lib : getNativeLibraries())
{ {
lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath); lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
@ -618,22 +645,6 @@ void MinecraftProfile::getLibraryFiles(const QString& architecture, QStringList&
} }
} }
QString MinecraftProfile::getMainJarUrl() const
{
auto iter = mojangDownloads.find("client");
if(iter != mojangDownloads.end())
{
// current
return iter.value()->url;
}
else
{
// legacy fallback
return URLConstants::getLegacyJarUrl(getMinecraftVersion());
}
}
void MinecraftProfile::installJarMods(QStringList selectedFiles) void MinecraftProfile::installJarMods(QStringList selectedFiles)
{ {
m_strategy->installJarMods(selectedFiles); m_strategy->installJarMods(selectedFiles);

View File

@ -101,6 +101,7 @@ public: /* application of profile variables from patches */
void applyTweakers(const QStringList &tweakers); void applyTweakers(const QStringList &tweakers);
void applyJarMods(const QList<JarmodPtr> &jarMods); void applyJarMods(const QList<JarmodPtr> &jarMods);
void applyLibrary(LibraryPtr library); void applyLibrary(LibraryPtr library);
void applyMainJar(LibraryPtr jar);
void applyProblemSeverity(ProblemSeverity severity); void applyProblemSeverity(ProblemSeverity severity);
void applyMojangDownload(const QString & key, MojangDownloadInfo::Ptr download); void applyMojangDownload(const QString & key, MojangDownloadInfo::Ptr download);
@ -116,8 +117,9 @@ public: /* getters for profile variables */
const QList<JarmodPtr> & getJarMods() const; const QList<JarmodPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const; const QList<LibraryPtr> & getLibraries() const;
const QList<LibraryPtr> & getNativeLibraries() const; const QList<LibraryPtr> & getNativeLibraries() const;
void getLibraryFiles(const QString & architecture, QStringList & jars, QStringList & nativeJars, const QString & overridePath) const; const LibraryPtr getMainJar() const;
QString getMainJarUrl() const; void getLibraryFiles(const QString & architecture, QStringList & jars, QStringList & nativeJars, const QString & overridePath,
const QString & tempPath) const;
bool hasTrait(const QString & trait) const; bool hasTrait(const QString & trait) const;
ProblemSeverity getProblemSeverity() const; ProblemSeverity getProblemSeverity() const;
@ -170,6 +172,9 @@ private: /* data */
/// the list of libraries /// the list of libraries
QList<LibraryPtr> m_libraries; QList<LibraryPtr> m_libraries;
/// the main jar
LibraryPtr m_mainJar;
/// the list of libraries /// the list of libraries
QList<LibraryPtr> m_nativeLibraries; QList<LibraryPtr> m_nativeLibraries;

View File

@ -30,6 +30,7 @@ void VersionFile::applyTo(MinecraftProfile *profile)
profile->applyMinecraftAssets(mojangAssetIndex); profile->applyMinecraftAssets(mojangAssetIndex);
} }
profile->applyMainJar(mainJar);
profile->applyMainClass(mainClass); profile->applyMainClass(mainClass);
profile->applyAppletClass(appletClass); profile->applyAppletClass(appletClass);
profile->applyMinecraftArguments(minecraftArguments); profile->applyMinecraftArguments(minecraftArguments);

View File

@ -41,10 +41,10 @@ public: /* data */
/// MultiMC: version of this package /// MultiMC: version of this package
QString version; QString version;
/// MultiMC: dependency on a Minecraft version /// MultiMC: DEPRECATED dependency on a Minecraft version
QString dependsOnMinecraftVersion; QString dependsOnMinecraftVersion;
/// Mojang: used to version the Mojang version format /// Mojang: DEPRECATED used to version the Mojang version format
int minimumLauncherVersion = -1; int minimumLauncherVersion = -1;
/// Mojang: DEPRECATED version of Minecraft this is /// Mojang: DEPRECATED version of Minecraft this is
@ -65,7 +65,7 @@ public: /* data */
/// Mojang: the time this version was actually released by Mojang /// Mojang: the time this version was actually released by Mojang
QDateTime releaseTime; QDateTime releaseTime;
/// Mojang: the time this version was last updated by Mojang /// Mojang: DEPRECATED the time this version was last updated by Mojang
QDateTime updateTime; QDateTime updateTime;
/// Mojang: DEPRECATED asset group to be used with Minecraft /// Mojang: DEPRECATED asset group to be used with Minecraft
@ -77,6 +77,9 @@ public: /* data */
/// Mojang: list of libraries to add to the version /// Mojang: list of libraries to add to the version
QList<LibraryPtr> libraries; QList<LibraryPtr> libraries;
// The main jar (Minecraft version library, normally)
LibraryPtr mainJar;
/// MultiMC: list of attached traits of this version file - used to enable features /// MultiMC: list of attached traits of this version file - used to enable features
QSet<QString> traits; QSet<QString> traits;
@ -84,7 +87,7 @@ public: /* data */
QList<JarmodPtr> jarMods; QList<JarmodPtr> jarMods;
public: public:
// Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more. // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more.
QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads; QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
// Mojang: extended asset index download information // Mojang: extended asset index download information

View File

@ -159,20 +159,6 @@ QString OneSixInstance::getLocalLibraryPath() const
return libraries_dir.absolutePath(); return libraries_dir.absolutePath();
} }
QString OneSixInstance::mainJarPath() const
{
auto jarMods = getJarMods();
if (!jarMods.isEmpty())
{
return QDir(binRoot()).absoluteFilePath("minecraft.jar");
}
else
{
QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar";
return versionsPath().absoluteFilePath(relpath);
}
}
QString OneSixInstance::createLaunchScript(AuthSessionPtr session) QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
{ {
QString launchScript; QString launchScript;
@ -221,12 +207,11 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
{ {
QStringList jars, nativeJars; QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString(); auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath()); m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
for(auto file: jars) for(auto file: jars)
{ {
launchScript += "cp " + file + "\n"; launchScript += "cp " + file + "\n";
} }
launchScript += "cp " + mainJarPath() + "\n";
for(auto file: nativeJars) for(auto file: nativeJars)
{ {
launchScript += "ext " + file + "\n"; launchScript += "ext " + file + "\n";
@ -265,7 +250,7 @@ QStringList OneSixInstance::verboseDescription(AuthSessionPtr session)
out << "Libraries:"; out << "Libraries:";
QStringList jars, nativeJars; QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString(); auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath()); m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
auto printLibFile = [&](const QString & path) auto printLibFile = [&](const QString & path)
{ {
QFileInfo info(path); QFileInfo info(path);
@ -282,7 +267,6 @@ QStringList OneSixInstance::verboseDescription(AuthSessionPtr session)
{ {
printLibFile(file); printLibFile(file);
} }
printLibFile(mainJarPath());
out << ""; out << "";
out << "Native libraries:"; out << "Native libraries:";
for(auto file: nativeJars) for(auto file: nativeJars)
@ -390,18 +374,6 @@ std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
auto profile = m_inst->getMinecraftProfile(); auto profile = m_inst->getMinecraftProfile();
// nuke obsolete stripped jar(s) if needed // nuke obsolete stripped jar(s) if needed
QString version_id = profile->getMinecraftVersion(); QString version_id = profile->getMinecraftVersion();
QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
QFile strippedJar(strippedPath);
if(strippedJar.exists())
{
strippedJar.remove();
}
auto tempJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
QFile tempJar(tempJarPath);
if(tempJar.exists())
{
tempJar.remove();
}
if(!FS::ensureFolderPathExists(m_inst->binRoot())) if(!FS::ensureFolderPathExists(m_inst->binRoot()))
{ {
emitFailed(tr("Couldn't create the bin folder for Minecraft.jar")); emitFailed(tr("Couldn't create the bin folder for Minecraft.jar"));
@ -421,11 +393,10 @@ std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
auto jarMods = m_inst->getJarMods(); auto jarMods = m_inst->getJarMods();
if(jarMods.size()) if(jarMods.size())
{ {
auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version_id + "/" + version_id + ".jar"); auto mainJar = profile->getMainJar();
QString localPath = version_id + "/" + version_id + ".jar"; QStringList jars, temp1, temp2, temp3, temp4;
auto metacache = ENV.metacache(); mainJar->getApplicableFiles(currentSystem, jars, temp1, temp2, temp3, m_inst->getLocalLibraryPath());
auto entry = metacache->resolveEntry("versions", localPath); auto sourceJarPath = jars[0];
QString fullJarPath = entry->getFullPath();
if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods)) if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
{ {
emitFailed(tr("Failed to create the custom Minecraft jar file.")); emitFailed(tr("Failed to create the custom Minecraft jar file."));
@ -699,8 +670,7 @@ QStringList OneSixInstance::getClassPath() const
{ {
QStringList jars, nativeJars; QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString(); auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath()); m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
jars.append(mainJarPath());
return jars; return jars;
} }
@ -713,6 +683,6 @@ QStringList OneSixInstance::getNativeJars() const
{ {
QStringList jars, nativeJars; QStringList jars, nativeJars;
auto javaArchitecture = settings()->get("JavaArchitecture").toString(); auto javaArchitecture = settings()->get("JavaArchitecture").toString();
m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath()); m_profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
return nativeJars; return nativeJars;
} }

View File

@ -115,9 +115,6 @@ protected:
signals: signals:
void versionReloaded(); void versionReloaded();
private:
QString mainJarPath() const;
protected: protected:
std::shared_ptr<MinecraftProfile> m_profile; std::shared_ptr<MinecraftProfile> m_profile;
mutable std::shared_ptr<ModList> m_loader_mod_list; mutable std::shared_ptr<ModList> m_loader_mod_list;

View File

@ -142,6 +142,32 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
readLibs("+libraries"); readLibs("+libraries");
} }
// if we have mainJar, just use it
if(root.contains("mainJar"))
{
QJsonObject libObj = requireObject(root, "mainJar");
out->mainJar = libraryFromJson(libObj, filename);
}
// else reconstruct it from downloads and id ... if that's available
else if(!out->minecraftVersion.isEmpty())
{
auto lib = std::make_shared<Library>();
lib->setRawName(GradleSpecifier(QString("com.mojang:minecraft:%1:client").arg(out->minecraftVersion)));
// we have a reliable client download, use it.
if(out->mojangDownloads.contains("client"))
{
auto LibDLInfo = std::make_shared<MojangLibraryDownloadInfo>();
LibDLInfo->artifact = out->mojangDownloads["client"];
lib->setMojangDownloadInfo(LibDLInfo);
}
// we got nothing... guess based on ancient hardcoded Mojang behaviour
// FIXME: this will eventually break...
else
{
lib->setAbsoluteUrl(URLConstants::getLegacyJarUrl(out->minecraftVersion));
}
}
/* removed features that shouldn't be used */ /* removed features that shouldn't be used */
if (root.contains("tweakers")) if (root.contains("tweakers"))
{ {

View File

@ -21,36 +21,36 @@ void LibrariesTask::executeTask()
// Build a list of URLs that will need to be downloaded. // Build a list of URLs that will need to be downloaded.
std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile(); std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
// minecraft.jar for this version
{
QString version_id = profile->getMinecraftVersion();
QString localPath = version_id + "/" + version_id + ".jar";
QString urlstr = profile->getMainJarUrl();
auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
downloadJob.reset(job);
auto metacache = ENV.metacache();
auto entry = metacache->resolveEntry("versions", localPath);
job->addNetAction(Net::Download::makeCached(QUrl(urlstr), entry));
downloadJob.reset(job);
}
auto metacache = ENV.metacache(); auto metacache = ENV.metacache();
QList<LibraryPtr> brokenLocalLibs; QList<LibraryPtr> brokenLocalLibs;
QStringList failedFiles; QStringList failedFiles;
auto createJob = [&](const LibraryPtr & lib)
{
if(!lib)
{
emitFailed(tr("Null jar is specified in the metadata, aborting."));
return;
}
auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath());
for(auto dl : dls)
{
downloadJob->addNetAction(dl);
}
};
auto createJobs = [&](const QList<LibraryPtr> & libs) auto createJobs = [&](const QList<LibraryPtr> & libs)
{ {
for (auto lib : libs) for (auto lib : libs)
{ {
auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath()); createJob(lib);
for(auto dl : dls)
{
downloadJob->addNetAction(dl);
}
} }
}; };
createJobs(profile->getLibraries()); createJobs(profile->getLibraries());
createJobs(profile->getNativeLibraries()); createJobs(profile->getNativeLibraries());
createJob(profile->getMainJar());
// FIXME: this is never filled!!!! // FIXME: this is never filled!!!!
if (!brokenLocalLibs.empty()) if (!brokenLocalLibs.empty())