first commit
Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s

This commit is contained in:
asminme committed 2026-10-24 15:18:03 +02:00
commit bbccd4a815
454 files changed
+45050

No files matched your search

@@ -0,0 +1,24 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.BukkitVoicechatService;
import de.maxhenkel.voicechat.api.VoicechatPlugin;
import java.util.ArrayList;
import java.util.List;
public class BukkitVoicechatServiceImpl
implements BukkitVoicechatService {
private final List<VoicechatPlugin> plugins = new ArrayList<VoicechatPlugin>();
@Override
public void registerPlugin(VoicechatPlugin plugin) {
this.plugins.add(plugin);
}
public List<VoicechatPlugin> getPlugins() {
return this.plugins;
}
}
@@ -0,0 +1,57 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.entity.Entity
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.Entity;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import java.util.Objects;
import java.util.UUID;
public class EntityImpl
implements Entity {
protected org.bukkit.entity.Entity entity;
public EntityImpl(org.bukkit.entity.Entity entity) {
this.entity = entity;
}
@Override
public UUID getUuid() {
return this.entity.getUniqueId();
}
@Override
public Object getEntity() {
return this.entity;
}
@Override
public Position getPosition() {
return new PositionImpl(this.entity.getLocation());
}
public org.bukkit.entity.Entity getRealEntity() {
return this.entity;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
EntityImpl entity1 = (EntityImpl)object;
return Objects.equals(this.entity, entity1.entity);
}
public int hashCode() {
return this.entity != null ? this.entity.hashCode() : 0;
}
}
@@ -0,0 +1,184 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.voice.common.PlayerState;
import de.maxhenkel.voicechat.voice.server.Group;
import de.maxhenkel.voicechat.voice.server.Server;
import java.util.Objects;
import java.util.UUID;
import javax.annotation.Nullable;
public class GroupImpl
implements de.maxhenkel.voicechat.api.Group {
private final Group group;
public GroupImpl(Group group) {
this.group = group;
}
@Override
public String getName() {
return this.group.getName();
}
@Override
public boolean hasPassword() {
return this.group.getPassword() != null;
}
@Override
public UUID getId() {
return this.group.getId();
}
@Override
public boolean isPersistent() {
return this.group.isPersistent();
}
@Override
public boolean isHidden() {
return this.group.isHidden();
}
@Override
public Group.Type getType() {
return this.group.getType();
}
public Group getGroup() {
return this.group;
}
@Nullable
public static GroupImpl create(PlayerState state) {
Group g;
UUID groupId = state.getGroup();
Server server = Voicechat.SERVER.getServer();
if (server != null && groupId != null && (g = server.getGroupManager().getGroup(groupId)) != null) {
return new GroupImpl(g);
}
return null;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
GroupImpl group1 = (GroupImpl)object;
return Objects.equals(this.group.getId(), group1.group.getId());
}
public int hashCode() {
return this.group != null ? this.group.getId().hashCode() : 0;
}
public static class TypeImpl
implements Group.Type {
public static short toInt(Group.Type type) {
if (type == OPEN) {
return 1;
}
if (type == ISOLATED) {
return 2;
}
return 0;
}
public static Group.Type fromInt(short i) {
if (i == 1) {
return OPEN;
}
if (i == 2) {
return ISOLATED;
}
return NORMAL;
}
}
public static class BuilderImpl
implements Group.Builder {
@Nullable
private UUID id;
private String name;
@Nullable
private String password;
private boolean persistent;
private boolean hidden;
private Group.Type type = Group.Type.NORMAL;
@Override
public Group.Builder setId(@Nullable UUID id) {
this.id = id;
return this;
}
@Override
public Group.Builder setName(String name) {
this.name = name;
this.name = BuilderImpl.convertGroupName(name);
return this;
}
private static String convertGroupName(String name) {
if ((name = name.replaceAll("[\\n\\r\\t]", "")).matches("^\\s.*")) {
name = name.replaceFirst("^\\s+", "");
}
if (name.length() > 16) {
return name.substring(0, 16);
}
return name;
}
@Override
public Group.Builder setPassword(String password) {
this.password = password;
return this;
}
@Override
public Group.Builder setPersistent(boolean persistent) {
this.persistent = persistent;
return this;
}
@Override
public Group.Builder setHidden(boolean hidden) {
this.hidden = hidden;
return this;
}
@Override
public Group.Builder setType(Group.Type type) {
this.type = type;
return this;
}
@Override
public de.maxhenkel.voicechat.api.Group build() {
if (this.name == null) {
throw new IllegalStateException("Group is missing a name");
}
if (!Voicechat.GROUP_REGEX.matcher(this.name).matches()) {
throw new IllegalStateException(String.format("Invalid group name: %s", this.name));
}
GroupImpl group = new GroupImpl(new Group(this.id == null ? UUID.randomUUID() : this.id, this.name, this.password, this.persistent, this.hidden, this.type));
Server server = Voicechat.SERVER.getServer();
if (server != null && this.persistent) {
server.getGroupManager().addGroup(group.getGroup(), null);
}
return group;
}
}
}
@@ -0,0 +1,30 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.entity.Entity
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.plugins.impl.EntityImpl;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class PlayerImpl
extends EntityImpl
implements de.maxhenkel.voicechat.api.Player {
public PlayerImpl(Player entity) {
super((Entity)entity);
}
@Override
public Object getPlayer() {
return this.entity;
}
public Player getRealPlayer() {
return (Player)this.entity;
}
}
@@ -0,0 +1,59 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.Location
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.Position;
import java.util.Objects;
import org.bukkit.Location;
public class PositionImpl
implements Position {
private final Location position;
public PositionImpl(Location position) {
this.position = position;
}
public PositionImpl(double x, double y, double z) {
this.position = new Location(null, x, y, z);
}
@Override
public double getX() {
return this.position.getX();
}
@Override
public double getY() {
return this.position.getY();
}
@Override
public double getZ() {
return this.position.getZ();
}
public Location getPosition() {
return this.position;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
PositionImpl position1 = (PositionImpl)object;
return Objects.equals(this.position, position1.position);
}
public int hashCode() {
return this.position != null ? this.position.hashCode() : 0;
}
}
@@ -0,0 +1,37 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.RawUdpPacket;
import java.net.SocketAddress;
public class RawUdpPacketImpl
implements RawUdpPacket {
private static final byte[] BUFFER = new byte[4096];
private final byte[] data;
private final SocketAddress socketAddress;
private final long timestamp;
public RawUdpPacketImpl(byte[] data, SocketAddress socketAddress, long timestamp) {
this.data = data;
this.socketAddress = socketAddress;
this.timestamp = timestamp;
}
@Override
public byte[] getData() {
return this.data;
}
@Override
public long getTimestamp() {
return this.timestamp;
}
@Override
public SocketAddress getSocketAddress() {
return this.socketAddress;
}
}
@@ -0,0 +1,41 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.World
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.ServerLevel;
import java.util.Objects;
import org.bukkit.World;
public class ServerLevelImpl
implements ServerLevel {
private final World serverLevel;
public ServerLevelImpl(World serverLevel) {
this.serverLevel = serverLevel;
}
@Override
public Object getServerLevel() {
return this.serverLevel;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
ServerLevelImpl that = (ServerLevelImpl)object;
return Objects.equals(this.serverLevel, that.serverLevel);
}
public int hashCode() {
return this.serverLevel != null ? this.serverLevel.hashCode() : 0;
}
}
@@ -0,0 +1,31 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.ServerLevel;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.plugins.impl.PlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerLevelImpl;
import org.bukkit.entity.Player;
public class ServerPlayerImpl
extends PlayerImpl
implements ServerPlayer {
public ServerPlayerImpl(Player entity) {
super(entity);
}
public Player getRealServerPlayer() {
return (Player)this.entity;
}
@Override
public ServerLevel getServerLevel() {
return new ServerLevelImpl(this.entity.getWorld());
}
}
@@ -0,0 +1,114 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
* org.bukkit.World
* org.bukkit.entity.Entity
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.Entity;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.ServerLevel;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.VoicechatApi;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.audio.AudioConverter;
import de.maxhenkel.voicechat.api.mp3.Mp3Decoder;
import de.maxhenkel.voicechat.api.mp3.Mp3Encoder;
import de.maxhenkel.voicechat.api.opus.OpusDecoder;
import de.maxhenkel.voicechat.api.opus.OpusEncoder;
import de.maxhenkel.voicechat.api.opus.OpusEncoderMode;
import de.maxhenkel.voicechat.plugins.impl.EntityImpl;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerLevelImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.VolumeCategoryImpl;
import de.maxhenkel.voicechat.plugins.impl.audio.AudioConverterImpl;
import de.maxhenkel.voicechat.plugins.impl.opus.OpusManager;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.Nullable;
import javax.sound.sampled.AudioFormat;
import org.bukkit.World;
import org.bukkit.entity.Player;
public abstract class VoicechatApiImpl
implements VoicechatApi {
private static final AudioConverter AUDIO_CONVERTER = new AudioConverterImpl();
@Override
public OpusEncoder createEncoder() {
return OpusManager.createEncoder(null);
}
@Override
public OpusEncoder createEncoder(OpusEncoderMode mode) {
return OpusManager.createEncoder(mode);
}
@Override
@Nullable
public Mp3Encoder createMp3Encoder(AudioFormat audioFormat, int bitrate, int quality, OutputStream outputStream) {
return null;
}
@Override
@Nullable
public Mp3Decoder createMp3Decoder(InputStream inputStream) {
return null;
}
@Override
public OpusDecoder createDecoder() {
return OpusManager.createDecoder();
}
@Override
public AudioConverter getAudioConverter() {
return AUDIO_CONVERTER;
}
@Override
public Entity fromEntity(Object entity) {
if (entity instanceof org.bukkit.entity.Entity) {
return new EntityImpl((org.bukkit.entity.Entity)entity);
}
throw new IllegalArgumentException("entity is not an instance of Entity");
}
@Override
public ServerLevel fromServerLevel(Object serverLevel) {
if (serverLevel instanceof World) {
return new ServerLevelImpl((World)serverLevel);
}
throw new IllegalArgumentException("serverLevel is not an instance of World");
}
@Override
public ServerPlayer fromServerPlayer(Object serverPlayer) {
if (serverPlayer instanceof Player) {
return new ServerPlayerImpl((Player)serverPlayer);
}
throw new IllegalArgumentException("serverPlayer is not an instance of Player");
}
@Override
public Position createPosition(double x, double y, double z) {
return new PositionImpl(x, y, z);
}
@Override
public VolumeCategory.Builder volumeCategoryBuilder() {
return new VolumeCategoryImpl.BuilderImpl();
}
@Override
public double getVoiceChatDistance() {
return Utils.getDefaultDistance();
}
}
@@ -0,0 +1,147 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.plugins.impl.GroupImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.voice.common.PlayerState;
import de.maxhenkel.voicechat.voice.server.Group;
import de.maxhenkel.voicechat.voice.server.PlayerStateManager;
import de.maxhenkel.voicechat.voice.server.Server;
import javax.annotation.Nullable;
import org.bukkit.entity.Player;
public class VoicechatConnectionImpl
implements VoicechatConnection {
private final ServerPlayer player;
private final Player serverPlayer;
private final PlayerState state;
@Nullable
private final de.maxhenkel.voicechat.api.Group group;
public VoicechatConnectionImpl(Player player, PlayerState state) {
this.serverPlayer = player;
this.player = new ServerPlayerImpl(player);
this.state = state;
this.group = GroupImpl.create(state);
}
@Nullable
public static VoicechatConnectionImpl fromPlayer(@Nullable Player player) {
if (player == null) {
return null;
}
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
PlayerState state = server.getPlayerStateManager().getState(player.getUniqueId());
if (state == null) {
return null;
}
return new VoicechatConnectionImpl(player, state);
}
@Override
@Nullable
public de.maxhenkel.voicechat.api.Group getGroup() {
return this.group;
}
@Override
public boolean isInGroup() {
return this.group != null;
}
@Override
public void setGroup(@Nullable de.maxhenkel.voicechat.api.Group group) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
if (group == null) {
server.getGroupManager().leaveGroup((Player)this.player.getPlayer());
return;
}
if (group instanceof GroupImpl) {
GroupImpl g = (GroupImpl)group;
Group actualGroup = server.getGroupManager().getGroup(g.getGroup().getId());
if (actualGroup == null) {
server.getGroupManager().addGroup(g.getGroup(), this.serverPlayer);
actualGroup = g.getGroup();
}
server.getGroupManager().joinGroup(actualGroup, this.serverPlayer, g.getGroup().getPassword());
}
}
@Override
public boolean isConnected() {
return !this.state.isDisconnected();
}
@Override
public void setConnected(boolean connected) {
if (this.isInstalled()) {
return;
}
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
PlayerStateManager manager = server.getPlayerStateManager();
PlayerState actualState = manager.getState(this.state.getUuid());
if (actualState == null) {
return;
}
if (actualState.isDisconnected() != connected) {
return;
}
actualState.setDisconnected(!connected);
manager.broadcastState(null, actualState);
}
@Override
public boolean isDisabled() {
return this.state.isDisabled();
}
@Override
public void setDisabled(boolean disabled) {
if (this.isInstalled()) {
return;
}
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
PlayerStateManager manager = server.getPlayerStateManager();
PlayerState actualState = manager.getState(this.state.getUuid());
if (actualState == null) {
return;
}
if (actualState.isDisabled() == disabled) {
return;
}
actualState.setDisabled(disabled);
manager.broadcastState(null, actualState);
}
@Override
public boolean isInstalled() {
return Voicechat.SERVER.isCompatible(this.serverPlayer);
}
@Override
public ServerPlayer getPlayer() {
return this.player;
}
}
@@ -0,0 +1,336 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
* org.bukkit.Bukkit
* org.bukkit.World
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.Entity;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.ServerLevel;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.VoicechatServerApi;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
import de.maxhenkel.voicechat.api.audiochannel.EntityAudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.StaticAudioChannel;
import de.maxhenkel.voicechat.api.audiolistener.AudioListener;
import de.maxhenkel.voicechat.api.audiolistener.PlayerAudioListener;
import de.maxhenkel.voicechat.api.audiosender.AudioSender;
import de.maxhenkel.voicechat.api.config.ConfigAccessor;
import de.maxhenkel.voicechat.api.opus.OpusEncoder;
import de.maxhenkel.voicechat.api.packets.ConvertablePacket;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.PluginManager;
import de.maxhenkel.voicechat.plugins.impl.GroupImpl;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.VoicechatApiImpl;
import de.maxhenkel.voicechat.plugins.impl.VoicechatConnectionImpl;
import de.maxhenkel.voicechat.plugins.impl.VolumeCategoryImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.AudioPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.AudioSupplier;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.EntityAudioChannelImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.LocationalAudioChannelImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.StaticAudioChannelImpl;
import de.maxhenkel.voicechat.plugins.impl.audiolistener.PlayerAudioListenerImpl;
import de.maxhenkel.voicechat.plugins.impl.audiosender.AudioSenderImpl;
import de.maxhenkel.voicechat.plugins.impl.config.ConfigAccessorImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.ConvertablePacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.EntitySoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.LocationalSoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.StaticSoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.PlayerState;
import de.maxhenkel.voicechat.voice.common.SoundPacket;
import de.maxhenkel.voicechat.voice.server.ClientConnection;
import de.maxhenkel.voicechat.voice.server.Group;
import de.maxhenkel.voicechat.voice.server.Server;
import de.maxhenkel.voicechat.voice.server.ServerPlayerManager;
import java.util.Collection;
import java.util.Collections;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class VoicechatServerApiImpl
extends VoicechatApiImpl
implements VoicechatServerApi {
private static final VoicechatServerApiImpl INSTANCE = new VoicechatServerApiImpl();
private VoicechatServerApiImpl() {
}
public static VoicechatServerApiImpl instance() {
return INSTANCE;
}
@Override
public void sendEntitySoundPacketTo(VoicechatConnection connection, EntitySoundPacket p) {
if (p instanceof EntitySoundPacketImpl) {
VoicechatServerApiImpl.sendPacket(connection, ((EntitySoundPacketImpl)p).getPacket());
}
}
@Override
public void sendLocationalSoundPacketTo(VoicechatConnection connection, LocationalSoundPacket p) {
if (p instanceof LocationalSoundPacketImpl) {
VoicechatServerApiImpl.sendPacket(connection, ((LocationalSoundPacketImpl)p).getPacket());
}
}
@Override
public void sendStaticSoundPacketTo(VoicechatConnection connection, StaticSoundPacket p) {
if (p instanceof StaticSoundPacketImpl) {
VoicechatServerApiImpl.sendPacket(connection, ((StaticSoundPacketImpl)p).getPacket());
}
}
@Override
public ConvertablePacket createPacket() {
return new ConvertablePacketImpl();
}
@Override
@Nullable
public EntityAudioChannel createEntityAudioChannel(UUID channelId, Entity entity) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
return new EntityAudioChannelImpl(channelId, server, entity);
}
@Override
@Nullable
public LocationalAudioChannel createLocationalAudioChannel(UUID channelId, ServerLevel level, Position initialPosition) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
if (initialPosition instanceof PositionImpl) {
return new LocationalAudioChannelImpl(channelId, server, level, (PositionImpl)initialPosition);
}
throw new IllegalArgumentException("initialPosition is not an instance of PositionImpl");
}
@Override
@Nullable
public StaticAudioChannel createStaticAudioChannel(UUID channelId, ServerLevel level, VoicechatConnection connection) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
StaticAudioChannelImpl staticAudioChannel = new StaticAudioChannelImpl(channelId, server);
staticAudioChannel.addTarget(connection);
return staticAudioChannel;
}
@Override
@Nullable
public StaticAudioChannel createStaticAudioChannel(UUID channelId) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
return new StaticAudioChannelImpl(channelId, server);
}
@Override
public AudioPlayer createAudioPlayer(AudioChannel audioChannel, OpusEncoder encoder, Supplier<short[]> audioSupplier) {
return new AudioPlayerImpl(audioChannel, encoder, audioSupplier);
}
@Override
public AudioPlayer createAudioPlayer(AudioChannel audioChannel, OpusEncoder encoder, short[] audio) {
return new AudioPlayerImpl(audioChannel, encoder, new AudioSupplier(audio));
}
@Override
public AudioSender createAudioSender(VoicechatConnection connection) {
return new AudioSenderImpl(connection.getPlayer().getUuid());
}
@Override
public boolean registerAudioSender(AudioSender sender) {
if (!(sender instanceof AudioSenderImpl)) {
return false;
}
return AudioSenderImpl.registerAudioSender((AudioSenderImpl)sender);
}
@Override
public boolean unregisterAudioSender(AudioSender sender) {
if (!(sender instanceof AudioSenderImpl)) {
return false;
}
return AudioSenderImpl.unregisterAudioSender((AudioSenderImpl)sender);
}
@Override
public PlayerAudioListener.Builder playerAudioListenerBuilder() {
return new PlayerAudioListenerImpl.BuilderImpl();
}
@Override
public boolean registerAudioListener(AudioListener listener) {
return PluginManager.instance().registerAudioListener(listener);
}
@Override
public boolean unregisterAudioListener(AudioListener listener) {
return this.unregisterAudioListener(listener.getListenerId());
}
@Override
public boolean unregisterAudioListener(UUID listenerId) {
return PluginManager.instance().unregisterAudioListener(listenerId);
}
public static void sendPacket(VoicechatConnection receiver, SoundPacket<?> soundPacket) {
if (!(receiver.getPlayer() instanceof ServerPlayerImpl)) {
throw new IllegalArgumentException("ServerPlayer is not an instance of ServerPlayerImpl");
}
VoicechatServerApiImpl.sendPacket(((ServerPlayerImpl)receiver.getPlayer()).getRealServerPlayer(), soundPacket);
}
public static void sendPacket(Player receiver, SoundPacket<?> soundPacket) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
PlayerState state = server.getPlayerStateManager().getState(receiver.getUniqueId());
if (state == null) {
return;
}
ClientConnection c = server.getConnections().get(receiver.getUniqueId());
server.sendSoundPacket(null, null, receiver, state, c, soundPacket, "plugin");
}
@Override
@Nullable
public VoicechatConnection getConnectionOf(UUID playerUuid) {
Player player = Bukkit.getPlayer((UUID)playerUuid);
if (player == null) {
return null;
}
return VoicechatConnectionImpl.fromPlayer(player);
}
@Override
public de.maxhenkel.voicechat.api.Group createGroup(String name, @Nullable String password) {
return this.createGroup(name, password, false);
}
@Override
public de.maxhenkel.voicechat.api.Group createGroup(String name, @Nullable String password, boolean persistent) {
return this.groupBuilder().setName(name).setPassword(password).setPersistent(persistent).build();
}
@Override
public Group.Builder groupBuilder() {
return new GroupImpl.BuilderImpl();
}
@Override
public boolean removeGroup(UUID groupId) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return false;
}
return server.getGroupManager().removeGroup(groupId);
}
@Override
@Nullable
public de.maxhenkel.voicechat.api.Group getGroup(UUID groupId) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return null;
}
return new GroupImpl(server.getGroupManager().getGroup(groupId));
}
@Override
public Collection<de.maxhenkel.voicechat.api.Group> getGroups() {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return Collections.emptyList();
}
return server.getGroupManager().getGroups().values().stream().map(group -> new GroupImpl((Group)group)).collect(Collectors.toList());
}
@Override
@Nullable
public UUID getSecret(UUID userId) {
return null;
}
@Override
public Collection<ServerPlayer> getPlayersInRange(ServerLevel level, Position pos, double range, @Nullable Predicate<ServerPlayer> filter) {
if (pos instanceof PositionImpl) {
return ServerPlayerManager.getPlayersInRange((World)level.getServerLevel(), ((PositionImpl)pos).getPosition(), range, filter == null ? null : player -> filter.test(new ServerPlayerImpl((Player)player))).stream().map(ServerPlayerImpl::new).collect(Collectors.toList());
}
throw new IllegalArgumentException("Position is not an instance of PositionImpl");
}
@Override
public double getBroadcastRange() {
return Math.max(Voicechat.SERVER_CONFIG.voiceChatDistance.get(), Voicechat.SERVER_CONFIG.broadcastRange.get());
}
@Override
public void registerVolumeCategory(VolumeCategory category) {
if (!(category instanceof VolumeCategoryImpl)) {
throw new IllegalArgumentException("VolumeCategory is not an instance of VolumeCategoryImpl");
}
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
server.getCategoryManager().addCategory((VolumeCategoryImpl)category);
PluginManager.instance().onRegisterVolumeCategory(category);
}
@Override
public void unregisterVolumeCategory(String categoryId) {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return;
}
VolumeCategoryImpl category = server.getCategoryManager().removeCategory(categoryId);
if (category != null) {
PluginManager.instance().onUnregisterVolumeCategory(category);
}
}
@Override
public Collection<VolumeCategory> getVolumeCategories() {
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return Collections.emptyList();
}
return server.getCategoryManager().getCategories().stream().map(VolumeCategory.class::cast).collect(Collectors.toList());
}
@Override
public ConfigAccessor getServerConfig() {
return new ConfigAccessorImpl(Voicechat.SERVER_CONFIG.voiceChatDistance.getConfig());
}
}
@@ -0,0 +1,29 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.debug.CooldownTimer;
import de.maxhenkel.voicechat.plugins.impl.RawUdpPacketImpl;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class VoicechatSocketBase {
private final byte[] BUFFER = new byte[4096];
public RawUdpPacketImpl read(DatagramSocket socket) throws IOException {
DatagramPacket packet = new DatagramPacket(this.BUFFER, this.BUFFER.length);
socket.receive(packet);
if (packet.getLength() >= this.BUFFER.length) {
CooldownTimer.run("udp_packet_too_large", () -> Voicechat.LOGGER.warn("Packet from {} is too large", packet.getSocketAddress()));
throw new IOException(String.format("Packet from %s is too large", packet.getSocketAddress()));
}
long timestamp = System.currentTimeMillis();
byte[] data = new byte[packet.getLength()];
System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());
return new RawUdpPacketImpl(data, packet.getSocketAddress(), timestamp);
}
}
@@ -0,0 +1,138 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.Bukkit
* org.bukkit.plugin.Plugin
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.RawUdpPacket;
import de.maxhenkel.voicechat.api.VoicechatSocket;
import de.maxhenkel.voicechat.plugins.impl.VoicechatSocketBase;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
public class VoicechatSocketImpl
extends VoicechatSocketBase
implements VoicechatSocket {
private DatagramSocket socket;
@Override
public void open(int port, String bindAddress) throws Exception {
if (this.socket != null) {
throw new IllegalStateException("Socket already opened");
}
this.checkCorrectHost();
InetAddress address = null;
try {
if (!bindAddress.isEmpty()) {
address = InetAddress.getByName(bindAddress);
}
}
catch (Exception e) {
bindAddress = "";
Voicechat.LOGGER.error("Failed to parse bind IP address '{}'", bindAddress, e);
}
try {
try {
this.socket = new DatagramSocket(port, address);
}
catch (BindException e) {
if (address == null || bindAddress.equals("0.0.0.0")) {
throw e;
}
Voicechat.LOGGER.error("Failed to bind to address '{}', binding to wildcard IP instead", bindAddress);
this.socket = new DatagramSocket(port);
}
this.socket.setTrafficClass(4);
}
catch (BindException e) {
Voicechat.LOGGER.fatal("Failed to run voice chat at UDP port {}, make sure no other application is running at that port", port);
Bukkit.getScheduler().runTask((Plugin)Voicechat.INSTANCE, () -> {
Voicechat.LOGGER.fatal("Disabling {}", "Simple Voice Chat");
Bukkit.getPluginManager().disablePlugin((Plugin)Voicechat.INSTANCE);
});
throw e;
}
}
private void checkCorrectHost() throws Exception {
String host = Voicechat.SERVER_CONFIG.voiceHost.get();
if (host.isEmpty()) {
return;
}
try {
int port = Integer.parseInt(host);
if (port <= 0 || port > 65535) {
Voicechat.LOGGER.warn("Invalid voice host port: {}", port);
} else {
Voicechat.LOGGER.info("Voice host port is {}", port);
}
}
catch (NumberFormatException ignored) {
try {
new URI("voicechat://" + host);
Voicechat.LOGGER.info("Voice host is '{}'", host);
}
catch (URISyntaxException e) {
Voicechat.LOGGER.warn("Failed to parse voice host", e);
Bukkit.shutdown();
throw e;
}
}
}
@Override
public RawUdpPacket read() throws Exception {
if (this.socket == null) {
throw new IllegalStateException("Socket not opened yet");
}
return this.read(this.socket);
}
@Override
public void send(byte[] data, SocketAddress address) throws Exception {
if (this.socket == null || this.socket.isClosed()) {
return;
}
this.socket.send(new DatagramPacket(data, data.length, address));
}
@Override
public int getLocalPort() {
if (this.socket == null) {
return -1;
}
return this.socket.getLocalPort();
}
@Override
public void close() {
if (this.socket != null) {
try {
this.socket.close();
}
catch (Throwable throwable) {
// empty catch block
}
}
}
@Override
public boolean isClosed() {
if (this.socket == null) {
return true;
}
return this.socket.isClosed();
}
}
@@ -0,0 +1,205 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.util.FriendlyByteBuf;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
public class VolumeCategoryImpl
implements VolumeCategory {
public static final Pattern ID_REGEX = Pattern.compile("^[a-z_]{1,16}$");
private final String id;
private final String name;
@Nullable
private final String nameTranslationKey;
@Nullable
private final String description;
@Nullable
private final String descriptionTranslationKey;
@Nullable
private final int[][] icon;
public VolumeCategoryImpl(String id, String name, @Nullable String nameTranslationKey, @Nullable String description, @Nullable String descriptionTranslationKey, @Nullable int[][] icon) {
if (!ID_REGEX.matcher(id).matches()) {
throw new IllegalArgumentException("Volume category ID can only contain a-z and _ with a maximum amount of 16 characters");
}
this.id = id;
this.name = name;
this.nameTranslationKey = nameTranslationKey;
this.description = description;
this.descriptionTranslationKey = descriptionTranslationKey;
this.icon = icon;
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
@Override
@Nullable
public String getNameTranslationKey() {
return this.nameTranslationKey;
}
@Override
@Nullable
public String getDescription() {
return this.description;
}
@Override
@Nullable
public String getDescriptionTranslationKey() {
return this.descriptionTranslationKey;
}
@Override
@Nullable
public int[][] getIcon() {
return this.icon;
}
public static VolumeCategoryImpl fromBytes(FriendlyByteBuf buf) {
String id = buf.readUtf(16);
String name = buf.readUtf(16);
String nameTranslationKey = VolumeCategoryImpl.readOptionalString(buf);
String description = VolumeCategoryImpl.readOptionalString(buf);
String descriptionTranslationKey = VolumeCategoryImpl.readOptionalString(buf);
int[][] icon = null;
if (buf.readBoolean()) {
icon = new int[16][16];
for (int x = 0; x < icon.length; ++x) {
for (int y = 0; y < icon.length; ++y) {
icon[x][y] = buf.readInt();
}
}
}
return new VolumeCategoryImpl(id, name, nameTranslationKey, description, descriptionTranslationKey, icon);
}
@Nullable
private static String readOptionalString(FriendlyByteBuf buf) {
if (buf.readBoolean()) {
return buf.readUtf(Short.MAX_VALUE);
}
return null;
}
public void toBytes(FriendlyByteBuf buf) {
buf.writeUtf(this.id, 16);
buf.writeUtf(this.name, 16);
VolumeCategoryImpl.writeOptionalString(buf, this.nameTranslationKey);
VolumeCategoryImpl.writeOptionalString(buf, this.description);
VolumeCategoryImpl.writeOptionalString(buf, this.descriptionTranslationKey);
buf.writeBoolean(this.icon != null);
if (this.icon != null) {
if (this.icon.length != 16) {
throw new IllegalStateException("Icon is not 16x16");
}
for (int x = 0; x < this.icon.length; ++x) {
if (this.icon[x].length != 16) {
throw new IllegalStateException("Icon is not 16x16");
}
for (int y = 0; y < this.icon.length; ++y) {
buf.writeInt(this.icon[x][y]);
}
}
}
}
private static void writeOptionalString(FriendlyByteBuf buf, @Nullable String string) {
buf.writeBoolean(string != null);
if (string != null) {
buf.writeUtf(string, Short.MAX_VALUE);
}
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
VolumeCategoryImpl that = (VolumeCategoryImpl)object;
return this.id.equals(that.id);
}
public int hashCode() {
return this.id.hashCode();
}
public static class BuilderImpl
implements VolumeCategory.Builder {
private String id;
private String name;
@Nullable
private String nameTranslationKey;
@Nullable
private String description;
@Nullable
private String descriptionTranslationKey;
@Nullable
private int[][] icon;
@Override
public VolumeCategory.Builder setId(String id) {
this.id = id;
return this;
}
@Override
public VolumeCategory.Builder setName(String name) {
this.name = name;
return this;
}
@Override
public VolumeCategory.Builder setNameTranslationKey(@Nullable String translationKey) {
this.nameTranslationKey = translationKey;
return this;
}
@Override
public VolumeCategory.Builder setDescription(@Nullable String description) {
this.description = description;
return this;
}
@Override
public VolumeCategory.Builder setDescriptionTranslationKey(@Nullable String translationKey) {
this.descriptionTranslationKey = translationKey;
return this;
}
@Override
public VolumeCategory.Builder setIcon(@Nullable int[][] icon) {
this.icon = icon;
return this;
}
@Override
public VolumeCategory build() {
if (this.id == null) {
throw new IllegalStateException("id missing");
}
if (this.name == null) {
throw new IllegalStateException("name missing");
}
return new VolumeCategoryImpl(this.id, this.name, this.nameTranslationKey, this.description, this.descriptionTranslationKey, this.icon);
}
}
}
@@ -0,0 +1,41 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.audio;
import de.maxhenkel.voicechat.api.audio.AudioConverter;
import de.maxhenkel.voicechat.voice.common.AudioUtils;
public class AudioConverterImpl
implements AudioConverter {
@Override
public short[] bytesToShorts(byte[] bytes) {
return AudioUtils.bytesToShorts(bytes);
}
@Override
public byte[] shortsToBytes(short[] shorts) {
return AudioUtils.shortsToBytes(shorts);
}
@Override
public short[] floatsToShorts(float[] floats) {
return AudioUtils.floatsToShorts(floats);
}
@Override
public float[] shortsToFloats(short[] shorts) {
return AudioUtils.shortsToFloats(shorts);
}
@Override
public byte[] floatsToBytes(float[] floats) {
return AudioUtils.floatsToBytes(floats);
}
@Override
public float[] bytesToFloats(byte[] bytes) {
return AudioUtils.bytesToFloats(bytes);
}
}
@@ -0,0 +1,59 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import de.maxhenkel.voicechat.voice.server.Server;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Predicate;
import javax.annotation.Nullable;
public abstract class AudioChannelImpl
implements AudioChannel {
protected UUID channelId;
protected Server server;
protected AtomicLong sequenceNumber;
@Nullable
protected Predicate<ServerPlayer> filter;
@Nullable
protected String category;
public AudioChannelImpl(UUID channelId, Server server) {
this.channelId = channelId;
this.server = server;
this.sequenceNumber = new AtomicLong();
}
@Override
public void setFilter(Predicate<ServerPlayer> filter) {
this.filter = filter;
}
@Override
public UUID getId() {
return this.channelId;
}
@Override
public boolean isClosed() {
return this.server.isClosed();
}
@Override
@Nullable
public String getCategory() {
return this.category;
}
@Override
public void setCategory(@Nullable String category) {
this.category = category;
}
}
@@ -0,0 +1,102 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nonnull
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
import de.maxhenkel.voicechat.api.opus.OpusEncoder;
import de.maxhenkel.voicechat.debug.VoicechatUncaughtExceptionHandler;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class AudioPlayerImpl
extends Thread
implements AudioPlayer {
private static final long FRAME_SIZE_NS = 20000000L;
public static final int FRAME_SIZE = 960;
private final AudioChannel audioChannel;
private final OpusEncoder encoder;
private final Supplier<short[]> audioSupplier;
private boolean started;
@Nullable
private Runnable onStopped;
public AudioPlayerImpl(AudioChannel audioChannel, @Nonnull OpusEncoder encoder, Supplier<short[]> audioSupplier) {
this.audioChannel = audioChannel;
this.encoder = encoder;
this.audioSupplier = audioSupplier;
this.setDaemon(true);
this.setName(String.format("AudioPlayer-%s", audioChannel.getId()));
this.setUncaughtExceptionHandler(new VoicechatUncaughtExceptionHandler());
}
@Override
public void startPlaying() {
if (this.started) {
return;
}
this.start();
this.started = true;
}
@Override
public void stopPlaying() {
this.interrupt();
}
@Override
public boolean isStarted() {
return this.started;
}
@Override
public boolean isPlaying() {
return this.isAlive();
}
@Override
public boolean isStopped() {
return this.started && !this.isAlive();
}
@Override
public void setOnStopped(Runnable onStopped) {
this.onStopped = onStopped;
}
@Override
public void run() {
short[] frame;
int framePosition = 0;
long startTime = System.nanoTime();
while ((frame = this.audioSupplier.get()) != null) {
if (frame.length != 960) {
Voicechat.LOGGER.error("Got invalid audio frame size {}!={}", frame.length, 960);
break;
}
this.audioChannel.send(this.encoder.encode(frame));
long waitTimestamp = startTime + (long)(++framePosition) * 20000000L;
long waitNanos = waitTimestamp - System.nanoTime();
try {
if (waitNanos <= 0L) continue;
Thread.sleep(waitNanos / 1000000L, (int)(waitNanos % 1000000L));
}
catch (InterruptedException e) {
break;
}
}
this.encoder.close();
this.audioChannel.flush();
if (this.onStopped != null) {
this.onStopped.run();
}
}
}
@@ -0,0 +1,31 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import java.util.Arrays;
import java.util.function.Supplier;
public class AudioSupplier
implements Supplier<short[]> {
private final short[] audioData;
private final short[] frame;
private int framePosition;
public AudioSupplier(short[] audioData) {
this.audioData = audioData;
this.frame = new short[960];
}
@Override
public short[] get() {
if (this.framePosition >= this.audioData.length) {
return null;
}
Arrays.fill(this.frame, (short)0);
System.arraycopy(this.audioData, this.framePosition, this.frame, 0, Math.min(this.frame.length, this.audioData.length - this.framePosition));
this.framePosition += this.frame.length;
return this.frame;
}
}
@@ -0,0 +1,88 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.entity.Entity
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.api.Entity;
import de.maxhenkel.voicechat.api.audiochannel.EntityAudioChannel;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.AudioChannelImpl;
import de.maxhenkel.voicechat.voice.common.PlayerSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import de.maxhenkel.voicechat.voice.server.Server;
import de.maxhenkel.voicechat.voice.server.ServerPlayerManager;
import java.util.UUID;
import org.bukkit.entity.Player;
public class EntityAudioChannelImpl
extends AudioChannelImpl
implements EntityAudioChannel {
protected Entity entity;
protected boolean whispering;
protected float distance;
public EntityAudioChannelImpl(UUID channelId, Server server, Entity entity) {
super(channelId, server);
this.entity = entity;
this.whispering = false;
this.distance = Utils.getDefaultDistance();
}
@Override
public void setWhispering(boolean whispering) {
this.whispering = whispering;
}
@Override
public boolean isWhispering() {
return this.whispering;
}
@Override
public void updateEntity(Entity entity) {
this.entity = entity;
}
@Override
public Entity getEntity() {
return this.entity;
}
@Override
public float getDistance() {
return this.distance;
}
@Override
public void setDistance(float distance) {
this.distance = distance;
}
@Override
public void send(byte[] opusData) {
this.broadcast(new PlayerSoundPacket(this.channelId, this.entity.getUuid(), opusData, this.sequenceNumber.getAndIncrement(), this.whispering, this.distance, this.category));
}
@Override
public void send(MicrophonePacket microphonePacket) {
this.broadcast(new PlayerSoundPacket(this.channelId, this.entity.getUuid(), microphonePacket.getOpusEncodedData(), this.sequenceNumber.getAndIncrement(), this.whispering, this.distance, this.category));
}
@Override
public void flush() {
this.broadcast(new PlayerSoundPacket(this.channelId, this.entity.getUuid(), new byte[0], this.sequenceNumber.getAndIncrement(), this.whispering, this.distance, this.category));
}
private void broadcast(PlayerSoundPacket packet) {
if (this.entity.getEntity() instanceof org.bukkit.entity.Entity) {
org.bukkit.entity.Entity entity = (org.bukkit.entity.Entity)this.entity.getEntity();
this.server.broadcast(ServerPlayerManager.getPlayersInRange(entity.getWorld(), entity.getLocation(), this.server.getBroadcastRange(this.distance), this.filter == null ? null : player -> this.filter.test(new ServerPlayerImpl((Player)player))), packet, null, null, null, "plugin");
}
}
}
@@ -0,0 +1,81 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.World
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.ServerLevel;
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.AudioChannelImpl;
import de.maxhenkel.voicechat.voice.common.LocationSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import de.maxhenkel.voicechat.voice.server.Server;
import de.maxhenkel.voicechat.voice.server.ServerPlayerManager;
import java.util.UUID;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class LocationalAudioChannelImpl
extends AudioChannelImpl
implements LocationalAudioChannel {
protected ServerLevel level;
protected PositionImpl position;
protected float distance;
public LocationalAudioChannelImpl(UUID channelId, Server server, ServerLevel level, PositionImpl position) {
super(channelId, server);
this.level = level;
this.position = position;
this.distance = Utils.getDefaultDistance();
}
@Override
public void updateLocation(Position position) {
if (!(position instanceof PositionImpl)) {
throw new IllegalArgumentException("position is not an instance of PositionImpl");
}
this.position = (PositionImpl)position;
}
@Override
public Position getLocation() {
return this.position;
}
@Override
public float getDistance() {
return this.distance;
}
@Override
public void setDistance(float distance) {
this.distance = distance;
}
@Override
public void send(byte[] opusData) {
this.broadcast(new LocationSoundPacket(this.channelId, this.channelId, this.position.getPosition(), opusData, this.sequenceNumber.getAndIncrement(), this.distance, this.category));
}
@Override
public void send(MicrophonePacket packet) {
this.send(packet.getOpusEncodedData());
}
@Override
public void flush() {
this.broadcast(new LocationSoundPacket(this.channelId, this.channelId, this.position.getPosition(), new byte[0], this.sequenceNumber.getAndIncrement(), this.distance, this.category));
}
private void broadcast(LocationSoundPacket packet) {
this.server.broadcast(ServerPlayerManager.getPlayersInRange((World)this.level.getServerLevel(), this.position.getPosition(), this.server.getBroadcastRange(this.distance), this.filter == null ? null : player -> this.filter.test(new ServerPlayerImpl((Player)player))), packet, null, null, null, "plugin");
}
}
@@ -0,0 +1,113 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.Bukkit
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.audiochannel.StaticAudioChannel;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.VoicechatServerApiImpl;
import de.maxhenkel.voicechat.plugins.impl.audiochannel.AudioChannelImpl;
import de.maxhenkel.voicechat.voice.common.GroupSoundPacket;
import de.maxhenkel.voicechat.voice.server.ClientConnection;
import de.maxhenkel.voicechat.voice.server.Group;
import de.maxhenkel.voicechat.voice.server.Server;
import de.maxhenkel.voicechat.voice.server.ServerGroupManager;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class StaticAudioChannelImpl
extends AudioChannelImpl
implements StaticAudioChannel {
protected boolean bypassGroupIsolation;
protected final Set<UUID> targets = new HashSet<UUID>();
public StaticAudioChannelImpl(UUID channelId, Server server) {
super(channelId, server);
}
@Override
public void send(byte[] opusData) {
this.broadcast(new GroupSoundPacket(this.channelId, this.channelId, opusData, this.sequenceNumber.getAndIncrement(), this.category));
}
@Override
public void send(MicrophonePacket packet) {
this.send(packet.getOpusEncodedData());
}
@Override
public void flush() {
GroupSoundPacket packet = new GroupSoundPacket(this.channelId, this.channelId, new byte[0], this.sequenceNumber.getAndIncrement(), this.category);
this.broadcast(packet);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
private void broadcast(GroupSoundPacket packet) {
Set<UUID> set = this.targets;
synchronized (set) {
ServerGroupManager groupManager = this.server.getGroupManager();
for (UUID target : this.targets) {
Group playerGroup;
Player player;
ClientConnection connection = this.server.getConnection(target);
if (connection == null || (player = Bukkit.getPlayer((UUID)target)) == null || !this.bypassGroupIsolation && (playerGroup = groupManager.getPlayerGroup(player)) != null && playerGroup.isIsolated() || this.filter != null && !this.filter.test(new ServerPlayerImpl(player))) continue;
VoicechatServerApiImpl.sendPacket(player, packet);
}
}
}
@Override
public void setBypassGroupIsolation(boolean bypassGroupIsolation) {
this.bypassGroupIsolation = bypassGroupIsolation;
}
@Override
public boolean bypassesGroupIsolation() {
return this.bypassGroupIsolation;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
@Override
public void addTarget(VoicechatConnection target) {
Set<UUID> set = this.targets;
synchronized (set) {
this.targets.add(target.getPlayer().getUuid());
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
@Override
public void removeTarget(VoicechatConnection target) {
Set<UUID> set = this.targets;
synchronized (set) {
this.targets.remove(target.getPlayer().getUuid());
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
@Override
public void clearTargets() {
Set<UUID> set = this.targets;
synchronized (set) {
this.targets.clear();
}
}
}
@@ -0,0 +1,79 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.audiolistener;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.audiolistener.PlayerAudioListener;
import de.maxhenkel.voicechat.api.packets.SoundPacket;
import java.util.UUID;
import java.util.function.Consumer;
import javax.annotation.Nullable;
public class PlayerAudioListenerImpl
implements PlayerAudioListener {
private final UUID playerUuid;
private final Consumer<SoundPacket> listener;
private final UUID listenerId;
public PlayerAudioListenerImpl(UUID playerUuid, Consumer<SoundPacket> listener) {
this.playerUuid = playerUuid;
this.listener = listener;
this.listenerId = UUID.randomUUID();
}
@Override
public UUID getListenerId() {
return this.listenerId;
}
@Override
public UUID getPlayerUuid() {
return this.playerUuid;
}
public Consumer<SoundPacket> getListener() {
return this.listener;
}
public static class BuilderImpl
implements PlayerAudioListener.Builder {
@Nullable
private UUID playerUuid;
@Nullable
private Consumer<SoundPacket> listener;
@Override
public PlayerAudioListener.Builder setPlayer(ServerPlayer player) {
this.playerUuid = player.getUuid();
return this;
}
@Override
public PlayerAudioListener.Builder setPlayer(UUID playerUuid) {
this.playerUuid = playerUuid;
return this;
}
@Override
public PlayerAudioListener.Builder setPacketListener(Consumer<SoundPacket> listener) {
this.listener = listener;
return this;
}
@Override
public PlayerAudioListener build() {
if (this.playerUuid == null) {
throw new IllegalStateException("No player provided");
}
if (this.listener == null) {
throw new IllegalStateException("No listener provided");
}
return new PlayerAudioListenerImpl(this.playerUuid, this.listener);
}
}
}
@@ -0,0 +1,99 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.audiosender;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.audiosender.AudioSender;
import de.maxhenkel.voicechat.voice.common.MicPacket;
import de.maxhenkel.voicechat.voice.server.Server;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class AudioSenderImpl
implements AudioSender {
private static final Map<UUID, AudioSenderImpl> AUDIO_SENDERS = new HashMap<UUID, AudioSenderImpl>();
private final UUID uuid;
private boolean whispering;
private long nextSequenceNumber;
public AudioSenderImpl(UUID uuid) {
this.uuid = uuid;
}
public static boolean registerAudioSender(AudioSenderImpl audioSender) {
if (Voicechat.SERVER.isCompatible(audioSender.uuid)) {
return false;
}
if (AUDIO_SENDERS.containsKey(audioSender.uuid)) {
return false;
}
AUDIO_SENDERS.put(audioSender.uuid, audioSender);
return true;
}
public static boolean unregisterAudioSender(AudioSenderImpl audioSender) {
return AUDIO_SENDERS.remove(audioSender.uuid) != null;
}
@Override
public AudioSender whispering(boolean whispering) {
this.whispering = whispering;
return this;
}
@Override
public boolean isWhispering() {
return this.whispering;
}
@Override
public AudioSender sequenceNumber(long sequenceNumber) {
if (sequenceNumber < 0L) {
throw new IllegalArgumentException("Sequence number must be positive");
}
this.nextSequenceNumber = sequenceNumber;
return this;
}
@Override
public boolean canSend() {
return !Voicechat.SERVER.isCompatible(this.uuid) && AUDIO_SENDERS.get(this.uuid) == this;
}
@Override
public boolean send(byte[] opusEncodedAudioData) {
return this.sendMicrophonePacket(opusEncodedAudioData);
}
@Override
public boolean reset() {
return this.sendMicrophonePacket(new byte[0]);
}
public boolean sendMicrophonePacket(byte[] data) {
if (data == null) {
throw new IllegalStateException("opusEncodedData is not set");
}
if (!this.canSend()) {
return false;
}
Server server = Voicechat.SERVER.getServer();
if (server == null) {
return true;
}
try {
MicPacket packet = new MicPacket(data, data.length > 0 && this.whispering, this.nextSequenceNumber++);
if (data.length <= 0) {
this.nextSequenceNumber = 0L;
}
server.onMicPacket(this.uuid, packet);
}
catch (Exception e) {
Voicechat.LOGGER.error("Failed to send audio", e);
}
return true;
}
}
@@ -0,0 +1,32 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.config;
import de.maxhenkel.voicechat.api.config.ConfigAccessor;
import de.maxhenkel.voicechat.configbuilder.Config;
import javax.annotation.Nullable;
public class ConfigAccessorImpl
implements ConfigAccessor {
private Config config;
public ConfigAccessorImpl(Config config) {
this.config = config;
}
@Override
public boolean hasKey(String key) {
return this.config.getEntries().containsKey(key);
}
@Override
@Nullable
public String getValue(String key) {
return this.config.getEntries().get(key);
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.CreateGroupEvent;
import de.maxhenkel.voicechat.plugins.impl.events.GroupEventImpl;
import javax.annotation.Nullable;
public class CreateGroupEventImpl
extends GroupEventImpl
implements CreateGroupEvent {
public CreateGroupEventImpl(Group group, @Nullable VoicechatConnection connection) {
super(group, connection);
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.EntitySoundPacketEvent;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.plugins.impl.events.SoundPacketEventImpl;
import javax.annotation.Nullable;
public class EntitySoundPacketEventImpl
extends SoundPacketEventImpl<EntitySoundPacket>
implements EntitySoundPacketEvent {
public EntitySoundPacketEventImpl(EntitySoundPacket packet, @Nullable VoicechatConnection senderConnection, VoicechatConnection receiverConnection, String source) {
super(packet, senderConnection, receiverConnection, source);
}
}
@@ -0,0 +1,31 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.events.Event;
public class EventImpl
implements Event {
private boolean cancelled;
@Override
public boolean isCancellable() {
return true;
}
@Override
public boolean cancel() {
if (!this.isCancellable()) {
return false;
}
this.cancelled = true;
return true;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
}
@@ -0,0 +1,38 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.GroupEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import javax.annotation.Nullable;
public class GroupEventImpl
extends ServerEventImpl
implements GroupEvent {
@Nullable
protected Group group;
protected VoicechatConnection connection;
public GroupEventImpl(@Nullable Group group, VoicechatConnection connection) {
this.group = group;
this.connection = connection;
}
@Override
@Nullable
public Group getGroup() {
return this.group;
}
@Override
public VoicechatConnection getConnection() {
return this.connection;
}
}
@@ -0,0 +1,18 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.JoinGroupEvent;
import de.maxhenkel.voicechat.plugins.impl.events.GroupEventImpl;
public class JoinGroupEventImpl
extends GroupEventImpl
implements JoinGroupEvent {
public JoinGroupEventImpl(Group group, VoicechatConnection connection) {
super(group, connection);
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.LeaveGroupEvent;
import de.maxhenkel.voicechat.plugins.impl.events.GroupEventImpl;
import javax.annotation.Nullable;
public class LeaveGroupEventImpl
extends GroupEventImpl
implements LeaveGroupEvent {
public LeaveGroupEventImpl(@Nullable Group group, VoicechatConnection connection) {
super(group, connection);
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.LocationalSoundPacketEvent;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.events.SoundPacketEventImpl;
import javax.annotation.Nullable;
public class LocationalSoundPacketEventImpl
extends SoundPacketEventImpl<LocationalSoundPacket>
implements LocationalSoundPacketEvent {
public LocationalSoundPacketEventImpl(LocationalSoundPacket packet, @Nullable VoicechatConnection senderConnection, VoicechatConnection receiverConnection, String source) {
super(packet, senderConnection, receiverConnection, source);
}
}
@@ -0,0 +1,18 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.MicrophonePacketEvent;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.plugins.impl.events.PacketEventImpl;
public class MicrophonePacketEventImpl
extends PacketEventImpl<MicrophonePacket>
implements MicrophonePacketEvent {
public MicrophonePacketEventImpl(MicrophonePacket packet, VoicechatConnection connection) {
super(packet, connection, null);
}
}
@@ -0,0 +1,47 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.PacketEvent;
import de.maxhenkel.voicechat.api.packets.Packet;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import javax.annotation.Nullable;
public class PacketEventImpl<T extends Packet>
extends ServerEventImpl
implements PacketEvent<T> {
private final T packet;
@Nullable
private final VoicechatConnection receiverConnection;
@Nullable
private final VoicechatConnection senderConnection;
public PacketEventImpl(T packet, @Nullable VoicechatConnection senderConnection, @Nullable VoicechatConnection receiverConnection) {
this.packet = packet;
this.senderConnection = senderConnection;
this.receiverConnection = receiverConnection;
}
@Override
public T getPacket() {
return this.packet;
}
@Override
@Nullable
public VoicechatConnection getReceiverConnection() {
return this.receiverConnection;
}
@Override
@Nullable
public VoicechatConnection getSenderConnection() {
return this.senderConnection;
}
}
@@ -0,0 +1,25 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.PlayerConnectedEvent;
import de.maxhenkel.voicechat.plugins.impl.VoicechatConnectionImpl;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
public class PlayerConnectedEventImpl
extends ServerEventImpl
implements PlayerConnectedEvent {
protected VoicechatConnectionImpl connection;
public PlayerConnectedEventImpl(VoicechatConnectionImpl connection) {
this.connection = connection;
}
@Override
public VoicechatConnection getConnection() {
return this.connection;
}
}
@@ -0,0 +1,24 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.events.PlayerDisconnectedEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import java.util.UUID;
public class PlayerDisconnectedEventImpl
extends ServerEventImpl
implements PlayerDisconnectedEvent {
protected UUID player;
public PlayerDisconnectedEventImpl(UUID player) {
this.player = player;
}
@Override
public UUID getPlayerUuid() {
return this.player;
}
}
@@ -0,0 +1,59 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.PlayerStateChangedEvent;
import de.maxhenkel.voicechat.plugins.impl.VoicechatConnectionImpl;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import de.maxhenkel.voicechat.voice.common.PlayerState;
import java.util.UUID;
import javax.annotation.Nullable;
import org.bukkit.entity.Player;
public class PlayerStateChangedEventImpl
extends ServerEventImpl
implements PlayerStateChangedEvent {
protected final PlayerState state;
@Nullable
protected VoicechatConnectionImpl connection;
public PlayerStateChangedEventImpl(PlayerState state) {
this.state = state;
}
@Override
public boolean isDisabled() {
return this.state.isDisabled();
}
@Override
public boolean isDisconnected() {
return this.state.isDisconnected();
}
@Override
public UUID getPlayerUuid() {
return this.state.getUuid();
}
@Override
@Nullable
public VoicechatConnection getConnection() {
if (this.connection == null) {
Player player = Voicechat.INSTANCE.getServer().getPlayer(this.state.getUuid());
if (player == null) {
return null;
}
this.connection = VoicechatConnectionImpl.fromPlayer(player);
}
return this.connection;
}
}
@@ -0,0 +1,17 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.events.RegisterVolumeCategoryEvent;
import de.maxhenkel.voicechat.plugins.impl.events.VolumeCategoryEventImpl;
public class RegisterVolumeCategoryEventImpl
extends VolumeCategoryEventImpl
implements RegisterVolumeCategoryEvent {
public RegisterVolumeCategoryEventImpl(VolumeCategory category) {
super(category);
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.Group;
import de.maxhenkel.voicechat.api.events.RemoveGroupEvent;
import de.maxhenkel.voicechat.plugins.impl.events.GroupEventImpl;
public class RemoveGroupEventImpl
extends GroupEventImpl
implements RemoveGroupEvent {
public RemoveGroupEventImpl(Group group) {
super(group, null);
}
@Override
public boolean isCancellable() {
return super.isCancellable() && this.group.isPersistent();
}
}
@@ -0,0 +1,19 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatServerApi;
import de.maxhenkel.voicechat.api.events.ServerEvent;
import de.maxhenkel.voicechat.plugins.impl.VoicechatServerApiImpl;
import de.maxhenkel.voicechat.plugins.impl.events.EventImpl;
public class ServerEventImpl
extends EventImpl
implements ServerEvent {
@Override
public VoicechatServerApi getVoicechat() {
return VoicechatServerApiImpl.instance();
}
}
@@ -0,0 +1,30 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.SoundPacketEvent;
import de.maxhenkel.voicechat.api.packets.Packet;
import de.maxhenkel.voicechat.plugins.impl.events.PacketEventImpl;
import javax.annotation.Nullable;
public class SoundPacketEventImpl<T extends Packet>
extends PacketEventImpl<T>
implements SoundPacketEvent<T> {
private final String source;
public SoundPacketEventImpl(T packet, @Nullable VoicechatConnection senderConnection, @Nullable VoicechatConnection receiverConnection, String source) {
super(packet, senderConnection, receiverConnection);
this.source = source;
}
@Override
public String getSource() {
return this.source;
}
}
@@ -0,0 +1,22 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.StaticSoundPacketEvent;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.events.SoundPacketEventImpl;
import javax.annotation.Nullable;
public class StaticSoundPacketEventImpl
extends SoundPacketEventImpl<StaticSoundPacket>
implements StaticSoundPacketEvent {
public StaticSoundPacketEventImpl(StaticSoundPacket packet, @Nullable VoicechatConnection senderConnection, VoicechatConnection receiverConnection, String source) {
super(packet, senderConnection, receiverConnection, source);
}
}
@@ -0,0 +1,17 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.events.UnregisterVolumeCategoryEvent;
import de.maxhenkel.voicechat.plugins.impl.events.VolumeCategoryEventImpl;
public class UnregisterVolumeCategoryEventImpl
extends VolumeCategoryEventImpl
implements UnregisterVolumeCategoryEvent {
public UnregisterVolumeCategoryEventImpl(VolumeCategory category) {
super(category);
}
}
@@ -0,0 +1,54 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatConnection;
import de.maxhenkel.voicechat.api.events.VoiceDistanceEvent;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import javax.annotation.Nullable;
public class VoiceDistanceEventImpl
extends ServerEventImpl
implements VoiceDistanceEvent {
private final MicrophonePacket packet;
private final VoicechatConnection senderConnection;
private float distance;
public VoiceDistanceEventImpl(MicrophonePacket packet, VoicechatConnection senderConnection, float distance) {
this.packet = packet;
this.senderConnection = senderConnection;
this.distance = distance;
}
@Override
public boolean isCancellable() {
return false;
}
@Override
public MicrophonePacket getPacket() {
return this.packet;
}
@Override
@Nullable
public VoicechatConnection getSenderConnection() {
return this.senderConnection;
}
@Override
public float getDistance() {
return this.distance;
}
@Override
public void setDistance(float distance) {
this.distance = distance;
}
}
@@ -0,0 +1,41 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.bukkit.entity.Player
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.ServerPlayer;
import de.maxhenkel.voicechat.api.events.VoiceHostEvent;
import de.maxhenkel.voicechat.plugins.impl.ServerPlayerImpl;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import org.bukkit.entity.Player;
public class VoiceHostEventImpl
extends ServerEventImpl
implements VoiceHostEvent {
private final ServerPlayerImpl player;
private String voiceHost;
public VoiceHostEventImpl(Player player, String voiceHost) {
this.player = new ServerPlayerImpl(player);
this.voiceHost = voiceHost;
}
@Override
public String getVoiceHost() {
return this.voiceHost;
}
@Override
public void setVoiceHost(String voiceHost) {
this.voiceHost = voiceHost;
}
@Override
public ServerPlayer getPlayer() {
return this.player;
}
}
@@ -0,0 +1,17 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
public class VoicechatServerStartedEventImpl
extends ServerEventImpl
implements VoicechatServerStartedEvent {
@Override
public boolean isCancellable() {
return false;
}
}
@@ -0,0 +1,36 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VoicechatSocket;
import de.maxhenkel.voicechat.api.events.VoicechatServerStartingEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
import javax.annotation.Nullable;
public class VoicechatServerStartingEventImpl
extends ServerEventImpl
implements VoicechatServerStartingEvent {
@Nullable
private VoicechatSocket socketImplementation;
@Override
public void setSocketImplementation(VoicechatSocket socket) {
this.socketImplementation = socket;
}
@Override
@Nullable
public VoicechatSocket getSocketImplementation() {
return this.socketImplementation;
}
@Override
public boolean isCancellable() {
return false;
}
}
@@ -0,0 +1,17 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.events.VoicechatServerStoppedEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
public class VoicechatServerStoppedEventImpl
extends ServerEventImpl
implements VoicechatServerStoppedEvent {
@Override
public boolean isCancellable() {
return false;
}
}
@@ -0,0 +1,29 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.events;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.events.VolumeCategoryEvent;
import de.maxhenkel.voicechat.plugins.impl.events.ServerEventImpl;
public class VolumeCategoryEventImpl
extends ServerEventImpl
implements VolumeCategoryEvent {
private final VolumeCategory category;
public VolumeCategoryEventImpl(VolumeCategory category) {
this.category = category;
}
@Override
public VolumeCategory getVolumeCategory() {
return this.category;
}
@Override
public boolean isCancellable() {
return false;
}
}
@@ -0,0 +1,116 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.opus;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.opus.OpusDecoder;
import de.maxhenkel.voicechat.concentus.OpusException;
import javax.annotation.Nullable;
public class JavaOpusDecoderImpl
implements OpusDecoder {
protected de.maxhenkel.voicechat.concentus.OpusDecoder opusDecoder;
protected short[] buffer;
protected int sampleRate;
public JavaOpusDecoderImpl(int sampleRate, int frameSize) {
this.sampleRate = sampleRate;
this.buffer = new short[frameSize];
this.open();
}
private void open() {
if (this.opusDecoder != null) {
return;
}
try {
this.opusDecoder = new de.maxhenkel.voicechat.concentus.OpusDecoder(this.sampleRate, 1);
}
catch (OpusException e) {
throw new IllegalStateException("Failed to create Opus decoder", e);
}
Voicechat.LOGGER.debug("Initializing Java Opus decoder with sample rate {} Hz, frame size {} bytes", this.sampleRate, this.buffer.length);
}
@Override
public short[] decode(@Nullable byte[] data) {
int result;
if (this.isClosed()) {
throw new IllegalStateException("Decoder is closed");
}
try {
result = data == null || data.length == 0 ? this.opusDecoder.decode(null, 0, 0, this.buffer, 0, this.buffer.length, true) : this.opusDecoder.decode(data, 0, data.length, this.buffer, 0, this.buffer.length, false);
}
catch (Exception e) {
throw new RuntimeException("Failed to decode audio", e);
}
short[] audio = new short[result];
System.arraycopy(this.buffer, 0, audio, 0, result);
return audio;
}
@Override
public short[][] decode(byte[] data, int frames) {
if (this.isClosed()) {
throw new IllegalStateException("Decoder is closed");
}
if (frames <= 0) {
throw new IllegalArgumentException("Frames must be greater than 0");
}
if (data == null || data.length == 0) {
throw new IllegalArgumentException("Data must not be null or empty");
}
short[][] recovered = new short[frames][];
try {
int result;
if (frames > 2) {
for (int i = 0; i < frames - 2; ++i) {
result = this.opusDecoder.decode(null, 0, 0, this.buffer, 0, this.buffer.length, true);
short[] audio = new short[result];
System.arraycopy(this.buffer, 0, audio, 0, result);
recovered[i] = audio;
}
}
if (frames > 1) {
result = this.opusDecoder.decode(data, 0, data.length, this.buffer, 0, this.buffer.length, true);
short[] audio = new short[result];
System.arraycopy(this.buffer, 0, audio, 0, result);
recovered[frames - 2] = audio;
}
result = this.opusDecoder.decode(data, 0, data.length, this.buffer, 0, this.buffer.length, false);
short[] audio = new short[result];
System.arraycopy(this.buffer, 0, audio, 0, result);
recovered[frames - 1] = audio;
}
catch (Exception e) {
throw new RuntimeException("Failed to decode audio", e);
}
return recovered;
}
@Override
public boolean isClosed() {
return this.opusDecoder == null;
}
@Override
public void close() {
if (this.isClosed()) {
return;
}
this.opusDecoder = null;
}
@Override
public void resetState() {
if (this.isClosed()) {
throw new IllegalStateException("Decoder is closed");
}
this.opusDecoder.resetState();
}
}
@@ -0,0 +1,82 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.opus;
import de.maxhenkel.voicechat.concentus.OpusApplication;
import de.maxhenkel.voicechat.concentus.OpusEncoder;
public class JavaOpusEncoderImpl
implements de.maxhenkel.voicechat.api.opus.OpusEncoder {
protected OpusEncoder opusEncoder;
protected byte[] buffer;
protected int sampleRate;
protected int frameSize;
protected int maxPayloadSize;
protected OpusApplication application;
public JavaOpusEncoderImpl(int sampleRate, int frameSize, int maxPayloadSize, OpusApplication application) {
this.sampleRate = sampleRate;
this.frameSize = frameSize;
this.maxPayloadSize = maxPayloadSize;
this.application = application;
this.buffer = new byte[maxPayloadSize];
this.open();
}
private void open() {
if (this.opusEncoder != null) {
return;
}
try {
this.opusEncoder = new OpusEncoder(this.sampleRate, 1, this.application);
this.opusEncoder.setUseInbandFEC(true);
this.opusEncoder.setPacketLossPercent(5);
}
catch (Exception e) {
throw new IllegalStateException("Opus encoder error " + e.getMessage());
}
}
@Override
public byte[] encode(short[] rawAudio) {
int result;
if (this.isClosed()) {
throw new IllegalStateException("Encoder is closed");
}
try {
result = this.opusEncoder.encode(rawAudio, 0, this.frameSize, this.buffer, 0, this.buffer.length);
}
catch (Exception e) {
throw new RuntimeException("Failed to encode audio data: " + e.getMessage());
}
if (result < 0) {
throw new RuntimeException("Failed to encode audio data");
}
byte[] audio = new byte[result];
System.arraycopy(this.buffer, 0, audio, 0, result);
return audio;
}
@Override
public void resetState() {
if (this.isClosed()) {
throw new IllegalStateException("Encoder is closed");
}
this.opusEncoder.resetState();
}
@Override
public boolean isClosed() {
return this.opusEncoder == null;
}
@Override
public void close() {
if (this.isClosed()) {
return;
}
this.opusEncoder = null;
}
}
@@ -0,0 +1,46 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.opus;
import de.maxhenkel.voicechat.api.opus.OpusDecoder;
import de.maxhenkel.voicechat.api.opus.OpusEncoder;
import de.maxhenkel.voicechat.api.opus.OpusEncoderMode;
import de.maxhenkel.voicechat.concentus.OpusApplication;
import de.maxhenkel.voicechat.plugins.impl.opus.JavaOpusDecoderImpl;
import de.maxhenkel.voicechat.plugins.impl.opus.JavaOpusEncoderImpl;
public class OpusManager {
public static final int SAMPLE_RATE = 48000;
public static final int FRAME_SIZE = 960;
public static OpusEncoder createEncoder(int sampleRate, int frameSize, int maxPayloadSize, OpusApplication application) {
return new JavaOpusEncoderImpl(sampleRate, frameSize, maxPayloadSize, application);
}
public static OpusEncoder createEncoder(OpusEncoderMode mode) {
OpusApplication application = OpusApplication.OPUS_APPLICATION_VOIP;
if (mode != null) {
switch (mode) {
case AUDIO: {
application = OpusApplication.OPUS_APPLICATION_AUDIO;
break;
}
case RESTRICTED_LOWDELAY: {
application = OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY;
break;
}
}
}
return OpusManager.createEncoder(48000, 960, 1024, application);
}
public static OpusDecoder createDecoder(int sampleRate, int frameSize) {
return new JavaOpusDecoderImpl(sampleRate, frameSize);
}
public static OpusDecoder createDecoder() {
return OpusManager.createDecoder(48000, 960);
}
}
@@ -0,0 +1,192 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.packets.ConvertablePacket;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.api.packets.SoundPacket;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.EntitySoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.LocationalSoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.StaticSoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.GroupSoundPacket;
import de.maxhenkel.voicechat.voice.common.LocationSoundPacket;
import de.maxhenkel.voicechat.voice.common.PlayerSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.util.UUID;
import javax.annotation.Nullable;
public class ConvertablePacketImpl
implements ConvertablePacket {
@Override
public EntitySoundPacket.Builder<?> entitySoundPacketBuilder() {
return new GenericEntitySoundPacketBuilder();
}
@Override
public LocationalSoundPacket.Builder<?> locationalSoundPacketBuilder() {
return new GenericLocationalSoundPacketBuilder();
}
@Override
public StaticSoundPacket.Builder<?> staticSoundPacketBuilder() {
return new GenericStaticSoundPacketBuilder();
}
@Override
public EntitySoundPacket toEntitySoundPacket(UUID entityUuid, boolean whispering) {
throw new UnsupportedOperationException();
}
@Override
public LocationalSoundPacket toLocationalSoundPacket(Position position) {
throw new UnsupportedOperationException();
}
@Override
public StaticSoundPacket toStaticSoundPacket() {
throw new UnsupportedOperationException();
}
public static class GenericEntitySoundPacketBuilder
extends GenericSoundPacketBuilder<GenericEntitySoundPacketBuilder, EntitySoundPacket>
implements EntitySoundPacket.Builder<GenericEntitySoundPacketBuilder> {
protected UUID entityUuid;
protected boolean whispering;
protected Float distance;
@Override
public GenericEntitySoundPacketBuilder entityUuid(UUID entityUuid) {
this.entityUuid = entityUuid;
return this;
}
@Override
public GenericEntitySoundPacketBuilder whispering(boolean whispering) {
this.whispering = whispering;
return this;
}
@Override
public GenericEntitySoundPacketBuilder distance(float distance) {
this.distance = Float.valueOf(distance);
return this;
}
@Override
public EntitySoundPacket build() {
this.checkRequiredFields();
if (this.entityUuid == null) {
throw new IllegalStateException("Entity UUID must be set");
}
if (this.distance == null) {
this.distance = Float.valueOf(Utils.getDefaultDistance());
}
return new EntitySoundPacketImpl(new PlayerSoundPacket(this.channelId, this.entityUuid, this.opusEncodedData, this.sequenceNumber, this.whispering, this.distance.floatValue(), this.category));
}
}
public static class GenericLocationalSoundPacketBuilder
extends GenericSoundPacketBuilder<GenericLocationalSoundPacketBuilder, LocationalSoundPacket>
implements LocationalSoundPacket.Builder<GenericLocationalSoundPacketBuilder> {
protected PositionImpl position;
protected Float distance;
@Override
public GenericLocationalSoundPacketBuilder position(Position position) {
this.position = (PositionImpl)position;
return this;
}
@Override
public GenericLocationalSoundPacketBuilder distance(float distance) {
this.distance = Float.valueOf(distance);
return this;
}
@Override
public LocationalSoundPacket build() {
this.checkRequiredFields();
if (this.position == null) {
throw new IllegalStateException("Position must be set");
}
if (this.distance == null) {
this.distance = Float.valueOf(Utils.getDefaultDistance());
}
return new LocationalSoundPacketImpl(new LocationSoundPacket(this.channelId, this.sender, this.position.getPosition(), this.opusEncodedData, this.sequenceNumber, this.distance.floatValue(), this.category));
}
}
public static class GenericStaticSoundPacketBuilder
extends GenericSoundPacketBuilder<GenericStaticSoundPacketBuilder, StaticSoundPacket>
implements StaticSoundPacket.Builder<GenericStaticSoundPacketBuilder> {
@Override
public StaticSoundPacket build() {
return new StaticSoundPacketImpl(new GroupSoundPacket(this.channelId, this.sender, this.opusEncodedData, this.sequenceNumber, this.category));
}
}
public static abstract class GenericSoundPacketBuilder<T extends SoundPacket.Builder<T, P>, P extends SoundPacket>
implements SoundPacket.Builder<T, P> {
@Nullable
protected UUID channelId;
@Nullable
protected UUID sender;
@Nullable
protected byte[] opusEncodedData;
@Nullable
protected Long sequenceNumber;
@Nullable
protected String category;
@Override
public T channelId(UUID channelId) {
this.channelId = channelId;
return (T)this;
}
@Override
public T sender(UUID sender) {
this.sender = sender;
return (T)this;
}
@Override
public T opusEncodedData(byte[] data) {
this.opusEncodedData = data;
return (T)this;
}
@Override
public T sequenceNumber(long sequenceNumber) {
this.sequenceNumber = sequenceNumber;
return (T)this;
}
@Override
public T category(@Nullable String category) {
this.category = category;
return (T)this;
}
public void checkRequiredFields() {
if (this.channelId == null) {
throw new IllegalStateException("Channel id must be set");
}
if (this.sequenceNumber == null) {
throw new IllegalStateException("Sequence number must be set");
}
if (this.opusEncodedData == null) {
throw new IllegalStateException("Opus encoded data must be set");
}
}
}
}
@@ -0,0 +1,102 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.plugins.impl.packets.LocationalSoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.SoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.PlayerSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.util.UUID;
import javax.annotation.Nullable;
public class EntitySoundPacketImpl
extends SoundPacketImpl
implements EntitySoundPacket {
private final PlayerSoundPacket packet;
public EntitySoundPacketImpl(PlayerSoundPacket packet) {
super(packet);
this.packet = packet;
}
@Override
public UUID getEntityUuid() {
return this.packet.getSender();
}
@Override
public boolean isWhispering() {
return this.packet.isWhispering();
}
@Override
public float getDistance() {
return this.packet.getDistance();
}
public PlayerSoundPacket getPacket() {
return this.packet;
}
@Override
public UUID getChannelId() {
return this.packet.getChannelId();
}
public static class BuilderImpl
extends SoundPacketImpl.BuilderImpl<BuilderImpl, EntitySoundPacket>
implements EntitySoundPacket.Builder<BuilderImpl> {
protected UUID entityUuid;
protected boolean whispering;
protected float distance;
public BuilderImpl(SoundPacketImpl soundPacket) {
super(soundPacket);
if (soundPacket instanceof EntitySoundPacketImpl) {
EntitySoundPacketImpl p = (EntitySoundPacketImpl)soundPacket;
this.entityUuid = p.getEntityUuid();
this.whispering = p.isWhispering();
this.distance = p.getDistance();
} else {
this.distance = soundPacket instanceof LocationalSoundPacketImpl ? ((LocationalSoundPacketImpl)soundPacket).getDistance() : Utils.getDefaultDistance();
}
}
public BuilderImpl(UUID channelId, UUID sender, byte[] opusEncodedData, long sequenceNumber, @Nullable String category) {
super(channelId, sender, opusEncodedData, sequenceNumber, category);
this.distance = Utils.getDefaultDistance();
}
@Override
public BuilderImpl entityUuid(UUID entityUuid) {
this.entityUuid = entityUuid;
return this;
}
@Override
public BuilderImpl whispering(boolean whispering) {
this.whispering = whispering;
return this;
}
@Override
public BuilderImpl distance(float distance) {
this.distance = distance;
return this;
}
@Override
public EntitySoundPacket build() {
if (this.entityUuid == null) {
throw new IllegalStateException("entityUuid missing");
}
return new EntitySoundPacketImpl(new PlayerSoundPacket(this.channelId, this.entityUuid, this.opusEncodedData, this.sequenceNumber, this.whispering, this.distance, this.category));
}
}
}
@@ -0,0 +1,88 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.EntitySoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.SoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.LocationSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.util.UUID;
import javax.annotation.Nullable;
public class LocationalSoundPacketImpl
extends SoundPacketImpl
implements LocationalSoundPacket {
private final LocationSoundPacket packet;
private final PositionImpl position;
public LocationalSoundPacketImpl(LocationSoundPacket packet) {
super(packet);
this.packet = packet;
this.position = new PositionImpl(packet.getLocation());
}
@Override
public Position getPosition() {
return this.position;
}
@Override
public float getDistance() {
return this.packet.getDistance();
}
public LocationSoundPacket getPacket() {
return this.packet;
}
public static class BuilderImpl
extends SoundPacketImpl.BuilderImpl<BuilderImpl, LocationalSoundPacket>
implements LocationalSoundPacket.Builder<BuilderImpl> {
protected PositionImpl position;
protected float distance;
public BuilderImpl(SoundPacketImpl soundPacket) {
super(soundPacket);
if (soundPacket instanceof LocationalSoundPacketImpl) {
LocationalSoundPacketImpl p = (LocationalSoundPacketImpl)soundPacket;
this.position = p.position;
this.distance = p.getDistance();
} else {
this.distance = soundPacket instanceof EntitySoundPacketImpl ? ((EntitySoundPacketImpl)soundPacket).getDistance() : Utils.getDefaultDistance();
}
}
public BuilderImpl(UUID channelId, UUID sender, byte[] opusEncodedData, long sequenceNumber, @Nullable String category) {
super(channelId, sender, opusEncodedData, sequenceNumber, category);
this.distance = Utils.getDefaultDistance();
}
@Override
public BuilderImpl position(Position position) {
this.position = (PositionImpl)position;
return this;
}
@Override
public BuilderImpl distance(float distance) {
this.distance = distance;
return this;
}
@Override
public LocationalSoundPacket build() {
if (this.position == null) {
throw new IllegalStateException("position missing");
}
return new LocationalSoundPacketImpl(new LocationSoundPacket(this.channelId, this.sender, this.position.getPosition(), this.opusEncodedData, this.sequenceNumber, this.distance, this.category));
}
}
}
@@ -0,0 +1,84 @@
/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.api.packets.MicrophonePacket;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.EntitySoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.LocationalSoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.StaticSoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.GroupSoundPacket;
import de.maxhenkel.voicechat.voice.common.LocationSoundPacket;
import de.maxhenkel.voicechat.voice.common.MicPacket;
import de.maxhenkel.voicechat.voice.common.PlayerSoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.util.Objects;
import java.util.UUID;
public class MicrophonePacketImpl
implements MicrophonePacket {
private final MicPacket packet;
private final UUID sender;
public MicrophonePacketImpl(MicPacket packet, UUID sender) {
this.packet = packet;
this.sender = sender;
}
@Override
public boolean isWhispering() {
return this.packet.isWhispering();
}
@Override
public byte[] getOpusEncodedData() {
return this.packet.getData();
}
@Override
public void setOpusEncodedData(byte[] data) {
this.packet.setData(Objects.requireNonNull(data));
}
@Override
public EntitySoundPacket.Builder<?> entitySoundPacketBuilder() {
return new EntitySoundPacketImpl.BuilderImpl(this.sender, this.sender, this.packet.getData(), this.packet.getSequenceNumber(), null);
}
@Override
public LocationalSoundPacket.Builder<?> locationalSoundPacketBuilder() {
return new LocationalSoundPacketImpl.BuilderImpl(this.sender, this.sender, this.packet.getData(), this.packet.getSequenceNumber(), null);
}
@Override
public StaticSoundPacket.Builder<?> staticSoundPacketBuilder() {
return new StaticSoundPacketImpl.BuilderImpl(this.sender, this.sender, this.packet.getData(), this.packet.getSequenceNumber(), null);
}
@Override
@Deprecated
public EntitySoundPacket toEntitySoundPacket(UUID entityUuid, boolean whispering) {
return new EntitySoundPacketImpl(new PlayerSoundPacket(this.sender, entityUuid, this.packet.getData(), this.packet.getSequenceNumber(), whispering, Utils.getDefaultDistance(), null));
}
@Override
@Deprecated
public LocationalSoundPacket toLocationalSoundPacket(Position position) {
if (position instanceof PositionImpl) {
return new LocationalSoundPacketImpl(new LocationSoundPacket(this.sender, this.sender, ((PositionImpl)position).getPosition(), this.packet.getData(), this.packet.getSequenceNumber(), Utils.getDefaultDistance(), null));
}
throw new IllegalArgumentException("position is not an instance of PositionImpl");
}
@Override
@Deprecated
public StaticSoundPacket toStaticSoundPacket() {
return new StaticSoundPacketImpl(new GroupSoundPacket(this.sender, this.sender, this.packet.getData(), this.packet.getSequenceNumber(), null));
}
}
@@ -0,0 +1,166 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.Position;
import de.maxhenkel.voicechat.api.packets.EntitySoundPacket;
import de.maxhenkel.voicechat.api.packets.LocationalSoundPacket;
import de.maxhenkel.voicechat.api.packets.SoundPacket;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.PositionImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.EntitySoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.LocationalSoundPacketImpl;
import de.maxhenkel.voicechat.plugins.impl.packets.StaticSoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.GroupSoundPacket;
import de.maxhenkel.voicechat.voice.common.LocationSoundPacket;
import de.maxhenkel.voicechat.voice.common.PlayerSoundPacket;
import de.maxhenkel.voicechat.voice.common.SoundPacket;
import de.maxhenkel.voicechat.voice.common.Utils;
import java.util.UUID;
import javax.annotation.Nullable;
public class SoundPacketImpl
implements de.maxhenkel.voicechat.api.packets.SoundPacket {
private final SoundPacket<?> packet;
public SoundPacketImpl(SoundPacket<?> packet) {
this.packet = packet;
}
@Override
public UUID getChannelId() {
return this.packet.getChannelId();
}
@Override
public UUID getSender() {
return this.packet.getSender();
}
@Override
public byte[] getOpusEncodedData() {
return this.packet.getData();
}
@Override
public long getSequenceNumber() {
return this.packet.getSequenceNumber();
}
@Override
@Nullable
public String getCategory() {
return this.packet.getCategory();
}
public SoundPacket<?> getPacket() {
return this.packet;
}
@Override
public EntitySoundPacket.Builder<?> entitySoundPacketBuilder() {
return new EntitySoundPacketImpl.BuilderImpl(this);
}
@Override
public LocationalSoundPacket.Builder<?> locationalSoundPacketBuilder() {
return new LocationalSoundPacketImpl.BuilderImpl(this);
}
@Override
public StaticSoundPacket.Builder<?> staticSoundPacketBuilder() {
return new StaticSoundPacketImpl.BuilderImpl(this);
}
@Override
public EntitySoundPacket toEntitySoundPacket(UUID entityUuid, boolean whispering) {
return new EntitySoundPacketImpl(new PlayerSoundPacket(this.packet.getChannelId(), entityUuid, this.packet.getData(), this.packet.getSequenceNumber(), whispering, this.getDistance(), null));
}
@Override
public LocationalSoundPacket toLocationalSoundPacket(Position position) {
if (position instanceof PositionImpl) {
return new LocationalSoundPacketImpl(new LocationSoundPacket(this.packet.getChannelId(), this.packet.getSender(), ((PositionImpl)position).getPosition(), this.packet.getData(), this.packet.getSequenceNumber(), this.getDistance(), null));
}
throw new IllegalArgumentException("position is not an instance of PositionImpl");
}
private float getDistance() {
if (this instanceof EntitySoundPacket) {
return ((EntitySoundPacket)((Object)this)).getDistance();
}
if (this instanceof LocationalSoundPacket) {
return ((LocationalSoundPacket)((Object)this)).getDistance();
}
return Utils.getDefaultDistance();
}
@Override
public StaticSoundPacket toStaticSoundPacket() {
return new StaticSoundPacketImpl(new GroupSoundPacket(this.packet.getChannelId(), this.packet.getSender(), this.packet.getData(), this.packet.getSequenceNumber(), null));
}
public static abstract class BuilderImpl<T extends BuilderImpl<T, P>, P extends de.maxhenkel.voicechat.api.packets.SoundPacket>
implements SoundPacket.Builder<T, P> {
protected UUID channelId;
protected UUID sender;
protected byte[] opusEncodedData;
protected long sequenceNumber;
@Nullable
protected String category;
public BuilderImpl(SoundPacketImpl soundPacket) {
this.channelId = soundPacket.getChannelId();
this.sender = soundPacket.getSender();
this.opusEncodedData = soundPacket.getOpusEncodedData();
this.sequenceNumber = soundPacket.getSequenceNumber();
this.category = soundPacket.getCategory();
}
public BuilderImpl(UUID channelId, UUID sender, byte[] opusEncodedData, long sequenceNumber, @Nullable String category) {
this.channelId = channelId;
this.sender = sender;
this.opusEncodedData = opusEncodedData;
this.sequenceNumber = sequenceNumber;
this.category = category;
}
@Override
public T channelId(UUID channelId) {
if (channelId == null) {
throw new IllegalArgumentException("channelId can't be null");
}
this.channelId = channelId;
return (T)this;
}
@Override
public T sender(UUID sender) {
this.sender = sender;
return (T)this;
}
@Override
public T opusEncodedData(byte[] data) {
this.opusEncodedData = data;
return (T)this;
}
@Override
public T sequenceNumber(long sequenceNumber) {
this.sequenceNumber = sequenceNumber;
return (T)this;
}
@Override
public T category(@Nullable String category) {
this.category = category;
return (T)this;
}
}
}
@@ -0,0 +1,39 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.packets;
import de.maxhenkel.voicechat.api.packets.StaticSoundPacket;
import de.maxhenkel.voicechat.plugins.impl.packets.SoundPacketImpl;
import de.maxhenkel.voicechat.voice.common.GroupSoundPacket;
import java.util.UUID;
import javax.annotation.Nullable;
public class StaticSoundPacketImpl
extends SoundPacketImpl
implements StaticSoundPacket {
public StaticSoundPacketImpl(GroupSoundPacket packet) {
super(packet);
}
public static class BuilderImpl
extends SoundPacketImpl.BuilderImpl<BuilderImpl, StaticSoundPacket>
implements StaticSoundPacket.Builder<BuilderImpl> {
public BuilderImpl(SoundPacketImpl soundPacket) {
super(soundPacket);
}
public BuilderImpl(UUID channelId, UUID sender, byte[] opusEncodedData, long sequenceNumber, @Nullable String category) {
super(channelId, sender, opusEncodedData, sequenceNumber, category);
}
@Override
public StaticSoundPacket build() {
return new StaticSoundPacketImpl(new GroupSoundPacket(this.channelId, this.sender, this.opusEncodedData, this.sequenceNumber, this.category));
}
}
}