Search in sources :

Example 1 with AudioManagerImpl

use of net.dv8tion.jda.internal.managers.AudioManagerImpl in project JDA by DV8FromTheWorld.

the class VoiceStateUpdateHandler method handleGuildVoiceState.

private void handleGuildVoiceState(DataObject content) {
    final long userId = content.getLong("user_id");
    final long guildId = content.getLong("guild_id");
    final Long channelId = !content.isNull("channel_id") ? content.getLong("channel_id") : null;
    final String sessionId = !content.isNull("session_id") ? content.getString("session_id") : null;
    boolean selfMuted = content.getBoolean("self_mute");
    boolean selfDeafened = content.getBoolean("self_deaf");
    boolean guildMuted = content.getBoolean("mute");
    boolean guildDeafened = content.getBoolean("deaf");
    boolean suppressed = content.getBoolean("suppress");
    boolean stream = content.getBoolean("self_stream");
    boolean video = content.getBoolean("self_video", false);
    String requestToSpeak = content.getString("request_to_speak_timestamp", null);
    OffsetDateTime requestToSpeakTime = null;
    long requestToSpeakTimestamp = 0L;
    if (requestToSpeak != null) {
        requestToSpeakTime = OffsetDateTime.parse(requestToSpeak);
        requestToSpeakTimestamp = requestToSpeakTime.toInstant().toEpochMilli();
    }
    Guild guild = getJDA().getGuildById(guildId);
    if (guild == null) {
        getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("Received a VOICE_STATE_UPDATE for a Guild that has yet to be cached. JSON: {}", content);
        return;
    }
    AudioChannel channel = null;
    if (channelId != null) {
        channel = (AudioChannel) guild.getGuildChannelById(channelId);
    }
    if (channel == null && (channelId != null)) {
        getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("Received VOICE_STATE_UPDATE for an AudioChannel that has yet to be cached. JSON: {}", content);
        return;
    }
    DataObject memberJson = content.getObject("member");
    MemberImpl member = getJDA().getEntityBuilder().createMember((GuildImpl) guild, memberJson);
    if (member == null)
        return;
    GuildVoiceStateImpl vState = (GuildVoiceStateImpl) member.getVoiceState();
    if (vState == null)
        return;
    // Cant really see a reason for an event for this
    vState.setSessionId(sessionId);
    VoiceDispatchInterceptor voiceInterceptor = getJDA().getVoiceInterceptor();
    boolean isSelf = guild.getSelfMember().equals(member);
    boolean wasMute = vState.isMuted();
    boolean wasDeaf = vState.isDeafened();
    if (selfMuted != vState.isSelfMuted()) {
        vState.setSelfMuted(selfMuted);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceSelfMuteEvent(getJDA(), responseNumber, member));
    }
    if (selfDeafened != vState.isSelfDeafened()) {
        vState.setSelfDeafened(selfDeafened);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceSelfDeafenEvent(getJDA(), responseNumber, member));
    }
    if (guildMuted != vState.isGuildMuted()) {
        vState.setGuildMuted(guildMuted);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceGuildMuteEvent(getJDA(), responseNumber, member));
    }
    if (guildDeafened != vState.isGuildDeafened()) {
        vState.setGuildDeafened(guildDeafened);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceGuildDeafenEvent(getJDA(), responseNumber, member));
    }
    if (suppressed != vState.isSuppressed()) {
        vState.setSuppressed(suppressed);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceSuppressEvent(getJDA(), responseNumber, member));
    }
    if (stream != vState.isStream()) {
        vState.setStream(stream);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceStreamEvent(getJDA(), responseNumber, member, stream));
    }
    if (video != vState.isSendingVideo()) {
        vState.setVideo(video);
        getJDA().getEntityBuilder().updateMemberCache(member);
        getJDA().handleEvent(new GuildVoiceVideoEvent(getJDA(), responseNumber, member, video));
    }
    if (wasMute != vState.isMuted())
        getJDA().handleEvent(new GuildVoiceMuteEvent(getJDA(), responseNumber, member));
    if (wasDeaf != vState.isDeafened())
        getJDA().handleEvent(new GuildVoiceDeafenEvent(getJDA(), responseNumber, member));
    if (requestToSpeakTimestamp != vState.getRequestToSpeak()) {
        OffsetDateTime oldRequestToSpeak = vState.getRequestToSpeakTimestamp();
        vState.setRequestToSpeak(requestToSpeakTime);
        getJDA().handleEvent(new GuildVoiceRequestToSpeakEvent(getJDA(), responseNumber, member, oldRequestToSpeak, requestToSpeakTime));
    }
    if (!Objects.equals(channel, vState.getChannel())) {
        AudioChannel oldChannel = vState.getChannel();
        vState.setConnectedChannel(channel);
        if (oldChannel == null) {
            ((AudioChannelMixin<?>) channel).getConnectedMembersMap().put(userId, member);
            getJDA().getEntityBuilder().updateMemberCache(member);
            getJDA().handleEvent(new GuildVoiceJoinEvent(getJDA(), responseNumber, member));
        } else if (channel == null) {
            ((AudioChannelMixin<?>) oldChannel).getConnectedMembersMap().remove(userId);
            if (isSelf)
                getJDA().getDirectAudioController().update(guild, null);
            getJDA().getEntityBuilder().updateMemberCache(member, memberJson.isNull("joined_at"));
            getJDA().handleEvent(new GuildVoiceLeaveEvent(getJDA(), responseNumber, member, oldChannel));
        } else {
            AudioManagerImpl mng = (AudioManagerImpl) getJDA().getAudioManagersView().get(guildId);
            // If the currently connected account is the one that is being moved
            if (isSelf && mng != null && voiceInterceptor == null) {
                // then change the channel we expect to be connected to.
                if (mng.isConnected())
                    mng.setConnectedChannel(channel);
                // (handled by updateAudioConnection)
                if (mng.isConnected())
                    getJDA().getDirectAudioController().update(guild, channel);
            // If we are not already connected this will be removed by VOICE_SERVER_UPDATE
            }
            ((AudioChannelMixin<?>) channel).getConnectedMembersMap().put(userId, member);
            ((AudioChannelMixin<?>) oldChannel).getConnectedMembersMap().remove(userId);
            getJDA().getEntityBuilder().updateMemberCache(member);
            getJDA().handleEvent(new GuildVoiceMoveEvent(getJDA(), responseNumber, member, oldChannel));
        }
    }
    if (isSelf && voiceInterceptor != null) {
        if (voiceInterceptor.onVoiceStateUpdate(new VoiceDispatchInterceptor.VoiceStateUpdate(channel, vState, allContent)))
            getJDA().getDirectAudioController().update(guild, channel);
    }
    ((GuildImpl) guild).updateRequestToSpeak();
}
Also used : Guild(net.dv8tion.jda.api.entities.Guild) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) AudioManagerImpl(net.dv8tion.jda.internal.managers.AudioManagerImpl) AudioChannel(net.dv8tion.jda.api.entities.AudioChannel) MemberImpl(net.dv8tion.jda.internal.entities.MemberImpl) AudioChannelMixin(net.dv8tion.jda.internal.entities.mixin.channel.middleman.AudioChannelMixin) VoiceDispatchInterceptor(net.dv8tion.jda.api.hooks.VoiceDispatchInterceptor) DataObject(net.dv8tion.jda.api.utils.data.DataObject) OffsetDateTime(java.time.OffsetDateTime) GuildVoiceStateImpl(net.dv8tion.jda.internal.entities.GuildVoiceStateImpl)

Example 2 with AudioManagerImpl

use of net.dv8tion.jda.internal.managers.AudioManagerImpl in project JDA by DV8FromTheWorld.

the class WebSocketClient method updateAudioManagerReferences.

protected void updateAudioManagerReferences() {
    AbstractCacheView<AudioManager> managerView = api.getAudioManagersView();
    try (UnlockHook hook = managerView.writeLock()) {
        final TLongObjectMap<AudioManager> managerMap = managerView.getMap();
        if (managerMap.size() > 0)
            LOG.trace("Updating AudioManager references");
        for (TLongObjectIterator<AudioManager> it = managerMap.iterator(); it.hasNext(); ) {
            it.advance();
            final long guildId = it.key();
            final AudioManagerImpl mng = (AudioManagerImpl) it.value();
            GuildImpl guild = (GuildImpl) api.getGuildById(guildId);
            if (guild == null) {
                // We no longer have access to the guild that this audio manager was for. Set the value to null.
                queuedAudioConnections.remove(guildId);
                mng.closeAudioConnection(ConnectionStatus.DISCONNECTED_REMOVED_DURING_RECONNECT);
                it.remove();
            }
        }
    }
}
Also used : AudioManager(net.dv8tion.jda.api.managers.AudioManager) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) AudioManagerImpl(net.dv8tion.jda.internal.managers.AudioManagerImpl) UnlockHook(net.dv8tion.jda.internal.utils.UnlockHook)

Example 3 with AudioManagerImpl

use of net.dv8tion.jda.internal.managers.AudioManagerImpl in project JDA by DV8FromTheWorld.

the class VoiceServerUpdateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    final long guildId = content.getLong("guild_id");
    if (getJDA().getGuildSetupController().isLocked(guildId))
        return guildId;
    Guild guild = getJDA().getGuildById(guildId);
    if (guild == null)
        throw new IllegalArgumentException("Attempted to start audio connection with Guild that doesn't exist!");
    getJDA().getDirectAudioController().update(guild, guild.getSelfMember().getVoiceState().getChannel());
    if (content.isNull("endpoint")) {
        // to actually connect to the audio server.
        return null;
    }
    // Strip the port from the endpoint.
    String endpoint = content.getString("endpoint").replace(":80", "");
    String token = content.getString("token");
    String sessionId = guild.getSelfMember().getVoiceState().getSessionId();
    if (sessionId == null)
        throw new IllegalArgumentException("Attempted to create audio connection without having a session ID. Did VOICE_STATE_UPDATED fail?");
    VoiceDispatchInterceptor voiceInterceptor = getJDA().getVoiceInterceptor();
    if (voiceInterceptor != null) {
        voiceInterceptor.onVoiceServerUpdate(new VoiceDispatchInterceptor.VoiceServerUpdate(guild, endpoint, token, sessionId, allContent));
        return null;
    }
    AudioManagerImpl audioManager = (AudioManagerImpl) getJDA().getAudioManagersView().get(guildId);
    if (audioManager == null) {
        WebSocketClient.LOG.debug("Received a VOICE_SERVER_UPDATE but JDA is not currently connected nor attempted to connect " + "to a VoiceChannel. Assuming that this is caused by another client running on this account. " + "Ignoring the event.");
        return null;
    }
    MiscUtil.locked(audioManager.CONNECTION_LOCK, () -> {
        // Synchronized to prevent attempts to close while setting up initial objects.
        AudioChannel target = guild.getSelfMember().getVoiceState().getChannel();
        if (target == null) {
            WebSocketClient.LOG.warn("Ignoring VOICE_SERVER_UPDATE for unknown channel");
            return;
        }
        AudioConnection connection = new AudioConnection(audioManager, endpoint, sessionId, token, target);
        audioManager.setAudioConnection(connection);
        connection.startConnection();
    });
    return null;
}
Also used : VoiceDispatchInterceptor(net.dv8tion.jda.api.hooks.VoiceDispatchInterceptor) AudioManagerImpl(net.dv8tion.jda.internal.managers.AudioManagerImpl) AudioChannel(net.dv8tion.jda.api.entities.AudioChannel) AudioConnection(net.dv8tion.jda.internal.audio.AudioConnection) Guild(net.dv8tion.jda.api.entities.Guild)

Example 4 with AudioManagerImpl

use of net.dv8tion.jda.internal.managers.AudioManagerImpl in project JDA by DV8FromTheWorld.

the class GuildDeleteHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    final long id = content.getLong("id");
    GuildSetupController setupController = getJDA().getGuildSetupController();
    boolean wasInit = setupController.onDelete(id, content);
    if (wasInit || setupController.isUnavailable(id))
        return null;
    GuildImpl guild = (GuildImpl) getJDA().getGuildById(id);
    boolean unavailable = content.getBoolean("unavailable");
    if (guild == null) {
        // getJDA().getEventCache().cache(EventCache.Type.GUILD, id, () -> handle(responseNumber, allContent));
        WebSocketClient.LOG.debug("Received GUILD_DELETE for a Guild that is not currently cached. ID: {} unavailable: {}", id, unavailable);
        return null;
    }
    // ignore the event
    if (setupController.isUnavailable(id) && unavailable)
        return null;
    // Remove everything from global cache
    // this prevents some race-conditions for getting audio managers from guilds
    SnowflakeCacheViewImpl<Guild> guildView = getJDA().getGuildsView();
    SnowflakeCacheViewImpl<StageChannel> stageView = getJDA().getStageChannelView();
    SnowflakeCacheViewImpl<TextChannel> textView = getJDA().getTextChannelsView();
    SnowflakeCacheViewImpl<ThreadChannel> threadView = getJDA().getThreadChannelsView();
    SnowflakeCacheViewImpl<NewsChannel> newsView = getJDA().getNewsChannelView();
    SnowflakeCacheViewImpl<VoiceChannel> voiceView = getJDA().getVoiceChannelsView();
    SnowflakeCacheViewImpl<Category> categoryView = getJDA().getCategoriesView();
    guildView.remove(id);
    try (UnlockHook hook = stageView.writeLock()) {
        guild.getStageChannelCache().forEachUnordered(chan -> stageView.getMap().remove(chan.getIdLong()));
    }
    try (UnlockHook hook = textView.writeLock()) {
        guild.getTextChannelCache().forEachUnordered(chan -> textView.getMap().remove(chan.getIdLong()));
    }
    try (UnlockHook hook = threadView.writeLock()) {
        guild.getThreadChannelsView().forEachUnordered(chan -> threadView.getMap().remove(chan.getIdLong()));
    }
    try (UnlockHook hook = newsView.writeLock()) {
        guild.getNewsChannelCache().forEachUnordered(chan -> newsView.getMap().remove(chan.getIdLong()));
    }
    try (UnlockHook hook = voiceView.writeLock()) {
        guild.getVoiceChannelCache().forEachUnordered(chan -> voiceView.getMap().remove(chan.getIdLong()));
    }
    try (UnlockHook hook = categoryView.writeLock()) {
        guild.getCategoryCache().forEachUnordered(chan -> categoryView.getMap().remove(chan.getIdLong()));
    }
    // Clear audio connection
    getJDA().getClient().removeAudioConnection(id);
    final AbstractCacheView<AudioManager> audioManagerView = getJDA().getAudioManagersView();
    // read-lock access/release
    final AudioManagerImpl manager = (AudioManagerImpl) audioManagerView.get(id);
    if (manager != null)
        // connection-lock access/release
        manager.closeAudioConnection(ConnectionStatus.DISCONNECTED_REMOVED_FROM_GUILD);
    // write-lock access/release
    audioManagerView.remove(id);
    // cleaning up all users that we do not share a guild with anymore
    // Anything left in memberIds will be removed from the main userMap
    // Use a new HashSet so that we don't actually modify the Member map so it doesn't affect Guild#getMembers for the leave event.
    // copies keys
    TLongSet memberIds = guild.getMembersView().keySet();
    getJDA().getGuildCache().stream().map(GuildImpl.class::cast).forEach(g -> memberIds.removeAll(g.getMembersView().keySet()));
    // Remember, everything left in memberIds is removed from the userMap
    SnowflakeCacheViewImpl<User> userView = getJDA().getUsersView();
    try (UnlockHook hook = userView.writeLock()) {
        long selfId = getJDA().getSelfUser().getIdLong();
        memberIds.forEach(memberId -> {
            if (memberId == selfId)
                // don't remove selfUser from cache
                return true;
            userView.remove(memberId);
            getJDA().getEventCache().clear(EventCache.Type.USER, memberId);
            return true;
        });
    }
    if (unavailable) {
        setupController.onUnavailable(id);
        getJDA().handleEvent(new GuildUnavailableEvent(getJDA(), responseNumber, guild));
    } else {
        getJDA().handleEvent(new GuildLeaveEvent(getJDA(), responseNumber, guild));
    }
    getJDA().getEventCache().clear(EventCache.Type.GUILD, id);
    return null;
}
Also used : GuildLeaveEvent(net.dv8tion.jda.api.events.guild.GuildLeaveEvent) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) AudioManager(net.dv8tion.jda.api.managers.AudioManager) GuildUnavailableEvent(net.dv8tion.jda.api.events.guild.GuildUnavailableEvent) AudioManagerImpl(net.dv8tion.jda.internal.managers.AudioManagerImpl) UnlockHook(net.dv8tion.jda.internal.utils.UnlockHook) TLongSet(gnu.trove.set.TLongSet)

Example 5 with AudioManagerImpl

use of net.dv8tion.jda.internal.managers.AudioManagerImpl in project JDA by DV8FromTheWorld.

the class GuildSetupNode method updateAudioManagerReference.

private void updateAudioManagerReference(GuildImpl guild) {
    JDAImpl api = getController().getJDA();
    AbstractCacheView<AudioManager> managerView = api.getAudioManagersView();
    try (UnlockHook hook = managerView.writeLock()) {
        TLongObjectMap<AudioManager> audioManagerMap = managerView.getMap();
        AudioManagerImpl mng = (AudioManagerImpl) audioManagerMap.get(id);
        if (mng == null)
            return;
        ConnectionListener listener = mng.getConnectionListener();
        final AudioManagerImpl newMng = new AudioManagerImpl(guild);
        newMng.setSelfMuted(mng.isSelfMuted());
        newMng.setSelfDeafened(mng.isSelfDeafened());
        newMng.setQueueTimeout(mng.getConnectTimeout());
        newMng.setSendingHandler(mng.getSendingHandler());
        newMng.setReceivingHandler(mng.getReceivingHandler());
        newMng.setConnectionListener(listener);
        newMng.setAutoReconnect(mng.isAutoReconnect());
        if (mng.isConnected()) {
            final long channelId = mng.getConnectedChannel().getIdLong();
            final VoiceChannel channel = api.getVoiceChannelById(channelId);
            if (channel != null) {
                if (mng.isConnected())
                    mng.closeAudioConnection(ConnectionStatus.ERROR_CANNOT_RESUME);
            } else {
                // The voice channel is not cached. It was probably deleted.
                api.getClient().removeAudioConnection(id);
                if (listener != null)
                    listener.onStatusChange(ConnectionStatus.DISCONNECTED_CHANNEL_DELETED);
            }
        }
        audioManagerMap.put(id, newMng);
    }
}
Also used : AudioManager(net.dv8tion.jda.api.managers.AudioManager) AudioManagerImpl(net.dv8tion.jda.internal.managers.AudioManagerImpl) UnlockHook(net.dv8tion.jda.internal.utils.UnlockHook) VoiceChannel(net.dv8tion.jda.api.entities.VoiceChannel) JDAImpl(net.dv8tion.jda.internal.JDAImpl) ConnectionListener(net.dv8tion.jda.api.audio.hooks.ConnectionListener)

Aggregations

AudioManagerImpl (net.dv8tion.jda.internal.managers.AudioManagerImpl)7 AudioManager (net.dv8tion.jda.api.managers.AudioManager)4 GuildImpl (net.dv8tion.jda.internal.entities.GuildImpl)3 UnlockHook (net.dv8tion.jda.internal.utils.UnlockHook)3 AudioChannel (net.dv8tion.jda.api.entities.AudioChannel)2 Guild (net.dv8tion.jda.api.entities.Guild)2 VoiceDispatchInterceptor (net.dv8tion.jda.api.hooks.VoiceDispatchInterceptor)2 TLongSet (gnu.trove.set.TLongSet)1 OffsetDateTime (java.time.OffsetDateTime)1 Nonnull (javax.annotation.Nonnull)1 ConnectionListener (net.dv8tion.jda.api.audio.hooks.ConnectionListener)1 VoiceChannel (net.dv8tion.jda.api.entities.VoiceChannel)1 GuildLeaveEvent (net.dv8tion.jda.api.events.guild.GuildLeaveEvent)1 GuildUnavailableEvent (net.dv8tion.jda.api.events.guild.GuildUnavailableEvent)1 DataObject (net.dv8tion.jda.api.utils.data.DataObject)1 JDAImpl (net.dv8tion.jda.internal.JDAImpl)1 AudioConnection (net.dv8tion.jda.internal.audio.AudioConnection)1 GuildVoiceStateImpl (net.dv8tion.jda.internal.entities.GuildVoiceStateImpl)1 MemberImpl (net.dv8tion.jda.internal.entities.MemberImpl)1 AudioChannelMixin (net.dv8tion.jda.internal.entities.mixin.channel.middleman.AudioChannelMixin)1