mirror of
https://github.com/ViaVersion/Mappings.git
synced 2024-09-30 04:47:34 +02:00
3.0.0
This commit is contained in:
parent
71b7ad7b05
commit
fd69be58b4
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,10 +1,8 @@
|
|||||||
server.jar
|
|
||||||
|
|
||||||
### Java files ###
|
### Java files ###
|
||||||
*.class
|
*.class
|
||||||
|
|
||||||
# Package Files
|
# Package Files
|
||||||
#*.jar
|
*.jar
|
||||||
*.war
|
*.war
|
||||||
*.ear
|
*.ear
|
||||||
|
|
||||||
|
20
README.md
20
README.md
@ -1,12 +1,18 @@
|
|||||||
## Mappings
|
# Mappings
|
||||||
|
|
||||||
Generates mapping files for Via*.
|
Generates and compiles mapping files for Via*. Current mapping files can be found in the `mappings/` directory.
|
||||||
|
|
||||||
## Usage
|
## Generating json mapping files for a Minecraft version
|
||||||
`java -jar MappingsGenerator-2.0.jar <path to server jar> <version>`\
|
|
||||||
So for example: `java -jar MappingsGenerator-2.0.jar server.jar 20w22a`
|
|
||||||
|
|
||||||
The mapping file will then be generated in the `mappings` directory.
|
Compile the project using `mvn clean build` and put the jar in some directory, ideally the project root.
|
||||||
|
|
||||||
|
Then run the jar with: `java -jar MappingsGenerator.jar <path to server jar> <version>`,
|
||||||
|
e.g. `java -jar MappingsGenerator.jar server.jar 20w22a`. The mapping file will then be generated in the `mappings/`
|
||||||
|
directory.
|
||||||
|
|
||||||
|
## Compiling json mapping files into compact nbt files
|
||||||
|
|
||||||
## License
|
## License
|
||||||
The Java code is licensed under the GNU GPL v3 license. The files under `mappings/` are free to copy, use, and expand upon in whatever way you like.
|
|
||||||
|
The Java code is licensed under the GNU GPL v3 license. The files under `mappings/` are free to copy, use, and expand
|
||||||
|
upon in whatever way you like.
|
15
pom.xml
15
pom.xml
@ -7,7 +7,7 @@
|
|||||||
<groupId>com.viaversion</groupId>
|
<groupId>com.viaversion</groupId>
|
||||||
<artifactId>mappingsgenerator</artifactId>
|
<artifactId>mappingsgenerator</artifactId>
|
||||||
<name>MappingsGenerator</name>
|
<name>MappingsGenerator</name>
|
||||||
<version>2.2</version>
|
<version>3.0.0</version>
|
||||||
|
|
||||||
<url>https://github.com/ViaVersion/Mappings</url>
|
<url>https://github.com/ViaVersion/Mappings</url>
|
||||||
<inceptionYear>2020</inceptionYear>
|
<inceptionYear>2020</inceptionYear>
|
||||||
@ -92,7 +92,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
<mainClass>com.viaversion.mappingsgenerator.Main</mainClass>
|
<mainClass>com.viaversion.mappingsgenerator.MappingsGenerator</mainClass>
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -110,7 +110,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<filters>
|
<filters>
|
||||||
<filter>
|
<filter>
|
||||||
<artifact>it.unimi.dsi:fastutil</artifact>
|
<artifact>it.unimi.dsi:fastutil</artifact>
|
||||||
@ -142,6 +141,16 @@
|
|||||||
</excludes>
|
</excludes>
|
||||||
</filter>
|
</filter>
|
||||||
</filters>
|
</filters>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>it.unimi.dsi.fastutil</pattern>
|
||||||
|
<shadedPattern>com.viaversion.libs.fastutil</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>com.google.gson</pattern>
|
||||||
|
<shadedPattern>com.viaversion.libs.libs.gson</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.viaversion.mappingsgenerator;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.NBTIO;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.viaversion.mappingsgenerator.util.JsonConverter;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public final class CursedMappings {
|
||||||
|
|
||||||
|
public static void optimizeAndSaveOhSoSpecial1_12AsNBT() throws IOException {
|
||||||
|
final JsonObject unmappedObject = MappingsLoader.load("mapping-1.12.json");
|
||||||
|
final JsonObject mappedObject = MappingsLoader.load("mapping-1.13.json");
|
||||||
|
final CompoundTag tag = new CompoundTag();
|
||||||
|
tag.put("v", new IntTag(MappingsOptimizer.VERSION));
|
||||||
|
MappingsOptimizer.handleUnknownFields(tag, unmappedObject);
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, null, "blocks", "blockstates", "blockstates", 4084);
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, null, "items", "items", "items", unmappedObject.getAsJsonObject("items").size());
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, null, "legacy_enchantments", "enchantments", "enchantments", 72);
|
||||||
|
MappingsOptimizer.mappings(tag, unmappedObject, mappedObject, null, true, false, "sounds");
|
||||||
|
NBTIO.writeFile(tag, new File(MappingsOptimizer.OUTPUT_DIR, "mappings-1.12to1.13.nbt"), false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void optimizeAndSaveOhSoSpecial1_12AsNBTBackwards() throws IOException {
|
||||||
|
final JsonObject unmappedObject = MappingsLoader.load("mapping-1.13.json");
|
||||||
|
final JsonObject mappedObject = MappingsLoader.load("mapping-1.12.json");
|
||||||
|
final JsonObject diffObject = MappingsLoader.load("mappingdiff-1.13to1.12.json");
|
||||||
|
final CompoundTag tag = new CompoundTag();
|
||||||
|
tag.put("v", new IntTag(MappingsOptimizer.VERSION));
|
||||||
|
MappingsOptimizer.handleUnknownFields(tag, unmappedObject);
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "blockstates", "blocks", "blockstates", 8582);
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "items", "items", "items", unmappedObject.getAsJsonArray("items").size());
|
||||||
|
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "enchantments", "legacy_enchantments", "enchantments", unmappedObject.getAsJsonArray("enchantments").size());
|
||||||
|
MappingsOptimizer.names(tag, unmappedObject, diffObject, "items", "itemnames");
|
||||||
|
MappingsOptimizer.fullNames(tag, diffObject, "entitynames", "entitynames");
|
||||||
|
MappingsOptimizer.fullNames(tag, diffObject, "sounds", "soundnames");
|
||||||
|
MappingsOptimizer.mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "sounds");
|
||||||
|
NBTIO.writeFile(tag, new File(MappingsOptimizer.OUTPUT_BACKWARDS_DIR, "mappings-1.13to1.12.nbt"), false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cursedMappings(
|
||||||
|
final CompoundTag tag,
|
||||||
|
final JsonObject unmappedObject,
|
||||||
|
final JsonObject mappedObject,
|
||||||
|
@Nullable final JsonObject diffObject,
|
||||||
|
final String unmappedKey,
|
||||||
|
final String mappedKey,
|
||||||
|
final String outputKey,
|
||||||
|
final int size
|
||||||
|
) {
|
||||||
|
final JsonObject mappedIdentifiers = JsonConverter.toJsonObject(mappedObject.get(mappedKey));
|
||||||
|
final Int2IntMap map = MappingsLoader.map(
|
||||||
|
JsonConverter.toJsonObject(unmappedObject.get(unmappedKey)),
|
||||||
|
mappedIdentifiers,
|
||||||
|
diffObject != null ? diffObject.getAsJsonObject(unmappedKey) : null,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
final CompoundTag changedTag = new CompoundTag();
|
||||||
|
final int[] unmapped = new int[map.size()];
|
||||||
|
final int[] mapped = new int[map.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (final Int2IntMap.Entry entry : map.int2IntEntrySet()) {
|
||||||
|
unmapped[i] = entry.getIntKey();
|
||||||
|
mapped[i] = entry.getIntValue();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
changedTag.put("id", new ByteTag(MappingsOptimizer.CHANGES_ID));
|
||||||
|
changedTag.put("nofill", new ByteTag((byte) 1));
|
||||||
|
changedTag.put("size", new IntTag(size));
|
||||||
|
changedTag.put("mappedSize", new IntTag(mappedIdentifiers.size()));
|
||||||
|
changedTag.put("at", new IntArrayTag(unmapped));
|
||||||
|
changedTag.put("val", new IntArrayTag(mapped));
|
||||||
|
tag.put(outputKey, changedTag);
|
||||||
|
}
|
||||||
|
}
|
@ -24,19 +24,65 @@ import com.google.gson.JsonArray;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.viaversion.mappingsgenerator.util.ServerJarUtil;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import org.slf4j.Logger;
|
||||||
public final class MappingsGenerator {
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For in-IDE execution.
|
* Mappings generator to collect certain json mappings from the server jar.
|
||||||
|
*
|
||||||
|
* @see MappingsOptimizer for the compacting process
|
||||||
*/
|
*/
|
||||||
|
public final class MappingsGenerator {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MappingsGenerator.class.getSimpleName());
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
|
if (args.length != 2 && args.length != 3) {
|
||||||
|
throw new IllegalArgumentException("Required args: path to server jar, version");
|
||||||
|
}
|
||||||
|
|
||||||
|
MappingsGenerator.cleanup();
|
||||||
|
|
||||||
|
final String serverPath = args[0];
|
||||||
|
final String version = args[1];
|
||||||
|
final String versionToCompareFrom = args.length == 3 ? args[2] : null;
|
||||||
|
|
||||||
|
final File serverFile = new File(serverPath);
|
||||||
|
if (!serverFile.exists()) {
|
||||||
|
LOGGER.error("Server file does not exist at {}", serverFile);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Loading net.minecraft.data.Main class...");
|
||||||
|
final ClassLoader loader = URLClassLoader.newInstance(
|
||||||
|
new URL[]{serverFile.toURI().toURL()},
|
||||||
|
MappingsGenerator.class.getClassLoader()
|
||||||
|
);
|
||||||
|
|
||||||
|
final String[] serverArgs = {"--reports"};
|
||||||
|
final Object serverMainConstructor = ServerJarUtil.loadMain(loader).getConstructor().newInstance();
|
||||||
|
serverMainConstructor.getClass().getDeclaredMethod("main", String[].class).invoke(null, (Object) serverArgs);
|
||||||
|
|
||||||
|
ServerJarUtil.waitForServerMain();
|
||||||
|
|
||||||
|
MappingsGenerator.collectMappings(version);
|
||||||
|
|
||||||
|
if (versionToCompareFrom != null) {
|
||||||
|
LOGGER.info("Running mappings optimizer for versions {} -> {}...", versionToCompareFrom, version);
|
||||||
|
MappingsOptimizer.optimizeAndSaveAsNBT(versionToCompareFrom, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static void main(final String[] args) throws Exception {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -51,15 +97,25 @@ public final class MappingsGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
collectMappings("23w08a");
|
collectMappings("23w08a");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the previous generated and logs directories.
|
||||||
|
*/
|
||||||
public static void cleanup() {
|
public static void cleanup() {
|
||||||
delete(new File("generated"));
|
delete(new File("generated"));
|
||||||
delete(new File("logs"));
|
delete(new File("logs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively deletes a directory or file.
|
||||||
|
*
|
||||||
|
* @param file file or directory to delete
|
||||||
|
*/
|
||||||
public static void delete(final File file) {
|
public static void delete(final File file) {
|
||||||
if (!file.exists()) return;
|
if (!file.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
for (final File f : file.listFiles()) {
|
for (final File f : file.listFiles()) {
|
||||||
delete(f);
|
delete(f);
|
||||||
@ -69,18 +125,20 @@ public final class MappingsGenerator {
|
|||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects registry mappings for the given Minecraft version and saves them to a json file.
|
||||||
|
*
|
||||||
|
* @param version Minecraft version
|
||||||
|
*/
|
||||||
public static void collectMappings(final String version) throws IOException {
|
public static void collectMappings(final String version) throws IOException {
|
||||||
System.out.println("Beginning mapping collection...");
|
LOGGER.info("Beginning mapping collection...");
|
||||||
String content = new String(Files.readAllBytes(new File("generated/reports/blocks.json").toPath()));
|
|
||||||
|
|
||||||
final Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
final Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||||
JsonObject object = gson.fromJson(content, JsonObject.class);
|
final String blocksContent = new String(Files.readAllBytes(new File("generated/reports/blocks.json").toPath()));
|
||||||
|
final JsonObject blocksObject = gson.fromJson(blocksContent, JsonObject.class);
|
||||||
final JsonObject viaMappings = new JsonObject();
|
|
||||||
|
|
||||||
// Blocks and blockstates
|
// Blocks and blockstates
|
||||||
final Map<Integer, String> blockstatesById = new TreeMap<>();
|
final Map<Integer, String> blockstatesById = new TreeMap<>();
|
||||||
for (final Map.Entry<String, JsonElement> blocksEntry : object.entrySet()) {
|
for (final Map.Entry<String, JsonElement> blocksEntry : blocksObject.entrySet()) {
|
||||||
final JsonObject block = blocksEntry.getValue().getAsJsonObject();
|
final JsonObject block = blocksEntry.getValue().getAsJsonObject();
|
||||||
final JsonArray states = block.getAsJsonArray("states");
|
final JsonArray states = block.getAsJsonArray("states");
|
||||||
for (final JsonElement state : states) {
|
for (final JsonElement state : states) {
|
||||||
@ -90,27 +148,13 @@ public final class MappingsGenerator {
|
|||||||
throw new IllegalArgumentException("Duplicate blockstate id: " + id);
|
throw new IllegalArgumentException("Duplicate blockstate id: " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder value = new StringBuilder(removeNamespace(blocksEntry.getKey()));
|
blockstatesById.put(id, serializeBlockState(blocksEntry.getKey(), stateObject));
|
||||||
if (stateObject.has("properties")) {
|
|
||||||
value.append('[');
|
|
||||||
final JsonObject properties = stateObject.getAsJsonObject("properties");
|
|
||||||
boolean first = true;
|
|
||||||
for (final Map.Entry<String, JsonElement> propertyEntry : properties.entrySet()) {
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
value.append(',');
|
|
||||||
}
|
|
||||||
value.append(propertyEntry.getKey()).append('=').append(propertyEntry.getValue().getAsJsonPrimitive().getAsString());
|
|
||||||
}
|
|
||||||
value.append(']');
|
|
||||||
}
|
|
||||||
blockstatesById.put(id, value.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final JsonArray blockstates = new JsonArray();
|
final JsonArray blockstates = new JsonArray();
|
||||||
final JsonArray blocks = new JsonArray();
|
final JsonArray blocks = new JsonArray();
|
||||||
|
final JsonObject viaMappings = new JsonObject();
|
||||||
viaMappings.add("blockstates", blockstates);
|
viaMappings.add("blockstates", blockstates);
|
||||||
viaMappings.add("blocks", blocks);
|
viaMappings.add("blocks", blocks);
|
||||||
|
|
||||||
@ -126,18 +170,17 @@ public final class MappingsGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content = new String(Files.readAllBytes(new File("generated/reports/registries.json").toPath()));
|
final String registriesContent = new String(Files.readAllBytes(new File("generated/reports/registries.json").toPath()));
|
||||||
object = gson.fromJson(content, JsonObject.class);
|
final JsonObject registries = gson.fromJson(registriesContent, JsonObject.class);
|
||||||
|
addArray(viaMappings, registries, "minecraft:item", "items");
|
||||||
addArray(viaMappings, object, "minecraft:item", "items");
|
addArray(viaMappings, registries, "minecraft:sound_event", "sounds");
|
||||||
addArray(viaMappings, object, "minecraft:sound_event", "sounds");
|
addArray(viaMappings, registries, "minecraft:particle_type", "particles");
|
||||||
addArray(viaMappings, object, "minecraft:particle_type", "particles");
|
addArray(viaMappings, registries, "minecraft:block_entity_type", "blockentities");
|
||||||
addArray(viaMappings, object, "minecraft:block_entity_type", "blockentities");
|
addArray(viaMappings, registries, "minecraft:command_argument_type", "argumenttypes");
|
||||||
addArray(viaMappings, object, "minecraft:command_argument_type", "argumenttypes");
|
addArray(viaMappings, registries, "minecraft:enchantment", "enchantments");
|
||||||
addArray(viaMappings, object, "minecraft:enchantment", "enchantments");
|
addArray(viaMappings, registries, "minecraft:entity_type", "entities");
|
||||||
addArray(viaMappings, object, "minecraft:entity_type", "entities");
|
addArray(viaMappings, registries, "minecraft:motive", "paintings");
|
||||||
addArray(viaMappings, object, "minecraft:motive", "paintings");
|
addArray(viaMappings, registries, "minecraft:painting_variant", "paintings");
|
||||||
addArray(viaMappings, object, "minecraft:painting_variant", "paintings");
|
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
new File("mappings").mkdir();
|
new File("mappings").mkdir();
|
||||||
@ -146,16 +189,53 @@ public final class MappingsGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new File("logs").deleteOnExit();
|
new File("logs").deleteOnExit();
|
||||||
System.out.println("Done!");
|
LOGGER.info("Mapping file has been written to mappings/mapping-{}.json", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a blockstate string for the given block and properties.
|
||||||
|
*
|
||||||
|
* @param block block identifier
|
||||||
|
* @param blockObject json object holding properties
|
||||||
|
* @return blockstate identifier
|
||||||
|
*/
|
||||||
|
private static String serializeBlockState(String block, final JsonObject blockObject) {
|
||||||
|
block = removeNamespace(block);
|
||||||
|
if (!blockObject.has("properties")) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder value = new StringBuilder(block);
|
||||||
|
value.append('[');
|
||||||
|
final JsonObject properties = blockObject.getAsJsonObject("properties");
|
||||||
|
boolean first = true;
|
||||||
|
for (final Map.Entry<String, JsonElement> propertyEntry : properties.entrySet()) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
value.append(',');
|
||||||
|
}
|
||||||
|
value.append(propertyEntry.getKey()).append('=').append(propertyEntry.getValue().getAsJsonPrimitive().getAsString());
|
||||||
|
}
|
||||||
|
value.append(']');
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds array mappings from a registry to the mappings object.
|
||||||
|
*
|
||||||
|
* @param mappings mappings to add to
|
||||||
|
* @param registry registry to read from
|
||||||
|
* @param registryKey registry key to read from
|
||||||
|
* @param mappingsKey mappings key to write to
|
||||||
|
*/
|
||||||
private static void addArray(final JsonObject mappings, final JsonObject registry, final String registryKey, final String mappingsKey) {
|
private static void addArray(final JsonObject mappings, final JsonObject registry, final String registryKey, final String mappingsKey) {
|
||||||
if (!registry.has(registryKey)) {
|
if (!registry.has(registryKey)) {
|
||||||
System.out.println("Ignoring missing registry: " + registryKey);
|
LOGGER.debug("Ignoring missing registry: {}", registryKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Collecting " + registryKey + "...");
|
LOGGER.debug("Collecting {}...", registryKey);
|
||||||
final JsonObject entries = registry.getAsJsonObject(registryKey).getAsJsonObject("entries");
|
final JsonObject entries = registry.getAsJsonObject(registryKey).getAsJsonObject("entries");
|
||||||
final String[] keys = new String[entries.size()];
|
final String[] keys = new String[entries.size()];
|
||||||
for (final Map.Entry<String, JsonElement> entry : entries.entrySet()) {
|
for (final Map.Entry<String, JsonElement> entry : entries.entrySet()) {
|
||||||
@ -177,6 +257,12 @@ public final class MappingsGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the Minecraft namespace from a potentially namespaced key.
|
||||||
|
*
|
||||||
|
* @param key key to remove the namespace from
|
||||||
|
* @return key without the Minecraft namespace
|
||||||
|
*/
|
||||||
private static String removeNamespace(final String key) {
|
private static String removeNamespace(final String key) {
|
||||||
if (key.startsWith("minecraft:")) {
|
if (key.startsWith("minecraft:")) {
|
||||||
return key.substring("minecraft:".length());
|
return key.substring("minecraft:".length());
|
||||||
|
@ -29,9 +29,9 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.viaversion.mappingsgenerator.MappingsLoader.MappingsResult;
|
||||||
import com.viaversion.mappingsgenerator.util.JsonConverter;
|
import com.viaversion.mappingsgenerator.util.JsonConverter;
|
||||||
import com.viaversion.mappingsgenerator.util.Version;
|
import com.viaversion.mappingsgenerator.util.Version;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -45,19 +45,22 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizes mapping files as nbt files with only the necessary data (mostly int to int mappings in form of int arrays).
|
||||||
|
*/
|
||||||
public final class MappingsOptimizer {
|
public final class MappingsOptimizer {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MappingsOptimizer.class.getSimpleName());
|
public static final int VERSION = 1;
|
||||||
|
public static final byte DIRECT_ID = 0;
|
||||||
|
public static final byte SHIFTS_ID = 1;
|
||||||
|
public static final byte CHANGES_ID = 2;
|
||||||
|
public static final byte IDENTITY_ID = 3;
|
||||||
|
public static final File MAPPINGS_DIR = new File("mappings");
|
||||||
public static final File OUTPUT_DIR = new File("output");
|
public static final File OUTPUT_DIR = new File("output");
|
||||||
public static final File OUTPUT_BACKWARDS_DIR = new File(OUTPUT_DIR, "backwards");
|
public static final File OUTPUT_BACKWARDS_DIR = new File(OUTPUT_DIR, "backwards");
|
||||||
public static final File MAPPINGS_DIR = new File("mappings");
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MappingsOptimizer.class.getSimpleName());
|
||||||
private static final Set<String> STANDARD_FIELDS = Set.of("blockstates", "blocks", "items", "sounds", "blockentities", "enchantments", "paintings", "entities", "particles", "argumenttypes", "statistics", "tags");
|
private static final Set<String> STANDARD_FIELDS = Set.of("blockstates", "blocks", "items", "sounds", "blockentities", "enchantments", "paintings", "entities", "particles", "argumenttypes", "statistics", "tags");
|
||||||
private static final Set<String> STANDARD_DIFF_FIELDS = Set.of("itemnames", "entitynames");
|
|
||||||
private static final int VERSION = 1;
|
|
||||||
private static final byte DIRECT_ID = 0;
|
|
||||||
private static final byte SHIFTS_ID = 1;
|
|
||||||
private static final byte CHANGES_ID = 2;
|
|
||||||
private static final byte IDENTITY_ID = 3;
|
|
||||||
private static final String DIFF_FILE_FORMAT = "mappingdiff-%sto%s.json";
|
private static final String DIFF_FILE_FORMAT = "mappingdiff-%sto%s.json";
|
||||||
private static final String MAPPING_FILE_FORMAT = "mapping-%s.json";
|
private static final String MAPPING_FILE_FORMAT = "mapping-%s.json";
|
||||||
private static final String OUTPUT_FILE_FORMAT = "mappings-%sto%s.nbt";
|
private static final String OUTPUT_FILE_FORMAT = "mappings-%sto%s.nbt";
|
||||||
@ -76,7 +79,7 @@ public final class MappingsOptimizer {
|
|||||||
|
|
||||||
final String from = args.length == 2 ? args[0] : "1.12";
|
final String from = args.length == 2 ? args[0] : "1.12";
|
||||||
final String to = args.length == 2 ? args[1] : "1.11";
|
final String to = args.length == 2 ? args[1] : "1.11";
|
||||||
optimizeAndSaveAsNBT(from, to, OUTPUT_DIR);
|
optimizeAndSaveAsNBT(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +88,8 @@ public final class MappingsOptimizer {
|
|||||||
* @param from version to map from
|
* @param from version to map from
|
||||||
* @param to version to map to
|
* @param to version to map to
|
||||||
*/
|
*/
|
||||||
private static void optimizeAndSaveAsNBT(final String from, final String to, final File outputDir) throws IOException {
|
public static void optimizeAndSaveAsNBT(final String from, final String to) throws IOException {
|
||||||
|
LOGGER.info("Compacting json mapping files for versions {} -> {}...", to, from);
|
||||||
final JsonObject unmappedObject = MappingsLoader.load(MAPPING_FILE_FORMAT.formatted(from));
|
final JsonObject unmappedObject = MappingsLoader.load(MAPPING_FILE_FORMAT.formatted(from));
|
||||||
final JsonObject mappedObject = MappingsLoader.load(MAPPING_FILE_FORMAT.formatted(to));
|
final JsonObject mappedObject = MappingsLoader.load(MAPPING_FILE_FORMAT.formatted(to));
|
||||||
final JsonObject diffObject = MappingsLoader.load(DIFF_FILE_FORMAT.formatted(from, to));
|
final JsonObject diffObject = MappingsLoader.load(DIFF_FILE_FORMAT.formatted(from, to));
|
||||||
@ -112,12 +116,15 @@ public final class MappingsOptimizer {
|
|||||||
mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "particles");
|
mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "particles");
|
||||||
mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "argumenttypes");
|
mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "argumenttypes");
|
||||||
mappings(tag, unmappedObject, mappedObject, diffObject, false, false, "statistics");
|
mappings(tag, unmappedObject, mappedObject, diffObject, false, false, "statistics");
|
||||||
|
|
||||||
if (diffObject != null) {
|
if (diffObject != null) {
|
||||||
names(tag, unmappedObject, diffObject, "items", "itemnames");
|
names(tag, unmappedObject, diffObject, "items", "itemnames");
|
||||||
fullNames(tag, diffObject, "entitynames", "entitynames");
|
fullNames(tag, diffObject, "entitynames", "entitynames");
|
||||||
if (outputDir == OUTPUT_BACKWARDS_DIR) { // EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
|
||||||
|
if (Version.isBackwards(from, to)) {
|
||||||
fullNames(tag, diffObject, "sounds", "soundnames");
|
fullNames(tag, diffObject, "sounds", "soundnames");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diffObject.has("tags")) {
|
if (diffObject.has("tags")) {
|
||||||
final CompoundTag tagsTag = new CompoundTag();
|
final CompoundTag tagsTag = new CompoundTag();
|
||||||
tags(tagsTag, mappedObject, diffObject);
|
tags(tagsTag, mappedObject, diffObject);
|
||||||
@ -125,6 +132,7 @@ public final class MappingsOptimizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final File outputDir = Version.isBackwards(from, to) ? OUTPUT_BACKWARDS_DIR : OUTPUT_DIR;
|
||||||
NBTIO.writeFile(tag, new File(outputDir, OUTPUT_FILE_FORMAT.formatted(from, to)), false, false);
|
NBTIO.writeFile(tag, new File(outputDir, OUTPUT_FILE_FORMAT.formatted(from, to)), false, false);
|
||||||
|
|
||||||
// Save full identifiers to a separate file per version
|
// Save full identifiers to a separate file per version
|
||||||
@ -142,37 +150,13 @@ public final class MappingsOptimizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void optimizeAndSaveOhSoSpecial1_12AsNBT() throws IOException {
|
/**
|
||||||
final JsonObject unmappedObject = MappingsLoader.load("mapping-1.12.json");
|
* Checks for unknown fields in the unmapped object and writes them to the tag unchanged.
|
||||||
final JsonObject mappedObject = MappingsLoader.load("mapping-1.13.json");
|
*
|
||||||
final CompoundTag tag = new CompoundTag();
|
* @param tag tag to write to
|
||||||
tag.put("v", new IntTag(VERSION));
|
* @param unmappedObject unmapped object to check all fields from
|
||||||
handleUnknownFields(tag, unmappedObject);
|
*/
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, null, "blocks", "blockstates", "blockstates", 4084);
|
public static void handleUnknownFields(final CompoundTag tag, final JsonObject unmappedObject) {
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, null, "items", "items", "items", unmappedObject.getAsJsonObject("items").size());
|
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, null, "legacy_enchantments", "enchantments", "enchantments", 72);
|
|
||||||
mappings(tag, unmappedObject, mappedObject, null, true, false, "sounds");
|
|
||||||
NBTIO.writeFile(tag, new File(OUTPUT_DIR, "mappings-1.12to1.13.nbt"), false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void optimizeAndSaveOhSoSpecial1_12AsNBTBackwards() throws IOException {
|
|
||||||
final JsonObject unmappedObject = MappingsLoader.load("mapping-1.13.json");
|
|
||||||
final JsonObject mappedObject = MappingsLoader.load("mapping-1.12.json");
|
|
||||||
final JsonObject diffObject = MappingsLoader.load("mappingdiff-1.13to1.12.json");
|
|
||||||
final CompoundTag tag = new CompoundTag();
|
|
||||||
tag.put("v", new IntTag(VERSION));
|
|
||||||
handleUnknownFields(tag, unmappedObject);
|
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "blockstates", "blocks", "blockstates", 8582);
|
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "items", "items", "items", unmappedObject.getAsJsonArray("items").size());
|
|
||||||
cursedMappings(tag, unmappedObject, mappedObject, diffObject, "enchantments", "legacy_enchantments", "enchantments", unmappedObject.getAsJsonArray("enchantments").size());
|
|
||||||
names(tag, unmappedObject, diffObject, "items", "itemnames");
|
|
||||||
fullNames(tag, diffObject, "entitynames", "entitynames");
|
|
||||||
fullNames(tag, diffObject, "sounds", "soundnames");
|
|
||||||
mappings(tag, unmappedObject, mappedObject, diffObject, true, false, "sounds");
|
|
||||||
NBTIO.writeFile(tag, new File(OUTPUT_BACKWARDS_DIR, "mappings-1.13to1.12.nbt"), false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleUnknownFields(final CompoundTag tag, final JsonObject unmappedObject) {
|
|
||||||
for (final String key : unmappedObject.keySet()) {
|
for (final String key : unmappedObject.keySet()) {
|
||||||
if (STANDARD_FIELDS.contains(key)) {
|
if (STANDARD_FIELDS.contains(key)) {
|
||||||
continue;
|
continue;
|
||||||
@ -192,28 +176,26 @@ public final class MappingsOptimizer {
|
|||||||
for (final File file : MAPPINGS_DIR.listFiles()) {
|
for (final File file : MAPPINGS_DIR.listFiles()) {
|
||||||
final String name = file.getName();
|
final String name = file.getName();
|
||||||
if (name.startsWith("mapping-")) {
|
if (name.startsWith("mapping-")) {
|
||||||
versions.add(name.substring("mapping-".length(), name.length() - ".json".length()));
|
final String version = name.substring("mapping-".length(), name.length() - ".json".length());
|
||||||
|
versions.add(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
versions.sort(Comparator.comparing(Version::new));
|
versions.sort(Comparator.comparing(Version::new));
|
||||||
|
|
||||||
for (int i = 0; i < versions.size() - 1; i++) {
|
for (int i = 0; i < versions.size() - 1; i++) {
|
||||||
final String from = versions.get(i);
|
final String from = versions.get(i);
|
||||||
final String to = versions.get(i + 1);
|
final String to = versions.get(i + 1);
|
||||||
LOGGER.info("=============================");
|
LOGGER.info("=============================");
|
||||||
LOGGER.info("Running {} to {}", from, to);
|
|
||||||
if (from.equals("1.12") && to.equals("1.13")) {
|
if (from.equals("1.12") && to.equals("1.13")) {
|
||||||
optimizeAndSaveOhSoSpecial1_12AsNBT();
|
CursedMappings.optimizeAndSaveOhSoSpecial1_12AsNBT();
|
||||||
LOGGER.info("Running {} to {}", to, from);
|
CursedMappings.optimizeAndSaveOhSoSpecial1_12AsNBTBackwards();
|
||||||
optimizeAndSaveOhSoSpecial1_12AsNBTBackwards();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
optimizeAndSaveAsNBT(from, to, OUTPUT_DIR);
|
optimizeAndSaveAsNBT(from, to);
|
||||||
|
|
||||||
LOGGER.info("-----------------------------");
|
LOGGER.info("-----------------------------");
|
||||||
LOGGER.info("Running {} to {}", to, from);
|
optimizeAndSaveAsNBT(to, from);
|
||||||
optimizeAndSaveAsNBT(to, from, OUTPUT_BACKWARDS_DIR);
|
|
||||||
LOGGER.info("");
|
LOGGER.info("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +211,7 @@ public final class MappingsOptimizer {
|
|||||||
* @param alwaysWriteIdentity whether to always write the identity mapping with size and mapped size, even if the two arrays are equal
|
* @param alwaysWriteIdentity whether to always write the identity mapping with size and mapped size, even if the two arrays are equal
|
||||||
* @param key to read from and write to
|
* @param key to read from and write to
|
||||||
*/
|
*/
|
||||||
private static void mappings(
|
public static void mappings(
|
||||||
final CompoundTag tag,
|
final CompoundTag tag,
|
||||||
final JsonObject unmappedObject,
|
final JsonObject unmappedObject,
|
||||||
final JsonObject mappedObject,
|
final JsonObject mappedObject,
|
||||||
@ -250,48 +232,19 @@ public final class MappingsOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final JsonObject diffIdentifiers = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
|
final JsonObject diffIdentifiers = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
|
||||||
final MappingsLoader.MappingsResult result = MappingsLoader.map(unmappedIdentifiers, mappedIdentifiers, diffIdentifiers, warnOnMissing);
|
final MappingsResult result = MappingsLoader.map(unmappedIdentifiers, mappedIdentifiers, diffIdentifiers, warnOnMissing);
|
||||||
serialize(result, tag, key, alwaysWriteIdentity);
|
serialize(result, tag, key, alwaysWriteIdentity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cursedMappings(
|
/**
|
||||||
final CompoundTag tag,
|
* Writes int->string mappings to the given tag.
|
||||||
final JsonObject unmappedObject,
|
*
|
||||||
final JsonObject mappedObject,
|
* @param data tag to write to
|
||||||
@Nullable final JsonObject diffObject,
|
* @param diffObject diff mappings object
|
||||||
final String unmappedKey,
|
* @param key key to read identifiers from
|
||||||
final String mappedKey,
|
* @param namesKey key to read names from and to write to
|
||||||
final String outputKey,
|
*/
|
||||||
final int size
|
public static void names(
|
||||||
) {
|
|
||||||
final JsonObject mappedIdentifiers = JsonConverter.toJsonObject(mappedObject.get(mappedKey));
|
|
||||||
final Int2IntMap map = MappingsLoader.map(
|
|
||||||
JsonConverter.toJsonObject(unmappedObject.get(unmappedKey)),
|
|
||||||
mappedIdentifiers,
|
|
||||||
diffObject != null ? diffObject.getAsJsonObject(unmappedKey) : null,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
final CompoundTag changedTag = new CompoundTag();
|
|
||||||
final int[] unmapped = new int[map.size()];
|
|
||||||
final int[] mapped = new int[map.size()];
|
|
||||||
int i = 0;
|
|
||||||
for (final Int2IntMap.Entry entry : map.int2IntEntrySet()) {
|
|
||||||
unmapped[i] = entry.getIntKey();
|
|
||||||
mapped[i] = entry.getIntValue();
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
changedTag.put("id", new ByteTag(CHANGES_ID));
|
|
||||||
changedTag.put("nofill", new ByteTag((byte) 1));
|
|
||||||
changedTag.put("size", new IntTag(size));
|
|
||||||
changedTag.put("mappedSize", new IntTag(mappedIdentifiers.size()));
|
|
||||||
changedTag.put("at", new IntArrayTag(unmapped));
|
|
||||||
changedTag.put("val", new IntArrayTag(mapped));
|
|
||||||
tag.put(outputKey, changedTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void names(
|
|
||||||
final CompoundTag data,
|
final CompoundTag data,
|
||||||
final JsonObject object,
|
final JsonObject object,
|
||||||
final JsonObject diffObject,
|
final JsonObject diffObject,
|
||||||
@ -313,7 +266,15 @@ public final class MappingsOptimizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fullNames(
|
/**
|
||||||
|
* Writes string->string mappings to the given tag.
|
||||||
|
*
|
||||||
|
* @param data tag to write to
|
||||||
|
* @param diffObject diff mappings object
|
||||||
|
* @param key key to read from
|
||||||
|
* @param outputKey key to write to
|
||||||
|
*/
|
||||||
|
public static void fullNames(
|
||||||
final CompoundTag data,
|
final CompoundTag data,
|
||||||
final JsonObject diffObject,
|
final JsonObject diffObject,
|
||||||
final String key,
|
final String key,
|
||||||
@ -409,7 +370,7 @@ public final class MappingsOptimizer {
|
|||||||
* @param key key to write to
|
* @param key key to write to
|
||||||
* @param alwaysWriteIdentity whether to write identity mappings even if there are no changes
|
* @param alwaysWriteIdentity whether to write identity mappings even if there are no changes
|
||||||
*/
|
*/
|
||||||
private static void serialize(final MappingsLoader.MappingsResult result, final CompoundTag parent, final String key, boolean alwaysWriteIdentity) {
|
private static void serialize(final MappingsResult result, final CompoundTag parent, final String key, final boolean alwaysWriteIdentity) {
|
||||||
final int[] mappings = result.mappings();
|
final int[] mappings = result.mappings();
|
||||||
final int numberOfChanges = mappings.length - result.identityMappings();
|
final int numberOfChanges = mappings.length - result.identityMappings();
|
||||||
final boolean hasChanges = numberOfChanges != 0 || result.emptyMappings() != 0;
|
final boolean hasChanges = numberOfChanges != 0 || result.emptyMappings() != 0;
|
||||||
@ -432,8 +393,28 @@ public final class MappingsOptimizer {
|
|||||||
final int shiftFormatSize = approximateShiftFormatSize(result);
|
final int shiftFormatSize = approximateShiftFormatSize(result);
|
||||||
final int plainFormatSize = mappings.length;
|
final int plainFormatSize = mappings.length;
|
||||||
if (changedFormatSize < plainFormatSize && changedFormatSize < shiftFormatSize) {
|
if (changedFormatSize < plainFormatSize && changedFormatSize < shiftFormatSize) {
|
||||||
|
writeChangedFormat(tag, result, key, numberOfChanges);
|
||||||
|
} else if (shiftFormatSize < changedFormatSize && shiftFormatSize < plainFormatSize) {
|
||||||
|
writeShiftFormat(tag, result, key);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("{}: Storing as direct values", key);
|
||||||
|
tag.put("id", new ByteTag(DIRECT_ID));
|
||||||
|
tag.put("val", new IntArrayTag(mappings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes compact int to int mappings as changed values to the given tag.
|
||||||
|
*
|
||||||
|
* @param tag tag to write to
|
||||||
|
* @param result result with int to int mappings
|
||||||
|
* @param key key to write to
|
||||||
|
* @param numberOfChanges number of changed mappings
|
||||||
|
*/
|
||||||
|
private static void writeChangedFormat(final CompoundTag tag, final MappingsResult result, final String key, final int numberOfChanges) {
|
||||||
// Put two intarrays of only changed ids instead of adding an entry for every single identifier
|
// Put two intarrays of only changed ids instead of adding an entry for every single identifier
|
||||||
LOGGER.debug("{}: Storing as changed and mapped arrays", key);
|
LOGGER.debug("{}: Storing as changed and mapped arrays", key);
|
||||||
|
final int[] mappings = result.mappings();
|
||||||
tag.put("id", new ByteTag(CHANGES_ID));
|
tag.put("id", new ByteTag(CHANGES_ID));
|
||||||
tag.put("size", new IntTag(mappings.length));
|
tag.put("size", new IntTag(mappings.length));
|
||||||
|
|
||||||
@ -455,8 +436,18 @@ public final class MappingsOptimizer {
|
|||||||
|
|
||||||
tag.put("at", new IntArrayTag(unmapped));
|
tag.put("at", new IntArrayTag(unmapped));
|
||||||
tag.put("val", new IntArrayTag(mapped));
|
tag.put("val", new IntArrayTag(mapped));
|
||||||
} else if (shiftFormatSize < changedFormatSize && shiftFormatSize < plainFormatSize) {
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes compact int to int mappings as shifted values to the given tag.
|
||||||
|
*
|
||||||
|
* @param tag tag to write to
|
||||||
|
* @param result result with int to int mappings
|
||||||
|
* @param key key to write to
|
||||||
|
*/
|
||||||
|
private static void writeShiftFormat(final CompoundTag tag, final MappingsResult result, final String key) {
|
||||||
LOGGER.debug("{}: Storing as shifts", key);
|
LOGGER.debug("{}: Storing as shifts", key);
|
||||||
|
final int[] mappings = result.mappings();
|
||||||
tag.put("id", new ByteTag(SHIFTS_ID));
|
tag.put("id", new ByteTag(SHIFTS_ID));
|
||||||
tag.put("size", new IntTag(mappings.length));
|
tag.put("size", new IntTag(mappings.length));
|
||||||
|
|
||||||
@ -486,19 +477,14 @@ public final class MappingsOptimizer {
|
|||||||
|
|
||||||
tag.put("at", new IntArrayTag(shiftsAt));
|
tag.put("at", new IntArrayTag(shiftsAt));
|
||||||
tag.put("to", new IntArrayTag(shiftsTo));
|
tag.put("to", new IntArrayTag(shiftsTo));
|
||||||
} else {
|
|
||||||
LOGGER.debug("{}: Storing as direct values", key);
|
|
||||||
tag.put("id", new ByteTag(DIRECT_ID));
|
|
||||||
tag.put("val", new IntArrayTag(mappings));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int approximateChangedFormatSize(final MappingsLoader.MappingsResult result) {
|
private static int approximateChangedFormatSize(final MappingsResult result) {
|
||||||
// Length of two arrays + more approximate length for extra tags
|
// Length of two arrays + more approximate length for extra tags
|
||||||
return (result.mappings().length - result.identityMappings()) * 2 + 10;
|
return (result.mappings().length - result.identityMappings()) * 2 + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int approximateShiftFormatSize(final MappingsLoader.MappingsResult result) {
|
private static int approximateShiftFormatSize(final MappingsResult result) {
|
||||||
// One entry in two arrays each time the id is not shifted by 1 from the last id + more approximate length for extra tags
|
// 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;
|
return result.shiftChanges() * 2 + 10;
|
||||||
}
|
}
|
||||||
|
@ -16,45 +16,14 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.viaversion.mappingsgenerator;
|
package com.viaversion.mappingsgenerator.util;
|
||||||
|
|
||||||
import java.io.File;
|
import org.slf4j.Logger;
|
||||||
import java.net.URL;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
|
|
||||||
public final class Main {
|
public final class ServerJarUtil {
|
||||||
|
|
||||||
private static final String[] ARGS = {"--reports"};
|
private static final Logger LOGGER = LoggerFactory.getLogger(ServerJarUtil.class.getSimpleName());
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
|
||||||
if (args.length != 2) {
|
|
||||||
throw new IllegalArgumentException("Required args: path to server jar, version");
|
|
||||||
}
|
|
||||||
|
|
||||||
final String serverPath = args[0];
|
|
||||||
final String version = args[1];
|
|
||||||
MappingsGenerator.cleanup();
|
|
||||||
|
|
||||||
final File serverFile = new File(serverPath);
|
|
||||||
if (!serverFile.exists()) {
|
|
||||||
System.err.println("Server file does not exist at " + serverFile);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Loading net.minecraft.data.Main class...");
|
|
||||||
final ClassLoader loader = URLClassLoader.newInstance(
|
|
||||||
new URL[]{serverFile.toURI().toURL()},
|
|
||||||
Main.class.getClassLoader()
|
|
||||||
);
|
|
||||||
|
|
||||||
final Object o = loadMain(loader).getConstructor().newInstance();
|
|
||||||
final Object[] mainArgs = {ARGS};
|
|
||||||
o.getClass().getDeclaredMethod("main", String[].class).invoke(null, mainArgs);
|
|
||||||
|
|
||||||
waitForServerMain();
|
|
||||||
|
|
||||||
MappingsGenerator.collectMappings(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void waitForServerMain() throws InterruptedException {
|
public static void waitForServerMain() throws InterruptedException {
|
||||||
final Thread serverMain = threadByName("ServerMain");
|
final Thread serverMain = threadByName("ServerMain");
|
||||||
@ -66,7 +35,7 @@ public final class Main {
|
|||||||
while (serverMain.isAlive()) {
|
while (serverMain.isAlive()) {
|
||||||
Thread.sleep(50);
|
Thread.sleep(50);
|
||||||
if (i++ * 50 > 30_000) {
|
if (i++ * 50 > 30_000) {
|
||||||
System.err.println("Something definitely went wrong");
|
LOGGER.error("Something definitely went wrong (waited over 30 seconds for the server main to start)");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +50,7 @@ public final class Main {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<?> loadMain(final ClassLoader classLoader) throws ClassNotFoundException {
|
public static Class<?> loadMain(final ClassLoader classLoader) throws ClassNotFoundException {
|
||||||
System.setProperty("bundlerMainClass", "net.minecraft.data.Main");
|
System.setProperty("bundlerMainClass", "net.minecraft.data.Main");
|
||||||
try {
|
try {
|
||||||
return classLoader.loadClass("net.minecraft.bundler.Main");
|
return classLoader.loadClass("net.minecraft.bundler.Main");
|
@ -45,6 +45,10 @@ public final class Version implements Comparable<Version> {
|
|||||||
tag = matcher.group("tag") == null ? "" : matcher.group("tag");
|
tag = matcher.group("tag") == null ? "" : matcher.group("tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBackwards(final String from, final String to) {
|
||||||
|
return new Version(from).compareTo(new Version(to)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two versions
|
* Compare two versions
|
||||||
*
|
*
|
||||||
@ -67,10 +71,12 @@ public final class Version implements Comparable<Version> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Simple tag check
|
// Simple tag check
|
||||||
if (verA.tag.isEmpty() && !verB.tag.isEmpty())
|
if (verA.tag.isEmpty() && !verB.tag.isEmpty()) {
|
||||||
return 1;
|
return 1;
|
||||||
if (!verA.tag.isEmpty() && verB.tag.isEmpty())
|
}
|
||||||
|
if (!verA.tag.isEmpty() && verB.tag.isEmpty()) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -102,13 +108,4 @@ public final class Version implements Comparable<Version> {
|
|||||||
result = 31 * result + Arrays.hashCode(parts);
|
result = 31 * result + Arrays.hashCode(parts);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tag, eg. -ALPHA
|
|
||||||
*
|
|
||||||
* @return The version tag
|
|
||||||
*/
|
|
||||||
public String getTag() {
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user