mirror of
https://github.com/ViaVersion/Mappings.git
synced 2024-12-04 14:03:26 +01:00
Add some update helper utilities
This commit is contained in:
parent
0a9ae7dc73
commit
fd0a16aaf5
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,6 +2,8 @@ libraries/
|
||||
logs/
|
||||
generated/
|
||||
output/
|
||||
states.txt
|
||||
states_output.txt
|
||||
|
||||
### Java files ###
|
||||
*.class
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.viaversion.mappingsgenerator.helper;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.viaversion.mappingsgenerator.util.GsonUtil;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.viaversion.mappingsgenerator.MappingsOptimizer.MAPPINGS_DIR;
|
||||
|
||||
/**
|
||||
* Similar to {@link BlockStateMapper} in use, except for the array of wood/stone-based building blocks.
|
||||
* <p>
|
||||
* Directly edits the diff file.
|
||||
*/
|
||||
final class AnnoyingBlockStateMapper {
|
||||
|
||||
private static final List<Function<String, String>> MAPPERS = new ArrayList<>();
|
||||
private static final List<String> WONDERFUL_STATES = List.of(
|
||||
"_wood", "_log", "_sapling", "_wall", "_slab", "_stairs",
|
||||
"_trapdoor", "_door", "_button", "_hanging_sign", "_wall_sign", "_sign",
|
||||
"_leaves", "_fence_gate", "_fence", "_pressure_plate"
|
||||
);
|
||||
|
||||
public static void main(final String[] args) throws IOException {
|
||||
// Input examples
|
||||
final String from = "1.21.4";
|
||||
final String to = "1.21.2";
|
||||
replace("resin_brick", "brick");
|
||||
replace("tuff", "andesite");
|
||||
contains("copper", "brick");
|
||||
|
||||
final Path path = MAPPINGS_DIR.resolve("diff").resolve(String.format("mapping-%sto%s.json", from, to));
|
||||
final JsonObject object = GsonUtil.GSON.fromJson(Files.readString(path), JsonObject.class);
|
||||
final JsonObject blockStates = object.getAsJsonObject("blockstates");
|
||||
final JsonObject outputStates = new JsonObject();
|
||||
final Set<String> handled = new HashSet<>();
|
||||
for (final Map.Entry<String, JsonElement> entry : blockStates.entrySet()) {
|
||||
final String value = entry.getValue().getAsString();
|
||||
final String key = entry.getKey();
|
||||
if (!value.isEmpty()) {
|
||||
outputStates.add(key, entry.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
final String keyPart = key.split("\\[")[0];
|
||||
if (handled.contains(keyPart)) {
|
||||
outputStates.add(key, entry.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
final String wonderfulState = WONDERFUL_STATES.stream().filter(keyPart::endsWith).findAny().orElse(null);
|
||||
if (wonderfulState == null) {
|
||||
outputStates.add(key, entry.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
handled.add(key);
|
||||
String outputKey = keyPart.replace(wonderfulState, "");
|
||||
for (final Function<String, String> mapper : MAPPERS) {
|
||||
outputKey = mapper.apply(outputKey);
|
||||
}
|
||||
outputStates.addProperty(keyPart, outputKey + wonderfulState + "[");
|
||||
}
|
||||
|
||||
object.add("blockstates", outputStates);
|
||||
Files.writeString(path, GsonUtil.GSON.toJson(object));
|
||||
}
|
||||
|
||||
private static void equals(final String from, final String to) {
|
||||
MAPPERS.add(s -> s.equals(from) ? to : s);
|
||||
}
|
||||
|
||||
private static void contains(final String from, final String to) {
|
||||
MAPPERS.add(s -> s.contains(from) ? to : s);
|
||||
}
|
||||
|
||||
private static void replace(final String from, final String to) {
|
||||
MAPPERS.add(s -> s.replace(from, to));
|
||||
}
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
package com.viaversion.mappingsgenerator.helper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Utility to more easily map blockstates.
|
||||
* <p>
|
||||
* Copy the stubbed lines from diff mappings into a file called states.txt and update the CONSUMER contents.
|
||||
* Different methods will do different things, the result will be printed to the console.
|
||||
*/
|
||||
final class BlockStateMapper {
|
||||
|
||||
private static final Function<BlockState, BlockState> CONSUMER = state -> {
|
||||
state.addProperty(5, "waterlogged", "false");
|
||||
state.setState("glow_lichen");
|
||||
return state;
|
||||
};
|
||||
|
||||
public static void main(final String[] args) throws IOException {
|
||||
applyFunction();
|
||||
}
|
||||
|
||||
public static void applyFunction() throws IOException {
|
||||
final String content = Files.readString(Path.of("states.txt"));
|
||||
for (final String line : content.split("\n")) {
|
||||
String trimmedLine = line.replace("\"", "").trim();
|
||||
if (trimmedLine.endsWith(": ,")) {
|
||||
trimmedLine = trimmedLine.substring(0, trimmedLine.length() - 3);
|
||||
}
|
||||
|
||||
final BlockState state = new BlockState(trimmedLine);
|
||||
System.out.println("\"" + trimmedLine + "\": \"" + CONSUMER.apply(state) + "\",");
|
||||
}
|
||||
}
|
||||
|
||||
public static void replace(final String... replacements) throws IOException {
|
||||
final String content = Files.readString(Path.of("states.txt"));
|
||||
for (final String line : content.split("\n")) {
|
||||
boolean found = false;
|
||||
for (int i = 0; i < replacements.length; i += 2) {
|
||||
final String from = replacements[i];
|
||||
if (!line.contains(from)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String to = replacements[i + 1];
|
||||
final String[] split = line.split("\": \"", 2);
|
||||
System.out.println(split[0] + "\": \"" + split[1].replace(from, to));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void editKey() throws IOException {
|
||||
final String newName = "dark_oak_slab";
|
||||
final String content = Files.readString(Path.of("states.txt"));
|
||||
for (String line : content.split("\"\",")) {
|
||||
if (line.trim().equals("}")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String firstPart = line;
|
||||
line = line.replace("\"", "").replace(": ", "").trim();
|
||||
final String[] split = line.split("\\[", 2);
|
||||
System.out.println(firstPart + "\"minecraft:" + newName + "[" + split[1] + "\",");
|
||||
}
|
||||
}
|
||||
|
||||
public static final class BlockState {
|
||||
|
||||
private final List<Property> properties = new ArrayList<>();
|
||||
private String state;
|
||||
|
||||
public BlockState(final String state) {
|
||||
final int start = state.indexOf('[');
|
||||
if (start == -1) {
|
||||
this.state = state;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.endsWith("]")) {
|
||||
throw new IllegalArgumentException("Invalid block state: " + state);
|
||||
}
|
||||
|
||||
this.state = state.substring(0, start);
|
||||
|
||||
int lastCommaIndex = start;
|
||||
int commaIndex;
|
||||
while ((commaIndex = state.indexOf(',', lastCommaIndex + 1)) != -1) {
|
||||
final String part = state.substring(lastCommaIndex + 1, commaIndex);
|
||||
final String[] split = part.split("=", 2);
|
||||
properties.add(new Property(split[0], split[1]));
|
||||
|
||||
lastCommaIndex = commaIndex;
|
||||
}
|
||||
|
||||
final String part = state.substring(lastCommaIndex + 1, state.length() - 1);
|
||||
final String[] split = part.split("=", 2);
|
||||
properties.add(new Property(split[0], split[1]));
|
||||
}
|
||||
|
||||
public @Nullable Property getProperty(final String key) {
|
||||
for (final Property property : properties) {
|
||||
if (property.key.equals(key)) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addProperty(final String key, final String value) {
|
||||
properties.add(new Property(key, value));
|
||||
}
|
||||
|
||||
public void addProperty(final int index, final String key, final String value) {
|
||||
properties.add(index, new Property(key, value));
|
||||
}
|
||||
|
||||
public @Nullable Property removeProperty(final String key) {
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
final Property property = properties.get(i);
|
||||
if (property.key.equals(key)) {
|
||||
properties.remove(i);
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Property> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(final String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder(state).append('[');
|
||||
for (final Property property : properties) {
|
||||
builder.append(property.getKey()).append('=').append(property.getValue()).append(',');
|
||||
}
|
||||
return builder.substring(0, builder.length() - 1) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final BlockState that = (BlockState) o;
|
||||
if (!properties.equals(that.properties)) return false;
|
||||
return state.equals(that.state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = properties.hashCode();
|
||||
result = 31 * result + state.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public BlockState copy() {
|
||||
return new BlockState(toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Property {
|
||||
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public Property(final String key, final String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(final String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final Property property = (Property) o;
|
||||
if (!key.equals(property.key)) return false;
|
||||
return value.equals(property.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = key.hashCode();
|
||||
result = 31 * result + value.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.viaversion.mappingsgenerator.helper;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.viaversion.mappingsgenerator.util.PathUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Utility to compare generate a diff of translations between two Minecraft versions.
|
||||
* Copy the output into VB's translations file.
|
||||
*/
|
||||
final class TranslationMapper {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TranslationMapper.class.getSimpleName());
|
||||
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
|
||||
|
||||
public static void main(final String[] args) throws IOException {
|
||||
final String oldVer = "1.21.2";
|
||||
final String newVer = "1.21.4-rc3";
|
||||
|
||||
final Map<String, String> oldTranslations = load(oldVer);
|
||||
final Set<String> oldValues = new HashSet<>(oldTranslations.values());
|
||||
final Map<String, String> newTranslations = load(newVer);
|
||||
|
||||
final JsonObject diff = new JsonObject();
|
||||
for (final Map.Entry<String, String> entry : newTranslations.entrySet()) {
|
||||
if (oldTranslations.containsKey(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldValues.contains(entry.getValue())) {
|
||||
LOGGER.warn("Changed value: {}", entry.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
diff.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// Check for removed translations
|
||||
for (final Map.Entry<String, String> entry : oldTranslations.entrySet()) {
|
||||
if (!newTranslations.containsKey(entry.getKey())) {
|
||||
//LOGGER.warn("mappings.put(\"" + entry.getKey() + "\", \"" + entry.getValue() + "\");");
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info(diff.toString());
|
||||
LOGGER.info("Mappings size: {}", diff.size());
|
||||
}
|
||||
|
||||
private static Map<String, String> load(final String version) throws IOException {
|
||||
final File jarFile = PathUtil.minecraftDir().resolve("versions").resolve(version).resolve(version + ".jar").toFile();
|
||||
if (!jarFile.exists()) {
|
||||
throw new IllegalArgumentException("File " + jarFile + " does not exist");
|
||||
}
|
||||
|
||||
final String contents;
|
||||
try (final ZipFile file = new ZipFile(jarFile)) {
|
||||
ZipEntry langEntry = file.getEntry("assets/minecraft/lang/en_us.json");
|
||||
if (langEntry == null) {
|
||||
// Pre 1.13 translations
|
||||
langEntry = file.getEntry("assets/minecraft/lang/en_us.lang");
|
||||
if (langEntry != null) {
|
||||
try (final InputStream inputStream = file.getInputStream(langEntry)) {
|
||||
contents = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
return loadLegacyTranslations(contents);
|
||||
}
|
||||
throw new IllegalArgumentException("File " + jarFile + " does not contain en_us.json");
|
||||
}
|
||||
|
||||
try (final InputStream inputStream = file.getInputStream(langEntry)) {
|
||||
contents = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
final JsonObject object = GSON.fromJson(contents, JsonObject.class);
|
||||
final Map<String, String> translations = new LinkedHashMap<>();
|
||||
for (final Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
translations.put(entry.getKey(), entry.getValue().getAsString());
|
||||
}
|
||||
return translations;
|
||||
}
|
||||
|
||||
private static Map<String, String> loadLegacyTranslations(final String contents) {
|
||||
final Map<String, String> translations = new LinkedHashMap<>();
|
||||
contents.lines().forEach(line -> {
|
||||
final int index = line.indexOf('=');
|
||||
if (index != -1) {
|
||||
translations.put(line.substring(0, index), line.substring(index + 1));
|
||||
}
|
||||
});
|
||||
return translations;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.viaversion.mappingsgenerator.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public final class GsonUtil {
|
||||
|
||||
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.viaversion.mappingsgenerator.util;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public final class PathUtil {
|
||||
|
||||
public static Path minecraftDir() {
|
||||
// Windows path
|
||||
Path minecraftDir = Paths.get(home(), "AppData", "Roaming", ".minecraft");
|
||||
if (!Files.isDirectory(minecraftDir)) {
|
||||
// MacOS path
|
||||
minecraftDir = Paths.get(home(), "Library", "Application Support", "minecraft");
|
||||
}
|
||||
return minecraftDir;
|
||||
}
|
||||
|
||||
private static String home() {
|
||||
return System.getProperty("user.home");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user