3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-20 15:00:11 +01:00

Merge branch 'master' into new-mcpl

Dieser Commit ist enthalten in:
chris 2024-09-15 13:35:59 +08:00 committet von GitHub
Commit c79aea4e4e
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
5 geänderte Dateien mit 77 neuen und 13 gelöschten Zeilen

Datei anzeigen

@ -25,8 +25,7 @@
package org.geysermc.geyser.item.enchantment; package org.geysermc.geyser.item.enchantment;
import java.util.List; import it.unimi.dsi.fastutil.ints.IntArrays;
import java.util.function.Function;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
@ -35,11 +34,14 @@ import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext; import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet; import java.util.function.ToIntFunction;
/** /**
* @param description only populated if {@link #bedrockEnchantment()} is not null. * @param description only populated if {@link #bedrockEnchantment()} is not null.
@ -86,21 +88,21 @@ public record Enchantment(String identifier,
} }
// TODO holder set util? // TODO holder set util?
private static HolderSet readHolderSet(@Nullable Object holderSet, Function<Key, Integer> keyIdMapping) { private static HolderSet readHolderSet(@Nullable Object holderSet, ToIntFunction<Key> keyIdMapping) {
if (holderSet == null) { if (holderSet == null) {
return new HolderSet(new int[]{}); return new HolderSet(IntArrays.EMPTY_ARRAY);
} }
if (holderSet instanceof String stringTag) { if (holderSet instanceof String stringTag) {
// Tag // Tag
if (stringTag.startsWith("#")) { if (stringTag.startsWith("#")) {
return new HolderSet(Key.key(stringTag.substring(1))); // Remove '#' at beginning that indicates tag return new HolderSet(MinecraftKey.key(stringTag.substring(1))); // Remove '#' at beginning that indicates tag
} else { } else {
return new HolderSet(new int[]{keyIdMapping.apply(Key.key(stringTag))}); return new HolderSet(new int[]{keyIdMapping.applyAsInt(MinecraftKey.key(stringTag))});
} }
} else if (holderSet instanceof List<?> list) { } else if (holderSet instanceof List<?> list) {
// Assume the list is a list of strings // Assume the list is a list of strings
return new HolderSet(list.stream().map(o -> (String) o).map(Key::key).map(keyIdMapping).mapToInt(Integer::intValue).toArray()); return new HolderSet(list.stream().map(o -> (String) o).map(Key::key).mapToInt(keyIdMapping).toArray());
} }
throw new IllegalArgumentException("Holder set must either be a tag, a string ID or a list of string IDs"); throw new IllegalArgumentException("Holder set must either be a tag, a string ID or a list of string IDs");
} }

Datei anzeigen

@ -34,6 +34,7 @@ import lombok.Setter;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.Scoreboard;
import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession; import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -70,6 +71,8 @@ public final class WorldCache {
@Setter @Setter
private boolean editingSignOnFront; private boolean editingSignOnFront;
private final Object2IntMap<Item> activeCooldowns = new Object2IntOpenHashMap<>(2);
public WorldCache(GeyserSession session) { public WorldCache(GeyserSession session) {
this.session = session; this.session = session;
this.scoreboard = new Scoreboard(session); this.scoreboard = new Scoreboard(session);
@ -201,4 +204,32 @@ public final class WorldCache {
public String removeActiveRecord(Vector3i pos) { public String removeActiveRecord(Vector3i pos) {
return this.activeRecords.remove(pos); return this.activeRecords.remove(pos);
} }
public void setCooldown(Item item, int ticks) {
if (ticks == 0) {
// As of Java 1.21
this.activeCooldowns.removeInt(item);
return;
}
this.activeCooldowns.put(item, session.getTicks() + ticks);
}
public boolean hasCooldown(Item item) {
return this.activeCooldowns.containsKey(item);
}
public void tick() {
// Implementation note: technically we could empty the field during hasCooldown checks,
// but we don't want the cooldown field to balloon in size from overuse.
if (!this.activeCooldowns.isEmpty()) {
int ticks = session.getTicks();
Iterator<Object2IntMap.Entry<Item>> it = Object2IntMaps.fastIterator(this.activeCooldowns);
while (it.hasNext()) {
Object2IntMap.Entry<Item> entry = it.next();
if (entry.getIntValue() <= ticks) {
it.remove();
}
}
}
}
} }

Datei anzeigen

@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
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;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
@ -42,6 +43,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetIte
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket; import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Entity;
@ -75,12 +77,15 @@ import org.geysermc.geyser.util.CooldownUtils;
import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.InventoryUtils;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; 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.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
@ -373,6 +378,22 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
break; break;
} else if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().writtenBook().getBedrockDefinition()) { } else if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().writtenBook().getBedrockDefinition()) {
session.setCurrentBook(packet.getItemInHand()); session.setCurrentBook(packet.getItemInHand());
} else if (session.getPlayerInventory().getItemInHand().asItem() == Items.GOAT_HORN) {
// Temporary workaround while we don't have full item/block use tracking.
if (!session.getWorldCache().hasCooldown(Items.GOAT_HORN)) {
Holder<Instrument> instrument = session.getPlayerInventory()
.getItemInHand()
.getComponent(DataComponentType.INSTRUMENT);
if (instrument != null && instrument.isId()) {
// BDS uses a LevelSoundEvent2Packet, but that doesn't work here... (as of 1.21.20)
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
soundPacket.setSound(SoundEvent.valueOf("GOAT_CALL_" + instrument.id()));
soundPacket.setPosition(session.getPlayerEntity().getPosition());
soundPacket.setIdentifier("minecraft:player");
soundPacket.setExtraData(-1);
session.sendUpstreamPacket(soundPacket);
}
}
} }
} }

Datei anzeigen

@ -57,5 +57,7 @@ public class JavaCooldownTranslator extends PacketTranslator<ClientboundCooldown
bedrockPacket.setCooldownDuration(packet.getCooldownTicks()); bedrockPacket.setCooldownDuration(packet.getCooldownTicks());
session.sendUpstreamPacket(bedrockPacket); session.sendUpstreamPacket(bedrockPacket);
} }
session.getWorldCache().setCooldown(item, packet.getCooldownTicks());
} }
} }

Datei anzeigen

@ -40,18 +40,25 @@ import net.kyori.adventure.text.serializer.legacy.CharacterAndFormat;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.packet.TextPacket; import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.*; import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.ChatDecoration;
import org.geysermc.geyser.text.DummyLegacyHoverEventSerializer;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.GsonComponentSerializerWrapper;
import org.geysermc.geyser.text.MinecraftTranslationRegistry;
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
import org.geysermc.mcprotocollib.protocol.data.game.Holder; 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.ChatType;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration; import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
import java.util.*; import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
public class MessageTranslator { public class MessageTranslator {
// These are used for handling the translations of the messages // These are used for handling the translations of the messages
@ -434,7 +441,7 @@ public class MessageTranslator {
* Deserialize an NbtMap with a description text component (usually provided from a registry) into a Bedrock-formatted string. * Deserialize an NbtMap with a description text component (usually provided from a registry) into a Bedrock-formatted string.
*/ */
public static String deserializeDescription(GeyserSession session, NbtMap tag) { public static String deserializeDescription(GeyserSession session, NbtMap tag) {
NbtMap description = tag.getCompound("description"); Object description = tag.get("description");
Component parsed = componentFromNbtTag(description); Component parsed = componentFromNbtTag(description);
return convertMessage(session, parsed); return convertMessage(session, parsed);
} }
@ -482,7 +489,8 @@ public class MessageTranslator {
} }
} }
throw new IllegalArgumentException("Expected tag to be a literal string, a list of components, or a component object with a text/translate key"); GeyserImpl.getInstance().getLogger().error("Expected tag to be a literal string, a list of components, or a component object with a text/translate key: " + nbtTag);
return Component.empty();
} }
private static List<Component> componentsFromNbtList(List<?> list, Style style) { private static List<Component> componentsFromNbtList(List<?> list, Style style) {