Skip to content

Instantly share code, notes, and snippets.

@Almighty-Alpaca
Created January 12, 2017 20:36
Show Gist options
  • Save Almighty-Alpaca/32629893e9cd305f1165652c80726b41 to your computer and use it in GitHub Desktop.
Save Almighty-Alpaca/32629893e9cd305f1165652c80726b41 to your computer and use it in GitHub Desktop.
A message cache for jda
package com.almightyalpaca.jda.messagecache;
import java.lang.reflect.Field;
import java.util.*;
import org.apache.http.util.Args;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.MessageChannel;
import net.dv8tion.jda.core.entities.MessageReaction;
import net.dv8tion.jda.core.entities.impl.MessageImpl;
import net.dv8tion.jda.core.events.Event;
import net.dv8tion.jda.core.events.message.MessageBulkDeleteEvent;
import net.dv8tion.jda.core.events.message.MessageDeleteEvent;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.events.message.MessageUpdateEvent;
import net.dv8tion.jda.core.events.message.react.GenericMessageReactionEvent;
import net.dv8tion.jda.core.hooks.EventListener;
import net.dv8tion.jda.core.hooks.SubscribeEvent;
import net.dv8tion.jda.core.requests.RestAction;
public class MessageCache implements EventListener
{
private final JDA api;
private final Field MESSAGE_REACTION_LIST;
private final Map<String, Message> messageMap;
public MessageCache(final JDA api, final boolean weak)
{
this.api = Args.notNull(api, "api");
this.messageMap = Collections.synchronizedMap(weak ? new WeakHashMap<String, Message>() : new HashMap<String, Message>());
try
{
this.MESSAGE_REACTION_LIST = MessageImpl.class.getDeclaredField("reactions");
this.MESSAGE_REACTION_LIST.setAccessible(true);
}
catch (NoSuchFieldException | SecurityException e)
{
throw new RuntimeException(e);
}
this.api.addEventListener(this);
}
public void clear()
{
this.messageMap.clear();
}
public Collection<Message> getCachedMessages()
{
return this.messageMap.values();
}
public RestAction<Message> getMessage(final MessageChannel channel, final String Id)
{
final Message message = this.getMessage(Id);
if (message == null)
return channel.getMessageById(Id);
else
return new RestAction.EmptyRestAction<>(message);
}
public Message getMessage(final String Id)
{
return this.messageMap.get(Id);
}
public RestAction<Message> getMessage(final String channelId, final String Id)
{
final Message message = this.getMessage(Id);
if (message == null)
{
MessageChannel channel = this.api.getTextChannelById(channelId);
if (channel == null)
channel = this.api.getPrivateChannelById(channelId);
if (channel != null)
return channel.getMessageById(Id);
}
return new RestAction.EmptyRestAction<>(message);
}
@SuppressWarnings("unchecked")
private List<MessageReaction> getReactions(final MessageImpl messageImpl)
{
try
{
return (List<MessageReaction>) this.MESSAGE_REACTION_LIST.get(messageImpl);
}
catch (final Exception e)
{
throw new RuntimeException(e);
}
}
@Override
@SubscribeEvent
public void onEvent(final Event event)
{
if (event instanceof MessageReceivedEvent)
{
final Message message = ((MessageReceivedEvent) event).getMessage();
this.messageMap.put(message.getId(), message);
}
if (event instanceof MessageDeleteEvent)
this.messageMap.remove(((MessageDeleteEvent) event).getMessageId());
if (event instanceof MessageBulkDeleteEvent)
this.messageMap.keySet().removeAll(((MessageBulkDeleteEvent) event).getMessageIds());
if (event instanceof MessageUpdateEvent)
{
final Message message = ((MessageUpdateEvent) event).getMessage();
this.messageMap.put(message.getId(), message);
}
if (event instanceof GenericMessageReactionEvent)
{
final GenericMessageReactionEvent reactionAddEvent = (GenericMessageReactionEvent) event;
final Message message = this.messageMap.get(reactionAddEvent.getMessageId());
if (message != null)
{
final MessageImpl messageImpl = (MessageImpl) message;
final MessageReaction messageReaction = reactionAddEvent.getReaction();
final List<MessageReaction> reactions = this.getReactions(messageImpl);
synchronized (messageImpl)
{
for (final MessageReaction oldReaction : reactions)
if (oldReaction.getEmote().equals(messageReaction.getEmote()))
reactions.remove(oldReaction);
reactions.add(messageReaction);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment