diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 0000000..e824a5e
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,21 @@
+name: Java CI with Gradle
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ - name: Validate Gradle Wrapper
+ uses: gradle/wrapper-validation-action@v1
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: 17
+ check-latest: true
+ - name: Build and test with Gradle
+ run: ./gradlew test
diff --git a/build.gradle.kts b/build.gradle.kts
index f4a3707..a50e216 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,10 +12,13 @@ dependencies {
api("com.google.code.gson:gson:2.10.1")
api("com.viaversion:nbt:3.0.0")
api("it.unimi.dsi:fastutil:8.5.12")
- api("ch.qos.logback:logback-classic:1.4.6")
+ api("ch.qos.logback:logback-classic:1.4.14")
compileOnly("org.jetbrains:annotations:24.0.1")
// Uncomment to manually run mappings gen in ide
// compileOnly(files("server.jar"))
+
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
group = "com.viaversion"
@@ -70,4 +73,8 @@ tasks {
build {
dependsOn(shadowJar)
}
+
+ test {
+ useJUnitPlatform()
+ }
}
diff --git a/mappings/diff/mapping-1.14to1.15.json b/mappings/diff/mapping-1.14to1.15.json
index 59ed5f1..033049a 100644
--- a/mappings/diff/mapping-1.14to1.15.json
+++ b/mappings/diff/mapping-1.14to1.15.json
@@ -16,5 +16,12 @@
"11211": "bell[attachment=double_wall,facing=south,powered=false]",
"11212": "bell[attachment=double_wall,facing=west,powered=false]",
"11213": "bell[attachment=double_wall,facing=east,powered=false]"
+ },
+ "sounds": {
+ "entity.parrot.imitate.enderman": "",
+ "entity.parrot.imitate.panda": "",
+ "entity.parrot.imitate.polar_bear": "",
+ "entity.parrot.imitate.wolf": "",
+ "entity.parrot.imitate.zombie_pigman": ""
}
}
\ No newline at end of file
diff --git a/output/backwards/mappings-1.13to1.12.nbt b/output/backwards/mappings-1.13to1.12.nbt
index 6b5d115..e246587 100644
Binary files a/output/backwards/mappings-1.13to1.12.nbt and b/output/backwards/mappings-1.13to1.12.nbt differ
diff --git a/output/mappings-1.12to1.13.nbt b/output/mappings-1.12to1.13.nbt
index 848c5a6..050e321 100644
Binary files a/output/mappings-1.12to1.13.nbt and b/output/mappings-1.12to1.13.nbt differ
diff --git a/src/main/java/com/viaversion/mappingsgenerator/CursedMappings.java b/src/main/java/com/viaversion/mappingsgenerator/CursedMappings.java
index 49d174e..fbf189c 100644
--- a/src/main/java/com/viaversion/mappingsgenerator/CursedMappings.java
+++ b/src/main/java/com/viaversion/mappingsgenerator/CursedMappings.java
@@ -23,27 +23,29 @@ import java.io.IOException;
public final class CursedMappings {
public static void optimizeAndSaveOhSoSpecial1_12AsNBT() throws IOException {
- final MappingsOptimizer optimizer = new MappingsOptimizer("1.12", "1.13");
- optimizer.keepUnknownFields();
- optimizer.handleUnknownFields();
+ final MappingsOptimizer optimizer = create("1.12", "1.13");
optimizer.cursedMappings("blocks", "blockstates", "blockstates", 4084);
- optimizer.cursedMappings("items", "items", "items");
optimizer.cursedMappings("legacy_enchantments", "enchantments", "enchantments", 72);
- optimizer.mappings(false, "sounds");
optimizer.write(MappingsOptimizer.OUTPUT_DIR);
}
public static void optimizeAndSaveOhSoSpecial1_12AsNBTBackwards() throws IOException {
- final MappingsOptimizer optimizer = new MappingsOptimizer("1.13", "1.12");
- optimizer.keepUnknownFields();
- optimizer.handleUnknownFields();
+ final MappingsOptimizer optimizer = create("1.13", "1.12");
optimizer.cursedMappings("blockstates", "blocks", "blockstates", 8582);
- optimizer.cursedMappings("items", "items", "items");
optimizer.cursedMappings("enchantments", "legacy_enchantments", "enchantments");
optimizer.names("items", "itemnames");
optimizer.fullNames("entitynames", "entitynames");
optimizer.fullNames("sounds", "soundnames");
- optimizer.mappings(false, "sounds");
optimizer.write(MappingsOptimizer.OUTPUT_BACKWARDS_DIR);
}
+
+ private static MappingsOptimizer create(final String from, final String to) throws IOException {
+ final MappingsOptimizer optimizer = new MappingsOptimizer(from, to);
+ optimizer.setErrorStrategy(ErrorStrategy.IGNORE);
+ optimizer.keepUnknownFields();
+ optimizer.handleUnknownFields();
+ optimizer.cursedMappings("items", "items", "items");
+ optimizer.mappings(false, "sounds");
+ return optimizer;
+ }
}
diff --git a/src/main/java/com/viaversion/mappingsgenerator/ErrorStrategy.java b/src/main/java/com/viaversion/mappingsgenerator/ErrorStrategy.java
new file mode 100644
index 0000000..8fe04f2
--- /dev/null
+++ b/src/main/java/com/viaversion/mappingsgenerator/ErrorStrategy.java
@@ -0,0 +1,40 @@
+/*
+ * This file is part of ViaVersion Mappings - https://github.com/ViaVersion/Mappings
+ * Copyright (C) 2023 Nassim Jahnke
+ * Copyright (C) 2023 ViaVersion and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.viaversion.mappingsgenerator;
+
+import java.util.function.Consumer;
+
+public enum ErrorStrategy {
+ IGNORE(message -> {
+ }),
+ WARN(MappingsLoader.LOGGER::warn),
+ ERROR(message -> {
+ throw new RuntimeException(message);
+ });
+
+ private final Consumer action;
+
+ ErrorStrategy(final Consumer action) {
+ this.action = action;
+ }
+
+ public void apply(final String message) {
+ action.accept(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/viaversion/mappingsgenerator/ManualRunner.java b/src/main/java/com/viaversion/mappingsgenerator/ManualRunner.java
index dca5b29..4a3fdbb 100644
--- a/src/main/java/com/viaversion/mappingsgenerator/ManualRunner.java
+++ b/src/main/java/com/viaversion/mappingsgenerator/ManualRunner.java
@@ -25,18 +25,15 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public final class ManualRunner {
- private static final Logger LOGGER = LoggerFactory.getLogger(ManualRunner.class.getSimpleName());
private static final Set SPECIAL_BACKWARDS_ONLY = Set.of("1.9.4", "1.10", "1.11");
private static final boolean ALL = true;
public static void main(final String[] args) throws IOException {
if (ALL) {
- runAll();
+ runAll(ErrorStrategy.WARN);
return;
}
@@ -52,9 +49,9 @@ public final class ManualRunner {
}
/**
- * Runs the optimizer for all mapping files present in the mappings/ directory.
+ * Runs the optimizer for all mapping files present in the 'mappings' directory.
*/
- public static void runAll() throws IOException {
+ public static void runAll(final ErrorStrategy errorStrategy) throws IOException {
final List versions = new ArrayList<>();
for (final File file : MappingsOptimizer.MAPPINGS_DIR.toFile().listFiles()) {
final String name = file.getName();
@@ -69,7 +66,6 @@ public final class ManualRunner {
for (int i = 0; i < versions.size() - 1; i++) {
final String from = versions.get(i);
final String to = versions.get(i + 1);
- LOGGER.info("=============================");
if (from.equals("1.12") && to.equals("1.13")) {
CursedMappings.optimizeAndSaveOhSoSpecial1_12AsNBT();
CursedMappings.optimizeAndSaveOhSoSpecial1_12AsNBTBackwards();
@@ -78,17 +74,18 @@ public final class ManualRunner {
final boolean special = SPECIAL_BACKWARDS_ONLY.contains(from);
if (!special) {
- new MappingsOptimizer(from, to).optimizeAndWrite();
- LOGGER.info("-----------------------------");
+ final MappingsOptimizer mappingsOptimizer = new MappingsOptimizer(from, to);
+ mappingsOptimizer.setErrorStrategy(errorStrategy);
+ mappingsOptimizer.optimizeAndWrite();
}
final MappingsOptimizer backwardsOptimizer = new MappingsOptimizer(to, from);
+ backwardsOptimizer.setErrorStrategy(errorStrategy);
if (special) {
backwardsOptimizer.ignoreMissingMappingsFor("sounds");
}
backwardsOptimizer.optimizeAndWrite();
- LOGGER.info("");
}
}
diff --git a/src/main/java/com/viaversion/mappingsgenerator/MappingsLoader.java b/src/main/java/com/viaversion/mappingsgenerator/MappingsLoader.java
index 6657a78..be8f918 100644
--- a/src/main/java/com/viaversion/mappingsgenerator/MappingsLoader.java
+++ b/src/main/java/com/viaversion/mappingsgenerator/MappingsLoader.java
@@ -38,8 +38,8 @@ import org.slf4j.LoggerFactory;
public final class MappingsLoader {
+ public static final Logger LOGGER = LoggerFactory.getLogger(MappingsLoader.class.getSimpleName());
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
- private static final Logger LOGGER = LoggerFactory.getLogger(MappingsLoader.class.getSimpleName());
/**
* Loads and return the json mappings file.
@@ -63,10 +63,10 @@ public final class MappingsLoader {
* @param unmappedIdentifiers array of unmapped identifiers
* @param mappedIdentifiers array of mapped identifiers
* @param diffIdentifiers diff identifiers
- * @param warnOnMissing whether to warn on missing mappings
+ * @param errorStrategy whether to warn on missing mappings
* @return mappings result with int to int array mappings
*/
- public static MappingsResult map(final JsonArray unmappedIdentifiers, final JsonArray mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final boolean warnOnMissing) {
+ public static MappingsResult map(final JsonArray unmappedIdentifiers, final JsonArray mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final ErrorStrategy errorStrategy) {
final int[] output = new int[unmappedIdentifiers.size()];
final Object2IntMap mappedIdentifierMap = MappingsLoader.arrayToMap(mappedIdentifiers);
int emptyMappings = 0;
@@ -74,7 +74,7 @@ public final class MappingsLoader {
int shiftChanges = 0;
for (int id = 0; id < unmappedIdentifiers.size(); id++) {
final JsonElement unmappedIdentifier = unmappedIdentifiers.get(id);
- final int mappedId = mapEntry(id, unmappedIdentifier.getAsString(), mappedIdentifierMap, diffIdentifiers, warnOnMissing);
+ final int mappedId = mapEntry(id, unmappedIdentifier.getAsString(), mappedIdentifierMap, diffIdentifiers, errorStrategy);
output[id] = mappedId;
if (mappedId == -1) {
@@ -98,16 +98,16 @@ public final class MappingsLoader {
* @param unmappedIdentifiers object of unmapped identifiers, keyed by their int id
* @param mappedIdentifiers object of mapped identifiers, keyed by their int id
* @param diffIdentifiers diff identifiers
- * @param warnOnMissing whether to warn on missing mappings
+ * @param errorStrategy whether to warn on missing mappings
* @return mappings result
*/
- public static Int2IntMap map(final JsonObject unmappedIdentifiers, final JsonObject mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final boolean warnOnMissing) {
+ public static Int2IntMap map(final JsonObject unmappedIdentifiers, final JsonObject mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final ErrorStrategy errorStrategy) {
final Int2IntMap output = new Int2IntLinkedOpenHashMap();
output.defaultReturnValue(-1);
final Object2IntMap mappedIdentifierMap = MappingsLoader.indexedObjectToMap(mappedIdentifiers);
for (final Map.Entry entry : unmappedIdentifiers.entrySet()) {
final int id = Integer.parseInt(entry.getKey());
- final int mappedId = mapEntry(id, entry.getValue().getAsString(), mappedIdentifierMap, diffIdentifiers, warnOnMissing);
+ final int mappedId = mapEntry(id, entry.getValue().getAsString(), mappedIdentifierMap, diffIdentifiers, errorStrategy);
output.put(id, mappedId);
}
return output;
@@ -120,10 +120,10 @@ public final class MappingsLoader {
* @param value value of the entry
* @param mappedIdentifiers mapped identifiers
* @param diffIdentifiers diff identifiers
- * @param warnOnMissing whether to warn on missing mappings
+ * @param errorStrategy whether to warn on missing mappings
* @return mapped id, or -1 if it was not found
*/
- private static int mapEntry(final int id, final String value, final Object2IntMap mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final boolean warnOnMissing) {
+ private static int mapEntry(final int id, final String value, final Object2IntMap mappedIdentifiers, @Nullable final JsonObject diffIdentifiers, final ErrorStrategy errorStrategy) {
int mappedId = mappedIdentifiers.getInt(value);
if (mappedId != -1) {
return mappedId;
@@ -131,9 +131,7 @@ public final class MappingsLoader {
final int dataIndex;
if (diffIdentifiers == null) {
- if (warnOnMissing) {
- LOGGER.warn("No direct mapping or diff file for {} :( ", value);
- }
+ errorStrategy.apply("No direct mapping or diff file for " + value + " :( ");
return -1;
}
@@ -167,8 +165,8 @@ public final class MappingsLoader {
mappedId = mappedIdentifiers.getInt(mappedName);
}
- if (mappedId == -1 && warnOnMissing) {
- LOGGER.warn("No diff entry for {} :( ", value);
+ if (mappedId == -1) {
+ errorStrategy.apply("No mapping for " + value + " :( ");
}
return mappedId;
}
@@ -202,7 +200,7 @@ public final class MappingsLoader {
final JsonObject existingDiffIdentifiers = existingDiffObject != null && existingDiffObject.has(key) ? existingDiffObject.getAsJsonObject(key) : null;
for (int id = 0; id < unmappedIdentifiers.size(); id++) {
final String unmappedIdentifier = unmappedIdentifiers.get(id).getAsString();
- final int mappedId = mapEntry(id, unmappedIdentifier, mappedIdentifierMap, existingDiffIdentifiers, false);
+ final int mappedId = mapEntry(id, unmappedIdentifier, mappedIdentifierMap, existingDiffIdentifiers, ErrorStrategy.IGNORE);
if (mappedId != -1) {
continue;
}
@@ -281,6 +279,6 @@ public final class MappingsLoader {
* @param identityMappings number of identity mappings
* @param shiftChanges number of shift changes where a mapped id is not the last mapped id + 1
*/
- record MappingsResult(int[] mappings, int mappedSize, int emptyMappings, int identityMappings, int shiftChanges) {
+ public record MappingsResult(int[] mappings, int mappedSize, int emptyMappings, int identityMappings, int shiftChanges) {
}
}
diff --git a/src/main/java/com/viaversion/mappingsgenerator/MappingsOptimizer.java b/src/main/java/com/viaversion/mappingsgenerator/MappingsOptimizer.java
index 43c7ef6..9a57338 100644
--- a/src/main/java/com/viaversion/mappingsgenerator/MappingsOptimizer.java
+++ b/src/main/java/com/viaversion/mappingsgenerator/MappingsOptimizer.java
@@ -87,6 +87,7 @@ public final class MappingsOptimizer {
private final String toVersion;
private final JsonObject unmappedObject;
private final JsonObject mappedObject;
+ private ErrorStrategy errorStrategy = ErrorStrategy.WARN;
private JsonObject diffObject;
private boolean keepUnknownFields;
@@ -143,7 +144,7 @@ public final class MappingsOptimizer {
* Optimizes mapping files as nbt files with only the necessary data (int to int mappings in form of int arrays).
*/
public void optimizeAndWrite() throws IOException {
- LOGGER.info("Compacting json mapping files for versions {} → {}...", fromVersion, toVersion);
+ LOGGER.info("=== Compacting json mapping files for versions {} → {}...", fromVersion, toVersion);
if (keepUnknownFields) {
handleUnknownFields();
@@ -244,7 +245,8 @@ public final class MappingsOptimizer {
continue;
}
- LOGGER.warn("NON-STANDARD FIELD: {} - writing it to the file without changes", key);
+ errorStrategy.apply("NON-STANDARD FIELD: " + key + " - writing it to the file without changes");
+
final Tag asTag = JsonConverter.toTag(unmappedObject.get(key));
output.put(key, asTag);
}
@@ -275,8 +277,8 @@ public final class MappingsOptimizer {
serialize(result, output, key, alwaysWriteIdentity);
}
- private boolean shouldWarn(final String key) {
- return !ignoreMissing.contains(key);
+ private ErrorStrategy shouldWarn(final String key) {
+ return ignoreMissing.contains(key) ? ErrorStrategy.IGNORE : errorStrategy;
}
public void cursedMappings(final String unmappedKey, final String mappedKey, final String outputKey) {
@@ -295,7 +297,7 @@ public final class MappingsOptimizer {
JsonConverter.toJsonObject(unmappedObject.get(unmappedKey)),
mappedIdentifiers,
diffObject != null ? diffObject.getAsJsonObject(unmappedKey) : null,
- true
+ errorStrategy
);
final CompoundTag changedTag = new CompoundTag();
@@ -560,4 +562,8 @@ public final class MappingsOptimizer {
// One entry in two arrays each time the id is not shifted by 1 from the last id + more approximate length for extra tags
return result.shiftChanges() * 2 + 10;
}
+
+ public void setErrorStrategy(final ErrorStrategy errorStrategy) {
+ this.errorStrategy = errorStrategy;
+ }
}
diff --git a/src/test/java/com/viaversion/mappingsgenerator/MappingsTest.java b/src/test/java/com/viaversion/mappingsgenerator/MappingsTest.java
new file mode 100644
index 0000000..fd27705
--- /dev/null
+++ b/src/test/java/com/viaversion/mappingsgenerator/MappingsTest.java
@@ -0,0 +1,12 @@
+package com.viaversion.mappingsgenerator;
+
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+
+public class MappingsTest {
+
+ @Test
+ void testFilledStatus() throws IOException {
+ ManualRunner.runAll(ErrorStrategy.ERROR);
+ }
+}