3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-03 14:50:19 +01:00

Set entities silent client-side, and more

Add warden entity events. Fix up other things.
Dieser Commit ist enthalten in:
Camotoy 2022-05-31 14:25:15 -04:00
Ursprung bf4e1d5be7
Commit 196742a597
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
13 geänderte Dateien mit 86 neuen und 51 gelöschten Zeilen

Datei anzeigen

@ -184,7 +184,7 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.INT, Entity::setAir) // Air/bubbles .addTranslator(MetadataType.INT, Entity::setAir) // Air/bubbles
.addTranslator(MetadataType.OPTIONAL_CHAT, Entity::setDisplayName) .addTranslator(MetadataType.OPTIONAL_CHAT, Entity::setDisplayName)
.addTranslator(MetadataType.BOOLEAN, Entity::setDisplayNameVisible) .addTranslator(MetadataType.BOOLEAN, Entity::setDisplayNameVisible)
.addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.SILENT, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .addTranslator(MetadataType.BOOLEAN, Entity::setSilent)
.addTranslator(MetadataType.BOOLEAN, Entity::setGravity) .addTranslator(MetadataType.BOOLEAN, Entity::setGravity)
.addTranslator(MetadataType.POSE, (entity, entityMetadata) -> entity.setPose(entityMetadata.getValue())) .addTranslator(MetadataType.POSE, (entity, entityMetadata) -> entity.setPose(entityMetadata.getValue()))
.addTranslator(MetadataType.INT, Entity::setFreezing) .addTranslator(MetadataType.INT, Entity::setFreezing)

Datei anzeigen

@ -23,11 +23,11 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.entity; package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.type.BoatEntity; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.InteractiveTag;

Datei anzeigen

@ -94,6 +94,8 @@ public class Entity {
private float boundingBoxWidth; private float boundingBoxWidth;
@Setter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
protected String nametag = ""; protected String nametag = "";
@Setter(AccessLevel.NONE)
protected boolean silent = false;
/* Metadata end */ /* Metadata end */
protected List<Entity> passengers = Collections.emptyList(); protected List<Entity> passengers = Collections.emptyList();
@ -148,6 +150,12 @@ public class Entity {
setFlag(EntityFlag.HAS_COLLISION, true); setFlag(EntityFlag.HAS_COLLISION, true);
setFlag(EntityFlag.CAN_SHOW_NAME, true); setFlag(EntityFlag.CAN_SHOW_NAME, true);
setFlag(EntityFlag.CAN_CLIMB, true); setFlag(EntityFlag.CAN_CLIMB, true);
// Let the Java server (or us) supply all sounds for an entity
setClientSideSilent();
}
protected void setClientSideSilent() {
setFlag(EntityFlag.SILENT, true);
} }
public void spawnEntity() { public void spawnEntity() {
@ -370,6 +378,10 @@ public class Entity {
dirtyMetadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) (entityMetadata.getPrimitiveValue() ? 1 : 0)); dirtyMetadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) (entityMetadata.getPrimitiveValue() ? 1 : 0));
} }
public final void setSilent(BooleanEntityMetadata entityMetadata) {
silent = entityMetadata.getPrimitiveValue();
}
public void setGravity(BooleanEntityMetadata entityMetadata) { public void setGravity(BooleanEntityMetadata entityMetadata) {
setFlag(EntityFlag.HAS_GRAVITY, !entityMetadata.getPrimitiveValue()); setFlag(EntityFlag.HAS_GRAVITY, !entityMetadata.getPrimitiveValue());
} }

Datei anzeigen

@ -27,7 +27,6 @@ package org.geysermc.geyser.entity.type;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket; import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -58,7 +57,7 @@ public class EvokerFangsEntity extends Entity implements Tickable {
public void setAttackStarted() { public void setAttackStarted() {
this.attackStarted = true; this.attackStarted = true;
if (!getFlag(EntityFlag.SILENT)) { if (!silent) {
// Play the chomp sound // Play the chomp sound
PlaySoundPacket packet = new PlaySoundPacket(); PlaySoundPacket packet = new PlaySoundPacket();
packet.setPosition(this.position); packet.setPosition(this.position);

Datei anzeigen

@ -28,17 +28,16 @@ package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket; import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import lombok.Getter; import lombok.Getter;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.level.block.BlockPositionIterator; import org.geysermc.geyser.level.block.BlockPositionIterator;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.BlockUtils;
import java.util.UUID; import java.util.UUID;
@ -129,7 +128,7 @@ public class FishingHookEntity extends ThrowableEntity {
} }
private void sendSplashSound(GeyserSession session) { private void sendSplashSound(GeyserSession session) {
if (!getFlag(EntityFlag.SILENT)) { if (!silent) {
float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY())); float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY()));
if (volume > 1) { if (volume > 1) {
volume = 1; volume = 1;

Datei anzeigen

@ -213,7 +213,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
*/ */
private void effectTick() { private void effectTick() {
Random random = ThreadLocalRandom.current(); Random random = ThreadLocalRandom.current();
if (!getFlag(EntityFlag.SILENT)) { if (!silent) {
if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) { if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) {
PlaySoundPacket playSoundPacket = new PlaySoundPacket(); PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setSound("mob.enderdragon.flap"); playSoundPacket.setSound("mob.enderdragon.flap");

Datei anzeigen

@ -31,13 +31,19 @@ import com.nukkitx.math.GenericMath;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Tickable;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.MathUtils; import org.geysermc.geyser.util.MathUtils;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
public class WardenEntity extends MonsterEntity implements Tickable {
private int heartBeatDelay;
private int tickCount;
public class WardenEntity extends MonsterEntity {
public WardenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { public WardenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
} }
@ -53,6 +59,23 @@ public class WardenEntity extends MonsterEntity {
public void setAngerLevel(IntEntityMetadata entityMetadata) { public void setAngerLevel(IntEntityMetadata entityMetadata) {
float anger = (float) entityMetadata.getPrimitiveValue() / 80f; float anger = (float) entityMetadata.getPrimitiveValue() / 80f;
dirtyMetadata.put(EntityData.HEARTBEAT_INTERVAL_TICKS, 40 - GenericMath.floor(MathUtils.clamp(anger, 0.0F, 1.0F) * 30F)); heartBeatDelay = 40 - GenericMath.floor(MathUtils.clamp(anger, 0.0F, 1.0F) * 30F);
dirtyMetadata.put(EntityData.HEARTBEAT_INTERVAL_TICKS, heartBeatDelay);
}
@Override
public void tick() {
if (++tickCount % heartBeatDelay == 0 && !silent) {
// We have to do these calculations because they're clientside on Java Edition but we mute entities
// to prevent hearing their step sounds
ThreadLocalRandom random = ThreadLocalRandom.current();
PlaySoundPacket packet = new PlaySoundPacket();
packet.setSound("mob.warden.heartbeat");
packet.setPosition(position);
packet.setPitch(1.0f);
packet.setVolume((random.nextFloat() - random.nextFloat()) * 0.2f + 1.0f);
session.sendUpstreamPacket(packet);
}
} }
} }

Datei anzeigen

@ -75,6 +75,11 @@ public class SessionPlayerEntity extends PlayerEntity {
valid = true; valid = true;
} }
@Override
protected void setClientSideSilent() {
// Do nothing, since we want the session player to hear their own footstep sounds for example.
}
@Override @Override
public void spawnEntity() { public void spawnEntity() {
// Already logged in // Already logged in

Datei anzeigen

@ -38,10 +38,10 @@ public class SoundMapping {
public SoundMapping(String java, String bedrock, String playsound, int extraData, String identifier, boolean levelEvent) { public SoundMapping(String java, String bedrock, String playsound, int extraData, String identifier, boolean levelEvent) {
this.java = java; this.java = java;
this.bedrock = bedrock == null || bedrock.equalsIgnoreCase("") ? null : bedrock; this.bedrock = bedrock == null || bedrock.isEmpty() ? null : bedrock;
this.playsound = playsound == null || playsound.equalsIgnoreCase("") ? null : playsound; this.playsound = playsound == null || playsound.isEmpty() ? null : playsound;
this.extraData = extraData; this.extraData = extraData;
this.identifier = identifier == null || identifier.equalsIgnoreCase("") ? ":" : identifier; this.identifier = identifier == null || identifier.isEmpty() ? ":" : identifier;
this.levelEvent = levelEvent; this.levelEvent = levelEvent;
} }
} }

Datei anzeigen

@ -26,7 +26,6 @@
package org.geysermc.geyser.translator.protocol.java.entity; package org.geysermc.geyser.translator.protocol.java.entity;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
@ -42,7 +41,6 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@Translator(packet = ClientboundEntityEventPacket.class) @Translator(packet = ClientboundEntityEventPacket.class)
@ -50,6 +48,7 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
@Override @Override
public void translate(GeyserSession session, ClientboundEntityEventPacket packet) { public void translate(GeyserSession session, ClientboundEntityEventPacket packet) {
System.out.println(packet);
Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId()); Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
if (entity == null) if (entity == null)
return; return;
@ -180,8 +179,9 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
case IRON_GOLEM_EMPTY_HAND: case IRON_GOLEM_EMPTY_HAND:
entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_WITHDRAW); entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_WITHDRAW);
break; break;
case IRON_GOLEM_ATTACK: case ATTACK:
if (entity.getDefinition() == EntityDefinitions.IRON_GOLEM || entity.getDefinition() == EntityDefinitions.EVOKER_FANGS) { if (entity.getDefinition() == EntityDefinitions.IRON_GOLEM || entity.getDefinition() == EntityDefinitions.EVOKER_FANGS
|| entity.getDefinition() == EntityDefinitions.WARDEN) {
entityEventPacket.setType(EntityEventType.ATTACK_START); entityEventPacket.setType(EntityEventType.ATTACK_START);
if (entity.getDefinition() == EntityDefinitions.EVOKER_FANGS) { if (entity.getDefinition() == EntityDefinitions.EVOKER_FANGS) {
((EvokerFangsEntity) entity).setAttackStarted(); ((EvokerFangsEntity) entity).setAttackStarted();
@ -236,28 +236,14 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
break; break;
case MAKE_POOF_PARTICLES: case MAKE_POOF_PARTICLES:
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity) {
// Not ideal, but... // Note that this event usually makes noise, but because we set all entities as silent on the
// LevelEventType.PARTICLE_DEATH_SMOKE doesn't work (as of 1.18.2 Bedrock) // client end this isn't an issue.
// EntityEventType.DEATH_SMOKE_CLOUD also plays the entity death noise entityEventPacket.setType(EntityEventType.DEATH_SMOKE_CLOUD);
// Bedrock sends the particles through EntityEventType.DEATH, but Java despawns the entity }
// prematurely so they don't show up. break;
Vector3f position = entity.getPosition(); case WARDEN_RECEIVE_SIGNAL:
float baseX = position.getX(); if (entity.getDefinition() == EntityDefinitions.WARDEN) {
float baseY = position.getY(); entityEventPacket.setType(EntityEventType.VIBRATION_DETECTED);
float baseZ = position.getZ();
float height = entity.getBoundingBoxHeight();
float width = entity.getBoundingBoxWidth();
Random random = ThreadLocalRandom.current();
for (int i = 0; i < 20; i++) {
// Reconstruct the Java Edition (1.18.1) logic, but in floats
float x = baseX + width * (2.0f * random.nextFloat() - 1f);
float y = baseY + height * random.nextFloat();
float z = baseZ + width * (2.0f * random.nextFloat() - 1f);
LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(Vector3f.from(x, y, z));
levelEventPacket.setType(LevelEventType.PARTICLE_EXPLODE);
session.sendUpstreamPacket(levelEventPacket);
}
} }
break; break;
} }

Datei anzeigen

@ -40,6 +40,6 @@ public class JavaSoundEntityTranslator extends PacketTranslator<ClientboundSound
if (entity == null) { if (entity == null) {
return; return;
} }
SoundUtils.playBuiltinSound(session, packet.getSound(), entity.getPosition(), packet.getPitch()); SoundUtils.playBuiltinSound(session, packet.getSound(), entity.getPosition(), packet.getVolume(), packet.getPitch());
} }
} }

Datei anzeigen

@ -38,6 +38,6 @@ public class JavaSoundTranslator extends PacketTranslator<ClientboundSoundPacket
@Override @Override
public void translate(GeyserSession session, ClientboundSoundPacket packet) { public void translate(GeyserSession session, ClientboundSoundPacket packet) {
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
SoundUtils.playBuiltinSound(session, packet.getSound(), position, packet.getPitch()); SoundUtils.playBuiltinSound(session, packet.getSound(), position, packet.getVolume(), packet.getPitch());
} }
} }

Datei anzeigen

@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
@ -74,10 +75,9 @@ public class SoundUtils {
return ""; return "";
} }
// Drop the namespace // Drop the Minecraft namespace if applicable
int colonPos = packetSound.indexOf(":"); if (packetSound.startsWith("minecraft:")) {
if (colonPos != -1) { packetSound = packetSound.substring("minecraft:".length());
packetSound = packetSound.substring(colonPos + 1);
} }
SoundMapping soundMapping = Registries.SOUNDS.get(packetSound); SoundMapping soundMapping = Registries.SOUNDS.get(packetSound);
@ -97,7 +97,7 @@ public class SoundUtils {
* @param position the position * @param position the position
* @param pitch the pitch * @param pitch the pitch
*/ */
public static void playBuiltinSound(GeyserSession session, BuiltinSound javaSound, Vector3f position, float pitch) { public static void playBuiltinSound(GeyserSession session, BuiltinSound javaSound, Vector3f position, float volume, float pitch) {
String packetSound = javaSound.getName(); String packetSound = javaSound.getName();
SoundMapping soundMapping = Registries.SOUNDS.get(packetSound); SoundMapping soundMapping = Registries.SOUNDS.get(packetSound);
@ -106,6 +106,17 @@ public class SoundUtils {
return; return;
} }
if (soundMapping.getPlaysound() != null) {
// We always prefer the PlaySound mapping because we can control volume and pitch
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setSound(soundMapping.getPlaysound());
playSoundPacket.setPosition(position);
playSoundPacket.setVolume(volume);
playSoundPacket.setPitch(pitch);
session.sendUpstreamPacket(playSoundPacket);
return;
}
if (soundMapping.isLevelEvent()) { if (soundMapping.isLevelEvent()) {
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position); levelEventPacket.setPosition(position);