2020-04-23 04:40:49 +00:00
/ *
2021-01-01 15:10:36 +00:00
* Copyright ( c ) 2019 - 2021 GeyserMC . http : //geysermc.org
2020-04-23 04:40:49 +00:00
*
* 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.connector.network.translators.java.world ;
import com.github.steveice10.mc.protocol.data.game.world.effect.* ;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlayEffectPacket ;
import com.nukkitx.math.vector.Vector3f ;
import com.nukkitx.protocol.bedrock.data.LevelEventType ;
import com.nukkitx.protocol.bedrock.data.SoundEvent ;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket ;
2020-04-30 05:21:02 +00:00
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket ;
2020-05-13 21:08:52 +00:00
import com.nukkitx.protocol.bedrock.packet.TextPacket ;
2020-04-23 04:40:49 +00:00
import org.geysermc.connector.GeyserConnector ;
import org.geysermc.connector.network.session.GeyserSession ;
import org.geysermc.connector.network.translators.PacketTranslator ;
import org.geysermc.connector.network.translators.Translator ;
import org.geysermc.connector.network.translators.effect.Effect ;
2021-07-13 01:19:40 +00:00
import org.geysermc.connector.registry.Registries ;
2020-05-13 21:08:52 +00:00
import org.geysermc.connector.utils.LocaleUtils ;
2021-03-31 18:15:55 +00:00
import java.util.Collections ;
2020-08-03 21:42:43 +00:00
import java.util.Locale ;
2020-04-23 04:40:49 +00:00
@Translator ( packet = ServerPlayEffectPacket . class )
public class JavaPlayEffectTranslator extends PacketTranslator < ServerPlayEffectPacket > {
@Override
2021-08-30 17:55:01 +00:00
public void translate ( GeyserSession session , ServerPlayEffectPacket packet ) {
2020-08-03 21:42:43 +00:00
// Separate case since each RecordEffectData in Java is an individual track in Bedrock
if ( packet . getEffect ( ) = = SoundEffect . RECORD ) {
RecordEffectData recordEffectData = ( RecordEffectData ) packet . getData ( ) ;
2021-07-13 01:19:40 +00:00
SoundEvent soundEvent = Registries . RECORDS . getOrDefault ( recordEffectData . getRecordId ( ) , SoundEvent . STOP_RECORD ) ;
2020-08-03 21:42:43 +00:00
Vector3f pos = Vector3f . from ( packet . getPosition ( ) . getX ( ) , packet . getPosition ( ) . getY ( ) , packet . getPosition ( ) . getZ ( ) ) . add ( 0 . 5f , 0 . 5f , 0 . 5f ) ;
LevelSoundEventPacket levelSoundEvent = new LevelSoundEventPacket ( ) ;
levelSoundEvent . setIdentifier ( " " ) ;
levelSoundEvent . setSound ( soundEvent ) ;
levelSoundEvent . setPosition ( pos ) ;
levelSoundEvent . setRelativeVolumeDisabled ( packet . isBroadcast ( ) ) ;
levelSoundEvent . setExtraData ( - 1 ) ;
levelSoundEvent . setBabySound ( false ) ;
session . sendUpstreamPacket ( levelSoundEvent ) ;
if ( soundEvent ! = SoundEvent . STOP_RECORD ) {
// Send text packet as it seems to be handled in Java Edition client-side.
TextPacket textPacket = new TextPacket ( ) ;
textPacket . setType ( TextPacket . Type . JUKEBOX_POPUP ) ;
textPacket . setNeedsTranslation ( true ) ;
textPacket . setXuid ( " " ) ;
textPacket . setPlatformChatId ( " " ) ;
textPacket . setSourceName ( null ) ;
textPacket . setMessage ( " record.nowPlaying " ) ;
String recordString = " %item. " + soundEvent . name ( ) . toLowerCase ( Locale . ROOT ) + " .desc " ;
2021-03-31 18:15:55 +00:00
textPacket . setParameters ( Collections . singletonList ( LocaleUtils . getLocaleString ( recordString , session . getLocale ( ) ) ) ) ;
2020-08-03 21:42:43 +00:00
session . sendUpstreamPacket ( textPacket ) ;
}
return ;
}
2021-09-10 18:10:56 +00:00
if ( packet . getEffect ( ) instanceof SoundEffect soundEffect ) {
2021-07-13 01:19:40 +00:00
Effect geyserEffect = Registries . SOUND_EFFECTS . get ( soundEffect ) ;
2020-04-23 04:40:49 +00:00
if ( geyserEffect ! = null ) {
2020-08-03 21:42:43 +00:00
geyserEffect . handleEffectPacket ( session , packet ) ;
return ;
}
GeyserConnector . getInstance ( ) . getLogger ( ) . debug ( " Unhandled sound effect: " + soundEffect . name ( ) ) ;
2021-09-10 18:10:56 +00:00
} else if ( packet . getEffect ( ) instanceof ParticleEffect particleEffect ) {
2020-08-03 21:42:43 +00:00
Vector3f pos = Vector3f . from ( packet . getPosition ( ) . getX ( ) , packet . getPosition ( ) . getY ( ) , packet . getPosition ( ) . getZ ( ) ) . add ( 0 . 5f , 0 . 5f , 0 . 5f ) ;
LevelEventPacket effectPacket = new LevelEventPacket ( ) ;
effectPacket . setPosition ( pos ) ;
effectPacket . setData ( 0 ) ;
switch ( particleEffect ) {
2021-09-10 18:10:56 +00:00
case COMPOSTER - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_CROP_GROWTH ) ;
ComposterEffectData composterEffectData = ( ComposterEffectData ) packet . getData ( ) ;
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
switch ( composterEffectData ) {
2021-09-10 18:10:56 +00:00
case FILL - > soundEventPacket . setSound ( SoundEvent . COMPOSTER_FILL ) ;
case FILL_SUCCESS - > soundEventPacket . setSound ( SoundEvent . COMPOSTER_FILL_LAYER ) ;
2020-08-03 21:42:43 +00:00
}
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
}
2021-09-10 18:10:56 +00:00
case BLOCK_LAVA_EXTINGUISH - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EVAPORATE ) ;
effectPacket . setPosition ( pos . add ( - 0 . 5f , 0 . 7f , - 0 . 5f ) ) ;
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
soundEventPacket . setSound ( SoundEvent . EXTINGUISH_FIRE ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
}
2021-09-10 18:10:56 +00:00
case BLOCK_REDSTONE_TORCH_BURNOUT - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EVAPORATE ) ;
effectPacket . setPosition ( pos . add ( - 0 . 5f , 0 , - 0 . 5f ) ) ;
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
soundEventPacket . setSound ( SoundEvent . EXTINGUISH_FIRE ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
}
2021-09-10 18:10:56 +00:00
case BLOCK_END_PORTAL_FRAME_FILL - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EVAPORATE ) ;
effectPacket . setPosition ( pos . add ( - 0 . 5f , 0 . 3125f , - 0 . 5f ) ) ;
2020-05-04 04:56:07 +00:00
2020-08-03 21:42:43 +00:00
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
soundEventPacket . setSound ( SoundEvent . BLOCK_END_PORTAL_FRAME_FILL ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
}
2021-09-10 18:10:56 +00:00
case SMOKE - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_SHOOT ) ;
SmokeEffectData smokeEffectData = ( SmokeEffectData ) packet . getData ( ) ;
int data = 0 ;
switch ( smokeEffectData ) {
2021-09-10 18:10:56 +00:00
case DOWN - > {
2020-08-03 21:42:43 +00:00
data = 4 ;
pos = pos . add ( 0 , - 0 . 9f , 0 ) ;
2021-09-10 18:10:56 +00:00
}
case UP - > {
2020-08-03 21:42:43 +00:00
data = 4 ;
pos = pos . add ( 0 , 0 . 5f , 0 ) ;
2021-09-10 18:10:56 +00:00
}
case NORTH - > {
2020-08-03 21:42:43 +00:00
data = 1 ;
pos = pos . add ( 0 , - 0 . 2f , - 0 . 7f ) ;
2021-09-10 18:10:56 +00:00
}
case SOUTH - > {
2020-08-03 21:42:43 +00:00
data = 7 ;
pos = pos . add ( 0 , - 0 . 2f , 0 . 7f ) ;
2021-09-10 18:10:56 +00:00
}
case WEST - > {
2020-08-03 21:42:43 +00:00
data = 3 ;
pos = pos . add ( - 0 . 7f , - 0 . 2f , 0 ) ;
2021-09-10 18:10:56 +00:00
}
case EAST - > {
2020-08-03 21:42:43 +00:00
data = 5 ;
pos = pos . add ( 0 . 7f , - 0 . 2f , 0 ) ;
2021-09-10 18:10:56 +00:00
}
2020-08-03 21:42:43 +00:00
}
effectPacket . setPosition ( pos ) ;
effectPacket . setData ( data ) ;
}
2021-09-10 18:10:56 +00:00
2020-08-03 21:42:43 +00:00
//TODO: Block break particles when under fire
2021-09-10 18:10:56 +00:00
case BREAK_BLOCK - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_DESTROY_BLOCK ) ;
BreakBlockEffectData breakBlockEffectData = ( BreakBlockEffectData ) packet . getData ( ) ;
2021-07-13 01:19:40 +00:00
effectPacket . setData ( session . getBlockMappings ( ) . getBedrockBlockId ( breakBlockEffectData . getBlockState ( ) ) ) ;
2020-08-03 21:42:43 +00:00
}
2021-09-10 18:10:56 +00:00
case BREAK_SPLASH_POTION - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_POTION_SPLASH ) ;
effectPacket . setPosition ( pos . add ( 0 , - 0 . 5f , 0 ) ) ;
BreakPotionEffectData splashPotionData = ( BreakPotionEffectData ) packet . getData ( ) ;
effectPacket . setData ( splashPotionData . getPotionId ( ) ) ;
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
soundEventPacket . setSound ( SoundEvent . GLASS ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
}
2021-09-10 18:10:56 +00:00
case BREAK_EYE_OF_ENDER - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EYE_OF_ENDER_DEATH ) ;
}
2021-09-10 18:10:56 +00:00
case MOB_SPAWN - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_MOB_BLOCK_SPAWN ) ; // TODO: Check, but I don't think I really verified this ever went into effect on Java
}
2021-09-10 18:10:56 +00:00
// Note that there is no particle without sound in Bedrock. If you wanted to implement the sound, send a PlaySoundPacket with "item.bone_meal.use" and volume and pitch at 1.0F
case BONEMEAL_GROW_WITH_SOUND , BONEMEAL_GROW - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_CROP_GROWTH ) ;
BonemealGrowEffectData growEffectData = ( BonemealGrowEffectData ) packet . getData ( ) ;
effectPacket . setData ( growEffectData . getParticleCount ( ) ) ;
}
2021-09-10 18:10:56 +00:00
case ENDERDRAGON_FIREBALL_EXPLODE - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EYE_OF_ENDER_DEATH ) ; // TODO
DragonFireballEffectData fireballEffectData = ( DragonFireballEffectData ) packet . getData ( ) ;
if ( fireballEffectData = = DragonFireballEffectData . HAS_SOUND ) {
2020-05-02 06:06:22 +00:00
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
2020-08-03 21:42:43 +00:00
soundEventPacket . setSound ( SoundEvent . EXPLODE ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
2020-05-02 06:06:22 +00:00
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
2020-05-05 15:51:43 +00:00
session . sendUpstreamPacket ( soundEventPacket ) ;
2020-04-23 04:40:49 +00:00
}
2020-08-03 21:42:43 +00:00
}
2021-09-10 18:10:56 +00:00
case EXPLOSION - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_GENERIC_SPAWN ) ;
effectPacket . setData ( 61 ) ;
}
2021-09-10 18:10:56 +00:00
case EVAPORATE - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EVAPORATE_WATER ) ;
effectPacket . setPosition ( pos . add ( - 0 . 5f , 0 . 5f , - 0 . 5f ) ) ;
}
2021-09-10 18:10:56 +00:00
case END_GATEWAY_SPAWN - > {
2020-08-03 21:42:43 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_EXPLOSION ) ;
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket ( ) ;
soundEventPacket . setSound ( SoundEvent . EXPLODE ) ;
soundEventPacket . setPosition ( pos ) ;
soundEventPacket . setIdentifier ( " " ) ;
soundEventPacket . setExtraData ( - 1 ) ;
soundEventPacket . setBabySound ( false ) ;
soundEventPacket . setRelativeVolumeDisabled ( false ) ;
session . sendUpstreamPacket ( soundEventPacket ) ;
2021-06-16 23:09:35 +00:00
}
2021-09-10 18:10:56 +00:00
case DRIPSTONE_DRIP - > {
2021-06-16 23:09:35 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_DRIPSTONE_DRIP ) ;
2020-08-03 21:42:43 +00:00
}
2021-09-10 18:10:56 +00:00
case ELECTRIC_SPARK - > {
2021-06-09 23:48:38 +00:00
// Matches with a Bedrock server but doesn't seem to match up with Java
effectPacket . setType ( LevelEventType . PARTICLE_ELECTRIC_SPARK ) ;
}
2021-09-10 18:10:56 +00:00
case WAX_ON - > {
2021-06-09 23:48:38 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_WAX_ON ) ;
}
2021-09-10 18:10:56 +00:00
case WAX_OFF - > {
2021-06-09 23:48:38 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_WAX_OFF ) ;
}
2021-09-10 18:10:56 +00:00
case SCRAPE - > {
2021-06-09 23:48:38 +00:00
effectPacket . setType ( LevelEventType . PARTICLE_SCRAPE ) ;
}
2021-09-10 18:10:56 +00:00
default - > {
2020-08-03 21:42:43 +00:00
GeyserConnector . getInstance ( ) . getLogger ( ) . debug ( " Unhandled particle effect: " + particleEffect . name ( ) ) ;
return ;
2020-04-23 04:40:49 +00:00
}
}
2020-08-03 21:42:43 +00:00
session . sendUpstreamPacket ( effectPacket ) ;
2020-04-23 04:40:49 +00:00
}
}
}