Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-19 14:30:17 +01:00
Painting re-implemented. Started on enchantments
Dieser Commit ist enthalten in:
Ursprung
214cc5a824
Commit
65fd409a00
@ -30,6 +30,8 @@ import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.PaintingType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
|
||||
@ -49,8 +51,14 @@ public class PaintingEntity extends Entity {
|
||||
// Wait until we get the metadata needed
|
||||
}
|
||||
|
||||
public void setPaintingType(ObjectEntityMetadata<org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType> entityMetadata) {
|
||||
PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue());
|
||||
public void setPaintingType(ObjectEntityMetadata<Holder<PaintingVariant>> entityMetadata) {
|
||||
if (!entityMetadata.getValue().isId()) {
|
||||
return;
|
||||
}
|
||||
PaintingType type = session.getRegistryCache().paintings().byId(entityMetadata.getValue().id());
|
||||
if (type == null) {
|
||||
return;
|
||||
}
|
||||
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
||||
addPaintingPacket.setUniqueEntityId(geyserId);
|
||||
addPaintingPacket.setRuntimeEntityId(geyserId);
|
||||
@ -79,7 +87,7 @@ public class PaintingEntity extends Entity {
|
||||
private Vector3f fixOffset(PaintingType paintingName) {
|
||||
Vector3f position = super.position;
|
||||
position = position.add(0.5, 0.5, 0.5);
|
||||
double widthOffset = paintingName.getWidth() > 1 ? 0.5 : 0;
|
||||
double widthOffset = paintingName.getWidth() > 1 && paintingName.getWidth() != 3 ? 0.5 : 0;
|
||||
double heightOffset = paintingName.getHeight() > 1 && paintingName.getHeight() != 3 ? 0.5 : 0;
|
||||
|
||||
return switch (direction) {
|
||||
|
@ -36,33 +36,25 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.WolfVariant;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WolfEntity extends TameableEntity {
|
||||
/**
|
||||
* A list of all foods a wolf can eat on Java Edition.
|
||||
* Used to display interactive tag or particles if needed.
|
||||
* TODO generate
|
||||
*/
|
||||
private static final Set<Item> WOLF_FOODS = Set.of(Items.PUFFERFISH, Items.TROPICAL_FISH, Items.CHICKEN, Items.COOKED_CHICKEN,
|
||||
Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON,
|
||||
Items.COOKED_RABBIT);
|
||||
|
||||
private byte collarColor = 14; // Red - default
|
||||
|
||||
private boolean isCurseOfBinding = false;
|
||||
@ -112,12 +104,14 @@ public class WolfEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
// 1.20.5+
|
||||
public void setWolfVariant(IntEntityMetadata entityMetadata) {
|
||||
WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue());
|
||||
if (wolfVariant == null) {
|
||||
wolfVariant = WolfVariant.PALE;
|
||||
}
|
||||
dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal());
|
||||
public void setWolfVariant(ObjectEntityMetadata<Holder<WolfVariant>> entityMetadata) {
|
||||
entityMetadata.getValue().ifId(id -> {
|
||||
BuiltInWolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(id);
|
||||
if (wolfVariant == null) {
|
||||
wolfVariant = BuiltInWolfVariant.PALE;
|
||||
}
|
||||
dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -187,7 +181,7 @@ public class WolfEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
// Ordered by bedrock id
|
||||
public enum WolfVariant {
|
||||
public enum BuiltInWolfVariant {
|
||||
PALE,
|
||||
ASHEN,
|
||||
BLACK,
|
||||
@ -198,16 +192,16 @@ public class WolfEntity extends TameableEntity {
|
||||
STRIPED,
|
||||
WOODS;
|
||||
|
||||
private static final WolfVariant[] VALUES = values();
|
||||
private static final BuiltInWolfVariant[] VALUES = values();
|
||||
|
||||
private final String javaIdentifier;
|
||||
|
||||
WolfVariant() {
|
||||
BuiltInWolfVariant() {
|
||||
this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) {
|
||||
for (WolfVariant wolfVariant : VALUES) {
|
||||
public static @Nullable BuiltInWolfVariant getByJavaIdentifier(String javaIdentifier) {
|
||||
for (BuiltInWolfVariant wolfVariant : VALUES) {
|
||||
if (wolfVariant.javaIdentifier.equals(javaIdentifier)) {
|
||||
return wolfVariant;
|
||||
}
|
||||
|
47
core/src/main/java/org/geysermc/geyser/item/Enchantment.java
Normale Datei
47
core/src/main/java/org/geysermc/geyser/item/Enchantment.java
Normale Datei
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.item;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
|
||||
/**
|
||||
* @param anvilCost also as a rarity multiplier
|
||||
*/
|
||||
public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) {
|
||||
|
||||
// Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes.
|
||||
// I'm not sure how that's wired over the network, so we'll put it off.
|
||||
public static Enchantment read(RegistryEntry entry) {
|
||||
NbtMap data = entry.getData();
|
||||
String supportedItems = data.getString("supported_items");
|
||||
int maxLevel = data.getInt("max_level");
|
||||
int anvilCost = data.getInt("anvil_cost");
|
||||
String exclusiveSet = data.getString("exclusive_set", null);
|
||||
return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet);
|
||||
}
|
||||
}
|
@ -146,8 +146,8 @@ public class BannerItem extends BlockItem {
|
||||
} else {
|
||||
List<NbtMap> patternList = new ArrayList<>(patterns.size());
|
||||
for (BannerPatternLayer patternLayer : patterns) {
|
||||
patternLayer.getPattern().ifId(holder -> {
|
||||
BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(holder.id());
|
||||
patternLayer.getPattern().ifId(id -> {
|
||||
BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(id);
|
||||
if (bannerPattern != null) {
|
||||
NbtMap tag = NbtMap.builder()
|
||||
.putString("Pattern", bannerPattern.getBedrockIdentifier())
|
||||
|
@ -29,6 +29,8 @@ import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public enum PaintingType {
|
||||
@ -61,7 +63,27 @@ public enum PaintingType {
|
||||
EARTH("Earth", 2, 2),
|
||||
WIND("Wind", 2, 2),
|
||||
WATER("Water", 2, 2),
|
||||
FIRE("Fire", 2, 2);
|
||||
FIRE("Fire", 2, 2),
|
||||
MEDITATIVE("meditative", 1, 1),
|
||||
PRAIRIE_RIDE("prairie_ride", 1, 2),
|
||||
BAROQUE("baroque", 2, 2),
|
||||
HUMBLE("humble", 2, 2),
|
||||
UNPACKED("unpacked", 4, 4),
|
||||
BACKYARD("backyard", 3, 4),
|
||||
BOUQUET("bouquet", 3, 3),
|
||||
CAVEBIRD("cavebird", 3, 3),
|
||||
CHANGING("changing", 4, 2),
|
||||
COTAN("cotan", 3, 3),
|
||||
ENDBOSS("endboss", 3, 3),
|
||||
FERN("fern", 3, 3),
|
||||
FINDING("finding", 4, 2),
|
||||
LOWMIST("lowmist", 4, 2),
|
||||
ORB("orb", 4, 4),
|
||||
OWLEMONS("owlemons", 3, 3),
|
||||
PASSAGE("passage", 4, 2),
|
||||
POND("pond", 3, 4),
|
||||
SUNFLOWERS("sunflowers", 3, 3),
|
||||
TIDES("tides", 3, 3);
|
||||
|
||||
private static final PaintingType[] VALUES = values();
|
||||
private final String bedrockName;
|
||||
@ -70,12 +92,8 @@ public enum PaintingType {
|
||||
|
||||
public static PaintingType getByName(String javaName) {
|
||||
for (PaintingType paintingName : VALUES) {
|
||||
if (paintingName.name().equalsIgnoreCase(javaName)) return paintingName;
|
||||
if (("minecraft:" + paintingName.name().toLowerCase(Locale.ROOT)).equals(javaName)) return paintingName;
|
||||
}
|
||||
return KEBAB;
|
||||
}
|
||||
|
||||
public static PaintingType getByPaintingType(org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType paintingType) {
|
||||
return getByName(paintingType.name());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class Conversion685_671 {
|
||||
private static final List<String> MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList();
|
||||
private static final List<Item> NEW_MUSIC_DISCS = List.of(Items.MUSIC_DISC_CREATOR, Items.MUSIC_DISC_CREATOR_MUSIC_BOX, Items.MUSIC_DISC_PRECIPICE);
|
||||
|
||||
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
|
||||
static GeyserMappingItem remapItem(Item item, GeyserMappingItem mapping) {
|
||||
String identifer = mapping.getBedrockIdentifier();
|
||||
|
||||
if (NEW_MUSIC_DISCS.contains(item)) {
|
||||
|
@ -1302,22 +1302,28 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to reduce amount of duplicate code. Sends ServerboundUseItemPacket.
|
||||
*/
|
||||
public void useItem(Hand hand) {
|
||||
sendDownstreamGamePacket(new ServerboundUseItemPacket(
|
||||
hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display
|
||||
* blocking and sends a packet to the Java server.
|
||||
*/
|
||||
private boolean attemptToBlock() {
|
||||
ServerboundUseItemPacket useItemPacket;
|
||||
if (playerInventory.getItemInHand().asItem() == Items.SHIELD) {
|
||||
useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, worldCache.nextPredictionSequence());
|
||||
useItem(Hand.MAIN_HAND);
|
||||
} else if (playerInventory.getOffhand().asItem() == Items.SHIELD) {
|
||||
useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND, worldCache.nextPredictionSequence());
|
||||
useItem(Hand.OFF_HAND);
|
||||
} else {
|
||||
// No blocking
|
||||
return false;
|
||||
}
|
||||
|
||||
sendDownstreamGamePacket(useItemPacket);
|
||||
playerEntity.setFlag(EntityFlag.BLOCKING, true);
|
||||
// Metadata should be updated later
|
||||
return true;
|
||||
|
@ -38,7 +38,9 @@ import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity;
|
||||
import org.geysermc.geyser.inventory.item.BannerPattern;
|
||||
import org.geysermc.geyser.inventory.recipe.TrimRecipe;
|
||||
import org.geysermc.geyser.item.Enchantment;
|
||||
import org.geysermc.geyser.level.JavaDimension;
|
||||
import org.geysermc.geyser.level.PaintingType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistry;
|
||||
import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry;
|
||||
@ -46,6 +48,7 @@ import org.geysermc.geyser.text.TextDecoration;
|
||||
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -72,11 +75,13 @@ public final class RegistryCache {
|
||||
static {
|
||||
register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry));
|
||||
register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry));
|
||||
register("enchantment", cache -> cache.enchantments, ($, entry) -> Enchantment.read(entry));
|
||||
register("painting_variant", cache -> cache.paintings, ($, entry) -> PaintingType.getByName(entry.getId()));
|
||||
register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial);
|
||||
register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern);
|
||||
register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome);
|
||||
register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId()));
|
||||
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId()));
|
||||
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId()));
|
||||
|
||||
// Load from MCProtocolLib's classloader
|
||||
NbtMap tag = MinecraftProtocol.loadNetworkCodec();
|
||||
@ -104,16 +109,18 @@ public final class RegistryCache {
|
||||
* Java -> Bedrock biome network IDs.
|
||||
*/
|
||||
private int[] biomeTranslations;
|
||||
private final JavaRegistry<TextDecoration> chatTypes = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<ChatType> chatTypes = new SimpleJavaRegistry<>();
|
||||
/**
|
||||
* All dimensions that the client could possibly connect to.
|
||||
*/
|
||||
private final JavaRegistry<JavaDimension> dimensions = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<Enchantment> enchantments = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<PaintingType> paintings = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<TrimMaterial> trimMaterials = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<TrimPattern> trimPatterns = new SimpleJavaRegistry<>();
|
||||
|
||||
private final JavaRegistry<BannerPattern> bannerPatterns = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<WolfEntity.WolfVariant> wolfVariants = new SimpleJavaRegistry<>();
|
||||
private final JavaRegistry<WolfEntity.BuiltInWolfVariant> wolfVariants = new SimpleJavaRegistry<>();
|
||||
|
||||
public RegistryCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
|
@ -57,4 +57,9 @@ public class SimpleJavaRegistry<T> implements JavaRegistry<T> {
|
||||
public List<T> values() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.values.toString();
|
||||
}
|
||||
}
|
||||
|
@ -30,21 +30,49 @@ import net.kyori.adventure.text.format.Style;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public final class TextDecoration {
|
||||
private final String translationKey;
|
||||
private final Style style;
|
||||
private final Set<Parameter> parameters;
|
||||
public record TextDecoration(String translationKey, List<Parameter> parameters, Style deserializedStyle) implements ChatTypeDecoration {
|
||||
|
||||
public TextDecoration(NbtMap tag) {
|
||||
translationKey = tag.getString("translation_key");
|
||||
@Override
|
||||
public NbtMap style() {
|
||||
// Should not ever be called.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
NbtMap styleTag = tag.getCompound("style");
|
||||
public static ChatType readChatType(RegistryEntry entry) {
|
||||
// Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
|
||||
// (This note has been passed around through several classes and iterations. It stays as a warning
|
||||
// to anyone that dares to try and hardcode registry IDs.)
|
||||
NbtMap tag = entry.getData();
|
||||
NbtMap chat = tag.getCompound("chat", null);
|
||||
if (chat != null) {
|
||||
String translationKey = tag.getString("translation_key");
|
||||
|
||||
NbtMap styleTag = tag.getCompound("style");
|
||||
Style style = deserializeStyle(styleTag);
|
||||
|
||||
List<ChatTypeDecoration.Parameter> parameters = new ArrayList<>();
|
||||
List<String> parametersNbt = tag.getList("parameters", NbtType.STRING);
|
||||
for (String parameter : parametersNbt) {
|
||||
parameters.add(ChatTypeDecoration.Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
return new ChatType(new TextDecoration(translationKey, parameters, style), null);
|
||||
}
|
||||
return new ChatType(null, null);
|
||||
}
|
||||
|
||||
public static Style getStyle(ChatTypeDecoration decoration) {
|
||||
if (decoration instanceof TextDecoration textDecoration) {
|
||||
return textDecoration.deserializedStyle();
|
||||
}
|
||||
return deserializeStyle(decoration.style());
|
||||
}
|
||||
|
||||
private static Style deserializeStyle(NbtMap styleTag) {
|
||||
Style.Builder builder = Style.style();
|
||||
if (!styleTag.isEmpty()) {
|
||||
String color = styleTag.getString("color", null);
|
||||
@ -57,50 +85,6 @@ public final class TextDecoration {
|
||||
builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC);
|
||||
}
|
||||
}
|
||||
style = builder.build();
|
||||
|
||||
this.parameters = EnumSet.noneOf(Parameter.class);
|
||||
List<String> parameters = tag.getList("parameters", NbtType.STRING);
|
||||
for (String parameter : parameters) {
|
||||
this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
|
||||
public String translationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
|
||||
public Style style() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public Set<Parameter> parameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TextDecoration{" +
|
||||
"translationKey='" + translationKey + '\'' +
|
||||
", style=" + style +
|
||||
", parameters=" + parameters +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static TextDecoration readChatType(RegistryEntry entry) {
|
||||
// Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
|
||||
NbtMap tag = entry.getData();
|
||||
NbtMap chat = tag.getCompound("chat", null);
|
||||
TextDecoration textDecoration = null;
|
||||
if (chat != null) {
|
||||
textDecoration = new TextDecoration(chat);
|
||||
}
|
||||
return textDecoration;
|
||||
}
|
||||
|
||||
public enum Parameter {
|
||||
CONTENT,
|
||||
SENDER,
|
||||
TARGET
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -394,8 +394,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
}
|
||||
}
|
||||
|
||||
ServerboundUseItemPacket useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence());
|
||||
session.sendDownstreamGamePacket(useItemPacket);
|
||||
session.useItem(Hand.MAIN_HAND);
|
||||
|
||||
List<LegacySetItemSlotData> legacySlots = packet.getLegacySlots();
|
||||
if (packet.getActions().size() == 1 && !legacySlots.isEmpty()) {
|
||||
@ -639,8 +638,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
Vector3f target = packet.getBlockPosition().toFloat().add(packet.getClickPosition());
|
||||
lookAt(session, target);
|
||||
|
||||
ServerboundUseItemPacket itemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence());
|
||||
session.sendDownstreamGamePacket(itemPacket);
|
||||
session.useItem(Hand.MAIN_HAND);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
@ -36,6 +33,8 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -66,7 +65,7 @@ public class BedrockMobEquipmentTranslator extends PacketTranslator<MobEquipment
|
||||
// Activate shield since we are already sneaking
|
||||
// (No need to send a release item packet - Java doesn't do this when swapping items)
|
||||
// Required to do it a tick later or else it doesn't register
|
||||
session.scheduleInEventLoop(() -> session.sendDownstreamGamePacket(new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence())),
|
||||
session.scheduleInEventLoop(() -> session.useItem(Hand.MAIN_HAND),
|
||||
50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
||||
entity.resetMetadata();
|
||||
}
|
||||
|
||||
if (!packet.isKeepAttributes()) {
|
||||
if (!packet.isKeepAttributeModifiers()) {
|
||||
entity.resetAttributes();
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.translator.text;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ScoreComponent;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
@ -41,6 +39,11 @@ import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.*;
|
||||
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -321,7 +324,7 @@ public class MessageTranslator {
|
||||
return PlainTextComponentSerializer.plainText().serialize(messageComponent);
|
||||
}
|
||||
|
||||
public static void handleChatPacket(GeyserSession session, Component message, int chatType, Component targetName, Component sender) {
|
||||
public static void handleChatPacket(GeyserSession session, Component message, Holder<ChatType> chatTypeHolder, Component targetName, Component sender) {
|
||||
TextPacket textPacket = new TextPacket();
|
||||
textPacket.setPlatformChatId("");
|
||||
textPacket.setSourceName("");
|
||||
@ -330,14 +333,15 @@ public class MessageTranslator {
|
||||
|
||||
textPacket.setNeedsTranslation(false);
|
||||
|
||||
TextDecoration decoration = session.getRegistryCache().chatTypes().byId(chatType);
|
||||
if (decoration != null) {
|
||||
ChatType chatType = chatTypeHolder.getOrCompute(session.getRegistryCache().chatTypes()::byId);
|
||||
if (chatType != null && chatType.chat() != null) {
|
||||
var chat = chatType.chat();
|
||||
// As of 1.19 - do this to apply all the styling for signed messages
|
||||
// Though, Bedrock cannot care about the signed stuff.
|
||||
TranslatableComponent.Builder withDecoration = Component.translatable()
|
||||
.key(decoration.translationKey())
|
||||
.style(decoration.style());
|
||||
Set<TextDecoration.Parameter> parameters = decoration.parameters();
|
||||
.key(chat.translationKey())
|
||||
.style(TextDecoration.getStyle(chat));
|
||||
List<ChatTypeDecoration.Parameter> parameters = chat.parameters();
|
||||
List<Component> args = new ArrayList<>(3);
|
||||
if (parameters.contains(TextDecoration.Parameter.TARGET)) {
|
||||
args.add(targetName);
|
||||
@ -348,7 +352,7 @@ public class MessageTranslator {
|
||||
if (parameters.contains(TextDecoration.Parameter.CONTENT)) {
|
||||
args.add(message);
|
||||
}
|
||||
withDecoration.args(args);
|
||||
withDecoration.arguments(args);
|
||||
textPacket.setMessage(MessageTranslator.convertMessage(withDecoration.build(), session.locale()));
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Likely illegal chat type detection found.");
|
||||
|
@ -13,7 +13,7 @@ websocket = "1.5.1"
|
||||
protocol = "3.0.0.Beta2-20240520.153053-5"
|
||||
raknet = "1.0.0.CR3-20240416.144209-1"
|
||||
mcauthlib = "e5b0bcc"
|
||||
mcprotocollib = "1.20.6-2-20240520.030045-8"
|
||||
mcprotocollib = "1.21-SNAPSHOT"
|
||||
adventure = "4.14.0"
|
||||
adventure-platform = "4.3.0"
|
||||
junit = "5.9.2"
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren