I have found a rather simple solution to all this after actually combing through the source codes of Mr Crayfishs Gun Mod and Timeless and Classics Guns Zero. They execute the sounds and particles not in the custom packet class itself but externally. You simply create another class (put it anywhere in your project in main), create a method and put in the desired sounds and particles or whatever you want in it. Create multiple methods for each individual task if you need to. You execute your code in the C2S Packet as follows:
public class SpittingC2SPacket {
public SpittingC2SPacket(){
}
public SpittingC2SPacket(FriendlyByteBuf buf){
}
public void toBytes(FriendlyByteBuf buf){
}
public boolean handle(Supplier<NetworkEvent.Context> supplier){
NetworkEvent.Context context = supplier.get();
context.enqueueWork(()-> {
ServerPlayer player = context.getSender();
ServerLevel sevel = player.getLevel();
RandomSource rdm = RandomSource.create();
//Entity
SpuckeEntity spit = new SpitEntity(sevel, player);
float r = (float)rdm.nextInt(3500,5000)/10000;
float y = player.getYRot();
float x = player.getXRot();
float z = 0f;
spucke.shootFromRotation(player, x, y, z, r, 1f);
sevel.addFreshEntity(spit);
//External handler
/////////////////////////////////////////////////////////////////
ServerPlayHandler.handleSpitting(player);
/////////////////////////////////////////////////////////////////
});
return true;
}
}
And your external handler class can look like this:
public class ServerPlayHandler {
public static void handleSpitting(ServerPlayer player){
if(player.isSpectator()) return;
Level lvl = player.level;
//Sounds
double posX = player.getX();
double posY = player.getY() + player.getEyeHeight();
double posZ = player.getZ();
float r = 0.8f + lvl.random.nextFloat() * 0.3f;
lvl.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LLAMA_SPIT, SoundSource.BLOCKS, 1f, r);
//Particles
Vec3 vec3 = player.getViewVector(1f);
Vec3 MausPos = player.getEyePosition();
Vec3 SchauWinkel = player.getLookAngle();
double x = player.getX() + vec3.x/4;
double y = MausPos.y + vec3.y/4;
double z = player.getZ() + vec3.z/4;
if(lvl instanceof ServerLevel slevel) {
slevel.sendParticles(ParticleTypes.SPIT, x, y, z, 3, 0d, 0d, 0d, 0.15d);
}
}
}
It works now. On client as well as on a server