Initial commit

This commit is contained in:
FirephoenixX02 2024-04-24 18:05:06 +02:00
commit df2838a6a2
24 changed files with 934 additions and 0 deletions

View 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);
}
}

View 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");
}
}

View file

@ -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");
}
}

View file

@ -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);
}
}

View file

@ -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");
}
}

View file

@ -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();
}
}

View 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;
}
}

View file

@ -0,0 +1,6 @@
[mysql]
host = "localhost"
port = "3306"
user = "user"
password = "changeme"
db = "your-database"

View 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
);