feat: Paper plugin + external API POST endpoint
This commit is contained in:
47
mc-report-plugin/pom.xml
Normal file
47
mc-report-plugin/pom.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.mcreport</groupId>
|
||||
<artifactId>mc-report-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.mcreport.plugin;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
private final String apiUrl;
|
||||
private final String externalKey;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public ApiClient(String apiUrl, String externalKey) {
|
||||
this.apiUrl = apiUrl;
|
||||
this.externalKey = externalKey;
|
||||
}
|
||||
|
||||
public boolean submitTicket(String type, String title, String reporterName, UUID reporterUuid,
|
||||
String targetName, UUID targetUuid, String reason, String description) {
|
||||
try {
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("type", type);
|
||||
body.addProperty("title", title);
|
||||
body.addProperty("reporter_game_name", reporterName);
|
||||
body.addProperty("reporter_game_uid", reporterUuid != null ? reporterUuid.toString() : "");
|
||||
|
||||
if (targetName != null && !targetName.isEmpty()) {
|
||||
body.addProperty("target_game_name", targetName);
|
||||
}
|
||||
if (targetUuid != null) {
|
||||
body.addProperty("target_game_uid", targetUuid.toString());
|
||||
}
|
||||
if (reason != null && !reason.isEmpty()) {
|
||||
body.addProperty("reason", reason);
|
||||
}
|
||||
if (description != null && !description.isEmpty()) {
|
||||
body.addProperty("description", description);
|
||||
}
|
||||
|
||||
URL url = new URI(apiUrl + "/tickets").toURL();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
conn.setRequestProperty("x-external-key", externalKey);
|
||||
conn.setDoOutput(true);
|
||||
conn.setConnectTimeout(5000);
|
||||
conn.setReadTimeout(5000);
|
||||
|
||||
try (OutputStream os = conn.getOutputStream()) {
|
||||
byte[] input = gson.toJson(body).getBytes(StandardCharsets.UTF_8);
|
||||
os.write(input, 0, input.length);
|
||||
}
|
||||
|
||||
int code = conn.getResponseCode();
|
||||
conn.disconnect();
|
||||
return code == 200 || code == 201;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String resolveUuid(String playerName) {
|
||||
try {
|
||||
URL url = new URI("https://api.mojang.com/users/profiles/minecraft/" + playerName).toURL();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
conn.setReadTimeout(5000);
|
||||
if (conn.getResponseCode() != 200) {
|
||||
conn.disconnect();
|
||||
return null;
|
||||
}
|
||||
String response = new String(conn.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
conn.disconnect();
|
||||
JsonObject json = gson.fromJson(response, JsonObject.class);
|
||||
return json != null ? json.get("id").getAsString() : null;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.mcreport.plugin;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AppealCommand implements CommandExecutor {
|
||||
|
||||
private final MCReportPlugin plugin;
|
||||
|
||||
public AppealCommand(MCReportPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage("§c仅玩家可使用此命令");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("§e/appeal <原因> §7- 提交申诉");
|
||||
return true;
|
||||
}
|
||||
|
||||
String reason = String.join(" ", args);
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
boolean ok = plugin.getApiClient().submitTicket(
|
||||
"appeal",
|
||||
"游戏内申诉: " + player.getName(),
|
||||
player.getName(),
|
||||
player.getUniqueId(),
|
||||
null, null,
|
||||
reason,
|
||||
reason
|
||||
);
|
||||
|
||||
if (ok) {
|
||||
player.sendMessage("§a申诉已提交!请等待处理");
|
||||
} else {
|
||||
player.sendMessage("§c提交失败,请联系管理员");
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.mcreport.plugin;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public final class MCReportPlugin extends JavaPlugin {
|
||||
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
saveDefaultConfig();
|
||||
String apiUrl = getConfig().getString("api_url", "http://localhost:3100/api/external");
|
||||
String externalKey = getConfig().getString("external_key", "");
|
||||
apiClient = new ApiClient(apiUrl, externalKey);
|
||||
|
||||
getCommand("report").setExecutor(new ReportCommand(this));
|
||||
getCommand("sugg").setExecutor(new SuggCommand(this));
|
||||
getCommand("appeal").setExecutor(new AppealCommand(this));
|
||||
|
||||
getLogger().info("MC举报系统插件已启用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("MC举报系统插件已卸载");
|
||||
}
|
||||
|
||||
public ApiClient getApiClient() {
|
||||
return apiClient;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.mcreport.plugin;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ReportCommand implements CommandExecutor {
|
||||
|
||||
private final MCReportPlugin plugin;
|
||||
|
||||
public ReportCommand(MCReportPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage("§c仅玩家可使用此命令");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("§6===== MC举报系统 ======");
|
||||
sender.sendMessage("§e/report <玩家名> <原因> §7- 举报玩家");
|
||||
sender.sendMessage("§e/report <原因> §7- 提交事项举报");
|
||||
sender.sendMessage("§e/sugg <内容> §7- 提交建议");
|
||||
sender.sendMessage("§e/appeal <原因> §7- 提交申诉");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player target = Bukkit.getPlayer(args[0]);
|
||||
String targetName = null;
|
||||
String targetUuid = null;
|
||||
int reasonStart = 0;
|
||||
|
||||
if (target != null && target.isOnline()) {
|
||||
targetName = target.getName();
|
||||
targetUuid = target.getUniqueId().toString();
|
||||
reasonStart = 1;
|
||||
}
|
||||
|
||||
if (args.length <= reasonStart) {
|
||||
sender.sendMessage("§c请填写举报原因");
|
||||
return true;
|
||||
}
|
||||
|
||||
String reason = String.join(" ", java.util.Arrays.copyOfRange(args, reasonStart, args.length));
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
boolean ok = plugin.getApiClient().submitTicket(
|
||||
"report",
|
||||
"游戏内举报: " + player.getName(),
|
||||
player.getName(),
|
||||
player.getUniqueId(),
|
||||
targetName,
|
||||
targetUuid != null ? java.util.UUID.fromString(targetUuid) : null,
|
||||
reason,
|
||||
null
|
||||
);
|
||||
|
||||
if (ok) {
|
||||
player.sendMessage("§a举报已提交!工作人员将尽快处理");
|
||||
} else {
|
||||
player.sendMessage("§c举报提交失败,请联系管理员");
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.mcreport.plugin;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SuggCommand implements CommandExecutor {
|
||||
|
||||
private final MCReportPlugin plugin;
|
||||
|
||||
public SuggCommand(MCReportPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage("§c仅玩家可使用此命令");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("§e/sugg <内容> §7- 提交建议");
|
||||
return true;
|
||||
}
|
||||
|
||||
String content = String.join(" ", args);
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
boolean ok = plugin.getApiClient().submitTicket(
|
||||
"suggestion",
|
||||
"游戏内建议: " + player.getName(),
|
||||
player.getName(),
|
||||
player.getUniqueId(),
|
||||
null, null, null,
|
||||
content
|
||||
);
|
||||
|
||||
if (ok) {
|
||||
player.sendMessage("§a建议已提交!感谢反馈");
|
||||
} else {
|
||||
player.sendMessage("§c提交失败,请联系管理员");
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
5
mc-report-plugin/src/main/resources/config.yml
Normal file
5
mc-report-plugin/src/main/resources/config.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
# MC举报系统 - 插件配置
|
||||
# API地址 (web服务地址)
|
||||
api_url: "http://localhost:3100/api/external"
|
||||
# 外部API密钥 (安装时生成)
|
||||
external_key: ""
|
||||
25
mc-report-plugin/src/main/resources/plugin.yml
Normal file
25
mc-report-plugin/src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
name: MCReport
|
||||
version: 1.0.0
|
||||
main: com.mcreport.plugin.MCReportPlugin
|
||||
api-version: 1.20
|
||||
author: Sea-Studio
|
||||
description: MC举报系统 - 游戏内举报插件
|
||||
|
||||
commands:
|
||||
report:
|
||||
description: 提交玩家举报
|
||||
usage: /<command> <玩家名> [原因]
|
||||
aliases: [jubao,举报]
|
||||
sugg:
|
||||
description: 提交建议
|
||||
usage: /<command> <内容>
|
||||
aliases: [jianyi,建议]
|
||||
appeal:
|
||||
description: 提交申诉
|
||||
usage: /<command> <原因>
|
||||
aliases: [shensu,申诉]
|
||||
|
||||
permissions:
|
||||
mcreport.use:
|
||||
description: 使用举报功能
|
||||
default: true
|
||||
Reference in New Issue
Block a user