From 769e0770784f2e32c4ccaf3ffab2631d6dc3538c Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 14 Oct 2026 20:18:50 -0400 Subject: [PATCH] Clarified ingest target errors - Rejected target pack names outside letters, digits, underscores and hyphens before ingest starts - Reported an existing target pack with a translated replace=true hint instead of the raw path --- .../art/arcane/iris/modded/command/ModIngestArguments.java | 4 ++++ .../arcane/iris/modded/command/ModdedCatalogCommands.java | 4 ++++ .../iris/modded/localization/ModdedCatalogMessages.java | 5 +++++ .../arcane/iris/modded/command/ModIngestArgumentsTest.java | 1 + core/src/main/resources/languages/de_DE.toml | 1 + core/src/main/resources/languages/es_ES.toml | 1 + core/src/main/resources/languages/fi_FI.toml | 1 + core/src/main/resources/languages/fr_FR.toml | 1 + core/src/main/resources/languages/he_IL.toml | 1 + core/src/main/resources/languages/it_IT.toml | 1 + core/src/main/resources/languages/ja-JP.toml | 1 + core/src/main/resources/languages/ko_KR.toml | 1 + core/src/main/resources/languages/lt_LT.toml | 1 + core/src/main/resources/languages/nl_NL.toml | 1 + core/src/main/resources/languages/pl_PL.toml | 1 + core/src/main/resources/languages/pt_PT.toml | 1 + core/src/main/resources/languages/ru_RU.toml | 1 + core/src/main/resources/languages/tr_TR.toml | 1 + core/src/main/resources/languages/vi_VI.toml | 1 + core/src/main/resources/languages/zh_CN.toml | 1 + core/src/main/resources/languages/zh_TW.toml | 1 + 21 files changed, 31 insertions(+) diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModIngestArguments.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModIngestArguments.java index 237dbf274..03b885d11 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModIngestArguments.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModIngestArguments.java @@ -29,6 +29,7 @@ import java.util.regex.Pattern; record ModIngestArguments(String sourcePack, String targetPack, String dimension, Set namespaces, boolean replace) { static final List OPTION_SUGGESTIONS = List.of("dimension=", "namespaces=", "replace=true"); private static final Pattern PACK = Pattern.compile("[A-Za-z0-9_.-]+"); + private static final Pattern TARGET_PACK = Pattern.compile("[A-Za-z0-9_-]+"); private static final Pattern DIMENSION = Pattern.compile("[A-Za-z0-9_/.-]+"); private static final Pattern NAMESPACE = Pattern.compile("[a-z0-9_.-]+"); private static final String DIMENSION_KEY = "dimension"; @@ -76,6 +77,9 @@ record ModIngestArguments(String sourcePack, String targetPack, String dimension } requirePack(source); requirePack(target); + if (!TARGET_PACK.matcher(target).matches()) { + throw new IllegalArgumentException("invalid target pack name '" + target + "'"); + } if (source.equals(target)) { throw new IllegalArgumentException("source and target must be different packs"); } diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedCatalogCommands.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedCatalogCommands.java index 48fea1dbb..c8560f906 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedCatalogCommands.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedCatalogCommands.java @@ -43,6 +43,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import java.io.File; import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -211,6 +212,9 @@ final class ModdedCatalogCommands { try { ModIngestReport report = ModIngester.ingest(request); source.execute(() -> reportIngest(source, report)); + } catch (FileAlreadyExistsException exists) { + source.execute(() -> IrisModdedCommands.fail(source, IrisLanguage.plain(ModdedCatalogMessages.INGEST_TARGET_EXISTS, + MessageArgument.untrusted("target", request.targetPack().getFileName().toString())))); } catch (IOException | RuntimeException failure) { ModdedIrisLog.error("Iris mod ingest into " + request.targetPack() + " failed", failure); String reason = reason(failure); diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/localization/ModdedCatalogMessages.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/localization/ModdedCatalogMessages.java index 02f3c2fcc..5482f9183 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/localization/ModdedCatalogMessages.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/localization/ModdedCatalogMessages.java @@ -91,6 +91,10 @@ public final class ModdedCatalogMessages { "iris.modded.catalog.ingest_failed", "Mod ingest failed: {reason}" ); + public static final TextKey INGEST_TARGET_EXISTS = TextKey.of( + "iris.modded.catalog.ingest_target_exists", + "Target pack '{target}' already exists. Add replace=true to overwrite it." + ); public static final TextKey INGEST_LINE = TextKey.of( "iris.modded.catalog.ingest_line", " {summary}" @@ -129,6 +133,7 @@ public final class ModdedCatalogMessages { INGEST_PACK_MISSING, INGEST_STARTED, INGEST_FAILED, + INGEST_TARGET_EXISTS, INGEST_LINE, INGEST_COMPLETE, HELP_CATALOG, diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModIngestArgumentsTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModIngestArgumentsTest.java index d484410b9..c90dcca25 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModIngestArgumentsTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModIngestArgumentsTest.java @@ -68,6 +68,7 @@ public class ModIngestArgumentsTest { public void valuesAreValidated() { assertEquals("replace must be true or false", reason("overworld modded replace=yes")); assertEquals("invalid pack name '../evil'", reason("../evil modded")); + assertEquals("invalid target pack name 'modded.v2'", reason("overworld modded.v2")); assertEquals("invalid dimension key 'a..b'", reason("overworld modded dimension=a..b")); assertEquals("invalid namespace 'Bad'", reason("overworld modded namespaces=ok,Bad")); assertEquals("namespaces must not be empty", reason("overworld modded namespaces=,")); diff --git a/core/src/main/resources/languages/de_DE.toml b/core/src/main/resources/languages/de_DE.toml index 7cae93127..25189f6f8 100644 --- a/core/src/main/resources/languages/de_DE.toml +++ b/core/src/main/resources/languages/de_DE.toml @@ -475,6 +475,7 @@ ingest_invalid = "Ungültige Argumente: {reason}. Verwendung: /iris ingest mods ingest_pack_missing = "Pack '{pack}' wurde unter {path} nicht gefunden." ingest_started = "Übernehme Mod-Worldgen aus '{source}' in '{target}' (Dimension {dimension})..." ingest_failed = "Mod-Übernahme fehlgeschlagen: {reason}" +ingest_target_exists = "Ziel-Pack '{target}' existiert bereits. Füge replace=true hinzu, um es zu überschreiben." ingest_line = " {summary}" ingest_complete = "Mod-Übernahme abgeschlossen: {path}" diff --git a/core/src/main/resources/languages/es_ES.toml b/core/src/main/resources/languages/es_ES.toml index 326db86d4..f126ae8d7 100644 --- a/core/src/main/resources/languages/es_ES.toml +++ b/core/src/main/resources/languages/es_ES.toml @@ -475,6 +475,7 @@ ingest_invalid = "Argumentos no válidos: {reason}. Uso: /iris ingest mods