feat: 新增 PVP 战神榜功能,新增 PVPManager 管理排行榜

This commit is contained in:
ypsdf1
2026-05-20 20:29:06 +08:00
parent cf246d4076
commit c9da8c8ec2
4 changed files with 1700 additions and 2 deletions
@@ -160,6 +160,32 @@ public class DatabaseManager {
+ "alert_date TEXT NOT NULL,"
+ "notified INTEGER DEFAULT 0,"
+ "notified_time INTEGER DEFAULT 0)");
// PVP区域表
st.execute("CREATE TABLE IF NOT EXISTS "
+ "pvp_regions ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "name TEXT NOT NULL UNIQUE,"
+ "world TEXT NOT NULL,"
+ "x1 INTEGER NOT NULL,"
+ "y1 INTEGER NOT NULL,"
+ "z1 INTEGER NOT NULL,"
+ "x2 INTEGER NOT NULL,"
+ "y2 INTEGER NOT NULL,"
+ "z2 INTEGER NOT NULL,"
+ "create_time INTEGER DEFAULT 0"
+ ")");
// PVP击杀总榜表
st.execute("CREATE TABLE IF NOT EXISTS "
+ "pvp_kills ("
+ "player_name TEXT NOT NULL,"
+ "region_name TEXT NOT NULL,"
+ "kills INTEGER DEFAULT 0,"
+ "deaths INTEGER DEFAULT 0,"
+ "PRIMARY KEY(player_name, region_name)"
+ ")");
// 菜单图标表
st.execute("CREATE TABLE IF NOT EXISTS "
+ "menu_icons ("
@@ -825,6 +851,252 @@ public class DatabaseManager {
return false;
}
}
// ==================== PVP区域 ====================
public void savePVPRegion(String name,
String world,
int x1, int y1, int z1,
int x2, int y2, int z2) {
try {
PreparedStatement ps =
db.prepareStatement(
"INSERT OR REPLACE "
+ "INTO pvp_regions "
+ "(name, world, "
+ "x1, y1, z1, "
+ "x2, y2, z2, "
+ "create_time) "
+ "VALUES "
+ "(?,?,?,?,?,?,?,?,?)");
ps.setString(1, name);
ps.setString(2, world);
ps.setInt(3, x1);
ps.setInt(4, y1);
ps.setInt(5, z1);
ps.setInt(6, x2);
ps.setInt(7, y2);
ps.setInt(8, z2);
ps.setLong(9,
System.currentTimeMillis());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public Map<String, Object>
getPVPRegion(String name) {
try {
PreparedStatement ps =
db.prepareStatement(
"SELECT * FROM "
+ "pvp_regions "
+ "WHERE name=?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Map<String, Object> row =
new LinkedHashMap<>();
for (int i = 1; i <= rs
.getMetaData()
.getColumnCount(); i++) {
row.put(rs.getMetaData()
.getColumnName(i),
rs.getObject(i));
}
rs.close();
ps.close();
return row;
}
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<Map<String, Object>>
getAllPVPRegions() {
List<Map<String, Object>> list =
new ArrayList<>();
try {
Statement st =
db.createStatement();
ResultSet rs =
st.executeQuery(
"SELECT * FROM "
+ "pvp_regions");
while (rs.next()) {
Map<String, Object> row =
new LinkedHashMap<>();
for (int i = 1; i <= rs
.getMetaData()
.getColumnCount(); i++) {
row.put(rs.getMetaData()
.getColumnName(i),
rs.getObject(i));
}
list.add(row);
}
rs.close();
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
public void deletePVPRegion(String name) {
try {
PreparedStatement ps =
db.prepareStatement(
"DELETE FROM "
+ "pvp_regions "
+ "WHERE name=?");
ps.setString(1, name);
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// ==================== PVP击杀 ====================
public int getPVPKills(
String player, String region) {
try {
PreparedStatement ps =
db.prepareStatement(
"SELECT kills FROM "
+ "pvp_kills "
+ "WHERE "
+ "player_name=? "
+ "AND region_name=?");
ps.setString(1, player);
ps.setString(2, region);
ResultSet rs = ps.executeQuery();
int kills = 0;
if (rs.next())
kills = rs.getInt("kills");
rs.close();
ps.close();
return kills;
} catch (SQLException e) {
return 0;
}
}
public int getPVPDeaths(
String player, String region) {
try {
PreparedStatement ps =
db.prepareStatement(
"SELECT deaths FROM "
+ "pvp_kills "
+ "WHERE "
+ "player_name=? "
+ "AND region_name=?");
ps.setString(1, player);
ps.setString(2, region);
ResultSet rs = ps.executeQuery();
int deaths = 0;
if (rs.next())
deaths = rs.getInt("deaths");
rs.close();
ps.close();
return deaths;
} catch (SQLException e) {
return 0;
}
}
public void addPVPKill(
String player, String region) {
try {
PreparedStatement ps =
db.prepareStatement(
"INSERT INTO pvp_kills "
+ "(player_name, "
+ "region_name, "
+ "kills, deaths) "
+ "VALUES (?,?,1,0) "
+ "ON CONFLICT"
+ "(player_name, "
+ "region_name) "
+ "DO UPDATE SET "
+ "kills=kills+1");
ps.setString(1, player);
ps.setString(2, region);
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void addPVPDeath(
String player, String region) {
try {
PreparedStatement ps =
db.prepareStatement(
"INSERT INTO pvp_kills "
+ "(player_name, "
+ "region_name, "
+ "kills, deaths) "
+ "VALUES (?,?,0,1) "
+ "ON CONFLICT"
+ "(player_name, "
+ "region_name) "
+ "DO UPDATE SET "
+ "deaths=deaths+1");
ps.setString(1, player);
ps.setString(2, region);
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public List<Map<String, Object>>
getPVPKillTop(String region, int limit) {
List<Map<String, Object>> list =
new ArrayList<>();
try {
PreparedStatement ps =
db.prepareStatement(
"SELECT player_name, "
+ "kills, deaths "
+ "FROM pvp_kills "
+ "WHERE "
+ "region_name=? "
+ "AND kills>0 "
+ "ORDER BY kills "
+ "DESC LIMIT ?");
ps.setString(1, region);
ps.setInt(2, limit);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Map<String, Object> row =
new LinkedHashMap<>();
row.put("player_name",
rs.getString("player_name"));
row.put("kills",
rs.getInt("kills"));
row.put("deaths",
rs.getInt("deaths"));
list.add(row);
}
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
// ==================== 安全报警 ====================
+81 -1
View File
@@ -131,6 +131,8 @@ public class Main extends JavaPlugin
public CommissionManager getCommission() {
return commission;
}
//pvp
private PVPManager pvpManager;
private static class PwdRollback {
final String hash;
@@ -355,7 +357,6 @@ public class Main extends JavaPlugin
startPasswordReminder();
startTicketAutoProcess();
radio.startMainRadio();
new BukkitRunnable() {
public void run() {
if (questTracker == null) return;
@@ -367,9 +368,74 @@ public class Main extends JavaPlugin
}
}
}.runTaskTimer(this, 600L, 600L);
// 12 ===PVP===
pvpManager = new PVPManager(this);
getServer().getPluginManager()
.registerEvents(pvpManager, this);
// PVP区域检测定时器
getServer().getScheduler()
.runTaskTimer(this,
() -> pvpManager.tickRegions(),
20L, 20L);
setupPVPTab();
getLogger().info("Sdf1_login v1.0 | 就绪");
}
private void setupPVPTab() {
if (getCommand("pvp") != null) {
getCommand("pvp")
.setTabCompleter(
(sender, cmd,
alias, args) -> {
List<String> list =
new ArrayList<>();
if (args.length == 1) {
String[] sub = {
"create", "stats",
"list", "delete",
"tool", "on", "off",
"tempban"};
for (String s : sub) {
if (s.startsWith(
args[0]
.toLowerCase())) {
list.add(s);
}
}
} else if (args.length == 2) {
String sub =
args[0].toLowerCase();
if (sub.equals("stats")) {
for (Player pp : Bukkit
.getOnlinePlayers()) {
if (pp.getName()
.toLowerCase()
.startsWith(args[1]
.toLowerCase())) {
list.add(pp.getName());
}
}
} else if (sub.equals("delete")
|| sub.equals("on")
|| sub.equals("off")
|| sub.equals("tempban")) {
for (String rn :
pvpManager
.getRegionNames()) {
if (rn.toLowerCase()
.startsWith(args[1]
.toLowerCase())) {
list.add(rn);
}
}
}
}
return list;
});
}
}
@Override
public void onDisable() {
@@ -2107,6 +2173,9 @@ public class Main extends JavaPlugin
public MenuManager getMenu() {
return menu;
}
public PVPManager getPVPManager() {
return pvpManager;
}
// ===== Inventory Click(旧逻辑 + 新主菜单布局 + 新功能) =====
@@ -3185,6 +3254,17 @@ public class Main extends JavaPlugin
String[] args) {
String cmdName = cmd.getName().toLowerCase();
if (label.equalsIgnoreCase("pvp")) {
if (!(sender instanceof Player)) {
sender.sendMessage("§c仅玩家可用");
return true;
}
Player p = (Player) sender;
return pvpManager.onCommand(p, args);
}
// ===== /chat 独立命令 =====
if (cmdName.equals("chat")
|| cmdName.equals("聊天")) {
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -86,4 +86,7 @@ commands:
usage: /垃圾清理
menu:
description: 雪球菜单开关控制
usage: /menu <开/关>
usage: /menu <开/关>
pvp :
description: PVP榜单
usage: /pvp