Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-27 08:30:12 +01:00
Most things now use Gson for JSON
Dieser Commit ist enthalten in:
Ursprung
8d24891c97
Commit
2d33cfd149
@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.GeyserLogger;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
@ -84,7 +85,12 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements Gey
|
||||
|
||||
@Override
|
||||
public void debug(String message) {
|
||||
log.debug(ChatColor.GRAY + message);
|
||||
log.debug(ChatColor.GRAY + "{}", message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(@Nullable Object object) {
|
||||
log.debug("{}", object);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,6 +26,7 @@ package org.geysermc.geyser.platform.viaproxy;
|
||||
|
||||
import net.raphimc.viaproxy.cli.ConsoleFormatter;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserLogger;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
|
||||
@ -75,6 +76,13 @@ public class GeyserViaProxyLogger implements GeyserLogger, GeyserCommandSource {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(@Nullable Object object) {
|
||||
if (this.debug) {
|
||||
this.logger.debug(ConsoleFormatter.convert(String.valueOf(object)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
|
@ -99,7 +99,10 @@ public interface GeyserLogger extends GeyserCommandSource {
|
||||
* @param object the object to log
|
||||
*/
|
||||
default void debug(@Nullable Object object) {
|
||||
debug(String.valueOf(object));
|
||||
if (isDebug()) {
|
||||
// Don't create String object by default
|
||||
info(String.valueOf(object));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,7 @@ import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@ConfigSerializable
|
||||
public interface GeyserConfig {
|
||||
BedrockConfig bedrock();
|
||||
|
||||
|
@ -25,11 +25,10 @@
|
||||
|
||||
package org.geysermc.geyser.pack;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.api.pack.ResourcePackManifest;
|
||||
|
||||
@ -37,15 +36,14 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public record GeyserResourcePackManifest(@JsonProperty("format_version") int formatVersion, Header header, Collection<Module> modules, Collection<Dependency> dependencies) implements ResourcePackManifest {
|
||||
public record GeyserResourcePackManifest(@SerializedName("format_version") int formatVersion, Header header, Collection<Module> modules, Collection<Dependency> dependencies) implements ResourcePackManifest {
|
||||
|
||||
public record Header(UUID uuid, Version version, String name, String description, @JsonProperty("min_engine_version") Version minimumSupportedMinecraftVersion) implements ResourcePackManifest.Header { }
|
||||
public record Header(UUID uuid, Version version, String name, String description, @SerializedName("min_engine_version") Version minimumSupportedMinecraftVersion) implements ResourcePackManifest.Header { }
|
||||
|
||||
public record Module(UUID uuid, Version version, String type, String description) implements ResourcePackManifest.Module { }
|
||||
|
||||
public record Dependency(UUID uuid, Version version) implements ResourcePackManifest.Dependency { }
|
||||
|
||||
@JsonDeserialize(using = Version.VersionDeserializer.class)
|
||||
public record Version(int major, int minor, int patch) implements ResourcePackManifest.Version {
|
||||
|
||||
@Override
|
||||
@ -53,11 +51,17 @@ public record GeyserResourcePackManifest(@JsonProperty("format_version") int for
|
||||
return major + "." + minor + "." + patch;
|
||||
}
|
||||
|
||||
public static class VersionDeserializer extends JsonDeserializer<Version> {
|
||||
public static class VersionDeserializer extends TypeAdapter<Version> {
|
||||
@Override
|
||||
public Version deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
int[] version = ctxt.readValue(p, int[].class);
|
||||
return new Version(version[0], version[1], version[2]);
|
||||
public void write(JsonWriter jsonWriter, Version version) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version read(JsonReader jsonReader) throws IOException {
|
||||
jsonReader.beginArray();
|
||||
Version version = new Version(jsonReader.nextInt(), jsonReader.nextInt(), jsonReader.nextInt());
|
||||
jsonReader.endArray();
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.ping;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import io.netty.handler.codec.haproxy.HAProxyCommand;
|
||||
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
|
||||
import io.netty.util.NetUtil;
|
||||
@ -34,9 +33,19 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.util.VarInts;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runnable {
|
||||
@ -130,11 +139,11 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn
|
||||
}
|
||||
}
|
||||
|
||||
this.pingInfo = GeyserImpl.JSON_MAPPER.readValue(buffer, GeyserPingInfo.class);
|
||||
this.pingInfo = JsonUtils.fromJson(buffer, GeyserPingInfo.class);
|
||||
} catch (SocketTimeoutException | ConnectException ex) {
|
||||
this.pingInfo = null;
|
||||
this.geyser.getLogger().debug("Connection timeout for ping passthrough.");
|
||||
} catch (JsonParseException | JsonMappingException ex) {
|
||||
} catch (JsonSyntaxException ex) {
|
||||
this.geyser.getLogger().error("Failed to parse json when pinging server!", ex);
|
||||
} catch (EOFException e) {
|
||||
this.pingInfo = null;
|
||||
|
@ -30,10 +30,10 @@ import com.google.gson.reflect.TypeToken;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@ -50,7 +50,7 @@ public class BiomeIdentifierRegistryLoader implements RegistryLoader<String, Obj
|
||||
Map<String, BiomeEntry> biomeEntries;
|
||||
|
||||
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/biomes.json")) {
|
||||
biomeEntries = GeyserImpl.GSON.fromJson(new InputStreamReader(stream), biomeEntriesType);
|
||||
biomeEntries = JsonUtils.fromJson(stream, biomeEntriesType);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("Unable to load Bedrock runtime biomes", e);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.registry.loader;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
@ -55,6 +57,9 @@ import java.util.zip.ZipFile;
|
||||
* Loads {@link ResourcePack}s within a {@link Path} directory, firing the {@link GeyserLoadResourcePacksEvent}.
|
||||
*/
|
||||
public class ResourcePackLoader implements RegistryLoader<Path, Map<String, ResourcePack>> {
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(GeyserResourcePackManifest.Version.class, new GeyserResourcePackManifest.Version.VersionDeserializer())
|
||||
.create();
|
||||
|
||||
static final PathMatcher PACK_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**.{zip,mcpack}");
|
||||
|
||||
@ -135,7 +140,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
|
||||
}
|
||||
if (name.contains("manifest.json")) {
|
||||
try {
|
||||
GeyserResourcePackManifest manifest = FileUtils.loadJson(zip.getInputStream(x), GeyserResourcePackManifest.class);
|
||||
GeyserResourcePackManifest manifest = FileUtils.loadJson(GSON, zip.getInputStream(x), GeyserResourcePackManifest.class);
|
||||
if (manifest.header().uuid() != null) {
|
||||
manifestReference.set(manifest);
|
||||
}
|
||||
|
@ -25,7 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.registry.mappings;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@ -35,6 +36,7 @@ import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping;
|
||||
import org.geysermc.geyser.registry.mappings.versions.MappingsReader;
|
||||
import org.geysermc.geyser.registry.mappings.versions.MappingsReader_v1;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -95,10 +97,10 @@ public class MappingsConfigReader {
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable JsonNode getMappingsRoot(Path file) {
|
||||
JsonNode mappingsRoot;
|
||||
try {
|
||||
mappingsRoot = GeyserImpl.JSON_MAPPER.readTree(file.toFile());
|
||||
public @Nullable JsonObject getMappingsRoot(Path file) {
|
||||
JsonObject mappingsRoot;
|
||||
try (FileReader reader = new FileReader(file.toFile())) {
|
||||
mappingsRoot = (JsonObject) new JsonParser().parse(reader);
|
||||
} catch (IOException e) {
|
||||
GeyserImpl.getInstance().getLogger().error("Failed to read custom mapping file: " + file, e);
|
||||
return null;
|
||||
@ -112,8 +114,8 @@ public class MappingsConfigReader {
|
||||
return mappingsRoot;
|
||||
}
|
||||
|
||||
public int getFormatVersion(JsonNode mappingsRoot, Path file) {
|
||||
int formatVersion = mappingsRoot.get("format_version").asInt();
|
||||
public int getFormatVersion(JsonObject mappingsRoot, Path file) {
|
||||
int formatVersion = mappingsRoot.get("format_version").getAsInt();
|
||||
if (!this.mappingReaders.containsKey(formatVersion)) {
|
||||
GeyserImpl.getInstance().getLogger().error("Mappings file " + file + " has an unknown format version: " + formatVersion);
|
||||
return -1;
|
||||
@ -122,7 +124,7 @@ public class MappingsConfigReader {
|
||||
}
|
||||
|
||||
public void readItemMappingsFromJson(Path file, BiConsumer<String, CustomItemData> consumer) {
|
||||
JsonNode mappingsRoot = getMappingsRoot(file);
|
||||
JsonObject mappingsRoot = getMappingsRoot(file);
|
||||
|
||||
if (mappingsRoot == null) {
|
||||
return;
|
||||
@ -138,7 +140,7 @@ public class MappingsConfigReader {
|
||||
}
|
||||
|
||||
public void readBlockMappingsFromJson(Path file, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||
JsonNode mappingsRoot = getMappingsRoot(file);
|
||||
JsonObject mappingsRoot = getMappingsRoot(file);
|
||||
|
||||
if (mappingsRoot == null) {
|
||||
return;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.registry.mappings.versions;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||
import org.geysermc.geyser.api.item.custom.CustomRenderOffsets;
|
||||
@ -36,14 +36,14 @@ import java.nio.file.Path;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public abstract class MappingsReader {
|
||||
public abstract void readItemMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomItemData> consumer);
|
||||
public abstract void readBlockMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer);
|
||||
public abstract void readItemMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomItemData> consumer);
|
||||
public abstract void readBlockMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer);
|
||||
|
||||
public abstract CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMappingsFileException;
|
||||
public abstract CustomBlockMapping readBlockMappingEntry(String identifier, JsonNode node) throws InvalidCustomMappingsFileException;
|
||||
public abstract CustomItemData readItemMappingEntry(JsonObject node) throws InvalidCustomMappingsFileException;
|
||||
public abstract CustomBlockMapping readBlockMappingEntry(String identifier, JsonObject node) throws InvalidCustomMappingsFileException;
|
||||
|
||||
protected @Nullable CustomRenderOffsets fromJsonNode(JsonNode node) {
|
||||
if (node == null || !node.isObject()) {
|
||||
protected @Nullable CustomRenderOffsets fromJsonObject(JsonObject node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -53,9 +53,8 @@ public abstract class MappingsReader {
|
||||
);
|
||||
}
|
||||
|
||||
protected CustomRenderOffsets.@Nullable Hand getHandOffsets(JsonNode node, String hand) {
|
||||
JsonNode tmpNode = node.get(hand);
|
||||
if (tmpNode == null || !tmpNode.isObject()) {
|
||||
protected CustomRenderOffsets.@Nullable Hand getHandOffsets(JsonObject node, String hand) {
|
||||
if (!(node.get(hand) instanceof JsonObject tmpNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -65,9 +64,8 @@ public abstract class MappingsReader {
|
||||
);
|
||||
}
|
||||
|
||||
protected CustomRenderOffsets.@Nullable Offset getPerspectiveOffsets(JsonNode node, String perspective) {
|
||||
JsonNode tmpNode = node.get(perspective);
|
||||
if (tmpNode == null || !tmpNode.isObject()) {
|
||||
protected CustomRenderOffsets.@Nullable Offset getPerspectiveOffsets(JsonObject node, String perspective) {
|
||||
if (!(node.get(perspective) instanceof JsonObject tmpNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -78,9 +76,8 @@ public abstract class MappingsReader {
|
||||
);
|
||||
}
|
||||
|
||||
protected CustomRenderOffsets.@Nullable OffsetXYZ getOffsetXYZ(JsonNode node, String offsetType) {
|
||||
JsonNode tmpNode = node.get(offsetType);
|
||||
if (tmpNode == null || !tmpNode.isObject()) {
|
||||
protected CustomRenderOffsets.@Nullable OffsetXYZ getOffsetXYZ(JsonObject node, String offsetType) {
|
||||
if (!(node.get(offsetType) instanceof JsonObject tmpNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -89,9 +86,9 @@ public abstract class MappingsReader {
|
||||
}
|
||||
|
||||
return new CustomRenderOffsets.OffsetXYZ(
|
||||
tmpNode.get("x").floatValue(),
|
||||
tmpNode.get("y").floatValue(),
|
||||
tmpNode.get("z").floatValue()
|
||||
tmpNode.get("x").getAsFloat(),
|
||||
tmpNode.get("y").getAsFloat(),
|
||||
tmpNode.get("z").getAsFloat()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,10 @@
|
||||
|
||||
package org.geysermc.geyser.registry.mappings.versions;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@ -34,9 +36,14 @@ import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
||||
import org.geysermc.geyser.api.block.custom.CustomBlockPermutation;
|
||||
import org.geysermc.geyser.api.block.custom.CustomBlockState;
|
||||
import org.geysermc.geyser.api.block.custom.component.*;
|
||||
import org.geysermc.geyser.api.block.custom.component.BoxComponent;
|
||||
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents;
|
||||
import org.geysermc.geyser.api.block.custom.component.GeometryComponent;
|
||||
import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
|
||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
|
||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.BlockFilterType;
|
||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
|
||||
import org.geysermc.geyser.api.block.custom.component.TransformationComponent;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
|
||||
import org.geysermc.geyser.api.util.CreativeCategory;
|
||||
@ -57,7 +64,13 @@ import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.geyser.util.MinecraftKey;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@ -68,7 +81,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class MappingsReader_v1 extends MappingsReader {
|
||||
@Override
|
||||
public void readItemMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
||||
public void readItemMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
||||
this.readItemMappingsV1(file, mappingsRoot, consumer);
|
||||
}
|
||||
|
||||
@ -76,24 +89,24 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* Read item block from a JSON node
|
||||
*
|
||||
* @param file The path to the file
|
||||
* @param mappingsRoot The {@link JsonNode} containing the mappings
|
||||
* @param mappingsRoot The {@link JsonObject} containing the mappings
|
||||
* @param consumer The consumer to accept the mappings
|
||||
* @see #readBlockMappingsV1(Path, JsonNode, BiConsumer)
|
||||
* @see #readBlockMappingsV1(Path, JsonObject, BiConsumer)
|
||||
*/
|
||||
@Override
|
||||
public void readBlockMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||
public void readBlockMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||
this.readBlockMappingsV1(file, mappingsRoot, consumer);
|
||||
}
|
||||
|
||||
public void readItemMappingsV1(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
||||
JsonNode itemsNode = mappingsRoot.get("items");
|
||||
public void readItemMappingsV1(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
||||
JsonObject itemsNode = mappingsRoot.getAsJsonObject("items");
|
||||
|
||||
if (itemsNode != null && itemsNode.isObject()) {
|
||||
itemsNode.fields().forEachRemaining(entry -> {
|
||||
if (entry.getValue().isArray()) {
|
||||
entry.getValue().forEach(data -> {
|
||||
if (itemsNode != null) {
|
||||
itemsNode.entrySet().forEach(entry -> {
|
||||
if (entry.getValue() instanceof JsonArray array) {
|
||||
array.forEach(data -> {
|
||||
try {
|
||||
CustomItemData customItemData = this.readItemMappingEntry(data);
|
||||
CustomItemData customItemData = this.readItemMappingEntry((JsonObject) data);
|
||||
consumer.accept(entry.getKey(), customItemData);
|
||||
} catch (InvalidCustomMappingsFileException e) {
|
||||
GeyserImpl.getInstance().getLogger().error("Error in registering items for custom mapping file: " + file.toString(), e);
|
||||
@ -108,19 +121,17 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* Read block mappings from a JSON node
|
||||
*
|
||||
* @param file The path to the file
|
||||
* @param mappingsRoot The {@link JsonNode} containing the mappings
|
||||
* @param mappingsRoot The {@link JsonObject} containing the mappings
|
||||
* @param consumer The consumer to accept the mappings
|
||||
* @see #readBlockMappings(Path, JsonNode, BiConsumer)
|
||||
* @see #readBlockMappings(Path, JsonObject, BiConsumer)
|
||||
*/
|
||||
public void readBlockMappingsV1(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||
JsonNode blocksNode = mappingsRoot.get("blocks");
|
||||
|
||||
if (blocksNode != null && blocksNode.isObject()) {
|
||||
blocksNode.fields().forEachRemaining(entry -> {
|
||||
if (entry.getValue().isObject()) {
|
||||
public void readBlockMappingsV1(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||
if (mappingsRoot.get("blocks") instanceof JsonObject blocksNode) {
|
||||
blocksNode.entrySet().forEach(entry -> {
|
||||
if (entry.getValue() instanceof JsonObject jsonObject) {
|
||||
try {
|
||||
String identifier = MinecraftKey.key(entry.getKey()).asString();
|
||||
CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, entry.getValue());
|
||||
CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, jsonObject);
|
||||
consumer.accept(identifier, customBlockMapping);
|
||||
} catch (Exception e) {
|
||||
GeyserImpl.getInstance().getLogger().error("Error in registering blocks for custom mapping file: " + file.toString());
|
||||
@ -131,85 +142,85 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
}
|
||||
}
|
||||
|
||||
private CustomItemOptions readItemCustomItemOptions(JsonNode node) {
|
||||
private CustomItemOptions readItemCustomItemOptions(JsonObject node) {
|
||||
CustomItemOptions.Builder customItemOptions = CustomItemOptions.builder();
|
||||
|
||||
JsonNode customModelData = node.get("custom_model_data");
|
||||
if (customModelData != null && customModelData.isInt()) {
|
||||
customItemOptions.customModelData(customModelData.asInt());
|
||||
JsonElement customModelData = node.get("custom_model_data");
|
||||
if (customModelData != null && customModelData.isJsonPrimitive()) {
|
||||
customItemOptions.customModelData(customModelData.getAsInt());
|
||||
}
|
||||
|
||||
JsonNode damagePredicate = node.get("damage_predicate");
|
||||
if (damagePredicate != null && damagePredicate.isInt()) {
|
||||
customItemOptions.damagePredicate(damagePredicate.asInt());
|
||||
JsonElement damagePredicate = node.get("damage_predicate");
|
||||
if (damagePredicate != null && damagePredicate.isJsonPrimitive()) {
|
||||
customItemOptions.damagePredicate(damagePredicate.getAsInt());
|
||||
}
|
||||
|
||||
JsonNode unbreakable = node.get("unbreakable");
|
||||
if (unbreakable != null && unbreakable.isBoolean()) {
|
||||
customItemOptions.unbreakable(unbreakable.asBoolean());
|
||||
JsonElement unbreakable = node.get("unbreakable");
|
||||
if (unbreakable != null && unbreakable.isJsonPrimitive()) {
|
||||
customItemOptions.unbreakable(unbreakable.getAsBoolean());
|
||||
}
|
||||
|
||||
JsonNode defaultItem = node.get("default");
|
||||
if (defaultItem != null && defaultItem.isBoolean()) {
|
||||
customItemOptions.defaultItem(defaultItem.asBoolean());
|
||||
JsonElement defaultItem = node.get("default");
|
||||
if (defaultItem != null && defaultItem.isJsonPrimitive()) {
|
||||
customItemOptions.defaultItem(defaultItem.getAsBoolean());
|
||||
}
|
||||
|
||||
return customItemOptions.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMappingsFileException {
|
||||
if (node == null || !node.isObject()) {
|
||||
public CustomItemData readItemMappingEntry(JsonObject node) throws InvalidCustomMappingsFileException {
|
||||
if (node == null) {
|
||||
throw new InvalidCustomMappingsFileException("Invalid item mappings entry");
|
||||
}
|
||||
|
||||
JsonNode name = node.get("name");
|
||||
if (name == null || !name.isTextual() || name.asText().isEmpty()) {
|
||||
JsonElement name = node.get("name");
|
||||
if (name == null || !name.isJsonPrimitive() || name.getAsString().isEmpty()) {
|
||||
throw new InvalidCustomMappingsFileException("An item entry has no name");
|
||||
}
|
||||
|
||||
CustomItemData.Builder customItemData = CustomItemData.builder()
|
||||
.name(name.asText())
|
||||
.name(name.getAsString())
|
||||
.customItemOptions(this.readItemCustomItemOptions(node));
|
||||
|
||||
//The next entries are optional
|
||||
if (node.has("display_name")) {
|
||||
customItemData.displayName(node.get("display_name").asText());
|
||||
customItemData.displayName(node.get("display_name").getAsString());
|
||||
}
|
||||
|
||||
if (node.has("icon")) {
|
||||
customItemData.icon(node.get("icon").asText());
|
||||
customItemData.icon(node.get("icon").getAsString());
|
||||
}
|
||||
|
||||
if (node.has("creative_category")) {
|
||||
customItemData.creativeCategory(node.get("creative_category").asInt());
|
||||
customItemData.creativeCategory(node.get("creative_category").getAsInt());
|
||||
}
|
||||
|
||||
if (node.has("creative_group")) {
|
||||
customItemData.creativeGroup(node.get("creative_group").asText());
|
||||
customItemData.creativeGroup(node.get("creative_group").getAsString());
|
||||
}
|
||||
|
||||
if (node.has("allow_offhand")) {
|
||||
customItemData.allowOffhand(node.get("allow_offhand").asBoolean());
|
||||
customItemData.allowOffhand(node.get("allow_offhand").getAsBoolean());
|
||||
}
|
||||
|
||||
if (node.has("display_handheld")) {
|
||||
customItemData.displayHandheld(node.get("display_handheld").asBoolean());
|
||||
customItemData.displayHandheld(node.get("display_handheld").getAsBoolean());
|
||||
}
|
||||
|
||||
if (node.has("texture_size")) {
|
||||
customItemData.textureSize(node.get("texture_size").asInt());
|
||||
customItemData.textureSize(node.get("texture_size").getAsInt());
|
||||
}
|
||||
|
||||
if (node.has("render_offsets")) {
|
||||
JsonNode tmpNode = node.get("render_offsets");
|
||||
JsonObject tmpNode = node.getAsJsonObject("render_offsets");
|
||||
|
||||
customItemData.renderOffsets(fromJsonNode(tmpNode));
|
||||
customItemData.renderOffsets(fromJsonObject(tmpNode));
|
||||
}
|
||||
|
||||
if (node.get("tags") instanceof ArrayNode tags) {
|
||||
if (node.get("tags") instanceof JsonArray tags) {
|
||||
Set<String> tagsSet = new ObjectOpenHashSet<>();
|
||||
tags.forEach(tag -> tagsSet.add(tag.asText()));
|
||||
tags.forEach(tag -> tagsSet.add(tag.getAsString()));
|
||||
customItemData.tags(tagsSet);
|
||||
}
|
||||
|
||||
@ -220,26 +231,26 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* Read a block mapping entry from a JSON node and Java identifier
|
||||
*
|
||||
* @param identifier The Java identifier of the block
|
||||
* @param node The {@link JsonNode} containing the block mapping entry
|
||||
* @param node The {@link JsonObject} containing the block mapping entry
|
||||
* @return The {@link CustomBlockMapping} record to be read by {@link org.geysermc.geyser.registry.populator.CustomBlockRegistryPopulator}
|
||||
* @throws InvalidCustomMappingsFileException If the JSON node is invalid
|
||||
*/
|
||||
@Override
|
||||
public CustomBlockMapping readBlockMappingEntry(String identifier, JsonNode node) throws InvalidCustomMappingsFileException {
|
||||
if (node == null || !node.isObject()) {
|
||||
public CustomBlockMapping readBlockMappingEntry(String identifier, JsonObject node) throws InvalidCustomMappingsFileException {
|
||||
if (node == null) {
|
||||
throw new InvalidCustomMappingsFileException("Invalid block mappings entry:" + node);
|
||||
}
|
||||
|
||||
String name = node.get("name").asText();
|
||||
String name = node.get("name").getAsString();
|
||||
if (name == null || name.isEmpty()) {
|
||||
throw new InvalidCustomMappingsFileException("A block entry has no name");
|
||||
}
|
||||
|
||||
boolean includedInCreativeInventory = node.has("included_in_creative_inventory") && node.get("included_in_creative_inventory").asBoolean();
|
||||
boolean includedInCreativeInventory = node.has("included_in_creative_inventory") && node.get("included_in_creative_inventory").getAsBoolean();
|
||||
|
||||
CreativeCategory creativeCategory = CreativeCategory.NONE;
|
||||
if (node.has("creative_category")) {
|
||||
String categoryName = node.get("creative_category").asText();
|
||||
String categoryName = node.get("creative_category").getAsString();
|
||||
try {
|
||||
creativeCategory = CreativeCategory.valueOf(categoryName.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
@ -249,11 +260,11 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
|
||||
String creativeGroup = "";
|
||||
if (node.has("creative_group")) {
|
||||
creativeGroup = node.get("creative_group").asText();
|
||||
creativeGroup = node.get("creative_group").getAsString();
|
||||
}
|
||||
|
||||
// If this is true, we will only register the states the user has specified rather than all the possible block states
|
||||
boolean onlyOverrideStates = node.has("only_override_states") && node.get("only_override_states").asBoolean();
|
||||
boolean onlyOverrideStates = node.has("only_override_states") && node.get("only_override_states").getAsBoolean();
|
||||
|
||||
// Create the data for the overall block
|
||||
CustomBlockData.Builder customBlockDataBuilder = new GeyserCustomBlockData.Builder()
|
||||
@ -273,12 +284,9 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
|
||||
Map<String, CustomBlockComponentsMapping> componentsMap = new LinkedHashMap<>();
|
||||
|
||||
JsonNode stateOverrides = node.get("state_overrides");
|
||||
if (stateOverrides != null && stateOverrides.isObject()) {
|
||||
if (node.get("state_overrides") instanceof JsonObject stateOverrides) {
|
||||
// Load components for specific Java block states
|
||||
Iterator<Map.Entry<String, JsonNode>> fields = stateOverrides.fields();
|
||||
while (fields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> overrideEntry = fields.next();
|
||||
for (Map.Entry<String, JsonElement> overrideEntry : stateOverrides.entrySet()) {
|
||||
String state = identifier + "[" + overrideEntry.getKey() + "]";
|
||||
if (!BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().containsKey(state)) {
|
||||
throw new InvalidCustomMappingsFileException("Unknown Java block state: " + state + " for state_overrides.");
|
||||
@ -358,12 +366,12 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
/**
|
||||
* Creates a {@link CustomBlockComponents} object for the passed state override or base block node, Java block state identifier, and custom block name
|
||||
*
|
||||
* @param node the state override or base block {@link JsonNode}
|
||||
* @param element the state override or base block {@link JsonObject}
|
||||
* @param stateKey the Java block state identifier
|
||||
* @param name the name of the custom block
|
||||
* @return the {@link CustomBlockComponents} object
|
||||
*/
|
||||
private CustomBlockComponentsMapping createCustomBlockComponentsMapping(JsonNode node, String stateKey, String name) {
|
||||
private CustomBlockComponentsMapping createCustomBlockComponentsMapping(JsonElement element, String stateKey, String name) {
|
||||
// This is needed to find the correct selection box for the given block
|
||||
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(stateKey, -1);
|
||||
BoxComponent boxComponent = createBoxComponent(id);
|
||||
@ -372,7 +380,7 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
.collisionBox(boxComponent)
|
||||
.selectionBox(boxComponent);
|
||||
|
||||
if (node == null) {
|
||||
if (!(element instanceof JsonObject node)) {
|
||||
// No other components were defined
|
||||
return new CustomBlockComponentsMapping(builder.build(), extendedBoxComponent);
|
||||
}
|
||||
@ -394,28 +402,28 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
// We set this to max value by default so that we may dictate the correct destroy time ourselves
|
||||
float destructibleByMining = Float.MAX_VALUE;
|
||||
if (node.has("destructible_by_mining")) {
|
||||
destructibleByMining = node.get("destructible_by_mining").floatValue();
|
||||
destructibleByMining = node.get("destructible_by_mining").getAsFloat();
|
||||
}
|
||||
builder.destructibleByMining(destructibleByMining);
|
||||
|
||||
if (node.has("geometry")) {
|
||||
if (node.get("geometry").isTextual()) {
|
||||
if (node.get("geometry").isJsonPrimitive()) {
|
||||
builder.geometry(new GeyserGeometryComponent.Builder()
|
||||
.identifier(node.get("geometry").asText())
|
||||
.identifier(node.get("geometry").getAsString())
|
||||
.build());
|
||||
} else {
|
||||
JsonNode geometry = node.get("geometry");
|
||||
JsonObject geometry = node.getAsJsonObject("geometry");
|
||||
GeometryComponent.Builder geometryBuilder = new GeyserGeometryComponent.Builder();
|
||||
if (geometry.has("identifier")) {
|
||||
geometryBuilder.identifier(geometry.get("identifier").asText());
|
||||
geometryBuilder.identifier(geometry.get("identifier").getAsString());
|
||||
}
|
||||
if (geometry.has("bone_visibility")) {
|
||||
JsonNode boneVisibility = geometry.get("bone_visibility");
|
||||
if (boneVisibility.isObject()) {
|
||||
if (geometry.get("bone_visibility") instanceof JsonObject boneVisibility) {
|
||||
Map<String, String> boneVisibilityMap = new Object2ObjectOpenHashMap<>();
|
||||
boneVisibility.fields().forEachRemaining(entry -> {
|
||||
boneVisibility.entrySet().forEach(entry -> {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue().isBoolean() ? (entry.getValue().asBoolean() ? "1" : "0") : entry.getValue().asText();
|
||||
String value = entry.getValue() instanceof JsonPrimitive primitive && primitive.isBoolean()
|
||||
? (entry.getValue().getAsBoolean() ? "1" : "0") : entry.getValue().getAsString();
|
||||
boneVisibilityMap.put(key, value);
|
||||
});
|
||||
geometryBuilder.boneVisibility(boneVisibilityMap);
|
||||
@ -427,30 +435,30 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
|
||||
String displayName = name;
|
||||
if (node.has("display_name")) {
|
||||
displayName = node.get("display_name").asText();
|
||||
displayName = node.get("display_name").getAsString();
|
||||
}
|
||||
builder.displayName(displayName);
|
||||
|
||||
if (node.has("friction")) {
|
||||
builder.friction(node.get("friction").floatValue());
|
||||
builder.friction(node.get("friction").getAsFloat());
|
||||
}
|
||||
|
||||
if (node.has("light_emission")) {
|
||||
builder.lightEmission(node.get("light_emission").asInt());
|
||||
builder.lightEmission(node.get("light_emission").getAsInt());
|
||||
}
|
||||
|
||||
if (node.has("light_dampening")) {
|
||||
builder.lightDampening(node.get("light_dampening").asInt());
|
||||
builder.lightDampening(node.get("light_dampening").getAsInt());
|
||||
}
|
||||
|
||||
boolean placeAir = true;
|
||||
if (node.has("place_air")) {
|
||||
placeAir = node.get("place_air").asBoolean();
|
||||
placeAir = node.get("place_air").getAsBoolean();
|
||||
}
|
||||
builder.placeAir(placeAir);
|
||||
|
||||
if (node.has("transformation")) {
|
||||
JsonNode transformation = node.get("transformation");
|
||||
JsonObject transformation = node.getAsJsonObject("transformation");
|
||||
|
||||
int rotationX = 0;
|
||||
int rotationY = 0;
|
||||
@ -463,22 +471,22 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
float transformZ = 0;
|
||||
|
||||
if (transformation.has("rotation")) {
|
||||
JsonNode rotation = transformation.get("rotation");
|
||||
rotationX = rotation.get(0).asInt();
|
||||
rotationY = rotation.get(1).asInt();
|
||||
rotationZ = rotation.get(2).asInt();
|
||||
JsonArray rotation = transformation.getAsJsonArray("rotation");
|
||||
rotationX = rotation.get(0).getAsInt();
|
||||
rotationY = rotation.get(1).getAsInt();
|
||||
rotationZ = rotation.get(2).getAsInt();
|
||||
}
|
||||
if (transformation.has("scale")) {
|
||||
JsonNode scale = transformation.get("scale");
|
||||
scaleX = scale.get(0).floatValue();
|
||||
scaleY = scale.get(1).floatValue();
|
||||
scaleZ = scale.get(2).floatValue();
|
||||
JsonArray scale = transformation.getAsJsonArray("scale");
|
||||
scaleX = scale.get(0).getAsFloat();
|
||||
scaleY = scale.get(1).getAsFloat();
|
||||
scaleZ = scale.get(2).getAsFloat();
|
||||
}
|
||||
if (transformation.has("translation")) {
|
||||
JsonNode translation = transformation.get("translation");
|
||||
transformX = translation.get(0).floatValue();
|
||||
transformY = translation.get(1).floatValue();
|
||||
transformZ = translation.get(2).floatValue();
|
||||
JsonArray translation = transformation.getAsJsonArray("translation");
|
||||
transformX = translation.get(0).getAsFloat();
|
||||
transformY = translation.get(1).getAsFloat();
|
||||
transformZ = translation.get(2).getAsFloat();
|
||||
}
|
||||
builder.transformation(new TransformationComponent(rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, transformX, transformY, transformZ));
|
||||
}
|
||||
@ -490,12 +498,10 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
}
|
||||
|
||||
if (node.has("material_instances")) {
|
||||
JsonNode materialInstances = node.get("material_instances");
|
||||
if (materialInstances.isObject()) {
|
||||
materialInstances.fields().forEachRemaining(entry -> {
|
||||
if (node.get("material_instances") instanceof JsonObject materialInstances) {
|
||||
materialInstances.entrySet().forEach(entry -> {
|
||||
String key = entry.getKey();
|
||||
JsonNode value = entry.getValue();
|
||||
if (value.isObject()) {
|
||||
if (entry.getValue() instanceof JsonObject value) {
|
||||
MaterialInstance materialInstance = createMaterialInstanceComponent(value);
|
||||
builder.materialInstance(key, materialInstance);
|
||||
}
|
||||
@ -503,16 +509,10 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.has("placement_filter")) {
|
||||
JsonNode placementFilter = node.get("placement_filter");
|
||||
if (placementFilter.isObject()) {
|
||||
if (placementFilter.has("conditions")) {
|
||||
JsonNode conditions = placementFilter.get("conditions");
|
||||
if (conditions.isArray()) {
|
||||
List<PlacementConditions> filter = createPlacementFilterComponent(conditions);
|
||||
builder.placementFilter(filter);
|
||||
}
|
||||
}
|
||||
if (node.get("placement_filter") instanceof JsonObject placementFilter) {
|
||||
if (placementFilter.get("conditions") instanceof JsonArray conditions) {
|
||||
List<PlacementConditions> filter = createPlacementFilterComponent(conditions);
|
||||
builder.placementFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,9 +521,9 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
// Ideally we could programmatically extract the tags here https://wiki.bedrock.dev/blocks/block-tags.html
|
||||
// This would let us automatically apply the correct vanilla tags to blocks
|
||||
// However, its worth noting that vanilla tools do not currently honor these tags anyway
|
||||
if (node.get("tags") instanceof ArrayNode tags) {
|
||||
if (node.get("tags") instanceof JsonArray tags) {
|
||||
Set<String> tagsSet = new ObjectOpenHashSet<>();
|
||||
tags.forEach(tag -> tagsSet.add(tag.asText()));
|
||||
tags.forEach(tag -> tagsSet.add(tag.getAsString()));
|
||||
builder.tags(tagsSet);
|
||||
}
|
||||
|
||||
@ -613,21 +613,21 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
/**
|
||||
* Creates a {@link BoxComponent} from a JSON Node
|
||||
*
|
||||
* @param node the JSON node
|
||||
* @param element the JSON node
|
||||
* @return the {@link BoxComponent}
|
||||
*/
|
||||
private @Nullable BoxComponent createBoxComponent(JsonNode node) {
|
||||
if (node != null && node.isObject()) {
|
||||
private @Nullable BoxComponent createBoxComponent(JsonElement element) {
|
||||
if (element instanceof JsonObject node) {
|
||||
if (node.has("origin") && node.has("size")) {
|
||||
JsonNode origin = node.get("origin");
|
||||
float originX = origin.get(0).floatValue();
|
||||
float originY = origin.get(1).floatValue();
|
||||
float originZ = origin.get(2).floatValue();
|
||||
JsonArray origin = node.getAsJsonArray("origin");
|
||||
float originX = origin.get(0).getAsFloat();
|
||||
float originY = origin.get(1).getAsFloat();
|
||||
float originZ = origin.get(2).getAsFloat();
|
||||
|
||||
JsonNode size = node.get("size");
|
||||
float sizeX = size.get(0).floatValue();
|
||||
float sizeY = size.get(1).floatValue();
|
||||
float sizeZ = size.get(2).floatValue();
|
||||
JsonArray size = node.getAsJsonArray("size");
|
||||
float sizeX = size.get(0).getAsFloat();
|
||||
float sizeY = size.get(1).getAsFloat();
|
||||
float sizeZ = size.get(2).getAsFloat();
|
||||
|
||||
return new BoxComponent(originX, originY, originZ, sizeX, sizeY, sizeZ);
|
||||
}
|
||||
@ -642,26 +642,26 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* @param node the material instance node
|
||||
* @return the {@link MaterialInstance}
|
||||
*/
|
||||
private MaterialInstance createMaterialInstanceComponent(JsonNode node) {
|
||||
private MaterialInstance createMaterialInstanceComponent(JsonObject node) {
|
||||
// Set default values, and use what the user provides if they have provided something
|
||||
String texture = null;
|
||||
if (node.has("texture")) {
|
||||
texture = node.get("texture").asText();
|
||||
texture = node.get("texture").getAsString();
|
||||
}
|
||||
|
||||
String renderMethod = "opaque";
|
||||
if (node.has("render_method")) {
|
||||
renderMethod = node.get("render_method").asText();
|
||||
renderMethod = node.get("render_method").getAsString();
|
||||
}
|
||||
|
||||
boolean faceDimming = true;
|
||||
if (node.has("face_dimming")) {
|
||||
faceDimming = node.get("face_dimming").asBoolean();
|
||||
faceDimming = node.get("face_dimming").getAsBoolean();
|
||||
}
|
||||
|
||||
boolean ambientOcclusion = true;
|
||||
if (node.has("ambient_occlusion")) {
|
||||
ambientOcclusion = node.get("ambient_occlusion").asBoolean();
|
||||
ambientOcclusion = node.get("ambient_occlusion").getAsBoolean();
|
||||
}
|
||||
|
||||
return new GeyserMaterialInstance.Builder()
|
||||
@ -678,32 +678,33 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* @param node the conditions node
|
||||
* @return the list of {@link PlacementConditions}
|
||||
*/
|
||||
private List<PlacementConditions> createPlacementFilterComponent(JsonNode node) {
|
||||
private List<PlacementConditions> createPlacementFilterComponent(JsonArray node) {
|
||||
List<PlacementConditions> conditions = new ArrayList<>();
|
||||
|
||||
// The structure of the placement filter component is the most complex of the current components
|
||||
// Each condition effectively separated into two arrays: one of allowed faces, and one of blocks/block Molang queries
|
||||
node.forEach(condition -> {
|
||||
node.forEach(json -> {
|
||||
if (!(json instanceof JsonObject condition)) {
|
||||
return;
|
||||
}
|
||||
Set<Face> faces = EnumSet.noneOf(Face.class);
|
||||
if (condition.has("allowed_faces")) {
|
||||
JsonNode allowedFaces = condition.get("allowed_faces");
|
||||
if (allowedFaces.isArray()) {
|
||||
allowedFaces.forEach(face -> faces.add(Face.valueOf(face.asText().toUpperCase())));
|
||||
if (condition.get("allowed_faces") instanceof JsonArray allowedFaces) {
|
||||
allowedFaces.forEach(face -> faces.add(Face.valueOf(face.getAsString().toUpperCase())));
|
||||
}
|
||||
}
|
||||
|
||||
LinkedHashMap<String, BlockFilterType> blockFilters = new LinkedHashMap<>();
|
||||
if (condition.has("block_filter")) {
|
||||
JsonNode blockFilter = condition.get("block_filter");
|
||||
if (blockFilter.isArray()) {
|
||||
if (condition.get("block_filter") instanceof JsonArray blockFilter) {
|
||||
blockFilter.forEach(filter -> {
|
||||
if (filter.isObject()) {
|
||||
if (filter.has("tags")) {
|
||||
JsonNode tags = filter.get("tags");
|
||||
blockFilters.put(tags.asText(), BlockFilterType.TAG);
|
||||
if (filter instanceof JsonObject jsonObject) {
|
||||
if (jsonObject.has("tags")) {
|
||||
JsonElement tags = jsonObject.get("tags");
|
||||
blockFilters.put(tags.getAsString(), BlockFilterType.TAG);
|
||||
}
|
||||
} else if (filter.isTextual()) {
|
||||
blockFilters.put(filter.asText(), BlockFilterType.BLOCK);
|
||||
} else if (filter instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||
blockFilters.put(filter.getAsString(), BlockFilterType.BLOCK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -25,17 +25,26 @@
|
||||
|
||||
package org.geysermc.geyser.registry.populator;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.cloudburstmc.nbt.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.cloudburstmc.nbt.NBTInputStream;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.nbt.NbtUtils;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
|
||||
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
|
||||
@ -56,12 +65,21 @@ import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
@ -461,23 +479,23 @@ public final class BlockRegistryPopulator {
|
||||
|
||||
BLOCKS_NBT = blocksNbt;
|
||||
|
||||
JsonNode blockInteractionsJson;
|
||||
JsonObject blockInteractionsJson;
|
||||
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/interactions.json")) {
|
||||
blockInteractionsJson = GeyserImpl.JSON_MAPPER.readTree(stream);
|
||||
blockInteractionsJson = JsonUtils.fromJson(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java block interaction mappings", e);
|
||||
}
|
||||
|
||||
BlockRegistries.INTERACTIVE.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("always_consumes")));
|
||||
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("requires_may_build")));
|
||||
BlockRegistries.INTERACTIVE.set(toBlockStateSet(blockInteractionsJson.getAsJsonArray("always_consumes")));
|
||||
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet(blockInteractionsJson.getAsJsonArray("requires_may_build")));
|
||||
|
||||
BlockRegistries.BLOCK_STATES.freeze();
|
||||
}
|
||||
|
||||
private static BitSet toBlockStateSet(ArrayNode node) {
|
||||
private static BitSet toBlockStateSet(JsonArray node) {
|
||||
BitSet blockStateSet = new BitSet(node.size());
|
||||
for (JsonNode javaIdentifier : node) {
|
||||
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.textValue()));
|
||||
for (JsonElement javaIdentifier : node) {
|
||||
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.getAsString()));
|
||||
}
|
||||
return blockStateSet;
|
||||
}
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.registry.populator;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
@ -37,6 +39,7 @@ import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@ -61,16 +64,16 @@ public class CreativeItemRegistryPopulator {
|
||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||
|
||||
// Load creative items
|
||||
JsonNode creativeItemEntries;
|
||||
JsonArray creativeItemEntries;
|
||||
try (InputStream stream = bootstrap.getResourceOrThrow(String.format("bedrock/creative_items.%s.json", palette.version()))) {
|
||||
creativeItemEntries = GeyserImpl.JSON_MAPPER.readTree(stream).get("items");
|
||||
creativeItemEntries = JsonUtils.fromJson(stream).getAsJsonArray("items");
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load creative items", e);
|
||||
}
|
||||
|
||||
BlockMappings blockMappings = BlockRegistries.BLOCKS.forVersion(palette.protocolVersion());
|
||||
for (JsonNode itemNode : creativeItemEntries) {
|
||||
ItemData.Builder itemBuilder = createItemData(itemNode, blockMappings, definitions);
|
||||
for (JsonElement itemNode : creativeItemEntries) {
|
||||
ItemData.Builder itemBuilder = createItemData((JsonObject) itemNode, blockMappings, definitions);
|
||||
if (itemBuilder == null) {
|
||||
continue;
|
||||
}
|
||||
@ -79,41 +82,41 @@ public class CreativeItemRegistryPopulator {
|
||||
}
|
||||
}
|
||||
|
||||
private static ItemData.@Nullable Builder createItemData(JsonNode itemNode, BlockMappings blockMappings, Map<String, ItemDefinition> definitions) {
|
||||
private static ItemData.@Nullable Builder createItemData(JsonObject itemNode, BlockMappings blockMappings, Map<String, ItemDefinition> definitions) {
|
||||
int count = 1;
|
||||
int damage = 0;
|
||||
int bedrockBlockRuntimeId;
|
||||
NbtMap tag = null;
|
||||
|
||||
String identifier = itemNode.get("id").textValue();
|
||||
String identifier = itemNode.get("id").getAsString();
|
||||
for (BiPredicate<String, Integer> predicate : JAVA_ONLY_ITEM_FILTER) {
|
||||
if (predicate.test(identifier, damage)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode damageNode = itemNode.get("damage");
|
||||
JsonElement damageNode = itemNode.get("damage");
|
||||
if (damageNode != null) {
|
||||
damage = damageNode.asInt();
|
||||
damage = damageNode.getAsInt();
|
||||
}
|
||||
|
||||
JsonNode countNode = itemNode.get("count");
|
||||
JsonElement countNode = itemNode.get("count");
|
||||
if (countNode != null) {
|
||||
count = countNode.asInt();
|
||||
count = countNode.getAsInt();
|
||||
}
|
||||
|
||||
GeyserBedrockBlock blockDefinition = null;
|
||||
JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
||||
JsonNode blockStateNode;
|
||||
JsonElement blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
||||
JsonElement blockStateNode;
|
||||
if (blockRuntimeIdNode != null) {
|
||||
bedrockBlockRuntimeId = blockRuntimeIdNode.asInt();
|
||||
bedrockBlockRuntimeId = blockRuntimeIdNode.getAsInt();
|
||||
if (bedrockBlockRuntimeId == 0 && !identifier.equals("minecraft:blue_candle")) { // FIXME
|
||||
bedrockBlockRuntimeId = -1;
|
||||
}
|
||||
|
||||
blockDefinition = bedrockBlockRuntimeId == -1 ? null : blockMappings.getDefinition(bedrockBlockRuntimeId);
|
||||
} else if ((blockStateNode = itemNode.get("block_state_b64")) != null) {
|
||||
byte[] bytes = Base64.getDecoder().decode(blockStateNode.asText());
|
||||
byte[] bytes = Base64.getDecoder().decode(blockStateNode.getAsString());
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
try {
|
||||
NbtMap stateTag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
||||
@ -132,9 +135,9 @@ public class CreativeItemRegistryPopulator {
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode nbtNode = itemNode.get("nbt_b64");
|
||||
JsonElement nbtNode = itemNode.get("nbt_b64");
|
||||
if (nbtNode != null) {
|
||||
byte[] bytes = Base64.getDecoder().decode(nbtNode.asText());
|
||||
byte[] bytes = Base64.getDecoder().decode(nbtNode.getAsString());
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
try {
|
||||
tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
||||
|
@ -25,15 +25,21 @@
|
||||
|
||||
package org.geysermc.geyser.registry.populator;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
@ -61,10 +67,24 @@ import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.*;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||
import org.geysermc.geyser.registry.type.GeyserMappingItem;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.NonVanillaItemRegistration;
|
||||
import org.geysermc.geyser.registry.type.PaletteItem;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -92,12 +112,12 @@ public class ItemRegistryPopulator {
|
||||
|
||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||
|
||||
TypeReference<Map<String, GeyserMappingItem>> mappingItemsType = new TypeReference<>() { };
|
||||
Type mappingItemsType = new TypeToken<Map<String, GeyserMappingItem>>() { }.getType();
|
||||
|
||||
Map<String, GeyserMappingItem> items;
|
||||
try (InputStream stream = bootstrap.getResourceOrThrow("mappings/items.json")) {
|
||||
// Load item mappings from Java Edition to Bedrock Edition
|
||||
items = GeyserImpl.JSON_MAPPER.readValue(stream, mappingItemsType);
|
||||
items = JsonUtils.fromJson(stream, mappingItemsType);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||
}
|
||||
@ -126,11 +146,11 @@ public class ItemRegistryPopulator {
|
||||
|
||||
/* Load item palette */
|
||||
for (PaletteVersion palette : paletteVersions) {
|
||||
TypeReference<List<PaletteItem>> paletteEntriesType = new TypeReference<>() {};
|
||||
Type paletteEntriesType = new TypeToken<List<PaletteItem>>() { }.getType();
|
||||
|
||||
List<PaletteItem> itemEntries;
|
||||
try (InputStream stream = bootstrap.getResourceOrThrow(String.format("bedrock/runtime_item_states.%s.json", palette.version()))) {
|
||||
itemEntries = GeyserImpl.JSON_MAPPER.readValue(stream, paletteEntriesType);
|
||||
itemEntries = JsonUtils.fromJson(stream, paletteEntriesType);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.registry.type;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
@ -43,14 +43,14 @@ import lombok.With;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GeyserMappingItem {
|
||||
@JsonProperty("bedrock_identifier") String bedrockIdentifier;
|
||||
@JsonProperty("bedrock_data") int bedrockData;
|
||||
@SerializedName("bedrock_identifier") String bedrockIdentifier;
|
||||
@SerializedName("bedrock_data") int bedrockData;
|
||||
Integer firstBlockRuntimeId;
|
||||
Integer lastBlockRuntimeId;
|
||||
@JsonProperty("tool_type") String toolType;
|
||||
@JsonProperty("tool_tier") String toolTier;
|
||||
@JsonProperty("armor_type") String armorType;
|
||||
@JsonProperty("protection_value") int protectionValue;
|
||||
@JsonProperty("is_edible") boolean edible = false;
|
||||
@JsonProperty("is_entity_placer") boolean entityPlacer = false;
|
||||
@SerializedName("tool_type") String toolType;
|
||||
@SerializedName("tool_tier") String toolTier;
|
||||
@SerializedName("armor_type") String armorType;
|
||||
@SerializedName("protection_value") int protectionValue;
|
||||
@SerializedName("is_edible") boolean edible = false;
|
||||
@SerializedName("is_entity_placer") boolean entityPlacer = false;
|
||||
}
|
||||
|
@ -282,6 +282,7 @@ public class SkinManager {
|
||||
}
|
||||
|
||||
public static @Nullable GameProfileData loadFromJson(String encodedJson) throws IOException, IllegalArgumentException {
|
||||
// TODO use GameProfile method.
|
||||
JsonNode skinObject;
|
||||
try {
|
||||
skinObject = GeyserImpl.JSON_MAPPER.readTree(new String(Base64.getDecoder().decode(encodedJson), StandardCharsets.UTF_8));
|
||||
|
@ -25,11 +25,13 @@
|
||||
|
||||
package org.geysermc.geyser.text;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.util.AssetUtils;
|
||||
import org.geysermc.geyser.util.FileUtils;
|
||||
import org.geysermc.geyser.util.JsonUtils;
|
||||
import org.geysermc.geyser.util.WebUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
@ -39,7 +41,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@ -189,14 +190,12 @@ public class MinecraftLocale {
|
||||
// Read the localefile
|
||||
try (InputStream localeStream = Files.newInputStream(localeFile, StandardOpenOption.READ)) {
|
||||
// Parse the file as json
|
||||
JsonNode localeObj = GeyserImpl.JSON_MAPPER.readTree(localeStream);
|
||||
JsonObject localeObj = JsonUtils.fromJson(localeStream);
|
||||
|
||||
// Parse all the locale fields
|
||||
Iterator<Map.Entry<String, JsonNode>> localeIterator = localeObj.fields();
|
||||
Map<String, String> langMap = new HashMap<>();
|
||||
while (localeIterator.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = localeIterator.next();
|
||||
langMap.put(entry.getKey(), entry.getValue().asText());
|
||||
for (Map.Entry<String, JsonElement> entry : localeObj.entrySet()) {
|
||||
langMap.put(entry.getKey(), entry.getValue().getAsString());
|
||||
}
|
||||
return langMap;
|
||||
} catch (FileNotFoundException e){
|
||||
|
@ -25,18 +25,28 @@
|
||||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@ -83,7 +93,7 @@ public final class AssetUtils {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
// Get the version manifest from Mojang
|
||||
VersionManifest versionManifest = GeyserImpl.JSON_MAPPER.readValue(
|
||||
VersionManifest versionManifest = GeyserImpl.GSON.fromJson(
|
||||
WebUtils.getBody("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest.class);
|
||||
|
||||
// Get the url for the latest version of the games manifest
|
||||
@ -101,26 +111,24 @@ public final class AssetUtils {
|
||||
}
|
||||
|
||||
// Get the individual version manifest
|
||||
VersionInfo versionInfo = GeyserImpl.JSON_MAPPER.readValue(WebUtils.getBody(latestInfoURL), VersionInfo.class);
|
||||
VersionInfo versionInfo = GeyserImpl.GSON.fromJson(WebUtils.getBody(latestInfoURL), VersionInfo.class);
|
||||
|
||||
// Get the client jar for use when downloading the en_us locale
|
||||
GeyserImpl.getInstance().getLogger().debug(GeyserImpl.JSON_MAPPER.writeValueAsString(versionInfo.getDownloads()));
|
||||
GeyserImpl.getInstance().getLogger().debug(versionInfo.getDownloads()); // Was previously a Jackson call for writeValueToString
|
||||
CLIENT_JAR_INFO = versionInfo.getDownloads().get("client");
|
||||
GeyserImpl.getInstance().getLogger().debug(GeyserImpl.JSON_MAPPER.writeValueAsString(CLIENT_JAR_INFO));
|
||||
GeyserImpl.getInstance().getLogger().debug(CLIENT_JAR_INFO); // Was previously a Jackson call for writeValueToString
|
||||
|
||||
// Get the assets list
|
||||
JsonNode assets = GeyserImpl.JSON_MAPPER.readTree(WebUtils.getBody(versionInfo.getAssetIndex().getUrl())).get("objects");
|
||||
JsonObject assets = ((JsonObject) new JsonParser().parse(WebUtils.getBody(versionInfo.getAssetIndex().getUrl()))).getAsJsonObject("objects");
|
||||
|
||||
// Put each asset into an array for use later
|
||||
Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields();
|
||||
while (assetIterator.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = assetIterator.next();
|
||||
for (Map.Entry<String, JsonElement> entry : assets.entrySet()) {
|
||||
if (!entry.getKey().startsWith("minecraft/lang/")) {
|
||||
// No need to cache non-language assets as we don't use them
|
||||
continue;
|
||||
}
|
||||
|
||||
Asset asset = GeyserImpl.JSON_MAPPER.treeToValue(entry.getValue(), Asset.class);
|
||||
Asset asset = GeyserImpl.GSON.fromJson(entry.getValue(), Asset.class);
|
||||
ASSET_MAP.put(entry.getKey(), asset);
|
||||
}
|
||||
|
||||
@ -221,106 +229,99 @@ public final class AssetUtils {
|
||||
|
||||
/* Classes that map to JSON files served by Mojang */
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class VersionManifest {
|
||||
@JsonProperty("latest")
|
||||
@SerializedName("latest")
|
||||
private LatestVersion latestVersion;
|
||||
|
||||
@JsonProperty("versions")
|
||||
@SerializedName("versions")
|
||||
private List<Version> versions;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class LatestVersion {
|
||||
@JsonProperty("release")
|
||||
@SerializedName("release")
|
||||
private String release;
|
||||
|
||||
@JsonProperty("snapshot")
|
||||
@SerializedName("snapshot")
|
||||
private String snapshot;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class Version {
|
||||
@JsonProperty("id")
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("type")
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("url")
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
|
||||
@JsonProperty("time")
|
||||
@SerializedName("time")
|
||||
private String time;
|
||||
|
||||
@JsonProperty("releaseTime")
|
||||
@SerializedName("releaseTime")
|
||||
private String releaseTime;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class VersionInfo {
|
||||
@JsonProperty("id")
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("type")
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
|
||||
@JsonProperty("time")
|
||||
@SerializedName("time")
|
||||
private String time;
|
||||
|
||||
@JsonProperty("releaseTime")
|
||||
@SerializedName("releaseTime")
|
||||
private String releaseTime;
|
||||
|
||||
@JsonProperty("assetIndex")
|
||||
@SerializedName("assetIndex")
|
||||
private AssetIndex assetIndex;
|
||||
|
||||
@JsonProperty("downloads")
|
||||
@SerializedName("downloads")
|
||||
private Map<String, VersionDownload> downloads;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class VersionDownload {
|
||||
@JsonProperty("sha1")
|
||||
@SerializedName("sha1")
|
||||
private String sha1;
|
||||
|
||||
@JsonProperty("size")
|
||||
@SerializedName("size")
|
||||
private int size;
|
||||
|
||||
@JsonProperty("url")
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
static class AssetIndex {
|
||||
@JsonProperty("id")
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("sha1")
|
||||
@SerializedName("sha1")
|
||||
private String sha1;
|
||||
|
||||
@JsonProperty("size")
|
||||
@SerializedName("size")
|
||||
private int size;
|
||||
|
||||
@JsonProperty("totalSize")
|
||||
@SerializedName("totalSize")
|
||||
private int totalSize;
|
||||
|
||||
@JsonProperty("url")
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Getter
|
||||
public static class Asset {
|
||||
@JsonProperty("hash")
|
||||
@SerializedName("hash")
|
||||
private String hash;
|
||||
|
||||
@JsonProperty("size")
|
||||
@SerializedName("size")
|
||||
private int size;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import com.fasterxml.jackson.annotation.Nulls;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.google.gson.Gson;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
|
||||
@ -63,9 +64,13 @@ public class FileUtils {
|
||||
return objectMapper.readValue(src, valueType);
|
||||
}
|
||||
|
||||
public static <T> T loadJson(InputStream src, Class<T> valueType) throws IOException {
|
||||
public static <T> T loadJson(InputStream src, Class<T> valueType) {
|
||||
return loadJson(GeyserImpl.GSON, src, valueType);
|
||||
}
|
||||
|
||||
public static <T> T loadJson(Gson gson, InputStream src, Class<T> valueType) {
|
||||
// Read specifically with UTF-8 to allow any non-UTF-encoded JSON to read
|
||||
return GeyserImpl.JSON_MAPPER.readValue(new InputStreamReader(src, StandardCharsets.UTF_8), valueType);
|
||||
return gson.fromJson(new InputStreamReader(src, StandardCharsets.UTF_8), valueType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
53
core/src/main/java/org/geysermc/geyser/util/JsonUtils.java
Normale Datei
53
core/src/main/java/org/geysermc/geyser/util/JsonUtils.java
Normale Datei
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public final class JsonUtils {
|
||||
|
||||
public static <T> T fromJson(byte[] bytes, Class<T> type) {
|
||||
return GeyserImpl.GSON.fromJson(new String(bytes, StandardCharsets.UTF_8), type);
|
||||
}
|
||||
|
||||
public static JsonObject fromJson(InputStream stream) {
|
||||
return (JsonObject) new JsonParser().parse(new InputStreamReader(stream));
|
||||
}
|
||||
|
||||
public static <T> T fromJson(InputStream stream, Type type) {
|
||||
return GeyserImpl.GSON.fromJson(new InputStreamReader(stream), type);
|
||||
}
|
||||
|
||||
private JsonUtils() {
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren