forked from SteamWar/SteamWar
Merge pull request 'Improve and fix the discord rate limit warnings' (#37) from VelocityCore/ImproveDiscordChannel into main
Reviewed-on: SteamWar/SteamWar#37 Reviewed-by: Lixfel <lixfel@noreply.localhost>
This commit is contained in:
@@ -167,14 +167,19 @@ public class DiscordBot {
|
|||||||
checklistChannel = new ChecklistChannel(config.channel("checklist"));
|
checklistChannel = new ChecklistChannel(config.channel("checklist"));
|
||||||
config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId)));
|
config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId)));
|
||||||
|
|
||||||
announcementChannel = new DiscordChannel(config.channel("announcement")) {
|
announcementChannel = new DiscordChannel(config.channel("announcement"), 0) {
|
||||||
@Override
|
@Override
|
||||||
public void received(MessageReceivedEvent event) {
|
public void received(MessageReceivedEvent event) {
|
||||||
Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay());
|
Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast);
|
|
||||||
serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam);
|
// There is a hard limit of 30 messages per minute to send as a webhook, thus with 8 webhooks we can send
|
||||||
|
// 240 messages per minute. Which means 4 every second. I looked at the WGS fights and there were around
|
||||||
|
// ~70 in a short burst and then rather long no new message.
|
||||||
|
ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 8);
|
||||||
|
// 60 messages per minute should be enough for the server team!
|
||||||
|
serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 2);
|
||||||
|
|
||||||
VelocityCore.schedule(() -> {
|
VelocityCore.schedule(() -> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class ChecklistChannel extends DiscordChannel {
|
|||||||
private final List<Integer> lastSchematics = new ArrayList<>();
|
private final List<Integer> lastSchematics = new ArrayList<>();
|
||||||
|
|
||||||
public ChecklistChannel(String channel) {
|
public ChecklistChannel(String channel) {
|
||||||
super(channel);
|
super(channel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
|
|||||||
@@ -26,17 +26,21 @@ import de.steamwar.velocitycore.discord.DiscordBot;
|
|||||||
import de.steamwar.velocitycore.discord.listeners.ChannelListener;
|
import de.steamwar.velocitycore.discord.listeners.ChannelListener;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.dv8tion.jda.api.entities.Icon;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.Webhook;
|
||||||
|
import net.dv8tion.jda.api.entities.WebhookClient;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
|
import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import net.dv8tion.jda.api.utils.ImageProxy;
|
|
||||||
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
|
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
|
||||||
|
import net.dv8tion.jda.internal.requests.IncomingWebhookClientImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class DiscordChannel extends Chatter.PlayerlessChatter {
|
public class DiscordChannel extends Chatter.PlayerlessChatter {
|
||||||
@@ -46,21 +50,36 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
|
|||||||
return user != null ? user : SteamwarUser.get(0);
|
return user != null ? user : SteamwarUser.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Queue<Webhook> webhooks = new ArrayDeque<>();
|
||||||
|
|
||||||
private final SteamwarUser user;
|
private final SteamwarUser user;
|
||||||
@Getter
|
@Getter
|
||||||
private final MessageChannel channel;
|
private final MessageChannel channel;
|
||||||
|
|
||||||
|
private final int maxNumberOfWebhooks;
|
||||||
|
|
||||||
public DiscordChannel(User user) {
|
public DiscordChannel(User user) {
|
||||||
this(userOrPublic(user), user.openPrivateChannel().complete());
|
this(userOrPublic(user), user.openPrivateChannel().complete(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscordChannel(String channel) {
|
public DiscordChannel(String channel, int maxNumberOfWebhooks) {
|
||||||
this(DiscordBot.getGuild().getTextChannelById(channel));
|
this(DiscordBot.getGuild().getTextChannelById(channel), maxNumberOfWebhooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscordChannel(MessageChannel channel) {
|
public DiscordChannel(MessageChannel channel, int maxNumberOfWebhooks) {
|
||||||
this(SteamwarUser.get(-1), channel);
|
this(SteamwarUser.get(-1), channel, maxNumberOfWebhooks);
|
||||||
ChannelListener.getChannels().put(this.channel, this);
|
ChannelListener.getChannels().put(this.channel, this);
|
||||||
|
|
||||||
|
if (channel instanceof TextChannel) {
|
||||||
|
TextChannel textChannel = (TextChannel) channel;
|
||||||
|
webhooks.addAll(textChannel.retrieveWebhooks().complete());
|
||||||
|
while (webhooks.size() > maxNumberOfWebhooks) {
|
||||||
|
webhooks.remove().delete().queue();
|
||||||
|
}
|
||||||
|
while (webhooks.size() < maxNumberOfWebhooks) {
|
||||||
|
webhooks.add(textChannel.createWebhook(DiscordBot.getInstance().getJda().getSelfUser().getName()).complete());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(String message) {
|
public void send(String message) {
|
||||||
@@ -70,7 +89,7 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
|
|||||||
.replace("@here", "`@here`")
|
.replace("@here", "`@here`")
|
||||||
.replaceAll("<[@#]!?\\d+>", "`$0`");
|
.replaceAll("<[@#]!?\\d+>", "`$0`");
|
||||||
|
|
||||||
if (getChannel() instanceof TextChannel && message.contains("»")) {
|
if (maxNumberOfWebhooks > 0 && getChannel() instanceof TextChannel && message.contains("»")) {
|
||||||
String[] strings = message.split("»", 2);
|
String[] strings = message.split("»", 2);
|
||||||
String userName = strings[0];
|
String userName = strings[0];
|
||||||
String sendMessage = strings[1];
|
String sendMessage = strings[1];
|
||||||
@@ -85,29 +104,24 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageProxy avatarUrl;
|
String avatarUrl;
|
||||||
if (user.getDiscordId() != null) {
|
if (user.getDiscordId() != null) {
|
||||||
avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatar();
|
avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatarUrl();
|
||||||
} else {
|
} else {
|
||||||
avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatar();
|
avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatarUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextChannel textChannel = (TextChannel) getChannel();
|
Webhook webhook = webhooks.poll();
|
||||||
try {
|
webhooks.add(webhook);
|
||||||
textChannel.createWebhook(userName)
|
|
||||||
.setAvatar(Icon.from(avatarUrl.download(128).get()))
|
// This works as per this documentation: https://discord.com/developers/docs/resources/webhook#execute-webhook
|
||||||
.onSuccess(webhook -> {
|
IncomingWebhookClientImpl webhookClient = (IncomingWebhookClientImpl) WebhookClient.createClient(DiscordBot.getInstance().getJda(), webhook.getUrl());
|
||||||
webhook.sendMessage(sendMessage)
|
webhookClient.sendRequest()
|
||||||
.onSuccess(__ -> {
|
.setUsername(userName)
|
||||||
webhook.delete().queue();
|
.setAvatarUrl(avatarUrl)
|
||||||
})
|
.setContent(sendMessage)
|
||||||
.queue();
|
.queue();
|
||||||
})
|
return;
|
||||||
.queue();
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Ignore and send message as normal!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send(new MessageCreateBuilder()
|
send(new MessageCreateBuilder()
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ public class DiscordChatRoom extends DiscordChannel {
|
|||||||
private final String format;
|
private final String format;
|
||||||
private final Supplier<ChatterGroup> target;
|
private final Supplier<ChatterGroup> target;
|
||||||
|
|
||||||
public DiscordChatRoom(String channel, String format, Supplier<ChatterGroup> target) {
|
public DiscordChatRoom(String channel, String format, Supplier<ChatterGroup> target, int maxNumberOfWebhooks) {
|
||||||
super(channel);
|
super(channel, maxNumberOfWebhooks);
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -46,14 +46,14 @@ public class StaticMessageChannel extends DiscordChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
||||||
super(channel);
|
super(channel, 0);
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
this.interaction = interaction;
|
this.interaction = interaction;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StaticMessageChannel(MessageChannel channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
public StaticMessageChannel(MessageChannel channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
||||||
super(channel);
|
super(channel, 0);
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
this.interaction = interaction;
|
this.interaction = interaction;
|
||||||
init();
|
init();
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ public class DiscordTicketHandler extends ListenerAdapter {
|
|||||||
Permission.MESSAGE_HISTORY).complete();
|
Permission.MESSAGE_HISTORY).complete();
|
||||||
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
|
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
|
||||||
|
|
||||||
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel);
|
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel, 0);
|
||||||
channel.send(new MessageCreateBuilder()
|
channel.send(new MessageCreateBuilder()
|
||||||
.setEmbeds(new EmbedBuilder()
|
.setEmbeds(new EmbedBuilder()
|
||||||
.setTitle(channel.parseToPlain("DC_TICKET_TITLE"))
|
.setTitle(channel.parseToPlain("DC_TICKET_TITLE"))
|
||||||
|
|||||||
Reference in New Issue
Block a user