Search in sources :

Example 1 with EmoteImpl

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

the class GuildEmojisUpdateHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    if (!getJDA().isCacheFlagSet(CacheFlag.EMOTE))
        return null;
    final long guildId = content.getLong("guild_id");
    if (getJDA().getGuildSetupController().isLocked(guildId))
        return guildId;
    GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId);
    if (guild == null) {
        getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle);
        return null;
    }
    DataArray array = content.getArray("emojis");
    List<Emote> oldEmotes, newEmotes;
    SnowflakeCacheViewImpl<Emote> emoteView = guild.getEmotesView();
    try (UnlockHook hook = emoteView.writeLock()) {
        TLongObjectMap<Emote> emoteMap = emoteView.getMap();
        // snapshot of emote cache
        oldEmotes = new ArrayList<>(emoteMap.valueCollection());
        newEmotes = new ArrayList<>();
        for (int i = 0; i < array.length(); i++) {
            DataObject current = array.getObject(i);
            final long emoteId = current.getLong("id");
            EmoteImpl emote = (EmoteImpl) emoteMap.get(emoteId);
            EmoteImpl oldEmote = null;
            if (emote == null) {
                emote = new EmoteImpl(emoteId, guild);
                newEmotes.add(emote);
            } else {
                // emote is in our cache which is why we don't want to remove it in cleanup later
                oldEmotes.remove(emote);
                oldEmote = emote.clone();
            }
            emote.setName(current.getString("name")).setAnimated(current.getBoolean("animated")).setManaged(current.getBoolean("managed"));
            // update roles
            DataArray roles = current.getArray("roles");
            Set<Role> newRoles = emote.getRoleSet();
            // snapshot of cached roles
            Set<Role> oldRoles = new HashSet<>(newRoles);
            for (int j = 0; j < roles.length(); j++) {
                Role role = guild.getRoleById(roles.getString(j));
                if (role != null) {
                    newRoles.add(role);
                    oldRoles.remove(role);
                }
            }
            // cleanup old cached roles that were not found in the JSONArray
            for (Role r : oldRoles) {
                // newRoles directly writes to the set contained in the emote
                newRoles.remove(r);
            }
            // finally, update the emote
            emoteMap.put(emote.getIdLong(), emote);
            // check for updated fields and fire events
            handleReplace(oldEmote, emote);
        }
        for (Emote e : oldEmotes) emoteMap.remove(e.getIdLong());
    }
    // cleanup old emotes that don't exist anymore
    for (Emote e : oldEmotes) {
        getJDA().handleEvent(new EmoteRemovedEvent(getJDA(), responseNumber, e));
    }
    for (Emote e : newEmotes) {
        getJDA().handleEvent(new EmoteAddedEvent(getJDA(), responseNumber, e));
    }
    return null;
}
Also used : EmoteRemovedEvent(net.dv8tion.jda.api.events.emote.EmoteRemovedEvent) Emote(net.dv8tion.jda.api.entities.Emote) DataArray(net.dv8tion.jda.api.utils.data.DataArray) Role(net.dv8tion.jda.api.entities.Role) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) EmoteImpl(net.dv8tion.jda.internal.entities.EmoteImpl) DataObject(net.dv8tion.jda.api.utils.data.DataObject) UnlockHook(net.dv8tion.jda.internal.utils.UnlockHook) EmoteAddedEvent(net.dv8tion.jda.api.events.emote.EmoteAddedEvent)

Example 2 with EmoteImpl

use of net.dv8tion.jda.internal.entities.EmoteImpl in project pokeraidbot by magnusmickelsson.

the class InstallEmotesCommand method createEmote.

// Code taken from JDA's GuildController since they have a limitation that bot accounts can't upload emotes.
private void createEmote(String iconName, CommandEvent commandEvent, Icon icon, Role... roles) {
    JSONObject body = new JSONObject();
    body.put("name", iconName);
    body.put("image", icon.getEncoding());
    if (// making sure none of the provided roles are null before mapping them to the snowflake id
    roles.length > 0) {
        body.put("roles", Stream.of(roles).filter(Objects::nonNull).map(ISnowflake::getId).collect(Collectors.toSet()));
    }
    StringWriter writer = new StringWriter();
    body.write(writer);
    DataObject dataObject = DataObject.fromJson(writer.toString());
    GuildImpl guild = (GuildImpl) commandEvent.getGuild();
    JDA jda = commandEvent.getJDA();
    Route.CompiledRoute route = Route.Emotes.CREATE_EMOTE.compile(guild.getId());
    AuditableRestAction<Emote> action = new AuditableRestActionImpl<Emote>(jda, route, dataObject) {

        @Override
        public void handleResponse(Response response, Request<Emote> request) {
            if (response.isOk()) {
                DataObject obj = response.getObject();
                final long id = obj.getLong("id");
                String name = obj.getString("name");
                EmoteImpl emote = new EmoteImpl(id, guild).setName(name);
                // managed is false by default, should always be false for emotes created by client accounts.
                DataArray rolesArr = obj.getArray("roles");
                Set<Role> roleSet = emote.getRoleSet();
                for (int i = 0; i < rolesArr.length(); i++) {
                    roleSet.add(guild.getRoleById(rolesArr.getString(i)));
                }
                // put emote into cache
                guild.createEmote(name, icon, roles);
                request.onSuccess(emote);
            } else {
                request.onFailure(response);
                throw new RuntimeException("Couldn't install emojis. " + "Make sure that pokeraidbot has access to manage emojis.");
            }
        }
    };
    action.queue();
}
Also used : JDA(net.dv8tion.jda.api.JDA) Emote(net.dv8tion.jda.api.entities.Emote) Request(net.dv8tion.jda.api.requests.Request) DataArray(net.dv8tion.jda.api.utils.data.DataArray) Response(net.dv8tion.jda.api.requests.Response) Role(net.dv8tion.jda.api.entities.Role) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) EmoteImpl(net.dv8tion.jda.internal.entities.EmoteImpl) DataObject(net.dv8tion.jda.api.utils.data.DataObject) AuditableRestActionImpl(net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl) JSONObject(org.json.JSONObject) StringWriter(java.io.StringWriter) Route(net.dv8tion.jda.internal.requests.Route) ISnowflake(net.dv8tion.jda.api.entities.ISnowflake)

Example 3 with EmoteImpl

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

the class GuildRoleDeleteHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    final long guildId = content.getLong("guild_id");
    if (getJDA().getGuildSetupController().isLocked(guildId))
        return guildId;
    GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId);
    if (guild == null) {
        getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle);
        EventCache.LOG.debug("GUILD_ROLE_DELETE was received for a Guild that is not yet cached: {}", content);
        return null;
    }
    final long roleId = content.getLong("role_id");
    Role removedRole = guild.getRolesView().remove(roleId);
    if (removedRole == null) {
        // getJDA().getEventCache().cache(EventCache.Type.ROLE, roleId, () -> handle(responseNumber, allContent));
        WebSocketClient.LOG.debug("GUILD_ROLE_DELETE was received for a Role that is not yet cached: {}", content);
        return null;
    }
    // Now that the role is removed from the Guild, remove it from all users and emotes.
    guild.getMembersView().forEach(m -> {
        MemberImpl member = (MemberImpl) m;
        member.getRoleSet().remove(removedRole);
    });
    for (Emote emote : guild.getEmoteCache()) {
        EmoteImpl impl = (EmoteImpl) emote;
        if (impl.canProvideRoles())
            impl.getRoleSet().remove(removedRole);
    }
    getJDA().handleEvent(new RoleDeleteEvent(getJDA(), responseNumber, removedRole));
    getJDA().getEventCache().clear(EventCache.Type.ROLE, roleId);
    return null;
}
Also used : Role(net.dv8tion.jda.api.entities.Role) GuildImpl(net.dv8tion.jda.internal.entities.GuildImpl) EmoteImpl(net.dv8tion.jda.internal.entities.EmoteImpl) RoleDeleteEvent(net.dv8tion.jda.api.events.role.RoleDeleteEvent) MemberImpl(net.dv8tion.jda.internal.entities.MemberImpl) Emote(net.dv8tion.jda.api.entities.Emote)

Example 4 with EmoteImpl

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

the class MessageReactionHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    if (!content.isNull("guild_id")) {
        long guildId = content.getLong("guild_id");
        if (api.getGuildSetupController().isLocked(guildId))
            return guildId;
    }
    DataObject emoji = content.getObject("emoji");
    final long userId = content.getLong("user_id");
    final long messageId = content.getLong("message_id");
    final long channelId = content.getLong("channel_id");
    final Long emojiId = emoji.isNull("id") ? null : emoji.getLong("id");
    String emojiName = emoji.getString("name", null);
    final boolean emojiAnimated = emoji.getBoolean("animated");
    if (emojiId == null && emojiName == null) {
        WebSocketClient.LOG.debug("Received a reaction {} with no name nor id. json: {}", JDALogger.getLazyString(() -> add ? "add" : "remove"), content);
        return null;
    }
    final long guildId = content.getUnsignedLong("guild_id", 0);
    Guild guild = api.getGuildById(guildId);
    MemberImpl member = null;
    if (guild != null) {
        member = (MemberImpl) guild.getMemberById(userId);
        // Attempt loading the member if possible
        Optional<DataObject> memberJson = content.optObject("member");
        if (// Check if we can load a member here
        memberJson.isPresent()) {
            DataObject json = memberJson.get();
            if (// do we need to load a member?
            member == null || !member.hasTimeJoined())
                member = api.getEntityBuilder().createMember((GuildImpl) guild, json);
            else // otherwise update the cache
            {
                List<Role> roles = json.getArray("roles").stream(DataArray::getUnsignedLong).map(guild::getRoleById).filter(Objects::nonNull).collect(Collectors.toList());
                api.getEntityBuilder().updateMember((GuildImpl) guild, member, json, roles);
            }
            // update internal references
            api.getEntityBuilder().updateMemberCache(member);
        }
        if (member == null && add && guild.isLoaded()) {
            WebSocketClient.LOG.debug("Dropping reaction event for unknown member {}", content);
            return null;
        }
    }
    User user = api.getUserById(userId);
    if (user == null && member != null)
        // this happens when we have guild subscriptions disabled
        user = member.getUser();
    if (user == null) {
        // The only time we can receive a reaction add but not have the user cached would be if we receive the event in an uncached or partially built PrivateChannel.
        if (add && guild != null) {
            api.getEventCache().cache(EventCache.Type.USER, userId, responseNumber, allContent, this::handle);
            EventCache.LOG.debug("Received a reaction for a user that JDA does not currently have cached. " + "UserID: {} ChannelId: {} MessageId: {}", userId, channelId, messageId);
            return null;
        }
    }
    // TODO-v5-unified-channel-cache
    MessageChannel channel = api.getTextChannelById(channelId);
    if (channel == null)
        channel = api.getNewsChannelById(channelId);
    if (channel == null)
        channel = api.getThreadChannelById(channelId);
    if (channel == null)
        channel = api.getPrivateChannelById(channelId);
    if (channel == null) {
        if (guildId != 0) {
            api.getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle);
            EventCache.LOG.debug("Received a reaction for a channel that JDA does not currently have cached");
            return null;
        }
        // create a new private channel with minimal information for this event
        channel = getJDA().getEntityBuilder().createPrivateChannel(DataObject.empty().put("id", channelId));
    }
    MessageReaction.ReactionEmote rEmote;
    if (emojiId != null) {
        Emote emote = api.getEmoteById(emojiId);
        if (emote == null) {
            if (emojiName != null) {
                emote = new EmoteImpl(emojiId, api).setAnimated(emojiAnimated).setName(emojiName);
            } else {
                WebSocketClient.LOG.debug("Received a reaction {} with a null name. json: {}", JDALogger.getLazyString(() -> add ? "add" : "remove"), content);
                return null;
            }
        }
        rEmote = MessageReaction.ReactionEmote.fromCustom(emote);
    } else {
        rEmote = MessageReaction.ReactionEmote.fromUnicode(emojiName, api);
    }
    MessageReaction reaction = new MessageReaction(channel, rEmote, messageId, userId == api.getSelfUser().getIdLong(), -1);
    if (channel.getType() == ChannelType.PRIVATE) {
        api.usedPrivateChannel(reaction.getChannel().getIdLong());
        PrivateChannelImpl priv = (PrivateChannelImpl) channel;
        // try to add the user here if we need to, as we have their ID
        if (priv.getUser() == null && user != null) {
            priv.setUser(user);
        }
    }
    if (add) {
        api.handleEvent(new MessageReactionAddEvent(api, responseNumber, user, member, reaction, userId));
    } else {
        api.handleEvent(new MessageReactionRemoveEvent(api, responseNumber, user, member, reaction, userId));
    }
    return null;
}
Also used : MessageReactionAddEvent(net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent) MessageReactionRemoveEvent(net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEvent) MemberImpl(net.dv8tion.jda.internal.entities.MemberImpl) PrivateChannelImpl(net.dv8tion.jda.internal.entities.PrivateChannelImpl) EmoteImpl(net.dv8tion.jda.internal.entities.EmoteImpl) DataObject(net.dv8tion.jda.api.utils.data.DataObject)

Example 5 with EmoteImpl

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

the class MessageReactionClearEmoteHandler method handleInternally.

@Override
protected Long handleInternally(DataObject content) {
    long guildId = content.getUnsignedLong("guild_id");
    if (getJDA().getGuildSetupController().isLocked(guildId))
        return guildId;
    Guild guild = getJDA().getGuildById(guildId);
    if (guild == null) {
        EventCache.LOG.debug("Caching MESSAGE_REACTION_REMOVE_EMOJI event for unknown guild {}", guildId);
        getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle);
        return null;
    }
    long channelId = content.getUnsignedLong("channel_id");
    // TODO-v5-unified-channel-cache
    GuildMessageChannel channel = guild.getTextChannelById(channelId);
    if (channel == null)
        channel = guild.getNewsChannelById(channelId);
    if (channel == null)
        channel = guild.getThreadChannelById(channelId);
    if (channel == null) {
        EventCache.LOG.debug("Caching MESSAGE_REACTION_REMOVE_EMOJI event for unknown channel {}", channelId);
        getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle);
        return null;
    }
    long messageId = content.getUnsignedLong("message_id");
    DataObject emoji = content.getObject("emoji");
    MessageReaction.ReactionEmote reactionEmote = null;
    if (emoji.isNull("id")) {
        reactionEmote = MessageReaction.ReactionEmote.fromUnicode(emoji.getString("name"), getJDA());
    } else {
        long emoteId = emoji.getUnsignedLong("id");
        Emote emote = getJDA().getEmoteById(emoteId);
        if (emote == null) {
            emote = new EmoteImpl(emoteId, getJDA()).setAnimated(emoji.getBoolean("animated")).setName(emoji.getString("name", ""));
        }
        reactionEmote = MessageReaction.ReactionEmote.fromCustom(emote);
    }
    MessageReaction reaction = new MessageReaction(channel, reactionEmote, messageId, false, 0);
    getJDA().handleEvent(new MessageReactionRemoveEmoteEvent(getJDA(), responseNumber, messageId, channel, reaction));
    return null;
}
Also used : MessageReaction(net.dv8tion.jda.api.entities.MessageReaction) EmoteImpl(net.dv8tion.jda.internal.entities.EmoteImpl) MessageReactionRemoveEmoteEvent(net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEmoteEvent) DataObject(net.dv8tion.jda.api.utils.data.DataObject) Emote(net.dv8tion.jda.api.entities.Emote) Guild(net.dv8tion.jda.api.entities.Guild) GuildMessageChannel(net.dv8tion.jda.api.entities.GuildMessageChannel)

Aggregations

EmoteImpl (net.dv8tion.jda.internal.entities.EmoteImpl)5 Emote (net.dv8tion.jda.api.entities.Emote)4 DataObject (net.dv8tion.jda.api.utils.data.DataObject)4 Role (net.dv8tion.jda.api.entities.Role)3 GuildImpl (net.dv8tion.jda.internal.entities.GuildImpl)3 DataArray (net.dv8tion.jda.api.utils.data.DataArray)2 MemberImpl (net.dv8tion.jda.internal.entities.MemberImpl)2 StringWriter (java.io.StringWriter)1 JDA (net.dv8tion.jda.api.JDA)1 Guild (net.dv8tion.jda.api.entities.Guild)1 GuildMessageChannel (net.dv8tion.jda.api.entities.GuildMessageChannel)1 ISnowflake (net.dv8tion.jda.api.entities.ISnowflake)1 MessageReaction (net.dv8tion.jda.api.entities.MessageReaction)1 EmoteAddedEvent (net.dv8tion.jda.api.events.emote.EmoteAddedEvent)1 EmoteRemovedEvent (net.dv8tion.jda.api.events.emote.EmoteRemovedEvent)1 MessageReactionAddEvent (net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent)1 MessageReactionRemoveEmoteEvent (net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEmoteEvent)1 MessageReactionRemoveEvent (net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEvent)1 RoleDeleteEvent (net.dv8tion.jda.api.events.role.RoleDeleteEvent)1 Request (net.dv8tion.jda.api.requests.Request)1