修复:垃圾箱物品存入立即吞噬的问题和服务器没启用飞行功能被踢出的问题

This commit is contained in:
ypsdf1
2026-05-11 13:26:55 +08:00
parent 145b392112
commit 87de2e12c8
9 changed files with 8259 additions and 8105 deletions
+1 -2
View File
@@ -1,6 +1,5 @@
*.md text=auto encoding=UTF-8
*.png binary *.png binary
*.jpg binary *.jpg binary
*.jpeg binary *.jpeg binary
*.gif binary *.gif binary
*.ico binary
*.bmp binary
+17 -6
View File
@@ -312,6 +312,14 @@ public class ConfigManager {
requesterPointsReward = parseInt( requesterPointsReward = parseInt(
m.getOrDefault("报单人积分奖励", "10"), m.getOrDefault("报单人积分奖励", "10"),
10); 10);
garbageEnabled = Boolean.parseBoolean(
m.getOrDefault("垃圾站_启用", "true"));
garbageInterval = parseInt(
m.getOrDefault("垃圾站_清理间隔秒",
"300"), 300);
garbageMaxRounds = parseInt(
m.getOrDefault("垃圾站_保留轮数",
"1"), 1);
} }
@@ -331,12 +339,10 @@ public class ConfigManager {
L.add("挂机超时秒数=" + afkTimeout); L.add("挂机超时秒数=" + afkTimeout);
// 垃圾站设置 // 垃圾站设置
L.add("# ---- 垃圾站 ----"); L.add("# ---- 垃圾站 ----");
L.add("垃圾站_启用: " L.add("垃圾站_启用=" + garbageEnabled);
+ garbageEnabled); L.add("垃圾站_清理间隔秒=" + garbageInterval);
L.add("垃圾站_清理间隔秒: " L.add("垃圾站_保留轮数=" + garbageMaxRounds);
+ garbageInterval);
L.add("垃圾站_保留轮数: "
+ garbageMaxRounds);
writeLines(file, L); writeLines(file, L);
} }
@@ -364,6 +370,11 @@ public class ConfigManager {
L.add("基础经济奖励=" + baseEconomyReward); L.add("基础经济奖励=" + baseEconomyReward);
L.add("经济奖励每评分=" + providerEconomyPerScore); L.add("经济奖励每评分=" + providerEconomyPerScore);
L.add("报单人积分奖励=" + requesterPointsReward); L.add("报单人积分奖励=" + requesterPointsReward);
L.add("# ---- 垃圾站 ----");
L.add("垃圾站_启用=true");
L.add("垃圾站_清理间隔秒=300");
L.add("垃圾站_保留轮数=1");
writeLines(f, L); writeLines(f, L);
} }
+12 -1
View File
@@ -201,7 +201,18 @@ public class DatabaseManager {
+ "active INTEGER DEFAULT 1," + "active INTEGER DEFAULT 1,"
+ "join_time INTEGER DEFAULT 0" + "join_time INTEGER DEFAULT 0"
+ ")"); + ")");
// 垃圾回收站物品表
st.execute("CREATE TABLE IF NOT EXISTS "
+ "items ("
+ "id INTEGER PRIMARY KEY "
+ "AUTOINCREMENT,"
+ "player_name TEXT NOT NULL,"
+ "item_data TEXT DEFAULT '',"
+ "amount INTEGER DEFAULT 1,"
+ "create_time INTEGER DEFAULT 0"
+ ")");
safeAdd(st, "menu_snowball",
"INTEGER DEFAULT 1");
st.close(); st.close();
logger.info("[Sdf1_login] 数据库初始化完成"); logger.info("[Sdf1_login] 数据库初始化完成");
} catch (Exception e) { } catch (Exception e) {
+6
View File
@@ -489,6 +489,12 @@ public class GUIManager {
"§e设置密码")); "§e设置密码"));
g.setItem(16, mkItem(Material.BARRIER, g.setItem(16, mkItem(Material.BARRIER,
"§c删除用户", "§7二次验证删除")); "§c删除用户", "§7二次验证删除"));
// 雪球菜单检测(slot 14)
g.setItem(14, mkItem(
Material.SNOWBALL,
"§e§l雪球菜单",
"§7点击为该玩家发放菜单雪球"));
g.setItem(22, mkItem(Material.ARROW, "§7返回")); g.setItem(22, mkItem(Material.ARROW, "§7返回"));
p.openInventory(g); p.openInventory(g);
} }
@@ -380,6 +380,38 @@ public class GarbageManager {
int amount = ((Number) item int amount = ((Number) item
.get("amount")).intValue(); .get("amount")).intValue();
ItemStack stack = base64ToStack(data); ItemStack stack = base64ToStack(data);
if (stack != null) {
try {
byte[] bytes =
stack.serializeAsBytes();
String b64 = java.util.Base64
.getEncoder()
.encodeToString(bytes);
int len = b64.length();
String f = len > 15
? b64.substring(10, 15) : "短";
String m = len >= 5
? b64.substring(len / 2,
Math.min(len / 2 + 5, len))
: "短";
String b = len > 10
? b64.substring(len - 10, len - 5)
: "短";
plugin.getLogger().info(
"[垃圾站加载] ID#" + id
+ " " + stack.getType()
+ " x" + amount
+ " base64[" + len + "]"
+ " 前=" + f
+ " 中=" + m
+ " 后=" + b);
} catch (Exception ex) {
plugin.getLogger().warning(
"[垃圾站加载] 序列化异常: "
+ ex.getMessage());
}
}
if (stack != null) { if (stack != null) {
stack.setAmount(amount); stack.setAmount(amount);
ItemMeta im = ItemMeta im =
@@ -431,6 +463,10 @@ public class GarbageManager {
g.setItem(51, mk(Material.ARROW, g.setItem(51, mk(Material.ARROW,
"§7已是最后一页")); "§7已是最后一页"));
} }
// 52格:返回按钮
g.setItem(52, mk(Material.ARROW,
"§7返回",
"§7返回主菜单"));
p.openInventory(g); p.openInventory(g);
} }
@@ -459,6 +495,12 @@ public class GarbageManager {
openRecyclePage(p, page + 1); openRecyclePage(p, page + 1);
return true; return true;
} }
// 52:返回
if (slot == 52) {
plugin.getGui().openMain(p);
return true;
}
// 50/52/53:不处理 // 50/52/53:不处理
if (slot >= 49 && slot <= 53) if (slot >= 49 && slot <= 53)
return true; return true;
+11 -48
View File
@@ -155,55 +155,18 @@ public class GiftManager {
} }
public boolean canClaim(Player p, int stage) { public boolean canClaim(Player p, int stage) {
Map<String, Object> user = plugin.getDb() String name = p.getName();
.getUser(p.getName()); int curStage = ((Number) plugin.getDb()
if (user.isEmpty()) return false; .getField(name, "gift_stage"))
int curStage = ((Number) user.getOrDefault( .intValue();
"gift_stage", 0)).intValue(); String claimed = (String) plugin.getDb()
if (stage > curStage + 1) return false; .getField(name, "gift_claimed");
if (stage < 1 || stage > stages.size()) if (claimed == null) claimed = "";
return false; return curStage >= stage
String claimed = (String) user.getOrDefault( && !claimed.contains(
"gift_claimed", ""); String.valueOf(stage));
if (claimed.contains("[" + stage + "]")) }
return false;
// debug 绕过:检查 tasks_completed
String completed = (String) user.getOrDefault(
"tasks_completed", "");
if (completed.contains("[" + stage + "]"))
return true;
// 正常条件检查
long dbTime = ((Number) user.getOrDefault(
"total_online_time", 0L)).longValue();
long sessionTime = 0;
Object lastObj = plugin.getDb().getField(
p.getName(), "last_online_check");
if (lastObj != null && plugin.getLoggedIn()
.contains(p.getName())) {
long last = ((Number) lastObj).longValue();
if (last > 0) {
sessionTime =
System.currentTimeMillis() - last;
}
}
long onlineTime = dbTime + sessionTime;
int broken = ((Number) user.getOrDefault(
"blocks_broken", 0)).intValue();
int placed = ((Number) user.getOrDefault(
"blocks_placed", 0)).intValue();
switch (stage) {
case 1: return true;
case 2: return onlineTime >= 3600000;
case 3: return broken >= 100
&& onlineTime >= 86400000L;
case 4: return (broken + placed) >= 300
&& onlineTime >= 604800000L;
default: return false;
}
}
public void claimReward(Player p, int stage) { public void claimReward(Player p, int stage) {
if (!canClaim(p, stage)) return; if (!canClaim(p, stage)) return;
+240 -109
View File
@@ -196,6 +196,8 @@ public class Main extends JavaPlugin
getCommand("sdf1debug").setExecutor(this); getCommand("sdf1debug").setExecutor(this);
if (getCommand("oa") != null) if (getCommand("oa") != null)
getCommand("oa").setExecutor(this); getCommand("oa").setExecutor(this);
if (getCommand("menu") != null)
getCommand("menu").setExecutor(this);
getServer().getPluginManager() getServer().getPluginManager()
@@ -1099,6 +1101,9 @@ public class Main extends JavaPlugin
return; return;
} }
} }
if (isFrozen(p)) {
p.setAllowFlight(true);
}
if (!"manual".equals(config.approvalMode) if (!"manual".equals(config.approvalMode)
&& !db.userExists(name)) { && !db.userExists(name)) {
@@ -1238,36 +1243,82 @@ public class Main extends JavaPlugin
private static final String MENU_SNOWBALL_TAG = private static final String MENU_SNOWBALL_TAG =
"sdf1_menu"; "sdf1_menu";
// 雪球菜单
public void giveMenuSnowball(Player p) { public void giveMenuSnowball(Player p) {
// 检查背包里是否已有菜单雪球 // 检查开关
Object val = db.getField(
p.getName(), "menu_snowball");
if (val != null) {
int on = val instanceof Number
? ((Number) val).intValue()
: 1;
if (on == 0) {
return; // 开关关了,不发放
}
}
// 检查是否已有
for (ItemStack it : p.getInventory() for (ItemStack it : p.getInventory()
.getContents()) { .getContents()) {
if (isMenuSnowball(it)) { if (isMenuSnowball(it)) {
return; // 已有,不重复发 return;
} }
} }
// 没有则发放 // 发放
ItemStack snow = new ItemStack( ItemStack snow = new ItemStack(
Material.SNOWBALL); Material.SNOWBALL);
ItemMeta im = snow.getItemMeta(); ItemMeta im = snow.getItemMeta();
if (im != null) { if (im != null) {
im.setDisplayName( im.setDisplayName(
"§e§l[菜单] §f右键打开主菜单"); "§e§l[菜单] §f右键打开主菜单");
List<String> lore = new ArrayList<>(); List<String> lore =
new ArrayList<>();
lore.add("§7右键点击打开功能菜单"); lore.add("§7右键点击打开功能菜单");
lore.add("§8" + MENU_SNOWBALL_TAG); lore.add("§8" + MENU_SNOWBALL_TAG);
im.setLore(lore); im.setLore(lore);
snow.setItemMeta(im); snow.setItemMeta(im);
} }
// 放到最后一个空格,避免覆盖 int slot = p.getInventory()
int emptySlot =
p.getInventory()
.firstEmpty(); .firstEmpty();
if (emptySlot >= 0) { if (slot >= 0) {
p.getInventory().setItem( p.getInventory().setItem(
emptySlot, snow); slot, snow);
} else {
p.getWorld().dropItemNaturally(
p.getLocation(), snow);
}
}
/**
* 手动发放雪球菜单(绕过开关检查)
*/
public void forceGiveMenuSnowball(
Player p) {
// 只检查是否已有
for (ItemStack it : p.getInventory()
.getContents()) {
if (isMenuSnowball(it)) {
return;
}
}
ItemStack snow = new ItemStack(
Material.SNOWBALL);
ItemMeta im = snow.getItemMeta();
if (im != null) {
im.setDisplayName(
"§e§l[菜单] §f右键打开主菜单");
List<String> lore =
new ArrayList<>();
lore.add("§7右键点击打开功能菜单");
lore.add("§8" + MENU_SNOWBALL_TAG);
im.setLore(lore);
snow.setItemMeta(im);
}
int slot = p.getInventory()
.firstEmpty();
if (slot >= 0) {
p.getInventory().setItem(
slot, snow);
} else { } else {
// 背包满,丢在地上
p.getWorld().dropItemNaturally( p.getWorld().dropItemNaturally(
p.getLocation(), snow); p.getLocation(), snow);
} }
@@ -1296,21 +1347,24 @@ public class Main extends JavaPlugin
@EventHandler @EventHandler
public void onMove(PlayerMoveEvent e) { public void onMove(PlayerMoveEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
if (!isFrozen(p)) return;
Location from = e.getFrom(); Location from = e.getFrom();
Location to = e.getTo(); Location to = e.getTo();
if (isFrozen(p)) { if (to == null) return;
if (to != null && (from.getX() != to.getX()
|| from.getY() != to.getY() // 允许转头(无位移)
|| from.getZ() != to.getZ())) { if (from.getBlockX() == to.getBlockX()
e.setTo(e.getFrom()); && from.getBlockY() == to.getBlockY()
} && from.getBlockZ() == to.getBlockZ()) {
return; return;
} }
if (to != null && (from.getX() != to.getX()
|| from.getY() != to.getY() // 有位移 → 取消
|| from.getZ() != to.getZ())) { e.setCancelled(true);
afk.recordAction(p.getUniqueId());
} // 防止"服务器未启用飞行"踢出
p.setAllowFlight(true);
} }
@EventHandler @EventHandler
@@ -1484,6 +1538,7 @@ public class Main extends JavaPlugin
// ===== Inventory Click =====
// ===== Inventory Click ===== // ===== Inventory Click =====
@EventHandler @EventHandler
public void onInvClick(InventoryClickEvent e) { public void onInvClick(InventoryClickEvent e) {
@@ -1494,12 +1549,41 @@ public class Main extends JavaPlugin
e.setCancelled(true); e.setCancelled(true);
return; return;
} }
String title = String title = e.getView().getTitle();
e.getView().getTitle();
int slot = e.getRawSlot(); int slot = e.getRawSlot();
if (needsPasswordChange.contains(p.getName()) // Shift+点击背包物品 → 存入垃圾箱
&& !title.equals("§6§l任务面板")) { if (e.isShiftClick()
&& e.getClickedInventory() != null
&& e.getClickedInventory()
== p.getInventory()
&& e.getCurrentItem() != null
&& e.getCurrentItem().getType()
!= Material.AIR
&& !isMenuSnowball(
e.getCurrentItem())
&& title.equals(
"§6§l垃圾回收站")) {
e.setCancelled(true);
ItemStack clicked =
e.getCurrentItem().clone();
garbage.saveItem(clicked);
e.getInventory().setItem(
e.getSlot(), null);
Bukkit.getScheduler()
.runTaskLater(this,
() -> {
garbage.openRecyclePage(p,
garbage.getRecyclePage(
p.getName()));
}, 1L);
return;
}
if (needsPasswordChange
.contains(p.getName())
&& !title.equals(
"§6§l任务面板")) {
e.setCancelled(true); e.setCancelled(true);
p.sendMessage("§c请先修改密码!"); p.sendMessage("§c请先修改密码!");
return; return;
@@ -1516,12 +1600,15 @@ public class Main extends JavaPlugin
TicketManager.T_TICKET_ADMIN) TicketManager.T_TICKET_ADMIN)
|| title.equals( || title.equals(
TicketManager.T_TICKET_DETAIL) TicketManager.T_TICKET_DETAIL)
|| title.equals("§d§l服务商面板") || title.equals(
|| title.equals("§6§l抢单大厅") "§d§l服务商面板")
|| title.equals(
"§6§l抢单大厅")
|| title.equals( || title.equals(
"§b§l我处理中的工单")) { "§b§l我处理中的工单")) {
e.setCancelled(true); e.setCancelled(true);
ticket.handleClick(p, title, slot); ticket.handleClick(
p, title, slot);
return; return;
} }
@@ -1539,96 +1626,67 @@ public class Main extends JavaPlugin
ItemStack inSlot = ItemStack inSlot =
e.getInventory().getItem(slot); e.getInventory().getItem(slot);
ItemStack onCursor = e.getCursor(); ItemStack cursor = e.getCursor();
// 1. 格子里是垃圾站物品 → 取出 // ===== 取出 =====
if (isTrashDisplayItem(inSlot)) { if (inSlot != null
&& inSlot.hasItemMeta()
&& inSlot.getItemMeta().hasLore()) {
List<String> lore =
inSlot.getItemMeta().getLore();
if (lore != null && !lore.isEmpty()
&& lore.get(0)
.startsWith("§7ID: #")) {
e.setCancelled(true); e.setCancelled(true);
try { try {
List<String> lore = String numStr = lore.get(0)
inSlot.getItemMeta() .replace("§7ID: #", "")
.getLore();
String numStr =
lore.get(0)
.replace(
"§7ID: #", "")
.trim(); .trim();
int dbId = Integer int dbId =
.parseInt(numStr); Integer.parseInt(numStr);
// 先从DB删除 if (garbage.removeItem(dbId)) {
if (garbage.removeItem(
dbId)) {
// 再给玩家(去掉ID lore)
ItemStack give = ItemStack give =
inSlot.clone(); inSlot.clone();
ItemMeta gm = ItemMeta gm =
give.getItemMeta(); give.getItemMeta();
if (gm != null) { gm.setLore(null);
List<String> newLore =
new ArrayList<>();
// 保留原始lore(跳过ID和数量行)
if (lore.size() > 2) {
for (int li = 2;
li < lore
.size();
li++) {
newLore.add(
lore.get(
li));
}
}
gm.setLore(
newLore.isEmpty()
? null
: newLore);
give.setItemMeta(gm); give.setItemMeta(gm);
}
p.getInventory() p.getInventory()
.addItem(give); .addItem(give);
// 清空格子
e.getInventory() e.getInventory()
.setItem(slot, .setItem(slot, null);
null);
} }
} catch (Exception ex) { } catch (Exception ex) {
p.sendMessage("§c取出失败"); p.sendMessage("§c取出失败");
} }
return; return;
} }
// 2. 格子空 + 手上有物品 → 放入
if ((inSlot == null
|| inSlot.getType()
== Material.AIR)
&& onCursor != null
&& onCursor.getType()
!= Material.AIR
&& !isMenuSnowball(
onCursor)) {
// 不取消!让物品自然进入格子
Bukkit.getScheduler()
.runTaskLater(this,
() -> {
ItemStack after =
e.getInventory()
.getItem(
slot);
if (after != null
&& after.getType()
!= Material.AIR) {
garbage.saveItem(
after
.clone());
e.getInventory()
.setItem(
slot,
null);
} }
// ===== 光标存入 =====
if (cursor != null
&& cursor.getType()
!= Material.AIR
&& !isMenuSnowball(cursor)) {
ItemStack toSave = cursor.clone();
getLogger().info(
"[垃圾站] 存入: "
+ toSave.getType()
+ " x" + toSave.getAmount());
garbage.saveItem(toSave);
e.setCancelled(true);
Bukkit.getScheduler().runTaskLater(
this, () -> {
p.getOpenInventory()
.setCursor(null);
garbage.openRecyclePage(p,
garbage.getRecyclePage(
p.getName()));
}, 1L); }, 1L);
return; return;
} }
// 3. 其他情况 // 默认取消
e.setCancelled(true); e.setCancelled(true);
return; return;
} }
@@ -1806,6 +1864,7 @@ public class Main extends JavaPlugin
p.closeInventory(); p.closeInventory();
p.sendMessage("§e请输入邀请码:"); p.sendMessage("§e请输入邀请码:");
} }
return; return;
} }
@@ -1828,6 +1887,7 @@ public class Main extends JavaPlugin
.replace("§e", "") .replace("§e", "")
.replace("§a", "")); .replace("§a", ""));
} }
return; return;
} }
@@ -1856,6 +1916,17 @@ public class Main extends JavaPlugin
p.closeInventory(); p.closeInventory();
p.sendMessage("§e输入" + tgt p.sendMessage("§e输入" + tgt
+ "的临时密码:"); + "的临时密码:");
} else if (slot == 14) {
Player tp = Bukkit.getPlayer(tgt);
if (tp != null && tp.isOnline()) {
forceGiveMenuSnowball(tp);
p.sendMessage("§a已发放雪球菜单给 "
+ tgt);
} else {
p.sendMessage("§c玩家不在线");
}
} else if (slot == 16) { } else if (slot == 16) {
chatInput.getState(p).type = chatInput.getState(p).type =
ChatInputManager.InputType ChatInputManager.InputType
@@ -1866,9 +1937,12 @@ public class Main extends JavaPlugin
p.sendMessage(config.msg( p.sendMessage(config.msg(
"admin_delete_confirm")); "admin_delete_confirm"));
} }
return; return;
} }
// 积分商城 // 积分商城
if (title.startsWith("§d§l积分商城")) { if (title.startsWith("§d§l积分商城")) {
e.setCancelled(true); e.setCancelled(true);
@@ -1958,25 +2032,29 @@ public class Main extends JavaPlugin
// 回收站拖拽 // 回收站拖拽
if (t.equals("§6§l垃圾回收站")) { if (t.equals("§6§l垃圾回收站")) {
for (int rawSlot : e.getRawSlots()) { for (int rawSlot :
if (rawSlot >= 49 e.getRawSlots()) {
&& rawSlot <= 53) { if (rawSlot >= 49) {
e.setCancelled(true); e.setCancelled(true);
return; return;
} }
} }
// 0-48:不取消,延迟存DB // 0-48允许拖入,不取消
// 延迟2tick后扫描格子
final Player fp = p;
Bukkit.getScheduler() Bukkit.getScheduler()
.runTaskLater(this, () -> { .runTaskLater(this,
() -> {
Inventory top = fp
.getOpenInventory()
.getTopInventory();
for (int rawSlot : for (int rawSlot :
e.getRawSlots()) { e.getRawSlots()) {
if (rawSlot < 0 if (rawSlot < 0
|| rawSlot >= 49) || rawSlot >= 49)
continue; continue;
ItemStack item = ItemStack item =
e.getInventory() top.getItem(rawSlot);
.getItem(
rawSlot);
if (item != null if (item != null
&& item.getType() && item.getType()
!= Material.AIR != Material.AIR
@@ -1984,17 +2062,15 @@ public class Main extends JavaPlugin
item)) { item)) {
garbage.saveItem( garbage.saveItem(
item.clone()); item.clone());
e.getInventory() top.setItem(
.setItem( rawSlot, null);
rawSlot,
null);
} }
} }
}, 1L); }, 2L);
return; return;
} }
//服务商工单系统
if (t.equals(TicketManager.T_TICKET_MAIN) if (t.equals(TicketManager.T_TICKET_MAIN)
|| t.equals( || t.equals(
TicketManager.T_TICKET_CREATE) TicketManager.T_TICKET_CREATE)
@@ -2050,6 +2126,38 @@ public class Main extends JavaPlugin
+ count + " 个掉落物"); + count + " 个掉落物");
return true; return true;
} }
// /menu 开关雪球菜单
if (cmdName.equals("menu")) {
if (!(sender instanceof Player)) {
sender.sendMessage(
"§c仅玩家可用");
return true;
}
Player p2 = (Player) sender;
if (args.length == 0) {
p2.sendMessage(
"§e用法: /menu <开/关>");
return true;
}
String arg = args[0];
if (arg.equals("开")) {
db.setField(p2.getName(),
"menu_snowball", 1);
p2.sendMessage(
"§a雪球菜单已开启,"
+ "下次进入将发放");
} else if (arg.equals("关")) {
db.setField(p2.getName(),
"menu_snowball", 0);
p2.sendMessage(
"§c雪球菜单已关闭,"
+ "下次进入不再发放");
} else {
p2.sendMessage(
"§e用法: /menu <开/关>");
}
return true;
}
if (cmdName.equals("reg") if (cmdName.equals("reg")
|| cmdName.equals("注册")) { || cmdName.equals("注册")) {
@@ -2790,6 +2898,29 @@ public class Main extends JavaPlugin
} }
return true; return true;
} }
// give - 手动发放雪球菜单
if (sub.equals("give")) {
if (args.length < 2) {
sender.sendMessage(
"§e用法: /sdf1_login give <玩家名>");
return true;
}
Player tp = Bukkit.getPlayer(
args[1]);
if (tp == null || !tp.isOnline()) {
sender.sendMessage(
"§c玩家不在线: "
+ args[1]);
return true;
}
forceGiveMenuSnowball(tp);
tp.sendMessage(
"§a管理员已为您发放菜单雪球");
sender.sendMessage(
"§a已发放雪球菜单给 "
+ args[1]);
return true;
}
// shopadd // shopadd
if (sub.equals("shopadd")) { if (sub.equals("shopadd")) {
+4 -16
View File
@@ -1014,22 +1014,10 @@ public class TicketManager {
openDetail(p, id); openDetail(p, id);
return true; return true;
} }
// 管理员:标记完结(自己在处理) // 管理员:标记完结(已回复状态)
if (adm(p) && "processing".equals(st) if (adm(p) && "replied".equals(st)
&& asg.equals("admin")) { && asg.equals("admin")) {
Map<String, Object> tk =
plugin.getDb().getTicket(id);
String tkType = sv(tk, "type");
if (TYPE_DELETE.equals(tkType)) {
approveDeleteTicket(p, id);
return true;
}
plugin.getDb().completeTicket(id);
p.sendMessage("§a工单 #" + id
+ " 已标记完结");
openDetail(p, id);
return true;
}
// 管理员:标记完结(已回复状态) // 管理员:标记完结(已回复状态)
if (adm(p) && "replied".equals(st) if (adm(p) && "replied".equals(st)
&& asg.equals("admin")) { && asg.equals("admin")) {
@@ -1046,7 +1034,7 @@ public class TicketManager {
openDetail(p, id); openDetail(p, id);
return true; return true;
} }
}
// 服务商:抢单 // 服务商:抢单
if (plugin.getDb() if (plugin.getDb()
.isServiceProvider(p.getName()) .isServiceProvider(p.getName())
+3
View File
@@ -84,3 +84,6 @@ commands:
垃圾清理: 垃圾清理:
description: 手动清理掉落物 description: 手动清理掉落物
usage: /垃圾清理 usage: /垃圾清理
menu:
description: 雪球菜单开关控制
usage: /menu <开/关>