mirror of
https://github.com/FirephoenixX02/RapidReport.git
synced 2026-04-25 19:16:21 +02:00
Initial commit
This commit is contained in:
commit
df2838a6a2
24 changed files with 934 additions and 0 deletions
108
src/main/java/me/firephoenix/rapidreport/RapidReport.java
Normal file
108
src/main/java/me/firephoenix/rapidreport/RapidReport.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package me.firephoenix.rapidreport;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
import com.velocitypowered.api.command.CommandManager;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.plugin.Dependency;
|
||||
import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import lombok.Getter;
|
||||
import me.firephoenix.rapidreport.commands.CloseReportCommand;
|
||||
import me.firephoenix.rapidreport.commands.ListReportsCommand;
|
||||
import me.firephoenix.rapidreport.commands.ReportCommand;
|
||||
import me.firephoenix.rapidreport.commands.ReportGUICommand;
|
||||
import me.firephoenix.rapidreport.utils.DataBaseManager;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Plugin(
|
||||
id = "rapidreport",
|
||||
name = "RapidReport",
|
||||
version = "1.0",
|
||||
authors = {"NieGestorben"},
|
||||
dependencies = {
|
||||
@Dependency(id = "protocolize")
|
||||
}
|
||||
)
|
||||
public class RapidReport {
|
||||
public static RapidReport INSTANCE;
|
||||
@Getter
|
||||
public Logger logger;
|
||||
@Getter
|
||||
public ProxyServer proxy;
|
||||
@Getter
|
||||
public Path dataFolderPath;
|
||||
@Getter
|
||||
public Toml config;
|
||||
@Getter
|
||||
public DataBaseManager dataBaseManager;
|
||||
@Getter
|
||||
public String chatPrefix = "<gray>[<red>RapidReport<gray>] ";
|
||||
|
||||
@Inject
|
||||
public RapidReport(ProxyServer proxyServer, Logger logger, @DataDirectory final Path folder) {
|
||||
this.proxy = proxyServer;
|
||||
this.logger = logger;
|
||||
this.dataFolderPath = folder;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||||
CommandManager commandManager = proxy.getCommandManager();
|
||||
|
||||
setInstance(this);
|
||||
|
||||
config = loadConfig(dataFolderPath);
|
||||
|
||||
dataBaseManager = new DataBaseManager();
|
||||
|
||||
dataBaseManager.initDB();
|
||||
|
||||
commandManager.register(commandManager.metaBuilder("report").plugin(this).build(), new ReportCommand());
|
||||
commandManager.register(commandManager.metaBuilder("reports").plugin(this).build(), new ListReportsCommand());
|
||||
commandManager.register(commandManager.metaBuilder("closereport").plugin(this).build(), new CloseReportCommand());
|
||||
commandManager.register(commandManager.metaBuilder("reportgui").plugin(this).build(), new ReportGUICommand());
|
||||
}
|
||||
|
||||
public void setInstance(RapidReport INSTANCE) {
|
||||
RapidReport.INSTANCE = INSTANCE;
|
||||
}
|
||||
|
||||
public Toml loadConfig(Path path) {
|
||||
File folder = path.toFile();
|
||||
File file = new File(folder, "config.toml");
|
||||
|
||||
if (!file.getParentFile().exists()) {
|
||||
boolean created = file.getParentFile().mkdirs();
|
||||
if (!created) {
|
||||
throw new RuntimeException("Failed to create directories for config file.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!file.exists()) {
|
||||
try (InputStream inputStream = RapidReport.class.getResourceAsStream("/" + file.getName())) {
|
||||
if (inputStream != null) {
|
||||
Files.copy(inputStream, file.toPath());
|
||||
} else {
|
||||
boolean created = file.createNewFile();
|
||||
if (!created) {
|
||||
throw new RuntimeException("Failed to create config file.");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error while loading config file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return new Toml().read(file);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package me.firephoenix.rapidreport.commands;
|
||||
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import me.firephoenix.rapidreport.RapidReport;
|
||||
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2024, All Rights Reserved.
|
||||
*/
|
||||
public class CloseReportCommand implements SimpleCommand {
|
||||
|
||||
@Override
|
||||
public void execute(final Invocation invocation) {
|
||||
CommandSource commandSource = invocation.source();
|
||||
|
||||
String[] args = invocation.arguments();
|
||||
|
||||
if (args.length != 1) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Please provide the ID of the report which should be closed.");
|
||||
return;
|
||||
}
|
||||
|
||||
int id = Integer.parseInt(args[0]);
|
||||
|
||||
RapidReport.INSTANCE.getDataBaseManager().runStatementAsync("UPDATE rapid_report_reports SET status = 'Resolved' WHERE id = " + id);
|
||||
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Closed Report with ID <gray>" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final Invocation invocation) {
|
||||
return invocation.source().hasPermission("rapidreport.closereports");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package me.firephoenix.rapidreport.commands;
|
||||
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import me.firephoenix.rapidreport.RapidReport;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2024, All Rights Reserved.
|
||||
*/
|
||||
public class ListReportsCommand implements SimpleCommand {
|
||||
|
||||
@Override
|
||||
public void execute(final Invocation invocation) {
|
||||
CommandSource commandSource = invocation.source();
|
||||
|
||||
String[] args = invocation.arguments();
|
||||
|
||||
if (args.length == 0) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Fetching first 10 reports from database...");
|
||||
|
||||
CompletableFuture<ResultSet> future = RapidReport.INSTANCE.getDataBaseManager().getSQLStatementResultAsync("SELECT * FROM rapid_report_reports WHERE status = 'Unresolved' LIMIT 10");
|
||||
|
||||
future.thenAccept(result -> {
|
||||
try {
|
||||
while (result.next()) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<gray>[<red>" + result.getString("id") + "<gray>] <red>Reported Player: <gray>" + result.getString("reportedName") + " <red> Reason: <gray>" + result.getString("reason"));
|
||||
}
|
||||
result.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (args.length != 1) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Please provide the name of the player you want to get reports for.");
|
||||
return;
|
||||
}
|
||||
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Fetching first 10 reports for player <gray>" + args[0] + "<red> from database...");
|
||||
|
||||
CompletableFuture<ResultSet> future = RapidReport.INSTANCE.getDataBaseManager().getSQLStatementResultAsync("SELECT * FROM rapid_report_reports WHERE reportedName = '" + args[0] + "' LIMIT 10");
|
||||
|
||||
future.thenAccept(result -> {
|
||||
try {
|
||||
while (result.next()) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<gray>[<red>" + result.getString("id") + "<gray>] <red>Reported Player: <gray>" + result.getString("reportedName") + " <red> Reason: <gray>" + result.getString("reason"));
|
||||
}
|
||||
result.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final Invocation invocation) {
|
||||
return invocation.source().hasPermission("rapidreport.reports");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package me.firephoenix.rapidreport.commands;
|
||||
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import me.firephoenix.rapidreport.RapidReport;
|
||||
import me.firephoenix.rapidreport.utils.DataBaseManager;
|
||||
import me.firephoenix.rapidreport.utils.Report;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2024, All Rights Reserved.
|
||||
*/
|
||||
public class ReportCommand implements SimpleCommand {
|
||||
|
||||
@Override
|
||||
public void execute(final Invocation invocation) {
|
||||
CommandSource commandSource = invocation.source();
|
||||
|
||||
String reporterName = commandSource instanceof Player player ? player.getUsername() : "console";
|
||||
|
||||
String[] args = invocation.arguments();
|
||||
|
||||
if (args.length != 2) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Please enter in a player you want to report and a reason.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RapidReport.INSTANCE.getProxy().getPlayer(args[0]).isEmpty()) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>The player <gray>" + args[0] + "<red> is not online!");
|
||||
return;
|
||||
}
|
||||
|
||||
Player reportedPlayer = RapidReport.INSTANCE.getProxy().getPlayer(args[0]).get();
|
||||
|
||||
UUID reportedPlayerUUID = reportedPlayer.getUniqueId();
|
||||
|
||||
Report report = new Report(reporterName, reportedPlayer.getUsername(), reportedPlayerUUID, args[1], "Unresolved");
|
||||
|
||||
RapidReport.INSTANCE.getDataBaseManager().submitNewReportToDB(report);
|
||||
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>Player <gray>" + reportedPlayer.getUsername() + "<red> for <gray>" + args[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final Invocation invocation) {
|
||||
return invocation.source().hasPermission("rapidreport.report");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<String>> suggestAsync(final Invocation invocation) {
|
||||
List<String> playerNames = new ArrayList<>();
|
||||
RapidReport.INSTANCE.getProxy().getAllPlayers().forEach(player -> playerNames.add(player.getUsername()));
|
||||
return CompletableFuture.completedFuture(playerNames);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package me.firephoenix.rapidreport.commands;
|
||||
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import dev.simplix.protocolize.api.Protocolize;
|
||||
import dev.simplix.protocolize.api.chat.ChatElement;
|
||||
import dev.simplix.protocolize.api.inventory.Inventory;
|
||||
import dev.simplix.protocolize.api.player.ProtocolizePlayer;
|
||||
import dev.simplix.protocolize.data.inventory.InventoryType;
|
||||
import me.firephoenix.rapidreport.RapidReport;
|
||||
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2024, All Rights Reserved.
|
||||
*/
|
||||
public class ReportGUICommand implements SimpleCommand {
|
||||
|
||||
@Override
|
||||
public void execute(final Invocation invocation) {
|
||||
CommandSource commandSource = invocation.source();
|
||||
|
||||
String[] args = invocation.arguments();
|
||||
|
||||
if (!(commandSource instanceof Player)) {
|
||||
commandSource.sendRichMessage(RapidReport.INSTANCE.getChatPrefix() + "<red>This command can only be executed by a player.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Inventory inventory = new Inventory(InventoryType.GENERIC_9X4);
|
||||
inventory.title(ChatElement.ofLegacyText("§9Inventory"));
|
||||
|
||||
ProtocolizePlayer protocolizePlayer = Protocolize.playerProvider().player(((Player) commandSource).getUniqueId());
|
||||
|
||||
protocolizePlayer.openInventory(inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final Invocation invocation) {
|
||||
return invocation.source().hasPermission("rapidreport.gui");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
package me.firephoenix.rapidreport.utils;
|
||||
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import lombok.Getter;
|
||||
import me.firephoenix.rapidreport.RapidReport;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2023, All Rights Reserved.
|
||||
*/
|
||||
@Getter
|
||||
public class DataBaseManager {
|
||||
|
||||
private final HikariDataSource hikariCP;
|
||||
|
||||
public DataBaseManager() {
|
||||
this.hikariCP = new HikariDataSource();
|
||||
try {
|
||||
String host = RapidReport.INSTANCE.getConfig().getString("mysql.host");
|
||||
int port = Integer.parseInt(RapidReport.INSTANCE.getConfig().getString("mysql.port"));
|
||||
String username = RapidReport.INSTANCE.getConfig().getString("mysql.user");
|
||||
String password = RapidReport.INSTANCE.getConfig().getString("mysql.password");
|
||||
String database = RapidReport.INSTANCE.getConfig().getString("mysql.db");
|
||||
|
||||
getHikariCP().setMaximumPoolSize(25);
|
||||
getHikariCP().setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + "?characterEncoding=utf8");
|
||||
getHikariCP().addDataSourceProperty("port", port);
|
||||
getHikariCP().addDataSourceProperty("password", password);
|
||||
getHikariCP().addDataSourceProperty("databaseName", database);
|
||||
getHikariCP().addDataSourceProperty("user", username);
|
||||
getHikariCP().addDataSourceProperty("cachePrepStmts", true);
|
||||
getHikariCP().addDataSourceProperty("prepStmtCacheSize", 250);
|
||||
getHikariCP().addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
|
||||
getHikariCP().addDataSourceProperty("useServerPrepStmts", true);
|
||||
getHikariCP().addDataSourceProperty("useLocalSessionState", true);
|
||||
getHikariCP().addDataSourceProperty("rewriteBatchedStatements", true);
|
||||
getHikariCP().addDataSourceProperty("cacheResultSetMetadata", true);
|
||||
getHikariCP().addDataSourceProperty("cacheServerConfiguration", true);
|
||||
getHikariCP().addDataSourceProperty("elideSetAutoCommits", true);
|
||||
getHikariCP().addDataSourceProperty("maintainTimeStats", false);
|
||||
getHikariCP().addDataSourceProperty("alwaysSendSetIsolation", false);
|
||||
getHikariCP().addDataSourceProperty("cacheCallableStmts", true);
|
||||
|
||||
getHikariCP().setUsername(username);
|
||||
getHikariCP().setPassword(password);
|
||||
|
||||
this.hikariCP.getConnection();
|
||||
RapidReport.INSTANCE.logger.info("Successfully connected to database!");
|
||||
} catch (SQLException e) {
|
||||
RapidReport.INSTANCE.logger.info("There was an error connecting to the database! Error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void runStatementAsync(String statement) {
|
||||
RapidReport.INSTANCE.proxy.getScheduler().buildTask(RapidReport.INSTANCE, () -> {
|
||||
try {
|
||||
Connection connection = hikariCP.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(statement);
|
||||
preparedStatement.execute();
|
||||
preparedStatement.close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).schedule();
|
||||
}
|
||||
|
||||
public CompletableFuture<ResultSet> getSQLStatementResultAsync(String statement) {
|
||||
CompletableFuture<ResultSet> future = new CompletableFuture<>();
|
||||
|
||||
RapidReport.INSTANCE.proxy.getScheduler().buildTask(RapidReport.INSTANCE, () -> {
|
||||
try (Connection connection = hikariCP.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(statement)) {
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
future.complete(resultSet);
|
||||
} catch (SQLException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
}).schedule();
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public void submitNewReportToDB(Report report) {
|
||||
runStatementAsync("INSERT INTO rapid_report_reports (reporterName, reportedName, reportedUUID, reason, status) VALUES ('" + report.reporterPlayerName + "', '" + report.reportedPlayerName + "', '" + report.reportedPlayerUUID.toString() + "', '" + report.reason + "', '" + report.status + "')");
|
||||
}
|
||||
|
||||
public void initDB() {
|
||||
// first lets read our setup file.
|
||||
// This file contains statements to create our inital tables.
|
||||
// it is located in the resources.
|
||||
String setup;
|
||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream("dbsetup.sql")) {
|
||||
// Java 9+ way
|
||||
// Legacy way
|
||||
assert in != null;
|
||||
setup = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
|
||||
// Mariadb can only handle a single query per statement. We need to split at ;.
|
||||
String[] queries = setup.split(";");
|
||||
// execute each query to the database.
|
||||
for (String query : queries) {
|
||||
// If you use the legacy way you have to check for empty queries here.
|
||||
if (query.isEmpty()) continue;
|
||||
try (Connection conn = hikariCP.getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||
stmt.execute();
|
||||
} catch (SQLException e) {
|
||||
RapidReport.INSTANCE.logger.info("Error executing database setup!", e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
RapidReport.INSTANCE.logger.info("Could not read db setup file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
hikariCP.close();
|
||||
}
|
||||
}
|
||||
|
||||
26
src/main/java/me/firephoenix/rapidreport/utils/Report.java
Normal file
26
src/main/java/me/firephoenix/rapidreport/utils/Report.java
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package me.firephoenix.rapidreport.utils;
|
||||
|
||||
import me.firephoenix.rapidreport.commands.ReportCommand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author NieGestorben
|
||||
* Copyright© (c) 2024, All Rights Reserved.
|
||||
*/
|
||||
public class Report {
|
||||
public final String reporterPlayerName;
|
||||
public final String reportedPlayerName;
|
||||
public final UUID reportedPlayerUUID;
|
||||
public final String reason;
|
||||
public final String status;
|
||||
|
||||
public Report(final String reporterPlayerName, final String reportedPlayerName, final UUID reportedPlayerUUID, final String reason, final String status) {
|
||||
this.reporterPlayerName = reporterPlayerName;
|
||||
this.reportedPlayerName = reportedPlayerName;
|
||||
this.reportedPlayerUUID = reportedPlayerUUID;
|
||||
this.reason = reason;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
}
|
||||
6
src/main/resources/config.toml
Normal file
6
src/main/resources/config.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[mysql]
|
||||
host = "localhost"
|
||||
port = "3306"
|
||||
user = "user"
|
||||
password = "changeme"
|
||||
db = "your-database"
|
||||
8
src/main/resources/dbsetup.sql
Normal file
8
src/main/resources/dbsetup.sql
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE IF NOT EXISTS rapid_report_reports (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
reporterName VARCHAR(255) NOT NULL,
|
||||
reportedName VARCHAR(255) NOT NULL,
|
||||
reportedUUID VARCHAR(255) NOT NULL,
|
||||
reason VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(255) NOT NULL
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue