use of com.sx4.bot.entities.mod.action.Action in project Sx4 by sx4-discord-bot.
the class OffencesCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "user", endless = true, nullDefault = true) Member member) {
Bson filter = Filters.eq("guildId", event.getGuild().getIdLong());
if (member != null) {
filter = Filters.and(filter, Filters.eq("targetId", member.getIdLong()));
}
event.getMongo().getOffences(filter, Sorts.descending("_id")).whenComplete((iterable, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
try {
List<Document> data = iterable.into(new ArrayList<>());
if (data.isEmpty()) {
event.replyFailure((member == null ? "This server" : "**" + member.getUser().getAsTag() + "**") + " has no offences").queue();
return;
}
User user = member == null ? null : member.getUser();
PagedResult<Document> paged = new PagedResult<>(event.getBot(), data).setPerPage(6).setCustomFunction(page -> {
EmbedBuilder embed = new EmbedBuilder().setAuthor("Offences", null, member == null ? event.getGuild().getIconUrl() : user.getEffectiveAvatarUrl()).setTitle("Page " + page.getPage() + "/" + page.getMaxPage()).setFooter(PagedResult.DEFAULT_FOOTER_TEXT);
page.forEach((offence, index) -> {
Action action = Action.fromData(offence.get("action", Document.class));
ObjectId id = offence.getObjectId("_id");
OffsetDateTime time = OffsetDateTime.ofInstant(Instant.ofEpochSecond(id.getTimestamp()), ZoneOffset.UTC);
long targetId = offence.getLong("targetId");
User target = member == null ? event.getShardManager().getUserById(targetId) : user;
String targetContent = target == null ? "Anonymous#0000 (" + targetId + ")" : target.getAsTag();
long moderatorId = offence.getLong("moderatorId");
User moderator = event.getShardManager().getUserById(moderatorId);
String moderatorContent = moderator == null ? "Anonymous#0000 (" + moderatorId + ")" : moderator.getAsTag();
embed.addField(action.toString(), String.format("Target: %s\nModerator: %s\nReason: %s\nTime: %s", targetContent, moderatorContent, offence.get("reason", "None Given"), time.format(this.formatter)), true);
});
return new MessageBuilder().setEmbeds(embed.build());
});
paged.execute(event);
} catch (Throwable e) {
e.printStackTrace();
}
});
}
use of com.sx4.bot.entities.mod.action.Action in project Sx4 by sx4-discord-bot.
the class ModLogCommand method view.
@Command(value = "view", aliases = { "viewcase", "view case", "list" }, description = "View a mod log case from the server")
@CommandId(70)
@Examples({ "modlog view 5e45ce6d3688b30ee75201ae", "modlog view" })
public void view(Sx4CommandEvent event, @Argument(value = "id", nullDefault = true) ObjectId id) {
Bson projection = Projections.include("moderatorId", "reason", "targetId", "action");
if (id == null) {
List<Document> allData = event.getMongo().getModLogs(Filters.eq("guildId", event.getGuild().getIdLong()), projection).into(new ArrayList<>());
if (allData.isEmpty()) {
event.replyFailure("There are no mod logs in this server").queue();
return;
}
PagedResult<Document> paged = new PagedResult<>(event.getBot(), allData).setDisplayFunction(data -> {
long targetId = data.getLong("targetId");
User target = event.getShardManager().getUserById(targetId);
return Action.fromData(data.get("action", Document.class)) + " to `" + (target == null ? targetId : target.getAsTag() + "`");
}).setIncreasedIndex(true);
paged.onSelect(select -> event.reply(ModLog.fromData(select.getSelected()).getEmbed(event.getShardManager())).queue());
paged.execute(event);
} else {
Document data = event.getMongo().getModLogById(Filters.and(Filters.eq("_id", id), Filters.eq("guildId", event.getGuild().getIdLong())), projection);
if (data == null) {
event.replyFailure("I could not find a mod log with that id").queue();
return;
}
event.reply(ModLog.fromData(data).getEmbed(event.getShardManager())).queue();
}
}
use of com.sx4.bot.entities.mod.action.Action in project Sx4 by sx4-discord-bot.
the class ColourCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "colour", endless = true) @DefaultNumber(-1) @Colour int colour) {
if (colour == -1) {
colour = event.getRandom().nextInt(0xFFFFFF + 1);
}
String hex = "#" + ColourUtility.toHexString(colour);
MessageEmbed embed = new EmbedBuilder().setColor(ImageUtility.getEmbedColour(colour)).setAuthor(hex, null, "attachment://image.png").setDescription(String.format("Hex: %s\nRGB: %s", hex, ColourUtility.toRGBString(colour))).setImage("attachment://image.png").build();
Request request = new ImageRequest(event.getConfig().getImageWebserverUrl("colour")).addQuery("colour", colour).build(event.getConfig().getImageWebserver());
event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
MessageAction action = ImageUtility.getImageMessage(event, response);
if (response.isSuccessful()) {
action.setEmbeds(embed);
}
action.queue();
});
}
use of com.sx4.bot.entities.mod.action.Action 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.Action 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;
}
Aggregations