use of com.sx4.bot.entities.mod.action.Warn in project Sx4 by sx4-discord-bot.
the class WarnCommand method view.
@Command(value = "view", description = "View the amount of warnings a specific user is on")
@CommandId(259)
@Examples({ "warn view @Shea#6653", "warn view Shea", "warn view 402557516728369153" })
@Redirects({ "warnings", "warns" })
public void view(Sx4CommandEvent event, @Argument(value = "user", endless = true) Member member) {
List<Bson> pipeline = List.of(Aggregates.match(Filters.and(Filters.eq("userId", member.getIdLong()), Filters.eq("guildId", event.getGuild().getIdLong()))), Aggregates.project(Projections.computed("warnings", Operators.cond(Operators.or(Operators.isNull("$reset"), Operators.isNull("$warnings")), Operators.ifNull("$warnings", 0), Operators.max(0, Operators.subtract("$warnings", Operators.multiply(Operators.toInt(Operators.floor(Operators.divide(Operators.subtract(Operators.nowEpochSecond(), "$lastWarning"), "$reset.after"))), "$reset.amount")))))));
event.getMongo().aggregateWarnings(pipeline).whenComplete((documents, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
Document data = documents.isEmpty() ? MongoDatabase.EMPTY_DOCUMENT : documents.get(0);
int warnings = data.getInteger("warnings", 0);
event.reply("**" + member.getUser().getAsTag() + "** is currently on **" + warnings + "** warning" + (warnings == 1 ? "" : "s")).queue();
});
}
use of com.sx4.bot.entities.mod.action.Warn in project Sx4 by sx4-discord-bot.
the class WarnCommand method set.
@Command(value = "set", description = "Set the amount of warns a user has")
@CommandId(242)
@Redirects({ "set warns", "set warnings" })
@Examples({ "warn set @Shea#6653 2", "warn set Shea#6653 0", "warn set 402557516728369153 1" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
public void set(Sx4CommandEvent event, @Argument(value = "user") Member member, @Argument(value = "warnings") int warnings) {
if (member.canInteract(event.getMember())) {
event.replyFailure("You cannot change the amount of warnings of someone higher or equal than your top role").queue();
return;
}
Document warnData = event.getMongo().getGuildById(event.getGuild().getIdLong(), Projections.include("warn")).get("warn", MongoDatabase.EMPTY_DOCUMENT);
boolean punishments = warnData.get("punishments", true);
int maxWarning = punishments ? warnData.getList("config", Document.class, Warn.DEFAULT_CONFIG).stream().map(d -> d.getInteger("number")).max(Integer::compareTo).get() : Integer.MAX_VALUE;
if (warnings > maxWarning) {
event.replyFailure("The max amount of warnings you can give is **" + maxWarning + "**").queue();
return;
}
Bson update = warnings == 0 ? Updates.unset("warnings") : Updates.combine(Updates.set("warnings", warnings), Updates.set("lastWarning", Clock.systemUTC().instant().getEpochSecond()));
Bson filter = Filters.and(Filters.eq("userId", member.getIdLong()), Filters.eq("guildId", event.getGuild().getIdLong()));
event.getMongo().updateWarnings(filter, update, new UpdateOptions().upsert(true)).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (result.getModifiedCount() == 0 && result.getUpsertedId() == null) {
event.replyFailure("That user already had that amount of warnings").queue();
return;
}
event.replySuccess("That user now has **" + warnings + "** warning" + (warnings == 1 ? "" : "s")).queue();
});
}
use of com.sx4.bot.entities.mod.action.Warn in project Sx4 by sx4-discord-bot.
the class ModUtility method performAction.
public static CompletableFuture<? extends Action> performAction(Sx4 bot, Action action, Member target, Member moderator, Reason reason) {
Guild guild = target.getGuild();
switch(action.getModAction()) {
case WARN:
return ModUtility.warn(bot, target, moderator, reason);
case MUTE:
case MUTE_EXTEND:
if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
return CompletableFuture.failedFuture(new BotPermissionException(Permission.MANAGE_ROLES));
}
return ModUtility.mute(bot, target, moderator, Duration.ofSeconds(((TimeAction) action).getDuration()), action.getModAction().isExtend(), reason);
case KICK:
if (!guild.getSelfMember().hasPermission(Permission.KICK_MEMBERS)) {
return CompletableFuture.failedFuture(new BotPermissionException(Permission.KICK_MEMBERS));
}
if (!guild.getSelfMember().canInteract(target)) {
return CompletableFuture.failedFuture(new BotHierarchyException("kick"));
}
if (!moderator.hasPermission(Permission.KICK_MEMBERS)) {
return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.KICK_MEMBERS));
}
return target.kick(ModUtility.getAuditReason(reason, moderator.getUser())).submit().thenApply($ -> {
bot.getModActionManager().onModAction(new KickEvent(moderator, target.getUser(), reason));
return action;
});
case TEMPORARY_BAN:
if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
return CompletableFuture.failedFuture(new BotPermissionException(Permission.BAN_MEMBERS));
}
if (!guild.getSelfMember().canInteract(target)) {
return CompletableFuture.failedFuture(new BotHierarchyException("ban"));
}
if (!moderator.hasPermission(Permission.BAN_MEMBERS)) {
return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.BAN_MEMBERS));
}
long temporaryBanDuration = ((TimeAction) action).getDuration();
List<Bson> temporaryBanUpdate = List.of(Operators.set("unbanAt", Operators.add(Operators.nowEpochSecond(), temporaryBanDuration)));
Bson filter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
return bot.getMongo().updateTemporaryBan(filter, temporaryBanUpdate, new UpdateOptions().upsert(true)).thenCompose(temporaryBanResult -> target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).submit()).thenApply($ -> {
bot.getModActionManager().onModAction(new TemporaryBanEvent(moderator, target.getUser(), reason, true, temporaryBanDuration));
bot.getTemporaryBanManager().putBan(guild.getIdLong(), target.getIdLong(), temporaryBanDuration);
return action;
});
case BAN:
if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
return CompletableFuture.failedFuture(new BotPermissionException(Permission.BAN_MEMBERS));
}
if (!guild.getSelfMember().canInteract(target)) {
return CompletableFuture.failedFuture(new BotHierarchyException("ban"));
}
if (!moderator.hasPermission(Permission.BAN_MEMBERS)) {
return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.BAN_MEMBERS));
}
return target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).submit().thenApply($ -> {
bot.getModActionManager().onModAction(new BanEvent(moderator, target.getUser(), reason, true));
return action;
});
default:
return CompletableFuture.completedFuture(null);
}
}
use of com.sx4.bot.entities.mod.action.Warn in project Sx4 by sx4-discord-bot.
the class ModUtility method warn.
public static CompletableFuture<WarnAction> warn(Sx4 bot, Member target, Member moderator, Reason reason) {
CompletableFuture<WarnAction> future = new CompletableFuture<>();
Guild guild = target.getGuild();
Document data = bot.getMongo().getGuildById(guild.getIdLong(), Projections.include("warn", "mute", "temporaryBan", "fakePermissions"));
List<Document> fakePermissions = data.getEmbedded(List.of("fakePermissions", "holders"), Collections.emptyList());
Document warnData = data.get("warn", MongoDatabase.EMPTY_DOCUMENT);
List<Document> config = warnData.getList("config", Document.class, Warn.DEFAULT_CONFIG);
boolean punishments = warnData.getBoolean("punishments", true);
Document reset = warnData.get("reset", Document.class);
int maxWarning = punishments ? config.stream().map(d -> d.getInteger("number")).max(Integer::compareTo).get() : Integer.MAX_VALUE;
List<Bson> update = List.of(Operators.set("warnings", Operators.let(new Document("warnings", Operators.ifNull("$warnings", 0)), Operators.mod(Operators.cond(Operators.exists("$reset"), Operators.max(1, Operators.add(1, Operators.subtract("$$warnings", Operators.multiply(Operators.toInt(Operators.floor(Operators.divide(Operators.subtract(Operators.nowEpochSecond(), "$lastWarning"), "$reset.after"))), "$reset.amount")))), Operators.add("$$warnings", 1)), maxWarning))), Operators.set("lastWarning", Operators.nowEpochSecond()), reset == null ? Operators.unset("reset") : Operators.set("reset", reset));
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER).projection(Projections.include("warnings")).upsert(true);
Bson filter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
bot.getMongo().findAndUpdateWarnings(filter, update, options).whenComplete((result, exception) -> {
if (exception != null) {
future.completeExceptionally(exception);
return;
}
int warnings = result.getInteger("warnings");
Action warnAction = new Action(ModAction.WARN);
Action currentAction = warnAction, nextAction = warnAction;
if (punishments) {
for (Document configData : config) {
int number = configData.getInteger("number");
if (number == warnings) {
currentAction = Action.fromData(configData.get("action", Document.class));
} else if (number == warnings + 1) {
nextAction = Action.fromData(configData.get("action", Document.class));
}
}
}
Action action = currentAction;
Warn currentWarning = new Warn(action, warnings);
Warn nextWarning = new Warn(nextAction, warnings + 1);
switch(action.getModAction()) {
case WARN:
bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
future.complete(new WarnAction(currentWarning));
break;
case MUTE_EXTEND:
case MUTE:
if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
future.completeExceptionally(new BotPermissionException(Permission.MANAGE_ROLES));
return;
}
AtomicReference<Role> atomicRole = new AtomicReference<>();
Document mute = data.get("mute", MongoDatabase.EMPTY_DOCUMENT);
long muteDuration = ((TimeAction) action).getDuration();
boolean extend = action.getModAction().isExtend();
ModUtility.upsertMuteRole(bot.getMongo(), guild, mute.get("roleId", 0L), mute.get("autoUpdate", true)).thenCompose(role -> {
atomicRole.set(role);
List<Bson> muteUpdate = List.of(Operators.set("unmuteAt", Operators.add(muteDuration, Operators.cond(Operators.and(extend, Operators.exists("$unmuteAt")), "$unmuteAt", Operators.nowEpochSecond()))));
Bson muteFilter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
return bot.getMongo().updateMute(muteFilter, muteUpdate, new UpdateOptions().upsert(true));
}).whenComplete((muteResult, muteException) -> {
if (muteException != null) {
future.completeExceptionally(muteException);
return;
}
Role role = atomicRole.get();
guild.addRoleToMember(target, role).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
bot.getMuteManager().putMute(guild.getIdLong(), target.getIdLong(), role.getIdLong(), muteDuration, extend && muteResult.getUpsertedId() == null);
bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
future.complete(new WarnAction(currentWarning));
});
});
break;
case KICK:
if (!guild.getSelfMember().hasPermission(Permission.KICK_MEMBERS)) {
future.completeExceptionally(new BotPermissionException(Permission.KICK_MEMBERS));
return;
}
if (!guild.getSelfMember().canInteract(target)) {
future.completeExceptionally(new BotHierarchyException("kick"));
return;
}
if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.KICK_MEMBERS)) {
future.completeExceptionally(new AuthorPermissionException(Permission.KICK_MEMBERS));
return;
}
target.kick(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
future.complete(new WarnAction(currentWarning));
});
break;
case TEMPORARY_BAN:
if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
future.completeExceptionally(new BotPermissionException(Permission.BAN_MEMBERS));
return;
}
if (!guild.getSelfMember().canInteract(target)) {
future.completeExceptionally(new BotHierarchyException("ban"));
return;
}
if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.BAN_MEMBERS)) {
future.completeExceptionally(new AuthorPermissionException(Permission.BAN_MEMBERS));
return;
}
long temporaryBanDuration = ((TimeAction) action).getDuration();
Bson temporaryBanUpdate = Updates.set("unbanAt", Clock.systemUTC().instant().getEpochSecond() + temporaryBanDuration);
Bson temporaryBanFilter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
bot.getMongo().updateTemporaryBan(temporaryBanFilter, temporaryBanUpdate, new UpdateOptions().upsert(true)).whenComplete((temporaryBanResult, temporaryBanException) -> {
if (temporaryBanException != null) {
future.completeExceptionally(temporaryBanException);
return;
}
target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
bot.getTemporaryBanManager().putBan(guild.getIdLong(), target.getIdLong(), ((TimeAction) action).getDuration());
future.complete(new WarnAction(currentWarning));
});
});
break;
case BAN:
if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
future.completeExceptionally(new BotPermissionException(Permission.BAN_MEMBERS));
return;
}
if (!guild.getSelfMember().canInteract(target)) {
future.completeExceptionally(new BotHierarchyException("ban"));
return;
}
if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.BAN_MEMBERS)) {
future.completeExceptionally(new AuthorPermissionException(Permission.BAN_MEMBERS));
return;
}
target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
future.complete(new WarnAction(currentWarning));
});
break;
default:
break;
}
});
return future;
}
use of com.sx4.bot.entities.mod.action.Warn in project Sx4 by sx4-discord-bot.
the class WarnCommand method list.
@Command(value = "list", description = "Lists all the warned users in the server and how many warnings they have")
@CommandId(258)
@Examples({ "warn list" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void list(Sx4CommandEvent event) {
List<Bson> pipeline = List.of(Aggregates.match(Filters.eq("guildId", event.getGuild().getIdLong())), Aggregates.project(Projections.fields(Projections.include("userId"), Projections.computed("warnings", Operators.cond(Operators.or(Operators.isNull("$reset"), Operators.isNull("$warnings")), Operators.ifNull("$warnings", 0), Operators.max(0, Operators.subtract("$warnings", Operators.multiply(Operators.toInt(Operators.floor(Operators.divide(Operators.subtract(Operators.nowEpochSecond(), "$lastWarning"), "$reset.after"))), "$reset.amount"))))))), Aggregates.match(Filters.ne("warnings", 0)), Aggregates.sort(Sorts.descending("warnings")));
event.getMongo().aggregateWarnings(pipeline).whenComplete((users, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (users.isEmpty()) {
event.replyFailure("There are no users with warnings in this server").queue();
return;
}
PagedResult<Document> paged = new PagedResult<>(event.getBot(), users).setAuthor("Warned Users", null, event.getGuild().getIconUrl()).setIndexed(false).setDisplayFunction(data -> {
long userId = data.getLong("userId");
User user = event.getShardManager().getUserById(userId);
return "`" + (user == null ? "Anonymous#0000 (" + userId + ")" : MarkdownSanitizer.escape(user.getAsTag())) + "` - Warning **#" + data.getInteger("warnings") + "**";
});
paged.execute(event);
});
}
Aggregations