Expand variables in JVM args and add library_dir variable (#4427)

This commit is contained in:
Alexandru Ionut Tripon
2025-12-09 21:09:03 +02:00
committed by GitHub
2 changed files with 64 additions and 45 deletions

View File

@@ -483,6 +483,29 @@ QStringList MinecraftInstance::getNativeJars()
return nativeJars;
}
static QString replaceTokensIn(const QString &text, const QMap<QString, QString> &with)
{
// TODO: does this still work??
QString result;
static const QRegularExpression s_token_regexp("\\$\\{(.+)\\}", QRegularExpression::InvertedGreedinessOption);
QStringList list;
QRegularExpressionMatchIterator i = s_token_regexp.globalMatch(text);
int lastCapturedEnd = 0;
while (i.hasNext()) {
QRegularExpressionMatch match = i.next();
result.append(text.mid(lastCapturedEnd, match.capturedStart()));
QString key = match.captured(1);
auto iter = with.find(key);
if (iter != with.end()) {
result.append(*iter);
}
lastCapturedEnd = match.capturedEnd();
}
result.append(text.mid(lastCapturedEnd));
return result;
}
QStringList MinecraftInstance::extraArguments()
{
auto list = BaseInstance::extraArguments();
@@ -495,7 +518,11 @@ QStringList MinecraftInstance::extraArguments()
}
auto addn = m_components->getProfile()->getAddnJvmArguments();
if (!addn.isEmpty()) {
list.append(addn);
QMap<QString, QString> tokenMapping = makeProfileVarMapping(m_components->getProfile());
for (const QString &item : addn) {
list.append(replaceTokensIn(item, tokenMapping));
}
}
auto agents = m_components->getProfile()->getAgents();
for (auto agent : agents) {
@@ -705,28 +732,6 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
return env;
}
static QString replaceTokensIn(QString text, QMap<QString, QString> with)
{
// TODO: does this still work??
QString result;
static const QRegularExpression s_token_regexp("\\$\\{(.+)\\}", QRegularExpression::InvertedGreedinessOption);
QStringList list;
QRegularExpressionMatchIterator i = s_token_regexp.globalMatch(text);
int lastCapturedEnd = 0;
while (i.hasNext()) {
QRegularExpressionMatch match = i.next();
result.append(text.mid(lastCapturedEnd, match.capturedStart()));
QString key = match.captured(1);
auto iter = with.find(key);
if (iter != with.end()) {
result.append(*iter);
}
lastCapturedEnd = match.capturedEnd();
}
result.append(text.mid(lastCapturedEnd));
return result;
}
QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin) const
{
auto profile = m_components->getProfile();
@@ -748,38 +753,27 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, Mine
}
}
QMap<QString, QString> token_mapping;
QMap<QString, QString> tokenMapping = makeProfileVarMapping(profile);
// yggdrasil!
if (session) {
// token_mapping["auth_username"] = session->username;
token_mapping["auth_session"] = session->session;
token_mapping["auth_access_token"] = session->access_token;
token_mapping["auth_player_name"] = session->player_name;
token_mapping["auth_uuid"] = session->uuid;
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
tokenMapping["auth_session"] = session->session;
tokenMapping["auth_access_token"] = session->access_token;
tokenMapping["auth_player_name"] = session->player_name;
tokenMapping["auth_uuid"] = session->uuid;
tokenMapping["user_properties"] = session->serializeUserProperties();
tokenMapping["user_type"] = session->user_type;
if (session->demo) {
args_pattern += " --demo";
}
}
token_mapping["profile_name"] = name();
token_mapping["version_name"] = profile->getMinecraftVersion();
token_mapping["version_type"] = profile->getMinecraftVersionType();
QString absRootDir = QDir(gameRoot()).absolutePath();
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
auto assets = profile->getMinecraftAssets();
token_mapping["game_assets"] = AssetsUtils::getAssetsDir(assets->id, resourcesDir()).absolutePath();
// 1.7.3+ assets tokens
token_mapping["assets_root"] = absAssetsDir;
token_mapping["assets_index_name"] = assets->id;
QStringList parts = args_pattern.split(' ', Qt::SkipEmptyParts);
for (int i = 0; i < parts.length(); i++) {
parts[i] = replaceTokensIn(parts[i], token_mapping);
parts[i] = replaceTokensIn(parts[i], tokenMapping);
}
return parts;
}
@@ -1024,6 +1018,29 @@ QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSess
return filter;
}
QMap<QString, QString> MinecraftInstance::makeProfileVarMapping(std::shared_ptr<LaunchProfile> profile) const
{
QMap<QString, QString> result;
result["profile_name"] = name();
result["version_name"] = profile->getMinecraftVersion();
result["version_type"] = profile->getMinecraftVersionType();
QString absRootDir = QDir(gameRoot()).absolutePath();
result["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
auto assets = profile->getMinecraftAssets();
result["game_assets"] = AssetsUtils::getAssetsDir(assets->id, resourcesDir()).absolutePath();
// 1.7.3+ assets tokens
result["assets_root"] = absAssetsDir;
result["assets_index_name"] = assets->id;
result["library_directory"] = APPLICATION->metacache()->getBasePath("libraries");
return result;
}
QStringList MinecraftInstance::getLogFileSearchPaths()
{
return { FS::PathCombine(gameRoot(), "crash-reports"), FS::PathCombine(gameRoot(), "logs"), gameRoot() };

View File

@@ -50,6 +50,7 @@ class ShaderPackFolderModel;
class TexturePackFolderModel;
class WorldList;
class LaunchStep;
class LaunchProfile;
class PackProfile;
class MinecraftInstance : public BaseInstance {
@@ -158,6 +159,7 @@ class MinecraftInstance : public BaseInstance {
protected:
QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
QMap<QString, QString> makeProfileVarMapping(std::shared_ptr<LaunchProfile> profile) const;
protected: // data
std::shared_ptr<PackProfile> m_components;