All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.neoforged.camelot.db.schemas.ModLogEntry Maven / Gradle / Ivy

There is a newer version: 1.0.177
Show newest version
package net.neoforged.camelot.db.schemas;

import com.google.common.collect.Lists;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.utils.TimeFormat;
import net.neoforged.camelot.util.Utils;
import org.jdbi.v3.core.mapper.RowMapper;
import org.jdbi.v3.core.statement.StatementContext;
import org.jetbrains.annotations.Nullable;
import net.neoforged.camelot.util.DateUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Represents a moderation action.
 */
public final class ModLogEntry {
    private int id;
    private final Type type;
    private final long user;
    private final long guild;
    private final long moderator;
    private final Instant timestamp;
    @Nullable
    private final Duration duration;
    @Nullable
    private final String reason;

    private ModLogEntry(int id, Type type, long user, long guild, long moderator, Instant timestamp, @Nullable Duration duration, @Nullable String reason) {
        this.id = id;
        this.type = type;
        this.user = user;
        this.guild = guild;
        this.moderator = moderator;
        this.timestamp = timestamp;
        this.duration = duration;
        this.reason = reason;
    }

    public void setId(int id) {
        this.id = id;
    }

    /**
     * {@return the ID of this entry}
     *
     * @throws UnsupportedOperationException if this entry does not have an ID (e.g. is not from a database)
     */
    public int id() {
        if (id == -1) {
            throw new UnsupportedOperationException("This entry is not from a database!");
        }
        return id;
    }

    /**
     * {@return the type of action this entry represents}
     */
    public Type type() {
        return type;
    }

    /**
     * {@return the ID of the moderated user}
     */
    public long user() {
        return user;
    }

    /**
     * {@return the ID of the guild the action was taken}
     */
    public long guild() {
        return guild;
    }

    /**
     * {@return the ID of the moderator}
     */
    public long moderator() {
        return moderator;
    }

    /**
     * {@return the timestamp of the moderation action}
     */
    public Instant timestamp() {
        return timestamp;
    }

    /**
     * {@return the duration of the moderation action}.
     * 

* Can be {@code null}. In the case of a ban, the user will be unbanned after this duration (if present), * and in the case of a mute it represents how long the user is muted for. *

*/ @Nullable public Duration duration() { return duration; } /** * {@return the reason for taking this action} */ @Nullable public String reason() { return reason; } /** * {@return the reason, or {@code Reason not specified} if one is not present} */ public String reasonOrDefault() { return Objects.requireNonNullElse(reason(), "Reason not specified"); } @Override public String toString() { return "ModLogEntry{" + "id=" + id + ", type=" + type + ", user=" + user + ", guild=" + guild + ", moderator=" + moderator + ", timestamp=" + timestamp + ", duration=" + duration + ", reason='" + reason + '\'' + '}'; } /** * Formats this log entry into an embed field containing all the information. * * @param jda the JDA instance to use for querying users * @return a completable future which will contain the formatted field */ public CompletableFuture format(JDA jda) { return type().format(this, jda); } /** * The type of a moderation action. */ public enum Type { WARN("warned", false, 0x00BFFF), KICK("kicked", false, 0xFFFFE0), MUTE("muted", true, 0xD3D3D3), UNMUTE("un-muted", false, 0xFFFFFF), BAN("banned", true, 0xFF0000), UNBAN("un-banned", false, 0x32CD32), NOTE("noted", false, 0x00FFFF) { @Override public CompletableFuture format(ModLogEntry entry, JDA jda) { return jda.retrieveUserById(entry.moderator()) .submit() .thenApply(mod -> Utils.getName(mod) + " (" + mod.getId() + ")") .exceptionally(ex -> String.valueOf(entry.moderator())) .thenApply(mod -> Lists.newArrayList( "**Type**: note", "**Moderator**: " + mod, "**Note**: " + entry.reason() )) .thenApply(lines -> new MessageEmbed.Field( "Note " + entry.id, String.join("\n", lines), false )); } }; private final String action; private final boolean supportsDuration; private final int color; Type(String action, boolean supportsDuration, int color) { this.action = action; this.supportsDuration = supportsDuration; this.color = color; } /** * {@return the past tense form of the verb describing the action} */ public String getAction() { return action; } /** * {@return {@code true} if this action supports a duration, {@code false} otherwise} */ public boolean supportsDuration() { return supportsDuration; } /** * {@return the color to be used for displaying this action in embeds} */ public int getColor() { return color; } /** * Formats a log entry into an embed field containing all the information. * * @param entry the log entry to format * @param jda the JDA instance to use for querying users * @return a completable future which will contain the formatted field */ public CompletableFuture format(ModLogEntry entry, JDA jda) { if (supportsDuration) { return collectInformation(entry, jda) .thenApply(accept(list -> list.add(entry.formatDuration()))) .thenApply(lines -> buildEmbed(entry, lines)); } return collectInformation(entry, jda) .thenApply(lines -> buildEmbed(entry, lines)); } protected final CompletableFuture> collectInformation(ModLogEntry entry, JDA jda) { return jda.retrieveUserById(entry.moderator()) .submit() .thenApply(mod -> Utils.getName(mod) + " (" + mod.getId() + ")") .exceptionally(ex -> String.valueOf(entry.moderator())) .thenApply(data -> Lists.newArrayList( "**Type**: " + name().toLowerCase(Locale.ROOT), "**Moderator**: " + data, "**Reason**: " + entry.reasonOrDefault() + " - " + TimeFormat.DATE_TIME_LONG.format(entry.timestamp()) )); } protected final MessageEmbed.Field buildEmbed(ModLogEntry entry, List lines) { return new MessageEmbed.Field( "Case " + entry.id(), String.join("\n", lines), false ); } protected final Function accept(Consumer cons) { return t -> { cons.accept(t); return t; }; } } /** * Formats the {@link #duration()} into a human-readable string, or if one doesn't exist, returns {@code Indefinite}. */ public String formatDuration() { return "**Duration**: " + (duration() == null ? "Indefinite" : DateUtils.formatDuration(duration) + " (until " + TimeFormat.DATE_TIME_LONG.format(timestamp.plus(duration())) + ")"); } public static ModLogEntry kick(long user, long guild, long moderator, @Nullable String reason) { return new ModLogEntry(-1, Type.KICK, user, guild, moderator, Instant.now(), null, reason); } public static ModLogEntry ban(long user, long guild, long moderator, @Nullable Duration duration, @Nullable String reason) { return new ModLogEntry(-1, Type.BAN, user, guild, moderator, Instant.now(), duration, reason); } public static ModLogEntry unban(long user, long guild, long moderator, @Nullable String reason) { return new ModLogEntry(-1, Type.UNBAN, user, guild, moderator, Instant.now(), null, reason); } public static ModLogEntry warn(long user, long guild, long moderator, @Nullable String reason) { return new ModLogEntry(-1, Type.WARN, user, guild, moderator, Instant.now(), null, reason); } public static ModLogEntry note(long user, long guild, long moderator, @Nullable String note) { return new ModLogEntry(-1, Type.NOTE, user, guild, moderator, Instant.now(), null, note); } public static ModLogEntry mute(long user, long guild, long moderator, @Nullable Duration duration, @Nullable String reason) { return new ModLogEntry(-1, Type.MUTE, user, guild, moderator, Instant.now(), duration, reason); } public static ModLogEntry unmute(long user, long guild, long moderator, @Nullable String reason) { return new ModLogEntry(-1, Type.UNMUTE, user, guild, moderator, Instant.now(), null, reason); } public static final class Mapper implements RowMapper { public static final Mapper INSTANCE = new Mapper(); @Override public ModLogEntry map(ResultSet rs, StatementContext ctx) throws SQLException { final long duration = rs.getLong(7); return new ModLogEntry( rs.getInt(1), Type.values()[rs.getInt(2)], rs.getLong(3), rs.getLong(4), rs.getLong(5), Instant.ofEpochSecond(rs.getLong(6)), duration == 0 ? null : Duration.of(duration, ChronoUnit.SECONDS), rs.getString(8) ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy