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 net.minecrell.terminalconsole.SimpleTerminalConsole;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.core.config.Configurator;
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||||
@ -84,7 +85,12 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements Gey
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void debug(String message) {
|
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
|
@Override
|
||||||
|
@ -26,6 +26,7 @@ package org.geysermc.geyser.platform.viaproxy;
|
|||||||
|
|
||||||
import net.raphimc.viaproxy.cli.ConsoleFormatter;
|
import net.raphimc.viaproxy.cli.ConsoleFormatter;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
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
|
@Override
|
||||||
public void setDebug(boolean debug) {
|
public void setDebug(boolean debug) {
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
|
@ -99,7 +99,10 @@ public interface GeyserLogger extends GeyserCommandSource {
|
|||||||
* @param object the object to log
|
* @param object the object to log
|
||||||
*/
|
*/
|
||||||
default void debug(@Nullable Object object) {
|
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.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
public interface GeyserConfig {
|
public interface GeyserConfig {
|
||||||
BedrockConfig bedrock();
|
BedrockConfig bedrock();
|
||||||
|
|
||||||
|
@ -25,11 +25,10 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.pack;
|
package org.geysermc.geyser.pack;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.google.gson.TypeAdapter;
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.geysermc.geyser.api.pack.ResourcePackManifest;
|
import org.geysermc.geyser.api.pack.ResourcePackManifest;
|
||||||
|
|
||||||
@ -37,15 +36,14 @@ import java.io.IOException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
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 Module(UUID uuid, Version version, String type, String description) implements ResourcePackManifest.Module { }
|
||||||
|
|
||||||
public record Dependency(UUID uuid, Version version) implements ResourcePackManifest.Dependency { }
|
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 {
|
public record Version(int major, int minor, int patch) implements ResourcePackManifest.Version {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -53,11 +51,17 @@ public record GeyserResourcePackManifest(@JsonProperty("format_version") int for
|
|||||||
return major + "." + minor + "." + patch;
|
return major + "." + minor + "." + patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class VersionDeserializer extends JsonDeserializer<Version> {
|
public static class VersionDeserializer extends TypeAdapter<Version> {
|
||||||
@Override
|
@Override
|
||||||
public Version deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
public void write(JsonWriter jsonWriter, Version version) throws IOException {
|
||||||
int[] version = ctxt.readValue(p, int[].class);
|
}
|
||||||
return new Version(version[0], version[1], version[2]);
|
|
||||||
|
@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;
|
package org.geysermc.geyser.ping;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import io.netty.handler.codec.haproxy.HAProxyCommand;
|
import io.netty.handler.codec.haproxy.HAProxyCommand;
|
||||||
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
|
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
|
||||||
import io.netty.util.NetUtil;
|
import io.netty.util.NetUtil;
|
||||||
@ -34,9 +33,19 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
import org.cloudburstmc.nbt.util.VarInts;
|
import org.cloudburstmc.nbt.util.VarInts;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
|
import org.geysermc.geyser.util.JsonUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.net.*;
|
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;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runnable {
|
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) {
|
} catch (SocketTimeoutException | ConnectException ex) {
|
||||||
this.pingInfo = null;
|
this.pingInfo = null;
|
||||||
this.geyser.getLogger().debug("Connection timeout for ping passthrough.");
|
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);
|
this.geyser.getLogger().error("Failed to parse json when pinging server!", ex);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
this.pingInfo = null;
|
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.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
import org.geysermc.geyser.util.JsonUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public class BiomeIdentifierRegistryLoader implements RegistryLoader<String, Obj
|
|||||||
Map<String, BiomeEntry> biomeEntries;
|
Map<String, BiomeEntry> biomeEntries;
|
||||||
|
|
||||||
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/biomes.json")) {
|
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) {
|
} catch (IOException e) {
|
||||||
throw new AssertionError("Unable to load Bedrock runtime biomes", e);
|
throw new AssertionError("Unable to load Bedrock runtime biomes", e);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.loader;
|
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.GeyserImpl;
|
||||||
import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent;
|
import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent;
|
||||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
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}.
|
* Loads {@link ResourcePack}s within a {@link Path} directory, firing the {@link GeyserLoadResourcePacksEvent}.
|
||||||
*/
|
*/
|
||||||
public class ResourcePackLoader implements RegistryLoader<Path, Map<String, ResourcePack>> {
|
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}");
|
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")) {
|
if (name.contains("manifest.json")) {
|
||||||
try {
|
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) {
|
if (manifest.header().uuid() != null) {
|
||||||
manifestReference.set(manifest);
|
manifestReference.set(manifest);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.mappings;
|
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.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
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;
|
||||||
import org.geysermc.geyser.registry.mappings.versions.MappingsReader_v1;
|
import org.geysermc.geyser.registry.mappings.versions.MappingsReader_v1;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -95,10 +97,10 @@ public class MappingsConfigReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable JsonNode getMappingsRoot(Path file) {
|
public @Nullable JsonObject getMappingsRoot(Path file) {
|
||||||
JsonNode mappingsRoot;
|
JsonObject mappingsRoot;
|
||||||
try {
|
try (FileReader reader = new FileReader(file.toFile())) {
|
||||||
mappingsRoot = GeyserImpl.JSON_MAPPER.readTree(file.toFile());
|
mappingsRoot = (JsonObject) new JsonParser().parse(reader);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
GeyserImpl.getInstance().getLogger().error("Failed to read custom mapping file: " + file, e);
|
GeyserImpl.getInstance().getLogger().error("Failed to read custom mapping file: " + file, e);
|
||||||
return null;
|
return null;
|
||||||
@ -112,8 +114,8 @@ public class MappingsConfigReader {
|
|||||||
return mappingsRoot;
|
return mappingsRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFormatVersion(JsonNode mappingsRoot, Path file) {
|
public int getFormatVersion(JsonObject mappingsRoot, Path file) {
|
||||||
int formatVersion = mappingsRoot.get("format_version").asInt();
|
int formatVersion = mappingsRoot.get("format_version").getAsInt();
|
||||||
if (!this.mappingReaders.containsKey(formatVersion)) {
|
if (!this.mappingReaders.containsKey(formatVersion)) {
|
||||||
GeyserImpl.getInstance().getLogger().error("Mappings file " + file + " has an unknown format version: " + formatVersion);
|
GeyserImpl.getInstance().getLogger().error("Mappings file " + file + " has an unknown format version: " + formatVersion);
|
||||||
return -1;
|
return -1;
|
||||||
@ -122,7 +124,7 @@ public class MappingsConfigReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void readItemMappingsFromJson(Path file, BiConsumer<String, CustomItemData> consumer) {
|
public void readItemMappingsFromJson(Path file, BiConsumer<String, CustomItemData> consumer) {
|
||||||
JsonNode mappingsRoot = getMappingsRoot(file);
|
JsonObject mappingsRoot = getMappingsRoot(file);
|
||||||
|
|
||||||
if (mappingsRoot == null) {
|
if (mappingsRoot == null) {
|
||||||
return;
|
return;
|
||||||
@ -138,7 +140,7 @@ public class MappingsConfigReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void readBlockMappingsFromJson(Path file, BiConsumer<String, CustomBlockMapping> consumer) {
|
public void readBlockMappingsFromJson(Path file, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||||
JsonNode mappingsRoot = getMappingsRoot(file);
|
JsonObject mappingsRoot = getMappingsRoot(file);
|
||||||
|
|
||||||
if (mappingsRoot == null) {
|
if (mappingsRoot == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.mappings.versions;
|
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.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||||
import org.geysermc.geyser.api.item.custom.CustomRenderOffsets;
|
import org.geysermc.geyser.api.item.custom.CustomRenderOffsets;
|
||||||
@ -36,14 +36,14 @@ import java.nio.file.Path;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public abstract class MappingsReader {
|
public abstract class MappingsReader {
|
||||||
public abstract void readItemMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomItemData> consumer);
|
public abstract void readItemMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomItemData> consumer);
|
||||||
public abstract void readBlockMappings(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer);
|
public abstract void readBlockMappings(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer);
|
||||||
|
|
||||||
public abstract CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMappingsFileException;
|
public abstract CustomItemData readItemMappingEntry(JsonObject node) throws InvalidCustomMappingsFileException;
|
||||||
public abstract CustomBlockMapping readBlockMappingEntry(String identifier, JsonNode node) throws InvalidCustomMappingsFileException;
|
public abstract CustomBlockMapping readBlockMappingEntry(String identifier, JsonObject node) throws InvalidCustomMappingsFileException;
|
||||||
|
|
||||||
protected @Nullable CustomRenderOffsets fromJsonNode(JsonNode node) {
|
protected @Nullable CustomRenderOffsets fromJsonObject(JsonObject node) {
|
||||||
if (node == null || !node.isObject()) {
|
if (node == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +53,8 @@ public abstract class MappingsReader {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CustomRenderOffsets.@Nullable Hand getHandOffsets(JsonNode node, String hand) {
|
protected CustomRenderOffsets.@Nullable Hand getHandOffsets(JsonObject node, String hand) {
|
||||||
JsonNode tmpNode = node.get(hand);
|
if (!(node.get(hand) instanceof JsonObject tmpNode)) {
|
||||||
if (tmpNode == null || !tmpNode.isObject()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,9 +64,8 @@ public abstract class MappingsReader {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CustomRenderOffsets.@Nullable Offset getPerspectiveOffsets(JsonNode node, String perspective) {
|
protected CustomRenderOffsets.@Nullable Offset getPerspectiveOffsets(JsonObject node, String perspective) {
|
||||||
JsonNode tmpNode = node.get(perspective);
|
if (!(node.get(perspective) instanceof JsonObject tmpNode)) {
|
||||||
if (tmpNode == null || !tmpNode.isObject()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +76,8 @@ public abstract class MappingsReader {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CustomRenderOffsets.@Nullable OffsetXYZ getOffsetXYZ(JsonNode node, String offsetType) {
|
protected CustomRenderOffsets.@Nullable OffsetXYZ getOffsetXYZ(JsonObject node, String offsetType) {
|
||||||
JsonNode tmpNode = node.get(offsetType);
|
if (!(node.get(offsetType) instanceof JsonObject tmpNode)) {
|
||||||
if (tmpNode == null || !tmpNode.isObject()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +86,9 @@ public abstract class MappingsReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new CustomRenderOffsets.OffsetXYZ(
|
return new CustomRenderOffsets.OffsetXYZ(
|
||||||
tmpNode.get("x").floatValue(),
|
tmpNode.get("x").getAsFloat(),
|
||||||
tmpNode.get("y").floatValue(),
|
tmpNode.get("y").getAsFloat(),
|
||||||
tmpNode.get("z").floatValue()
|
tmpNode.get("z").getAsFloat()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,10 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.mappings.versions;
|
package org.geysermc.geyser.registry.mappings.versions;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.google.gson.JsonArray;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
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.Object2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
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.CustomBlockData;
|
||||||
import org.geysermc.geyser.api.block.custom.CustomBlockPermutation;
|
import org.geysermc.geyser.api.block.custom.CustomBlockPermutation;
|
||||||
import org.geysermc.geyser.api.block.custom.CustomBlockState;
|
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.BlockFilterType;
|
||||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
|
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.CustomItemData;
|
||||||
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
|
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
|
||||||
import org.geysermc.geyser.api.util.CreativeCategory;
|
import org.geysermc.geyser.api.util.CreativeCategory;
|
||||||
@ -57,7 +64,13 @@ import org.geysermc.geyser.util.MathUtils;
|
|||||||
import org.geysermc.geyser.util.MinecraftKey;
|
import org.geysermc.geyser.util.MinecraftKey;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
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.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@ -68,7 +81,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class MappingsReader_v1 extends MappingsReader {
|
public class MappingsReader_v1 extends MappingsReader {
|
||||||
@Override
|
@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);
|
this.readItemMappingsV1(file, mappingsRoot, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,24 +89,24 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
* Read item block from a JSON node
|
* Read item block from a JSON node
|
||||||
*
|
*
|
||||||
* @param file The path to the file
|
* @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
|
* @param consumer The consumer to accept the mappings
|
||||||
* @see #readBlockMappingsV1(Path, JsonNode, BiConsumer)
|
* @see #readBlockMappingsV1(Path, JsonObject, BiConsumer)
|
||||||
*/
|
*/
|
||||||
@Override
|
@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);
|
this.readBlockMappingsV1(file, mappingsRoot, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readItemMappingsV1(Path file, JsonNode mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
public void readItemMappingsV1(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomItemData> consumer) {
|
||||||
JsonNode itemsNode = mappingsRoot.get("items");
|
JsonObject itemsNode = mappingsRoot.getAsJsonObject("items");
|
||||||
|
|
||||||
if (itemsNode != null && itemsNode.isObject()) {
|
if (itemsNode != null) {
|
||||||
itemsNode.fields().forEachRemaining(entry -> {
|
itemsNode.entrySet().forEach(entry -> {
|
||||||
if (entry.getValue().isArray()) {
|
if (entry.getValue() instanceof JsonArray array) {
|
||||||
entry.getValue().forEach(data -> {
|
array.forEach(data -> {
|
||||||
try {
|
try {
|
||||||
CustomItemData customItemData = this.readItemMappingEntry(data);
|
CustomItemData customItemData = this.readItemMappingEntry((JsonObject) data);
|
||||||
consumer.accept(entry.getKey(), customItemData);
|
consumer.accept(entry.getKey(), customItemData);
|
||||||
} catch (InvalidCustomMappingsFileException e) {
|
} catch (InvalidCustomMappingsFileException e) {
|
||||||
GeyserImpl.getInstance().getLogger().error("Error in registering items for custom mapping file: " + file.toString(), 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
|
* Read block mappings from a JSON node
|
||||||
*
|
*
|
||||||
* @param file The path to the file
|
* @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
|
* @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) {
|
public void readBlockMappingsV1(Path file, JsonObject mappingsRoot, BiConsumer<String, CustomBlockMapping> consumer) {
|
||||||
JsonNode blocksNode = mappingsRoot.get("blocks");
|
if (mappingsRoot.get("blocks") instanceof JsonObject blocksNode) {
|
||||||
|
blocksNode.entrySet().forEach(entry -> {
|
||||||
if (blocksNode != null && blocksNode.isObject()) {
|
if (entry.getValue() instanceof JsonObject jsonObject) {
|
||||||
blocksNode.fields().forEachRemaining(entry -> {
|
|
||||||
if (entry.getValue().isObject()) {
|
|
||||||
try {
|
try {
|
||||||
String identifier = MinecraftKey.key(entry.getKey()).asString();
|
String identifier = MinecraftKey.key(entry.getKey()).asString();
|
||||||
CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, entry.getValue());
|
CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, jsonObject);
|
||||||
consumer.accept(identifier, customBlockMapping);
|
consumer.accept(identifier, customBlockMapping);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
GeyserImpl.getInstance().getLogger().error("Error in registering blocks for custom mapping file: " + file.toString());
|
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();
|
CustomItemOptions.Builder customItemOptions = CustomItemOptions.builder();
|
||||||
|
|
||||||
JsonNode customModelData = node.get("custom_model_data");
|
JsonElement customModelData = node.get("custom_model_data");
|
||||||
if (customModelData != null && customModelData.isInt()) {
|
if (customModelData != null && customModelData.isJsonPrimitive()) {
|
||||||
customItemOptions.customModelData(customModelData.asInt());
|
customItemOptions.customModelData(customModelData.getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode damagePredicate = node.get("damage_predicate");
|
JsonElement damagePredicate = node.get("damage_predicate");
|
||||||
if (damagePredicate != null && damagePredicate.isInt()) {
|
if (damagePredicate != null && damagePredicate.isJsonPrimitive()) {
|
||||||
customItemOptions.damagePredicate(damagePredicate.asInt());
|
customItemOptions.damagePredicate(damagePredicate.getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode unbreakable = node.get("unbreakable");
|
JsonElement unbreakable = node.get("unbreakable");
|
||||||
if (unbreakable != null && unbreakable.isBoolean()) {
|
if (unbreakable != null && unbreakable.isJsonPrimitive()) {
|
||||||
customItemOptions.unbreakable(unbreakable.asBoolean());
|
customItemOptions.unbreakable(unbreakable.getAsBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode defaultItem = node.get("default");
|
JsonElement defaultItem = node.get("default");
|
||||||
if (defaultItem != null && defaultItem.isBoolean()) {
|
if (defaultItem != null && defaultItem.isJsonPrimitive()) {
|
||||||
customItemOptions.defaultItem(defaultItem.asBoolean());
|
customItemOptions.defaultItem(defaultItem.getAsBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
return customItemOptions.build();
|
return customItemOptions.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMappingsFileException {
|
public CustomItemData readItemMappingEntry(JsonObject node) throws InvalidCustomMappingsFileException {
|
||||||
if (node == null || !node.isObject()) {
|
if (node == null) {
|
||||||
throw new InvalidCustomMappingsFileException("Invalid item mappings entry");
|
throw new InvalidCustomMappingsFileException("Invalid item mappings entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode name = node.get("name");
|
JsonElement name = node.get("name");
|
||||||
if (name == null || !name.isTextual() || name.asText().isEmpty()) {
|
if (name == null || !name.isJsonPrimitive() || name.getAsString().isEmpty()) {
|
||||||
throw new InvalidCustomMappingsFileException("An item entry has no name");
|
throw new InvalidCustomMappingsFileException("An item entry has no name");
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomItemData.Builder customItemData = CustomItemData.builder()
|
CustomItemData.Builder customItemData = CustomItemData.builder()
|
||||||
.name(name.asText())
|
.name(name.getAsString())
|
||||||
.customItemOptions(this.readItemCustomItemOptions(node));
|
.customItemOptions(this.readItemCustomItemOptions(node));
|
||||||
|
|
||||||
//The next entries are optional
|
//The next entries are optional
|
||||||
if (node.has("display_name")) {
|
if (node.has("display_name")) {
|
||||||
customItemData.displayName(node.get("display_name").asText());
|
customItemData.displayName(node.get("display_name").getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("icon")) {
|
if (node.has("icon")) {
|
||||||
customItemData.icon(node.get("icon").asText());
|
customItemData.icon(node.get("icon").getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("creative_category")) {
|
if (node.has("creative_category")) {
|
||||||
customItemData.creativeCategory(node.get("creative_category").asInt());
|
customItemData.creativeCategory(node.get("creative_category").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("creative_group")) {
|
if (node.has("creative_group")) {
|
||||||
customItemData.creativeGroup(node.get("creative_group").asText());
|
customItemData.creativeGroup(node.get("creative_group").getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("allow_offhand")) {
|
if (node.has("allow_offhand")) {
|
||||||
customItemData.allowOffhand(node.get("allow_offhand").asBoolean());
|
customItemData.allowOffhand(node.get("allow_offhand").getAsBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("display_handheld")) {
|
if (node.has("display_handheld")) {
|
||||||
customItemData.displayHandheld(node.get("display_handheld").asBoolean());
|
customItemData.displayHandheld(node.get("display_handheld").getAsBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("texture_size")) {
|
if (node.has("texture_size")) {
|
||||||
customItemData.textureSize(node.get("texture_size").asInt());
|
customItemData.textureSize(node.get("texture_size").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("render_offsets")) {
|
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<>();
|
Set<String> tagsSet = new ObjectOpenHashSet<>();
|
||||||
tags.forEach(tag -> tagsSet.add(tag.asText()));
|
tags.forEach(tag -> tagsSet.add(tag.getAsString()));
|
||||||
customItemData.tags(tagsSet);
|
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
|
* Read a block mapping entry from a JSON node and Java identifier
|
||||||
*
|
*
|
||||||
* @param identifier The Java identifier of the block
|
* @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}
|
* @return The {@link CustomBlockMapping} record to be read by {@link org.geysermc.geyser.registry.populator.CustomBlockRegistryPopulator}
|
||||||
* @throws InvalidCustomMappingsFileException If the JSON node is invalid
|
* @throws InvalidCustomMappingsFileException If the JSON node is invalid
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CustomBlockMapping readBlockMappingEntry(String identifier, JsonNode node) throws InvalidCustomMappingsFileException {
|
public CustomBlockMapping readBlockMappingEntry(String identifier, JsonObject node) throws InvalidCustomMappingsFileException {
|
||||||
if (node == null || !node.isObject()) {
|
if (node == null) {
|
||||||
throw new InvalidCustomMappingsFileException("Invalid block mappings entry:" + node);
|
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()) {
|
if (name == null || name.isEmpty()) {
|
||||||
throw new InvalidCustomMappingsFileException("A block entry has no name");
|
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;
|
CreativeCategory creativeCategory = CreativeCategory.NONE;
|
||||||
if (node.has("creative_category")) {
|
if (node.has("creative_category")) {
|
||||||
String categoryName = node.get("creative_category").asText();
|
String categoryName = node.get("creative_category").getAsString();
|
||||||
try {
|
try {
|
||||||
creativeCategory = CreativeCategory.valueOf(categoryName.toUpperCase());
|
creativeCategory = CreativeCategory.valueOf(categoryName.toUpperCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
@ -249,11 +260,11 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
|
|
||||||
String creativeGroup = "";
|
String creativeGroup = "";
|
||||||
if (node.has("creative_group")) {
|
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
|
// 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
|
// Create the data for the overall block
|
||||||
CustomBlockData.Builder customBlockDataBuilder = new GeyserCustomBlockData.Builder()
|
CustomBlockData.Builder customBlockDataBuilder = new GeyserCustomBlockData.Builder()
|
||||||
@ -273,12 +284,9 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
|
|
||||||
Map<String, CustomBlockComponentsMapping> componentsMap = new LinkedHashMap<>();
|
Map<String, CustomBlockComponentsMapping> componentsMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
JsonNode stateOverrides = node.get("state_overrides");
|
if (node.get("state_overrides") instanceof JsonObject stateOverrides) {
|
||||||
if (stateOverrides != null && stateOverrides.isObject()) {
|
|
||||||
// Load components for specific Java block states
|
// Load components for specific Java block states
|
||||||
Iterator<Map.Entry<String, JsonNode>> fields = stateOverrides.fields();
|
for (Map.Entry<String, JsonElement> overrideEntry : stateOverrides.entrySet()) {
|
||||||
while (fields.hasNext()) {
|
|
||||||
Map.Entry<String, JsonNode> overrideEntry = fields.next();
|
|
||||||
String state = identifier + "[" + overrideEntry.getKey() + "]";
|
String state = identifier + "[" + overrideEntry.getKey() + "]";
|
||||||
if (!BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().containsKey(state)) {
|
if (!BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().containsKey(state)) {
|
||||||
throw new InvalidCustomMappingsFileException("Unknown Java block state: " + state + " for state_overrides.");
|
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
|
* 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 stateKey the Java block state identifier
|
||||||
* @param name the name of the custom block
|
* @param name the name of the custom block
|
||||||
* @return the {@link CustomBlockComponents} object
|
* @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
|
// This is needed to find the correct selection box for the given block
|
||||||
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(stateKey, -1);
|
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(stateKey, -1);
|
||||||
BoxComponent boxComponent = createBoxComponent(id);
|
BoxComponent boxComponent = createBoxComponent(id);
|
||||||
@ -372,7 +380,7 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
.collisionBox(boxComponent)
|
.collisionBox(boxComponent)
|
||||||
.selectionBox(boxComponent);
|
.selectionBox(boxComponent);
|
||||||
|
|
||||||
if (node == null) {
|
if (!(element instanceof JsonObject node)) {
|
||||||
// No other components were defined
|
// No other components were defined
|
||||||
return new CustomBlockComponentsMapping(builder.build(), extendedBoxComponent);
|
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
|
// We set this to max value by default so that we may dictate the correct destroy time ourselves
|
||||||
float destructibleByMining = Float.MAX_VALUE;
|
float destructibleByMining = Float.MAX_VALUE;
|
||||||
if (node.has("destructible_by_mining")) {
|
if (node.has("destructible_by_mining")) {
|
||||||
destructibleByMining = node.get("destructible_by_mining").floatValue();
|
destructibleByMining = node.get("destructible_by_mining").getAsFloat();
|
||||||
}
|
}
|
||||||
builder.destructibleByMining(destructibleByMining);
|
builder.destructibleByMining(destructibleByMining);
|
||||||
|
|
||||||
if (node.has("geometry")) {
|
if (node.has("geometry")) {
|
||||||
if (node.get("geometry").isTextual()) {
|
if (node.get("geometry").isJsonPrimitive()) {
|
||||||
builder.geometry(new GeyserGeometryComponent.Builder()
|
builder.geometry(new GeyserGeometryComponent.Builder()
|
||||||
.identifier(node.get("geometry").asText())
|
.identifier(node.get("geometry").getAsString())
|
||||||
.build());
|
.build());
|
||||||
} else {
|
} else {
|
||||||
JsonNode geometry = node.get("geometry");
|
JsonObject geometry = node.getAsJsonObject("geometry");
|
||||||
GeometryComponent.Builder geometryBuilder = new GeyserGeometryComponent.Builder();
|
GeometryComponent.Builder geometryBuilder = new GeyserGeometryComponent.Builder();
|
||||||
if (geometry.has("identifier")) {
|
if (geometry.has("identifier")) {
|
||||||
geometryBuilder.identifier(geometry.get("identifier").asText());
|
geometryBuilder.identifier(geometry.get("identifier").getAsString());
|
||||||
}
|
}
|
||||||
if (geometry.has("bone_visibility")) {
|
if (geometry.has("bone_visibility")) {
|
||||||
JsonNode boneVisibility = geometry.get("bone_visibility");
|
if (geometry.get("bone_visibility") instanceof JsonObject boneVisibility) {
|
||||||
if (boneVisibility.isObject()) {
|
|
||||||
Map<String, String> boneVisibilityMap = new Object2ObjectOpenHashMap<>();
|
Map<String, String> boneVisibilityMap = new Object2ObjectOpenHashMap<>();
|
||||||
boneVisibility.fields().forEachRemaining(entry -> {
|
boneVisibility.entrySet().forEach(entry -> {
|
||||||
String key = entry.getKey();
|
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);
|
boneVisibilityMap.put(key, value);
|
||||||
});
|
});
|
||||||
geometryBuilder.boneVisibility(boneVisibilityMap);
|
geometryBuilder.boneVisibility(boneVisibilityMap);
|
||||||
@ -427,30 +435,30 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
|
|
||||||
String displayName = name;
|
String displayName = name;
|
||||||
if (node.has("display_name")) {
|
if (node.has("display_name")) {
|
||||||
displayName = node.get("display_name").asText();
|
displayName = node.get("display_name").getAsString();
|
||||||
}
|
}
|
||||||
builder.displayName(displayName);
|
builder.displayName(displayName);
|
||||||
|
|
||||||
if (node.has("friction")) {
|
if (node.has("friction")) {
|
||||||
builder.friction(node.get("friction").floatValue());
|
builder.friction(node.get("friction").getAsFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("light_emission")) {
|
if (node.has("light_emission")) {
|
||||||
builder.lightEmission(node.get("light_emission").asInt());
|
builder.lightEmission(node.get("light_emission").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("light_dampening")) {
|
if (node.has("light_dampening")) {
|
||||||
builder.lightDampening(node.get("light_dampening").asInt());
|
builder.lightDampening(node.get("light_dampening").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean placeAir = true;
|
boolean placeAir = true;
|
||||||
if (node.has("place_air")) {
|
if (node.has("place_air")) {
|
||||||
placeAir = node.get("place_air").asBoolean();
|
placeAir = node.get("place_air").getAsBoolean();
|
||||||
}
|
}
|
||||||
builder.placeAir(placeAir);
|
builder.placeAir(placeAir);
|
||||||
|
|
||||||
if (node.has("transformation")) {
|
if (node.has("transformation")) {
|
||||||
JsonNode transformation = node.get("transformation");
|
JsonObject transformation = node.getAsJsonObject("transformation");
|
||||||
|
|
||||||
int rotationX = 0;
|
int rotationX = 0;
|
||||||
int rotationY = 0;
|
int rotationY = 0;
|
||||||
@ -463,22 +471,22 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
float transformZ = 0;
|
float transformZ = 0;
|
||||||
|
|
||||||
if (transformation.has("rotation")) {
|
if (transformation.has("rotation")) {
|
||||||
JsonNode rotation = transformation.get("rotation");
|
JsonArray rotation = transformation.getAsJsonArray("rotation");
|
||||||
rotationX = rotation.get(0).asInt();
|
rotationX = rotation.get(0).getAsInt();
|
||||||
rotationY = rotation.get(1).asInt();
|
rotationY = rotation.get(1).getAsInt();
|
||||||
rotationZ = rotation.get(2).asInt();
|
rotationZ = rotation.get(2).getAsInt();
|
||||||
}
|
}
|
||||||
if (transformation.has("scale")) {
|
if (transformation.has("scale")) {
|
||||||
JsonNode scale = transformation.get("scale");
|
JsonArray scale = transformation.getAsJsonArray("scale");
|
||||||
scaleX = scale.get(0).floatValue();
|
scaleX = scale.get(0).getAsFloat();
|
||||||
scaleY = scale.get(1).floatValue();
|
scaleY = scale.get(1).getAsFloat();
|
||||||
scaleZ = scale.get(2).floatValue();
|
scaleZ = scale.get(2).getAsFloat();
|
||||||
}
|
}
|
||||||
if (transformation.has("translation")) {
|
if (transformation.has("translation")) {
|
||||||
JsonNode translation = transformation.get("translation");
|
JsonArray translation = transformation.getAsJsonArray("translation");
|
||||||
transformX = translation.get(0).floatValue();
|
transformX = translation.get(0).getAsFloat();
|
||||||
transformY = translation.get(1).floatValue();
|
transformY = translation.get(1).getAsFloat();
|
||||||
transformZ = translation.get(2).floatValue();
|
transformZ = translation.get(2).getAsFloat();
|
||||||
}
|
}
|
||||||
builder.transformation(new TransformationComponent(rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, transformX, transformY, transformZ));
|
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")) {
|
if (node.has("material_instances")) {
|
||||||
JsonNode materialInstances = node.get("material_instances");
|
if (node.get("material_instances") instanceof JsonObject materialInstances) {
|
||||||
if (materialInstances.isObject()) {
|
materialInstances.entrySet().forEach(entry -> {
|
||||||
materialInstances.fields().forEachRemaining(entry -> {
|
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
JsonNode value = entry.getValue();
|
if (entry.getValue() instanceof JsonObject value) {
|
||||||
if (value.isObject()) {
|
|
||||||
MaterialInstance materialInstance = createMaterialInstanceComponent(value);
|
MaterialInstance materialInstance = createMaterialInstanceComponent(value);
|
||||||
builder.materialInstance(key, materialInstance);
|
builder.materialInstance(key, materialInstance);
|
||||||
}
|
}
|
||||||
@ -503,16 +509,10 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.has("placement_filter")) {
|
if (node.get("placement_filter") instanceof JsonObject placementFilter) {
|
||||||
JsonNode placementFilter = node.get("placement_filter");
|
if (placementFilter.get("conditions") instanceof JsonArray conditions) {
|
||||||
if (placementFilter.isObject()) {
|
List<PlacementConditions> filter = createPlacementFilterComponent(conditions);
|
||||||
if (placementFilter.has("conditions")) {
|
builder.placementFilter(filter);
|
||||||
JsonNode conditions = placementFilter.get("conditions");
|
|
||||||
if (conditions.isArray()) {
|
|
||||||
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
|
// 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
|
// 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
|
// 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<>();
|
Set<String> tagsSet = new ObjectOpenHashSet<>();
|
||||||
tags.forEach(tag -> tagsSet.add(tag.asText()));
|
tags.forEach(tag -> tagsSet.add(tag.getAsString()));
|
||||||
builder.tags(tagsSet);
|
builder.tags(tagsSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,21 +613,21 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
/**
|
/**
|
||||||
* Creates a {@link BoxComponent} from a JSON Node
|
* Creates a {@link BoxComponent} from a JSON Node
|
||||||
*
|
*
|
||||||
* @param node the JSON node
|
* @param element the JSON node
|
||||||
* @return the {@link BoxComponent}
|
* @return the {@link BoxComponent}
|
||||||
*/
|
*/
|
||||||
private @Nullable BoxComponent createBoxComponent(JsonNode node) {
|
private @Nullable BoxComponent createBoxComponent(JsonElement element) {
|
||||||
if (node != null && node.isObject()) {
|
if (element instanceof JsonObject node) {
|
||||||
if (node.has("origin") && node.has("size")) {
|
if (node.has("origin") && node.has("size")) {
|
||||||
JsonNode origin = node.get("origin");
|
JsonArray origin = node.getAsJsonArray("origin");
|
||||||
float originX = origin.get(0).floatValue();
|
float originX = origin.get(0).getAsFloat();
|
||||||
float originY = origin.get(1).floatValue();
|
float originY = origin.get(1).getAsFloat();
|
||||||
float originZ = origin.get(2).floatValue();
|
float originZ = origin.get(2).getAsFloat();
|
||||||
|
|
||||||
JsonNode size = node.get("size");
|
JsonArray size = node.getAsJsonArray("size");
|
||||||
float sizeX = size.get(0).floatValue();
|
float sizeX = size.get(0).getAsFloat();
|
||||||
float sizeY = size.get(1).floatValue();
|
float sizeY = size.get(1).getAsFloat();
|
||||||
float sizeZ = size.get(2).floatValue();
|
float sizeZ = size.get(2).getAsFloat();
|
||||||
|
|
||||||
return new BoxComponent(originX, originY, originZ, sizeX, sizeY, sizeZ);
|
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
|
* @param node the material instance node
|
||||||
* @return the {@link MaterialInstance}
|
* @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
|
// Set default values, and use what the user provides if they have provided something
|
||||||
String texture = null;
|
String texture = null;
|
||||||
if (node.has("texture")) {
|
if (node.has("texture")) {
|
||||||
texture = node.get("texture").asText();
|
texture = node.get("texture").getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String renderMethod = "opaque";
|
String renderMethod = "opaque";
|
||||||
if (node.has("render_method")) {
|
if (node.has("render_method")) {
|
||||||
renderMethod = node.get("render_method").asText();
|
renderMethod = node.get("render_method").getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean faceDimming = true;
|
boolean faceDimming = true;
|
||||||
if (node.has("face_dimming")) {
|
if (node.has("face_dimming")) {
|
||||||
faceDimming = node.get("face_dimming").asBoolean();
|
faceDimming = node.get("face_dimming").getAsBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ambientOcclusion = true;
|
boolean ambientOcclusion = true;
|
||||||
if (node.has("ambient_occlusion")) {
|
if (node.has("ambient_occlusion")) {
|
||||||
ambientOcclusion = node.get("ambient_occlusion").asBoolean();
|
ambientOcclusion = node.get("ambient_occlusion").getAsBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GeyserMaterialInstance.Builder()
|
return new GeyserMaterialInstance.Builder()
|
||||||
@ -678,32 +678,33 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
* @param node the conditions node
|
* @param node the conditions node
|
||||||
* @return the list of {@link PlacementConditions}
|
* @return the list of {@link PlacementConditions}
|
||||||
*/
|
*/
|
||||||
private List<PlacementConditions> createPlacementFilterComponent(JsonNode node) {
|
private List<PlacementConditions> createPlacementFilterComponent(JsonArray node) {
|
||||||
List<PlacementConditions> conditions = new ArrayList<>();
|
List<PlacementConditions> conditions = new ArrayList<>();
|
||||||
|
|
||||||
// The structure of the placement filter component is the most complex of the current components
|
// 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
|
// 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);
|
Set<Face> faces = EnumSet.noneOf(Face.class);
|
||||||
if (condition.has("allowed_faces")) {
|
if (condition.has("allowed_faces")) {
|
||||||
JsonNode allowedFaces = condition.get("allowed_faces");
|
if (condition.get("allowed_faces") instanceof JsonArray allowedFaces) {
|
||||||
if (allowedFaces.isArray()) {
|
allowedFaces.forEach(face -> faces.add(Face.valueOf(face.getAsString().toUpperCase())));
|
||||||
allowedFaces.forEach(face -> faces.add(Face.valueOf(face.asText().toUpperCase())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedHashMap<String, BlockFilterType> blockFilters = new LinkedHashMap<>();
|
LinkedHashMap<String, BlockFilterType> blockFilters = new LinkedHashMap<>();
|
||||||
if (condition.has("block_filter")) {
|
if (condition.has("block_filter")) {
|
||||||
JsonNode blockFilter = condition.get("block_filter");
|
if (condition.get("block_filter") instanceof JsonArray blockFilter) {
|
||||||
if (blockFilter.isArray()) {
|
|
||||||
blockFilter.forEach(filter -> {
|
blockFilter.forEach(filter -> {
|
||||||
if (filter.isObject()) {
|
if (filter instanceof JsonObject jsonObject) {
|
||||||
if (filter.has("tags")) {
|
if (jsonObject.has("tags")) {
|
||||||
JsonNode tags = filter.get("tags");
|
JsonElement tags = jsonObject.get("tags");
|
||||||
blockFilters.put(tags.asText(), BlockFilterType.TAG);
|
blockFilters.put(tags.getAsString(), BlockFilterType.TAG);
|
||||||
}
|
}
|
||||||
} else if (filter.isTextual()) {
|
} else if (filter instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||||
blockFilters.put(filter.asText(), BlockFilterType.BLOCK);
|
blockFilters.put(filter.getAsString(), BlockFilterType.BLOCK);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -25,17 +25,26 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.populator;
|
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.ImmutableMap;
|
||||||
import com.google.common.collect.Interner;
|
import com.google.common.collect.Interner;
|
||||||
import com.google.common.collect.Interners;
|
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.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
import it.unimi.dsi.fastutil.objects.*;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||||
import org.cloudburstmc.nbt.*;
|
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.v671.Bedrock_v671;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
|
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
|
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.BlockMappings;
|
||||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||||
import org.geysermc.geyser.util.BlockUtils;
|
import org.geysermc.geyser.util.BlockUtils;
|
||||||
|
import org.geysermc.geyser.util.JsonUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
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.stream.Stream;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@ -461,23 +479,23 @@ public final class BlockRegistryPopulator {
|
|||||||
|
|
||||||
BLOCKS_NBT = blocksNbt;
|
BLOCKS_NBT = blocksNbt;
|
||||||
|
|
||||||
JsonNode blockInteractionsJson;
|
JsonObject blockInteractionsJson;
|
||||||
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/interactions.json")) {
|
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/interactions.json")) {
|
||||||
blockInteractionsJson = GeyserImpl.JSON_MAPPER.readTree(stream);
|
blockInteractionsJson = JsonUtils.fromJson(stream);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("Unable to load Java block interaction mappings", e);
|
throw new AssertionError("Unable to load Java block interaction mappings", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockRegistries.INTERACTIVE.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("always_consumes")));
|
BlockRegistries.INTERACTIVE.set(toBlockStateSet(blockInteractionsJson.getAsJsonArray("always_consumes")));
|
||||||
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("requires_may_build")));
|
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet(blockInteractionsJson.getAsJsonArray("requires_may_build")));
|
||||||
|
|
||||||
BlockRegistries.BLOCK_STATES.freeze();
|
BlockRegistries.BLOCK_STATES.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BitSet toBlockStateSet(ArrayNode node) {
|
private static BitSet toBlockStateSet(JsonArray node) {
|
||||||
BitSet blockStateSet = new BitSet(node.size());
|
BitSet blockStateSet = new BitSet(node.size());
|
||||||
for (JsonNode javaIdentifier : node) {
|
for (JsonElement javaIdentifier : node) {
|
||||||
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.textValue()));
|
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.getAsString()));
|
||||||
}
|
}
|
||||||
return blockStateSet;
|
return blockStateSet;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.populator;
|
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.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
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.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||||
|
import org.geysermc.geyser.util.JsonUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -61,16 +64,16 @@ public class CreativeItemRegistryPopulator {
|
|||||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||||
|
|
||||||
// Load creative items
|
// Load creative items
|
||||||
JsonNode creativeItemEntries;
|
JsonArray creativeItemEntries;
|
||||||
try (InputStream stream = bootstrap.getResourceOrThrow(String.format("bedrock/creative_items.%s.json", palette.version()))) {
|
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) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("Unable to load creative items", e);
|
throw new AssertionError("Unable to load creative items", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockMappings blockMappings = BlockRegistries.BLOCKS.forVersion(palette.protocolVersion());
|
BlockMappings blockMappings = BlockRegistries.BLOCKS.forVersion(palette.protocolVersion());
|
||||||
for (JsonNode itemNode : creativeItemEntries) {
|
for (JsonElement itemNode : creativeItemEntries) {
|
||||||
ItemData.Builder itemBuilder = createItemData(itemNode, blockMappings, definitions);
|
ItemData.Builder itemBuilder = createItemData((JsonObject) itemNode, blockMappings, definitions);
|
||||||
if (itemBuilder == null) {
|
if (itemBuilder == null) {
|
||||||
continue;
|
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 count = 1;
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
int bedrockBlockRuntimeId;
|
int bedrockBlockRuntimeId;
|
||||||
NbtMap tag = null;
|
NbtMap tag = null;
|
||||||
|
|
||||||
String identifier = itemNode.get("id").textValue();
|
String identifier = itemNode.get("id").getAsString();
|
||||||
for (BiPredicate<String, Integer> predicate : JAVA_ONLY_ITEM_FILTER) {
|
for (BiPredicate<String, Integer> predicate : JAVA_ONLY_ITEM_FILTER) {
|
||||||
if (predicate.test(identifier, damage)) {
|
if (predicate.test(identifier, damage)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode damageNode = itemNode.get("damage");
|
JsonElement damageNode = itemNode.get("damage");
|
||||||
if (damageNode != null) {
|
if (damageNode != null) {
|
||||||
damage = damageNode.asInt();
|
damage = damageNode.getAsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode countNode = itemNode.get("count");
|
JsonElement countNode = itemNode.get("count");
|
||||||
if (countNode != null) {
|
if (countNode != null) {
|
||||||
count = countNode.asInt();
|
count = countNode.getAsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
GeyserBedrockBlock blockDefinition = null;
|
GeyserBedrockBlock blockDefinition = null;
|
||||||
JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
JsonElement blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
||||||
JsonNode blockStateNode;
|
JsonElement blockStateNode;
|
||||||
if (blockRuntimeIdNode != null) {
|
if (blockRuntimeIdNode != null) {
|
||||||
bedrockBlockRuntimeId = blockRuntimeIdNode.asInt();
|
bedrockBlockRuntimeId = blockRuntimeIdNode.getAsInt();
|
||||||
if (bedrockBlockRuntimeId == 0 && !identifier.equals("minecraft:blue_candle")) { // FIXME
|
if (bedrockBlockRuntimeId == 0 && !identifier.equals("minecraft:blue_candle")) { // FIXME
|
||||||
bedrockBlockRuntimeId = -1;
|
bedrockBlockRuntimeId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockDefinition = bedrockBlockRuntimeId == -1 ? null : blockMappings.getDefinition(bedrockBlockRuntimeId);
|
blockDefinition = bedrockBlockRuntimeId == -1 ? null : blockMappings.getDefinition(bedrockBlockRuntimeId);
|
||||||
} else if ((blockStateNode = itemNode.get("block_state_b64")) != null) {
|
} 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);
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
try {
|
try {
|
||||||
NbtMap stateTag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
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) {
|
if (nbtNode != null) {
|
||||||
byte[] bytes = Base64.getDecoder().decode(nbtNode.asText());
|
byte[] bytes = Base64.getDecoder().decode(nbtNode.getAsString());
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
try {
|
try {
|
||||||
tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
||||||
|
@ -25,15 +25,21 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.populator;
|
package org.geysermc.geyser.registry.populator;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.MultimapBuilder;
|
import com.google.common.collect.MultimapBuilder;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
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.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
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.item.type.Item;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
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.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;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,12 +112,12 @@ public class ItemRegistryPopulator {
|
|||||||
|
|
||||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||||
|
|
||||||
TypeReference<Map<String, GeyserMappingItem>> mappingItemsType = new TypeReference<>() { };
|
Type mappingItemsType = new TypeToken<Map<String, GeyserMappingItem>>() { }.getType();
|
||||||
|
|
||||||
Map<String, GeyserMappingItem> items;
|
Map<String, GeyserMappingItem> items;
|
||||||
try (InputStream stream = bootstrap.getResourceOrThrow("mappings/items.json")) {
|
try (InputStream stream = bootstrap.getResourceOrThrow("mappings/items.json")) {
|
||||||
// Load item mappings from Java Edition to Bedrock Edition
|
// Load item mappings from Java Edition to Bedrock Edition
|
||||||
items = GeyserImpl.JSON_MAPPER.readValue(stream, mappingItemsType);
|
items = JsonUtils.fromJson(stream, mappingItemsType);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||||
}
|
}
|
||||||
@ -126,11 +146,11 @@ public class ItemRegistryPopulator {
|
|||||||
|
|
||||||
/* Load item palette */
|
/* Load item palette */
|
||||||
for (PaletteVersion palette : paletteVersions) {
|
for (PaletteVersion palette : paletteVersions) {
|
||||||
TypeReference<List<PaletteItem>> paletteEntriesType = new TypeReference<>() {};
|
Type paletteEntriesType = new TypeToken<List<PaletteItem>>() { }.getType();
|
||||||
|
|
||||||
List<PaletteItem> itemEntries;
|
List<PaletteItem> itemEntries;
|
||||||
try (InputStream stream = bootstrap.getResourceOrThrow(String.format("bedrock/runtime_item_states.%s.json", palette.version()))) {
|
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) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
|
throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.registry.type;
|
package org.geysermc.geyser.registry.type;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -43,14 +43,14 @@ import lombok.With;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserMappingItem {
|
public class GeyserMappingItem {
|
||||||
@JsonProperty("bedrock_identifier") String bedrockIdentifier;
|
@SerializedName("bedrock_identifier") String bedrockIdentifier;
|
||||||
@JsonProperty("bedrock_data") int bedrockData;
|
@SerializedName("bedrock_data") int bedrockData;
|
||||||
Integer firstBlockRuntimeId;
|
Integer firstBlockRuntimeId;
|
||||||
Integer lastBlockRuntimeId;
|
Integer lastBlockRuntimeId;
|
||||||
@JsonProperty("tool_type") String toolType;
|
@SerializedName("tool_type") String toolType;
|
||||||
@JsonProperty("tool_tier") String toolTier;
|
@SerializedName("tool_tier") String toolTier;
|
||||||
@JsonProperty("armor_type") String armorType;
|
@SerializedName("armor_type") String armorType;
|
||||||
@JsonProperty("protection_value") int protectionValue;
|
@SerializedName("protection_value") int protectionValue;
|
||||||
@JsonProperty("is_edible") boolean edible = false;
|
@SerializedName("is_edible") boolean edible = false;
|
||||||
@JsonProperty("is_entity_placer") boolean entityPlacer = 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 {
|
public static @Nullable GameProfileData loadFromJson(String encodedJson) throws IOException, IllegalArgumentException {
|
||||||
|
// TODO use GameProfile method.
|
||||||
JsonNode skinObject;
|
JsonNode skinObject;
|
||||||
try {
|
try {
|
||||||
skinObject = GeyserImpl.JSON_MAPPER.readTree(new String(Base64.getDecoder().decode(encodedJson), StandardCharsets.UTF_8));
|
skinObject = GeyserImpl.JSON_MAPPER.readTree(new String(Base64.getDecoder().decode(encodedJson), StandardCharsets.UTF_8));
|
||||||
@ -334,4 +335,4 @@ public class SkinManager {
|
|||||||
|
|
||||||
private static final String DEFAULT_FLOODGATE_STEVE = "https://textures.minecraft.net/texture/31f477eb1a7beee631c2ca64d06f8f68fa93a3386d04452ab27f43acdf1b60cb";
|
private static final String DEFAULT_FLOODGATE_STEVE = "https://textures.minecraft.net/texture/31f477eb1a7beee631c2ca64d06f8f68fa93a3386d04452ab27f43acdf1b60cb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,13 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.text;
|
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.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.util.AssetUtils;
|
import org.geysermc.geyser.util.AssetUtils;
|
||||||
import org.geysermc.geyser.util.FileUtils;
|
import org.geysermc.geyser.util.FileUtils;
|
||||||
|
import org.geysermc.geyser.util.JsonUtils;
|
||||||
import org.geysermc.geyser.util.WebUtils;
|
import org.geysermc.geyser.util.WebUtils;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -39,7 +41,6 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -189,14 +190,12 @@ public class MinecraftLocale {
|
|||||||
// Read the localefile
|
// Read the localefile
|
||||||
try (InputStream localeStream = Files.newInputStream(localeFile, StandardOpenOption.READ)) {
|
try (InputStream localeStream = Files.newInputStream(localeFile, StandardOpenOption.READ)) {
|
||||||
// Parse the file as json
|
// Parse the file as json
|
||||||
JsonNode localeObj = GeyserImpl.JSON_MAPPER.readTree(localeStream);
|
JsonObject localeObj = JsonUtils.fromJson(localeStream);
|
||||||
|
|
||||||
// Parse all the locale fields
|
// Parse all the locale fields
|
||||||
Iterator<Map.Entry<String, JsonNode>> localeIterator = localeObj.fields();
|
|
||||||
Map<String, String> langMap = new HashMap<>();
|
Map<String, String> langMap = new HashMap<>();
|
||||||
while (localeIterator.hasNext()) {
|
for (Map.Entry<String, JsonElement> entry : localeObj.entrySet()) {
|
||||||
Map.Entry<String, JsonNode> entry = localeIterator.next();
|
langMap.put(entry.getKey(), entry.getValue().getAsString());
|
||||||
langMap.put(entry.getKey(), entry.getValue().asText());
|
|
||||||
}
|
}
|
||||||
return langMap;
|
return langMap;
|
||||||
} catch (FileNotFoundException e){
|
} catch (FileNotFoundException e){
|
||||||
@ -266,4 +265,4 @@ public class MinecraftLocale {
|
|||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,18 +25,28 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.util;
|
package org.geysermc.geyser.util;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.google.gson.JsonElement;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.google.gson.JsonObject;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
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.Files;
|
||||||
import java.nio.file.Path;
|
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.concurrent.CompletableFuture;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
@ -83,7 +93,7 @@ public final class AssetUtils {
|
|||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
// Get the version manifest from Mojang
|
// 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);
|
WebUtils.getBody("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest.class);
|
||||||
|
|
||||||
// Get the url for the latest version of the games manifest
|
// Get the url for the latest version of the games manifest
|
||||||
@ -101,26 +111,24 @@ public final class AssetUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the individual version manifest
|
// 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
|
// 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");
|
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
|
// 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
|
// Put each asset into an array for use later
|
||||||
Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields();
|
for (Map.Entry<String, JsonElement> entry : assets.entrySet()) {
|
||||||
while (assetIterator.hasNext()) {
|
|
||||||
Map.Entry<String, JsonNode> entry = assetIterator.next();
|
|
||||||
if (!entry.getKey().startsWith("minecraft/lang/")) {
|
if (!entry.getKey().startsWith("minecraft/lang/")) {
|
||||||
// No need to cache non-language assets as we don't use them
|
// No need to cache non-language assets as we don't use them
|
||||||
continue;
|
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);
|
ASSET_MAP.put(entry.getKey(), asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,106 +229,99 @@ public final class AssetUtils {
|
|||||||
|
|
||||||
/* Classes that map to JSON files served by Mojang */
|
/* Classes that map to JSON files served by Mojang */
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class VersionManifest {
|
static class VersionManifest {
|
||||||
@JsonProperty("latest")
|
@SerializedName("latest")
|
||||||
private LatestVersion latestVersion;
|
private LatestVersion latestVersion;
|
||||||
|
|
||||||
@JsonProperty("versions")
|
@SerializedName("versions")
|
||||||
private List<Version> versions;
|
private List<Version> versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class LatestVersion {
|
static class LatestVersion {
|
||||||
@JsonProperty("release")
|
@SerializedName("release")
|
||||||
private String release;
|
private String release;
|
||||||
|
|
||||||
@JsonProperty("snapshot")
|
@SerializedName("snapshot")
|
||||||
private String snapshot;
|
private String snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class Version {
|
static class Version {
|
||||||
@JsonProperty("id")
|
@SerializedName("id")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@JsonProperty("type")
|
@SerializedName("type")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
@JsonProperty("url")
|
@SerializedName("url")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
@JsonProperty("time")
|
@SerializedName("time")
|
||||||
private String time;
|
private String time;
|
||||||
|
|
||||||
@JsonProperty("releaseTime")
|
@SerializedName("releaseTime")
|
||||||
private String releaseTime;
|
private String releaseTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class VersionInfo {
|
static class VersionInfo {
|
||||||
@JsonProperty("id")
|
@SerializedName("id")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@JsonProperty("type")
|
@SerializedName("type")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
@JsonProperty("time")
|
@SerializedName("time")
|
||||||
private String time;
|
private String time;
|
||||||
|
|
||||||
@JsonProperty("releaseTime")
|
@SerializedName("releaseTime")
|
||||||
private String releaseTime;
|
private String releaseTime;
|
||||||
|
|
||||||
@JsonProperty("assetIndex")
|
@SerializedName("assetIndex")
|
||||||
private AssetIndex assetIndex;
|
private AssetIndex assetIndex;
|
||||||
|
|
||||||
@JsonProperty("downloads")
|
@SerializedName("downloads")
|
||||||
private Map<String, VersionDownload> downloads;
|
private Map<String, VersionDownload> downloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class VersionDownload {
|
static class VersionDownload {
|
||||||
@JsonProperty("sha1")
|
@SerializedName("sha1")
|
||||||
private String sha1;
|
private String sha1;
|
||||||
|
|
||||||
@JsonProperty("size")
|
@SerializedName("size")
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
@JsonProperty("url")
|
@SerializedName("url")
|
||||||
private String url;
|
private String url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
static class AssetIndex {
|
static class AssetIndex {
|
||||||
@JsonProperty("id")
|
@SerializedName("id")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@JsonProperty("sha1")
|
@SerializedName("sha1")
|
||||||
private String sha1;
|
private String sha1;
|
||||||
|
|
||||||
@JsonProperty("size")
|
@SerializedName("size")
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
@JsonProperty("totalSize")
|
@SerializedName("totalSize")
|
||||||
private int totalSize;
|
private int totalSize;
|
||||||
|
|
||||||
@JsonProperty("url")
|
@SerializedName("url")
|
||||||
private String url;
|
private String url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class Asset {
|
public static class Asset {
|
||||||
@JsonProperty("hash")
|
@SerializedName("hash")
|
||||||
private String hash;
|
private String hash;
|
||||||
|
|
||||||
@JsonProperty("size")
|
@SerializedName("size")
|
||||||
private int 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.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import org.geysermc.geyser.GeyserBootstrap;
|
import org.geysermc.geyser.GeyserBootstrap;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
|
||||||
@ -63,9 +64,13 @@ public class FileUtils {
|
|||||||
return objectMapper.readValue(src, valueType);
|
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
|
// 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