mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-10-23 17:06:19 +02:00
Fix #5089 and made Registries instance based
This commit is contained in:
parent
d64c0b38da
commit
0eee91f523
56 changed files with 1475 additions and 709 deletions
|
@ -34,6 +34,30 @@ import io.netty.channel.epoll.Epoll;
|
|||
import io.netty.util.NettyRuntime;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import io.netty.util.internal.SystemPropertyUtil;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.Key;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -103,31 +127,6 @@ import org.geysermc.geyser.util.VersionCheckUtils;
|
|||
import org.geysermc.geyser.util.WebUtils;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.Key;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Getter
|
||||
public class GeyserImpl implements GeyserApi, EventRegistrar {
|
||||
public static final ObjectMapper JSON_MAPPER = new ObjectMapper()
|
||||
|
@ -297,7 +296,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||
|
||||
SkinProvider.registerCacheImageTask(this);
|
||||
|
||||
Registries.RESOURCE_PACKS.load();
|
||||
Registries.resourcePacks().load();
|
||||
|
||||
String geyserUdpPort = System.getProperty("geyserUdpPort", "");
|
||||
String pluginUdpPort = geyserUdpPort.isEmpty() ? System.getProperty("pluginUdpPort", "") : geyserUdpPort;
|
||||
|
@ -723,7 +722,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||
runIfNonNull(newsHandler, NewsHandler::shutdown);
|
||||
runIfNonNull(erosionUnixListener, UnixSocketClientListener::close);
|
||||
|
||||
Registries.RESOURCE_PACKS.get().clear();
|
||||
Registries.resourcePacks().get().clear();
|
||||
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
@ -781,7 +780,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R extends T, T> @NonNull R provider(@NonNull Class<T> apiClass, @Nullable Object... args) {
|
||||
ProviderSupplier provider = Registries.PROVIDERS.get(apiClass);
|
||||
ProviderSupplier provider = Registries.providers().get(apiClass);
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("No provider found for " + apiClass);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
|||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.translator.entity.EntityMetadataTranslator;
|
||||
import org.geysermc.geyser.util.EnvironmentUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
@ -146,13 +145,8 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the given entity. If a testing environment has been discovered the entity is not registered,
|
||||
* otherwise it is. This is to prevent all the registries from loading, which will fail (and should
|
||||
* not be loaded) while testing
|
||||
*/
|
||||
public EntityDefinition<T> build() {
|
||||
return build(!EnvironmentUtils.isUnitTesting);
|
||||
return build(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,10 +159,10 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
}
|
||||
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators);
|
||||
if (register && definition.entityType() != null) {
|
||||
Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition);
|
||||
Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition);
|
||||
Registries.entityDefinitions().get().putIfAbsent(definition.entityType(), definition);
|
||||
Registries.javaEntityIdentifiers().get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition);
|
||||
if (definition.registeredProperties() != null) {
|
||||
Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(identifier));
|
||||
Registries.bedrockEntityProperties().get().add(definition.registeredProperties().toNbtMap(identifier));
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
|
|
|
@ -145,7 +145,6 @@ import org.geysermc.geyser.entity.type.living.monster.raid.VindicatorEntity;
|
|||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.EnvironmentUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
|
@ -1122,10 +1121,7 @@ public final class EntityDefinitions {
|
|||
.identifier("minecraft:armor_stand") // Emulated
|
||||
.build(false); // Never sent over the network
|
||||
|
||||
// causes the registries to load
|
||||
if (!EnvironmentUtils.isUnitTesting) {
|
||||
Registries.JAVA_ENTITY_IDENTIFIERS.get().put("minecraft:marker", null); // We don't need an entity definition for this as it is never sent over the network
|
||||
}
|
||||
Registries.javaEntityIdentifiers().get().put("minecraft:marker", null); // We don't need an entity definition for this as it is never sent over the network
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -38,8 +39,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatE
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AreaEffectCloudEntity extends Entity {
|
||||
|
||||
public AreaEffectCloudEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
|
@ -69,7 +68,7 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
|
||||
public void setParticle(EntityMetadata<Particle, ?> entityMetadata) {
|
||||
Particle particle = entityMetadata.getValue();
|
||||
Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
|
||||
Registries.particles().map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type));
|
||||
|
||||
if (particle.getData() instanceof EntityEffectParticleData effectParticleData) {
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -40,9 +42,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ThrownPotionEntity extends ThrowableItemEntity {
|
||||
private static final EnumSet<Potion> NON_ENCHANTED_POTIONS = EnumSet.of(Potion.WATER, Potion.MUNDANE, Potion.THICK, Potion.AWKWARD);
|
||||
|
||||
|
@ -73,7 +72,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
|
|||
}
|
||||
}
|
||||
|
||||
boolean isLingering = Registries.JAVA_ITEMS.get().get(itemStack.getId()) == Items.LINGERING_POTION;
|
||||
boolean isLingering = Registries.javaItems().get().get(itemStack.getId()) == Items.LINGERING_POTION;
|
||||
setFlag(EntityFlag.LINGERING, isLingering);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -36,6 +39,7 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.scoreboard.Team;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
|
@ -45,9 +49,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ArmorStandEntity extends LivingEntity {
|
||||
|
||||
// These are used to store the state of the armour stand for use when handling invisibility
|
||||
|
@ -123,6 +124,12 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNametag(@Nullable Team team) {
|
||||
// unlike all other LivingEntities, armor stands are not affected by team nametag visibility
|
||||
super.updateNametag(team, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayName(EntityMetadata<Optional<Component>, ?> entityMetadata) {
|
||||
super.setDisplayName(entityMetadata);
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
|
|||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||
|
@ -112,20 +111,6 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
|||
this.texturesProperty = texturesProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use! For testing purposes only
|
||||
*/
|
||||
public PlayerEntity(GeyserSession session, long geyserId, UUID uuid, String username) {
|
||||
super(session, -1, geyserId, uuid, EntityDefinitions.PLAYER, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0);
|
||||
this.username = username;
|
||||
this.nametag = username;
|
||||
this.texturesProperty = null;
|
||||
|
||||
// clear initial metadata
|
||||
dirtyMetadata.apply(new EntityDataMap());
|
||||
setFlagsDirty(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
|
@ -193,11 +178,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
|||
if (session.getEntityCache().getPlayerEntity(uuid) == null)
|
||||
return;
|
||||
|
||||
if (session.getEntityCache().getEntityByGeyserId(geyserId) == null) {
|
||||
session.getEntityCache().spawnEntity(this);
|
||||
} else {
|
||||
spawnEntity();
|
||||
}
|
||||
session.getEntityCache().spawnEntity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.inventory;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.HashMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
|
@ -39,8 +44,6 @@ 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.DataComponents;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Data
|
||||
public class GeyserItemStack {
|
||||
public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null);
|
||||
|
@ -165,7 +168,7 @@ public class GeyserItemStack {
|
|||
|
||||
public Item asItem() {
|
||||
if (item == null) {
|
||||
return (item = Registries.JAVA_ITEMS.get().get(javaId));
|
||||
return (item = Registries.javaItems().get().get(javaId));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,46 @@
|
|||
|
||||
package org.geysermc.geyser.item;
|
||||
|
||||
import static org.geysermc.geyser.item.type.Item.builder;
|
||||
|
||||
import org.geysermc.geyser.item.components.Rarity;
|
||||
import org.geysermc.geyser.item.components.ToolTier;
|
||||
import org.geysermc.geyser.item.type.*;
|
||||
import org.geysermc.geyser.item.type.ArmorItem;
|
||||
import org.geysermc.geyser.item.type.ArrowItem;
|
||||
import org.geysermc.geyser.item.type.AxolotlBucketItem;
|
||||
import org.geysermc.geyser.item.type.BannerItem;
|
||||
import org.geysermc.geyser.item.type.BlockItem;
|
||||
import org.geysermc.geyser.item.type.BoatItem;
|
||||
import org.geysermc.geyser.item.type.CompassItem;
|
||||
import org.geysermc.geyser.item.type.CrossbowItem;
|
||||
import org.geysermc.geyser.item.type.DecoratedPotItem;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.item.type.DyeableArmorItem;
|
||||
import org.geysermc.geyser.item.type.ElytraItem;
|
||||
import org.geysermc.geyser.item.type.EnchantedBookItem;
|
||||
import org.geysermc.geyser.item.type.FilledMapItem;
|
||||
import org.geysermc.geyser.item.type.FireworkRocketItem;
|
||||
import org.geysermc.geyser.item.type.FireworkStarItem;
|
||||
import org.geysermc.geyser.item.type.FishingRodItem;
|
||||
import org.geysermc.geyser.item.type.GoatHornItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.item.type.MaceItem;
|
||||
import org.geysermc.geyser.item.type.MapItem;
|
||||
import org.geysermc.geyser.item.type.OminousBottleItem;
|
||||
import org.geysermc.geyser.item.type.PlayerHeadItem;
|
||||
import org.geysermc.geyser.item.type.PotionItem;
|
||||
import org.geysermc.geyser.item.type.ShieldItem;
|
||||
import org.geysermc.geyser.item.type.ShulkerBoxItem;
|
||||
import org.geysermc.geyser.item.type.SpawnEggItem;
|
||||
import org.geysermc.geyser.item.type.TieredItem;
|
||||
import org.geysermc.geyser.item.type.TippedArrowItem;
|
||||
import org.geysermc.geyser.item.type.TropicalFishBucketItem;
|
||||
import org.geysermc.geyser.item.type.WolfArmorItem;
|
||||
import org.geysermc.geyser.item.type.WritableBookItem;
|
||||
import org.geysermc.geyser.item.type.WrittenBookItem;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
|
||||
import static org.geysermc.geyser.item.type.Item.builder;
|
||||
|
||||
/**
|
||||
* A list, in order, of all Java items.
|
||||
*/
|
||||
|
@ -1375,13 +1407,13 @@ public final class Items {
|
|||
public static final int AIR_ID = AIR.javaId();
|
||||
|
||||
private static <T extends Item> T register(T item) {
|
||||
return register(item, Registries.JAVA_ITEMS.get().size());
|
||||
return register(item, Registries.javaItems().get().size());
|
||||
}
|
||||
|
||||
public static <T extends Item> T register(T item, int id) {
|
||||
item.setJavaId(id);
|
||||
Registries.JAVA_ITEMS.registerWithAnyIndex(id, item, AIR);
|
||||
Registries.JAVA_ITEM_IDENTIFIERS.register(item.javaIdentifier(), item);
|
||||
Registries.javaItems().registerWithAnyIndex(id, item, AIR);
|
||||
Registries.javaItemIdentifiers().register(item.javaIdentifier(), item);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
package org.geysermc.geyser.item.enchantment;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.ToIntFunction;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -37,12 +42,6 @@ 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 java.util.function.ToIntFunction;
|
||||
|
||||
/**
|
||||
* @param description only populated if {@link #bedrockEnchantment()} is not null.
|
||||
* @param anvilCost also as a rarity multiplier
|
||||
|
@ -60,7 +59,7 @@ public record Enchantment(String identifier,
|
|||
NbtMap data = context.data();
|
||||
Set<EnchantmentComponent> effects = readEnchantmentComponents(data.getCompound("effects"));
|
||||
|
||||
HolderSet supportedItems = readHolderSet(data.get("supported_items"), itemId -> Registries.JAVA_ITEM_IDENTIFIERS.getOrDefault(itemId.asString(), Items.AIR).javaId());
|
||||
HolderSet supportedItems = readHolderSet(data.get("supported_items"), itemId -> Registries.javaItemIdentifiers().getOrDefault(itemId.asString(), Items.AIR).javaId());
|
||||
|
||||
int maxLevel = data.getInt("max_level");
|
||||
int anvilCost = data.getInt("anvil_cost");
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
package org.geysermc.geyser.network;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.OptionalInt;
|
||||
import org.cloudburstmc.protocol.bedrock.BedrockDisconnectReasons;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.compat.BedrockCompat;
|
||||
|
@ -69,14 +76,6 @@ import org.geysermc.geyser.util.LoginEncryptionUtils;
|
|||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.geyser.util.VersionCheckUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
private boolean networkSettingsRequested = false;
|
||||
|
@ -94,7 +93,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
}
|
||||
|
||||
private PacketSignal translateAndDefault(BedrockPacket packet) {
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.translate(packet.getClass(), packet, session);
|
||||
Registries.bedrockPacketTranslators().translate(packet.getClass(), packet, session);
|
||||
return PacketSignal.HANDLED; // PacketSignal.UNHANDLED will log a WARN publicly
|
||||
}
|
||||
|
||||
|
@ -182,7 +181,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
|
||||
// Set the block translation based off of version
|
||||
session.setBlockMappings(BlockRegistries.BLOCKS.forVersion(loginPacket.getProtocolVersion()));
|
||||
session.setItemMappings(Registries.ITEMS.forVersion(loginPacket.getProtocolVersion()));
|
||||
session.setItemMappings(Registries.items().forVersion(loginPacket.getProtocolVersion()));
|
||||
|
||||
LoginEncryptionUtils.encryptPlayerConnection(session, loginPacket);
|
||||
|
||||
|
@ -200,7 +199,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
|
||||
geyser.getSessionManager().addPendingSession(session);
|
||||
|
||||
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session, new HashMap<>(Registries.RESOURCE_PACKS.get()));
|
||||
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session, new HashMap<>(Registries.resourcePacks().get()));
|
||||
this.geyser.eventBus().fire(this.resourcePackLoadEvent);
|
||||
|
||||
ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket();
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.provider.ProviderSupplier;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.ParticleMapping;
|
||||
import org.geysermc.geyser.registry.type.SoundMapping;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundTranslator;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
|
||||
public interface CommonRegistries {
|
||||
/**
|
||||
* A registry holding all the providers.
|
||||
* This has to be initialized first to allow extensions to access providers during other registry events.
|
||||
*/
|
||||
SimpleMappedRegistry<Class<?>, ProviderSupplier> providers();
|
||||
|
||||
/**
|
||||
* A registry holding a CompoundTag of the known entity identifiers.
|
||||
*/
|
||||
SimpleRegistry<NbtMap> bedrockEntityIdentifiers();
|
||||
/**
|
||||
* A map containing all Java entity identifiers and their respective Geyser definitions
|
||||
*/
|
||||
SimpleMappedRegistry<String, EntityDefinition<?>> javaEntityIdentifiers();
|
||||
|
||||
/**
|
||||
* A map containing all entity types and their respective Geyser definitions
|
||||
*/
|
||||
SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions();
|
||||
/**
|
||||
* A registry holding a list of all the known entity properties to be sent to the client after start game.
|
||||
*/
|
||||
SimpleRegistry<Set<NbtMap>> bedrockEntityProperties();
|
||||
|
||||
/**
|
||||
* A registry holding a CompoundTag of all the known biomes.
|
||||
*/
|
||||
SimpleRegistry<NbtMap> biomesNbt();
|
||||
/**
|
||||
* A mapped registry which stores Java biome identifiers and their Bedrock biome identifier.
|
||||
*/
|
||||
SimpleRegistry<Object2IntMap<String>> biomeIdentifiers();
|
||||
|
||||
/**
|
||||
* A mapped registry which stores a block entity identifier to its {@link BlockEntityTranslator}.
|
||||
*/
|
||||
SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> blockEntities();
|
||||
|
||||
/**
|
||||
* A registry containing all the Bedrock packet translators.
|
||||
*/
|
||||
PacketTranslatorRegistry<BedrockPacket> bedrockPacketTranslators();
|
||||
/**
|
||||
* A registry containing all the Java packet translators.
|
||||
*/
|
||||
PacketTranslatorRegistry<Packet> javaPacketTranslators();
|
||||
|
||||
/**
|
||||
* A registry containing all Java items ordered by their network ID.
|
||||
*/
|
||||
ListRegistry<Item> javaItems();
|
||||
SimpleMappedRegistry<String, Item> javaItemIdentifiers();
|
||||
/**
|
||||
* A versioned registry which holds {@link ItemMappings} for each version. These item mappings contain
|
||||
* primarily Bedrock version-specific data.
|
||||
*/
|
||||
VersionedRegistry<ItemMappings> items();
|
||||
|
||||
/**
|
||||
* A mapped registry holding the {@link ParticleType} to a corresponding {@link ParticleMapping}, containing various pieces of
|
||||
* data primarily for how Bedrock should handle the particle.
|
||||
*/
|
||||
SimpleMappedRegistry<ParticleType, ParticleMapping> particles();
|
||||
|
||||
/**
|
||||
* A registry holding all the potion mixes.
|
||||
*/
|
||||
VersionedRegistry<Set<PotionMixData>> potionMixes();
|
||||
/**
|
||||
* A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value.
|
||||
*/
|
||||
SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> recipes();
|
||||
|
||||
/**
|
||||
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
|
||||
*/
|
||||
DeferredRegistry<Map<String, ResourcePack>> resourcePacks();
|
||||
|
||||
/**
|
||||
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
|
||||
*/
|
||||
SimpleMappedRegistry<String, SoundMapping> sounds();
|
||||
/**
|
||||
* A mapped registry holding {@link LevelEvent}s to their corresponding {@link LevelEventTranslator}.
|
||||
*/
|
||||
SimpleMappedRegistry<LevelEvent, LevelEventTranslator> soundLevelEvents();
|
||||
/**
|
||||
* A mapped registry holding {@link SoundTranslator}s to their corresponding {@link SoundInteractionTranslator}.
|
||||
*/
|
||||
SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> soundTranslators();
|
||||
|
||||
/**
|
||||
* Called after the instance has been set for {@link Registries#instance()}.
|
||||
* This allows registries that depend on other registries to continue working.
|
||||
* Done specifically for the {@link org.geysermc.geyser.item.Items} class.
|
||||
*/
|
||||
void postInit();
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* 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.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.loader.BiomeIdentifierRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.BlockEntityRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.ParticleTypesRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.PotionMixRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.ProviderRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.RecipeRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||
import org.geysermc.geyser.registry.loader.SoundEventsRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.SoundRegistryLoader;
|
||||
import org.geysermc.geyser.registry.loader.SoundTranslatorRegistryLoader;
|
||||
import org.geysermc.geyser.registry.populator.ItemRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.provider.ProviderSupplier;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.ParticleMapping;
|
||||
import org.geysermc.geyser.registry.type.SoundMapping;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundTranslator;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
|
||||
/**
|
||||
* Holds all the common registries in Geyser.
|
||||
*/
|
||||
public final class CommonRegistriesDefault implements CommonRegistries {
|
||||
private static final CommonRegistriesDefault INSTANCE = new CommonRegistriesDefault();
|
||||
|
||||
private final SimpleMappedRegistry<Class<?>, ProviderSupplier> providers = SimpleMappedRegistry.create(new IdentityHashMap<>(), ProviderRegistryLoader::new);
|
||||
|
||||
private final SimpleRegistry<NbtMap> bedrockEntityIdentifiers = SimpleRegistry.create("bedrock/entity_identifiers.dat", RegistryLoaders.NBT);
|
||||
private final SimpleMappedRegistry<String, EntityDefinition<?>> javaEntityIdentifiers = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
|
||||
private final SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions = SimpleMappedRegistry.create(RegistryLoaders.empty(() -> new EnumMap<>(EntityType.class)));
|
||||
private final SimpleRegistry<Set<NbtMap>> bedrockEntityProperties = SimpleRegistry.create(RegistryLoaders.empty(HashSet::new));
|
||||
|
||||
private final SimpleRegistry<NbtMap> biomesNbt = SimpleRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT);
|
||||
private final SimpleRegistry<Object2IntMap<String>> biomeIdentifiers = SimpleRegistry.create("mappings/biomes.json", BiomeIdentifierRegistryLoader::new);
|
||||
|
||||
private final SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> blockEntities = SimpleMappedRegistry.create("org.geysermc.geyser.translator.level.block.entity.BlockEntity", BlockEntityRegistryLoader::new);
|
||||
|
||||
private final PacketTranslatorRegistry<BedrockPacket> bedrockPacketTranslators = PacketTranslatorRegistry.create();
|
||||
private final PacketTranslatorRegistry<Packet> javaPacketTranslators = PacketTranslatorRegistry.create();
|
||||
|
||||
private final ListRegistry<Item> javaItems = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||
private final SimpleMappedRegistry<String, Item> javaItemIdentifiers = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
private final VersionedRegistry<ItemMappings> items = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
||||
|
||||
private final SimpleMappedRegistry<ParticleType, ParticleMapping> particles = SimpleMappedRegistry.create("mappings/particles.json", ParticleTypesRegistryLoader::new);
|
||||
|
||||
private VersionedRegistry<Set<PotionMixData>> potionMixes;
|
||||
private final SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> recipes = SimpleMappedRegistry.create("mappings/recipes.nbt", RecipeRegistryLoader::new);
|
||||
|
||||
private final DeferredRegistry<Map<String, ResourcePack>> resourcePacks = DeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), SimpleMappedRegistry::create, RegistryLoaders.RESOURCE_PACKS);
|
||||
|
||||
private final SimpleMappedRegistry<String, SoundMapping> sounds = SimpleMappedRegistry.create("mappings/sounds.json", SoundRegistryLoader::new);
|
||||
private final SimpleMappedRegistry<LevelEvent, LevelEventTranslator> soundLevelEvents = SimpleMappedRegistry.create("mappings/effects.json", SoundEventsRegistryLoader::new);
|
||||
private final SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> soundTranslators = SimpleMappedRegistry.create("org.geysermc.geyser.translator.sound.SoundTranslator", SoundTranslatorRegistryLoader::new);
|
||||
|
||||
CommonRegistriesDefault() {}
|
||||
|
||||
public static CommonRegistriesDefault instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit() {
|
||||
PacketRegistryPopulator.populate(this);
|
||||
ItemRegistryPopulator.populate(this);
|
||||
|
||||
// Create registries that require other registries to load first
|
||||
potionMixes = VersionedRegistry.create(this, PotionMixRegistryLoader::new);
|
||||
|
||||
// Remove unneeded client generation data from NbtMapBuilder
|
||||
NbtMapBuilder biomesNbt = NbtMap.builder();
|
||||
for (Map.Entry<String, Object> entry : this.biomesNbt.get().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
NbtMapBuilder value = ((NbtMap) entry.getValue()).toBuilder();
|
||||
value.remove("minecraft:consolidated_features");
|
||||
value.remove("minecraft:multinoise_generation_rules");
|
||||
value.remove("minecraft:surface_material_adjustments");
|
||||
value.remove( "minecraft:surface_parameters");
|
||||
biomesNbt.put(key, value.build());
|
||||
}
|
||||
this.biomesNbt.set(biomesNbt.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<Class<?>, ProviderSupplier> providers() {
|
||||
return providers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<NbtMap> bedrockEntityIdentifiers() {
|
||||
return bedrockEntityIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, EntityDefinition<?>> javaEntityIdentifiers() {
|
||||
return javaEntityIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions() {
|
||||
return entityDefinitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<Set<NbtMap>> bedrockEntityProperties() {
|
||||
return bedrockEntityProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<NbtMap> biomesNbt() {
|
||||
return biomesNbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<Object2IntMap<String>> biomeIdentifiers() {
|
||||
return biomeIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> blockEntities() {
|
||||
return blockEntities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketTranslatorRegistry<BedrockPacket> bedrockPacketTranslators() {
|
||||
return bedrockPacketTranslators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketTranslatorRegistry<Packet> javaPacketTranslators() {
|
||||
return javaPacketTranslators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListRegistry<Item> javaItems() {
|
||||
return javaItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, Item> javaItemIdentifiers() {
|
||||
return javaItemIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedRegistry<ItemMappings> items() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<ParticleType, ParticleMapping> particles() {
|
||||
return particles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedRegistry<Set<PotionMixData>> potionMixes() {
|
||||
return potionMixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> recipes() {
|
||||
return recipes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeferredRegistry<Map<String, ResourcePack>> resourcePacks() {
|
||||
return resourcePacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, SoundMapping> sounds() {
|
||||
return sounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<LevelEvent, LevelEventTranslator> soundLevelEvents() {
|
||||
return soundLevelEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> soundTranslators() {
|
||||
return soundTranslators;
|
||||
}
|
||||
}
|
|
@ -25,22 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.loader.*;
|
||||
import org.geysermc.geyser.registry.populator.ItemRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.loader.RecipeRegistryLoader;
|
||||
import org.geysermc.geyser.registry.provider.ProviderSupplier;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.ParticleMapping;
|
||||
|
@ -56,134 +51,159 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Holds all the common registries in Geyser.
|
||||
* Block specific registries can be found in {@link BlockRegistries}
|
||||
*/
|
||||
public final class Registries {
|
||||
private static CommonRegistries backingRegistries;
|
||||
|
||||
public static CommonRegistries instance() {
|
||||
return CommonRegistriesDefault.instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry holding all the providers.
|
||||
* This has to be initialized first to allow extensions to access providers during other registry events.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<Class<?>, ProviderSupplier> PROVIDERS = SimpleMappedRegistry.create(new IdentityHashMap<>(), ProviderRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<Class<?>, ProviderSupplier> providers() {
|
||||
return backingRegistries.providers();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry holding a CompoundTag of the known entity identifiers.
|
||||
*/
|
||||
public static final SimpleRegistry<NbtMap> BEDROCK_ENTITY_IDENTIFIERS = SimpleRegistry.create("bedrock/entity_identifiers.dat", RegistryLoaders.NBT);
|
||||
public static SimpleRegistry<NbtMap> bedrockEntityIdentifiers() {
|
||||
return backingRegistries.bedrockEntityIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry containing all the Bedrock packet translators.
|
||||
*/
|
||||
public static final PacketTranslatorRegistry<BedrockPacket> BEDROCK_PACKET_TRANSLATORS = PacketTranslatorRegistry.create();
|
||||
public static PacketTranslatorRegistry<BedrockPacket> bedrockPacketTranslators() {
|
||||
return backingRegistries.bedrockPacketTranslators();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry holding a CompoundTag of all the known biomes.
|
||||
*/
|
||||
public static final SimpleRegistry<NbtMap> BIOMES_NBT = SimpleRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT);
|
||||
public static SimpleRegistry<NbtMap> biomesNbt() {
|
||||
return backingRegistries.biomesNbt();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry which stores Java biome identifiers and their Bedrock biome identifier.
|
||||
*/
|
||||
public static final SimpleRegistry<Object2IntMap<String>> BIOME_IDENTIFIERS = SimpleRegistry.create("mappings/biomes.json", BiomeIdentifierRegistryLoader::new);
|
||||
public static SimpleRegistry<Object2IntMap<String>> biomeIdentifiers() {
|
||||
return backingRegistries.biomeIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry which stores a block entity identifier to its {@link BlockEntityTranslator}.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.geyser.translator.level.block.entity.BlockEntity", BlockEntityRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> blockEntities() {
|
||||
return backingRegistries.blockEntities();
|
||||
}
|
||||
|
||||
/**
|
||||
* A map containing all entity types and their respective Geyser definitions
|
||||
*/
|
||||
public static final SimpleMappedRegistry<EntityType, EntityDefinition<?>> ENTITY_DEFINITIONS = SimpleMappedRegistry.create(RegistryLoaders.empty(() -> new EnumMap<>(EntityType.class)));
|
||||
public static SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions() {
|
||||
return backingRegistries.entityDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry holding a list of all the known entity properties to be sent to the client after start game.
|
||||
*/
|
||||
public static final SimpleRegistry<Set<NbtMap>> BEDROCK_ENTITY_PROPERTIES = SimpleRegistry.create(RegistryLoaders.empty(HashSet::new));
|
||||
public static SimpleRegistry<Set<NbtMap>> bedrockEntityProperties() {
|
||||
return backingRegistries.bedrockEntityProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* A map containing all Java entity identifiers and their respective Geyser definitions
|
||||
*/
|
||||
public static final SimpleMappedRegistry<String, EntityDefinition<?>> JAVA_ENTITY_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
public static SimpleMappedRegistry<String, EntityDefinition<?>> javaEntityIdentifiers() {
|
||||
return backingRegistries.javaEntityIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry containing all the Java packet translators.
|
||||
*/
|
||||
public static final PacketTranslatorRegistry<Packet> JAVA_PACKET_TRANSLATORS = PacketTranslatorRegistry.create();
|
||||
public static PacketTranslatorRegistry<Packet> javaPacketTranslators() {
|
||||
return backingRegistries.javaPacketTranslators();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry containing all Java items ordered by their network ID.
|
||||
*/
|
||||
public static final ListRegistry<Item> JAVA_ITEMS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||
public static ListRegistry<Item> javaItems() {
|
||||
return backingRegistries.javaItems();
|
||||
}
|
||||
|
||||
public static final SimpleMappedRegistry<String, Item> JAVA_ITEM_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
public static SimpleMappedRegistry<String, Item> javaItemIdentifiers() {
|
||||
return backingRegistries.javaItemIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* A versioned registry which holds {@link ItemMappings} for each version. These item mappings contain
|
||||
* primarily Bedrock version-specific data.
|
||||
*/
|
||||
public static final VersionedRegistry<ItemMappings> ITEMS = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
||||
public static VersionedRegistry<ItemMappings> items() {
|
||||
return backingRegistries.items();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry holding the {@link ParticleType} to a corresponding {@link ParticleMapping}, containing various pieces of
|
||||
* data primarily for how Bedrock should handle the particle.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<ParticleType, ParticleMapping> PARTICLES = SimpleMappedRegistry.create("mappings/particles.json", ParticleTypesRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<ParticleType, ParticleMapping> particles() {
|
||||
return backingRegistries.particles();
|
||||
}
|
||||
|
||||
/**
|
||||
* A registry holding all the potion mixes.
|
||||
*/
|
||||
public static final VersionedRegistry<Set<PotionMixData>> POTION_MIXES;
|
||||
public static VersionedRegistry<Set<PotionMixData>> potionMixes() {
|
||||
return backingRegistries.potionMixes();
|
||||
}
|
||||
|
||||
/**
|
||||
* A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> RECIPES = SimpleMappedRegistry.create("mappings/recipes.nbt", RecipeRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> recipes() {
|
||||
return backingRegistries.recipes();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
|
||||
*/
|
||||
public static final DeferredRegistry<Map<String, ResourcePack>> RESOURCE_PACKS = DeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), SimpleMappedRegistry::create, RegistryLoaders.RESOURCE_PACKS);
|
||||
public static DeferredRegistry<Map<String, ResourcePack>> resourcePacks() {
|
||||
return backingRegistries.resourcePacks();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<String, SoundMapping> SOUNDS = SimpleMappedRegistry.create("mappings/sounds.json", SoundRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<String, SoundMapping> sounds() {
|
||||
return backingRegistries.sounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry holding {@link LevelEvent}s to their corresponding {@link LevelEventTranslator}.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<LevelEvent, LevelEventTranslator> SOUND_LEVEL_EVENTS = SimpleMappedRegistry.create("mappings/effects.json", SoundEventsRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<LevelEvent, LevelEventTranslator> soundLevelEvents() {
|
||||
return backingRegistries.soundLevelEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapped registry holding {@link SoundTranslator}s to their corresponding {@link SoundInteractionTranslator}.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> SOUND_TRANSLATORS = SimpleMappedRegistry.create("org.geysermc.geyser.translator.sound.SoundTranslator", SoundTranslatorRegistryLoader::new);
|
||||
public static SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> soundTranslators() {
|
||||
return backingRegistries.soundTranslators();
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
static {
|
||||
PacketRegistryPopulator.populate();
|
||||
ItemRegistryPopulator.populate();
|
||||
|
||||
// Create registries that require other registries to load first
|
||||
POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new);
|
||||
|
||||
// Remove unneeded client generation data from NbtMapBuilder
|
||||
NbtMapBuilder biomesNbt = NbtMap.builder();
|
||||
for (Map.Entry<String, Object> entry : BIOMES_NBT.get().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
NbtMapBuilder value = ((NbtMap) entry.getValue()).toBuilder();
|
||||
value.remove("minecraft:consolidated_features");
|
||||
value.remove("minecraft:multinoise_generation_rules");
|
||||
value.remove("minecraft:surface_material_adjustments");
|
||||
value.remove( "minecraft:surface_parameters");
|
||||
biomesNbt.put(key, value.build());
|
||||
}
|
||||
BIOMES_NBT.set(biomesNbt.build());
|
||||
backingRegistries = instance();
|
||||
backingRegistries.postInit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.registry;
|
||||
|
||||
import org.geysermc.geyser.registry.loader.RegistryLoader;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import org.geysermc.geyser.registry.loader.RegistryLoader;
|
||||
|
||||
/**
|
||||
* A wrapper around a value which is loaded based on the output from the provided
|
||||
|
@ -58,7 +57,7 @@ import java.util.function.Consumer;
|
|||
* however it demonstrates a fairly basic use case of how this system works. Typically
|
||||
* though, the first parameter would be a location of some sort, such as a file path
|
||||
* where the loader will load the mappings from. The NBT registry is a good reference
|
||||
* point for something both simple and practical. See {@link Registries#BIOMES_NBT} and
|
||||
* point for something both simple and practical. See {@link Registries#biomesNbt} and
|
||||
* {@link org.geysermc.geyser.registry.loader.NbtRegistryLoader}.
|
||||
*
|
||||
* @param <M> the value being held by the registry
|
||||
|
@ -111,4 +110,4 @@ public abstract class Registry<M> implements IRegistry<M> {
|
|||
public void register(Consumer<M> consumer) {
|
||||
consumer.accept(this.mappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,18 +27,17 @@ package org.geysermc.geyser.registry.loader;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.CommonRegistries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
|
||||
/**
|
||||
* Generates a collection of {@link PotionMixData} that enables the
|
||||
|
@ -49,12 +48,12 @@ import java.util.Set;
|
|||
* (Ex: Bedrock cannot normally place glass bottles or fully upgraded
|
||||
* potions into the brewing stand, but Java can.)
|
||||
*/
|
||||
public class PotionMixRegistryLoader implements RegistryLoader<Object, Int2ObjectMap<Set<PotionMixData>>> {
|
||||
public class PotionMixRegistryLoader implements RegistryLoader<CommonRegistries, Int2ObjectMap<Set<PotionMixData>>> {
|
||||
|
||||
@Override
|
||||
public Int2ObjectMap<Set<PotionMixData>> load(Object input) {
|
||||
var allPotionMixes = new Int2ObjectOpenHashMap<Set<PotionMixData>>(Registries.ITEMS.get().size());
|
||||
for (var entry : Registries.ITEMS.get().int2ObjectEntrySet()) {
|
||||
public Int2ObjectMap<Set<PotionMixData>> load(CommonRegistries registries) {
|
||||
var allPotionMixes = new Int2ObjectOpenHashMap<Set<PotionMixData>>(registries.items().get().size());
|
||||
for (var entry : registries.items().get().int2ObjectEntrySet()) {
|
||||
ItemMappings mappings = entry.getValue();
|
||||
List<ItemMapping> ingredients = new ArrayList<>();
|
||||
ingredients.add(getNonNull(mappings, Items.NETHER_WART));
|
||||
|
@ -120,9 +119,10 @@ public class PotionMixRegistryLoader implements RegistryLoader<Object, Int2Objec
|
|||
|
||||
private static ItemMapping getNonNull(ItemMappings mappings, Item javaItem) {
|
||||
ItemMapping itemMapping = mappings.getMapping(javaItem);
|
||||
if (itemMapping == null)
|
||||
if (itemMapping == null) {
|
||||
throw new NullPointerException("No item entry exists for java identifier: " + javaItem.javaIdentifier());
|
||||
}
|
||||
|
||||
return itemMapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,20 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
|||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.cloudburstmc.nbt.NBTInputStream;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
|
@ -68,21 +82,6 @@ import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
|||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* Populates the block registries.
|
||||
*/
|
||||
|
@ -461,7 +460,7 @@ public final class BlockRegistryPopulator {
|
|||
@Override
|
||||
public ItemStack pickItem(BlockState state) {
|
||||
if (this.item == null) {
|
||||
this.item = Registries.JAVA_ITEM_IDENTIFIERS.get(pickItem);
|
||||
this.item = Registries.javaItemIdentifiers().get(pickItem);
|
||||
if (this.item == null) {
|
||||
GeyserImpl.getInstance().getLogger().warning("We could not find item " + pickItem
|
||||
+ " for getting the item for block " + javaBlockState.identifier());
|
||||
|
|
|
@ -33,7 +33,22 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
|
@ -64,12 +79,14 @@ import org.geysermc.geyser.item.components.Rarity;
|
|||
import org.geysermc.geyser.item.type.BlockItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.*;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.geysermc.geyser.registry.CommonRegistries;
|
||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||
import org.geysermc.geyser.registry.type.GeyserMappingItem;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.NonVanillaItemRegistration;
|
||||
import org.geysermc.geyser.registry.type.PaletteItem;
|
||||
|
||||
/**
|
||||
* Populates the item registries.
|
||||
|
@ -89,7 +106,7 @@ public class ItemRegistryPopulator {
|
|||
GeyserMappingItem remap(Item item, GeyserMappingItem mapping);
|
||||
}
|
||||
|
||||
public static void populate() {
|
||||
public static void populate(CommonRegistries registries) {
|
||||
List<PaletteVersion> paletteVersions = new ArrayList<>(3);
|
||||
paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion685_671::remapItem));
|
||||
paletteVersions.add(new PaletteVersion("1_21_0", Bedrock_v685.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion712_685::remapItem));
|
||||
|
@ -218,7 +235,7 @@ public class ItemRegistryPopulator {
|
|||
Set<String> registeredItemNames = new ObjectOpenHashSet<>(); // This is used to check for duplicate item names
|
||||
|
||||
for (Map.Entry<String, GeyserMappingItem> entry : items.entrySet()) {
|
||||
Item javaItem = Registries.JAVA_ITEM_IDENTIFIERS.get(entry.getKey());
|
||||
Item javaItem = registries.javaItemIdentifiers().get(entry.getKey());
|
||||
if (javaItem == null) {
|
||||
throw new RuntimeException("Extra item in mappings? " + entry.getKey());
|
||||
}
|
||||
|
@ -619,7 +636,7 @@ public class ItemRegistryPopulator {
|
|||
.customBlockItemDefinitions(customBlockItemDefinitions)
|
||||
.build();
|
||||
|
||||
Registries.ITEMS.register(palette.protocolVersion(), itemMappings);
|
||||
registries.items().register(palette.protocolVersion(), itemMappings);
|
||||
|
||||
firstMappingsPass = false;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.geyser.registry.populator;
|
|||
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.CommonRegistries;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.FileUtils;
|
||||
|
@ -36,7 +36,7 @@ import org.geysermc.mcprotocollib.network.packet.Packet;
|
|||
public class PacketRegistryPopulator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void populate() {
|
||||
public static void populate(CommonRegistries registries) {
|
||||
for (Class<?> clazz : FileUtils.getGeneratedClassesForAnnotation(Translator.class)) {
|
||||
Class<?> packet = clazz.getAnnotation(Translator.class).packet();
|
||||
|
||||
|
@ -47,12 +47,12 @@ public class PacketRegistryPopulator {
|
|||
Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet;
|
||||
PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.getConstructor().newInstance();
|
||||
|
||||
Registries.JAVA_PACKET_TRANSLATORS.register(targetPacket, translator);
|
||||
registries.javaPacketTranslators().register(targetPacket, translator);
|
||||
} else if (BedrockPacket.class.isAssignableFrom(packet)) {
|
||||
Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet;
|
||||
PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.getConstructor().newInstance();
|
||||
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.register(targetPacket, translator);
|
||||
registries.bedrockPacketTranslators().register(targetPacket, translator);
|
||||
} else {
|
||||
GeyserImpl.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet.");
|
||||
}
|
||||
|
|
|
@ -90,6 +90,8 @@ public final class Team {
|
|||
// Remove old team from this map, and from the set of players of the old team.
|
||||
// Java 1.19.3 Mojmap: Scoreboard#addPlayerToTeam calls #removePlayerFromTeam
|
||||
oldTeam.entities.remove(player);
|
||||
// also remove the managed entity if there is one
|
||||
removeManagedEntity(player);
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
@ -282,6 +284,15 @@ public final class Team {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally to remove a managed entity without causing an update.
|
||||
* This is fine because its only used when the entity is added to another team,
|
||||
* which will fire the correct nametag updates etc.
|
||||
*/
|
||||
private void removeManagedEntity(String name) {
|
||||
managedEntities.removeIf(entity -> name.equals(entity.teamIdentifier()));
|
||||
}
|
||||
|
||||
private void refreshAllEntities() {
|
||||
for (Entity entity : session().getEntityCache().getEntities().values()) {
|
||||
entity.updateNametag(scoreboard.getTeamFor(entity.teamIdentifier()));
|
||||
|
|
|
@ -35,6 +35,26 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -191,7 +211,6 @@ import org.geysermc.mcprotocollib.network.event.session.SessionAdapter;
|
|||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpClientSession;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
import org.geysermc.mcprotocollib.protocol.ClientListener;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||
import org.geysermc.mcprotocollib.protocol.data.ProtocolState;
|
||||
|
@ -207,8 +226,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart;
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundFinishConfigurationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.handshake.serverbound.ClientIntentionPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket;
|
||||
|
@ -218,27 +235,6 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.Serv
|
|||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Getter
|
||||
public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
|
||||
|
@ -754,11 +750,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
|
||||
|
||||
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
||||
biomeDefinitionListPacket.setDefinitions(Registries.BIOMES_NBT.get());
|
||||
biomeDefinitionListPacket.setDefinitions(Registries.biomesNbt().get());
|
||||
upstream.sendPacket(biomeDefinitionListPacket);
|
||||
|
||||
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
|
||||
entityPacket.setIdentifiers(Registries.BEDROCK_ENTITY_IDENTIFIERS.get());
|
||||
entityPacket.setIdentifiers(Registries.bedrockEntityIdentifiers().get());
|
||||
upstream.sendPacket(entityPacket);
|
||||
|
||||
CameraPresetsPacket cameraPresetsPacket = new CameraPresetsPacket();
|
||||
|
@ -772,7 +768,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
// Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand.
|
||||
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||
craftingDataPacket.setCleanRecipes(true);
|
||||
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.forVersion(this.upstream.getProtocolVersion()));
|
||||
craftingDataPacket.getPotionMixData().addAll(Registries.potionMixes().forVersion(this.upstream.getProtocolVersion()));
|
||||
upstream.sendPacket(craftingDataPacket);
|
||||
|
||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||
|
@ -1152,7 +1148,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, GeyserSession.this);
|
||||
Registries.javaPacketTranslators().translate(packet.getClass(), packet, GeyserSession.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1683,7 +1679,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
}
|
||||
|
||||
private void syncEntityProperties() {
|
||||
for (NbtMap nbtMap : Registries.BEDROCK_ENTITY_PROPERTIES.get()) {
|
||||
for (NbtMap nbtMap : Registries.bedrockEntityProperties().get()) {
|
||||
SyncEntityPropertyPacket syncEntityPropertyPacket = new SyncEntityPropertyPacket();
|
||||
syncEntityPropertyPacket.setData(nbtMap);
|
||||
upstream.sendPacket(syncEntityPropertyPacket);
|
||||
|
|
|
@ -69,12 +69,13 @@ public class EntityCache {
|
|||
|
||||
public void spawnEntity(Entity entity) {
|
||||
if (cacheEntity(entity)) {
|
||||
entity.spawnEntity();
|
||||
|
||||
// start tracking newly spawned entities.
|
||||
// This is however not called for players, that's done in addPlayerEntity
|
||||
// start tracking newly spawned entities. Doing this before the actual entity spawn can result in combining
|
||||
// the otherwise sent metadata packet (in the case of team visibility, which sets the NAME metadata to
|
||||
// empty) with the entity spawn packet (which also includes metadata). Resulting in 1 less packet sent.
|
||||
session.getWorldCache().getScoreboard().entityRegistered(entity);
|
||||
|
||||
entity.spawnEntity();
|
||||
|
||||
if (entity instanceof Tickable) {
|
||||
// Start ticking it
|
||||
tickableEntities.add((Tickable) entity);
|
||||
|
@ -144,8 +145,6 @@ public class EntityCache {
|
|||
// notify scoreboard for new entity
|
||||
var scoreboard = session.getWorldCache().getScoreboard();
|
||||
scoreboard.playerRegistered(entity);
|
||||
// spawnPlayer's entityRegistered is not called for players
|
||||
scoreboard.entityRegistered(entity);
|
||||
}
|
||||
|
||||
public PlayerEntity getPlayerEntity(UUID uuid) {
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator
|
|||
public ShulkerInventoryTranslator() {
|
||||
// Ensure that the shulker box default state won't be trying to open in a state facing the player
|
||||
super(27, new BlockInventoryHolder(Blocks.SHULKER_BOX.defaultBlockState().withValue(Properties.FACING, Direction.NORTH), ContainerType.CONTAINER) {
|
||||
private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get(BlockEntityType.SHULKER_BOX);
|
||||
private final BlockEntityTranslator shulkerBoxTranslator = Registries.blockEntities().get(BlockEntityType.SHULKER_BOX);
|
||||
|
||||
@Override
|
||||
protected boolean isValidBlock(BlockState blockState) {
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.translator.item;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
@ -64,13 +70,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ItemTranslator {
|
||||
|
||||
/**
|
||||
|
@ -128,7 +127,7 @@ public final class ItemTranslator {
|
|||
session.getGeyser().getLogger().debug("ItemMapping returned air: " + javaId);
|
||||
return ItemData.builder();
|
||||
}
|
||||
return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, components);
|
||||
return translateToBedrock(session, Registries.javaItems().get().get(javaId), bedrockItem, count, components);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -143,7 +142,7 @@ public final class ItemTranslator {
|
|||
return ItemData.AIR;
|
||||
}
|
||||
// Java item needs to be loaded separately. The mapping for tipped arrow would
|
||||
return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getDataComponents())
|
||||
return translateToBedrock(session, Registries.javaItems().get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getDataComponents())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.translator.level;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||
|
@ -40,13 +34,19 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion;
|
|||
import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette;
|
||||
|
||||
// Array index formula by https://wiki.vg/Chunk_Format
|
||||
public class BiomeTranslator {
|
||||
|
||||
public static int loadServerBiome(RegistryEntry entry) {
|
||||
String javaIdentifier = entry.getId().asString();
|
||||
return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0);
|
||||
return Registries.biomeIdentifiers().get().getOrDefault(javaIdentifier, 0);
|
||||
}
|
||||
|
||||
public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) {
|
||||
|
|
|
@ -118,7 +118,7 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
|||
// As of 1.19.3, spawners can be empty
|
||||
builder.put("EntityIdentifier", entityId);
|
||||
|
||||
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId);
|
||||
EntityDefinition<?> definition = Registries.javaEntityIdentifiers().get(entityId);
|
||||
if (definition != null) {
|
||||
builder.putFloat("DisplayEntityWidth", definition.width());
|
||||
builder.putFloat("DisplayEntityHeight", definition.height());
|
||||
|
|
|
@ -47,7 +47,7 @@ public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
|||
return;
|
||||
}
|
||||
NbtMapBuilder spawnData = NbtMap.builder();
|
||||
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityData.getString("id"));
|
||||
EntityDefinition<?> definition = Registries.javaEntityIdentifiers().get(entityData.getString("id"));
|
||||
if (definition != null) {
|
||||
spawnData.putString("TypeId", definition.identifier());
|
||||
}
|
||||
|
|
|
@ -32,12 +32,29 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.*;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumConstraint;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandOverloadData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandParam;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AvailableCommandsPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent;
|
||||
|
@ -55,9 +72,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.command.properties.Resource
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@SuppressWarnings("removal") // We know. This is our doing.
|
||||
@Translator(packet = ClientboundCommandsPacket.class)
|
||||
public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommandsPacket> {
|
||||
|
@ -360,14 +374,14 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||
if (entityTypes != null) {
|
||||
return entityTypes;
|
||||
}
|
||||
return (entityTypes = Registries.JAVA_ENTITY_IDENTIFIERS.get().keySet().toArray(new String[0]));
|
||||
return (entityTypes = Registries.javaEntityIdentifiers().get().keySet().toArray(new String[0]));
|
||||
}
|
||||
|
||||
public String[] getItemNames() {
|
||||
if (itemNames != null) {
|
||||
return itemNames;
|
||||
}
|
||||
return (itemNames = Registries.JAVA_ITEM_IDENTIFIERS.get().keySet().toArray(new String[0]));
|
||||
return (itemNames = Registries.javaItemIdentifiers().get().keySet().toArray(new String[0]));
|
||||
}
|
||||
|
||||
private CommandEnumData getTeams() {
|
||||
|
|
|
@ -25,11 +25,25 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java;
|
||||
|
||||
import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntIterator;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
|
@ -68,21 +82,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.SmithingTransfo
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.StoneCuttingRecipeData;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID;
|
||||
|
||||
/**
|
||||
* Used to send all valid recipes from Java to Bedrock.
|
||||
* <p>
|
||||
|
@ -154,7 +153,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
if (stoneCuttingData.getIngredient().getOptions().length == 0) {
|
||||
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Received broken stone cutter recipe: " + stoneCuttingData + " " +
|
||||
recipe.getIdentifier() + " " + Registries.JAVA_ITEMS.get().get(stoneCuttingData.getResult().getId()).javaIdentifier());
|
||||
recipe.getIdentifier() + " " + Registries.javaItems().get().get(stoneCuttingData.getResult().getId()).javaIdentifier());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -215,7 +214,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("00000000-0000-0000-0000-000000000002"), context.getAndIncrementNetId()));
|
||||
}
|
||||
default -> {
|
||||
List<GeyserRecipe> recipes = Registries.RECIPES.get(recipe.getType());
|
||||
List<GeyserRecipe> recipes = Registries.recipes().get(recipe.getType());
|
||||
if (recipes != null) {
|
||||
List<String> bedrockRecipeIds = new ArrayList<>();
|
||||
if (recipe.getType() == RecipeType.CRAFTING_SPECIAL_TIPPEDARROW) {
|
||||
|
@ -247,14 +246,14 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
}
|
||||
}
|
||||
craftingDataPacket.getCraftingData().addAll(CARTOGRAPHY_RECIPES);
|
||||
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.forVersion(session.getUpstream().getProtocolVersion()));
|
||||
craftingDataPacket.getPotionMixData().addAll(Registries.potionMixes().forVersion(session.getUpstream().getProtocolVersion()));
|
||||
|
||||
Int2ObjectMap<GeyserStonecutterData> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
|
||||
for (Int2ObjectMap.Entry<List<StoneCuttingRecipeData>> data : unsortedStonecutterData.int2ObjectEntrySet()) {
|
||||
// Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore
|
||||
// We can get the correct order for button pressing
|
||||
data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData ->
|
||||
Registries.JAVA_ITEMS.get().get(stoneCuttingRecipeData.getResult().getId())
|
||||
Registries.javaItems().get().get(stoneCuttingRecipeData.getResult().getId())
|
||||
// See RecipeManager#getRecipesFor as of 1.21
|
||||
.translationKey())));
|
||||
|
||||
|
@ -452,7 +451,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
return null;
|
||||
}
|
||||
|
||||
Item javaItem = Registries.JAVA_ITEMS.get(result.getId());
|
||||
Item javaItem = Registries.javaItems().get(result.getId());
|
||||
if (!(javaItem instanceof BedrockRequiresTagItem)) {
|
||||
// Strip NBT - tools won't appear in the recipe book otherwise
|
||||
output = output.toBuilder().tag(null).build();
|
||||
|
@ -481,7 +480,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
return null;
|
||||
}
|
||||
|
||||
Item javaItem = Registries.JAVA_ITEMS.get(result.getId());
|
||||
Item javaItem = Registries.javaItems().get(result.getId());
|
||||
if (!(javaItem instanceof BedrockRequiresTagItem)) {
|
||||
// Strip NBT - tools won't appear in the recipe book otherwise
|
||||
output = output.toBuilder().tag(null).build();
|
||||
|
@ -510,7 +509,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
return null;
|
||||
}
|
||||
|
||||
Item javaItem = Registries.JAVA_ITEMS.get(result.getId());
|
||||
Item javaItem = Registries.javaItems().get(result.getId());
|
||||
if (!(javaItem instanceof BedrockRequiresTagItem)) {
|
||||
// Strip NBT - tools won't appear in the recipe book otherwise
|
||||
output = output.toBuilder().tag(null).build();
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.entity.player;
|
||||
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
|
||||
|
@ -35,15 +38,11 @@ import org.geysermc.geyser.session.GeyserSession;
|
|||
import org.geysermc.geyser.skin.SkinManager;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Translator(packet = ClientboundPlayerInfoUpdatePacket.class)
|
||||
public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<ClientboundPlayerInfoUpdatePacket> {
|
||||
@Override
|
||||
|
@ -95,8 +94,6 @@ public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<Clientbound
|
|||
if (self) {
|
||||
SkinManager.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape ->
|
||||
GeyserImpl.getInstance().getLogger().debug("Loaded Local Bedrock Java Skin Data for " + session.getClientData().getUsername()));
|
||||
} else {
|
||||
playerEntity.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.entity.spawn;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.*;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.FallingBlockEntity;
|
||||
import org.geysermc.geyser.entity.type.FishingHookEntity;
|
||||
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||
import org.geysermc.geyser.entity.type.PaintingEntity;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -43,13 +40,21 @@ import org.geysermc.geyser.skin.SkinManager;
|
|||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.EnvironmentUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
||||
|
||||
@Translator(packet = ClientboundAddEntityPacket.class)
|
||||
public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEntityPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) {
|
||||
EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
|
||||
EntityDefinition<?> definition = Registries.entityDefinitions().get(packet.getType());
|
||||
if (definition == null) {
|
||||
session.getGeyser().getLogger().debug("Could not find an entity definition with type " + packet.getType());
|
||||
return;
|
||||
|
@ -83,10 +88,13 @@ public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEnti
|
|||
entity.setHeadYaw(headYaw);
|
||||
entity.setMotion(motion);
|
||||
}
|
||||
session.getEntityCache().cacheEntity(entity);
|
||||
|
||||
entity.sendPlayer();
|
||||
SkinManager.requestAndHandleSkinAndCape(entity, session, null);
|
||||
// only load skin if we're not in a test environment.
|
||||
// Otherwise, it tries to load various resources
|
||||
if (!EnvironmentUtils.IS_UNIT_TESTING) {
|
||||
SkinManager.requestAndHandleSkinAndCape(entity, session, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.inventory;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
|
@ -46,9 +45,9 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
|||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket;
|
||||
|
||||
@Translator(packet = ClientboundMerchantOffersPacket.class)
|
||||
public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMerchantOffersPacket> {
|
||||
|
@ -173,7 +172,7 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
|
|||
|
||||
// Bedrock expects all price adjustments to be applied to the item's count
|
||||
int count = stack.getAmount() + ((int) Math.max(Math.floor(stack.getAmount() * demand * priceMultiplier), 0)) + specialPrice;
|
||||
count = MathUtils.constrain(count, 1, Registries.JAVA_ITEMS.get().get(stack.getId()).maxStackSize());
|
||||
count = MathUtils.constrain(count, 1, Registries.javaItems().get().get(stack.getId()).maxStackSize());
|
||||
|
||||
return getItemTag(session, stack, mapping, count);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.level;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCooldownPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerStartItemCooldownPacket;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
|
@ -33,13 +32,14 @@ import org.geysermc.geyser.registry.Registries;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCooldownPacket;
|
||||
|
||||
@Translator(packet = ClientboundCooldownPacket.class)
|
||||
public class JavaCooldownTranslator extends PacketTranslator<ClientboundCooldownPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundCooldownPacket packet) {
|
||||
Item item = Registries.JAVA_ITEMS.get().get(packet.getItemId());
|
||||
Item item = Registries.javaItems().get().get(packet.getItemId());
|
||||
// Not every item, as of 1.19, appears to be server-driven. Just these two.
|
||||
// Use a map here if it gets too big.
|
||||
String cooldownCategory;
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.level;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -62,12 +67,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.event.TrialSpawnerDet
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.UnknownLevelEventData;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@Translator(packet = ClientboundLevelEventPacket.class)
|
||||
public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelEventPacket> {
|
||||
|
||||
|
@ -87,7 +86,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
|
|||
Vector3f pos = Vector3f.from(origin.getX() + 0.5f, origin.getY() + 0.5f, origin.getZ() + 0.5f);
|
||||
|
||||
// Prioritize level events because it makes parrots dance.
|
||||
SoundMapping mapping = Registries.SOUNDS.get(jukeboxSong.soundEvent().replace("minecraft:", ""));
|
||||
SoundMapping mapping = Registries.sounds().get(jukeboxSong.soundEvent().replace("minecraft:", ""));
|
||||
SoundEvent soundEvent = null;
|
||||
if (mapping != null) {
|
||||
String bedrock = mapping.getBedrock();
|
||||
|
@ -133,7 +132,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
|
|||
}
|
||||
|
||||
// Check for a sound event translator
|
||||
LevelEventTranslator transformer = Registries.SOUND_LEVEL_EVENTS.get(packet.getEvent());
|
||||
LevelEventTranslator transformer = Registries.soundLevelEvents().get(packet.getEvent());
|
||||
if (transformer != null) {
|
||||
transformer.translate(session, packet);
|
||||
return;
|
||||
|
|
|
@ -25,18 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.level;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.BlockParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.DustParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ItemParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.VibrationParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.BlockPositionSource;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.EntityPositionSource;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
|
@ -52,11 +47,15 @@ import org.geysermc.geyser.translator.item.ItemTranslator;
|
|||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Function;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.BlockParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.DustParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ItemParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.VibrationParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.BlockPositionSource;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.EntityPositionSource;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket;
|
||||
|
||||
@Translator(packet = ClientboundLevelParticlesPacket.class)
|
||||
public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLevelParticlesPacket> {
|
||||
|
@ -178,7 +177,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
|
|||
};
|
||||
}
|
||||
default -> {
|
||||
ParticleMapping particleMapping = Registries.PARTICLES.get(particle.getType());
|
||||
ParticleMapping particleMapping = Registries.particles().get(particle.getType());
|
||||
if (particleMapping == null) { //TODO ensure no particle can be null
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.scoreboard;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket;
|
||||
import org.geysermc.geyser.scoreboard.Scoreboard;
|
||||
import org.geysermc.geyser.scoreboard.ScoreboardUpdater;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.WorldCache;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket;
|
||||
|
||||
@Translator(packet = ClientboundSetDisplayObjectivePacket.class)
|
||||
public class JavaSetDisplayObjectiveTranslator extends PacketTranslator<ClientboundSetDisplayObjectivePacket> {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java.scoreboard;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.GeyserLogger;
|
||||
import org.geysermc.geyser.scoreboard.Scoreboard;
|
||||
|
@ -43,10 +42,6 @@ public class JavaSetPlayerTeamTranslator extends PacketTranslator<ClientboundSet
|
|||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundSetPlayerTeamPacket packet) {
|
||||
if (logger.isDebug()) {
|
||||
logger.debug("Team packet " + packet.getTeamName() + " " + packet.getAction() + " " + Arrays.toString(packet.getPlayers()));
|
||||
}
|
||||
|
||||
if ((packet.getAction() == TeamAction.ADD_PLAYER || packet.getAction() == TeamAction.REMOVE_PLAYER) && packet.getPlayers().length == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.translator.sound;
|
||||
|
||||
import java.util.Map;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
|
@ -33,8 +34,6 @@ import org.geysermc.geyser.session.GeyserSession;
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sound interaction handler for when a block is right-clicked.
|
||||
*/
|
||||
|
@ -51,7 +50,7 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla
|
|||
// If we need to get the hand identifier, only get it once and save it to a variable
|
||||
String handIdentifier = null;
|
||||
|
||||
for (Map.Entry<SoundTranslator, SoundInteractionTranslator<?>> interactionEntry : Registries.SOUND_TRANSLATORS.get().entrySet()) {
|
||||
for (Map.Entry<SoundTranslator, SoundInteractionTranslator<?>> interactionEntry : Registries.soundTranslators().get().entrySet()) {
|
||||
if (!(interactionEntry.getValue() instanceof BlockSoundInteractionTranslator)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -34,9 +36,6 @@ import org.geysermc.geyser.session.GeyserSession;
|
|||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class BlockEntityUtils {
|
||||
/**
|
||||
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
||||
|
@ -68,7 +67,7 @@ public class BlockEntityUtils {
|
|||
}
|
||||
|
||||
public static BlockEntityTranslator getBlockEntityTranslator(BlockEntityType type) {
|
||||
return Registries.BLOCK_ENTITIES.get(type);
|
||||
return Registries.blockEntities().get(type);
|
||||
}
|
||||
|
||||
public static void updateBlockEntity(GeyserSession session, @NonNull NbtMap blockEntity, Vector3i position) {
|
||||
|
|
|
@ -297,7 +297,7 @@ public final class EntityUtils {
|
|||
private static String translatedEntityName(@NonNull String namespace, @NonNull String name, @NonNull GeyserSession session) {
|
||||
// MinecraftLocale would otherwise invoke getBootstrap (which doesn't exist) and create some folders,
|
||||
// so use the default fallback value as used in Minecraft Java
|
||||
if (EnvironmentUtils.isUnitTesting) {
|
||||
if (EnvironmentUtils.IS_UNIT_TESTING) {
|
||||
return "entity." + namespace + "." + name;
|
||||
}
|
||||
return MinecraftLocale.getLocaleString("entity." + namespace + "." + name, session.locale());
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
package org.geysermc.geyser.util;
|
||||
|
||||
public final class EnvironmentUtils {
|
||||
public static final boolean isUnitTesting = isUnitTesting();
|
||||
public static final boolean IS_UNIT_TESTING = isUnitTesting();
|
||||
|
||||
private EnvironmentUtils() {}
|
||||
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.IntFunction;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -38,7 +44,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.Container;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.LecternContainer;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.click.Click;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
|
||||
|
@ -64,13 +74,6 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.S
|
|||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
public class InventoryUtils {
|
||||
/**
|
||||
* Stores the last used recipe network ID. Since 1.16.200 (and for server-authoritative inventories),
|
||||
|
@ -238,7 +241,7 @@ public class InventoryUtils {
|
|||
}
|
||||
|
||||
private static ItemDefinition getUnusableSpaceBlockDefinition(int protocolVersion) {
|
||||
ItemMappings mappings = Registries.ITEMS.forVersion(protocolVersion);
|
||||
ItemMappings mappings = Registries.items().forVersion(protocolVersion);
|
||||
String unusableSpaceBlock = GeyserImpl.getInstance().getConfig().getUnusableSpaceBlock();
|
||||
ItemDefinition itemDefinition = mappings.getDefinition(unusableSpaceBlock);
|
||||
|
||||
|
@ -252,13 +255,13 @@ public class InventoryUtils {
|
|||
|
||||
public static IntFunction<ItemData> getUpgradeTemplate() {
|
||||
return protocolVersion -> ItemData.builder()
|
||||
.definition(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().upgradeTemplate().getBedrockDefinition())
|
||||
.definition(Registries.items().forVersion(protocolVersion).getStoredItems().upgradeTemplate().getBedrockDefinition())
|
||||
.count(1).build();
|
||||
}
|
||||
|
||||
public static IntFunction<ItemData> getTotemOfUndying() {
|
||||
return protocolVersion -> ItemData.builder()
|
||||
.definition(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().totem().getBedrockDefinition())
|
||||
.definition(Registries.items().forVersion(protocolVersion).getStoredItems().totem().getBedrockDefinition())
|
||||
.count(1).build();
|
||||
}
|
||||
|
||||
|
@ -317,7 +320,7 @@ public class InventoryUtils {
|
|||
|
||||
// Please remove!!!
|
||||
public static void findOrCreateItem(GeyserSession session, String itemName) {
|
||||
findOrCreateItem(session, Registries.JAVA_ITEM_IDENTIFIERS.getOrDefault(itemName, Items.AIR));
|
||||
findOrCreateItem(session, Registries.javaItemIdentifiers().getOrDefault(itemName, Items.AIR));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
|
@ -40,8 +41,6 @@ import org.geysermc.geyser.registry.type.SoundMapping;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public final class SoundUtils {
|
||||
|
||||
/**
|
||||
|
@ -67,7 +66,7 @@ public final class SoundUtils {
|
|||
*/
|
||||
public static String translatePlaySound(String javaIdentifier) {
|
||||
String soundIdentifier = removeMinecraftNamespace(javaIdentifier);
|
||||
SoundMapping soundMapping = Registries.SOUNDS.get(soundIdentifier);
|
||||
SoundMapping soundMapping = Registries.sounds().get(soundIdentifier);
|
||||
if (soundMapping == null || soundMapping.getPlaysound() == null) {
|
||||
// no mapping
|
||||
GeyserImpl.getInstance().getLogger().debug("[PlaySound] Defaulting to sound server gave us for " + javaIdentifier);
|
||||
|
@ -104,7 +103,7 @@ public final class SoundUtils {
|
|||
public static void playSound(GeyserSession session, Sound javaSound, Vector3f position, float volume, float pitch) {
|
||||
String soundIdentifier = removeMinecraftNamespace(javaSound.getName());
|
||||
|
||||
SoundMapping soundMapping = Registries.SOUNDS.get(soundIdentifier);
|
||||
SoundMapping soundMapping = Registries.sounds().get(soundIdentifier);
|
||||
if (soundMapping == null) {
|
||||
session.getGeyser().getLogger().debug("[Builtin] Sound mapping for " + soundIdentifier + " not found; assuming custom.");
|
||||
playSound(session, soundIdentifier, position, volume, pitch);
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
package org.geysermc.geyser.util;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.geysermc.cumulus.form.SimpleForm;
|
||||
import org.geysermc.cumulus.util.FormImage;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
|
@ -35,14 +41,16 @@ import org.geysermc.geyser.registry.Registries;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.BreakBlockStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.BreakItemStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.CraftItemStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.DropItemStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.KillEntityStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.KilledByEntityStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.PickupItemStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.UseItemStatistic;
|
||||
|
||||
public class StatisticsUtils {
|
||||
private static final Pattern CONTENT_PATTERN = Pattern.compile("^\\S+:", Pattern.MULTILINE);
|
||||
|
@ -76,7 +84,7 @@ public class StatisticsUtils {
|
|||
|
||||
List<String> content = new ArrayList<>();
|
||||
|
||||
List<Item> itemRegistry = Registries.JAVA_ITEMS.get();
|
||||
List<Item> itemRegistry = Registries.javaItems().get();
|
||||
switch (response.clickedButtonId()) {
|
||||
case 0:
|
||||
builder.title("stat.generalButton");
|
||||
|
|
|
@ -64,12 +64,12 @@ public class NameVisibilityScoreboardTest {
|
|||
new String[]{"player1"}
|
||||
)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,12 @@ public class NameVisibilityScoreboardTest {
|
|||
)
|
||||
);
|
||||
// only hidden if session player (Tim203) is in a team as well
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§4prefix§r§4player1§r§4suffix");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// create another team and add Tim203 to it
|
||||
|
@ -121,12 +121,12 @@ public class NameVisibilityScoreboardTest {
|
|||
)
|
||||
);
|
||||
// Tim203 is now in another team, so it should be hidden
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// add Tim203 to same team as player1, score should be visible again
|
||||
|
@ -134,12 +134,12 @@ public class NameVisibilityScoreboardTest {
|
|||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket("team1", TeamAction.ADD_PLAYER, new String[]{"Tim203"})
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§4prefix§r§4player1§r§4suffix");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,12 +166,12 @@ public class NameVisibilityScoreboardTest {
|
|||
)
|
||||
);
|
||||
// Tim203 is not in a team (let alone the same team), so should be visible
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§4prefix§r§4player1§r§4suffix");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// Tim203 is now in the same team as player1, so should be hidden
|
||||
|
@ -179,12 +179,12 @@ public class NameVisibilityScoreboardTest {
|
|||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket("team1", TeamAction.ADD_PLAYER, new String[]{"Tim203"})
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// create another team and add Tim203 to there, score should be visible again
|
||||
|
@ -203,12 +203,12 @@ public class NameVisibilityScoreboardTest {
|
|||
new String[]{"Tim203"}
|
||||
)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§4prefix§r§4player1§r§4suffix");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -234,12 +234,12 @@ public class NameVisibilityScoreboardTest {
|
|||
new String[]{"player1"}
|
||||
)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§4prefix§r§4player1§r§4suffix");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// adding self to another team shouldn't make a difference
|
||||
context.translate(
|
||||
|
|
|
@ -25,23 +25,57 @@
|
|||
|
||||
package org.geysermc.geyser.scoreboard.network;
|
||||
|
||||
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacket;
|
||||
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacketMatch;
|
||||
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacketType;
|
||||
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNoNextPacket;
|
||||
import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScoreboard.mockContextScoreboard;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.entity.type.living.monster.EnderDragonPartEntity;
|
||||
import org.geysermc.geyser.session.cache.EntityCache;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.JavaRemoveEntitiesTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.JavaSetEntityDataTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.player.JavaPlayerInfoUpdateTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.spawn.JavaAddEntityTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.spawn.JavaAddExperienceOrbTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetPlayerTeamTranslator;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
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.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.CollisionRule;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests that don't fit in a larger system (e.g. sidebar objective) that were reported on GitHub
|
||||
* Tests for issues reported on GitHub.
|
||||
*/
|
||||
public class ScoreboardIssueTests {
|
||||
/**
|
||||
|
@ -90,4 +124,136 @@ public class ScoreboardIssueTests {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for <a href="https://github.com/GeyserMC/Geyser/issues/5089">#5089</a>.
|
||||
* It follows the reproduction steps with all the packets it sends along its way.
|
||||
* Tested with the 2.0.0-SNAPSHOT version.
|
||||
* Note that this exact issue is actually 2 issues:
|
||||
* <ul>
|
||||
* <li>
|
||||
* An issue caused by remainders of code that was part of the initial PR that added support for players.
|
||||
* The code is now more streamlined.
|
||||
* </li>
|
||||
* <li>Armor stands are excluded from team visibility checks (the only living entity)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Test
|
||||
void nameNotUpdating() {
|
||||
mockContextScoreboard(context -> {
|
||||
var playerInfoUpdateTranslator = new JavaPlayerInfoUpdateTranslator();
|
||||
var setPlayerTeamTranslator = new JavaSetPlayerTeamTranslator();
|
||||
var addEntityTranslator = new JavaAddEntityTranslator();
|
||||
var setEntityDataTranslator = new JavaSetEntityDataTranslator();
|
||||
|
||||
|
||||
// first command, create NPC
|
||||
|
||||
|
||||
var npcUuid = UUID.fromString("b0eb01d7-52c9-4730-9fd3-2c03fcb00d6e");
|
||||
context.translate(
|
||||
playerInfoUpdateTranslator,
|
||||
new ClientboundPlayerInfoUpdatePacket(
|
||||
EnumSet.of(PlayerListEntryAction.ADD_PLAYER, PlayerListEntryAction.UPDATE_LISTED),
|
||||
new PlayerListEntry[] {
|
||||
new PlayerListEntry(npcUuid, new GameProfile(npcUuid, "1297"), false, 0, GameMode.SURVIVAL, null, null, 0, null, null)
|
||||
}));
|
||||
|
||||
//todo we don't have to remove an entry that was never in the playerlist in the first place
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new PlayerListPacket();
|
||||
packet.getEntries().add(new PlayerListPacket.Entry(npcUuid));
|
||||
packet.setAction(PlayerListPacket.Action.REMOVE);
|
||||
return packet;
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket(
|
||||
"npc_team_1297",
|
||||
Component.empty(),
|
||||
Component.empty(),
|
||||
Component.empty(),
|
||||
false,
|
||||
false,
|
||||
NameTagVisibility.NEVER,
|
||||
CollisionRule.NEVER,
|
||||
TeamColor.WHITE,
|
||||
new String[0]
|
||||
)
|
||||
);
|
||||
context.translate(
|
||||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket("npc_team_1297", TeamAction.ADD_PLAYER, new String[]{ "1297" }));
|
||||
|
||||
context.translate(addEntityTranslator, new ClientboundAddEntityPacket(1297, npcUuid, EntityType.PLAYER, 1, 2, 3, 4, 5, 6));
|
||||
// then it updates the displayed skin parts, which isn't relevant for us
|
||||
|
||||
assertNextPacketMatch(context, AddPlayerPacket.class, packet -> {
|
||||
assertEquals(3, packet.getRuntimeEntityId());
|
||||
assertEquals(npcUuid, packet.getUuid());
|
||||
assertEquals("1297", packet.getUsername());
|
||||
assertEquals((byte) 1, packet.getMetadata().get(EntityDataTypes.NAMETAG_ALWAYS_SHOW));
|
||||
assertEquals("", packet.getMetadata().get(EntityDataTypes.NAME));
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// second command, create hologram
|
||||
|
||||
|
||||
var hologramUuid = UUID.fromString("b1586291-5f68-44dc-847d-6c123c5b8cbf");
|
||||
context.translate(
|
||||
addEntityTranslator,
|
||||
new ClientboundAddEntityPacket(1298, hologramUuid, EntityType.ARMOR_STAND, 6, 5, 4, 3, 2, 1));
|
||||
|
||||
assertNextPacketMatch(context, AddEntityPacket.class, packet -> {
|
||||
assertEquals(4, packet.getRuntimeEntityId());
|
||||
assertEquals("minecraft:armor_stand", packet.getIdentifier());
|
||||
});
|
||||
|
||||
// invisible, custom name, custom name visible
|
||||
context.translate(setEntityDataTranslator, new ClientboundSetEntityDataPacket(1298, new EntityMetadata[]{
|
||||
new ByteEntityMetadata(0, MetadataType.BYTE, (byte) 0x20),
|
||||
new ObjectEntityMetadata<>(2, MetadataType.OPTIONAL_CHAT, Optional.of(Component.text("tesss"))),
|
||||
new BooleanEntityMetadata(3, MetadataType.BOOLEAN, true)
|
||||
}));
|
||||
|
||||
assertNextPacketMatch(context, SetEntityDataPacket.class, packet -> {
|
||||
assertEquals(4, packet.getRuntimeEntityId());
|
||||
var metadata = packet.getMetadata();
|
||||
assertEquals(0.0f, metadata.get(EntityDataTypes.SCALE));
|
||||
assertEquals("tesss", metadata.get(EntityDataTypes.NAME));
|
||||
assertEquals((byte) 1, metadata.get(EntityDataTypes.NAMETAG_ALWAYS_SHOW));
|
||||
});
|
||||
// because the armor stand turned invisible and has a nametag (nametag is hidden when invisible)
|
||||
assertNextPacketType(context, MoveEntityAbsolutePacket.class);
|
||||
|
||||
context.translate(
|
||||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket(
|
||||
"npc_team_1298",
|
||||
Component.empty(),
|
||||
Component.empty(),
|
||||
Component.empty(),
|
||||
false,
|
||||
false,
|
||||
NameTagVisibility.NEVER,
|
||||
CollisionRule.NEVER,
|
||||
TeamColor.WHITE,
|
||||
new String[0]
|
||||
)
|
||||
);
|
||||
context.translate(
|
||||
setPlayerTeamTranslator,
|
||||
new ClientboundSetPlayerTeamPacket("npc_team_1298", TeamAction.ADD_PLAYER, new String[]{ hologramUuid.toString() }));
|
||||
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "§f§r§ftesss§r§f");
|
||||
packet.setRuntimeEntityId(4);
|
||||
return packet;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ public class BasicBelownameScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "0 §r§9objective");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -131,24 +131,24 @@ public class BasicBelownameScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "0 §robjective");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -186,42 +186,42 @@ public class BasicBelownameScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "objective2")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "0 §robjective2");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "objective1")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "");
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "0 §robjective1");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.BELOW_NAME, "")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.SCORE, "");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScore
|
|||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ScoreInfo;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveObjectivePacket;
|
||||
|
@ -75,7 +74,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -83,7 +82,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
packet.setDisplaySlot("list");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -98,7 +97,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
new ClientboundSetObjectivePacket(
|
||||
"objective",
|
||||
ObjectiveAction.ADD,
|
||||
Component.text("objective", Style.style(NamedTextColor.AQUA, TextDecoration.BOLD)),
|
||||
Component.text("objective", NamedTextColor.AQUA, TextDecoration.BOLD),
|
||||
ScoreType.INTEGER,
|
||||
null
|
||||
)
|
||||
|
@ -109,7 +108,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("§b§lobjective");
|
||||
|
@ -117,7 +116,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
packet.setDisplaySlot("list");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -156,7 +155,7 @@ public class BasicPlayerlistScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "objective2")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective2");
|
||||
|
@ -164,26 +163,26 @@ public class BasicPlayerlistScoreboardTests {
|
|||
packet.setDisplaySlot("list");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
// session player name is Tim203
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 2, ScoreInfo.ScorerType.PLAYER, 1)));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "objective1")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new RemoveObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("2");
|
||||
packet.setDisplayName("objective1");
|
||||
|
@ -191,14 +190,14 @@ public class BasicPlayerlistScoreboardTests {
|
|||
packet.setDisplaySlot("list");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
// session player name is Tim203
|
||||
packet.setInfos(List.of(new ScoreInfo(3, "2", 1, ScoreInfo.ScorerType.PLAYER, 1)));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScore
|
|||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ScoreInfo;
|
||||
|
@ -88,7 +87,7 @@ public class CubecraftScoreboardTest {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "sidebar")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("sidebar");
|
||||
|
@ -96,7 +95,7 @@ public class CubecraftScoreboardTest {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
|
||||
// Now they're going to create a bunch of teams and add players to those teams in a very inefficient way.
|
||||
|
@ -191,27 +190,23 @@ public class CubecraftScoreboardTest {
|
|||
ObjectiveAction.UPDATE,
|
||||
Component.empty()
|
||||
.append(Component.text(
|
||||
"CubeCraft", Style.style(NamedTextColor.WHITE, TextDecoration.BOLD))),
|
||||
"CubeCraft", NamedTextColor.WHITE, TextDecoration.BOLD)),
|
||||
ScoreType.INTEGER,
|
||||
null));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new RemoveObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("§f§lCubeCraft");
|
||||
packet.setCriteria("dummy");
|
||||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new RemoveObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
return packet;
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("§f§lCubeCraft");
|
||||
packet.setCriteria("dummy");
|
||||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -234,7 +229,7 @@ public class CubecraftScoreboardTest {
|
|||
new ClientboundSetPlayerTeamPacket(
|
||||
"SB_l-0",
|
||||
Component.text("SB_l-0"),
|
||||
Component.empty().append(Component.text("", Style.style(NamedTextColor.BLACK))),
|
||||
Component.empty().append(Component.text("", NamedTextColor.BLACK)),
|
||||
Component.empty(),
|
||||
true,
|
||||
true,
|
||||
|
@ -244,14 +239,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§0", "sidebar", 10));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 10, "§r§0§0§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 10, "§r§0§0§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -287,14 +280,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§1", "sidebar", 9));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(2, "0", 9, "§bUser: §r§fTim203§r§0§1§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(2, "0", 9, "§bUser: §r§fTim203§r§0§1§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -330,14 +321,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§2", "sidebar", 8));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(3, "0", 8, "§bRank: §r§f\uE1AB §r§0§2§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(3, "0", 8, "§bRank: §r§f\uE1AB §r§0§2§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -370,14 +359,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§3", "sidebar", 7));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(4, "0", 7, "§r§0§3§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(4, "0", 7, "§r§0§3§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -410,14 +397,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§4", "sidebar", 6));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(5, "0", 6, "§r§0§4§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(5, "0", 6, "§r§0§4§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -450,14 +435,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§5", "sidebar", 5));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(6, "0", 5, "§r§0§5§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(6, "0", 5, "§r§0§5§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -493,14 +476,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§6", "sidebar", 4));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(7, "0", 4, "§bLobby: §r§fEU #10§r§0§6§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(7, "0", 4, "§bLobby: §r§fEU #10§r§0§6§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -536,14 +517,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§7", "sidebar", 3));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(8, "0", 3, "§bPlayers: §r§f783§r§0§7§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(8, "0", 3, "§bPlayers: §r§f783§r§0§7§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -576,14 +555,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§8", "sidebar", 2));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(9, "0", 2, "§r§0§8§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(9, "0", 2, "§r§0§8§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -616,14 +593,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§9", "sidebar", 1));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(10, "0", 1, "§824/09/24 (g2208)§r§0§9§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(10, "0", 1, "§824/09/24 (g2208)§r§0§9§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setTeamTranslator,
|
||||
|
@ -656,14 +631,12 @@ public class CubecraftScoreboardTest {
|
|||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("§0§a", "sidebar", 0));
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(11, "0", 0, "§6play.cubecraft.net§r§0§a§r")));
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(11, "0", 0, "§6play.cubecraft.net§r§0§a§r")));
|
||||
return packet;
|
||||
});
|
||||
|
||||
// after this we get a ClientboundPlayerInfoUpdatePacket with the action UPDATE_DISPLAY_NAME,
|
||||
// but that one is only shown in the tablist so we don't have to handle that.
|
||||
|
@ -673,84 +646,68 @@ public class CubecraftScoreboardTest {
|
|||
// So the only thing we have to verify is that the nametag is hidden
|
||||
|
||||
mockAndAddPlayerEntity(context, "A_Player", 2);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(2);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "B_Player", 3);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(3);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(3);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "E_Player", 4);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(4);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(4);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "H_Player", 5);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(5);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(5);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "J_Player", 6);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(6);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(6);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "K_Player", 7);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(7);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(7);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "L_Player", 8);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(8);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(8);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
|
||||
mockAndAddPlayerEntity(context, "O_Player", 9);
|
||||
assertNextPacket(
|
||||
() -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(9);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
},
|
||||
context);
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(9);
|
||||
packet.getMetadata().put(EntityDataTypes.NAME, "");
|
||||
return packet;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScore
|
|||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ScoreInfo;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveObjectivePacket;
|
||||
|
@ -75,7 +74,7 @@ public class BasicSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -83,17 +82,17 @@ public class BasicSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("list");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
context.translate(
|
||||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.PLAYER_LIST, "")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new RemoveObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ public class BasicSidebarScoreboardTests {
|
|||
new ClientboundSetObjectivePacket(
|
||||
"objective",
|
||||
ObjectiveAction.ADD,
|
||||
Component.text("objective", Style.style(NamedTextColor.AQUA, TextDecoration.BOLD)),
|
||||
Component.text("objective", NamedTextColor.AQUA, TextDecoration.BOLD),
|
||||
ScoreType.INTEGER,
|
||||
null
|
||||
)
|
||||
|
@ -119,7 +118,7 @@ public class BasicSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("§b§lobjective");
|
||||
|
@ -127,7 +126,7 @@ public class BasicSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -170,7 +169,7 @@ public class BasicSidebarScoreboardTests {
|
|||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective2")
|
||||
);
|
||||
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective2");
|
||||
|
@ -178,13 +177,13 @@ public class BasicSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 2, "Tim203")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
|
||||
|
@ -193,12 +192,12 @@ public class BasicSidebarScoreboardTests {
|
|||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective1")
|
||||
);
|
||||
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new RemoveObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("2");
|
||||
packet.setDisplayName("objective1");
|
||||
|
@ -206,13 +205,13 @@ public class BasicSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(3, "2", 1, "Tim203")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -106,8 +106,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -128,7 +128,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(15, "0", 3, "c")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// remove a score
|
||||
|
@ -136,43 +136,43 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("m", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(5, "0", 13, "m")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(16, "0", 2, "b")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add a score
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("aa", "objective", 13)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(16, "0", 2, "b")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(17, "0", 13, "aa")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add score with same score value (after)
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("ga", "objective", 9)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -180,8 +180,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(9, "0", 9, "§0§rg")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -189,14 +189,14 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 9, "§1§rga")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add another score with same score value (before all)
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("ag", "objective", 9)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -205,8 +205,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 9, "§2§rga")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -215,14 +215,14 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 9, "§2§rga")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// remove score with same value
|
||||
context.translate(
|
||||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("g", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -230,8 +230,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 9, "§1§rga")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -239,14 +239,14 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(20, "0", 4, "e")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// remove the other score with the same value
|
||||
context.translate(
|
||||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("ga", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -254,8 +254,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(19, "0", 9, "ag")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -263,7 +263,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(21, "0", 3, "c")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -327,7 +327,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -335,8 +335,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -357,7 +357,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(15, "0", 3, "c")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
// remove a score
|
||||
|
@ -365,36 +365,36 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("m", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(5, "0", 13, "m")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(16, "0", 2, "b")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add a score
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("aa", "objective", 13)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(16, "0", 2, "b")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(17, "0", 13, "aa")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add some teams for the upcoming score adds
|
||||
context.translate(
|
||||
|
@ -435,7 +435,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("oa", "objective", 11)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -443,8 +443,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(7, "0", 11, "§0§r§4prefix§r§4o§r§4suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -452,7 +452,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 11, "§1§r§3prefix§r§3oa§r§3suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// add a score that on Java should be before 'o', but would be after on Bedrock without manual order
|
||||
// due to the team color
|
||||
|
@ -460,7 +460,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("ao", "objective", 11)
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -469,8 +469,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 11, "§2§r§3prefix§r§3oa§r§3suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -479,14 +479,14 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 11, "§2§r§3prefix§r§3oa§r§3suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// remove original 'o' score
|
||||
context.translate(
|
||||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("o", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -494,8 +494,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(18, "0", 11, "§1§r§3prefix§r§3oa§r§3suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -503,14 +503,14 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(20, "0", 4, "e")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
|
||||
// remove the other score with the same value as 'o'
|
||||
context.translate(
|
||||
resetScoreTranslator,
|
||||
new ClientboundResetScorePacket("oa", "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -518,8 +518,8 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(19, "0", 11, "§5prefix§r§5ao§r§5suffix")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(
|
||||
|
@ -527,7 +527,7 @@ public class OrderAndLimitSidebarScoreboardTests {
|
|||
new ScoreInfo(21, "0", 3, "c")
|
||||
));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class VanillaSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -77,16 +77,16 @@ public class VanillaSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("owner", "objective", 1));
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "owner")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ public class VanillaSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -122,22 +122,22 @@ public class VanillaSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "owner")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(setScoreTranslator, new ClientboundSetScorePacket("owner", "objective", 2));
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 2, "owner")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ public class VanillaSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -174,31 +174,31 @@ public class VanillaSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "owner")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("owner", "objective", 1).withDisplay(Component.text("hi"))
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "hi")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "hi")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ public class VanillaSidebarScoreboardTests {
|
|||
setDisplayObjectiveTranslator,
|
||||
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "objective")
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetDisplayObjectivePacket();
|
||||
packet.setObjectiveId("0");
|
||||
packet.setDisplayName("objective");
|
||||
|
@ -235,31 +235,31 @@ public class VanillaSidebarScoreboardTests {
|
|||
packet.setDisplaySlot("sidebar");
|
||||
packet.setSortOrder(1);
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 1, "owner")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
assertNoNextPacket(context);
|
||||
|
||||
context.translate(
|
||||
setScoreTranslator,
|
||||
new ClientboundSetScorePacket("owner", "objective", 2).withDisplay(Component.text("hi"))
|
||||
);
|
||||
assertNextPacket(() -> {
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.REMOVE);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 2, "hi")));
|
||||
return packet;
|
||||
}, context);
|
||||
assertNextPacket(() -> {
|
||||
});
|
||||
assertNextPacket(context, () -> {
|
||||
var packet = new SetScorePacket();
|
||||
packet.setAction(SetScorePacket.Action.SET);
|
||||
packet.setInfos(List.of(new ScoreInfo(1, "0", 2, "hi")));
|
||||
return packet;
|
||||
}, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package org.geysermc.geyser.scoreboard.network.util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
@ -38,7 +39,7 @@ public class AssertUtils {
|
|||
Assertions.assertEquals(expected.get(), actual);
|
||||
}
|
||||
|
||||
public static void assertNextPacket(Supplier<BedrockPacket> expected, GeyserMockContext context) {
|
||||
public static void assertNextPacket(GeyserMockContext context, Supplier<BedrockPacket> expected) {
|
||||
assertContextEquals(expected, context.nextPacket());
|
||||
}
|
||||
|
||||
|
@ -50,6 +51,16 @@ public class AssertUtils {
|
|||
Assertions.assertEquals(type, actual.getClass());
|
||||
}
|
||||
|
||||
public static <T extends BedrockPacket> void assertNextPacketMatch(GeyserMockContext context, Class<T> type, Consumer<T> matcher) {
|
||||
var actual = context.nextPacket();
|
||||
if (actual == null) {
|
||||
Assertions.fail("Expected another packet!");
|
||||
}
|
||||
Assertions.assertEquals(type, actual.getClass(), "Expected packet to be an instance of " + type);
|
||||
//noinspection unchecked verified in the line above me
|
||||
matcher.accept((T) actual);
|
||||
}
|
||||
|
||||
public static void assertNoNextPacket(GeyserMockContext context) {
|
||||
Assertions.assertEquals(
|
||||
Collections.emptyList(),
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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.scoreboard.network.util;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.CommonRegistries;
|
||||
import org.geysermc.geyser.registry.DeferredRegistry;
|
||||
import org.geysermc.geyser.registry.ListRegistry;
|
||||
import org.geysermc.geyser.registry.PacketTranslatorRegistry;
|
||||
import org.geysermc.geyser.registry.SimpleMappedRegistry;
|
||||
import org.geysermc.geyser.registry.SimpleRegistry;
|
||||
import org.geysermc.geyser.registry.VersionedRegistry;
|
||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||
import org.geysermc.geyser.registry.provider.ProviderSupplier;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.ParticleMapping;
|
||||
import org.geysermc.geyser.registry.type.SoundMapping;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundTranslator;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
|
||||
public class CommonRegistriesMock implements CommonRegistries {
|
||||
private final SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions = SimpleMappedRegistry.create(RegistryLoaders.empty(() -> new EnumMap<>(EntityType.class)));
|
||||
private final SimpleRegistry<Set<NbtMap>> bedrockEntityProperties = SimpleRegistry.create(RegistryLoaders.empty(HashSet::new));
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<Class<?>, ProviderSupplier> providers() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<NbtMap> bedrockEntityIdentifiers() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, EntityDefinition<?>> javaEntityIdentifiers() {
|
||||
// not used in current unit tests, can be safely ignored
|
||||
return SimpleMappedRegistry.create(RegistryLoaders.empty(HashMap::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<EntityType, EntityDefinition<?>> entityDefinitions() {
|
||||
// it is safely initialized by EntityDefinitions
|
||||
return entityDefinitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<Set<NbtMap>> bedrockEntityProperties() {
|
||||
// it is safely initialized by EntityDefinitions
|
||||
return bedrockEntityProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<NbtMap> biomesNbt() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleRegistry<Object2IntMap<String>> biomeIdentifiers() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> blockEntities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketTranslatorRegistry<BedrockPacket> bedrockPacketTranslators() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketTranslatorRegistry<Packet> javaPacketTranslators() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListRegistry<Item> javaItems() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, Item> javaItemIdentifiers() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedRegistry<ItemMappings> items() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<ParticleType, ParticleMapping> particles() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedRegistry<Set<PotionMixData>> potionMixes() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> recipes() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeferredRegistry<Map<String, ResourcePack>> resourcePacks() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<String, SoundMapping> sounds() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<LevelEvent, LevelEventTranslator> soundLevelEvents() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> soundTranslators() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit() {}
|
||||
}
|
|
@ -35,16 +35,15 @@ import java.util.function.Consumer;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class GeyserMockContext {
|
||||
private final List<Object> mocksAndSpies = new ArrayList<>();
|
||||
private final List<Object> storedObjects = new ArrayList<>();
|
||||
private final List<BedrockPacket> packets = Collections.synchronizedList(new ArrayList<>());
|
||||
private MockedStatic<GeyserImpl> geyserImplMock;
|
||||
|
||||
public static void mockContext(Consumer<GeyserMockContext> geyserContext) {
|
||||
var context = new GeyserMockContext();
|
||||
|
@ -59,10 +58,18 @@ public class GeyserMockContext {
|
|||
var logger = context.storeObject(new EmptyGeyserLogger());
|
||||
when(geyserImpl.getLogger()).thenReturn(logger);
|
||||
|
||||
try (var mocked = mockStatic(GeyserImpl.class)) {
|
||||
mocked.when(GeyserImpl::getInstance).thenReturn(geyserImpl);
|
||||
context.geyserImplMock = mocked;
|
||||
geyserContext.accept(context);
|
||||
try (var geyserImplMock = mockStatic(GeyserImpl.class)) {
|
||||
geyserImplMock.when(GeyserImpl::getInstance).thenReturn(geyserImpl);
|
||||
|
||||
// Registries contains static methods that all call 'backingRegistries', that's the one we override.
|
||||
// So every other static method will invoke the real method.
|
||||
try (var registriesMock = mockStatic(Registries.class, Mockito.CALLS_REAL_METHODS)) {
|
||||
var commonRegistries = context.storeObject(new CommonRegistriesMock());
|
||||
registriesMock.when(Registries::instance).thenReturn(commonRegistries);
|
||||
Registries.init();
|
||||
|
||||
geyserContext.accept(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,8 +143,4 @@ public class GeyserMockContext {
|
|||
public <T> void translate(PacketTranslator<T> translator, T packet) {
|
||||
translator.translate(session(), packet);
|
||||
}
|
||||
|
||||
public MockedStatic<GeyserImpl> geyserImplMock() {
|
||||
return geyserImplMock;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
|
@ -83,7 +84,7 @@ public class GeyserMockContextScoreboard {
|
|||
}
|
||||
|
||||
public static PlayerEntity mockAndAddPlayerEntity(GeyserMockContext context, String username, long geyserId) {
|
||||
var playerEntity = spy(new PlayerEntity(context.session(), geyserId, UUID.randomUUID(), username));
|
||||
var playerEntity = spy(new PlayerEntity(context.session(), (int) geyserId, geyserId, UUID.randomUUID(), Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, username, null));
|
||||
// fake the player being spawned
|
||||
when(playerEntity.isValid()).thenReturn(true);
|
||||
|
||||
|
|
Loading…
Reference in a new issue