1010import net .discordjug .javabot .util .Responses ;
1111import net .discordjug .javabot .util .UserUtils ;
1212import net .dv8tion .jda .api .EmbedBuilder ;
13+ import net .dv8tion .jda .api .JDA ;
1314import net .dv8tion .jda .api .entities .*;
1415import net .dv8tion .jda .api .entities .channel .middleman .MessageChannel ;
1516import net .dv8tion .jda .api .utils .MarkdownUtil ;
2021
2122import lombok .RequiredArgsConstructor ;
2223
24+ import javax .annotation .CheckReturnValue ;
2325import javax .annotation .Nonnull ;
2426import java .time .Duration ;
2527import java .time .Instant ;
2628import java .time .LocalDateTime ;
2729import java .time .ZoneOffset ;
30+ import java .util .ArrayList ;
2831import java .util .Collections ;
2932import java .util .List ;
3033import java .util .Optional ;
34+ import java .util .concurrent .CompletableFuture ;
3135import java .util .concurrent .ExecutorService ;
3236import java .util .concurrent .TimeUnit ;
37+ import java .util .function .Consumer ;
3338
3439/**
3540 * This service provides methods for performing moderation actions, like banning
@@ -281,23 +286,44 @@ private void banAndSendGuildNotifications(User user, String reason, Member banne
281286 * @param quiet If true, don't send a message in the channel.
282287 * @return Whether the member is banned or not.
283288 */
284- public boolean unban (long userId , String reason , Member bannedBy , MessageChannel channel , boolean quiet ) {
289+ @ CheckReturnValue
290+ public CompletableFuture <?> unban (long userId , String reason , Member bannedBy , MessageChannel channel , boolean quiet ) {
285291 MessageEmbed unbanEmbed = this .buildUnbanEmbed (userId , reason , bannedBy );
286- boolean isBanned = isBanned (bannedBy .getGuild (), userId );
287292 ModerationConfig moderationConfig = getModerationConfig (bannedBy );
288- if ( isBanned ) {
289- bannedBy . getGuild ().unban ( User . fromId ( userId )) .queue (s -> {
290- moderationConfig . getLogChannel (). sendMessageEmbeds ( unbanEmbed ). queue ();
291- if (! quiet ) channel .sendMessageEmbeds (unbanEmbed ).queue ();
292- }, ExceptionLogger :: capture );
293- }
294- return isBanned ;
293+ return bannedBy . getGuild (). unban ( User . fromId ( userId )). reason ( reason ). map ( _ -> {
294+ moderationConfig . getLogChannel ().sendMessageEmbeds ( unbanEmbed ) .queue (unbanLogMessage -> notifyUserAboutUnban ( userId , unbanEmbed , moderationConfig , unbanLogMessage ));
295+ if (! quiet ) {
296+ channel .sendMessageEmbeds (unbanEmbed ).queue ();
297+ }
298+ return null ;
299+ }). submit () ;
295300 }
296301
297- private boolean isBanned (@ NotNull Guild guild , long userId ) {
298- return guild .retrieveBanList ().complete ()
299- .stream ().map (Guild .Ban ::getUser )
300- .map (User ::getIdLong ).toList ().contains (userId );
302+ private void notifyUserAboutUnban (long userId , MessageEmbed unbanEmbed , ModerationConfig moderationConfig , Message unbanLogMessage ) {
303+ JDA jda = moderationConfig .getGuild ().getJDA ();
304+ jda .retrieveUserById (userId )
305+ .flatMap (User ::openPrivateChannel )
306+ .flatMap (c -> c .getHistory ().retrievePast (1 ))
307+ .queue (history -> {
308+ if (history .isEmpty ()) {
309+ return ;
310+ }
311+ Message banMessage = history .getFirst ();
312+ if (banMessage .getAuthor ().getIdLong () != jda .getSelfUser ().getIdLong ()) {
313+ return ;
314+ }
315+ ArrayList <MessageEmbed > embeds = new ArrayList <>(banMessage .getEmbeds ());
316+ embeds .add (new EmbedBuilder (unbanEmbed ).setColor (Responses .Type .SUCCESS .getColor ()).build ());
317+ banMessage .editMessageEmbeds (embeds ).setContent (moderationConfig .getUnbanMessageText ()).queue (success -> {
318+ List <MessageEmbed > unbanLogEmbeds = unbanLogMessage .getEmbeds ();
319+ if (unbanLogEmbeds .isEmpty ()) {
320+ return ;
321+ }
322+ unbanLogMessage .editMessageEmbeds (new EmbedBuilder (unbanLogEmbeds .getLast ())
323+ .addField ("User informed" , "The ban info in the user's DMs has been updated." , true ).build ())
324+ .queue ();
325+ });
326+ });
301327 }
302328
303329 /**
@@ -329,8 +355,19 @@ public void sendBanGuildNotification(User user, String reason, Member moderator)
329355 sendGuildNotification (moderator .getGuild (), buildBanEmbed (user , moderator , reason ));
330356 }
331357
358+ /**
359+ * Sends an unban notification to the guild log.
360+ *
361+ * This will also try to update the ban notification of the user to say they are unbanned.
362+ * @param user The unbanned user
363+ * @param reason The reason they were unbanned
364+ * @param moderator The moderator unbanning them (That {@link Member}'s {@link Guild} is used to determine the guild log to send the notification to.
365+ */
332366 public void sendUnbanGuildNotification (User user , String reason , Member moderator ) {
333- sendGuildNotification (moderator .getGuild (), buildUnbanEmbed (user .getIdLong (), reason , moderator ));
367+ MessageEmbed unbanEmbed = buildUnbanEmbed (user .getIdLong (), reason , moderator );
368+ sendGuildNotification (moderator .getGuild (), unbanEmbed , msg -> {
369+ notifyUserAboutUnban (user .getIdLong (), unbanEmbed , botConfig .get (moderator .getGuild ()).getModerationConfig (), msg );
370+ });
334371 }
335372
336373 public void sendTimeoutGuildNotification (User user , String reason , Member moderator , Duration duration ) {
@@ -342,12 +379,19 @@ public void sendRemoveTimeoutGuildNotification(User user, String reason, Member
342379 }
343380
344381 private void sendGuildNotification (Guild guild , MessageEmbed embed ) {
382+ sendGuildNotification (guild , embed , _ -> {});
383+ }
384+
385+ private void sendGuildNotification (Guild guild , MessageEmbed embed , Consumer <Message > onComplete ) {
345386 MessageEmbed newEmbed = new EmbedBuilder (embed )
346387 .addField ("Source" , "This action was executed manually without a bot command." , false )
347388 .build ();
348389 notificationService
349390 .withGuild (guild )
350- .sendToModerationLog (c -> c .sendMessageEmbeds (newEmbed ));
391+ .sendToModerationLog (c -> c .sendMessageEmbeds (newEmbed ).map (success -> {
392+ onComplete .accept (success );
393+ return success ;
394+ }));
351395 }
352396
353397 private @ NotNull EmbedBuilder buildModerationEmbed (@ NotNull User user , @ NotNull Member moderator , String reason ) {
0 commit comments