Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
1.20.80 Support and Protocol Changes (#4561)
* Make evil more harder Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Deregister more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Pin protocol to 68dc192 * Correction * Update Protocol * More kicking Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * stop reading when there is no item to read (#9) * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * 1.20.80 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused postinitchannel GeyserServerInitializer * Pull protocol jitpack from cloudburst again * Actually builds Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BossEventPacket & EmotePacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add remove before merge comment Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BlockEntityDataPacket and ignore serverbound BossEventPacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol & add more illegal/ignored packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove deprecated packet Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Ignore ClientCacheStatusPacket instead of disallow Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Define static serializers Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Less static class nonsense more correct order Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused import Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Move codec processing to CodecProcessor Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Falsify recipe symetry assumption Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Update Protocol for 2 wrong packet IDs & 5 wrong directions * Jitpack protocol from Geyser repo --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Co-authored-by: chris <github@onechris.mozmail.com>
Dieser Commit ist enthalten in:
Ursprung
4d32b2fecb
Commit
3fa7952936
@ -14,7 +14,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.20.40 - 1.20.73 and Minecraft Java 1.20.4
|
### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4
|
||||||
|
|
||||||
## 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.
|
||||||
|
292
core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java
Normale Datei
292
core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java
Normale Datei
@ -0,0 +1,292 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipmentSerializer_v291;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v486.serializer.BossEventSerializer_v486;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v557.serializer.SetEntityDataSerializer_v557;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v662.serializer.SetEntityMotionSerializer_v662;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.AnvilDamagePacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.ClientCacheBlobStatusPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.ClientCacheStatusPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.ClientCheatAbilityPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.ClientToServerHandshakePacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.CodeBuilderSourcePacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.LabTablePacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.MapCreateLockedCopyPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.MultiplayerSettingsPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.NpcRequestPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PhotoInfoRequestPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PhotoTransferPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.PurchaseReceiptPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.RefreshEntitlementsPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.ScriptMessagePacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SettingsCommandPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SimpleEventPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SubChunkRequestPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.SubClientLoginPacket;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.packet.TickSyncPacket;
|
||||||
|
import org.cloudburstmc.protocol.common.util.VarInts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the Bedrock codec to remove or modify unused or unsafe packets and fields.
|
||||||
|
*/
|
||||||
|
class CodecProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic serializer that throws an exception when trying to serialize or deserialize a packet, leading to client disconnection.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private static final BedrockPacketSerializer ILLEGAL_SERIALIZER = new BedrockPacketSerializer<>() {
|
||||||
|
@Override
|
||||||
|
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
|
||||||
|
throw new IllegalArgumentException("Server tried to send unused packet " + packet.getClass().getSimpleName() + "!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
|
||||||
|
throw new IllegalArgumentException("Client tried to send unused packet " + packet.getClass().getSimpleName() + "!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic serializer that does nothing when trying to serialize or deserialize a packet.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private static final BedrockPacketSerializer IGNORED_SERIALIZER = new BedrockPacketSerializer<>() {
|
||||||
|
@Override
|
||||||
|
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that throws an exception when trying to deserialize InventoryContentPacket since server-auth inventory is used.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<InventoryContentPacket> INVENTORY_CONTENT_SERIALIZER = new InventoryContentSerializer_v407() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventoryContentPacket packet) {
|
||||||
|
throw new IllegalArgumentException("Client cannot send InventoryContentPacket in server-auth inventory environment!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that throws an exception when trying to deserialize InventorySlotPacket since server-auth inventory is used.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<InventorySlotPacket> INVENTORY_SLOT_SERIALIZER = new InventorySlotSerializer_v407() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventorySlotPacket packet) {
|
||||||
|
throw new IllegalArgumentException("Client cannot send InventorySlotPacket in server-auth inventory environment!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize BossEventPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<BossEventPacket> BOSS_EVENT_SERIALIZER = new BossEventSerializer_v486() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BossEventPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize MobArmorEquipmentPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<MobArmorEquipmentPacket> MOB_ARMOR_EQUIPMENT_SERIALIZER = new MobArmorEquipmentSerializer_v291() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobArmorEquipmentPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize PlayerHotbarPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<PlayerHotbarPacket> PLAYER_HOTBAR_SERIALIZER = new PlayerHotbarSerializer_v291() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerHotbarPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize PlayerSkinPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<PlayerSkinPacket> PLAYER_SKIN_SERIALIZER = new PlayerSkinSerializer_v390() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerSkinPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize SetEntityDataPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<SetEntityDataPacket> SET_ENTITY_DATA_SERIALIZER = new SetEntityDataSerializer_v557() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityDataPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<SetEntityMotionPacket> SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that does nothing when trying to deserialize SetEntityLinkPacket since it is not used from the client.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<SetEntityLinkPacket> SET_ENTITY_LINK_SERIALIZER = new SetEntityLinkSerializer_v291() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityLinkPacket packet) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer that skips over the item when trying to deserialize MobEquipmentPacket since only the slot info is used.
|
||||||
|
*/
|
||||||
|
private static final BedrockPacketSerializer<MobEquipmentPacket> MOB_EQUIPMENT_SERIALIZER = new MobEquipmentSerializer_v291() {
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobEquipmentPacket packet) {
|
||||||
|
packet.setRuntimeEntityId(VarInts.readUnsignedLong(buffer));
|
||||||
|
fakeItemRead(buffer);
|
||||||
|
packet.setInventorySlot(buffer.readUnsignedByte());
|
||||||
|
packet.setHotbarSlot(buffer.readUnsignedByte());
|
||||||
|
packet.setContainerId(buffer.readByte());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
static BedrockCodec processCodec(BedrockCodec codec) {
|
||||||
|
return codec.toBuilder()
|
||||||
|
// Illegal unused serverbound EDU packets
|
||||||
|
.updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(CodeBuilderSourcePacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(CreatePhotoPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(NpcRequestPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(PhotoInfoRequestPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
// Illegal unused serverbound packets for featured servers
|
||||||
|
.updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
// Illegal unused serverbound packets that are deprecated
|
||||||
|
.updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
// Illegal unusued serverbound packets that relate to unused features
|
||||||
|
.updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(SubClientLoginPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
// Ignored serverbound packets
|
||||||
|
.updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed
|
||||||
|
.updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(MapInfoRequestPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(SettingsCommandPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(AnvilDamagePacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(RefreshEntitlementsPacket.class, IGNORED_SERIALIZER)
|
||||||
|
// Illegal when serverbound due to Geyser specific setup
|
||||||
|
.updateSerializer(InventoryContentPacket.class, INVENTORY_CONTENT_SERIALIZER)
|
||||||
|
.updateSerializer(InventorySlotPacket.class, INVENTORY_SLOT_SERIALIZER)
|
||||||
|
// Ignored only when serverbound
|
||||||
|
.updateSerializer(BossEventPacket.class, BOSS_EVENT_SERIALIZER)
|
||||||
|
.updateSerializer(MobArmorEquipmentPacket.class, MOB_ARMOR_EQUIPMENT_SERIALIZER)
|
||||||
|
.updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER)
|
||||||
|
.updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER)
|
||||||
|
.updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER)
|
||||||
|
.updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER)
|
||||||
|
.updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER)
|
||||||
|
// Valid serverbound packets where reading of some fields can be skipped
|
||||||
|
.updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER)
|
||||||
|
// // Illegal bidirectional packets
|
||||||
|
.updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
.updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER)
|
||||||
|
// // Ignored bidirectional packets
|
||||||
|
.updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fake reading an item from the buffer to improve performance.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
private static void fakeItemRead(ByteBuf buffer) {
|
||||||
|
int id = VarInts.readInt(buffer); // Runtime ID
|
||||||
|
if (id == 0) { // nothing more to read
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buffer.skipBytes(2); // count
|
||||||
|
VarInts.readUnsignedInt(buffer); // damage
|
||||||
|
boolean hasNetId = buffer.readBoolean();
|
||||||
|
if (hasNetId) {
|
||||||
|
VarInts.readInt(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
VarInts.readInt(buffer); // Block runtime ID
|
||||||
|
int streamSize = VarInts.readUnsignedInt(buffer);
|
||||||
|
buffer.skipBytes(streamSize);
|
||||||
|
}
|
||||||
|
}
|
@ -27,17 +27,14 @@ 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 io.netty.buffer.ByteBuf;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
|
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
|
||||||
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
|
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket;
|
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -48,11 +45,12 @@ import java.util.StringJoiner;
|
|||||||
* Contains information about the supported protocols in Geyser.
|
* Contains information about the supported protocols in Geyser.
|
||||||
*/
|
*/
|
||||||
public final class GameProtocol {
|
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 BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC);
|
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of all supported Bedrock versions that can join Geyser
|
* A list of all supported Bedrock versions that can join Geyser
|
||||||
@ -66,18 +64,21 @@ 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(processCodec(Bedrock_v622.CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v622.CODEC.toBuilder()
|
||||||
.minecraftVersion("1.20.40/1.20.41")
|
.minecraftVersion("1.20.40/1.20.41")
|
||||||
.build()));
|
.build()));
|
||||||
SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v630.CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v630.CODEC.toBuilder()
|
||||||
.minecraftVersion("1.20.50/1.20.51")
|
.minecraftVersion("1.20.50/1.20.51")
|
||||||
.build()));
|
.build()));
|
||||||
SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v649.CODEC.toBuilder()
|
||||||
.minecraftVersion("1.20.60/1.20.62")
|
.minecraftVersion("1.20.60/1.20.62")
|
||||||
.build()));
|
.build()));
|
||||||
SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v662.CODEC.toBuilder()
|
||||||
.minecraftVersion("1.20.70/1.20.73")
|
.minecraftVersion("1.20.70/1.20.73")
|
||||||
.build()));
|
.build()));
|
||||||
|
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||||
|
.minecraftVersion("1.20.80")
|
||||||
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,16 +169,6 @@ public final class GameProtocol {
|
|||||||
return joiner.toString();
|
return joiner.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BedrockCodec processCodec(BedrockCodec codec) {
|
|
||||||
return codec.toBuilder()
|
|
||||||
.updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() {
|
|
||||||
@Override
|
|
||||||
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private GameProtocol() {
|
private GameProtocol() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,16 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.network;
|
package org.geysermc.geyser.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.DefaultEventLoopGroup;
|
import io.netty.channel.DefaultEventLoopGroup;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.cloudburstmc.protocol.bedrock.BedrockPeer;
|
import org.cloudburstmc.protocol.bedrock.BedrockPeer;
|
||||||
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
|
||||||
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
|
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
|
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
|
||||||
@ -63,6 +67,10 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
|
|||||||
|
|
||||||
bedrockServerSession.setLogging(true);
|
bedrockServerSession.setLogging(true);
|
||||||
GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next());
|
GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next());
|
||||||
|
|
||||||
|
Channel channel = bedrockServerSession.getPeer().getChannel();
|
||||||
|
channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session));
|
||||||
|
|
||||||
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session));
|
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session));
|
||||||
this.geyser.eventBus().fire(new SessionInitializeEvent(session));
|
this.geyser.eventBus().fire(new SessionInitializeEvent(session));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.network;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
public static final String NAME = "rak-error-handler";
|
||||||
|
|
||||||
|
private final GeyserSession session;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
Throwable rootCause = Stream.iterate(cause, Throwable::getCause)
|
||||||
|
.filter(element -> element.getCause() == null)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(cause);
|
||||||
|
|
||||||
|
|
||||||
|
if (!(rootCause instanceof IllegalArgumentException)) {
|
||||||
|
super.exceptionCaught(ctx, cause);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kick users that try to send illegal packets
|
||||||
|
session.getGeyser().getLogger().warning(rootCause.getMessage());
|
||||||
|
session.disconnect("Invalid packet received!");
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
|
|||||||
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
|
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
@ -122,7 +123,8 @@ public final class BlockRegistryPopulator {
|
|||||||
.put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock)
|
.put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock)
|
||||||
// Only changes in 1.20.60 are hard_stained_glass (an EDU only block)
|
// Only changes in 1.20.60 are hard_stained_glass (an EDU only block)
|
||||||
.put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock)
|
.put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock)
|
||||||
.put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), tag -> tag)
|
.put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), Conversion671_662::remapBlock)
|
||||||
|
.put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), tag -> tag)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// We can keep this strong as nothing should be garbage collected
|
// We can keep this strong as nothing should be garbage collected
|
||||||
|
@ -44,6 +44,8 @@ public class Conversion662_649 {
|
|||||||
|
|
||||||
|
|
||||||
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
|
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
|
||||||
|
mapping = Conversion671_662.remapItem(item, mapping);
|
||||||
|
|
||||||
String identifer = mapping.getBedrockIdentifier();
|
String identifer = mapping.getBedrockIdentifier();
|
||||||
|
|
||||||
if (identifer.equals("minecraft:grass_block")) {
|
if (identifer.equals("minecraft:grass_block")) {
|
||||||
@ -93,6 +95,8 @@ public class Conversion662_649 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NbtMap remapBlock(NbtMap tag) {
|
static NbtMap remapBlock(NbtMap tag) {
|
||||||
|
tag = Conversion671_662.remapBlock(tag);
|
||||||
|
|
||||||
final String name = tag.getString("name");
|
final String name = tag.getString("name");
|
||||||
|
|
||||||
if (!NEW_BLOCKS.contains(name)) {
|
if (!NEW_BLOCKS.contains(name)) {
|
||||||
|
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.registry.populator;
|
||||||
|
|
||||||
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
|
import org.geysermc.geyser.item.type.Item;
|
||||||
|
import org.geysermc.geyser.registry.type.GeyserMappingItem;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Conversion671_662 {
|
||||||
|
private static final List<String> NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan");
|
||||||
|
private static final List<String> NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan");
|
||||||
|
private static final List<String> NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley");
|
||||||
|
private static final List<String> NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling");
|
||||||
|
private static final List<String> NEW_BLOCKS = Stream.of(NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList();
|
||||||
|
|
||||||
|
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
|
||||||
|
String identifer = mapping.getBedrockIdentifier();
|
||||||
|
|
||||||
|
if (!NEW_BLOCKS.contains(identifer)) {
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NEW_FLOWERS.contains(identifer)) {
|
||||||
|
switch (identifer) {
|
||||||
|
case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); }
|
||||||
|
case "minecraft:blue_orchid" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); }
|
||||||
|
case "minecraft:allium" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); }
|
||||||
|
case "minecraft:azure_bluet" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); }
|
||||||
|
case "minecraft:red_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); }
|
||||||
|
case "minecraft:orange_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(5); }
|
||||||
|
case "minecraft:white_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(6); }
|
||||||
|
case "minecraft:pink_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(7); }
|
||||||
|
case "minecraft:oxeye_daisy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); }
|
||||||
|
case "minecraft:cornflower" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); }
|
||||||
|
case "minecraft:lily_of_the_valley" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NEW_SAPLINGS.contains(identifer)) {
|
||||||
|
switch (identifer) {
|
||||||
|
case "minecraft:oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(0); }
|
||||||
|
case "minecraft:spruce_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(1); }
|
||||||
|
case "minecraft:birch_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(2); }
|
||||||
|
case "minecraft:jungle_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(3); }
|
||||||
|
case "minecraft:acacia_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(4); }
|
||||||
|
case "minecraft:dark_oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(5); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NEW_CORAL_FANS.contains(identifer)) {
|
||||||
|
switch (identifer) {
|
||||||
|
case "minecraft:tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(0); }
|
||||||
|
case "minecraft:brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(1); }
|
||||||
|
case "minecraft:bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(2); }
|
||||||
|
case "minecraft:fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(3); }
|
||||||
|
case "minecraft:horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(4); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NEW_DEAD_CORAL_FANS.contains(identifer)) {
|
||||||
|
switch (identifer) {
|
||||||
|
case "minecraft:dead_tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(0); }
|
||||||
|
case "minecraft:dead_brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(1); }
|
||||||
|
case "minecraft:dead_bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(2); }
|
||||||
|
case "minecraft:dead_fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(3); }
|
||||||
|
case "minecraft:dead_horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(4); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NbtMap remapBlock(NbtMap tag) {
|
||||||
|
final String name = tag.getString("name");
|
||||||
|
|
||||||
|
if (!NEW_BLOCKS.contains(name)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("minecraft:bamboo_sapling")) {
|
||||||
|
NbtMap states = tag.getCompound("states")
|
||||||
|
.toBuilder()
|
||||||
|
.putString("sapling_type", "oak")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return tag.toBuilder().putCompound("states", states).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
String replacement;
|
||||||
|
|
||||||
|
if (NEW_SAPLINGS.contains(name)) {
|
||||||
|
replacement = "minecraft:sapling";
|
||||||
|
String saplingType = name.replaceAll("minecraft:|_sapling", "");;
|
||||||
|
|
||||||
|
NbtMap states = tag.getCompound("states")
|
||||||
|
.toBuilder()
|
||||||
|
.putString("sapling_type", saplingType)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NEW_FLOWERS.contains(name)) {
|
||||||
|
replacement = "minecraft:red_flower";
|
||||||
|
String flowerType;
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case "minecraft:poppy" -> flowerType = "poppy";
|
||||||
|
case "minecraft:blue_orchid" -> flowerType = "orchid";
|
||||||
|
case "minecraft:allium" -> flowerType = "allium";
|
||||||
|
case "minecraft:azure_bluet" -> flowerType = "houstonia";
|
||||||
|
case "minecraft:red_tulip" -> flowerType = "tulip_red";
|
||||||
|
case "minecraft:orange_tulip" -> flowerType = "tulip_orange";
|
||||||
|
case "minecraft:white_tulip" -> flowerType = "tulip_white";
|
||||||
|
case "minecraft:pink_tulip" -> flowerType = "tulip_pink";
|
||||||
|
case "minecraft:oxeye_daisy" -> flowerType = "oxeye";
|
||||||
|
case "minecraft:cornflower" -> flowerType = "cornflower";
|
||||||
|
case "minecraft:lily_of_the_valley" -> flowerType = "lily_of_the_valley";
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
NbtMap states = tag.getCompound("states")
|
||||||
|
.toBuilder()
|
||||||
|
.putString("flower_type", flowerType)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isLiveCoralFan = NEW_CORAL_FANS.contains(name);
|
||||||
|
boolean isDeadCoralFan = NEW_DEAD_CORAL_FANS.contains(name);
|
||||||
|
|
||||||
|
if (isLiveCoralFan || isDeadCoralFan) {
|
||||||
|
replacement = isLiveCoralFan ? "minecraft:coral_fan" : "minecraft:coral_fan_dead";
|
||||||
|
String coralColor;
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case "minecraft:tube_coral_fan", "minecraft:dead_tube_coral_fan" -> coralColor = "blue";
|
||||||
|
case "minecraft:brain_coral_fan", "minecraft:dead_brain_coral_fan" -> coralColor = "pink";
|
||||||
|
case "minecraft:bubble_coral_fan", "minecraft:dead_bubble_coral_fan" -> coralColor = "purple";
|
||||||
|
case "minecraft:fire_coral_fan", "minecraft:dead_fire_coral_fan" -> coralColor = "yellow";
|
||||||
|
case "minecraft:horn_coral_fan", "minecraft:dead_horn_coral_fan" -> coralColor = "red";
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
NbtMap states = tag.getCompound("states")
|
||||||
|
.toBuilder()
|
||||||
|
.putString("coral_color", coralColor)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
|
|||||||
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||||
@ -93,7 +94,8 @@ public class ItemRegistryPopulator {
|
|||||||
paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem));
|
paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem));
|
||||||
paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem));
|
paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem));
|
||||||
paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem));
|
paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem));
|
||||||
paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()));
|
paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion671_662::remapItem));
|
||||||
|
paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()));
|
||||||
|
|
||||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ public class RecipeRegistryPopulator {
|
|||||||
/* Convert end */
|
/* Convert end */
|
||||||
|
|
||||||
return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(),
|
return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(),
|
||||||
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false);
|
||||||
}
|
}
|
||||||
List<ItemData> inputs = new ObjectArrayList<>();
|
List<ItemData> inputs = new ObjectArrayList<>();
|
||||||
for (JsonNode entry : node.get("inputs")) {
|
for (JsonNode entry : node.get("inputs")) {
|
||||||
|
@ -162,7 +162,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||||||
bedrockRecipeIDs.add(uuid.toString());
|
bedrockRecipeIDs.add(uuid.toString());
|
||||||
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(),
|
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(),
|
||||||
shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs),
|
shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs),
|
||||||
Collections.singletonList(output), uuid, "crafting_table", 0, netId));
|
Collections.singletonList(output), uuid, "crafting_table", 0, netId, false));
|
||||||
recipeMap.put(netId++, new GeyserShapedRecipe(shapedRecipeData));
|
recipeMap.put(netId++, new GeyserShapedRecipe(shapedRecipeData));
|
||||||
}
|
}
|
||||||
addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
|
addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
|
||||||
|
@ -193,7 +193,8 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
|||||||
uuid,
|
uuid,
|
||||||
"crafting_table",
|
"crafting_table",
|
||||||
0,
|
0,
|
||||||
newRecipeId
|
newRecipeId,
|
||||||
|
false
|
||||||
));
|
));
|
||||||
craftPacket.setCleanRecipes(false);
|
craftPacket.setCleanRecipes(false);
|
||||||
session.sendUpstreamPacket(craftPacket);
|
session.sendUpstreamPacket(craftPacket);
|
||||||
|
BIN
core/src/main/resources/bedrock/block_palette.1_20_80.nbt
Normale Datei
BIN
core/src/main/resources/bedrock/block_palette.1_20_80.nbt
Normale Datei
Binäre Datei nicht angezeigt.
5812
core/src/main/resources/bedrock/creative_items.1_20_80.json
Normale Datei
5812
core/src/main/resources/bedrock/creative_items.1_20_80.json
Normale Datei
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
Binäre Datei nicht angezeigt.
6274
core/src/main/resources/bedrock/runtime_item_states.1_20_80.json
Normale Datei
6274
core/src/main/resources/bedrock/runtime_item_states.1_20_80.json
Normale Datei
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -1 +1 @@
|
|||||||
Subproject commit b1883ca53afc082de98aeb062ba2fad00e069617
|
Subproject commit 4f89411d5bfb4e48699f635876d9c556e5c7e505
|
@ -10,10 +10,10 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT"
|
|||||||
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 = "3.0.0.Beta1-20240313.120922-126"
|
protocol = "3.0.0.Beta1-20240411.165033-129"
|
||||||
protocol-connection = "3.0.0.Beta1-20240313.120922-125"
|
protocol-connection = "3.0.0.Beta1-20240411.165033-128"
|
||||||
raknet = "1.0.0.CR3-20240416.144209-1"
|
raknet = "1.0.0.CR3-20240416.144209-1"
|
||||||
blockstateupdater="1.20.70-20240303.125052-2"
|
blockstateupdater="1.20.80-20240411.142413-1"
|
||||||
mcauthlib = "d9d773e"
|
mcauthlib = "d9d773e"
|
||||||
mcprotocollib = "1.20.4-2-20240116.220521-7"
|
mcprotocollib = "1.20.4-2-20240116.220521-7"
|
||||||
adventure = "4.14.0"
|
adventure = "4.14.0"
|
||||||
@ -115,9 +115,12 @@ viaproxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaproxy"
|
|||||||
viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" }
|
viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" }
|
||||||
websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" }
|
websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" }
|
||||||
|
|
||||||
protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" }
|
#protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" }
|
||||||
protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" }
|
#protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" }
|
||||||
protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" }
|
#protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" }
|
||||||
|
protocol-common = { group = "com.github.GeyserMC.Protocol", name = "common", version = "ade21be" }
|
||||||
|
protocol-codec = { group = "com.github.GeyserMC.Protocol", name = "bedrock-codec", version = "ade21be" }
|
||||||
|
protocol-connection = { group = "com.github.GeyserMC.Protocol", name = "bedrock-connection", version = "ade21be" }
|
||||||
|
|
||||||
math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" }
|
math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" }
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren