Fix: Trial Spawner Level Events (#4821)

* commit every thing i could do, couldnt get it to work with ominous stuff

* Fix trial spawner events to work correctly.

* Update mappings to latest

* fix comment

* Workaround for buggy trial chamber particles

* Fix positioning and also fix become ominous event

* Fix sounds and positioning again

* Fix random new line

* Update mappings

* update cloudburst library to 20240704.153116-14

* Fix accidental random line
This commit is contained in:
Ethan 2024-07-06 17:58:54 +08:00 committed by GitHub
parent ff1e1dd7e3
commit 9f19c0a9f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 116 additions and 22 deletions

View file

@ -28,9 +28,16 @@ package org.geysermc.geyser.translator.protocol.java.level;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap; 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.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket;
import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.level.JukeboxSong; import org.geysermc.geyser.level.JukeboxSong;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
@ -40,13 +47,27 @@ import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
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 org.geysermc.geyser.util.DimensionUtils;
import org.geysermc.geyser.util.SoundUtils; import org.geysermc.geyser.util.SoundUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; import org.geysermc.mcprotocollib.protocol.data.game.level.event.BonemealGrowEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.BreakBlockEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.BreakPotionEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.ComposterEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.DragonFireballEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.RecordEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.SculkBlockChargeEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.SmokeEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.TrialSpawnerDetectEventData;
import org.geysermc.mcprotocollib.protocol.data.game.level.event.UnknownLevelEventData;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
@Translator(packet = ClientboundLevelEventPacket.class) @Translator(packet = ClientboundLevelEventPacket.class)
public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelEventPacket> { public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelEventPacket> {
@ -291,6 +312,20 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
soundEventPacket.setRelativeVolumeDisabled(false); soundEventPacket.setRelativeVolumeDisabled(false);
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case ANIMATION_SPAWN_COBWEB -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_SPAWN_COBWEB);
case ANIMATION_VAULT_ACTIVATE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_ACTIVATE);
case ANIMATION_VAULT_DEACTIVATE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_DEACTIVATE);
case ANIMATION_VAULT_EJECT_ITEM -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.ANIMATION_VAULT_EJECT_ITEM);
case ANIMATION_TRIAL_SPAWNER_EJECT_ITEM -> {
Random random = ThreadLocalRandom.current();
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setSound("trial_spawner.eject_item");
playSoundPacket.setPosition(pos);
playSoundPacket.setVolume(1.0f);
playSoundPacket.setPitch(0.8f + random.nextFloat() * 0.3f);
session.sendUpstreamPacket(playSoundPacket);
return;
}
case DRIPSTONE_DRIP -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DRIPSTONE_DRIP); case DRIPSTONE_DRIP -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DRIPSTONE_DRIP);
case PARTICLES_ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java case PARTICLES_ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java
case PARTICLES_AND_SOUND_WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON); case PARTICLES_AND_SOUND_WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON);
@ -303,22 +338,22 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
if (eventData.getCharge() > 0) { if (eventData.getCharge() > 0) {
levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE); levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("x", packet.getPosition().getX()) .putInt("x", packet.getPosition().getX())
.putInt("y", packet.getPosition().getY()) .putInt("y", packet.getPosition().getY())
.putInt("z", packet.getPosition().getZ()) .putInt("z", packet.getPosition().getZ())
.putShort("charge", (short) eventData.getCharge()) .putShort("charge", (short) eventData.getCharge())
.putShort("facing", encodeFacing(eventData.getBlockFaces())) // TODO check if this is actually correct .putShort("facing", encodeFacing(eventData.getBlockFaces())) // TODO check if this is actually correct
.build() .build()
); );
} else { } else {
levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE_POP); levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.SCULK_CHARGE_POP);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("x", packet.getPosition().getX()) .putInt("x", packet.getPosition().getX())
.putInt("y", packet.getPosition().getY()) .putInt("y", packet.getPosition().getY())
.putInt("z", packet.getPosition().getZ()) .putInt("z", packet.getPosition().getZ())
.build() .build()
); );
} }
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);
@ -328,11 +363,11 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket();
levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCULK_SHRIEK); levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCULK_SHRIEK);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("originX", packet.getPosition().getX()) .putInt("originX", packet.getPosition().getX())
.putInt("originY", packet.getPosition().getY()) .putInt("originY", packet.getPosition().getY())
.putInt("originZ", packet.getPosition().getZ()) .putInt("originZ", packet.getPosition().getZ())
.build() .build()
); );
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);
@ -346,6 +381,54 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
return; return;
} }
case PARTICLES_TRIAL_SPAWNER_DETECT_PLAYER -> {
// Particles spawn here
TrialSpawnerDetectEventData eventData = (TrialSpawnerDetectEventData) packet.getData();
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_DETECTION);
// 0.75 is used here for Y instead of 0.5 to match Java Positioning.
// 0.5 is what the BDS uses for positioning.
effectPacket.setPosition(pos.sub(0.5f, 0.75f, 0.5f));
effectPacket.setData(eventData.getDetectedPlayers());
}
case PARTICLES_TRIAL_SPAWNER_DETECT_PLAYER_OMINOUS -> {
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_DETECTION_CHARGED);
effectPacket.setPosition(pos.sub(0.5f, 0.75f, 0.5f));
/*
Particles don't spawn here for some reason, only sound plays
This seems to be a bug in v1.21.0 and v1.21.1: see https://bugs.mojang.com/browse/MCPE-181465
If this gets fixed, the spawnOminousTrialSpawnerParticles function can be removed.
The positioning should be the same as normal activation.
*/
spawnOminousTrialSpawnerParticles(session, pos);
}
case PARTICLES_TRIAL_SPAWNER_BECOME_OMINOUS -> {
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_BECOME_CHARGED);
effectPacket.setPosition(pos.sub(0.5f, 0.5f, 0.5f));
// Same issue as above here
spawnOminousTrialSpawnerParticles(session, pos);
}
case PARTICLES_TRIAL_SPAWNER_SPAWN_MOB_AT -> {
// This should be its own class in MCProtocolLib.
// if 0, use Orange Flames,
// if 1, use Blue Flames for ominous spawners
UnknownLevelEventData eventData = (UnknownLevelEventData) packet.getData();
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_SPAWNING);
effectPacket.setData(eventData.getData());
}
case PARTICLES_TRIAL_SPAWNER_SPAWN -> {
UnknownLevelEventData eventData = (UnknownLevelEventData) packet.getData();
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_SPAWNING);
effectPacket.setData(eventData.getData());
Random random = ThreadLocalRandom.current();
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setSound("trial_spawner.spawn_mob");
playSoundPacket.setPosition(pos);
playSoundPacket.setVolume(1.0f);
playSoundPacket.setPitch(0.8f + random.nextFloat() * 0.3f);
session.sendUpstreamPacket(playSoundPacket);
}
case PARTICLES_TRIAL_SPAWNER_SPAWN_ITEM -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TRIAL_SPAWNER_EJECTING);
case SOUND_STOP_JUKEBOX_SONG -> { case SOUND_STOP_JUKEBOX_SONG -> {
String bedrockSound = session.getWorldCache().removeActiveRecord(origin); String bedrockSound = session.getWorldCache().removeActiveRecord(origin);
if (bedrockSound == null) { if (bedrockSound == null) {
@ -396,4 +479,15 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
} }
return facing; return facing;
} }
private static void spawnOminousTrialSpawnerParticles(GeyserSession session, Vector3f pos) {
int dimensionId = DimensionUtils.javaToBedrock(session.getDimension());
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier("minecraft:trial_spawner_detection_ominous");
stringPacket.setDimensionId(dimensionId);
stringPacket.setPosition(pos.sub(0.5f, 0.75f, 0.5f));
stringPacket.setMolangVariablesJson(Optional.empty());
stringPacket.setUniqueEntityId(-1);
session.sendUpstreamPacket(stringPacket);
}
} }

@ -1 +1 @@
Subproject commit 69e302bf3a118e5274f86b23a1818c61dba84c64 Subproject commit aaf53d6953c927e5ac1b87fd6627ffbfd4aa7cf5

View file

@ -10,7 +10,7 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT"
guava = "29.0-jre" guava = "29.0-jre"
gson = "2.3.1" # Provided by Spigot 1.8.8 gson = "2.3.1" # Provided by Spigot 1.8.8
websocket = "1.5.1" websocket = "1.5.1"
protocol = "3.0.0.Beta2-20240616.144648-10" protocol = "3.0.0.Beta2-20240704.153116-14"
raknet = "1.0.0.CR3-20240416.144209-1" raknet = "1.0.0.CR3-20240416.144209-1"
mcauthlib = "e5b0bcc" mcauthlib = "e5b0bcc"
mcprotocollib = "1.21-20240616.154144-5" mcprotocollib = "1.21-20240616.154144-5"