Allow components to specify Java agents and JVM arguments (#175)

This commit is contained in:
Una 2022-04-05 23:22:24 -07:00 committed by GitHub
parent 8732bea99b
commit dc6340bf38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 2 deletions

View File

@ -348,7 +348,7 @@ set(MINECRAFT_SOURCES
mojang/PackageManifest.h
mojang/PackageManifest.cpp
)
minecraft/Agent.h)
add_unit_test(GradleSpecifier
SOURCES minecraft/GradleSpecifier_test.cpp

View File

@ -0,0 +1,36 @@
#pragma once
#include <QString>
#include "Library.h"
class Agent;
typedef std::shared_ptr<Agent> AgentPtr;
class Agent {
public:
Agent(LibraryPtr library, QString &argument)
{
m_library = library;
m_argument = argument;
}
public: /* methods */
LibraryPtr library() {
return m_library;
}
QString argument() {
return m_argument;
}
protected: /* data */
/// The library pointing to the jar this Java agent is contained within
LibraryPtr m_library;
/// The argument to the Java agent, passed after an = if present
QString m_argument;
};

View File

@ -42,11 +42,13 @@ void LaunchProfile::clear()
m_minecraftVersionType.clear();
m_minecraftAssets.reset();
m_minecraftArguments.clear();
m_addnJvmArguments.clear();
m_tweakers.clear();
m_mainClass.clear();
m_appletClass.clear();
m_libraries.clear();
m_mavenFiles.clear();
m_agents.clear();
m_traits.clear();
m_jarMods.clear();
m_mainJar.reset();
@ -80,6 +82,11 @@ void LaunchProfile::applyMinecraftArguments(const QString& minecraftArguments)
applyString(minecraftArguments, this->m_minecraftArguments);
}
void LaunchProfile::applyAddnJvmArguments(const QStringList& addnJvmArguments)
{
this->m_addnJvmArguments.append(addnJvmArguments);
}
void LaunchProfile::applyMinecraftVersionType(const QString& type)
{
applyString(type, this->m_minecraftVersionType);
@ -214,6 +221,22 @@ void LaunchProfile::applyMavenFile(LibraryPtr mavenFile)
m_mavenFiles.append(Library::limitedCopy(mavenFile));
}
void LaunchProfile::applyAgent(AgentPtr agent)
{
auto lib = agent->library();
if(!lib->isActive())
{
return;
}
if(lib->isNative())
{
return;
}
m_agents.append(agent);
}
const LibraryPtr LaunchProfile::getMainJar() const
{
return m_mainJar;
@ -295,6 +318,11 @@ QString LaunchProfile::getMinecraftArguments() const
return m_minecraftArguments;
}
const QStringList & LaunchProfile::getAddnJvmArguments() const
{
return m_addnJvmArguments;
}
const QList<LibraryPtr> & LaunchProfile::getJarMods() const
{
return m_jarMods;
@ -315,6 +343,11 @@ const QList<LibraryPtr> & LaunchProfile::getMavenFiles() const
return m_mavenFiles;
}
const QList<AgentPtr> & LaunchProfile::getAgents() const
{
return m_agents;
}
const QList<int> & LaunchProfile::getCompatibleJavaMajors() const
{
return m_compatibleJavaMajors;

View File

@ -36,6 +36,7 @@
#pragma once
#include <QString>
#include "Library.h"
#include "Agent.h"
#include <ProblemProvider.h>
class LaunchProfile: public ProblemProvider
@ -48,6 +49,7 @@ public: /* application of profile variables from patches */
void applyMainClass(const QString& mainClass);
void applyAppletClass(const QString& appletClass);
void applyMinecraftArguments(const QString& minecraftArguments);
void applyAddnJvmArguments(const QStringList& minecraftArguments);
void applyMinecraftVersionType(const QString& type);
void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
void applyTraits(const QSet<QString> &traits);
@ -56,6 +58,7 @@ public: /* application of profile variables from patches */
void applyMods(const QList<LibraryPtr> &jarMods);
void applyLibrary(LibraryPtr library);
void applyMavenFile(LibraryPtr library);
void applyAgent(AgentPtr agent);
void applyCompatibleJavaMajors(QList<int>& javaMajor);
void applyMainJar(LibraryPtr jar);
void applyProblemSeverity(ProblemSeverity severity);
@ -69,12 +72,14 @@ public: /* getters for profile variables */
QString getMinecraftVersionType() const;
MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
QString getMinecraftArguments() const;
const QStringList & getAddnJvmArguments() const;
const QSet<QString> & getTraits() const;
const QStringList & getTweakers() const;
const QList<LibraryPtr> & getJarMods() const;
const QList<LibraryPtr> & getLibraries() const;
const QList<LibraryPtr> & getNativeLibraries() const;
const QList<LibraryPtr> & getMavenFiles() const;
const QList<AgentPtr> & getAgents() const;
const QList<int> & getCompatibleJavaMajors() const;
const LibraryPtr getMainJar() const;
void getLibraryFiles(
@ -106,6 +111,12 @@ private:
*/
QString m_minecraftArguments;
/**
* Additional arguments to pass to the JVM in addition to those the user has configured,
* memory settings, etc.
*/
QStringList m_addnJvmArguments;
/// A list of all tweaker classes
QStringList m_tweakers;
@ -121,6 +132,9 @@ private:
/// the list of maven files to be placed in the libraries folder, but not acted upon
QList<LibraryPtr> m_mavenFiles;
/// the list of java agents to add to JVM arguments
QList<AgentPtr> m_agents;
/// the main jar
LibraryPtr m_mainJar;

View File

@ -330,6 +330,17 @@ QStringList MinecraftInstance::extraArguments() const
list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
"-Dfml.ignorePatchDiscrepancies=true"});
}
auto addn = m_components->getProfile()->getAddnJvmArguments();
if (!addn.isEmpty()) {
list.append(addn);
}
auto agents = m_components->getProfile()->getAgents();
for (auto agent : agents)
{
QStringList jar, temp1, temp2, temp3;
agent->library()->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, getLocalLibraryPath());
list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument()));
}
return list;
}

View File

@ -1,5 +1,6 @@
#include "OneSixVersionFormat.h"
#include <Json.h>
#include "minecraft/Agent.h"
#include "minecraft/ParseUtils.h"
#include <minecraft/MojangVersionFormat.h>
@ -108,6 +109,14 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
}
}
if (root.contains("+jvmArgs"))
{
for (auto arg : requireArray(root.value("+jvmArgs")))
{
out->addnJvmArguments.append(requireString(arg));
}
}
if (root.contains("jarMods"))
{
@ -176,6 +185,21 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
readLibs("mavenFiles", out->mavenFiles);
}
if(root.contains("+agents")) {
for (auto agentVal : requireArray(root.value("+agents")))
{
QJsonObject agentObj = requireObject(agentVal);
auto lib = libraryFromJson(*out, agentObj, filename);
QString arg = "";
if (agentObj.contains("argument"))
{
readString(agentObj, "argument", arg);
}
AgentPtr agent(new Agent(lib, arg));
out->agents.append(agent);
}
}
// if we have mainJar, just use it
if(root.contains("mainJar"))
{

View File

@ -67,6 +67,7 @@ void VersionFile::applyTo(LaunchProfile *profile)
profile->applyMainClass(mainClass);
profile->applyAppletClass(appletClass);
profile->applyMinecraftArguments(minecraftArguments);
profile->applyAddnJvmArguments(addnJvmArguments);
profile->applyTweakers(addTweakers);
profile->applyJarMods(jarMods);
profile->applyMods(mods);
@ -81,6 +82,10 @@ void VersionFile::applyTo(LaunchProfile *profile)
{
profile->applyMavenFile(mavenFile);
}
for (auto agent : agents)
{
profile->applyAgent(agent);
}
profile->applyProblemSeverity(getProblemSeverity());
}

View File

@ -45,6 +45,7 @@
#include "minecraft/Rule.h"
#include "ProblemProvider.h"
#include "Library.h"
#include "Agent.h"
#include <meta/JsonFormat.h>
class PackProfile;
@ -92,6 +93,9 @@ public: /* data */
/// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
QString minecraftArguments;
/// PolyMC: Additional JVM launch arguments
QStringList addnJvmArguments;
/// Mojang: list of compatible java majors
QList<int> compatibleJavaMajors;
@ -116,6 +120,9 @@ public: /* data */
/// PolyMC: list of maven files to put in the libraries folder, but not in classpath
QList<LibraryPtr> mavenFiles;
/// PolyMC: list of agents to add to JVM arguments
QList<AgentPtr> agents;
/// The main jar (Minecraft version library, normally)
LibraryPtr mainJar;

View File

@ -48,6 +48,10 @@ void LibrariesTask::executeTask()
libArtifactPool.append(profile->getLibraries());
libArtifactPool.append(profile->getNativeLibraries());
libArtifactPool.append(profile->getMavenFiles());
for (auto agent : profile->getAgents())
{
libArtifactPool.append(agent->library());
}
libArtifactPool.append(profile->getMainJar());
processArtifactPool(libArtifactPool, failedLocalLibraries, inst->getLocalLibraryPath());

View File

@ -74,7 +74,7 @@
<item>
<widget class="QLabel" name="labelCustomCmdsDescription">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pre-launch command runs before the instance launches and post-exit command runs after it exits.&lt;/p&gt;&lt;p&gt;Both will be run in the launcher's working folder with extra environment variables:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;$INST_NAME - Name of the instance&lt;/li&gt;&lt;li&gt;$INST_ID - ID of the instance (its folder name)&lt;/li&gt;&lt;li&gt;$INST_DIR - absolute path of the instance&lt;/li&gt;&lt;li&gt;$INST_MC_DIR - absolute path of Minecraft&lt;/li&gt;&lt;li&gt;$INST_JAVA - Java binary used for launch&lt;/li&gt;&lt;li&gt;$INST_JAVA_ARGS - command-line parameters used for launch&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Wrapper command allows launching using an extra wrapper program (like 'optirun' on Linux)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pre-launch command runs before the instance launches and post-exit command runs after it exits.&lt;/p&gt;&lt;p&gt;Both will be run in the launcher's working folder with extra environment variables:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;$INST_NAME - Name of the instance&lt;/li&gt;&lt;li&gt;$INST_ID - ID of the instance (its folder name)&lt;/li&gt;&lt;li&gt;$INST_DIR - absolute path of the instance&lt;/li&gt;&lt;li&gt;$INST_MC_DIR - absolute path of Minecraft&lt;/li&gt;&lt;li&gt;$INST_JAVA - Java binary used for launch&lt;/li&gt;&lt;li&gt;$INST_JAVA_ARGS - command-line parameters used for launch (warning: will not work correctly if arguments contain spaces)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Wrapper command allows launching using an extra wrapper program (like 'optirun' on Linux)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>