
API Issue with EntityAudioChanne
fordin93379 opened this issue ยท 1 comments
Confirmation
- I have read the wiki
Bug description
I am experiencing challenges with the API while developing an addon that introduces radios into the game. My goal is to create functionality where, when a radio held by a player receives a signal, nearby players can hear the sound as if it were emanating from the player holding the radio.
Despite my efforts, I have been unable to make the EntityAudioChannel work as intended. Based on my analysis of other mods, your source code, and the provided documentation, I understand that channels are meant to offer a more convenient way to send sounds to the client compared to individually sending packets to each player's connection.
To make it easier for you to assist me, I have simplified my mod to two basic classes.
Here is the main class, which is common for both cases:
package org.fordin.immersive_radio;
import com.mojang.logging.LogUtils;
import net.minecraft.world.item.Item;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.slf4j.Logger;
@Mod(ImmersiveRadio.MODID)
public class ImmersiveRadio {
public static final String MODID = "immersive_radio";
public static final Logger LOGGER = LogUtils.getLogger();
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ImmersiveRadio.MODID);
public static final RegistryObject<Item> PROFESSIONAL_RADIO = ITEMS.register("professional_radio", () -> new Item(new Item.Properties().stacksTo(1)));
public ImmersiveRadio() {
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
MinecraftForge.EVENT_BUS.register(this);
}
}
Below is the plugin class that works:
package org.fordin.immersive_radio;
import de.maxhenkel.voicechat.api.*;
import de.maxhenkel.voicechat.api.events.EventRegistration;
import de.maxhenkel.voicechat.api.events.MicrophonePacketEvent;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
@ForgeVoicechatPlugin
public class RadioVoicechatPlugin implements VoicechatPlugin {
@Override
public String getPluginId() {
return ImmersiveRadio.MODID;
}
@Override
public void registerEvents(EventRegistration registration) {
registration.registerEvent(MicrophonePacketEvent.class, this::onMicPacket);
}
private void onMicPacket(MicrophonePacketEvent event) {
VoicechatServerApi api = event.getVoicechat();
ServerLevel serverLevel = (ServerLevel) event.getSenderConnection().getPlayer().getServerLevel().getServerLevel();
for (ServerPlayer serverPlayer : serverLevel.players()) {
EntitySoundPacket packet = event.getPacket().entitySoundPacketBuilder()
.entityUuid(serverPlayer.getUUID())
.distance(10f)
.build(); // Creating a packet that should be heard by all players holding or near a player with a radio
if (serverPlayer.getItemInHand(InteractionHand.MAIN_HAND).is(ImmersiveRadio.PROFESSIONAL_RADIO.get())) {
for (ServerPlayer toSendPlayer : serverLevel.players()) {
if (toSendPlayer.getItemInHand(InteractionHand.MAIN_HAND).is(ImmersiveRadio.PROFESSIONAL_RADIO.get())) { // Sending packet to all players holding the item
VoicechatConnection connection = api.getConnectionOf(toSendPlayer.getUUID());
api.sendEntitySoundPacketTo(connection, packet);
}
}
}
}
}
}
Here is the version that does not work:
package org.fordin.immersive_radio;
import de.maxhenkel.voicechat.api.*;
import de.maxhenkel.voicechat.api.audiochannel.EntityAudioChannel;
import de.maxhenkel.voicechat.api.events.EventRegistration;
import de.maxhenkel.voicechat.api.events.MicrophonePacketEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import java.util.HashMap;
import java.util.UUID;
@ForgeVoicechatPlugin
public class RadioVoicechatPlugin implements VoicechatPlugin {
@Override
public String getPluginId() {
return ImmersiveRadio.MODID;
}
@Override
public void registerEvents(EventRegistration registration) {
registration.registerEvent(MicrophonePacketEvent.class, this::onMicPacket);
}
private static HashMap<UUID, EntityAudioChannel> map = new HashMap<>();
private void onMicPacket(MicrophonePacketEvent event) {
VoicechatServerApi api = event.getVoicechat();
ServerLevel serverLevel = (ServerLevel) event.getSenderConnection().getPlayer().getServerLevel().getServerLevel();
for (ServerPlayer serverPlayer : serverLevel.players()) {
if (serverPlayer.getItemInHand(InteractionHand.MAIN_HAND).is(ImmersiveRadio.PROFESSIONAL_RADIO.get())) {
for (ServerPlayer toSendPlayer : serverLevel.players()) {
if (toSendPlayer.getItemInHand(InteractionHand.MAIN_HAND).is(ImmersiveRadio.PROFESSIONAL_RADIO.get())) { // Sending packet to all players holding the item
EntityAudioChannel channel = map.get(toSendPlayer.getUUID());
if (channel == null || channel.isClosed()) {
channel = api.createEntityAudioChannel(UUID.randomUUID(), api.fromEntity(toSendPlayer));
map.put(toSendPlayer.getUUID(), channel);
}
channel.send(event.getPacket());
}
}
}
}
}
}
It is possible that I have misunderstood the concept of channels. From reviewing the API source code, I noticed that the only mandatory parameter for creating a packet is the entity UUID. However, I also attempted to use a channel with a custom sound category.
If this issue stems from a misunderstanding on my part, I would kindly ask you to improve the documentation to help others avoid similar challenges.
Thank you for your time and assistance!
Minecraft version
1.19.2
Mod/Plugin version
1.19.2-2.5.26
Mod/Plugin loader and version
forge 43.4.0
Steps to reproduce
Provided above
Expected behavior
No response
Log files
Screenshots
No response