Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 07:40:10 +01:00
Merge master into extensions (#2941)
* Don't always store cert/client data used for skin uploaded This takes up a decent 30K of memory that we don't use after the skin is uploaded. The GameProfileTranslator cannot be run more than once per session. * Make all moon phases visible The fix to prevent integer overflows also prevented moon phases from being visible until now. Fixes #2927 * SetTimeTranslator: cast from long on the entire modulus This should fix some inaccuracies with time on older worlds. * Bump version; drop 1.17.40; support 1.18.30 * Actually bump to 2.0.3-SNAPSHOT * Fix message being sent still if a single escape character is sent * Replace instances of configs using `generateduuid` for Metrics * Fix some merge mistakes Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
Dieser Commit ist enthalten in:
Ursprung
d1cedbb823
Commit
03b067e23e
@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||
|
||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
||||
|
||||
### Currently supporting Minecraft Bedrock 1.17.41 + 1.18.0 - 1.18.10 and Minecraft Java 1.18.2.
|
||||
### Currently supporting Minecraft Bedrock 1.18.0 - 1.18.30 and Minecraft Java 1.18.2.
|
||||
|
||||
## Setting Up
|
||||
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
||||
|
@ -30,7 +30,7 @@ object Versions {
|
||||
const val guavaVersion = "29.0-jre"
|
||||
const val nbtVersion = "2.1.0"
|
||||
const val websocketVersion = "1.5.1"
|
||||
const val protocolVersion = "0cd24c0"
|
||||
const val protocolVersion = "29ecd7a"
|
||||
const val raknetVersion = "1.6.28-SNAPSHOT"
|
||||
const val mcauthlibVersion = "d9d773e"
|
||||
const val mcprotocollibversion = "0771504"
|
||||
|
@ -29,7 +29,7 @@ dependencies {
|
||||
// Network libraries
|
||||
implementation("org.java-websocket", "Java-WebSocket", Versions.websocketVersion)
|
||||
|
||||
api("com.github.CloudburstMC.Protocol", "bedrock-v486", Versions.protocolVersion) {
|
||||
api("com.github.CloudburstMC.Protocol", "bedrock-v503", Versions.protocolVersion) {
|
||||
exclude("com.nukkitx.network", "raknet")
|
||||
exclude("com.nukkitx", "nbt")
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.network.AuthType;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
import org.geysermc.geyser.network.CIDRMatcher;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -37,6 +37,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||
import com.nukkitx.protocol.bedrock.data.GameType;
|
||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||
import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
@ -126,6 +127,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
addPlayerPacket.setPlatformChatId("");
|
||||
addPlayerPacket.setGameType(GameType.SURVIVAL); //TODO
|
||||
addPlayerPacket.getMetadata().putFlags(flags);
|
||||
dirtyMetadata.apply(addPlayerPacket.getMetadata());
|
||||
|
||||
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.entity.type.player;
|
||||
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.data.GameType;
|
||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||
import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
@ -84,6 +85,7 @@ public class SkullPlayerEntity extends PlayerEntity {
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
addPlayerPacket.setPlatformChatId("");
|
||||
addPlayerPacket.setGameType(GameType.SURVIVAL);
|
||||
addPlayerPacket.getMetadata().putFlags(flags);
|
||||
dirtyMetadata.apply(addPlayerPacket.getMetadata());
|
||||
|
||||
|
41
core/src/main/java/org/geysermc/geyser/level/BedrockDimension.java
Normale Datei
41
core/src/main/java/org/geysermc/geyser/level/BedrockDimension.java
Normale Datei
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 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.level;
|
||||
|
||||
/**
|
||||
* A data structure to represent what Bedrock believes are the height requirements for a specific dimension.
|
||||
* As of 1.18.30, biome count is representative of the height of the world, and out-of-bounds chunks can crash
|
||||
* the client.
|
||||
*
|
||||
* @param minY The minimum height Bedrock Edition will accept.
|
||||
* @param height The maximum chunk height Bedrock Edition will accept, from the lowest point to the highest.
|
||||
* @param doUpperHeightWarn whether to warn in the console if the Java dimension height exceeds Bedrock's.
|
||||
*/
|
||||
public record BedrockDimension(int minY, int height, boolean doUpperHeightWarn) {
|
||||
public static BedrockDimension OVERWORLD = new BedrockDimension(-64, 384, true);
|
||||
public static BedrockDimension THE_NETHER = new BedrockDimension(0, 128, false);
|
||||
public static BedrockDimension THE_END = new BedrockDimension(0, 256, true);
|
||||
}
|
@ -26,8 +26,6 @@
|
||||
package org.geysermc.geyser.level.block;
|
||||
|
||||
import com.nukkitx.network.util.Preconditions;
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
public class BlockPositionIterator {
|
||||
private final int minX;
|
||||
|
@ -28,11 +28,14 @@ package org.geysermc.geyser.network;
|
||||
import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
|
||||
import com.github.steveice10.mc.protocol.codec.PacketCodec;
|
||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
|
||||
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
|
||||
import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
|
||||
import com.nukkitx.protocol.bedrock.v503.Bedrock_v503;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Contains information about the supported protocols in Geyser.
|
||||
@ -42,7 +45,7 @@ public final class GameProtocol {
|
||||
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
||||
* release of the game that Geyser supports.
|
||||
*/
|
||||
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v486.V486_CODEC;
|
||||
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v503.V503_CODEC;
|
||||
/**
|
||||
* A list of all supported Bedrock versions that can join Geyser
|
||||
*/
|
||||
@ -55,11 +58,11 @@ public final class GameProtocol {
|
||||
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
|
||||
|
||||
static {
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v471.V471_CODEC);
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v475.V475_CODEC.toBuilder().minecraftVersion("1.18.0/1.18.1/1.18.2").build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v486.V486_CODEC.toBuilder()
|
||||
.minecraftVersion("1.18.10/1.18.12") // 1.18.11 is also supported, but was only on Switch and since that auto-updates it's not needed
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,16 +32,17 @@ import com.nukkitx.protocol.bedrock.data.ResourcePackType;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.PendingMicrosoftAuthentication;
|
||||
import org.geysermc.geyser.api.network.AuthType;
|
||||
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.pack.ResourcePack;
|
||||
import org.geysermc.geyser.pack.ResourcePackManifest;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.PendingMicrosoftAuthentication;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.util.*;
|
||||
import org.geysermc.geyser.util.LoginEncryptionUtils;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
@ -28,8 +28,9 @@ package org.geysermc.geyser.registry.populator;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.nukkitx.nbt.*;
|
||||
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
|
||||
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
|
||||
import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
|
||||
import com.nukkitx.protocol.bedrock.v503.Bedrock_v503;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
@ -60,35 +61,50 @@ public class BlockRegistryPopulator {
|
||||
private static final ImmutableMap<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> BLOCK_MAPPERS;
|
||||
private static final BiFunction<String, NbtMapBuilder, String> EMPTY_MAPPER = (bedrockIdentifier, statesBuilder) -> null;
|
||||
|
||||
private static final BiFunction<String, NbtMapBuilder, String> V486_MAPPER = (bedrockIdentifier, statesBuilder) -> {
|
||||
statesBuilder.remove("no_drop_bit"); // Used in skulls
|
||||
if (bedrockIdentifier.equals("minecraft:glow_lichen")) {
|
||||
// Moved around north, south, west
|
||||
int bits = (int) statesBuilder.get("multi_face_direction_bits");
|
||||
boolean north = (bits & (1 << 2)) != 0;
|
||||
boolean south = (bits & (1 << 3)) != 0;
|
||||
boolean west = (bits & (1 << 4)) != 0;
|
||||
if (north) {
|
||||
bits |= 1 << 4;
|
||||
} else {
|
||||
bits &= ~(1 << 4);
|
||||
}
|
||||
if (south) {
|
||||
bits |= 1 << 2;
|
||||
} else {
|
||||
bits &= ~(1 << 2);
|
||||
}
|
||||
if (west) {
|
||||
bits |= 1 << 3;
|
||||
} else {
|
||||
bits &= ~(1 << 3);
|
||||
}
|
||||
statesBuilder.put("multi_face_direction_bits", bits);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
static {
|
||||
ImmutableMap.Builder<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> stateMapperBuilder = ImmutableMap.<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>>builder()
|
||||
.put(ObjectIntPair.of("1_17_40", Bedrock_v471.V471_CODEC.getProtocolVersion()), EMPTY_MAPPER)
|
||||
.put(ObjectIntPair.of("1_18_10", Bedrock_v486.V486_CODEC.getProtocolVersion()), (bedrockIdentifier, statesBuilder) -> {
|
||||
statesBuilder.remove("no_drop_bit"); // Used in skulls
|
||||
if (bedrockIdentifier.equals("minecraft:glow_lichen")) {
|
||||
// Moved around north, south, west
|
||||
int bits = (int) statesBuilder.get("multi_face_direction_bits");
|
||||
boolean north = (bits & (1 << 2)) != 0;
|
||||
boolean south = (bits & (1 << 3)) != 0;
|
||||
boolean west = (bits & (1 << 4)) != 0;
|
||||
if (north) {
|
||||
bits |= 1 << 4;
|
||||
} else {
|
||||
bits &= ~(1 << 4);
|
||||
}
|
||||
if (south) {
|
||||
bits |= 1 << 2;
|
||||
} else {
|
||||
bits &= ~(1 << 2);
|
||||
}
|
||||
if (west) {
|
||||
bits |= 1 << 3;
|
||||
} else {
|
||||
bits &= ~(1 << 3);
|
||||
}
|
||||
statesBuilder.put("multi_face_direction_bits", bits);
|
||||
}
|
||||
return null;
|
||||
.put(ObjectIntPair.of("1_18_0", Bedrock_v475.V475_CODEC.getProtocolVersion()), EMPTY_MAPPER)
|
||||
.put(ObjectIntPair.of("1_18_10", Bedrock_v486.V486_CODEC.getProtocolVersion()), V486_MAPPER)
|
||||
.put(ObjectIntPair.of("1_18_30", Bedrock_v503.V503_CODEC.getProtocolVersion()), (bedrockIdentifier, statesBuilder) -> {
|
||||
// Apply these fixes too
|
||||
V486_MAPPER.apply(bedrockIdentifier, statesBuilder);
|
||||
return switch (bedrockIdentifier) {
|
||||
case "minecraft:pistonArmCollision" -> "minecraft:piston_arm_collision";
|
||||
case "minecraft:stickyPistonArmCollision" -> "minecraft:sticky_piston_arm_collision";
|
||||
case "minecraft:movingBlock" -> "minecraft:moving_block";
|
||||
case "minecraft:tripWire" -> "minecraft:trip_wire";
|
||||
case "minecraft:seaLantern" -> "minecraft:sea_lantern";
|
||||
case "minecraft:concretePowder" -> "minecraft:concrete_powder";
|
||||
default -> null;
|
||||
};
|
||||
});
|
||||
|
||||
BLOCK_MAPPERS = stateMapperBuilder.build();
|
||||
|
@ -35,10 +35,12 @@ import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
|
||||
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
|
||||
import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import com.nukkitx.protocol.bedrock.v503.Bedrock_v503;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
@ -58,19 +60,16 @@ import java.util.*;
|
||||
* Populates the item registries.
|
||||
*/
|
||||
public class ItemRegistryPopulator {
|
||||
private static final Map<String, PaletteVersion> PALETTE_VERSIONS;
|
||||
|
||||
static {
|
||||
PALETTE_VERSIONS = new Object2ObjectOpenHashMap<>();
|
||||
PALETTE_VERSIONS.put("1_17_40", new PaletteVersion(Bedrock_v471.V471_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
PALETTE_VERSIONS.put("1_18_0", new PaletteVersion(Bedrock_v475.V475_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
PALETTE_VERSIONS.put("1_18_10", new PaletteVersion(Bedrock_v486.V486_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
}
|
||||
|
||||
private record PaletteVersion(int protocolVersion, Map<String, String> additionalTranslatedItems) {
|
||||
}
|
||||
|
||||
public static void populate() {
|
||||
Map<String, PaletteVersion> paletteVersions = new Object2ObjectOpenHashMap<>();
|
||||
paletteVersions.put("1_18_0", new PaletteVersion(Bedrock_v475.V475_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
paletteVersions.put("1_18_10", new PaletteVersion(Bedrock_v486.V486_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
paletteVersions.put("1_18_30", new PaletteVersion(Bedrock_v503.V503_CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
|
||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||
|
||||
TypeReference<Map<String, GeyserMappingItem>> mappingItemsType = new TypeReference<>() { };
|
||||
@ -88,7 +87,7 @@ public class ItemRegistryPopulator {
|
||||
Int2IntMap dyeColors = new FixedInt2IntMap();
|
||||
|
||||
/* Load item palette */
|
||||
for (Map.Entry<String, PaletteVersion> palette : PALETTE_VERSIONS.entrySet()) {
|
||||
for (Map.Entry<String, PaletteVersion> palette : paletteVersions.entrySet()) {
|
||||
TypeReference<List<PaletteItem>> paletteEntriesType = new TypeReference<>() {};
|
||||
|
||||
// Used to get the Bedrock namespaced ID (in instances where there are small differences)
|
||||
@ -232,12 +231,15 @@ public class ItemRegistryPopulator {
|
||||
}
|
||||
|
||||
String bedrockIdentifier;
|
||||
if (javaIdentifier.equals("minecraft:music_disc_otherside") && palette.getValue().protocolVersion() <= Bedrock_v471.V471_CODEC.getProtocolVersion()) {
|
||||
bedrockIdentifier = "minecraft:music_disc_pigstep";
|
||||
} else if (javaIdentifier.equals("minecraft:globe_banner_pattern") && palette.getValue().protocolVersion() < Bedrock_v486.V486_CODEC.getProtocolVersion()) {
|
||||
if (javaIdentifier.equals("minecraft:globe_banner_pattern") && palette.getValue().protocolVersion() < Bedrock_v486.V486_CODEC.getProtocolVersion()) {
|
||||
bedrockIdentifier = "minecraft:banner_pattern";
|
||||
} else {
|
||||
bedrockIdentifier = mappingItem.getBedrockIdentifier();
|
||||
if (palette.getValue().protocolVersion() >= Bedrock_v503.V503_CODEC.getProtocolVersion()) {
|
||||
if (bedrockIdentifier.equals("minecraft:sealantern")) {
|
||||
bedrockIdentifier = "minecraft:sea_lantern";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (usingFurnaceMinecart && javaIdentifier.equals("minecraft:furnace_minecart")) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.session;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsException;
|
||||
import com.github.steveice10.mc.auth.exception.request.RequestException;
|
||||
@ -66,7 +67,6 @@ import com.nukkitx.protocol.bedrock.data.*;
|
||||
import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
@ -144,6 +144,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
private AuthData authData;
|
||||
@Setter
|
||||
private BedrockClientData clientData;
|
||||
/**
|
||||
* Used for Floodgate skin uploading
|
||||
*/
|
||||
@Setter
|
||||
private JsonNode certChainData;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@Setter
|
||||
@ -1377,7 +1382,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
startGamePacket.setPlayerPosition(Vector3f.from(0, 69, 0));
|
||||
startGamePacket.setRotation(Vector2f.from(1, 1));
|
||||
|
||||
startGamePacket.setSeed(-1);
|
||||
startGamePacket.setSeed(-1L);
|
||||
startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(dimension));
|
||||
startGamePacket.setGeneratorId(1);
|
||||
startGamePacket.setLevelGameType(GameType.SURVIVAL);
|
||||
@ -1426,10 +1431,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
settings.setServerAuthoritativeBlockBreaking(false);
|
||||
startGamePacket.setPlayerMovementSettings(settings);
|
||||
|
||||
if (upstream.getProtocolVersion() <= Bedrock_v471.V471_CODEC.getProtocolVersion()) {
|
||||
startGamePacket.getExperiments().add(new ExperimentData("caves_and_cliffs", true));
|
||||
}
|
||||
|
||||
upstream.sendPacket(startGamePacket);
|
||||
}
|
||||
|
||||
|
@ -25,18 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.session.auth;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record AuthData(String name, UUID uuid, String xuid,
|
||||
JsonNode certChainData, String clientData) {
|
||||
|
||||
public void upload(GeyserImpl geyser) {
|
||||
// we can't upload the skin in LoginEncryptionUtil since the global server would return
|
||||
// the skin too fast, that's why we upload it after we know for sure that the target server
|
||||
// is ready to handle the result of the global server
|
||||
geyser.getSkinUploader().uploadSkin(certChainData, clientData);
|
||||
}
|
||||
public record AuthData(String name, UUID uuid, String xuid) {
|
||||
}
|
||||
|
@ -25,9 +25,11 @@
|
||||
|
||||
package org.geysermc.geyser.session.auth;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.floodgate.util.DeviceOs;
|
||||
import org.geysermc.floodgate.util.InputMode;
|
||||
import org.geysermc.floodgate.util.UiProfile;
|
||||
@ -107,6 +109,10 @@ public final class BedrockClientData {
|
||||
@JsonProperty(value = "PlayFabId")
|
||||
private String playFabId;
|
||||
|
||||
@JsonIgnore
|
||||
@Setter
|
||||
private String originalString = null;
|
||||
|
||||
public DeviceOs getDeviceOs() {
|
||||
return deviceOs != null ? deviceOs : DeviceOs.UNKNOWN;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import lombok.Setter;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.chunk.GeyserChunk;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
|
||||
public class ChunkCache {
|
||||
@ -45,11 +46,11 @@ public class ChunkCache {
|
||||
private int heightY;
|
||||
|
||||
/**
|
||||
* Whether the Bedrock client believes they are in a world with a minimum of -64 and maximum of 320
|
||||
* Which dimension Bedrock understands themselves to be in.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean isExtendedHeight = false;
|
||||
private BedrockDimension bedrockDimension = BedrockDimension.OVERWORLD;
|
||||
|
||||
public ChunkCache(GeyserSession session) {
|
||||
this.cache = !session.getGeyser().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing
|
||||
|
@ -40,11 +40,8 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||
public void translate(GeyserSession session, TextPacket packet) {
|
||||
String message = packet.getMessage();
|
||||
|
||||
if (message.isBlank()) {
|
||||
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!
|
||||
return;
|
||||
}
|
||||
|
||||
// The order here is important - strip out illegal characters first, then check if it's blank
|
||||
// (in case the message is blank after removing)
|
||||
if (message.indexOf(ChatColor.ESCAPE) != -1) {
|
||||
// Filter out all escape characters - Java doesn't let you type these
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@ -57,6 +54,11 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||
message = builder.toString();
|
||||
}
|
||||
|
||||
if (message.isBlank()) {
|
||||
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!
|
||||
return;
|
||||
}
|
||||
|
||||
if (MessageTranslator.isTooLong(message, session)) {
|
||||
return;
|
||||
}
|
||||
|
@ -37,14 +37,12 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
|
||||
@Translator(packet = MovePlayerPacket.class)
|
||||
public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPacket> {
|
||||
/* The upper and lower bounds to check for the void floor that only exists in Bedrock. These are the constants for the overworld. */
|
||||
private static final int BEDROCK_OVERWORLD_VOID_FLOOR_UPPER_Y = -104;
|
||||
private static final int BEDROCK_OVERWORLD_VOID_FLOOR_LOWER_Y = BEDROCK_OVERWORLD_VOID_FLOOR_UPPER_Y + 2;
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, MovePlayerPacket packet) {
|
||||
@ -124,11 +122,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
||||
|
||||
if (notMovingUp) {
|
||||
int floorY = position.getFloorY();
|
||||
// If the client believes the world has extended height, then it also believes the void floor
|
||||
// still exists, just at a lower spot
|
||||
boolean extendedWorld = session.getChunkCache().isExtendedHeight();
|
||||
if (floorY <= (extendedWorld ? BEDROCK_OVERWORLD_VOID_FLOOR_LOWER_Y : -38)
|
||||
&& floorY >= (extendedWorld ? BEDROCK_OVERWORLD_VOID_FLOOR_UPPER_Y : -40)) {
|
||||
// The void floor is offset about 40 blocks below the bottom of the world
|
||||
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
|
||||
int voidFloorLocation = bedrockDimension.minY() - 40;
|
||||
if (floorY <= (voidFloorLocation + 2) && floorY >= voidFloorLocation) {
|
||||
// Work around there being a floor at the bottom of the world and teleport the player below it
|
||||
// Moving from below to above the void floor works fine
|
||||
entity.setPosition(entity.getPosition().sub(0, 4f, 0));
|
||||
|
@ -57,7 +57,13 @@ public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameP
|
||||
if (remoteAuthType == AuthType.HYBRID) {
|
||||
// We'll send the skin upload a bit after the handshake packet (aka this packet),
|
||||
// because otherwise the global server returns the data too fast.
|
||||
session.getAuthData().upload(session.getGeyser());
|
||||
// We upload it after we know for sure that the target server
|
||||
// is ready to handle the result of the global server.
|
||||
session.getGeyser().getSkinUploader().uploadSkin(session.getCertChainData(), session.getClientData().getOriginalString());
|
||||
}
|
||||
|
||||
// We no longer need these variables; they're just taking up space in memory now
|
||||
session.setCertChainData(null);
|
||||
session.getClientData().setOriginalString(null);
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import com.nukkitx.network.VarInts;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
||||
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
|
||||
import com.nukkitx.protocol.bedrock.v503.Bedrock_v503;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
@ -52,26 +52,29 @@ import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTranslator;
|
||||
import org.geysermc.geyser.level.chunk.BlockStorage;
|
||||
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
|
||||
import org.geysermc.geyser.level.chunk.bitarray.BitArray;
|
||||
import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion;
|
||||
import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
import org.geysermc.geyser.util.ChunkUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.geysermc.geyser.util.ChunkUtils.*;
|
||||
|
||||
@ -98,13 +101,13 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
BitSet waterloggedPaletteIds = new BitSet();
|
||||
BitSet pistonOrFlowerPaletteIds = new BitSet();
|
||||
|
||||
boolean overworld = session.getChunkCache().isExtendedHeight();
|
||||
int maxBedrockSectionY = ((overworld ? MAXIMUM_ACCEPTED_HEIGHT_OVERWORLD : MAXIMUM_ACCEPTED_HEIGHT) >> 4) - 1;
|
||||
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
|
||||
int maxBedrockSectionY = (bedrockDimension.height() >> 4) - 1;
|
||||
|
||||
int sectionCount;
|
||||
byte[] payload;
|
||||
ByteBuf byteBuf = null;
|
||||
GeyserChunkSection[] sections = new GeyserChunkSection[javaChunks.length - (yOffset + ((overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4))];
|
||||
GeyserChunkSection[] sections = new GeyserChunkSection[javaChunks.length - (yOffset + (bedrockDimension.minY() >> 4))];
|
||||
|
||||
try {
|
||||
NetInput in = new StreamNetInput(new ByteArrayInputStream(packet.getChunkData()));
|
||||
@ -113,7 +116,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
javaChunks[sectionY] = javaSection.getChunkData();
|
||||
javaBiomes[sectionY] = javaSection.getBiomeData();
|
||||
|
||||
int bedrockSectionY = sectionY + (yOffset - ((overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4));
|
||||
int bedrockSectionY = sectionY + (yOffset - (bedrockDimension.minY() >> 4));
|
||||
if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) {
|
||||
// Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client
|
||||
continue;
|
||||
@ -309,11 +312,11 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
}
|
||||
}
|
||||
|
||||
// As of 1.17.10, Bedrock hardcodes to always read 32 biome sections
|
||||
// As of 1.18, this hardcode was lowered to 25
|
||||
boolean isNewVersion = session.getUpstream().getProtocolVersion() >= Bedrock_v475.V475_CODEC.getProtocolVersion();
|
||||
int biomeCount = isNewVersion ? 25 : 32;
|
||||
int dimensionOffset = (overworld ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT) >> 4;
|
||||
// As of 1.18.0, Bedrock hardcodes to always read 25 biome sections
|
||||
// As of 1.18.30, the hardcode may now be tied to the dimension definition
|
||||
boolean isNewVersion = session.getUpstream().getProtocolVersion() >= Bedrock_v503.V503_CODEC.getProtocolVersion();
|
||||
int biomeCount = isNewVersion ? bedrockDimension.height() >> 4 : 25;
|
||||
int dimensionOffset = bedrockDimension.minY() >> 4;
|
||||
for (int i = 0; i < biomeCount; i++) {
|
||||
int biomeYOffset = dimensionOffset + i;
|
||||
if (biomeYOffset < yOffset) {
|
||||
|
@ -42,7 +42,10 @@ public class JavaSetTimeTranslator extends PacketTranslator<ClientboundSetTimePa
|
||||
|
||||
// https://minecraft.gamepedia.com/Day-night_cycle#24-hour_Minecraft_day
|
||||
SetTimePacket setTimePacket = new SetTimePacket();
|
||||
setTimePacket.setTime((int) Math.abs(time) % 24000);
|
||||
// We use modulus to prevent an integer overflow
|
||||
// 24000 is the range of ticks that a Minecraft day can be; we times by 8 so all moon phases are visible
|
||||
// (Last verified behavior: Bedrock 1.18.12 / Java 1.18.2)
|
||||
setTimePacket.setTime((int) (Math.abs(time) % (24000 * 8)));
|
||||
session.sendUpstreamPacket(setTimePacket);
|
||||
if (!session.isDaylightCycle() && time >= 0) {
|
||||
// Client thinks there is no daylight cycle but there is
|
||||
|
@ -46,23 +46,13 @@ import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
||||
|
||||
import static org.geysermc.geyser.level.block.BlockStateValues.JAVA_AIR_ID;
|
||||
|
||||
@UtilityClass
|
||||
public class ChunkUtils {
|
||||
/**
|
||||
* The minimum height Bedrock Edition will accept.
|
||||
*/
|
||||
public static final int MINIMUM_ACCEPTED_HEIGHT = 0;
|
||||
public static final int MINIMUM_ACCEPTED_HEIGHT_OVERWORLD = -64;
|
||||
/**
|
||||
* The maximum chunk height Bedrock Edition will accept, from the lowest point to the highest.
|
||||
*/
|
||||
public static final int MAXIMUM_ACCEPTED_HEIGHT = 256;
|
||||
public static final int MAXIMUM_ACCEPTED_HEIGHT_OVERWORLD = 384;
|
||||
|
||||
/**
|
||||
* An empty subchunk.
|
||||
*/
|
||||
@ -249,17 +239,20 @@ public class ChunkUtils {
|
||||
throw new RuntimeException("Maximum Y must be a multiple of 16!");
|
||||
}
|
||||
|
||||
int dimension = DimensionUtils.javaToBedrock(session.getDimension());
|
||||
boolean extendedHeight = dimension == 0;
|
||||
session.getChunkCache().setExtendedHeight(extendedHeight);
|
||||
BedrockDimension bedrockDimension = switch (session.getDimension()) {
|
||||
case DimensionUtils.THE_END -> BedrockDimension.THE_END;
|
||||
case DimensionUtils.NETHER -> DimensionUtils.isCustomBedrockNetherId() ? BedrockDimension.THE_END : BedrockDimension.THE_NETHER;
|
||||
default -> BedrockDimension.OVERWORLD;
|
||||
};
|
||||
session.getChunkCache().setBedrockDimension(bedrockDimension);
|
||||
|
||||
// Yell in the console if the world height is too height in the current scenario
|
||||
// The constraints change depending on if the player is in the overworld or not, and if experimental height is enabled
|
||||
if (minY < (extendedHeight ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT)
|
||||
|| maxY > (extendedHeight ? MAXIMUM_ACCEPTED_HEIGHT_OVERWORLD : MAXIMUM_ACCEPTED_HEIGHT)) {
|
||||
// (Ignore this for the Nether. We can't change that at the moment without the workaround. :/ )
|
||||
if (minY < bedrockDimension.minY() || (bedrockDimension.doUpperHeightWarn() && maxY > bedrockDimension.height())) {
|
||||
session.getGeyser().getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.network.translator.chunk.out_of_bounds",
|
||||
extendedHeight ? MINIMUM_ACCEPTED_HEIGHT_OVERWORLD : MINIMUM_ACCEPTED_HEIGHT,
|
||||
extendedHeight ? MAXIMUM_ACCEPTED_HEIGHT_OVERWORLD : MAXIMUM_ACCEPTED_HEIGHT,
|
||||
String.valueOf(bedrockDimension.minY()),
|
||||
String.valueOf(bedrockDimension.height()),
|
||||
session.getDimension()));
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ public class DimensionUtils {
|
||||
// we check if the player is entering the nether and apply the nether fog to fake the fact that the client
|
||||
// thinks they are in the end dimension.
|
||||
if (BEDROCK_NETHER_ID == 2) {
|
||||
if (bedrockDimension == BEDROCK_NETHER_ID) {
|
||||
if (NETHER.equals(javaDimension)) {
|
||||
session.sendFog("minecraft:fog_hell");
|
||||
} else if (previousDimension == BEDROCK_NETHER_ID) {
|
||||
session.removeFog("minecraft:fog_hell");
|
||||
|
@ -155,10 +155,11 @@ public class LoginEncryptionUtils {
|
||||
session.setAuthenticationData(new AuthData(
|
||||
extraData.get("displayName").asText(),
|
||||
UUID.fromString(extraData.get("identity").asText()),
|
||||
extraData.get("XUID").asText(),
|
||||
certChainData, clientData
|
||||
extraData.get("XUID").asText()
|
||||
));
|
||||
|
||||
session.setCertChainData(certChainData);
|
||||
|
||||
if (payload.get("identityPublicKey").getNodeType() != JsonNodeType.STRING) {
|
||||
throw new RuntimeException("Identity Public Key was not found!");
|
||||
}
|
||||
@ -169,6 +170,7 @@ public class LoginEncryptionUtils {
|
||||
|
||||
JsonNode clientDataJson = JSON_MAPPER.readTree(clientJwt.getPayload().toBytes());
|
||||
BedrockClientData data = JSON_MAPPER.convertValue(clientDataJson, BedrockClientData.class);
|
||||
data.setOriginalString(clientData);
|
||||
session.setClientData(data);
|
||||
|
||||
if (EncryptionUtils.canUseEncryption()) {
|
||||
|
BIN
core/src/main/resources/bedrock/block_palette.1_18_30.nbt
Normale Datei
BIN
core/src/main/resources/bedrock/block_palette.1_18_30.nbt
Normale Datei
Binäre Datei nicht angezeigt.
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -7,6 +7,10 @@
|
||||
"name" : "minecraft:acacia_button",
|
||||
"id" : -140
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:acacia_chest_boat",
|
||||
"id" : 637
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:acacia_door",
|
||||
"id" : 556
|
||||
@ -51,6 +55,10 @@
|
||||
"name" : "minecraft:air",
|
||||
"id" : -158
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:allay_spawn_egg",
|
||||
"id" : 630
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:allow",
|
||||
"id" : 210
|
||||
@ -133,7 +141,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:banner_pattern",
|
||||
"id" : 628
|
||||
"id" : 642
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:barrel",
|
||||
@ -207,6 +215,10 @@
|
||||
"name" : "minecraft:birch_button",
|
||||
"id" : -141
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:birch_chest_boat",
|
||||
"id" : 634
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:birch_door",
|
||||
"id" : 554
|
||||
@ -317,7 +329,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:boat",
|
||||
"id" : 626
|
||||
"id" : 640
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:bone",
|
||||
@ -363,10 +375,6 @@
|
||||
"name" : "minecraft:brewing_stand",
|
||||
"id" : 431
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:brewingstandblock",
|
||||
"id" : 117
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:brick",
|
||||
"id" : 383
|
||||
@ -433,7 +441,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:campfire",
|
||||
"id" : 588
|
||||
"id" : 589
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:candle",
|
||||
@ -493,7 +501,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:chain",
|
||||
"id" : 618
|
||||
"id" : 619
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:chain_command_block",
|
||||
@ -531,6 +539,10 @@
|
||||
"name" : "minecraft:chest",
|
||||
"id" : 54
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:chest_boat",
|
||||
"id" : 639
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:chest_minecart",
|
||||
"id" : 389
|
||||
@ -797,7 +809,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:crimson_door",
|
||||
"id" : 615
|
||||
"id" : 616
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:crimson_double_slab",
|
||||
@ -837,7 +849,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:crimson_sign",
|
||||
"id" : 613
|
||||
"id" : 614
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:crimson_slab",
|
||||
@ -907,6 +919,10 @@
|
||||
"name" : "minecraft:dark_oak_button",
|
||||
"id" : -142
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:dark_oak_chest_boat",
|
||||
"id" : 638
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:dark_oak_door",
|
||||
"id" : 557
|
||||
@ -955,10 +971,6 @@
|
||||
"name" : "minecraft:deadbush",
|
||||
"id" : 32
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:debug_stick",
|
||||
"id" : 590
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:deepslate",
|
||||
"id" : -378
|
||||
@ -1177,7 +1189,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:dye",
|
||||
"id" : 627
|
||||
"id" : 641
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:egg",
|
||||
@ -1705,7 +1717,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:end_crystal",
|
||||
"id" : 630
|
||||
"id" : 644
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:end_gateway",
|
||||
@ -1811,6 +1823,10 @@
|
||||
"name" : "minecraft:fire_charge",
|
||||
"id" : 509
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:firefly_spawn_egg",
|
||||
"id" : 632
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:firework_rocket",
|
||||
"id" : 519
|
||||
@ -1863,6 +1879,14 @@
|
||||
"name" : "minecraft:frame",
|
||||
"id" : 513
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:frog_spawn",
|
||||
"id" : -468
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:frog_spawn_egg",
|
||||
"id" : 627
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:frosted_ice",
|
||||
"id" : 207
|
||||
@ -1899,13 +1923,17 @@
|
||||
"name" : "minecraft:glistering_melon_slice",
|
||||
"id" : 434
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:globe_banner_pattern",
|
||||
"id" : 588
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:glow_berries",
|
||||
"id" : 631
|
||||
"id" : 645
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:glow_frame",
|
||||
"id" : 622
|
||||
"id" : 623
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:glow_ink_sac",
|
||||
@ -1921,7 +1949,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:glow_stick",
|
||||
"id" : 166
|
||||
"id" : 601
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:glowingobsidian",
|
||||
@ -1935,10 +1963,6 @@
|
||||
"name" : "minecraft:glowstone_dust",
|
||||
"id" : 394
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:goat_horn",
|
||||
"id" : 623
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:goat_spawn_egg",
|
||||
"id" : 501
|
||||
@ -2168,7 +2192,7 @@
|
||||
"id" : 413
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:invisiblebedrock",
|
||||
"name" : "minecraft:invisible_bedrock",
|
||||
"id" : 95
|
||||
},
|
||||
{
|
||||
@ -2255,6 +2279,10 @@
|
||||
"name" : "minecraft:item.birch_door",
|
||||
"id" : 194
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:item.brewing_stand",
|
||||
"id" : 117
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:item.cake",
|
||||
"id" : 92
|
||||
@ -2363,6 +2391,10 @@
|
||||
"name" : "minecraft:jungle_button",
|
||||
"id" : -143
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:jungle_chest_boat",
|
||||
"id" : 635
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:jungle_door",
|
||||
"id" : 555
|
||||
@ -2577,7 +2609,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:lodestone_compass",
|
||||
"id" : 601
|
||||
"id" : 602
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:log",
|
||||
@ -2619,6 +2651,18 @@
|
||||
"name" : "minecraft:magma_cube_spawn_egg",
|
||||
"id" : 455
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mangrove_leaves",
|
||||
"id" : -472
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mangrove_propagule",
|
||||
"id" : -474
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mangrove_propagule_hanging",
|
||||
"id" : -476
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:medicine",
|
||||
"id" : 599
|
||||
@ -2688,9 +2732,33 @@
|
||||
"id" : -175
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:movingblock",
|
||||
"name" : "minecraft:moving_block",
|
||||
"id" : 250
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud",
|
||||
"id" : -473
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud_brick_double_slab",
|
||||
"id" : -479
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud_brick_slab",
|
||||
"id" : -478
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud_brick_stairs",
|
||||
"id" : -480
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud_brick_wall",
|
||||
"id" : -481
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mud_bricks",
|
||||
"id" : -475
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mule_spawn_egg",
|
||||
"id" : 466
|
||||
@ -2731,9 +2799,13 @@
|
||||
"name" : "minecraft:music_disc_mellohi",
|
||||
"id" : 540
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:music_disc_otherside",
|
||||
"id" : 626
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:music_disc_pigstep",
|
||||
"id" : 619
|
||||
"id" : 620
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:music_disc_stal",
|
||||
@ -2759,14 +2831,6 @@
|
||||
"name" : "minecraft:mycelium",
|
||||
"id" : 110
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mysterious_frame",
|
||||
"id" : -466
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:mysterious_frame_slot",
|
||||
"id" : -467
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:name_tag",
|
||||
"id" : 548
|
||||
@ -2793,7 +2857,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:nether_sprouts",
|
||||
"id" : 620
|
||||
"id" : 621
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:nether_star",
|
||||
@ -2813,7 +2877,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_axe",
|
||||
"id" : 606
|
||||
"id" : 607
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_block",
|
||||
@ -2821,43 +2885,43 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_boots",
|
||||
"id" : 611
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_chestplate",
|
||||
"id" : 609
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_helmet",
|
||||
"id" : 608
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_hoe",
|
||||
"id" : 607
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_ingot",
|
||||
"id" : 602
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_leggings",
|
||||
"id" : 610
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_pickaxe",
|
||||
"id" : 605
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_scrap",
|
||||
"id" : 612
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_chestplate",
|
||||
"id" : 610
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_helmet",
|
||||
"id" : 609
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_hoe",
|
||||
"id" : 608
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_ingot",
|
||||
"id" : 603
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_leggings",
|
||||
"id" : 611
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_pickaxe",
|
||||
"id" : 606
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_scrap",
|
||||
"id" : 613
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_shovel",
|
||||
"id" : 604
|
||||
"id" : 605
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherite_sword",
|
||||
"id" : 603
|
||||
"id" : 604
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:netherrack",
|
||||
@ -2883,6 +2947,10 @@
|
||||
"name" : "minecraft:oak_boat",
|
||||
"id" : 375
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:oak_chest_boat",
|
||||
"id" : 633
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:oak_sign",
|
||||
"id" : 358
|
||||
@ -2903,6 +2971,10 @@
|
||||
"name" : "minecraft:ocelot_spawn_egg",
|
||||
"id" : 451
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:ochre_froglight",
|
||||
"id" : -471
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:orange_candle",
|
||||
"id" : -414
|
||||
@ -2943,6 +3015,10 @@
|
||||
"name" : "minecraft:packed_ice",
|
||||
"id" : 174
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:packed_mud",
|
||||
"id" : -477
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:painting",
|
||||
"id" : 357
|
||||
@ -2959,6 +3035,10 @@
|
||||
"name" : "minecraft:parrot_spawn_egg",
|
||||
"id" : 478
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:pearlescent_froglight",
|
||||
"id" : -469
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:phantom_membrane",
|
||||
"id" : 574
|
||||
@ -3008,7 +3088,7 @@
|
||||
"id" : 33
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:pistonarmcollision",
|
||||
"name" : "minecraft:piston_arm_collision",
|
||||
"id" : 34
|
||||
},
|
||||
{
|
||||
@ -3387,6 +3467,10 @@
|
||||
"name" : "minecraft:redstone_wire",
|
||||
"id" : 55
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:reinforced_deepslate",
|
||||
"id" : -466
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:repeater",
|
||||
"id" : 419
|
||||
@ -3467,6 +3551,10 @@
|
||||
"name" : "minecraft:scute",
|
||||
"id" : 572
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:sea_lantern",
|
||||
"id" : 169
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:sea_pickle",
|
||||
"id" : -156
|
||||
@ -3475,10 +3563,6 @@
|
||||
"name" : "minecraft:seagrass",
|
||||
"id" : -130
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:sealantern",
|
||||
"id" : 169
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:shears",
|
||||
"id" : 421
|
||||
@ -3593,7 +3677,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:soul_campfire",
|
||||
"id" : 621
|
||||
"id" : 622
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:soul_fire",
|
||||
@ -3621,7 +3705,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:spawn_egg",
|
||||
"id" : 629
|
||||
"id" : 643
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:spider_eye",
|
||||
@ -3651,6 +3735,10 @@
|
||||
"name" : "minecraft:spruce_button",
|
||||
"id" : -144
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:spruce_chest_boat",
|
||||
"id" : 636
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:spruce_door",
|
||||
"id" : 553
|
||||
@ -3720,7 +3808,7 @@
|
||||
"id" : 29
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:stickypistonarmcollision",
|
||||
"name" : "minecraft:sticky_piston_arm_collision",
|
||||
"id" : -217
|
||||
},
|
||||
{
|
||||
@ -3845,7 +3933,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:suspicious_stew",
|
||||
"id" : 589
|
||||
"id" : 590
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:sweet_berries",
|
||||
@ -3855,6 +3943,14 @@
|
||||
"name" : "minecraft:sweet_berry_bush",
|
||||
"id" : -207
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:tadpole_bucket",
|
||||
"id" : 629
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:tadpole_spawn_egg",
|
||||
"id" : 628
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:tallgrass",
|
||||
"id" : 31
|
||||
@ -3896,7 +3992,7 @@
|
||||
"id" : 546
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:tripwire",
|
||||
"name" : "minecraft:trip_wire",
|
||||
"id" : 132
|
||||
},
|
||||
{
|
||||
@ -3959,6 +4055,10 @@
|
||||
"name" : "minecraft:unpowered_repeater",
|
||||
"id" : 93
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:verdant_froglight",
|
||||
"id" : -470
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:vex_spawn_egg",
|
||||
"id" : 476
|
||||
@ -3987,13 +4087,17 @@
|
||||
"name" : "minecraft:wandering_trader_spawn_egg",
|
||||
"id" : 492
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warden_spawn_egg",
|
||||
"id" : 631
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_button",
|
||||
"id" : -261
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_door",
|
||||
"id" : 616
|
||||
"id" : 617
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_double_slab",
|
||||
@ -4013,7 +4117,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_fungus_on_a_stick",
|
||||
"id" : 617
|
||||
"id" : 618
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_hyphae",
|
||||
@ -4037,7 +4141,7 @@
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_sign",
|
||||
"id" : 614
|
||||
"id" : 615
|
||||
},
|
||||
{
|
||||
"name" : "minecraft:warped_slab",
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren