feat: 告示牌放置/编辑监控记录
1. land_block_log表新增detail列(已有数据库ALTER兼容) 2. DatabaseManager新增recordLandBlockWithDetail方法 3. LandRecordManager新增recordSignEdit方法,记录sign_place/sign_edit动作+内容 4. AreaProtection.onSignChange()延迟1tick记录(等事件处理完) 5. 回声碎片显示告示牌内容: 玩家XXX在HH:MM放置/编辑告示牌 [内容]
This commit is contained in:
@@ -4994,13 +4994,25 @@ public class AreaProtection implements Listener {
|
||||
@EventHandler
|
||||
public void onSignChange(SignChangeEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (p.hasPermission("sdf1.admin")) return; // 管理员跳过
|
||||
AreaConfig ac = getArea(
|
||||
p.getWorld().getName(),
|
||||
e.getBlock().getX(),
|
||||
e.getBlock().getY(),
|
||||
e.getBlock().getZ());
|
||||
if (ac == null) return;
|
||||
|
||||
// ★ 记录告示牌放置/编辑(权限检查前记录,被取消也要记录尝试)
|
||||
// 检测是编辑还是放置:如果该位置已有告示牌方块数据
|
||||
boolean isEdit = e.getBlock().getState() instanceof org.bukkit.block.Sign;
|
||||
String[] lines = e.getLines();
|
||||
// 延迟记录(等事件处理完后,内容已写入)
|
||||
final boolean editFinal = isEdit;
|
||||
plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
|
||||
plugin.landRecordManager.recordSignEdit(ac, p, e.getBlock(),
|
||||
lines, editFinal);
|
||||
}, 1L);
|
||||
|
||||
if (p.hasPermission("sdf1.admin")) return; // 管理员跳过
|
||||
if (p.getName().equalsIgnoreCase(ac.owner)) return; // 领地主免检
|
||||
if (isAreaAdmin(p)) return; // 插件管理员免检
|
||||
// ★ 授权成员(白名单内玩家)也豁免denySignEdit
|
||||
|
||||
@@ -317,9 +317,15 @@ public class DatabaseManager {
|
||||
+ "player_name TEXT,"
|
||||
+ "action TEXT,"
|
||||
+ "material TEXT,"
|
||||
+ "detail TEXT,"
|
||||
+ "time INTEGER"
|
||||
+ ")");
|
||||
|
||||
// ★ 新增detail列(已有数据库兼容)
|
||||
try {
|
||||
st.executeUpdate("ALTER TABLE land_block_log ADD COLUMN detail TEXT");
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
// 领地容器记录表:记录领地内容器的打开/拿取(7天滚动)
|
||||
st.execute("CREATE TABLE IF NOT EXISTS "
|
||||
+ "land_container_log ("
|
||||
@@ -2247,6 +2253,35 @@ public class DatabaseManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** ★ 记录领地方块(含detail,用于告示牌内容等) */
|
||||
public void recordLandBlockWithDetail(String landName, int landId,
|
||||
String world, int x, int y, int z,
|
||||
String playerName, String action,
|
||||
String material, String detail) {
|
||||
try {
|
||||
PreparedStatement ps = db.prepareStatement(
|
||||
"INSERT INTO land_block_log"
|
||||
+ " (land_name, land_id, world, x, y, z,"
|
||||
+ " player_name, action, material, detail, time)"
|
||||
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?)");
|
||||
ps.setString(1, landName);
|
||||
ps.setInt(2, landId);
|
||||
ps.setString(3, world);
|
||||
ps.setInt(4, x);
|
||||
ps.setInt(5, y);
|
||||
ps.setInt(6, z);
|
||||
ps.setString(7, playerName);
|
||||
ps.setString(8, action);
|
||||
ps.setString(9, material);
|
||||
ps.setString(10, detail);
|
||||
ps.setLong(11, System.currentTimeMillis());
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** 记录领地容器打开/拿取 */
|
||||
public void recordLandContainer(String landName, int landId,
|
||||
String world, int x, int y, int z,
|
||||
@@ -2285,7 +2320,7 @@ public class DatabaseManager {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
try {
|
||||
PreparedStatement ps = db.prepareStatement(
|
||||
"SELECT time, player_name, action, material"
|
||||
"SELECT time, player_name, action, material, detail"
|
||||
+ " FROM land_block_log"
|
||||
+ " WHERE world=? AND x=? AND y=? AND z=?"
|
||||
+ " ORDER BY time DESC LIMIT ?");
|
||||
@@ -2303,6 +2338,7 @@ public class DatabaseManager {
|
||||
rs.getString("player_name"));
|
||||
row.put("action", rs.getString("action"));
|
||||
row.put("material", rs.getString("material"));
|
||||
row.put("detail", rs.getString("detail"));
|
||||
list.add(row);
|
||||
}
|
||||
rs.close();
|
||||
|
||||
@@ -133,6 +133,32 @@ public class LandRecordManager implements Listener {
|
||||
recordBlock(ac, p, block, "state_change");
|
||||
}
|
||||
|
||||
/** ★ 记录告示牌放置/编辑(含内容) */
|
||||
public void recordSignEdit(AreaConfig ac, Player p, Block block,
|
||||
String[] lines, boolean isEdit) {
|
||||
try {
|
||||
int landId = plugin.areaProtection.getLandIdFromDb(ac.name);
|
||||
// 拼接4行内容,空行跳过
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String line : lines) {
|
||||
if (line != null && !line.isEmpty()) {
|
||||
if (sb.length() > 0) sb.append(" | ");
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
String detail = sb.toString();
|
||||
String action = isEdit ? "sign_edit" : "sign_place";
|
||||
plugin.getDb().recordLandBlockWithDetail(
|
||||
ac.name, landId,
|
||||
block.getWorld().getName(),
|
||||
block.getX(), block.getY(), block.getZ(),
|
||||
p.getName(), action,
|
||||
block.getType().name(), detail);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void recordBlock(AreaConfig ac, Player p, Block block,
|
||||
String action) {
|
||||
try {
|
||||
@@ -328,14 +354,27 @@ public class LandRecordManager implements Listener {
|
||||
act = "§a放置";
|
||||
} else if ("state_change".equals(action)) {
|
||||
act = "§e状态变化";
|
||||
} else if ("sign_place".equals(action)) {
|
||||
act = "§a放置告示牌";
|
||||
} else if ("sign_edit".equals(action)) {
|
||||
act = "§b编辑告示牌";
|
||||
} else {
|
||||
act = "§7" + action;
|
||||
}
|
||||
String mat = (String) r.get("material");
|
||||
String zh = translations.getOrDefault(mat, MaterialTranslator.toReadable(mat));
|
||||
p.sendMessage(" §7" + fmt((Long) r.get("time"))
|
||||
+ " §f" + r.get("player_name")
|
||||
+ " " + act + " §e" + mat + " §a" + zh);
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append(" §7").append(fmt((Long) r.get("time")))
|
||||
.append(" §f").append(r.get("player_name"))
|
||||
.append(" ").append(act)
|
||||
.append(" §e").append(mat).append(" §a").append(zh);
|
||||
// ★ 告示牌内容显示
|
||||
String detail = (String) r.get("detail");
|
||||
if (detail != null && !detail.isEmpty()
|
||||
&& ("sign_place".equals(action) || "sign_edit".equals(action))) {
|
||||
msg.append(" §7[§f").append(detail).append("§7]");
|
||||
}
|
||||
p.sendMessage(msg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user