mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-22 14:34:59 +01:00
parent
ef4acb121f
commit
521df04ed9
9 changed files with 250 additions and 39 deletions
|
@ -25,10 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
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;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiConsumer;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
|
@ -37,10 +37,10 @@ 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 java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiConsumer;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Represents data for an entity. This includes properties such as height and width, as well as the list of entity
|
||||
|
@ -146,8 +146,13 @@ 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(true);
|
||||
return build(!EnvironmentUtils.isUnitTesting);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,34 +25,131 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import org.geysermc.geyser.entity.type.AbstractWindChargeEntity;
|
||||
import org.geysermc.geyser.entity.factory.EntityFactory;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity;
|
||||
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;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.factory.EntityFactory;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.type.*;
|
||||
import org.geysermc.geyser.entity.type.living.*;
|
||||
import org.geysermc.geyser.entity.type.living.animal.*;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.*;
|
||||
import org.geysermc.geyser.entity.type.AbstractArrowEntity;
|
||||
import org.geysermc.geyser.entity.type.AbstractWindChargeEntity;
|
||||
import org.geysermc.geyser.entity.type.AreaEffectCloudEntity;
|
||||
import org.geysermc.geyser.entity.type.ArrowEntity;
|
||||
import org.geysermc.geyser.entity.type.BoatEntity;
|
||||
import org.geysermc.geyser.entity.type.ChestBoatEntity;
|
||||
import org.geysermc.geyser.entity.type.CommandBlockMinecartEntity;
|
||||
import org.geysermc.geyser.entity.type.DisplayBaseEntity;
|
||||
import org.geysermc.geyser.entity.type.EnderCrystalEntity;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.EvokerFangsEntity;
|
||||
import org.geysermc.geyser.entity.type.ExpOrbEntity;
|
||||
import org.geysermc.geyser.entity.type.FallingBlockEntity;
|
||||
import org.geysermc.geyser.entity.type.FireballEntity;
|
||||
import org.geysermc.geyser.entity.type.FireworkEntity;
|
||||
import org.geysermc.geyser.entity.type.FishingHookEntity;
|
||||
import org.geysermc.geyser.entity.type.FurnaceMinecartEntity;
|
||||
import org.geysermc.geyser.entity.type.InteractionEntity;
|
||||
import org.geysermc.geyser.entity.type.ItemEntity;
|
||||
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||
import org.geysermc.geyser.entity.type.LeashKnotEntity;
|
||||
import org.geysermc.geyser.entity.type.LightningEntity;
|
||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
import org.geysermc.geyser.entity.type.MinecartEntity;
|
||||
import org.geysermc.geyser.entity.type.PaintingEntity;
|
||||
import org.geysermc.geyser.entity.type.SpawnerMinecartEntity;
|
||||
import org.geysermc.geyser.entity.type.TNTEntity;
|
||||
import org.geysermc.geyser.entity.type.TextDisplayEntity;
|
||||
import org.geysermc.geyser.entity.type.ThrowableEntity;
|
||||
import org.geysermc.geyser.entity.type.ThrowableItemEntity;
|
||||
import org.geysermc.geyser.entity.type.ThrownPotionEntity;
|
||||
import org.geysermc.geyser.entity.type.TridentEntity;
|
||||
import org.geysermc.geyser.entity.type.WitherSkullEntity;
|
||||
import org.geysermc.geyser.entity.type.living.AbstractFishEntity;
|
||||
import org.geysermc.geyser.entity.type.living.AgeableEntity;
|
||||
import org.geysermc.geyser.entity.type.living.AllayEntity;
|
||||
import org.geysermc.geyser.entity.type.living.ArmorStandEntity;
|
||||
import org.geysermc.geyser.entity.type.living.BatEntity;
|
||||
import org.geysermc.geyser.entity.type.living.DolphinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.GlowSquidEntity;
|
||||
import org.geysermc.geyser.entity.type.living.IronGolemEntity;
|
||||
import org.geysermc.geyser.entity.type.living.MagmaCubeEntity;
|
||||
import org.geysermc.geyser.entity.type.living.MobEntity;
|
||||
import org.geysermc.geyser.entity.type.living.SlimeEntity;
|
||||
import org.geysermc.geyser.entity.type.living.SnowGolemEntity;
|
||||
import org.geysermc.geyser.entity.type.living.SquidEntity;
|
||||
import org.geysermc.geyser.entity.type.living.TadpoleEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.ArmadilloEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.AxolotlEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.BeeEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.ChickenEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.CowEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.FoxEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.FrogEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.GoatEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.HoglinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.MooshroomEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.OcelotEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.PandaEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.PigEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.PolarBearEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.PufferFishEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.RabbitEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.SheepEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.SnifferEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.StriderEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.TurtleEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.ChestedHorseEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.HorseEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.LlamaEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.SkeletonHorseEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.TraderLlamaEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.horse.ZombieHorseEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.CatEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.ParrotEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.TameableEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity;
|
||||
import org.geysermc.geyser.entity.type.living.merchant.AbstractMerchantEntity;
|
||||
import org.geysermc.geyser.entity.type.living.merchant.VillagerEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.*;
|
||||
import org.geysermc.geyser.entity.type.living.monster.AbstractSkeletonEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.BasePiglinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.BlazeEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.BoggedEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.BreezeEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.CreeperEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ElderGuardianEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.EnderDragonEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.EnderDragonPartEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.EndermanEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.GhastEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.GiantEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.GuardianEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.MonsterEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.PhantomEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.PiglinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ShulkerEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.SkeletonEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.SpiderEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.VexEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.WardenEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.WitherEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ZoglinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ZombieEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ZombieVillagerEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.ZombifiedPiglinEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.PillagerEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.RaidParticipantEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.SpellcasterIllagerEntity;
|
||||
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;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
public final class EntityDefinitions {
|
||||
public static final EntityDefinition<AllayEntity> ALLAY;
|
||||
|
@ -1025,7 +1122,10 @@ public final class EntityDefinitions {
|
|||
.identifier("minecraft:armor_stand") // Emulated
|
||||
.build(false); // Never sent over the network
|
||||
|
||||
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
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
|
|
@ -427,7 +427,10 @@ public class Entity implements GeyserEntity {
|
|||
}
|
||||
|
||||
public String teamIdentifier() {
|
||||
return uuid.toString();
|
||||
// experience orbs are the only known entities that do not send an uuid (even though they do have one),
|
||||
// but to be safe in the future it's done in the entity class itself instead of the entity specific one.
|
||||
// All entities without an uuid cannot show up in the scoreboard!
|
||||
return uuid != null ? uuid.toString() : null;
|
||||
}
|
||||
|
||||
public void setDisplayName(EntityMetadata<Optional<Component>, ?> entityMetadata) {
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
|
@ -66,7 +65,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
|||
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.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
@Getter @Setter
|
||||
public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||
|
@ -118,18 +116,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
|||
* Do not use! For testing purposes only
|
||||
*/
|
||||
public PlayerEntity(GeyserSession session, long geyserId, UUID uuid, String username) {
|
||||
super(
|
||||
session,
|
||||
-1,
|
||||
geyserId,
|
||||
uuid,
|
||||
EntityDefinition.builder(null).type(EntityType.PLAYER).build(false),
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
super(session, -1, geyserId, uuid, EntityDefinitions.PLAYER, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0);
|
||||
this.username = username;
|
||||
this.nametag = username;
|
||||
this.texturesProperty = null;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import java.util.Locale;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
||||
|
@ -46,8 +47,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public final class EntityUtils {
|
||||
/**
|
||||
* A constant array of the two hands that a player can interact with an entity.
|
||||
|
@ -294,6 +293,10 @@ public final class EntityUtils {
|
|||
}
|
||||
|
||||
private static String translatedEntityName(String namespace, String name, GeyserSession session) {
|
||||
// MinecraftLocale would otherwise invoke getBootstrap (which doesn't exist) and create some folders
|
||||
if (EnvironmentUtils.isUnitTesting) {
|
||||
return "entity." + namespace + "." + name;
|
||||
}
|
||||
return MinecraftLocale.getLocaleString("entity." + namespace + "." + name, session.locale());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
public final class EnvironmentUtils {
|
||||
public static final boolean isUnitTesting = isUnitTesting();
|
||||
|
||||
private EnvironmentUtils() {}
|
||||
|
||||
private static boolean isUnitTesting() {
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
if (element.getClassName().startsWith("org.junit.")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacketType;
|
||||
import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScoreboard.mockContextScoreboard;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.JavaRemoveEntitiesTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.java.entity.spawn.JavaAddExperienceOrbTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TeamIdentifierTest {
|
||||
@Test
|
||||
void entityWithoutUuid() {
|
||||
// experience orbs are the only known entities without an uuid, see Entity#teamIdentifier for more info
|
||||
mockContextScoreboard(context -> {
|
||||
var addExperienceOrbTranslator = new JavaAddExperienceOrbTranslator();
|
||||
var removeEntitiesTranslator = new JavaRemoveEntitiesTranslator();
|
||||
|
||||
// Entity#teamIdentifier used to throw because it returned uuid.toString where uuid could be null.
|
||||
// this would result in both EntityCache#spawnEntity and EntityCache#removeEntity throwing an exception,
|
||||
// because the entity would be registered and deregistered to the scoreboard.
|
||||
assertDoesNotThrow(() -> {
|
||||
context.translate(addExperienceOrbTranslator, new ClientboundAddExperienceOrbPacket(2, 0, 0, 0, 1));
|
||||
context.translate(removeEntitiesTranslator, new ClientboundRemoveEntitiesPacket(new int[] { 2 }));
|
||||
});
|
||||
|
||||
// we know that spawning and removing the entity should be fine
|
||||
assertNextPacketType(context, AddEntityPacket.class);
|
||||
assertNextPacketType(context, RemoveEntityPacket.class);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -42,6 +42,14 @@ public class AssertUtils {
|
|||
assertContextEquals(expected, context.nextPacket());
|
||||
}
|
||||
|
||||
public static void assertNextPacketType(GeyserMockContext context, Class<? extends BedrockPacket> type) {
|
||||
var actual = context.nextPacket();
|
||||
if (actual == null) {
|
||||
Assertions.fail("Expected another packet! " + type);
|
||||
}
|
||||
Assertions.assertEquals(type, actual.getClass());
|
||||
}
|
||||
|
||||
public static void assertNoNextPacket(GeyserMockContext context) {
|
||||
Assertions.assertEquals(
|
||||
Collections.emptyList(),
|
||||
|
|
|
@ -34,8 +34,8 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataMap;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
@ -57,7 +57,10 @@ public class GeyserMockContextScoreboard {
|
|||
// GeyserSession has so many dependencies, it's easier to just mock it
|
||||
var session = context.mock(GeyserSession.class);
|
||||
|
||||
when(session.getGeyser()).thenReturn(context.mockOrSpy(GeyserImpl.class));
|
||||
|
||||
when(session.locale()).thenReturn("en_US");
|
||||
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
context.addPacket(invocation.getArgument(0, BedrockPacket.class));
|
||||
return null;
|
||||
|
|
Loading…
Reference in a new issue