mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-04-17 19:12:14 +02:00
Some more components, still needs their tests, work on text component hashing
This commit is contained in:
parent
ba9544713a
commit
8cfe776363
9 changed files with 220 additions and 12 deletions
core/src/main/java/org/geysermc/geyser
item/hashing
ComponentHasher.javaDataComponentHashers.javaMapBuilder.javaMapHasher.javaMinecraftHasher.javaRegistryHasher.java
session/cache
translator/protocol/java/entity/player
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2025 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.hashing;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
|
||||
public interface ComponentHasher {
|
||||
|
||||
MinecraftHasher<Component> COMPONENT = (value, encoder) -> encoder.empty(); // TODO
|
||||
|
||||
MinecraftHasher<NamedTextColor> NAMED_COLOR = MinecraftHasher.STRING.convert(NamedTextColor::toString);
|
||||
|
||||
MinecraftHasher<TextColor> DIRECT_COLOR = MinecraftHasher.STRING.convert(TextColor::asHexString);
|
||||
|
||||
MinecraftHasher<TextColor> COLOR = (value, encoder) -> {
|
||||
if (value instanceof NamedTextColor named) {
|
||||
return NAMED_COLOR.hash(named, encoder);
|
||||
}
|
||||
return DIRECT_COLOR.hash(value, encoder);
|
||||
};
|
||||
|
||||
MinecraftHasher<TextDecoration.State> DECORATION_STATE = MinecraftHasher.BOOL.convert(state -> switch (state) {
|
||||
case NOT_SET -> null; // Should never happen since we're using .optional() with NOT_SET as default value below
|
||||
case FALSE -> false;
|
||||
case TRUE -> true;
|
||||
});
|
||||
|
||||
MinecraftHasher<ClickEvent.Action> CLICK_EVENT_ACTION = MinecraftHasher.STRING.convert(ClickEvent.Action::toString);
|
||||
|
||||
MinecraftHasher<ClickEvent> CLICK_EVENT = CLICK_EVENT_ACTION.dispatch("action", ClickEvent::action, action -> switch (action) {
|
||||
case OPEN_URL -> builder -> builder.accept("url", MinecraftHasher.STRING, ClickEvent::value);
|
||||
case OPEN_FILE -> builder -> builder.accept("path", MinecraftHasher.STRING, ClickEvent::value);
|
||||
case RUN_COMMAND, SUGGEST_COMMAND -> builder -> builder.accept("command", MinecraftHasher.STRING, ClickEvent::value);
|
||||
case CHANGE_PAGE -> builder -> builder.accept("page", MinecraftHasher.STRING, ClickEvent::value);
|
||||
case COPY_TO_CLIPBOARD -> builder -> builder.accept("value", MinecraftHasher.STRING, ClickEvent::value);
|
||||
});
|
||||
|
||||
MinecraftHasher<HoverEvent.Action<?>> HOVER_EVENT_ACTION = MinecraftHasher.STRING.convert(HoverEvent.Action::toString);
|
||||
|
||||
MinecraftHasher<HoverEvent<?>> HOVER_EVENT = HOVER_EVENT_ACTION.dispatch("action", HoverEvent::action, action -> {
|
||||
if (action == HoverEvent.Action.SHOW_TEXT) {
|
||||
|
||||
} else if (action == HoverEvent.Action.SHOW_ITEM) {
|
||||
|
||||
}
|
||||
return builder -> builder;
|
||||
});
|
||||
|
||||
// TODO shadow colours - needs kyori bump
|
||||
MinecraftHasher<Style> STYLE = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.optionalNullable("color", COLOR, Style::color)
|
||||
.optional("bold", DECORATION_STATE, style -> style.decoration(TextDecoration.BOLD), TextDecoration.State.NOT_SET)
|
||||
.optional("italic", DECORATION_STATE, style -> style.decoration(TextDecoration.ITALIC), TextDecoration.State.NOT_SET)
|
||||
.optional("underlined", DECORATION_STATE, style -> style.decoration(TextDecoration.UNDERLINED), TextDecoration.State.NOT_SET)
|
||||
.optional("strikethrough", DECORATION_STATE, style -> style.decoration(TextDecoration.STRIKETHROUGH), TextDecoration.State.NOT_SET)
|
||||
.optional("obfuscated", DECORATION_STATE, style -> style.decoration(TextDecoration.OBFUSCATED), TextDecoration.State.NOT_SET)
|
||||
.optionalNullable("click_event", CLICK_EVENT, Style::clickEvent)
|
||||
/*.optional() // hover event*/
|
||||
.optionalNullable("insertion", MinecraftHasher.STRING, Style::insertion)
|
||||
.optionalNullable("font", MinecraftHasher.KEY, Style::font));
|
||||
|
||||
MinecraftHasher<TextComponent> SIMPLE_TEXT_COMPONENT = MinecraftHasher.STRING.convert(TextComponent::content);
|
||||
|
||||
MinecraftHasher<TextComponent> TEXT_COMPONENT = (value, encoder) -> {
|
||||
if (value.children().isEmpty() && value.style().isEmpty()) {
|
||||
return SIMPLE_TEXT_COMPONENT.hash(value, encoder);
|
||||
}
|
||||
return encoder.empty(); // TODO
|
||||
};
|
||||
|
||||
MinecraftHasher<Component> ACTUAL_COMPONENT = (value, encoder) -> encoder.empty(); // TODO
|
||||
}
|
|
@ -63,10 +63,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class ComponentHashers {
|
||||
public class DataComponentHashers {
|
||||
private static final Map<DataComponentType<?>, MinecraftHasher<?>> hashers = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
@ -102,7 +101,7 @@ public class ComponentHashers {
|
|||
registerInt(DataComponentTypes.REPAIR_COST);
|
||||
|
||||
register(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, MinecraftHasher.BOOL);
|
||||
//register(DataComponentTypes.INTANGIBLE_PROJECTILE); // TODO MCPL is wrong
|
||||
registerUnit(DataComponentTypes.INTANGIBLE_PROJECTILE);
|
||||
|
||||
registerMap(DataComponentTypes.FOOD, builder -> builder
|
||||
.accept("nutrition", MinecraftHasher.INT, FoodProperties::getNutrition)
|
||||
|
@ -156,8 +155,8 @@ public class ComponentHashers {
|
|||
registerInt(DataComponentTypes.MAP_ID);
|
||||
register(DataComponentTypes.MAP_DECORATIONS, MinecraftHasher.NBT_MAP);
|
||||
|
||||
// TODO charged projectiles also need the recursion™
|
||||
// TODO same for bundle contents
|
||||
register(DataComponentTypes.CHARGED_PROJECTILES, RegistryHasher.ITEM_STACK.list()); // TODO test one of these, preferably bundle contents which is more complicated
|
||||
register(DataComponentTypes.BUNDLE_CONTENTS, RegistryHasher.ITEM_STACK.list());
|
||||
|
||||
registerMap(DataComponentTypes.POTION_CONTENTS, builder -> builder
|
||||
.optional("potion", RegistryHasher.POTION, PotionContents::getPotionId, -1)
|
||||
|
@ -166,6 +165,17 @@ public class ComponentHashers {
|
|||
.optionalNullable("custom_name", MinecraftHasher.STRING, PotionContents::getCustomName));
|
||||
|
||||
register(DataComponentTypes.POTION_DURATION_SCALE, MinecraftHasher.FLOAT);
|
||||
register(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, RegistryHasher.SUSPICIOUS_STEW_EFFECT.list());
|
||||
|
||||
// TODO writable book content
|
||||
// TODO written book content
|
||||
// TODO trim
|
||||
register(DataComponentTypes.DEBUG_STICK_STATE, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.BUCKET_ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.BLOCK_ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
|
||||
register(DataComponentTypes.INSTRUMENT, RegistryHasher.INSTRUMENT_COMPONENT);
|
||||
}
|
||||
|
||||
private static void registerUnit(DataComponentType<Unit> component) {
|
||||
|
@ -176,7 +186,7 @@ public class ComponentHashers {
|
|||
register(component, MinecraftHasher.INT);
|
||||
}
|
||||
|
||||
private static <T> void registerMap(DataComponentType<T> component, UnaryOperator<MapHasher<T>> builder) {
|
||||
private static <T> void registerMap(DataComponentType<T> component, MapBuilder<T> builder) {
|
||||
register(component, MinecraftHasher.mapBuilder(builder));
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2025 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.hashing;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MapBuilder<T> extends UnaryOperator<MapHasher<T>> {
|
||||
}
|
|
@ -40,9 +40,13 @@ public class MapHasher<T> {
|
|||
private final Map<HashCode, HashCode> map;
|
||||
|
||||
MapHasher(T object, MinecraftHashEncoder encoder) {
|
||||
this(object, encoder, new HashMap<>());
|
||||
}
|
||||
|
||||
private MapHasher(T object, MinecraftHashEncoder encoder, Map<HashCode, HashCode> map) {
|
||||
this.encoder = encoder;
|
||||
this.object = object;
|
||||
map = new HashMap<>();
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public MapHasher<T> accept(String key, HashCode hash) {
|
||||
|
@ -54,6 +58,12 @@ public class MapHasher<T> {
|
|||
return accept(key, hasher.hash(extractor.apply(object), encoder));
|
||||
}
|
||||
|
||||
// Adds keys and values from the builder directly to this map (document me properly)
|
||||
public <V> MapHasher<T> accept(Function<V, MapBuilder<T>> builderExtractor, Function<T, V> extractor) {
|
||||
builderExtractor.apply(extractor.apply(object)).apply(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <V> MapHasher<T> optionalNullable(String key, MinecraftHasher<V> hasher, Function<T, V> extractor) {
|
||||
V value = extractor.apply(object);
|
||||
if (value != null) {
|
||||
|
|
|
@ -83,6 +83,12 @@ public interface MinecraftHasher<T> {
|
|||
return (list, encoder) -> encoder.list(list.stream().map(element -> hash(element, encoder)).toList());
|
||||
}
|
||||
|
||||
default <D> MinecraftHasher<D> dispatch(String typeKey, Function<D, T> typeExtractor, Function<T, MapBuilder<D>> hashDispatch) {
|
||||
return mapBuilder(builder -> builder
|
||||
.accept(typeKey, this, typeExtractor)
|
||||
.accept(hashDispatch, typeExtractor));
|
||||
}
|
||||
|
||||
default <F> MinecraftHasher<F> convert(Function<F, T> converter) {
|
||||
return (value, encoder) -> hash(converter.apply(value), encoder);
|
||||
}
|
||||
|
@ -91,6 +97,11 @@ public interface MinecraftHasher<T> {
|
|||
return (value, encoder) -> hash(converter.apply(encoder.session(), value), encoder);
|
||||
}
|
||||
|
||||
static <T> MinecraftHasher<T> lazyInitialize(Supplier<MinecraftHasher<T>> hasher) {
|
||||
Supplier<MinecraftHasher<T>> memoized = Suppliers.memoize(hasher::get);
|
||||
return (value, encoder) -> memoized.get().hash(value, encoder);
|
||||
}
|
||||
|
||||
static <T> MinecraftHasher<T> recursive(UnaryOperator<MinecraftHasher<T>> delegate) {
|
||||
return new Recursive<>(delegate);
|
||||
}
|
||||
|
@ -104,7 +115,7 @@ public interface MinecraftHasher<T> {
|
|||
return STRING.convert(t -> t.name().toLowerCase());
|
||||
}
|
||||
|
||||
static <T> MinecraftHasher<T> mapBuilder(UnaryOperator<MapHasher<T>> builder) {
|
||||
static <T> MinecraftHasher<T> mapBuilder(MapBuilder<T> builder) {
|
||||
return (value, encoder) -> builder.apply(new MapHasher<>(value, encoder)).build();
|
||||
}
|
||||
|
||||
|
@ -114,6 +125,16 @@ public interface MinecraftHasher<T> {
|
|||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
|
||||
static <T, F, S> MinecraftHasher<T> either(MinecraftHasher<F> firstHasher, Function<T, F> firstExtractor, MinecraftHasher<S> secondHasher, Function<T, S> secondExtractor) {
|
||||
return (value, encoder) -> {
|
||||
F first = firstExtractor.apply(value);
|
||||
if (first != null) {
|
||||
return firstHasher.hash(first, encoder);
|
||||
}
|
||||
return secondHasher.hash(secondExtractor.apply(value), encoder);
|
||||
};
|
||||
}
|
||||
|
||||
class Recursive<T> implements MinecraftHasher<T> {
|
||||
private final Supplier<MinecraftHasher<T>> delegate;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.geysermc.geyser.inventory.item.Potion;
|
|||
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
|
||||
import org.geysermc.geyser.util.MinecraftKey;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
@ -36,7 +37,9 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentComponent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.SuspiciousStewEffect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ToolData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound;
|
||||
|
@ -58,7 +61,7 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
|
|||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"}) // Java generics :(
|
||||
MinecraftHasher<DataComponent<?, ?>> DATA_COMPONENT = (component, encoder) -> {
|
||||
MinecraftHasher hasher = ComponentHashers.hasherOrEmpty(component.getType());
|
||||
MinecraftHasher hasher = DataComponentHashers.hasherOrEmpty(component.getType());
|
||||
return hasher.hash(component.getValue(), encoder);
|
||||
};
|
||||
|
||||
|
@ -71,6 +74,12 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
|
|||
|
||||
MinecraftHasher<Effect> EFFECT = enumRegistry();
|
||||
|
||||
RegistryHasher EFFECT_ID = enumIdRegistry(Effect.values());
|
||||
|
||||
MinecraftHasher<SuspiciousStewEffect> SUSPICIOUS_STEW_EFFECT = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("id", EFFECT_ID, SuspiciousStewEffect::getMobEffectId)
|
||||
.optional("duration", INT, SuspiciousStewEffect::getDuration, 160));
|
||||
|
||||
MinecraftHasher<MobEffectInstance> MOB_EFFECT_INSTANCE = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("id", RegistryHasher.EFFECT, MobEffectInstance::getEffect)
|
||||
.optional("amplifier", BYTE, instance -> (byte) instance.getDetails().getAmplifier(), (byte) 0)
|
||||
|
@ -94,6 +103,16 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
|
|||
return CUSTOM_SOUND.hash((CustomSound) sound, encoder);
|
||||
};
|
||||
|
||||
MinecraftHasher<InstrumentComponent.Instrument> DIRECT_INSTRUMENT = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("sound_event", SOUND_EVENT, InstrumentComponent.Instrument::soundEvent)
|
||||
.accept("use_duration", FLOAT, InstrumentComponent.Instrument::useDuration)
|
||||
.accept("range", FLOAT, InstrumentComponent.Instrument::range)
|
||||
/*.accept("description", COMPONENT, InstrumentComponent.Instrument::description)*/); // TODO component description
|
||||
|
||||
MinecraftHasher<Holder<InstrumentComponent.Instrument>> INSTRUMENT = holder(JavaRegistries.INSTRUMENT, DIRECT_INSTRUMENT);
|
||||
|
||||
MinecraftHasher<InstrumentComponent> INSTRUMENT_COMPONENT = MinecraftHasher.either(INSTRUMENT, InstrumentComponent::instrumentHolder, KEY, InstrumentComponent::instrumentLocation);
|
||||
|
||||
MinecraftHasher<ToolData.Rule> TOOL_RULE = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("blocks", RegistryHasher.BLOCK.holderSet(), ToolData.Rule::getBlocks)
|
||||
.optionalNullable("speed", MinecraftHasher.FLOAT, ToolData.Rule::getSpeed)
|
||||
|
@ -104,6 +123,17 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
|
|||
return hasher::hash;
|
||||
}
|
||||
|
||||
// We don't need the registry generic type, and this works easier for goat horn instruments
|
||||
static <T> MinecraftHasher<Holder<T>> holder(JavaRegistryKey<?> registry, MinecraftHasher<T> direct) {
|
||||
RegistryHasher registryHasher = registry(registry);
|
||||
return (value, encoder) -> {
|
||||
if (value.isId()) {
|
||||
return registryHasher.hash(value.id(), encoder);
|
||||
}
|
||||
return direct.hash(value.custom(), encoder);
|
||||
};
|
||||
}
|
||||
|
||||
static <T extends Enum<T>> MinecraftHasher<T> enumRegistry() {
|
||||
return KEY.convert(t -> MinecraftKey.key(t.name().toLowerCase()));
|
||||
}
|
||||
|
|
|
@ -86,10 +86,11 @@ public final class RegistryCache {
|
|||
private static final Map<Key, BiConsumer<RegistryCache, List<RegistryEntry>>> REGISTRIES = new HashMap<>();
|
||||
|
||||
static {
|
||||
// TODO reorder these, and maybe have all in javaregistries (though that'd make geyser cache tags for all of them)
|
||||
register("chat_type", cache -> cache.chatTypes, ChatDecoration::readChatType);
|
||||
register("dimension_type", cache -> cache.dimensions, JavaDimension::read);
|
||||
register(JavaRegistries.ENCHANTMENT, cache -> cache.enchantments, Enchantment::read);
|
||||
register("instrument", cache -> cache.instruments, GeyserInstrument::read);
|
||||
register(JavaRegistries.INSTRUMENT, cache -> cache.instruments, GeyserInstrument::read);
|
||||
register("jukebox_song", cache -> cache.jukeboxSongs, JukeboxSong::read);
|
||||
register("painting_variant", cache -> cache.paintings, context -> PaintingType.getByName(context.id()));
|
||||
register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial);
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.geysermc.geyser.entity.type.living.animal.farm.TemperatureVariantAnim
|
|||
import org.geysermc.geyser.entity.type.living.animal.tameable.CatEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity;
|
||||
import org.geysermc.geyser.inventory.item.BannerPattern;
|
||||
import org.geysermc.geyser.inventory.item.GeyserInstrument;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
|
@ -55,6 +56,7 @@ public class JavaRegistries {
|
|||
public static final JavaRegistryKey<Item> ITEM = create("item", Registries.JAVA_ITEMS, Item::javaId, Item::javaKey);
|
||||
public static final JavaRegistryKey<Enchantment> ENCHANTMENT = create("enchantment", RegistryCache::enchantments);
|
||||
public static final JavaRegistryKey<BannerPattern> BANNER_PATTERN = create("banner_pattern", RegistryCache::bannerPatterns);
|
||||
public static final JavaRegistryKey<GeyserInstrument> INSTRUMENT = create("instrument", RegistryCache::instruments);
|
||||
|
||||
public static final JavaRegistryKey<CatEntity.BuiltInVariant> CAT_VARIANT = create("cat_variant", RegistryCache::catVariants);
|
||||
public static final JavaRegistryKey<FrogEntity.BuiltInVariant> FROG_VARIANT = create("frog_variant", RegistryCache::frogVariants);
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.RespawnPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.item.hashing.ComponentHashers;
|
||||
import org.geysermc.geyser.item.hashing.DataComponentHashers;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.TeleportCache;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
|
@ -84,7 +84,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
|
|||
entity.updateOwnRotation(entity.getYaw(), entity.getPitch(), entity.getHeadYaw());
|
||||
|
||||
session.setSpawned(true);
|
||||
ComponentHashers.testHashing(session);
|
||||
DataComponentHashers.testHashing(session);
|
||||
|
||||
// Make sure the player moves away from (0, 32767, 0) before accepting movement packets
|
||||
session.setUnconfirmedTeleport(new TeleportCache(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ(), packet.getXRot(), packet.getYRot(), packet.getId())); // TODO
|
||||
|
|
Loading…
Add table
Reference in a new issue