mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-29 13:05:44 +01:00
Various improvements to 1st party Discord API
This commit is contained in:
parent
0c9732fe11
commit
7457fd90d0
@ -28,6 +28,7 @@ import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
|||||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@ -64,6 +65,23 @@ public interface DiscordUser extends Snowflake, Mentionable {
|
|||||||
@NotNull
|
@NotNull
|
||||||
String getDiscriminator();
|
String getDiscriminator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Discord user's avatar url, if an avatar is set.
|
||||||
|
* @return the user's avatar url or {@code null}
|
||||||
|
*/
|
||||||
|
@Placeholder("user_avatar_url")
|
||||||
|
@Nullable
|
||||||
|
String getAvatarUrl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Discord user's avatar that is currently active,
|
||||||
|
* if an avatar isn't set it'll be the url to the default avatar provided by Discord.
|
||||||
|
* @return the user's avatar url
|
||||||
|
*/
|
||||||
|
@Placeholder("user_effective_avatar_url")
|
||||||
|
@NotNull
|
||||||
|
String getEffectiveAvatarUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Discord user's username followed by a {@code #} and their discriminator.
|
* Gets the Discord user's username followed by a {@code #} and their discriminator.
|
||||||
* @return the Discord user's username & discriminator in the following format {@code Username#1234}
|
* @return the Discord user's username & discriminator in the following format {@code Username#1234}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||||
|
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.api.discord.api.entity.channel;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface DiscordGuildChannel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the channel.
|
||||||
|
* @return the name of the channel
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Discord server that this channel is in.
|
||||||
|
* @return the Discord server that contains this channel
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
DiscordGuild getGuild();
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||||
|
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.api.discord.api.entity.channel;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.Mentionable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A regular Discord channel that messages can be sent to (threads not included).
|
||||||
|
*/
|
||||||
|
public interface DiscordGuildMessageChannel extends DiscordMessageChannel, DiscordGuildChannel, Mentionable {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<DiscordThreadChannel> getActiveThreads();
|
||||||
|
|
||||||
|
CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedPrivateThreads();
|
||||||
|
CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedJoinedPrivateThreads();
|
||||||
|
CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedPublicThreads();
|
||||||
|
|
||||||
|
CompletableFuture<DiscordThreadChannel> createThread(String name, boolean privateThread);
|
||||||
|
CompletableFuture<DiscordThreadChannel> createThread(String name, long messageId);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||||
|
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.api.discord.api.entity.channel;
|
||||||
|
|
||||||
|
import com.discordsrv.api.DiscordSRVApi;
|
||||||
|
import net.dv8tion.jda.api.entities.NewsChannel;
|
||||||
|
|
||||||
|
public interface DiscordNewsChannel extends DiscordGuildMessageChannel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JDA representation of this object. This should not be used if it can be avoided.
|
||||||
|
* @return the JDA representation of this object
|
||||||
|
* @see DiscordSRVApi#jda()
|
||||||
|
*/
|
||||||
|
NewsChannel getAsJDANewsChannel();
|
||||||
|
}
|
@ -24,23 +24,13 @@
|
|||||||
package com.discordsrv.api.discord.api.entity.channel;
|
package com.discordsrv.api.discord.api.entity.channel;
|
||||||
|
|
||||||
import com.discordsrv.api.DiscordSRVApi;
|
import com.discordsrv.api.DiscordSRVApi;
|
||||||
import com.discordsrv.api.discord.api.entity.Mentionable;
|
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Discord text channel.
|
* A Discord text channel.
|
||||||
*/
|
*/
|
||||||
public interface DiscordTextChannel extends DiscordMessageChannel, Mentionable {
|
public interface DiscordTextChannel extends DiscordGuildMessageChannel {
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of the text channel.
|
|
||||||
* @return the name of the channel
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the topic of the text channel.
|
* Gets the topic of the text channel.
|
||||||
@ -49,13 +39,6 @@ public interface DiscordTextChannel extends DiscordMessageChannel, Mentionable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
String getTopic();
|
String getTopic();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Discord server that this channel is in.
|
|
||||||
* @return the Discord server that contains this channel
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
DiscordGuild getGuild();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the JDA representation of this object. This should not be used if it can be avoided.
|
* Returns the JDA representation of this object. This should not be used if it can be avoided.
|
||||||
* @return the JDA representation of this object
|
* @return the JDA representation of this object
|
||||||
|
@ -67,6 +67,13 @@ public interface DiscordGuildMember extends DiscordUser, Mentionable {
|
|||||||
return getNickname().orElseGet(this::getUsername);
|
return getNickname().orElseGet(this::getUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the avatar url that is active for this user in this server.
|
||||||
|
* @return the user's avatar url in this server
|
||||||
|
*/
|
||||||
|
@Placeholder("user_effective_avatar_url")
|
||||||
|
String getEffectiveServerAvatarUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the color of this user's highest role that has a color.
|
* Gets the color of this user's highest role that has a color.
|
||||||
* @return the color that will be used for this user
|
* @return the color that will be used for this user
|
||||||
|
@ -160,6 +160,20 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Builder convertToNonWebhook() {
|
||||||
|
String webhookUsername = this.webhookUsername;
|
||||||
|
if (webhookUsername == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: configuration?
|
||||||
|
this.content = webhookUsername + " > " + content;
|
||||||
|
this.webhookUsername = null;
|
||||||
|
this.webhookAvatarUrl = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull SendableDiscordMessage build() {
|
public @NotNull SendableDiscordMessage build() {
|
||||||
return new SendableDiscordMessageImpl(content, embeds, allowedMentions, webhookUsername, webhookAvatarUrl);
|
return new SendableDiscordMessageImpl(content, embeds, allowedMentions, webhookUsername, webhookAvatarUrl);
|
||||||
@ -167,8 +181,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Formatter toFormatter() {
|
public Formatter toFormatter() {
|
||||||
return new FormatterImpl(
|
return new FormatterImpl(clone());
|
||||||
clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
@ -218,6 +231,12 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Formatter convertToNonWebhook() {
|
||||||
|
builder.convertToNonWebhook();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private Function<Matcher, Object> wrapFunction(Function<Matcher, Object> function) {
|
private Function<Matcher, Object> wrapFunction(Function<Matcher, Object> function) {
|
||||||
return matcher -> {
|
return matcher -> {
|
||||||
Object result = function.apply(matcher);
|
Object result = function.apply(matcher);
|
||||||
|
@ -16,15 +16,19 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.module.modules;
|
package com.discordsrv.common.discord.api;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.events.DiscordMessageDeleteEvent;
|
||||||
|
import com.discordsrv.api.discord.events.DiscordMessageReceiveEvent;
|
||||||
|
import com.discordsrv.api.discord.events.DiscordMessageUpdateEvent;
|
||||||
import com.discordsrv.api.event.bus.Subscribe;
|
import com.discordsrv.api.event.bus.Subscribe;
|
||||||
import com.discordsrv.api.discord.events.DiscordMessageReceivedEvent;
|
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
import com.discordsrv.common.discord.api.entity.channel.DiscordMessageChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
|
import com.discordsrv.common.discord.api.entity.message.ReceivedDiscordMessageImpl;
|
||||||
import com.discordsrv.common.module.type.AbstractModule;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
|
||||||
|
|
||||||
public class DiscordAPIEventModule extends AbstractModule {
|
public class DiscordAPIEventModule extends AbstractModule {
|
||||||
|
|
||||||
@ -33,10 +37,26 @@ public class DiscordAPIEventModule extends AbstractModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onMessageReceivedEvent(MessageReceivedEvent event) {
|
public void onMessageReceived(MessageReceivedEvent event) {
|
||||||
discordSRV.eventBus().publish(new DiscordMessageReceivedEvent(
|
discordSRV.eventBus().publish(new DiscordMessageReceiveEvent(
|
||||||
ReceivedDiscordMessageImpl.fromJDA(discordSRV, event.getMessage()),
|
DiscordMessageChannelImpl.get(discordSRV, event.getChannel()),
|
||||||
DiscordMessageChannelImpl.get(discordSRV, event.getChannel()))
|
ReceivedDiscordMessageImpl.fromJDA(discordSRV, event.getMessage())
|
||||||
);
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onMessageUpdate(MessageUpdateEvent event) {
|
||||||
|
discordSRV.eventBus().publish(new DiscordMessageUpdateEvent(
|
||||||
|
DiscordMessageChannelImpl.get(discordSRV, event.getChannel()),
|
||||||
|
ReceivedDiscordMessageImpl.fromJDA(discordSRV, event.getMessage())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onMessageDelete(MessageDeleteEvent event) {
|
||||||
|
discordSRV.eventBus().publish(new DiscordMessageDeleteEvent(
|
||||||
|
DiscordMessageChannelImpl.get(discordSRV, event.getChannel()),
|
||||||
|
event.getMessageIdLong()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,10 +21,12 @@ package com.discordsrv.common.discord.api;
|
|||||||
import club.minnced.discord.webhook.WebhookClient;
|
import club.minnced.discord.webhook.WebhookClient;
|
||||||
import club.minnced.discord.webhook.WebhookClientBuilder;
|
import club.minnced.discord.webhook.WebhookClientBuilder;
|
||||||
import com.discordsrv.api.discord.api.DiscordAPI;
|
import com.discordsrv.api.discord.api.DiscordAPI;
|
||||||
|
import com.discordsrv.api.discord.api.ThreadChannelLookup;
|
||||||
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordMessageChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordMessageChannel;
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
||||||
|
import com.discordsrv.api.discord.api.entity.channel.DiscordThreadChannel;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
||||||
import com.discordsrv.api.discord.api.exception.NotReadyException;
|
import com.discordsrv.api.discord.api.exception.NotReadyException;
|
||||||
@ -32,35 +34,43 @@ import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
|
|||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordDMChannelImpl;
|
import com.discordsrv.common.config.main.channels.base.ThreadConfig;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordTextChannelImpl;
|
import com.discordsrv.common.discord.api.entity.DiscordUserImpl;
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
|
import com.discordsrv.common.discord.api.entity.channel.DiscordDMChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordRoleImpl;
|
import com.discordsrv.common.discord.api.entity.channel.DiscordTextChannelImpl;
|
||||||
|
import com.discordsrv.common.discord.api.entity.guild.DiscordGuildImpl;
|
||||||
|
import com.discordsrv.common.discord.api.entity.guild.DiscordRoleImpl;
|
||||||
|
import com.discordsrv.common.function.CheckedSupplier;
|
||||||
import com.github.benmanes.caffeine.cache.AsyncCacheLoader;
|
import com.github.benmanes.caffeine.cache.AsyncCacheLoader;
|
||||||
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
|
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
|
||||||
import com.github.benmanes.caffeine.cache.Expiry;
|
import com.github.benmanes.caffeine.cache.Expiry;
|
||||||
import com.github.benmanes.caffeine.cache.RemovalListener;
|
import com.github.benmanes.caffeine.cache.RemovalListener;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.ThreadChannel;
|
||||||
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.Webhook;
|
||||||
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
|
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
|
||||||
|
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||||
import net.dv8tion.jda.api.requests.ErrorResponse;
|
import net.dv8tion.jda.api.requests.ErrorResponse;
|
||||||
import net.dv8tion.jda.api.requests.GatewayIntent;
|
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||||
import org.checkerframework.checker.index.qual.NonNegative;
|
import org.checkerframework.checker.index.qual.NonNegative;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class DiscordAPIImpl implements DiscordAPI {
|
public class DiscordAPIImpl implements DiscordAPI {
|
||||||
|
|
||||||
private final DiscordSRV discordSRV;
|
private final DiscordSRV discordSRV;
|
||||||
|
|
||||||
private final AsyncLoadingCache<Long, WebhookClient> cachedClients;
|
private final AsyncLoadingCache<Long, WebhookClient> cachedClients;
|
||||||
|
private final List<ThreadChannelLookup> threadLookups = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public DiscordAPIImpl(DiscordSRV discordSRV) {
|
public DiscordAPIImpl(DiscordSRV discordSRV) {
|
||||||
this.discordSRV = discordSRV;
|
this.discordSRV = discordSRV;
|
||||||
@ -82,6 +92,226 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
return cachedClients;
|
return cachedClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds active threads based for the provided {@link IChannelConfig}.
|
||||||
|
* @param config the config that specified the threads
|
||||||
|
* @return the list of active threads
|
||||||
|
*/
|
||||||
|
public List<DiscordThreadChannel> findThreads(IChannelConfig config) {
|
||||||
|
List<DiscordThreadChannel> channels = new ArrayList<>();
|
||||||
|
findOrCreateThreads(config, channels::add, null);
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds or potentially unarchives or creates threads based on the provided {@link IChannelConfig}.
|
||||||
|
* @param config the config
|
||||||
|
* @param channelConsumer the consumer that will take the channels as they are gathered
|
||||||
|
* @param futures a possibly null list of {@link CompletableFuture} for tasks that need to be completed to get all threads
|
||||||
|
*/
|
||||||
|
public void findOrCreateThreads(
|
||||||
|
IChannelConfig config,
|
||||||
|
Consumer<DiscordThreadChannel> channelConsumer,
|
||||||
|
@Nullable List<CompletableFuture<DiscordThreadChannel>> futures
|
||||||
|
) {
|
||||||
|
List<ThreadConfig> threads = config.threads();
|
||||||
|
if (threads == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ThreadConfig threadConfig : threads) {
|
||||||
|
long channelId = threadConfig.channelId;
|
||||||
|
DiscordTextChannel channel = getTextChannelById(channelId).orElse(null);
|
||||||
|
if (channel == null) {
|
||||||
|
if (channelId > 0) {
|
||||||
|
discordSRV.logger().error("Unable to find channel with ID "
|
||||||
|
+ Long.toUnsignedString(channelId)
|
||||||
|
+ ", unable to forward message to Discord");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a thread by the same name is still active
|
||||||
|
DiscordThreadChannel thread = findThread(threadConfig, channel.getActiveThreads());
|
||||||
|
if (thread != null) {
|
||||||
|
ThreadChannel jdaChannel = thread.getAsJDAThreadChannel();
|
||||||
|
if (!jdaChannel.isLocked() && !jdaChannel.isArchived()) {
|
||||||
|
channelConsumer.accept(thread);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (futures == null) {
|
||||||
|
// Futures not specified, don't try to unarchive or create threads
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<DiscordThreadChannel> future;
|
||||||
|
if (thread != null) {
|
||||||
|
// Unarchive the thread
|
||||||
|
future = new CompletableFuture<>();
|
||||||
|
unarchiveOrCreateThread(threadConfig, channel, thread, future);
|
||||||
|
} else {
|
||||||
|
// Find or create the thread
|
||||||
|
future = findOrCreateThread(threadConfig, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
futures.add(future.handle((threadChannel, t) -> {
|
||||||
|
if (t instanceof InsufficientPermissionException) {
|
||||||
|
discordSRV.logger().error(
|
||||||
|
"Unable to send message to channel " + channel
|
||||||
|
+ " because the bot is lacking the "
|
||||||
|
+ ((InsufficientPermissionException) t).getPermission().getName()
|
||||||
|
+ " permission");
|
||||||
|
throw new RuntimeException();
|
||||||
|
} else if (t != null) {
|
||||||
|
discordSRV.logger().error("Failed to find thread in channel " + channel, t);
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadChannel != null) {
|
||||||
|
channelConsumer.accept(threadChannel);
|
||||||
|
}
|
||||||
|
return threadChannel;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiscordThreadChannel findThread(ThreadConfig config, List<DiscordThreadChannel> threads) {
|
||||||
|
for (DiscordThreadChannel thread : threads) {
|
||||||
|
if (thread.getName().equals(config.threadName)) {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<DiscordThreadChannel> findOrCreateThread(ThreadConfig config, DiscordTextChannel textChannel) {
|
||||||
|
if (!config.unarchive) {
|
||||||
|
return textChannel.createThread(config.threadName, config.privateThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<DiscordThreadChannel> completableFuture = new CompletableFuture<>();
|
||||||
|
lookupThreads(
|
||||||
|
textChannel,
|
||||||
|
config.privateThread,
|
||||||
|
lookup -> findOrCreateThread(config, textChannel, lookup, completableFuture),
|
||||||
|
(thread, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
completableFuture.completeExceptionally(throwable);
|
||||||
|
} else {
|
||||||
|
completableFuture.complete(thread);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findOrCreateThread(
|
||||||
|
ThreadConfig config,
|
||||||
|
DiscordTextChannel textChannel,
|
||||||
|
ThreadChannelLookup lookup,
|
||||||
|
CompletableFuture<DiscordThreadChannel> completableFuture
|
||||||
|
) {
|
||||||
|
completableFuture.whenComplete((threadChannel, throwable) -> {
|
||||||
|
CompletableFuture<DiscordThreadChannel> future = lookup.getChannelFuture();
|
||||||
|
if (throwable != null) {
|
||||||
|
future.completeExceptionally(throwable);
|
||||||
|
} else {
|
||||||
|
future.complete(threadChannel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lookup.getFuture().whenComplete((channels, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
completableFuture.completeExceptionally(throwable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscordThreadChannel thread = findThread(config, channels);
|
||||||
|
unarchiveOrCreateThread(config, textChannel, thread, completableFuture);
|
||||||
|
}).exceptionally(t -> {
|
||||||
|
if (t instanceof CompletionException) {
|
||||||
|
completableFuture.completeExceptionally(t.getCause());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
completableFuture.completeExceptionally(t);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unarchiveOrCreateThread(
|
||||||
|
ThreadConfig config,
|
||||||
|
DiscordTextChannel textChannel,
|
||||||
|
DiscordThreadChannel thread,
|
||||||
|
CompletableFuture<DiscordThreadChannel> future
|
||||||
|
) {
|
||||||
|
if (thread != null) {
|
||||||
|
ThreadChannel channel = thread.getAsJDAThreadChannel();
|
||||||
|
if (channel.isLocked() || channel.isArchived()) {
|
||||||
|
try {
|
||||||
|
channel.getManager().setArchived(false).queue(
|
||||||
|
v -> future.complete(thread),
|
||||||
|
future::completeExceptionally
|
||||||
|
);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
future.completeExceptionally(t);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
future.complete(thread);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
textChannel.createThread(config.threadName, config.privateThread).whenComplete(((threadChannel, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
future.completeExceptionally(t);
|
||||||
|
} else {
|
||||||
|
future.complete(threadChannel);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lookupThreads(
|
||||||
|
DiscordTextChannel textChannel,
|
||||||
|
boolean privateThreads,
|
||||||
|
Consumer<ThreadChannelLookup> lookupConsumer,
|
||||||
|
BiConsumer<DiscordThreadChannel, Throwable> channelConsumer
|
||||||
|
) {
|
||||||
|
ThreadChannelLookup lookup;
|
||||||
|
synchronized (threadLookups) {
|
||||||
|
for (ThreadChannelLookup threadLookup : threadLookups) {
|
||||||
|
if (threadLookup.isPrivateThreads() != privateThreads
|
||||||
|
|| threadLookup.getChannelId() != textChannel.getId()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
threadLookup.getChannelFuture().whenComplete(channelConsumer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup = new ThreadChannelLookup(
|
||||||
|
textChannel.getId(), privateThreads,
|
||||||
|
privateThreads
|
||||||
|
? textChannel.retrieveArchivedPrivateThreads()
|
||||||
|
: textChannel.retrieveArchivedPublicThreads()
|
||||||
|
);
|
||||||
|
threadLookups.add(lookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup.getChannelFuture().whenComplete(channelConsumer);
|
||||||
|
lookupConsumer.accept(lookup);
|
||||||
|
lookup.getFuture().whenComplete((channel, t) -> threadLookups.remove(lookup));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> CompletableFuture<T> mapExceptions(CheckedSupplier<CompletableFuture<T>> futureSupplier) {
|
||||||
|
try {
|
||||||
|
return mapExceptions(futureSupplier.get());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
CompletableFuture<T> future = new CompletableFuture<>();
|
||||||
|
future.completeExceptionally(t);
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T> CompletableFuture<T> mapExceptions(CompletableFuture<T> future) {
|
public <T> CompletableFuture<T> mapExceptions(CompletableFuture<T> future) {
|
||||||
return future.handle((msg, t) -> {
|
return future.handle((msg, t) -> {
|
||||||
if (t instanceof ErrorResponseException) {
|
if (t instanceof ErrorResponseException) {
|
||||||
@ -172,7 +402,7 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
public @NonNull CompletableFuture<WebhookClient> asyncLoad(@NonNull Long channelId, @NonNull Executor executor) {
|
public @NonNull CompletableFuture<WebhookClient> asyncLoad(@NonNull Long channelId, @NonNull Executor executor) {
|
||||||
JDA jda = discordSRV.jda().orElse(null);
|
JDA jda = discordSRV.jda().orElse(null);
|
||||||
if (jda == null) {
|
if (jda == null) {
|
||||||
return discordSRV.discordAPI().notReady();
|
return notReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture<WebhookClient> future = new CompletableFuture<>();
|
CompletableFuture<WebhookClient> future = new CompletableFuture<>();
|
||||||
@ -208,7 +438,7 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
}).thenApply(webhook ->
|
}).thenApply(webhook ->
|
||||||
WebhookClientBuilder.fromJDA(webhook)
|
WebhookClientBuilder.fromJDA(webhook)
|
||||||
.setHttpClient(jda.getHttpClient())
|
.setHttpClient(jda.getHttpClient())
|
||||||
.setExecutorService(discordSRV.scheduler().scheduledExecutor())
|
.setExecutorService(discordSRV.scheduler().scheduledExecutorService())
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -219,7 +449,7 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
private boolean isConfiguredChannel(Long channelId) {
|
private boolean isConfiguredChannel(Long channelId) {
|
||||||
for (BaseChannelConfig config : discordSRV.config().channels.values()) {
|
for (BaseChannelConfig config : discordSRV.config().channels.values()) {
|
||||||
if (config instanceof IChannelConfig
|
if (config instanceof IChannelConfig
|
||||||
&& ((IChannelConfig) config).ids().contains(channelId)) {
|
&& ((IChannelConfig) config).channelIds().contains(channelId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
|
||||||
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.channel;
|
|
||||||
|
|
||||||
import club.minnced.discord.webhook.WebhookClient;
|
|
||||||
import club.minnced.discord.webhook.receive.ReadonlyMessage;
|
|
||||||
import club.minnced.discord.webhook.send.WebhookMessage;
|
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
|
||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
|
||||||
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
|
||||||
import com.discordsrv.common.DiscordSRV;
|
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
|
|
||||||
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
|
|
||||||
import com.discordsrv.common.discord.api.message.util.SendableDiscordMessageUtil;
|
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
|
||||||
import net.dv8tion.jda.api.requests.restaction.MessageAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
public class DiscordTextChannelImpl extends DiscordMessageChannelImpl implements DiscordTextChannel {
|
|
||||||
|
|
||||||
private final DiscordSRV discordSRV;
|
|
||||||
private final TextChannel textChannel;
|
|
||||||
private final DiscordGuild guild;
|
|
||||||
|
|
||||||
public DiscordTextChannelImpl(DiscordSRV discordSRV, TextChannel textChannel) {
|
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
this.textChannel = textChannel;
|
|
||||||
this.guild = new DiscordGuildImpl(discordSRV, textChannel.getGuild());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getId() {
|
|
||||||
return textChannel.getIdLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getName() {
|
|
||||||
return textChannel.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getTopic() {
|
|
||||||
return textChannel.getTopic();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull DiscordGuild getGuild() {
|
|
||||||
return guild;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextChannel getAsJDATextChannel() {
|
|
||||||
return textChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull CompletableFuture<ReceivedDiscordMessage> sendMessage(SendableDiscordMessage message) {
|
|
||||||
return message(message, WebhookClient::send, MessageChannel::sendMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Void> deleteMessageById(long id) {
|
|
||||||
return null; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull CompletableFuture<ReceivedDiscordMessage> editMessageById(long id, SendableDiscordMessage message) {
|
|
||||||
return message(
|
|
||||||
message,
|
|
||||||
(client, msg) -> client.edit(id, msg),
|
|
||||||
(textChannel, msg) -> textChannel.editMessageById(id, msg)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MessageChannel getAsJDAMessageChannel() {
|
|
||||||
return textChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<ReceivedDiscordMessage> message(
|
|
||||||
SendableDiscordMessage message,
|
|
||||||
BiFunction<WebhookClient, WebhookMessage, CompletableFuture<ReadonlyMessage>> webhookFunction,
|
|
||||||
BiFunction<TextChannel, Message, MessageAction> jdaFunction) {
|
|
||||||
CompletableFuture<ReceivedDiscordMessage> future;
|
|
||||||
if (message.isWebhookMessage()) {
|
|
||||||
future = discordSRV.discordAPI().queryWebhookClient(getId())
|
|
||||||
.thenCompose(client -> webhookFunction.apply(
|
|
||||||
client, SendableDiscordMessageUtil.toWebhook(message)))
|
|
||||||
.thenApply(msg -> ReceivedDiscordMessageImpl.fromWebhook(discordSRV, msg));
|
|
||||||
} else {
|
|
||||||
future = jdaFunction
|
|
||||||
.apply(textChannel, SendableDiscordMessageUtil.toJDA(message))
|
|
||||||
.submit()
|
|
||||||
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
return discordSRV.discordAPI().mapExceptions(future);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAsMention() {
|
|
||||||
return textChannel.getAsMention();
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,15 +16,16 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api;
|
package com.discordsrv.common.discord.api.entity;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordDMChannelImpl;
|
import com.discordsrv.common.discord.api.entity.channel.DiscordDMChannelImpl;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@ -65,6 +66,16 @@ public class DiscordUserImpl implements DiscordUser {
|
|||||||
return user.getDiscriminator();
|
return user.getDiscriminator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getAvatarUrl() {
|
||||||
|
return user.getAvatarUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getEffectiveAvatarUrl() {
|
||||||
|
return user.getEffectiveAvatarUrl();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<DiscordDMChannel> openPrivateChannel() {
|
public CompletableFuture<DiscordDMChannel> openPrivateChannel() {
|
||||||
JDA jda = discordSRV.jda().orElse(null);
|
JDA jda = discordSRV.jda().orElse(null);
|
@ -16,56 +16,42 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.channel;
|
package com.discordsrv.common.discord.api.entity.channel;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||||
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
import com.discordsrv.common.discord.api.entity.DiscordUserImpl;
|
||||||
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
|
import com.discordsrv.common.discord.api.entity.message.ReceivedDiscordMessageImpl;
|
||||||
import com.discordsrv.common.discord.api.message.util.SendableDiscordMessageUtil;
|
import com.discordsrv.common.discord.api.entity.message.util.SendableDiscordMessageUtil;
|
||||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.PrivateChannel;
|
import net.dv8tion.jda.api.entities.PrivateChannel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class DiscordDMChannelImpl extends DiscordMessageChannelImpl implements DiscordDMChannel {
|
public class DiscordDMChannelImpl extends DiscordMessageChannelImpl<PrivateChannel> implements DiscordDMChannel {
|
||||||
|
|
||||||
private final DiscordSRV discordSRV;
|
|
||||||
private final PrivateChannel privateChannel;
|
|
||||||
private final DiscordUser user;
|
private final DiscordUser user;
|
||||||
|
|
||||||
public DiscordDMChannelImpl(DiscordSRV discordSRV, PrivateChannel privateChannel) {
|
public DiscordDMChannelImpl(DiscordSRV discordSRV, PrivateChannel privateChannel) {
|
||||||
this.discordSRV = discordSRV;
|
super(discordSRV, privateChannel);
|
||||||
this.privateChannel = privateChannel;
|
|
||||||
this.user = new DiscordUserImpl(discordSRV, privateChannel.getUser());
|
this.user = new DiscordUserImpl(discordSRV, privateChannel.getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getId() {
|
|
||||||
return privateChannel.getIdLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscordUser getUser() {
|
public DiscordUser getUser() {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrivateChannel getAsJDAPrivateChannel() {
|
public @NotNull CompletableFuture<ReceivedDiscordMessage> sendMessage(@NotNull SendableDiscordMessage message) {
|
||||||
return privateChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull CompletableFuture<ReceivedDiscordMessage> sendMessage(SendableDiscordMessage message) {
|
|
||||||
if (message.isWebhookMessage()) {
|
if (message.isWebhookMessage()) {
|
||||||
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
|
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture<ReceivedDiscordMessage> future = privateChannel
|
CompletableFuture<ReceivedDiscordMessage> future = channel
|
||||||
.sendMessage(SendableDiscordMessageUtil.toJDA(message))
|
.sendMessage(SendableDiscordMessageUtil.toJDA(message))
|
||||||
.submit()
|
.submit()
|
||||||
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
||||||
@ -74,17 +60,20 @@ public class DiscordDMChannelImpl extends DiscordMessageChannelImpl implements D
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> deleteMessageById(long id) {
|
public CompletableFuture<Void> deleteMessageById(long id, boolean webhookMessage) {
|
||||||
return discordSRV.discordAPI().mapExceptions(privateChannel.deleteMessageById(id).submit());
|
if (webhookMessage) {
|
||||||
|
throw new IllegalArgumentException("DMChannels do not contain webhook messages");
|
||||||
|
}
|
||||||
|
return discordSRV.discordAPI().mapExceptions(channel.deleteMessageById(id).submit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull CompletableFuture<ReceivedDiscordMessage> editMessageById(long id, SendableDiscordMessage message) {
|
public @NotNull CompletableFuture<ReceivedDiscordMessage> editMessageById(long id, @NotNull SendableDiscordMessage message) {
|
||||||
if (message.isWebhookMessage()) {
|
if (message.isWebhookMessage()) {
|
||||||
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
|
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture<ReceivedDiscordMessage> future = privateChannel
|
CompletableFuture<ReceivedDiscordMessage> future = channel
|
||||||
.editMessageById(id, SendableDiscordMessageUtil.toJDA(message))
|
.editMessageById(id, SendableDiscordMessageUtil.toJDA(message))
|
||||||
.submit()
|
.submit()
|
||||||
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
||||||
@ -93,7 +82,7 @@ public class DiscordDMChannelImpl extends DiscordMessageChannelImpl implements D
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MessageChannel getAsJDAMessageChannel() {
|
public PrivateChannel getAsJDAPrivateChannel() {
|
||||||
return privateChannel;
|
return channel;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.common.discord.api.entity.channel;
|
||||||
|
|
||||||
|
import club.minnced.discord.webhook.WebhookClient;
|
||||||
|
import club.minnced.discord.webhook.receive.ReadonlyMessage;
|
||||||
|
import club.minnced.discord.webhook.send.WebhookMessage;
|
||||||
|
import com.discordsrv.api.discord.api.entity.channel.DiscordGuildMessageChannel;
|
||||||
|
import com.discordsrv.api.discord.api.entity.channel.DiscordThreadChannel;
|
||||||
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.discord.api.entity.guild.DiscordGuildImpl;
|
||||||
|
import com.discordsrv.common.discord.api.entity.message.ReceivedDiscordMessageImpl;
|
||||||
|
import com.discordsrv.common.discord.api.entity.message.util.SendableDiscordMessageUtil;
|
||||||
|
import net.dv8tion.jda.api.entities.*;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.MessageAction;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.ThreadChannelAction;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.pagination.ThreadChannelPaginationAction;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public abstract class DiscordGuildMessageChannelImpl<T extends GuildMessageChannel & IThreadContainer>
|
||||||
|
extends DiscordMessageChannelImpl<T>
|
||||||
|
implements DiscordGuildMessageChannel {
|
||||||
|
|
||||||
|
private final DiscordGuild guild;
|
||||||
|
|
||||||
|
public DiscordGuildMessageChannelImpl(DiscordSRV discordSRV, T channel) {
|
||||||
|
super(discordSRV, channel);
|
||||||
|
this.guild = new DiscordGuildImpl(discordSRV, channel.getGuild());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return channel.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsMention() {
|
||||||
|
return channel.getAsMention();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull DiscordGuild getGuild() {
|
||||||
|
return guild;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<DiscordThreadChannel> getActiveThreads() {
|
||||||
|
List<ThreadChannel> threads = channel.getThreadChannels();
|
||||||
|
List<DiscordThreadChannel> threadChannels = new ArrayList<>(threads.size());
|
||||||
|
for (ThreadChannel thread : threads) {
|
||||||
|
threadChannels.add(new DiscordThreadChannelImpl(discordSRV, thread));
|
||||||
|
}
|
||||||
|
return threadChannels;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedPrivateThreads() {
|
||||||
|
return threads(IThreadContainer::retrieveArchivedPrivateThreadChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedJoinedPrivateThreads() {
|
||||||
|
return threads(IThreadContainer::retrieveArchivedPrivateJoinedThreadChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<List<DiscordThreadChannel>> retrieveArchivedPublicThreads() {
|
||||||
|
return threads(IThreadContainer::retrieveArchivedPublicThreadChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<List<DiscordThreadChannel>> threads(Function<IThreadContainer, ThreadChannelPaginationAction> action) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(() ->
|
||||||
|
action.apply(channel)
|
||||||
|
.submit()
|
||||||
|
.thenApply(channels -> channels.stream()
|
||||||
|
.map(channel -> new DiscordThreadChannelImpl(discordSRV, channel))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DiscordThreadChannel> createThread(String name, boolean privateThread) {
|
||||||
|
return thread(channel -> channel.createThreadChannel(name, privateThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DiscordThreadChannel> createThread(String name, long messageId) {
|
||||||
|
return thread(channel -> channel.createThreadChannel(name, messageId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<DiscordThreadChannel> thread(Function<T, ThreadChannelAction> action) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(() ->
|
||||||
|
action.apply(channel)
|
||||||
|
.submit()
|
||||||
|
.thenApply(channel -> new DiscordThreadChannelImpl(discordSRV, channel))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompletableFuture<ReceivedDiscordMessage> sendMessage(@NotNull SendableDiscordMessage message) {
|
||||||
|
return message(message, WebhookClient::send, MessageChannel::sendMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompletableFuture<ReceivedDiscordMessage> editMessageById(long id, @NotNull SendableDiscordMessage message) {
|
||||||
|
return message(
|
||||||
|
message,
|
||||||
|
(client, msg) -> client.edit(id, msg),
|
||||||
|
(textChannel, msg) -> textChannel.editMessageById(id, msg)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<ReceivedDiscordMessage> message(
|
||||||
|
SendableDiscordMessage message,
|
||||||
|
BiFunction<WebhookClient, WebhookMessage, CompletableFuture<ReadonlyMessage>> webhookFunction,
|
||||||
|
BiFunction<T, Message, MessageAction> jdaFunction) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(() -> {
|
||||||
|
CompletableFuture<ReceivedDiscordMessage> future;
|
||||||
|
if (message.isWebhookMessage()) {
|
||||||
|
future = discordSRV.discordAPI().queryWebhookClient(getId())
|
||||||
|
.thenCompose(client -> webhookFunction.apply(
|
||||||
|
client, SendableDiscordMessageUtil.toWebhook(message)))
|
||||||
|
.thenApply(msg -> ReceivedDiscordMessageImpl.fromWebhook(discordSRV, msg));
|
||||||
|
} else {
|
||||||
|
future = jdaFunction
|
||||||
|
.apply(channel, SendableDiscordMessageUtil.toJDA(message))
|
||||||
|
.submit()
|
||||||
|
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
|
||||||
|
}
|
||||||
|
return future;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> deleteMessageById(long id, boolean webhookMessage) {
|
||||||
|
CompletableFuture<Void> future;
|
||||||
|
if (webhookMessage) {
|
||||||
|
future = channel.deleteMessageById(id).submit();
|
||||||
|
} else {
|
||||||
|
future = discordSRV.discordAPI()
|
||||||
|
.queryWebhookClient(channel.getIdLong())
|
||||||
|
.thenCompose(client -> client.delete(id));
|
||||||
|
}
|
||||||
|
return discordSRV.discordAPI().mapExceptions(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.common.discord.api.entity.channel;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.channel.DiscordNewsChannel;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import net.dv8tion.jda.api.entities.NewsChannel;
|
||||||
|
|
||||||
|
public class DiscordNewsChannelImpl
|
||||||
|
extends DiscordGuildMessageChannelImpl<NewsChannel>
|
||||||
|
implements DiscordNewsChannel {
|
||||||
|
|
||||||
|
public DiscordNewsChannelImpl(DiscordSRV discordSRV, NewsChannel channel) {
|
||||||
|
super(discordSRV, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NewsChannel getAsJDANewsChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
@ -16,23 +16,27 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.channel;
|
package com.discordsrv.common.discord.api.entity.channel;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordMessageChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.PrivateChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public abstract class DiscordMessageChannelImpl implements DiscordMessageChannel {
|
public class DiscordTextChannelImpl extends DiscordGuildMessageChannelImpl<TextChannel> implements DiscordTextChannel {
|
||||||
|
|
||||||
public static DiscordMessageChannelImpl get(DiscordSRV discordSRV, MessageChannel messageChannel) {
|
public DiscordTextChannelImpl(DiscordSRV discordSRV, TextChannel textChannel) {
|
||||||
if (messageChannel instanceof TextChannel) {
|
super(discordSRV, textChannel);
|
||||||
return new DiscordTextChannelImpl(discordSRV, (TextChannel) messageChannel);
|
|
||||||
} else if (messageChannel instanceof PrivateChannel) {
|
|
||||||
return new DiscordDMChannelImpl(discordSRV, (PrivateChannel) messageChannel);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown MessageChannel type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getTopic() {
|
||||||
|
return channel.getTopic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextChannel getAsJDATextChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.guild;
|
package com.discordsrv.common.discord.api.entity.guild;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.guild;
|
package com.discordsrv.common.discord.api.entity.guild;
|
||||||
|
|
||||||
import com.discordsrv.api.color.Color;
|
import com.discordsrv.api.color.Color;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||||
@ -26,7 +26,7 @@ import com.discordsrv.api.placeholder.annotation.Placeholder;
|
|||||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
import com.discordsrv.common.discord.api.entity.DiscordUserImpl;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
@ -73,6 +73,11 @@ public class DiscordGuildMemberImpl extends DiscordUserImpl implements DiscordGu
|
|||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEffectiveServerAvatarUrl() {
|
||||||
|
return member.getEffectiveAvatarUrl();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getColor() {
|
public Color getColor() {
|
||||||
return color;
|
return color;
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.guild;
|
package com.discordsrv.common.discord.api.entity.guild;
|
||||||
|
|
||||||
import com.discordsrv.api.color.Color;
|
import com.discordsrv.api.color.Color;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.message;
|
package com.discordsrv.common.discord.api.entity.message;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.discord.api.message;
|
package com.discordsrv.common.discord.api.entity.message;
|
||||||
|
|
||||||
import club.minnced.discord.webhook.WebhookClient;
|
import club.minnced.discord.webhook.WebhookClient;
|
||||||
import club.minnced.discord.webhook.receive.ReadonlyAttachment;
|
import club.minnced.discord.webhook.receive.ReadonlyAttachment;
|
||||||
@ -40,9 +40,9 @@ import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
|||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
import com.discordsrv.common.discord.api.entity.DiscordUserImpl;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
import com.discordsrv.common.discord.api.entity.channel.DiscordMessageChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordGuildMemberImpl;
|
import com.discordsrv.common.discord.api.entity.guild.DiscordGuildMemberImpl;
|
||||||
import com.discordsrv.common.function.OrDefault;
|
import com.discordsrv.common.function.OrDefault;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
@ -265,7 +265,7 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
return textChannel.deleteMessageById(getId());
|
return textChannel.deleteMessageById(getId(), fromSelf && getWebhookUsername().isPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
Loading…
Reference in New Issue
Block a user