Search in sources :

Example 1 with ThreadChannelImpl

use of net.dv8tion.jda.internal.entities.ThreadChannelImpl in project JDA by DV8FromTheWorld.

the class MessageCreateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    MessageType type = MessageType.fromId(content.getInt("type"));
    if (type == MessageType.UNKNOWN) {
        WebSocketClient.LOG.debug("JDA received a message of unknown type. Type: {}  JSON: {}", type, content);
        return null;
    }
    // Drop ephemeral messages since they are broken due to missing guild_id
    if ((content.getInt("flags", 0) & 64) != 0)
        return null;
    JDAImpl jda = getJDA();
    Guild guild = null;
    if (!content.isNull("guild_id")) {
        long guildId = content.getLong("guild_id");
        if (jda.getGuildSetupController().isLocked(guildId))
            return guildId;
        guild = api.getGuildById(guildId);
        if (guild == null) {
            api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle);
            EventCache.LOG.debug("Received message for a guild that JDA does not currently have cached");
            return null;
        }
    }
    Message message;
    try {
        message = jda.getEntityBuilder().createMessageWithLookup(content, guild, true);
    } catch (IllegalArgumentException e) {
        switch(e.getMessage()) {
            case EntityBuilder.MISSING_CHANNEL:
                {
                    final long channelId = content.getLong("channel_id");
                    jda.getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle);
                    EventCache.LOG.debug("Received a message for a channel that JDA does not currently have cached");
                    return null;
                }
            case EntityBuilder.MISSING_USER:
                {
                    final long authorId = content.getObject("author").getLong("id");
                    jda.getEventCache().cache(EventCache.Type.USER, authorId, responseNumber, allContent, this::handle);
                    EventCache.LOG.debug("Received a message for a user that JDA does not currently have cached");
                    return null;
                }
            case EntityBuilder.UNKNOWN_MESSAGE_TYPE:
                {
                    WebSocketClient.LOG.debug("Ignoring message with unknown type: {}", content);
                    return null;
                }
            default:
                throw e;
        }
    }
    MessageChannel channel = message.getChannel();
    ChannelType channelType = channel.getType();
    // Update the variable that tracks the latest message received in the channel
    ((MessageChannelMixin<?>) channel).setLatestMessageIdLong(message.getIdLong());
    if (channelType.isGuild()) {
        if (channelType.isThread()) {
            ThreadChannelImpl gThread = (ThreadChannelImpl) channel;
            // Discord will only ever allow this property to show up to 50,
            // so we don't want to update it to be over 50 because we don't want users to use it incorrectly.
            int newMessageCount = Math.min(gThread.getMessageCount() + 1, 50);
            gThread.setMessageCount(newMessageCount);
        }
    } else {
        api.usedPrivateChannel(channel.getIdLong());
    }
    jda.handleEvent(new MessageReceivedEvent(jda, responseNumber, message));
    return null;
}
Also used : MessageChannelMixin(net.dv8tion.jda.internal.entities.mixin.channel.middleman.MessageChannelMixin) ThreadChannelImpl(net.dv8tion.jda.internal.entities.ThreadChannelImpl) JDAImpl(net.dv8tion.jda.internal.JDAImpl) MessageReceivedEvent(net.dv8tion.jda.api.events.message.MessageReceivedEvent)

Example 2 with ThreadChannelImpl

use of net.dv8tion.jda.internal.entities.ThreadChannelImpl in project JDA by DV8FromTheWorld.

the class ThreadMembersUpdateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    long guildId = content.getLong("guild_id");
    if (api.getGuildSetupController().isLocked(guildId))
        return guildId;
    final long threadId = content.getLong("id");
    ThreadChannelImpl thread = (ThreadChannelImpl) getJDA().getThreadChannelById(threadId);
    if (thread == null) {
        getJDA().getEventCache().cache(EventCache.Type.CHANNEL, threadId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("THREAD_MEMBERS_UPDATE attempted to update a thread that does not exist. JSON: {}", content);
        return null;
    }
    if (!content.isNull("added_members")) {
        DataArray addedMembersJson = content.getArray("added_members");
        handleAddedThreadMembers(thread, addedMembersJson);
    }
    if (!content.isNull("removed_member_ids")) {
        List<Long> removedMemberIds = content.getArray("removed_member_ids").stream(DataArray::getString).map(MiscUtil::parseSnowflake).collect(Collectors.toList());
        handleRemovedThreadMembers(thread, removedMemberIds);
    }
    return null;
}
Also used : ThreadChannelImpl(net.dv8tion.jda.internal.entities.ThreadChannelImpl) DataArray(net.dv8tion.jda.api.utils.data.DataArray)

Example 3 with ThreadChannelImpl

use of net.dv8tion.jda.internal.entities.ThreadChannelImpl in project JDA by DV8FromTheWorld.

the class MessageDeleteHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    if (!content.isNull("guild_id")) {
        long guildId = content.getLong("guild_id");
        if (getJDA().getGuildSetupController().isLocked(guildId))
            return guildId;
    }
    final long messageId = content.getLong("id");
    final long channelId = content.getLong("channel_id");
    // TODO-v5-unified-channel-cache
    MessageChannel channel = getJDA().getTextChannelById(channelId);
    if (channel == null)
        channel = getJDA().getNewsChannelById(channelId);
    if (channel == null)
        channel = getJDA().getThreadChannelById(channelId);
    if (channel == null)
        channel = getJDA().getPrivateChannelById(channelId);
    if (channel == null) {
        getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("Got message delete for a channel/group that is not yet cached. ChannelId: {}", channelId);
        return null;
    }
    if (channel.getType().isThread()) {
        ThreadChannelImpl gThread = (ThreadChannelImpl) channel;
        // If we have less than 50 messages then we can still accurately track how many messages are in the message count.
        // Once we exceed 50 messages Discord caps this value, so we cannot confidently decrement it.
        int messageCount = gThread.getMessageCount();
        if (messageCount < 50 && messageCount > 0) {
            gThread.setMessageCount(messageCount - 1);
        }
    }
    getJDA().handleEvent(new MessageDeleteEvent(getJDA(), responseNumber, messageId, channel));
    return null;
}
Also used : ThreadChannelImpl(net.dv8tion.jda.internal.entities.ThreadChannelImpl) MessageChannel(net.dv8tion.jda.api.entities.MessageChannel) MessageDeleteEvent(net.dv8tion.jda.api.events.message.MessageDeleteEvent)

Example 4 with ThreadChannelImpl

use of net.dv8tion.jda.internal.entities.ThreadChannelImpl in project JDA by DV8FromTheWorld.

the class ThreadUpdateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    long guildId = content.getLong("guild_id");
    if (api.getGuildSetupController().isLocked(guildId))
        return guildId;
    final long threadId = content.getLong("id");
    ThreadChannelImpl thread = (ThreadChannelImpl) getJDA().getThreadChannelById(threadId);
    // Refer to the documentation for more info: https://discord.com/developers/docs/topics/threads#unarchiving-a-thread
    if (thread == null) {
        // Technically, when the ThreadChannel is unarchived the archive_timestamp (getTimeArchiveInfoLastModified) changes
        // as well, but we don't have the original value because we didn't have the thread in memory, so we can't
        // provide an entirely accurate ChannelUpdateArchiveTimestampEvent. Not sure how much that'll matter.
        thread = (ThreadChannelImpl) api.getEntityBuilder().createThreadChannel(content, guildId);
        api.handleEvent(new ChannelUpdateArchivedEvent(api, responseNumber, thread, true, false));
        return null;
    }
    final DataObject threadMetadata = content.getObject("thread_metadata");
    final String name = content.getString("name");
    final ThreadChannel.AutoArchiveDuration autoArchiveDuration = ThreadChannel.AutoArchiveDuration.fromKey(threadMetadata.getInt("auto_archive_duration"));
    final boolean locked = threadMetadata.getBoolean("locked");
    final boolean archived = threadMetadata.getBoolean("archived");
    final boolean invitable = threadMetadata.getBoolean("invitable");
    final long archiveTimestamp = Helpers.toTimestamp(threadMetadata.getString("archive_timestamp"));
    final int slowmode = content.getInt("rate_limit_per_user", 0);
    final String oldName = thread.getName();
    final ThreadChannel.AutoArchiveDuration oldAutoArchiveDuration = thread.getAutoArchiveDuration();
    final boolean oldLocked = thread.isLocked();
    final boolean oldArchived = thread.isArchived();
    final boolean oldInvitable = !thread.isPublic() && thread.isInvitable();
    final long oldArchiveTimestamp = thread.getArchiveTimestamp();
    final int oldSlowmode = thread.getSlowmode();
    // TODO should these be Thread specific events?
    if (!Objects.equals(oldName, name)) {
        thread.setName(name);
        api.handleEvent(new ChannelUpdateNameEvent(getJDA(), responseNumber, thread, oldName, name));
    }
    if (oldSlowmode != slowmode) {
        thread.setSlowmode(slowmode);
        api.handleEvent(new ChannelUpdateSlowmodeEvent(api, responseNumber, thread, oldSlowmode, slowmode));
    }
    if (oldAutoArchiveDuration != autoArchiveDuration) {
        thread.setAutoArchiveDuration(autoArchiveDuration);
        api.handleEvent(new ChannelUpdateAutoArchiveDurationEvent(api, responseNumber, thread, oldAutoArchiveDuration, autoArchiveDuration));
    }
    if (oldLocked != locked) {
        thread.setLocked(locked);
        api.handleEvent(new ChannelUpdateLockedEvent(api, responseNumber, thread, oldLocked, locked));
    }
    if (oldArchived != archived) {
        thread.setArchived(archived);
        api.handleEvent(new ChannelUpdateArchivedEvent(api, responseNumber, thread, oldArchived, archived));
    }
    if (oldArchiveTimestamp != archiveTimestamp) {
        thread.setArchiveTimestamp(archiveTimestamp);
        api.handleEvent(new ChannelUpdateArchiveTimestampEvent(api, responseNumber, thread, oldArchiveTimestamp, archiveTimestamp));
    }
    if (oldInvitable != invitable) {
        thread.setInvitable(invitable);
        api.handleEvent(new ChannelUpdateInvitableEvent(api, responseNumber, thread, oldInvitable, invitable));
    }
    return null;
}
Also used : ThreadChannelImpl(net.dv8tion.jda.internal.entities.ThreadChannelImpl) DataObject(net.dv8tion.jda.api.utils.data.DataObject) ThreadChannel(net.dv8tion.jda.api.entities.ThreadChannel)

Example 5 with ThreadChannelImpl

use of net.dv8tion.jda.internal.entities.ThreadChannelImpl in project JDA by DV8FromTheWorld.

the class ThreadMemberUpdateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    long guildId = content.getLong("guild_id");
    if (api.getGuildSetupController().isLocked(guildId))
        return guildId;
    final long threadId = content.getLong("id");
    ThreadChannelImpl thread = (ThreadChannelImpl) getJDA().getThreadChannelById(threadId);
    if (thread == null) {
        getJDA().getEventCache().cache(EventCache.Type.CHANNEL, threadId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("THREAD_MEMBER_UPDATE attempted to update a thread that does not exist. JSON: {}", content);
        return null;
    }
    // Based on the docs it is expected that we will only ever receive THREAD_MEMBER_UPDATE when Discord needs to inform
    // us that we are a member of a ThreadChannels that we might not have in memory. Currently this only happens
    // for ThreadChannels that get unarchived.
    // Details available at: https://discord.com/developers/docs/topics/threads#unarchiving-a-thread
    long userId = content.getLong("user_id");
    if (userId != getJDA().getSelfUser().getIdLong()) {
        JDAImpl.LOG.warn("Received a THREAD_MEMBER_UPDATE for a user that isn't the current bot user. " + "This validates assumptions that THREAD_MEMBER_UPDATE would ONLY be for the current bot user. " + "Skipping this dispatch for now. This should be reported as a bug." + "\nDetails: {}", content);
        return null;
    }
    CacheView.SimpleCacheView<ThreadMember> view = thread.getThreadMemberView();
    try (UnlockHook lock = view.writeLock()) {
        // We might have still had the ThreadChannel in memory, so our ThreadMember might still exist. Do an existence check.
        ThreadMember threadMember = view.getMap().get(userId);
        if (threadMember == null) {
            threadMember = api.getEntityBuilder().createThreadMember(thread, thread.getGuild().getSelfMember(), content);
            view.getMap().put(threadMember.getIdLong(), threadMember);
        }
    }
    return null;
}
Also used : ThreadChannelImpl(net.dv8tion.jda.internal.entities.ThreadChannelImpl) CacheView(net.dv8tion.jda.api.utils.cache.CacheView) UnlockHook(net.dv8tion.jda.internal.utils.UnlockHook) ThreadMember(net.dv8tion.jda.api.entities.ThreadMember)

Aggregations

ThreadChannelImpl (net.dv8tion.jda.internal.entities.ThreadChannelImpl)5 MessageChannel (net.dv8tion.jda.api.entities.MessageChannel)1 ThreadChannel (net.dv8tion.jda.api.entities.ThreadChannel)1 ThreadMember (net.dv8tion.jda.api.entities.ThreadMember)1 MessageDeleteEvent (net.dv8tion.jda.api.events.message.MessageDeleteEvent)1 MessageReceivedEvent (net.dv8tion.jda.api.events.message.MessageReceivedEvent)1 CacheView (net.dv8tion.jda.api.utils.cache.CacheView)1 DataArray (net.dv8tion.jda.api.utils.data.DataArray)1 DataObject (net.dv8tion.jda.api.utils.data.DataObject)1 JDAImpl (net.dv8tion.jda.internal.JDAImpl)1 MessageChannelMixin (net.dv8tion.jda.internal.entities.mixin.channel.middleman.MessageChannelMixin)1 UnlockHook (net.dv8tion.jda.internal.utils.UnlockHook)1