Skip to content

Commit

Permalink
Simplistic initial data cache system, for #25
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Nov 24, 2019
1 parent 8d08e25 commit 4ebca0a
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 59 deletions.
164 changes: 159 additions & 5 deletions src/main/java/com/denizenscript/ddiscordbot/DiscordConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
import discord4j.core.DiscordClient;
import discord4j.core.event.EventDispatcher;
import discord4j.core.event.domain.Event;
import discord4j.core.event.domain.guild.MemberJoinEvent;
import discord4j.core.event.domain.guild.MemberLeaveEvent;
import discord4j.core.event.domain.guild.MemberUpdateEvent;
import discord4j.core.event.domain.UserUpdateEvent;
import discord4j.core.event.domain.channel.*;
import discord4j.core.event.domain.guild.*;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.event.domain.message.MessageDeleteEvent;
import discord4j.core.event.domain.message.MessageUpdateEvent;
import discord4j.core.object.entity.*;
import discord4j.core.object.util.Snowflake;
import org.bukkit.Bukkit;

import java.util.ArrayList;

public class DiscordConnection {

public String botID;
Expand All @@ -20,8 +24,13 @@ public class DiscordConnection {

public void registerHandlers() {
EventDispatcher events = client.getEventDispatcher();
registerScriptEventHandlers(events);
registerCacheTrackers(events);
}

public void registerScriptEventHandlers(EventDispatcher events) {
events.on(MessageCreateEvent.class).subscribe(event ->
autoHandle(event, DiscordMessageReceivedScriptEvent.instance));
autoHandle(event, DiscordMessageReceivedScriptEvent.instance));
events.on(MessageUpdateEvent.class).subscribe(event ->
autoHandle(event, DiscordMessageModifiedScriptEvent.instance));
events.on(MessageDeleteEvent.class).subscribe(event ->
Expand All @@ -31,7 +40,7 @@ public void registerHandlers() {
events.on(MemberLeaveEvent.class).subscribe(event ->
autoHandle(event, DiscordUserLeavesScriptEvent.instance));
events.on(MemberUpdateEvent.class).subscribe(event ->
autoHandle(event, DiscordUserRoleChangeScriptEvent.instance));
autoHandle(event, DiscordUserRoleChangeScriptEvent.instance));
}

public void autoHandle(Event event, DiscordScriptEvent scriptEvent) {
Expand All @@ -45,4 +54,149 @@ public void autoHandle(Event event, DiscordScriptEvent scriptEvent) {
scriptEvent.fire();
});
}

public static class UserCache {
public long id;
public String username;
public String discriminator;
public UserCache(Member member) {
id = member.getId().asLong();
username = member.getUsername();
discriminator = member.getDiscriminator();
}
}

public static class ChannelCache {
public long id;
public String name;
public long guildId;
public ChannelCache(GuildChannel channel) {
id = channel.getId().asLong();
name = channel.getName();
guildId = channel.getGuildId().asLong();
}
}

public static class GuildCache {
public long id;
public String name;
public ArrayList<ChannelCache> channels = new ArrayList<>();
public ArrayList<UserCache> users = new ArrayList<>();
}

public ArrayList<GuildCache> guildsCached = new ArrayList<>();

public void uncacheGuild(long id) {
synchronized (this) {
for (int i = 0; i < guildsCached.size(); i++) {
if (guildsCached.get(i).id == id) {
guildsCached.remove(i);
return;
}
}
}
}

public GuildCache cacheGuild(Guild guild) {
uncacheGuild(guild.getId().asLong());
GuildCache cache = new GuildCache();
cache.id = guild.getId().asLong();
cache.name = guild.getName();
for (GuildChannel channel : guild.getChannels().toIterable()) {
cache.channels.add(new ChannelCache(channel));
}
for (Member member : guild.getMembers().toIterable()) {
cache.users.add(new UserCache(member));
}
synchronized (this) {
guildsCached.add(cache);
}
return cache;
}

public GuildCache getCachedGuild(long id) {
for (GuildCache cache : guildsCached) {
if (cache.id == id) {
return cache;
}
}
Guild guild = client.getGuildById(Snowflake.of(id)).defaultIfEmpty(null).block();
if (guild == null) {
return null;
}
return cacheGuild(guild);
}

public void newMember(long guild, Member member) {
GuildCache cache = getCachedGuild(guild);
synchronized (this) {
cache.users.add(new UserCache(member));
}
}

public void memberLeave(long guild, long userId) {
GuildCache cache = getCachedGuild(guild);
synchronized (this) {
for (int i = 0; i < cache.users.size(); i++) {
if (cache.users.get(i).id == userId) {
cache.users.remove(i);
return;
}
}
}
}

public void userUpdate(User user) {
long id = user.getId().asLong();
for (GuildCache cache : guildsCached) {
for (UserCache userCache : cache.users) {
if (userCache.id == id) {
userCache.username = user.getUsername();
userCache.discriminator = user.getDiscriminator();
}
}
}
}

public void uncacheChannel(GuildCache cache, long channelId) {
synchronized (this) {
for (int i = 0; i < cache.channels.size(); i++) {
if (cache.channels.get(i).id == channelId) {
cache.channels.remove(i);
return;
}
}
}
}

public void channelCreate(Channel channel) {
if (!(channel instanceof GuildChannel)) {
return;
}
GuildCache cache = getCachedGuild(((GuildChannel) channel).getGuildId().asLong());
uncacheChannel(cache, channel.getId().asLong());
synchronized (this) {
cache.channels.add(new ChannelCache((GuildChannel) channel));
}
}

public void channelDelete(long guildId, long channelId) {
GuildCache cache = getCachedGuild(guildId);
uncacheChannel(cache, channelId);
}

public void registerCacheTrackers(EventDispatcher events) {
events.on(GuildCreateEvent.class).subscribe(event -> cacheGuild(event.getGuild()));
events.on(GuildUpdateEvent.class).subscribe(event -> cacheGuild(event.getCurrent()));
events.on(GuildDeleteEvent.class).subscribe(event -> uncacheGuild(event.getGuildId().asLong()));
events.on(MemberJoinEvent.class).subscribe(event -> newMember(event.getGuildId().asLong(), event.getMember()));
events.on(MemberLeaveEvent.class).subscribe(event -> memberLeave(event.getGuildId().asLong(), event.getUser().getId().asLong()));
events.on(UserUpdateEvent.class).subscribe(event -> userUpdate(event.getCurrent()));
events.on(TextChannelCreateEvent.class).subscribe(event -> channelCreate(event.getChannel()));
events.on(VoiceChannelCreateEvent.class).subscribe(event -> channelCreate(event.getChannel()));
events.on(TextChannelUpdateEvent.class).subscribe(event -> channelCreate(event.getCurrent()));
events.on(VoiceChannelUpdateEvent.class).subscribe(event -> channelCreate(event.getCurrent()));
events.on(TextChannelDeleteEvent.class).subscribe(event -> channelDelete(event.getChannel().getGuildId().asLong(), event.getChannel().getId().asLong()));
events.on(VoiceChannelDeleteEvent.class).subscribe(event -> channelDelete(event.getChannel().getGuildId().asLong(), event.getChannel().getId().asLong()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.tags.ObjectTagProcessor;
import com.denizenscript.denizencore.tags.TagRunnable;
import discord4j.core.object.entity.Guild;
import com.denizenscript.denizencore.tags.Attribute;
import com.denizenscript.denizencore.tags.TagContext;
import com.denizenscript.denizencore.utilities.CoreUtilities;
Expand Down Expand Up @@ -118,8 +117,8 @@ public static void registerTags() {
return null;
}
ListTag list = new ListTag();
for (Guild guild : connection.client.getGuilds().toIterable()) {
list.addObject(new DiscordGroupTag(object.bot, guild));
for (DiscordConnection.GuildCache guild : connection.guildsCached) {
list.addObject(new DiscordGroupTag(object.bot, guild.id));
}
return list;

Expand All @@ -141,9 +140,9 @@ public static void registerTags() {
return null;
}
String matchString = CoreUtilities.toLowerCase(attribute.getContext(1));
Guild bestMatch = null;
for (Guild guild : connection.client.getGuilds().toIterable()) {
String guildName = CoreUtilities.toLowerCase(guild.getName());
DiscordConnection.GuildCache bestMatch = null;
for (DiscordConnection.GuildCache guild : connection.guildsCached) {
String guildName = CoreUtilities.toLowerCase(guild.name);
if (matchString.equals(guildName)) {
bestMatch = guild;
break;
Expand All @@ -155,7 +154,7 @@ public static void registerTags() {
if (bestMatch == null) {
return null;
}
return new DiscordGroupTag(object.bot, bestMatch);
return new DiscordGroupTag(object.bot, bestMatch.id);

});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import com.denizenscript.denizencore.tags.ObjectTagProcessor;
import com.denizenscript.denizencore.tags.TagRunnable;
import discord4j.core.object.entity.*;
import discord4j.core.object.util.Snowflake;
import com.denizenscript.denizencore.tags.Attribute;
import com.denizenscript.denizencore.tags.TagContext;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import discord4j.core.object.util.Snowflake;

public class DiscordChannelTag implements ObjectTag {

Expand Down Expand Up @@ -80,12 +80,6 @@ public static boolean matches(String arg) {
public DiscordChannelTag(String bot, long channelId) {
this.bot = bot;
this.channel_id = channelId;
if (bot != null) {
DiscordConnection conn = DenizenDiscordBot.instance.connections.get(bot);
if (conn != null) {
channel = conn.client.getChannelById(Snowflake.of(channel_id)).block();
}
}
}

public DiscordChannelTag(String bot, Channel channel) {
Expand All @@ -94,6 +88,29 @@ public DiscordChannelTag(String bot, Channel channel) {
channel_id = channel.getId().asLong();
}

public DiscordConnection getBot() {
return DenizenDiscordBot.instance.connections.get(bot);
}

public DiscordConnection.ChannelCache getCacheChannel() {
for (DiscordConnection.GuildCache cache : getBot().guildsCached) {
for (DiscordConnection.ChannelCache chan : cache.channels) {
if (chan.id == channel_id) {
return chan;
}
}
}
return null;
}

public Channel getChannel() {
if (channel != null) {
return channel;
}
channel = getBot().client.getChannelById(Snowflake.of(channel_id)).block();
return channel;
}

public Channel channel;

public String bot;
Expand All @@ -110,7 +127,11 @@ public static void registerTags() {
// Returns the name of the channel.
// -->
registerTag("name", (attribute, object) -> {
Channel chan = object.channel;
DiscordConnection.ChannelCache cache = object.getCacheChannel();
if (cache != null) {
return new ElementTag(cache.name);
}
Channel chan = object.getChannel();
String name;
if (chan instanceof GuildChannel) {
name = ((GuildChannel) chan).getName();
Expand All @@ -134,7 +155,7 @@ else if (chan instanceof PrivateChannel) {
// Will be any of: GUILD_TEXT, DM, GUILD_VOICE, GROUP_DM, GUILD_CATEGORY
// -->
registerTag("type", (attribute, object) -> {
return new ElementTag(object.channel.getType().name());
return new ElementTag(object.getChannel().getType().name());

});

Expand All @@ -158,7 +179,7 @@ else if (chan instanceof PrivateChannel) {
// Returns the raw mention string for the channel.
// -->
registerTag("mention", (attribute, object) -> {
return new ElementTag(object.channel.getMention());
return new ElementTag("<#" + Snowflake.of(object.getCacheChannel().id).asString() + ">");

});

Expand All @@ -170,7 +191,11 @@ else if (chan instanceof PrivateChannel) {
// Returns the group that owns this channel.
// -->
registerTag("group", (attribute, object) -> {
Channel chan = object.channel;
DiscordConnection.ChannelCache cache = object.getCacheChannel();
if (cache != null) {
return new DiscordGroupTag(object.bot, cache.guildId);
}
Channel chan = object.getChannel();
Guild guild;
if (chan instanceof GuildChannel) {
guild = ((GuildChannel) chan).getGuild().block();
Expand Down
Loading

0 comments on commit 4ebca0a

Please sign in to comment.