Merge remote-tracking branch 'upstream/master' into JE-1.19.3

This commit is contained in:
Konicai 2022-12-01 22:00:57 -05:00
commit 92aa2059d2
No known key found for this signature in database
GPG key ID: 710D09287708C823
31 changed files with 1174 additions and 10937 deletions

View file

@ -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! 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.19.0 - 1.19.40 and Minecraft Java 1.19.1/1.19.2. ### Currently supporting Minecraft Bedrock 1.19.20 - 1.19.50 and Minecraft Java 1.19.1/1.19.2.
## Setting Up ## Setting Up
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.

View file

@ -16,11 +16,11 @@ dependencies {
// Within the gradle plugin classpath, there is a version conflict between loom and some other // Within the gradle plugin classpath, there is a version conflict between loom and some other
// plugin for databind. This fixes it: minimum 2.13.2 is required by loom. // plugin for databind. This fixes it: minimum 2.13.2 is required by loom.
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0")
} }
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions { kotlinOptions {
jvmTarget = "16" jvmTarget = "16"
} }
} }

View file

@ -111,6 +111,8 @@ public interface GeyserConfiguration {
boolean isNotifyOnNewBedrockUpdate(); boolean isNotifyOnNewBedrockUpdate();
String getUnusableSpaceBlock();
IMetricsInfo getMetrics(); IMetricsInfo getMetrics();
int getPendingAuthenticationTimeout(); int getPendingAuthenticationTimeout();

View file

@ -154,6 +154,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
@JsonProperty("notify-on-new-bedrock-update") @JsonProperty("notify-on-new-bedrock-update")
private boolean notifyOnNewBedrockUpdate = true; private boolean notifyOnNewBedrockUpdate = true;
@JsonProperty("unusable-space-block")
private String unusableSpaceBlock = "minecraft:barrier";
private MetricsInfo metrics = new MetricsInfo(); private MetricsInfo metrics = new MetricsInfo();
@JsonProperty("pending-authentication-timeout") @JsonProperty("pending-authentication-timeout")

View file

@ -44,6 +44,8 @@ import lombok.Setter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.GeyserDirtyMetadata; import org.geysermc.geyser.entity.GeyserDirtyMetadata;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.EntityUtils;
@ -355,6 +357,7 @@ public class Entity {
setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02); setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
// Swimming is ignored here and instead we rely on the pose // Swimming is ignored here and instead we rely on the pose
setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);

View file

@ -76,7 +76,7 @@ public class AnvilContainer extends Container {
String originalName = ItemUtils.getCustomName(getInput().getNbt()); String originalName = ItemUtils.getCustomName(getInput().getNbt());
String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.locale()); String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.locale());
String plainNewName = MessageTranslator.convertToPlainText(rename, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename);
if (!plainOriginalName.equals(plainNewName)) { if (!plainOriginalName.equals(plainNewName)) {
// Strip out formatting since Java Edition does not allow it // Strip out formatting since Java Edition does not allow it
correctRename = plainNewName; correctRename = plainNewName;

View file

@ -25,7 +25,6 @@
package org.geysermc.geyser.inventory.holder; package org.geysermc.geyser.inventory.holder;
import com.google.common.collect.ImmutableSet;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
@ -35,11 +34,11 @@ import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.BlockUtils;
import org.geysermc.geyser.util.InventoryUtils;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -50,8 +49,6 @@ import java.util.Set;
* This class will attempt to use a real block first, if possible. * This class will attempt to use a real block first, if possible.
*/ */
public class BlockInventoryHolder extends InventoryHolder { public class BlockInventoryHolder extends InventoryHolder {
private static final int FAKE_BLOCK_DISTANCE = 1;
/** /**
* The default Java block ID to translate as a fake block * The default Java block ID to translate as a fake block
*/ */
@ -66,7 +63,7 @@ public class BlockInventoryHolder extends InventoryHolder {
Set<String> validBlocksTemp = new HashSet<>(validBlocks.length + 1); Set<String> validBlocksTemp = new HashSet<>(validBlocks.length + 1);
Collections.addAll(validBlocksTemp, validBlocks); Collections.addAll(validBlocksTemp, validBlocks);
validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
this.validBlocks = ImmutableSet.copyOf(validBlocksTemp); this.validBlocks = Set.copyOf(validBlocksTemp);
} else { } else {
this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
} }
@ -91,20 +88,10 @@ public class BlockInventoryHolder extends InventoryHolder {
} }
} }
// Check if a fake block can be placed, either above the player or beneath. Vector3i position = InventoryUtils.findAvailableWorldSpace(session);
BedrockDimension dimension = session.getChunkCache().getBedrockDimension(); if (position == null) {
int minY = dimension.minY(), maxY = minY + dimension.height();
Vector3i flatPlayerPosition = session.getPlayerEntity().getPosition().toInt();
Vector3i position = flatPlayerPosition.add(Vector3i.UP);
if (position.getY() < minY) {
return false; return false;
} }
if (position.getY() >= maxY) {
position = flatPlayerPosition.sub(0, 4, 0);
if (position.getY() >= maxY) {
return false;
}
}
UpdateBlockPacket blockPacket = new UpdateBlockPacket(); UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0); blockPacket.setDataLayer(0);

View file

@ -28,12 +28,11 @@ package org.geysermc.geyser.network;
import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
import com.github.steveice10.mc.protocol.codec.PacketCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.v527.Bedrock_v527;
import com.nukkitx.protocol.bedrock.v534.Bedrock_v534;
import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; import com.nukkitx.protocol.bedrock.v544.Bedrock_v544;
import com.nukkitx.protocol.bedrock.v545.Bedrock_v545; import com.nukkitx.protocol.bedrock.v545.Bedrock_v545;
import com.nukkitx.protocol.bedrock.v554.Bedrock_v554; import com.nukkitx.protocol.bedrock.v554.Bedrock_v554;
import com.nukkitx.protocol.bedrock.v557.Bedrock_v557; import com.nukkitx.protocol.bedrock.v557.Bedrock_v557;
import com.nukkitx.protocol.bedrock.v560.Bedrock_v560;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import java.util.ArrayList; import java.util.ArrayList;
@ -48,7 +47,7 @@ public final class GameProtocol {
* Default Bedrock codec that should act as a fallback. Should represent the latest available * Default Bedrock codec that should act as a fallback. Should represent the latest available
* release of the game that Geyser supports. * release of the game that Geyser supports.
*/ */
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v557.V557_CODEC; public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v560.V560_CODEC;
/** /**
* A list of all supported Bedrock versions that can join Geyser * A list of all supported Bedrock versions that can join Geyser
*/ */
@ -61,12 +60,6 @@ public final class GameProtocol {
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
static { static {
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v527.V527_CODEC.toBuilder()
.minecraftVersion("1.19.0/1.19.2")
.build());
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v534.V534_CODEC.toBuilder()
.minecraftVersion("1.19.10/1.19.11")
.build());
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v544.V544_CODEC); SUPPORTED_BEDROCK_CODECS.add(Bedrock_v544.V544_CODEC);
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v545.V545_CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(Bedrock_v545.V545_CODEC.toBuilder()
.minecraftVersion("1.19.21/1.19.22") .minecraftVersion("1.19.21/1.19.22")
@ -74,6 +67,7 @@ public final class GameProtocol {
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v554.V554_CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(Bedrock_v554.V554_CODEC.toBuilder()
.minecraftVersion("1.19.30/1.19.31") .minecraftVersion("1.19.30/1.19.31")
.build()); .build());
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v557.V557_CODEC);
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
} }
@ -93,14 +87,14 @@ public final class GameProtocol {
/* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */ /* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */
public static boolean supports1_19_10(GeyserSession session) {
return session.getUpstream().getProtocolVersion() >= Bedrock_v534.V534_CODEC.getProtocolVersion();
}
public static boolean supports1_19_30(GeyserSession session) { public static boolean supports1_19_30(GeyserSession session) {
return session.getUpstream().getProtocolVersion() >= Bedrock_v554.V554_CODEC.getProtocolVersion(); return session.getUpstream().getProtocolVersion() >= Bedrock_v554.V554_CODEC.getProtocolVersion();
} }
public static boolean supports1_19_50(GeyserSession session) {
return session.getUpstream().getProtocolVersion() >= Bedrock_v560.V560_CODEC.getProtocolVersion();
}
/** /**
* Gets the {@link PacketCodec} for Minecraft: Java Edition. * Gets the {@link PacketCodec} for Minecraft: Java Edition.
* *

View file

@ -46,9 +46,13 @@ import org.geysermc.geyser.util.MathUtils;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayDeque;
import java.util.Deque;
public class UpstreamPacketHandler extends LoggingPacketHandler { public class UpstreamPacketHandler extends LoggingPacketHandler {
private Deque<String> packsToSent = new ArrayDeque<>();
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) { public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
super(geyser, session); super(geyser, session);
} }
@ -161,24 +165,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
break; break;
case SEND_PACKS: case SEND_PACKS:
for(String id : packet.getPackIds()) { packsToSent.addAll(packet.getPackIds());
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket(); sendPackDataInfo(packsToSent.pop());
String[] packID = id.split("_");
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
ResourcePackManifest.Header header = pack.getManifest().getHeader();
data.setPackId(header.getUuid());
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
data.setChunkCount(chunkCount);
data.setCompressedPackSize(pack.getFile().length());
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
data.setHash(pack.getSha256());
data.setPackVersion(packID[1]);
data.setPremium(false);
data.setType(ResourcePackType.RESOURCE);
session.sendUpstreamPacket(data);
}
break; break;
case HAVE_ALL_PACKS: case HAVE_ALL_PACKS:
@ -271,7 +259,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
data.setPackId(packet.getPackId()); data.setPackId(packet.getPackId());
int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE; int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE;
byte[] packData = new byte[(int) MathUtils.constrain(pack.getFile().length() - offset, 0, ResourcePack.CHUNK_SIZE)]; long remainingSize = pack.getFile().length() - offset;
byte[] packData = new byte[(int) MathUtils.constrain(remainingSize, 0, ResourcePack.CHUNK_SIZE)];
try (InputStream inputStream = new FileInputStream(pack.getFile())) { try (InputStream inputStream = new FileInputStream(pack.getFile())) {
inputStream.skip(offset); inputStream.skip(offset);
@ -283,6 +272,31 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
data.setData(packData); data.setData(packData);
session.sendUpstreamPacket(data); session.sendUpstreamPacket(data);
// Check if it is the last chunk and send next pack in queue when available.
if (remainingSize <= ResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) {
sendPackDataInfo(packsToSent.pop());
}
return true; return true;
} }
private void sendPackDataInfo(String id) {
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
String[] packID = id.split("_");
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
ResourcePackManifest.Header header = pack.getManifest().getHeader();
data.setPackId(header.getUuid());
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
data.setChunkCount(chunkCount);
data.setCompressedPackSize(pack.getFile().length());
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
data.setHash(pack.getSha256());
data.setPackVersion(packID[1]);
data.setPremium(false);
data.setType(ResourcePackType.RESOURCE);
session.sendUpstreamPacket(data);
}
} }

View file

@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.nukkitx.nbt.*; import com.nukkitx.nbt.*;
import com.nukkitx.protocol.bedrock.v527.Bedrock_v527; import com.nukkitx.protocol.bedrock.v527.Bedrock_v527;
import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; import com.nukkitx.protocol.bedrock.v544.Bedrock_v544;
import com.nukkitx.protocol.bedrock.v560.Bedrock_v560;
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.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
@ -73,13 +74,9 @@ public final class BlockRegistryPopulator {
private static void registerBedrockBlocks() { private static void registerBedrockBlocks() {
BiFunction<String, NbtMapBuilder, String> emptyMapper = (bedrockIdentifier, statesBuilder) -> null; BiFunction<String, NbtMapBuilder, String> emptyMapper = (bedrockIdentifier, statesBuilder) -> null;
ImmutableMap<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> blockMappers = ImmutableMap.<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>>builder() ImmutableMap<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> blockMappers = ImmutableMap.<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>>builder()
.put(ObjectIntPair.of("1_19_0", Bedrock_v527.V527_CODEC.getProtocolVersion()), (bedrockIdentifier, statesBuilder) -> { .put(ObjectIntPair.of("1_19_20", Bedrock_v544.V544_CODEC.getProtocolVersion()), emptyMapper)
if (bedrockIdentifier.equals("minecraft:muddy_mangrove_roots")) { .put(ObjectIntPair.of("1_19_50", Bedrock_v560.V560_CODEC.getProtocolVersion()), emptyMapper)
statesBuilder.remove("pillar_axis"); .build();
}
return null;
})
.put(ObjectIntPair.of("1_19_20", Bedrock_v544.V544_CODEC.getProtocolVersion()), emptyMapper).build();
for (Map.Entry<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> palette : blockMappers.entrySet()) { for (Map.Entry<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> palette : blockMappers.entrySet()) {
NbtList<NbtMap> blocksTag; NbtList<NbtMap> blocksTag;

View file

@ -37,6 +37,7 @@ import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData; import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import com.nukkitx.protocol.bedrock.v560.Bedrock_v560;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import com.nukkitx.protocol.bedrock.v527.Bedrock_v527; import com.nukkitx.protocol.bedrock.v527.Bedrock_v527;
import com.nukkitx.protocol.bedrock.v534.Bedrock_v534; import com.nukkitx.protocol.bedrock.v534.Bedrock_v534;
@ -76,10 +77,8 @@ public class ItemRegistryPopulator {
public static void populate() { public static void populate() {
Map<String, PaletteVersion> paletteVersions = new Object2ObjectOpenHashMap<>(); Map<String, PaletteVersion> paletteVersions = new Object2ObjectOpenHashMap<>();
paletteVersions.put("1_19_0", new PaletteVersion(Bedrock_v527.V527_CODEC.getProtocolVersion(),
Collections.singletonMap("minecraft:trader_llama_spawn_egg", "minecraft:llama_spawn_egg")));
paletteVersions.put("1_19_10", new PaletteVersion(Bedrock_v534.V534_CODEC.getProtocolVersion(), Collections.emptyMap()));
paletteVersions.put("1_19_20", new PaletteVersion(Bedrock_v544.V544_CODEC.getProtocolVersion(), Collections.emptyMap())); paletteVersions.put("1_19_20", new PaletteVersion(Bedrock_v544.V544_CODEC.getProtocolVersion(), Collections.emptyMap()));
paletteVersions.put("1_19_50", new PaletteVersion(Bedrock_v560.V560_CODEC.getProtocolVersion(), Collections.emptyMap()));
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();

View file

@ -58,19 +58,55 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket; import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket;
import com.github.steveice10.packetlib.BuiltinFlags; import com.github.steveice10.packetlib.BuiltinFlags;
import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.event.session.ConnectedEvent;
import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
import com.github.steveice10.packetlib.event.session.PacketErrorEvent;
import com.github.steveice10.packetlib.event.session.PacketSendingEvent;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpClientSession; import com.github.steveice10.packetlib.tcp.TcpClientSession;
import com.github.steveice10.packetlib.tcp.TcpSession; import com.github.steveice10.packetlib.tcp.TcpSession;
import com.nukkitx.math.GenericMath; import com.nukkitx.math.GenericMath;
import com.nukkitx.math.vector.*; import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3d;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockPacket;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.data.Ability;
import com.nukkitx.protocol.bedrock.data.AbilityLayer;
import com.nukkitx.protocol.bedrock.data.AttributeData;
import com.nukkitx.protocol.bedrock.data.AuthoritativeMovementMode;
import com.nukkitx.protocol.bedrock.data.ChatRestrictionLevel;
import com.nukkitx.protocol.bedrock.data.GamePublishSetting;
import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.GameType;
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.SyncedPlayerMovementSettings;
import com.nukkitx.protocol.bedrock.data.command.CommandPermission; import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.AvailableEntityIdentifiersPacket;
import com.nukkitx.protocol.bedrock.packet.BiomeDefinitionListPacket;
import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
import com.nukkitx.protocol.bedrock.packet.ClientboundMapItemDataPacket;
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
import com.nukkitx.protocol.bedrock.packet.CreativeContentPacket;
import com.nukkitx.protocol.bedrock.packet.EmoteListPacket;
import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
import com.nukkitx.protocol.bedrock.packet.ItemComponentPacket;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerFogPacket;
import com.nukkitx.protocol.bedrock.packet.SetTimePacket;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket;
import com.nukkitx.protocol.bedrock.packet.TransferPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateAbilitiesPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateAdventureSettingsPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import it.unimi.dsi.fastutil.bytes.ByteArrays; import it.unimi.dsi.fastutil.bytes.ByteArrays;
@ -127,7 +163,20 @@ import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.session.auth.AuthData; import org.geysermc.geyser.session.auth.AuthData;
import org.geysermc.geyser.session.auth.BedrockClientData; import org.geysermc.geyser.session.auth.BedrockClientData;
import org.geysermc.geyser.session.cache.*; import org.geysermc.geyser.session.cache.AdvancementsCache;
import org.geysermc.geyser.session.cache.BookEditCache;
import org.geysermc.geyser.session.cache.ChunkCache;
import org.geysermc.geyser.session.cache.EntityCache;
import org.geysermc.geyser.session.cache.EntityEffectCache;
import org.geysermc.geyser.session.cache.FormCache;
import org.geysermc.geyser.session.cache.LodestoneCache;
import org.geysermc.geyser.session.cache.PistonCache;
import org.geysermc.geyser.session.cache.PreferencesCache;
import org.geysermc.geyser.session.cache.SkullCache;
import org.geysermc.geyser.session.cache.TagCache;
import org.geysermc.geyser.session.cache.TeleportCache;
import org.geysermc.geyser.session.cache.WorldBorder;
import org.geysermc.geyser.session.cache.WorldCache;
import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.skin.FloodgateSkinUploader;
import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.text.MinecraftLocale;
@ -143,7 +192,14 @@ import java.net.ConnectException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -1630,76 +1686,40 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
boolean spectator = gameMode == GameMode.SPECTATOR; boolean spectator = gameMode == GameMode.SPECTATOR;
boolean worldImmutable = gameMode == GameMode.ADVENTURE || spectator; boolean worldImmutable = gameMode == GameMode.ADVENTURE || spectator;
if (GameProtocol.supports1_19_10(this)) { UpdateAdventureSettingsPacket adventureSettingsPacket = new UpdateAdventureSettingsPacket();
UpdateAdventureSettingsPacket adventureSettingsPacket = new UpdateAdventureSettingsPacket(); adventureSettingsPacket.setNoMvP(false);
adventureSettingsPacket.setNoMvP(false); adventureSettingsPacket.setNoPvM(false);
adventureSettingsPacket.setNoPvM(false); adventureSettingsPacket.setImmutableWorld(worldImmutable);
adventureSettingsPacket.setImmutableWorld(worldImmutable); adventureSettingsPacket.setShowNameTags(false);
adventureSettingsPacket.setShowNameTags(false); adventureSettingsPacket.setAutoJump(true);
adventureSettingsPacket.setAutoJump(true); sendUpstreamPacket(adventureSettingsPacket);
sendUpstreamPacket(adventureSettingsPacket);
UpdateAbilitiesPacket updateAbilitiesPacket = new UpdateAbilitiesPacket(); UpdateAbilitiesPacket updateAbilitiesPacket = new UpdateAbilitiesPacket();
updateAbilitiesPacket.setUniqueEntityId(bedrockId); updateAbilitiesPacket.setUniqueEntityId(bedrockId);
updateAbilitiesPacket.setCommandPermission(commandPermission); updateAbilitiesPacket.setCommandPermission(commandPermission);
updateAbilitiesPacket.setPlayerPermission(playerPermission); updateAbilitiesPacket.setPlayerPermission(playerPermission);
AbilityLayer abilityLayer = new AbilityLayer(); AbilityLayer abilityLayer = new AbilityLayer();
Set<Ability> abilities = abilityLayer.getAbilityValues(); Set<Ability> abilities = abilityLayer.getAbilityValues();
if (canFly || spectator) { if (canFly || spectator) {
abilities.add(Ability.MAY_FLY); abilities.add(Ability.MAY_FLY);
}
// Default stuff we have to fill in
abilities.add(Ability.BUILD);
abilities.add(Ability.MINE);
// Needed so you can drop items
abilities.add(Ability.DOORS_AND_SWITCHES);
if (gameMode == GameMode.CREATIVE) {
// Needed so the client doesn't attempt to take away items
abilities.add(Ability.INSTABUILD);
}
if (commandPermission == CommandPermission.OPERATOR) {
// Fixes a bug? since 1.19.11 where the player can change their gamemode in Bedrock settings and
// a packet is not sent to the server.
// https://github.com/GeyserMC/Geyser/issues/3191
abilities.add(Ability.OPERATOR_COMMANDS);
}
if (flying || spectator) {
if (spectator && !flying) {
// We're "flying locked" in this gamemode
flying = true;
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(true);
sendDownstreamPacket(abilitiesPacket);
}
abilities.add(Ability.FLYING);
}
if (spectator) {
abilities.add(Ability.NO_CLIP);
}
abilityLayer.setLayerType(AbilityLayer.Type.BASE);
abilityLayer.setFlySpeed(flySpeed);
// https://github.com/GeyserMC/Geyser/issues/3139 as of 1.19.10
abilityLayer.setWalkSpeed(walkSpeed == 0f ? 0.01f : walkSpeed);
Collections.addAll(abilityLayer.getAbilitiesSet(), USED_ABILITIES);
updateAbilitiesPacket.getAbilityLayers().add(abilityLayer);
sendUpstreamPacket(updateAbilitiesPacket);
return;
} }
AdventureSettingsPacket adventureSettingsPacket = new AdventureSettingsPacket(); // Default stuff we have to fill in
adventureSettingsPacket.setUniqueEntityId(bedrockId); abilities.add(Ability.BUILD);
adventureSettingsPacket.setCommandPermission(commandPermission); abilities.add(Ability.MINE);
adventureSettingsPacket.setPlayerPermission(playerPermission); // Needed so you can drop items
abilities.add(Ability.DOORS_AND_SWITCHES);
if (gameMode == GameMode.CREATIVE) {
// Needed so the client doesn't attempt to take away items
abilities.add(Ability.INSTABUILD);
}
Set<AdventureSetting> flags = adventureSettingsPacket.getSettings(); if (commandPermission == CommandPermission.OPERATOR) {
if (canFly || spectator) { // Fixes a bug? since 1.19.11 where the player can change their gamemode in Bedrock settings and
flags.add(AdventureSetting.MAY_FLY); // a packet is not sent to the server.
// https://github.com/GeyserMC/Geyser/issues/3191
abilities.add(Ability.OPERATOR_COMMANDS);
} }
if (flying || spectator) { if (flying || spectator) {
@ -1709,20 +1729,21 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(true); ServerboundPlayerAbilitiesPacket abilitiesPacket = new ServerboundPlayerAbilitiesPacket(true);
sendDownstreamPacket(abilitiesPacket); sendDownstreamPacket(abilitiesPacket);
} }
flags.add(AdventureSetting.FLYING); abilities.add(Ability.FLYING);
}
if (worldImmutable) {
flags.add(AdventureSetting.WORLD_IMMUTABLE);
} }
if (spectator) { if (spectator) {
flags.add(AdventureSetting.NO_CLIP); abilities.add(Ability.NO_CLIP);
} }
flags.add(AdventureSetting.AUTO_JUMP); abilityLayer.setLayerType(AbilityLayer.Type.BASE);
abilityLayer.setFlySpeed(flySpeed);
// https://github.com/GeyserMC/Geyser/issues/3139 as of 1.19.10
abilityLayer.setWalkSpeed(walkSpeed == 0f ? 0.01f : walkSpeed);
Collections.addAll(abilityLayer.getAbilitiesSet(), USED_ABILITIES);
sendUpstreamPacket(adventureSettingsPacket); updateAbilitiesPacket.getAbilityLayers().add(abilityLayer);
sendUpstreamPacket(updateAbilitiesPacket);
} }
private int getRenderDistance() { private int getRenderDistance() {

View file

@ -59,10 +59,12 @@ public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0]; CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0];
AnvilContainer container = (AnvilContainer) inventory; AnvilContainer container = (AnvilContainer) inventory;
// Required as of 1.18.30 - FilterTextPackets no longer appear to be sent if (request.getFilterStrings().length != 0) {
String name = request.getFilterStrings()[data.getFilteredStringIndex()]; // Required as of 1.18.30 - FilterTextPackets no longer appear to be sent
if (!Objects.equals(name, container.getNewName())) { String name = request.getFilterStrings()[data.getFilteredStringIndex()];
container.checkForRename(session, name); if (!Objects.equals(name, container.getNewName())) { // TODO is this still necessary after pre-1.19.50 support is dropped?
container.checkForRename(session, name);
}
} }
return super.translateRequest(session, inventory, request); return super.translateRequest(session, inventory, request);

View file

@ -35,12 +35,12 @@ import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.block.DoubleChestValue; import org.geysermc.geyser.level.block.DoubleChestValue;
import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator;
import org.geysermc.geyser.util.InventoryUtils;
public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
private final int defaultJavaBlockState; private final int defaultJavaBlockState;
@ -82,19 +82,10 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
} }
} }
// Check if a fake block can be placed, either above the player or beneath. Vector3i position = InventoryUtils.findAvailableWorldSpace(session);
BedrockDimension dimension = session.getChunkCache().getBedrockDimension(); if (position == null) {
int minY = dimension.minY(), maxY = minY + dimension.height();
Vector3i position = session.getPlayerEntity().getPosition().toInt().add(0, 5, 0);
if (position.getY() < minY) {
return false; return false;
} }
if (position.getY() >= maxY) {
position = session.getPlayerEntity().getPosition().toInt().sub(0, 5, 0);
if (position.getY() >= maxY) {
return false;
}
}
Vector3i pairPosition = position.add(Vector3i.UNIT_X); Vector3i pairPosition = position.add(Vector3i.UNIT_X);
int bedrockBlockId = session.getBlockMappings().getBedrockBlockId(defaultJavaBlockState); int bedrockBlockId = session.getBlockMappings().getBedrockBlockId(defaultJavaBlockState);

View file

@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
@ -38,16 +39,14 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
@Override @Override
public void translate(GeyserSession session, CommandRequestPacket packet) { public void translate(GeyserSession session, CommandRequestPacket packet) {
String command = packet.getCommand().replace("/", ""); String command = MessageTranslator.convertToPlainText(packet.getCommand());
if (!(session.getGeyser().getPlatformType() == PlatformType.STANDALONE if (!(session.getGeyser().getPlatformType() == PlatformType.STANDALONE
&& GeyserImpl.getInstance().commandManager().runCommand(session, command))) { && GeyserImpl.getInstance().commandManager().runCommand(session, command.substring(1)))) {
String message = packet.getCommand().trim(); if (MessageTranslator.isTooLong(command, session)) {
if (MessageTranslator.isTooLong(message, session)) {
return; return;
} }
session.sendCommand(message.substring(1)); session.sendCommand(command.substring(1));
} }
} }
} }

View file

@ -32,12 +32,21 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
import com.nukkitx.math.vector.Vector3d; import com.nukkitx.math.vector.Vector3d;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.inventory.*; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData;
import com.nukkitx.protocol.bedrock.data.inventory.InventorySource;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.data.inventory.LegacySetItemSlotData;
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket; import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
@ -54,7 +63,6 @@ import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
@ -63,7 +71,11 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator; import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.util.*; import org.geysermc.geyser.util.BlockUtils;
import org.geysermc.geyser.util.CooldownUtils;
import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InventoryUtils;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -464,10 +476,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
InteractAction.ATTACK, session.isSneaking()); InteractAction.ATTACK, session.isSneaking());
session.sendDownstreamPacket(attackPacket); session.sendDownstreamPacket(attackPacket);
if (GameProtocol.supports1_19_10(session)) { // Since 1.19.10, LevelSoundEventPackets are no longer sent by the client when attacking entities
// Since 1.19.10, LevelSoundEventPackets are no longer sent by the client when attacking entities CooldownUtils.sendCooldown(session);
CooldownUtils.sendCooldown(session);
}
} }
} }
break; break;

View file

@ -37,21 +37,7 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
@Override @Override
public void translate(GeyserSession session, TextPacket packet) { public void translate(GeyserSession session, TextPacket packet) {
String message = packet.getMessage(); String message = MessageTranslator.convertToPlainText(packet.getMessage());
// 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();
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
if (c != ChatColor.ESCAPE) {
builder.append(c);
}
}
message = builder.toString();
}
if (message.isBlank()) { if (message.isBlank()) {
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either! // Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!

View file

@ -39,7 +39,7 @@ public class JavaPlayerCombatKillTranslator extends PacketTranslator<Clientbound
@Override @Override
public void translate(GeyserSession session, ClientboundPlayerCombatKillPacket packet) { public void translate(GeyserSession session, ClientboundPlayerCombatKillPacket packet) {
if (packet.getPlayerId() == session.getPlayerEntity().getEntityId() && GameProtocol.supports1_19_10(session)) { if (packet.getPlayerId() == session.getPlayerEntity().getEntityId()) {
Component deathMessage = packet.getMessage(); Component deathMessage = packet.getMessage();
// TODO - could inject score in, but as of 1.19.10 newlines don't center and start at the left of the first text // TODO - could inject score in, but as of 1.19.10 newlines don't center and start at the left of the first text
DeathInfoPacket deathInfoPacket = new DeathInfoPacket(); DeathInfoPacket deathInfoPacket = new DeathInfoPacket();

View file

@ -51,6 +51,8 @@ public class JavaMapItemDataTranslator extends PacketTranslator<ClientboundMapIt
mapItemDataPacket.setLocked(packet.isLocked()); mapItemDataPacket.setLocked(packet.isLocked());
mapItemDataPacket.setOrigin(Vector3i.ZERO); // Required since 1.19.20 mapItemDataPacket.setOrigin(Vector3i.ZERO); // Required since 1.19.20
mapItemDataPacket.setScale(packet.getScale()); mapItemDataPacket.setScale(packet.getScale());
// Required as of 1.19.50
mapItemDataPacket.getTrackedEntityIds().add(packet.getMapId());
MapData data = packet.getData(); MapData data = packet.getData();
if (data != null) { if (data != null) {

View file

@ -201,6 +201,28 @@ public class MessageTranslator {
return GSON_SERIALIZER.serialize(component); return GSON_SERIALIZER.serialize(component);
} }
/**
* Convert legacy format message to plain text
*
* @param message Message to convert
* @return The plain text of the message
*/
public static String convertToPlainText(String message) {
char[] input = message.toCharArray();
char[] output = new char[input.length];
int outputSize = 0;
for (int i = 0, inputLength = input.length; i < inputLength; i++) {
char c = input[i];
if (c == ChatColor.ESCAPE) {
i++;
} else {
output[outputSize++] = c;
}
}
return new String(output, 0, outputSize);
}
/** /**
* Convert JSON and legacy format message to plain text * Convert JSON and legacy format message to plain text
* *

View file

@ -27,12 +27,16 @@ package org.geysermc.geyser.util;
import com.github.steveice10.mc.protocol.data.game.entity.Effect; import com.github.steveice10.mc.protocol.data.game.entity.Effect;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.PlayerActionType;
import com.nukkitx.protocol.bedrock.packet.ChangeDimensionPacket; import com.nukkitx.protocol.bedrock.packet.ChangeDimensionPacket;
import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
import com.nukkitx.protocol.bedrock.packet.MobEffectPacket; import com.nukkitx.protocol.bedrock.packet.MobEffectPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
import com.nukkitx.protocol.bedrock.packet.StopSoundPacket; import com.nukkitx.protocol.bedrock.packet.StopSoundPacket;
import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import java.util.Set; import java.util.Set;
@ -94,8 +98,10 @@ public class DimensionUtils {
changeDimensionPacket.setRespawn(true); changeDimensionPacket.setRespawn(true);
changeDimensionPacket.setPosition(pos); changeDimensionPacket.setPosition(pos);
session.sendUpstreamPacket(changeDimensionPacket); session.sendUpstreamPacket(changeDimensionPacket);
session.setDimension(javaDimension); session.setDimension(javaDimension);
setBedrockDimension(session, javaDimension); setBedrockDimension(session, javaDimension);
player.setPosition(pos); player.setPosition(pos);
session.setSpawned(false); session.setSpawned(false);
session.setLastChunkPosition(null); session.setLastChunkPosition(null);
@ -117,6 +123,19 @@ public class DimensionUtils {
stopSoundPacket.setSoundName(""); stopSoundPacket.setSoundName("");
session.sendUpstreamPacket(stopSoundPacket); session.sendUpstreamPacket(stopSoundPacket);
// Kind of silly but Bedrock 1.19.50 requires an acknowledgement after the
// initial chunks are sent, prior to the client acknowledgement
if (GameProtocol.supports1_19_50(session)) {
// Note: send this before chunks are sent. Fixed https://github.com/GeyserMC/Geyser/issues/3421
PlayerActionPacket ackPacket = new PlayerActionPacket();
ackPacket.setRuntimeEntityId(player.getGeyserId());
ackPacket.setAction(PlayerActionType.DIMENSION_CHANGE_SUCCESS);
ackPacket.setBlockPosition(Vector3i.ZERO);
ackPacket.setResultPosition(Vector3i.ZERO);
ackPacket.setFace(0);
session.sendUpstreamPacket(ackPacket);
}
// TODO - fix this hack of a fix by sending the final dimension switching logic after sections have been sent. // TODO - fix this hack of a fix by sending the final dimension switching logic after sections have been sent.
// The client wants sections sent to it before it can successfully respawn. // The client wants sections sent to it before it can successfully respawn.
ChunkUtils.sendEmptyChunks(session, player.getPosition().toInt(), 3, true); ChunkUtils.sendEmptyChunks(session, player.getPosition().toInt(), 3, true);

View file

@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtType;
@ -38,6 +39,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket; import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
@ -46,6 +48,7 @@ import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -134,6 +137,28 @@ public class InventoryUtils {
} }
} }
/**
* Finds a usable block space in the world to place a fake inventory block, and returns the position.
*/
@Nullable
public static Vector3i findAvailableWorldSpace(GeyserSession session) {
// Check if a fake block can be placed, either above the player or beneath.
BedrockDimension dimension = session.getChunkCache().getBedrockDimension();
int minY = dimension.minY(), maxY = minY + dimension.height();
Vector3i flatPlayerPosition = session.getPlayerEntity().getPosition().toInt();
Vector3i position = flatPlayerPosition.add(Vector3i.UP);
if (position.getY() < minY) {
return null;
}
if (position.getY() >= maxY) {
position = flatPlayerPosition.sub(0, 4, 0);
if (position.getY() >= maxY) {
return null;
}
}
return position;
}
public static void updateCursor(GeyserSession session) { public static void updateCursor(GeyserSession session) {
InventorySlotPacket cursorPacket = new InventorySlotPacket(); InventorySlotPacket cursorPacket = new InventorySlotPacket();
cursorPacket.setContainerId(ContainerId.UI); cursorPacket.setContainerId(ContainerId.UI);
@ -148,18 +173,6 @@ public class InventoryUtils {
return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt()); return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt());
} }
public static boolean canStack(ItemStack item1, ItemStack item2) {
if (item1 == null || item2 == null)
return false;
return item1.getId() == item2.getId() && Objects.equals(item1.getNbt(), item2.getNbt());
}
public static boolean canStack(ItemData item1, ItemData item2) {
if (item1 == null || item2 == null)
return false;
return item1.equals(item2, false, true, true);
}
/** /**
* Checks to see if an item stack represents air or has no count. * Checks to see if an item stack represents air or has no count.
*/ */
@ -184,11 +197,22 @@ public class InventoryUtils {
root.put("display", display.build()); root.put("display", display.build());
return protocolVersion -> ItemData.builder() return protocolVersion -> ItemData.builder()
.id(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId()) .id(getUnusableSpaceBlockID(protocolVersion))
.count(1) .count(1)
.tag(root.build()).build(); .tag(root.build()).build();
} }
private static int getUnusableSpaceBlockID(int protocolVersion) {
String unusableSpaceBlock = GeyserImpl.getInstance().getConfig().getUnusableSpaceBlock();
ItemMapping unusableSpaceBlockID = Registries.ITEMS.forVersion(protocolVersion).getMapping(unusableSpaceBlock);
if (unusableSpaceBlockID != null) {
return unusableSpaceBlockID.getBedrockId();
} else {
GeyserImpl.getInstance().getLogger().error("Invalid value" + unusableSpaceBlock + ". Resorting to barrier block.");
return Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId();
}
}
/** /**
* See {@link #findOrCreateItem(GeyserSession, String)}. This is for finding a specified {@link ItemStack}. * See {@link #findOrCreateItem(GeyserSession, String)}. This is for finding a specified {@link ItemStack}.
* *

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
}, },
{ {
"name" : "minecraft:acacia_chest_boat", "name" : "minecraft:acacia_chest_boat",
"id" : 642 "id" : 645
}, },
{ {
"name" : "minecraft:acacia_door", "name" : "minecraft:acacia_door",
@ -19,6 +19,10 @@
"name" : "minecraft:acacia_fence_gate", "name" : "minecraft:acacia_fence_gate",
"id" : 187 "id" : 187
}, },
{
"name" : "minecraft:acacia_hanging_sign",
"id" : -504
},
{ {
"name" : "minecraft:acacia_pressure_plate", "name" : "minecraft:acacia_pressure_plate",
"id" : -150 "id" : -150
@ -131,17 +135,97 @@
"name" : "minecraft:bamboo", "name" : "minecraft:bamboo",
"id" : -163 "id" : -163
}, },
{
"name" : "minecraft:bamboo_button",
"id" : -511
},
{
"name" : "minecraft:bamboo_chest_raft",
"id" : 648
},
{
"name" : "minecraft:bamboo_door",
"id" : -517
},
{
"name" : "minecraft:bamboo_double_slab",
"id" : -521
},
{
"name" : "minecraft:bamboo_fence",
"id" : -515
},
{
"name" : "minecraft:bamboo_fence_gate",
"id" : -516
},
{
"name" : "minecraft:bamboo_hanging_sign",
"id" : -522
},
{
"name" : "minecraft:bamboo_mosaic",
"id" : -509
},
{
"name" : "minecraft:bamboo_mosaic_double_slab",
"id" : -525
},
{
"name" : "minecraft:bamboo_mosaic_slab",
"id" : -524
},
{
"name" : "minecraft:bamboo_mosaic_stairs",
"id" : -523
},
{
"name" : "minecraft:bamboo_planks",
"id" : -510
},
{
"name" : "minecraft:bamboo_pressure_plate",
"id" : -514
},
{
"name" : "minecraft:bamboo_raft",
"id" : 638
},
{ {
"name" : "minecraft:bamboo_sapling", "name" : "minecraft:bamboo_sapling",
"id" : -164 "id" : -164
}, },
{
"name" : "minecraft:bamboo_sign",
"id" : 637
},
{
"name" : "minecraft:bamboo_slab",
"id" : -513
},
{
"name" : "minecraft:bamboo_stairs",
"id" : -512
},
{
"name" : "minecraft:bamboo_standing_sign",
"id" : -518
},
{
"name" : "minecraft:bamboo_trapdoor",
"id" : -520
},
{
"name" : "minecraft:bamboo_wall_sign",
"id" : -519
},
{ {
"name" : "minecraft:banner", "name" : "minecraft:banner",
"id" : 567 "id" : 567
}, },
{ {
"name" : "minecraft:banner_pattern", "name" : "minecraft:banner_pattern",
"id" : 651 "id" : 655
}, },
{ {
"name" : "minecraft:barrel", "name" : "minecraft:barrel",
@ -217,7 +301,7 @@
}, },
{ {
"name" : "minecraft:birch_chest_boat", "name" : "minecraft:birch_chest_boat",
"id" : 639 "id" : 642
}, },
{ {
"name" : "minecraft:birch_door", "name" : "minecraft:birch_door",
@ -227,6 +311,10 @@
"name" : "minecraft:birch_fence_gate", "name" : "minecraft:birch_fence_gate",
"id" : 184 "id" : 184
}, },
{
"name" : "minecraft:birch_hanging_sign",
"id" : -502
},
{ {
"name" : "minecraft:birch_pressure_plate", "name" : "minecraft:birch_pressure_plate",
"id" : -151 "id" : -151
@ -329,7 +417,7 @@
}, },
{ {
"name" : "minecraft:boat", "name" : "minecraft:boat",
"id" : 649 "id" : 653
}, },
{ {
"name" : "minecraft:bone", "name" : "minecraft:bone",
@ -435,6 +523,10 @@
"name" : "minecraft:calcite", "name" : "minecraft:calcite",
"id" : -326 "id" : -326
}, },
{
"name" : "minecraft:camel_spawn_egg",
"id" : 633
},
{ {
"name" : "minecraft:camera", "name" : "minecraft:camera",
"id" : 593 "id" : 593
@ -541,7 +633,7 @@
}, },
{ {
"name" : "minecraft:chest_boat", "name" : "minecraft:chest_boat",
"id" : 645 "id" : 649
}, },
{ {
"name" : "minecraft:chest_minecart", "name" : "minecraft:chest_minecart",
@ -555,6 +647,10 @@
"name" : "minecraft:chicken_spawn_egg", "name" : "minecraft:chicken_spawn_egg",
"id" : 435 "id" : 435
}, },
{
"name" : "minecraft:chiseled_bookshelf",
"id" : -526
},
{ {
"name" : "minecraft:chiseled_deepslate", "name" : "minecraft:chiseled_deepslate",
"id" : -395 "id" : -395
@ -827,6 +923,10 @@
"name" : "minecraft:crimson_fungus", "name" : "minecraft:crimson_fungus",
"id" : -228 "id" : -228
}, },
{
"name" : "minecraft:crimson_hanging_sign",
"id" : -506
},
{ {
"name" : "minecraft:crimson_hyphae", "name" : "minecraft:crimson_hyphae",
"id" : -299 "id" : -299
@ -921,7 +1021,7 @@
}, },
{ {
"name" : "minecraft:dark_oak_chest_boat", "name" : "minecraft:dark_oak_chest_boat",
"id" : 643 "id" : 646
}, },
{ {
"name" : "minecraft:dark_oak_door", "name" : "minecraft:dark_oak_door",
@ -931,6 +1031,10 @@
"name" : "minecraft:dark_oak_fence_gate", "name" : "minecraft:dark_oak_fence_gate",
"id" : 186 "id" : 186
}, },
{
"name" : "minecraft:dark_oak_hanging_sign",
"id" : -505
},
{ {
"name" : "minecraft:dark_oak_pressure_plate", "name" : "minecraft:dark_oak_pressure_plate",
"id" : -152 "id" : -152
@ -1121,7 +1225,7 @@
}, },
{ {
"name" : "minecraft:disc_fragment_5", "name" : "minecraft:disc_fragment_5",
"id" : 637 "id" : 640
}, },
{ {
"name" : "minecraft:dispenser", "name" : "minecraft:dispenser",
@ -1193,11 +1297,11 @@
}, },
{ {
"name" : "minecraft:dye", "name" : "minecraft:dye",
"id" : 650 "id" : 654
}, },
{ {
"name" : "minecraft:echo_shard", "name" : "minecraft:echo_shard",
"id" : 647 "id" : 651
}, },
{ {
"name" : "minecraft:egg", "name" : "minecraft:egg",
@ -1725,7 +1829,7 @@
}, },
{ {
"name" : "minecraft:end_crystal", "name" : "minecraft:end_crystal",
"id" : 653 "id" : 657
}, },
{ {
"name" : "minecraft:end_gateway", "name" : "minecraft:end_gateway",
@ -1933,7 +2037,7 @@
}, },
{ {
"name" : "minecraft:glow_berries", "name" : "minecraft:glow_berries",
"id" : 654 "id" : 658
}, },
{ {
"name" : "minecraft:glow_frame", "name" : "minecraft:glow_frame",
@ -2405,7 +2509,7 @@
}, },
{ {
"name" : "minecraft:jungle_chest_boat", "name" : "minecraft:jungle_chest_boat",
"id" : 640 "id" : 643
}, },
{ {
"name" : "minecraft:jungle_door", "name" : "minecraft:jungle_door",
@ -2415,6 +2519,10 @@
"name" : "minecraft:jungle_fence_gate", "name" : "minecraft:jungle_fence_gate",
"id" : 185 "id" : 185
}, },
{
"name" : "minecraft:jungle_hanging_sign",
"id" : -503
},
{ {
"name" : "minecraft:jungle_pressure_plate", "name" : "minecraft:jungle_pressure_plate",
"id" : -153 "id" : -153
@ -2665,7 +2773,7 @@
}, },
{ {
"name" : "minecraft:mangrove_boat", "name" : "minecraft:mangrove_boat",
"id" : 635 "id" : 636
}, },
{ {
"name" : "minecraft:mangrove_button", "name" : "minecraft:mangrove_button",
@ -2673,11 +2781,11 @@
}, },
{ {
"name" : "minecraft:mangrove_chest_boat", "name" : "minecraft:mangrove_chest_boat",
"id" : 644 "id" : 647
}, },
{ {
"name" : "minecraft:mangrove_door", "name" : "minecraft:mangrove_door",
"id" : 633 "id" : 634
}, },
{ {
"name" : "minecraft:mangrove_double_slab", "name" : "minecraft:mangrove_double_slab",
@ -2691,6 +2799,10 @@
"name" : "minecraft:mangrove_fence_gate", "name" : "minecraft:mangrove_fence_gate",
"id" : -492 "id" : -492
}, },
{
"name" : "minecraft:mangrove_hanging_sign",
"id" : -508
},
{ {
"name" : "minecraft:mangrove_leaves", "name" : "minecraft:mangrove_leaves",
"id" : -472 "id" : -472
@ -2717,7 +2829,7 @@
}, },
{ {
"name" : "minecraft:mangrove_sign", "name" : "minecraft:mangrove_sign",
"id" : 634 "id" : 635
}, },
{ {
"name" : "minecraft:mangrove_slab", "name" : "minecraft:mangrove_slab",
@ -2861,7 +2973,7 @@
}, },
{ {
"name" : "minecraft:music_disc_5", "name" : "minecraft:music_disc_5",
"id" : 636 "id" : 639
}, },
{ {
"name" : "minecraft:music_disc_blocks", "name" : "minecraft:music_disc_blocks",
@ -3037,7 +3149,11 @@
}, },
{ {
"name" : "minecraft:oak_chest_boat", "name" : "minecraft:oak_chest_boat",
"id" : 638 "id" : 641
},
{
"name" : "minecraft:oak_hanging_sign",
"id" : -500
}, },
{ {
"name" : "minecraft:oak_sign", "name" : "minecraft:oak_sign",
@ -3473,7 +3589,7 @@
}, },
{ {
"name" : "minecraft:recovery_compass", "name" : "minecraft:recovery_compass",
"id" : 646 "id" : 650
}, },
{ {
"name" : "minecraft:red_candle", "name" : "minecraft:red_candle",
@ -3781,7 +3897,7 @@
}, },
{ {
"name" : "minecraft:spawn_egg", "name" : "minecraft:spawn_egg",
"id" : 652 "id" : 656
}, },
{ {
"name" : "minecraft:spider_eye", "name" : "minecraft:spider_eye",
@ -3813,7 +3929,7 @@
}, },
{ {
"name" : "minecraft:spruce_chest_boat", "name" : "minecraft:spruce_chest_boat",
"id" : 641 "id" : 644
}, },
{ {
"name" : "minecraft:spruce_door", "name" : "minecraft:spruce_door",
@ -3823,6 +3939,10 @@
"name" : "minecraft:spruce_fence_gate", "name" : "minecraft:spruce_fence_gate",
"id" : 183 "id" : 183
}, },
{
"name" : "minecraft:spruce_hanging_sign",
"id" : -501
},
{ {
"name" : "minecraft:spruce_pressure_plate", "name" : "minecraft:spruce_pressure_plate",
"id" : -154 "id" : -154
@ -4081,7 +4201,7 @@
}, },
{ {
"name" : "minecraft:trader_llama_spawn_egg", "name" : "minecraft:trader_llama_spawn_egg",
"id" : 648 "id" : 652
}, },
{ {
"name" : "minecraft:trapdoor", "name" : "minecraft:trapdoor",
@ -4223,6 +4343,10 @@
"name" : "minecraft:warped_fungus_on_a_stick", "name" : "minecraft:warped_fungus_on_a_stick",
"id" : 618 "id" : 618
}, },
{
"name" : "minecraft:warped_hanging_sign",
"id" : -507
},
{ {
"name" : "minecraft:warped_hyphae", "name" : "minecraft:warped_hyphae",
"id" : -298 "id" : -298

View file

@ -183,6 +183,10 @@ log-player-ip-addresses: true
# auto-update. # auto-update.
notify-on-new-bedrock-update: true notify-on-new-bedrock-update: true
# Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative,
# or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item.
unusable-space-block: minecraft:barrier
# bStats is a stat tracker that is entirely anonymous and tracks only basic information # bStats is a stat tracker that is entirely anonymous and tracks only basic information
# about Geyser, such as how many people are online, how many servers are using Geyser, # about Geyser, such as how many people are online, how many servers are using Geyser,
# what OS is being used, etc. You can learn more about bStats here: https://bstats.org/. # what OS is being used, etc. You can learn more about bStats here: https://bstats.org/.

View file

@ -85,6 +85,7 @@ public class MessageTranslatorTest {
@Test @Test
public void convertToPlainText() { public void convertToPlainText() {
Assert.assertEquals("JSON message is not handled properly", "Many colors here", MessageTranslator.convertToPlainText("{\"extra\":[{\"color\":\"red\",\"text\":\"M\"},{\"color\":\"gold\",\"text\":\"a\"},{\"color\":\"yellow\",\"text\":\"n\"},{\"color\":\"green\",\"text\":\"y \"},{\"color\":\"aqua\",\"text\":\"c\"},{\"color\":\"dark_purple\",\"text\":\"o\"},{\"color\":\"red\",\"text\":\"l\"},{\"color\":\"gold\",\"text\":\"o\"},{\"color\":\"yellow\",\"text\":\"r\"},{\"color\":\"green\",\"text\":\"s \"},{\"color\":\"aqua\",\"text\":\"h\"},{\"color\":\"dark_purple\",\"text\":\"e\"},{\"color\":\"red\",\"text\":\"r\"},{\"color\":\"gold\",\"text\":\"e\"}],\"text\":\"\"}", "en_US")); Assert.assertEquals("JSON message is not handled properly", "Many colors here", MessageTranslator.convertToPlainText("{\"extra\":[{\"color\":\"red\",\"text\":\"M\"},{\"color\":\"gold\",\"text\":\"a\"},{\"color\":\"yellow\",\"text\":\"n\"},{\"color\":\"green\",\"text\":\"y \"},{\"color\":\"aqua\",\"text\":\"c\"},{\"color\":\"dark_purple\",\"text\":\"o\"},{\"color\":\"red\",\"text\":\"l\"},{\"color\":\"gold\",\"text\":\"o\"},{\"color\":\"yellow\",\"text\":\"r\"},{\"color\":\"green\",\"text\":\"s \"},{\"color\":\"aqua\",\"text\":\"h\"},{\"color\":\"dark_purple\",\"text\":\"e\"},{\"color\":\"red\",\"text\":\"r\"},{\"color\":\"gold\",\"text\":\"e\"}],\"text\":\"\"}", "en_US"));
Assert.assertEquals("Legacy formatted message is not handled properly (Colors)", "Many colors here", MessageTranslator.convertToPlainText("§cM§6a§en§ay §bc§5o§cl§6o§er§as §bh§5e§cr§6e"));
Assert.assertEquals("Legacy formatted message is not handled properly (Colors)", "Many colors here", MessageTranslator.convertToPlainText("§cM§6a§en§ay §bc§5o§cl§6o§er§as §bh§5e§cr§6e", "en_US")); Assert.assertEquals("Legacy formatted message is not handled properly (Colors)", "Many colors here", MessageTranslator.convertToPlainText("§cM§6a§en§ay §bc§5o§cl§6o§er§as §bh§5e§cr§6e", "en_US"));
Assert.assertEquals("Legacy formatted message is not handled properly (Style)", "Obf Bold Strikethrough Underline Italic Reset", MessageTranslator.convertToPlainText("§kObf §lBold §mStrikethrough §nUnderline §oItalic §rReset", "en_US")); Assert.assertEquals("Legacy formatted message is not handled properly (Style)", "Obf Bold Strikethrough Underline Italic Reset", MessageTranslator.convertToPlainText("§kObf §lBold §mStrikethrough §nUnderline §oItalic §rReset", "en_US"));
Assert.assertEquals("Valid lenient JSON is not handled properly", "Strange", MessageTranslator.convertToPlainText("§rStrange", "en_US")); Assert.assertEquals("Valid lenient JSON is not handled properly", "Strange", MessageTranslator.convertToPlainText("§rStrange", "en_US"));

View file

@ -1,11 +1,11 @@
[versions] [versions]
jackson = "2.13.4" jackson = "2.14.0"
fastutil = "8.5.2" fastutil = "8.5.2"
netty = "4.1.80.Final" netty = "4.1.80.Final"
guava = "29.0-jre" guava = "29.0-jre"
gson = "2.3.1" # Provided by Spigot 1.8.8 gson = "2.3.1" # Provided by Spigot 1.8.8
websocket = "1.5.1" websocket = "1.5.1"
protocol = "2.9.14-20221025.193624-1" protocol = "2.9.15-20221129.204554-2"
raknet = "1.6.28-20220125.214016-6" raknet = "1.6.28-20220125.214016-6"
mcauthlib = "d9d773e" mcauthlib = "d9d773e"
mcprotocollib = "1.19.3-SNAPSHOT" mcprotocollib = "1.19.3-SNAPSHOT"
@ -82,7 +82,7 @@ junit = { group = "junit", name = "junit", version.ref = "junit" }
mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" } mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" }
mcprotocollib = { group = "com.github.steveice10", name = "mcprotocollib", version.ref = "mcprotocollib" } mcprotocollib = { group = "com.github.steveice10", name = "mcprotocollib", version.ref = "mcprotocollib" }
packetlib = { group = "com.github.steveice10", name = "packetlib", version.ref = "packetlib" } packetlib = { group = "com.github.steveice10", name = "packetlib", version.ref = "packetlib" }
protocol = { group = "com.nukkitx.protocol", name = "bedrock-v557", version.ref = "protocol" } protocol = { group = "com.nukkitx.protocol", name = "bedrock-v560", version.ref = "protocol" }
raknet = { group = "com.nukkitx.network", name = "raknet", version.ref = "raknet" } raknet = { group = "com.nukkitx.network", name = "raknet", version.ref = "raknet" }
sponge-api = { group = "org.spongepowered", name = "spongeapi", version.ref = "sponge" } sponge-api = { group = "org.spongepowered", name = "spongeapi", version.ref = "sponge" }
terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" } terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" }
@ -95,4 +95,4 @@ jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ]
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ]
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j18-impl" ] log4j = [ "log4j-api", "log4j-core", "log4j-slf4j18-impl" ]
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]