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:
Commit
c79aea4e4e
@ -25,8 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.item.enchantment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
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.session.cache.registry.RegistryEntryContext;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
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.
|
||||
@ -86,21 +88,21 @@ public record Enchantment(String identifier,
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return new HolderSet(new int[]{});
|
||||
return new HolderSet(IntArrays.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
if (holderSet instanceof String stringTag) {
|
||||
// Tag
|
||||
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 {
|
||||
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) {
|
||||
// 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");
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import lombok.Setter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
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.ScoreboardUpdater.ScoreboardSession;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@ -70,6 +71,8 @@ public final class WorldCache {
|
||||
@Setter
|
||||
private boolean editingSignOnFront;
|
||||
|
||||
private final Object2IntMap<Item> activeCooldowns = new Object2IntOpenHashMap<>(2);
|
||||
|
||||
public WorldCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
this.scoreboard = new Scoreboard(session);
|
||||
@ -201,4 +204,32 @@ public final class WorldCache {
|
||||
public String removeActiveRecord(Vector3i 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
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.ItemDefinition;
|
||||
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.InventoryTransactionPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
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.InteractionResult;
|
||||
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.player.GameMode;
|
||||
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.PlayerAction;
|
||||
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.player.ServerboundInteractPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
|
||||
@ -373,6 +378,22 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
break;
|
||||
} else if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().writtenBook().getBedrockDefinition()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,5 +57,7 @@ public class JavaCooldownTranslator extends PacketTranslator<ClientboundCooldown
|
||||
bedrockPacket.setCooldownDuration(packet.getCooldownTicks());
|
||||
session.sendUpstreamPacket(bedrockPacket);
|
||||
}
|
||||
|
||||
session.getWorldCache().setCooldown(item, packet.getCooldownTicks());
|
||||
}
|
||||
}
|
||||
|
@ -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.plain.PlainTextComponentSerializer;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
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.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.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.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MessageTranslator {
|
||||
// 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.
|
||||
*/
|
||||
public static String deserializeDescription(GeyserSession session, NbtMap tag) {
|
||||
NbtMap description = tag.getCompound("description");
|
||||
Object description = tag.get("description");
|
||||
Component parsed = componentFromNbtTag(description);
|
||||
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) {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren