use of com.sx4.bot.config.Config 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.config.Config in project Sx4 by sx4-discord-bot.
the class ReactionRoleHandler method onGenericGuildMessageReaction.
public void onGenericGuildMessageReaction(GenericGuildMessageReactionEvent event) {
User user = event.getUser();
Guild guild = event.getGuild();
ReactionEmote emote = event.getReactionEmote();
if (user == null || user.isBot()) {
return;
}
Config config = this.bot.getConfig();
List<Document> reactionRoles = this.bot.getMongo().getReactionRoles(Filters.eq("messageId", event.getMessageIdLong()), MongoDatabase.EMPTY_DOCUMENT).into(new ArrayList<>());
if (reactionRoles.isEmpty()) {
return;
}
if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
user.openPrivateChannel().flatMap(channel -> channel.sendMessage("I am missing the `" + Permission.MANAGE_ROLES.getName() + "` permission " + config.getFailureEmote())).queue(null, ErrorResponseException.ignore(ErrorResponse.CANNOT_SEND_TO_USER));
return;
}
int reactedTo = 0;
List<Role> roles = null;
Document reactionRole = null;
boolean remove = false;
Set<Role> memberRoles = new HashSet<>(event.getMember().getRoles());
for (Document data : reactionRoles) {
List<Role> rolesData = data.getList("roles", Long.class).stream().map(guild::getRoleById).filter(Objects::nonNull).filter(role -> guild.getSelfMember().canInteract(role)).collect(Collectors.toList());
boolean allRoles = memberRoles.containsAll(rolesData);
if (allRoles) {
reactedTo++;
}
Document emoteData = data.get("emote", Document.class);
if ((emote.isEmoji() && emoteData.containsKey("name") && emoteData.getString("name").equals(emote.getEmoji())) || (emote.isEmote() && emoteData.containsKey("id") && emoteData.getLong("id") == emote.getEmote().getIdLong())) {
if (rolesData.isEmpty()) {
return;
}
roles = rolesData;
reactionRole = data;
remove = allRoles;
}
}
if (roles == null) {
return;
}
if (!remove) {
List<Document> permissions = reactionRole.getList("permissions", Document.class, Collections.emptyList());
for (int i = 0; i < permissions.size(); i++) {
Document permission = permissions.get(i);
long holderId = permission.getLong("id");
int type = permission.getInteger("type");
boolean granted = permission.getBoolean("granted");
if (type == HolderType.USER.getType() && holderId == user.getIdLong()) {
if (granted) {
break;
}
} else if (type == HolderType.ROLE.getType() && (holderId == guild.getIdLong() || memberRoles.stream().anyMatch(role -> role.getIdLong() == holderId))) {
if (granted) {
break;
}
}
if (i == permissions.size() - 1) {
user.openPrivateChannel().flatMap(channel -> channel.sendMessage("You are not whitelisted to be able to get the roles behind this reaction " + config.getFailureEmote())).queue(null, ErrorResponseException.ignore(ErrorResponse.CANNOT_SEND_TO_USER));
return;
}
}
}
int maxReactions = reactionRole.get("maxReactions", 0);
if (!remove && reactedTo >= maxReactions && maxReactions != 0) {
user.openPrivateChannel().flatMap(channel -> channel.sendMessage("You can only react to **" + maxReactions + "** reaction" + (maxReactions == 1 ? "" : "s") + " on this message " + config.getFailureEmote())).queue(null, ErrorResponseException.ignore(ErrorResponse.CANNOT_SEND_TO_USER));
return;
}
if (remove) {
guild.modifyMemberRoles(event.getMember(), null, roles).queue();
} else {
guild.modifyMemberRoles(event.getMember(), roles, null).queue();
}
String message = "You " + (remove ? "no longer" : "now") + " have the role" + (roles.size() == 1 ? "" : "s") + " `" + roles.stream().map(Role::getName).collect(Collectors.joining("`, `")) + "` " + config.getSuccessEmote();
if (reactionRole.getBoolean("dm", true)) {
user.openPrivateChannel().flatMap(channel -> channel.sendMessage(message)).queue(null, ErrorResponseException.ignore(ErrorResponse.CANNOT_SEND_TO_USER));
}
}
use of com.sx4.bot.config.Config 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.config.Config in project Sx4 by sx4-discord-bot.
the class StarboardHandler method onGuildMessageReactionRemove.
public void onGuildMessageReactionRemove(GuildMessageReactionRemoveEvent event) {
User user = event.getUser();
if (user == null || user.isBot()) {
return;
}
List<Bson> starboardPipeline = List.of(Aggregates.match(Filters.or(Filters.eq("originalMessageId", event.getMessageIdLong()), Filters.eq("messageId", event.getMessageIdLong()))), Aggregates.project(Projections.include("originalMessageId", "messageId", "count")));
List<Bson> pipeline = List.of(Aggregates.match(Filters.eq("_id", event.getGuild().getIdLong())), Aggregates.project(Projections.fields(Projections.include("starboard"), Projections.computed("premium", Operators.lt(Operators.nowEpochSecond(), Operators.ifNull("$premium.endAt", 0L))))), Aggregates.unionWith("starboards", starboardPipeline), Aggregates.group(null, Accumulators.max("count", "$count"), Accumulators.max("messageId", "$messageId"), Accumulators.max("originalMessageId", "$originalMessageId"), Accumulators.max("starboard", "$starboard"), Accumulators.max("premium", "$premium")));
this.bot.getMongo().aggregateGuilds(pipeline).whenComplete((documents, aggregateException) -> {
if (ExceptionUtility.sendErrorMessage(aggregateException)) {
return;
}
if (documents.isEmpty()) {
return;
}
Document data = documents.get(0);
Document starboard = data.get("starboard", MongoDatabase.EMPTY_DOCUMENT);
if (!starboard.get("enabled", false)) {
return;
}
long channelId = starboard.get("channelId", 0L);
TextChannel channel = channelId == 0L ? null : event.getGuild().getTextChannelById(channelId);
if (channel == null) {
return;
}
ReactionEmote emote = event.getReactionEmote();
boolean emoji = emote.isEmoji();
Document emoteData = starboard.get("emote", new Document("name", "⭐"));
if ((emoji && !emote.getEmoji().equals(emoteData.getString("name"))) || (!emoji && (!emoteData.containsKey("id") || emoteData.getLong("id") != emote.getIdLong()))) {
return;
}
Long originalMessageId = data.getLong("originalMessageId");
if (originalMessageId == null) {
return;
}
List<Document> config = starboard.getList("messages", Document.class, StarboardManager.DEFAULT_CONFIGURATION);
this.bot.getMongo().deleteStarById(event.getUserIdLong(), originalMessageId).thenCompose(result -> {
if (result.getDeletedCount() == 0) {
return CompletableFuture.completedFuture(null);
}
List<Bson> update = List.of(Operators.set("count", Operators.subtract("$count", 1)), Operators.set("messageId", Operators.cond(Operators.isEmpty(Operators.filter(config, Operators.gte(Operators.subtract("$count", 1), "$$this.stars"))), Operators.REMOVE, "$messageId")));
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER);
return this.bot.getMongo().findAndUpdateStarboard(Filters.eq("originalMessageId", originalMessageId), update, options);
}).whenComplete((updatedData, exception) -> {
if (ExceptionUtility.sendErrorMessage(exception) || updatedData == null) {
return;
}
if (!data.containsKey("messageId")) {
return;
}
WebhookMessage webhookMessage = this.getStarboardMessage(starboard, updatedData, event.getGuild(), event.getMember(), emote, data.getBoolean("premium"));
if (webhookMessage == null) {
this.bot.getStarboardManager().deleteStarboard(data.getLong("messageId"), channel.getIdLong(), starboard.get("webhook", MongoDatabase.EMPTY_DOCUMENT));
} else {
this.bot.getStarboardManager().editStarboard(data.getLong("messageId"), channel.getIdLong(), starboard.get("webhook", MongoDatabase.EMPTY_DOCUMENT), webhookMessage);
}
});
});
}
Aggregations