diff --git a/pom.xml b/pom.xml index 395d2f0..4ebe5ca 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer NewbTitle - 0.2-alpha + 0.34-alpha jar NewbTitle diff --git a/src/main/java/cn/lunadeer/newbtitle/Commands.java b/src/main/java/cn/lunadeer/newbtitle/Commands.java index 4a27619..bcb84aa 100644 --- a/src/main/java/cn/lunadeer/newbtitle/Commands.java +++ b/src/main/java/cn/lunadeer/newbtitle/Commands.java @@ -10,7 +10,10 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import static cn.lunadeer.newbtitle.commands.PlayerCommands.*; @@ -32,12 +35,7 @@ public class Commands implements TabExecutor { switch (label) { case "nt": if (args.length == 0) { - if (sender instanceof Player) { - Player player = (Player) sender; - Notification.warn(player, "用法: /nt "); - } else { - XLogger.info("用法: /nt "); - } + printHelp(sender); return true; } switch (args[0]) { @@ -67,17 +65,10 @@ public class Commands implements TabExecutor { return AdminCommands.setAmount(sender, args); case "setendat": return AdminCommands.setSaleEndAt(sender, args); + case "listall": + return AdminCommands.listAllTitle(sender, args); default: - if (sender instanceof Player) { - Player player = (Player) sender; - Notification.warn(player, "用法: /nt "); - if (player.isOp()){ - Notification.warn(player, "用法: /nt "); - } - } else { - XLogger.info("用法: /nt "); - XLogger.info("用法: /nt "); - } + printHelp(sender); return true; } default: @@ -85,6 +76,19 @@ public class Commands implements TabExecutor { } } + private void printHelp(@NotNull CommandSender sender) { + if (sender instanceof Player) { + Player player = (Player) sender; + Notification.warn(player, "用法: /nt "); + if (player.isOp()){ + Notification.warn(player, "用法: /nt "); + } + } else { + XLogger.info("用法: /nt "); + XLogger.info("用法: /nt "); + } + } + /** * Requests a list of possible completions for a command argument. * @@ -104,7 +108,7 @@ public class Commands implements TabExecutor { case "nt": if (args.length == 0) { String[] player_cmd = {"use", "list", "shop", "buy"}; - String[] admin_cmd = {"create", "delete", "setdesc", "setname", "addshop", "removeshop", "setprice", "setamount", "setendat"}; + String[] admin_cmd = {"create", "delete", "setdesc", "setname", "addshop", "removeshop", "setprice", "setamount", "setendat", "listall"}; List res = new ArrayList<>(); if (sender instanceof Player) { Player player = (Player) sender; @@ -124,7 +128,6 @@ public class Commands implements TabExecutor { case "use": return Collections.singletonList("要使用的称号ID"); case "list": - return Collections.singletonList("页数(可选)"); case "shop": return Collections.singletonList("页数(可选)"); case "buy": @@ -132,13 +135,12 @@ public class Commands implements TabExecutor { case "create": return Collections.singletonList("<称号名称> <称号描述>"); case "delete": + case "addshop": return Collections.singletonList("<称号ID>"); case "setdesc": return Collections.singletonList("<称号ID> <称号描述>"); case "setname": return Collections.singletonList("<称号ID> <称号名称>"); - case "addshop": - return Collections.singletonList("<称号ID>"); case "removeshop": return Collections.singletonList("<商品ID>"); case "setprice": diff --git a/src/main/java/cn/lunadeer/newbtitle/Events.java b/src/main/java/cn/lunadeer/newbtitle/Events.java index 67e7a38..8b2244d 100644 --- a/src/main/java/cn/lunadeer/newbtitle/Events.java +++ b/src/main/java/cn/lunadeer/newbtitle/Events.java @@ -1,6 +1,7 @@ package cn.lunadeer.newbtitle; -import org.bukkit.entity.Player; +import io.papermc.paper.event.player.AsyncChatEvent; +import net.kyori.adventure.text.Component; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -9,6 +10,31 @@ public class Events implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - new XPlayer(event.getPlayer()); + XPlayer player = new XPlayer(event.getPlayer()); + } + + @EventHandler + public void onPlayerSendChat(AsyncChatEvent event) { + XPlayer xPlayer = new XPlayer(event.getPlayer()); + PlayerTitle title = xPlayer.getTitle(); + Component nameComponent = event.getPlayer().displayName(); + Component chatComponent = event.message(); + if (title == null) { + Component newChatComponent = Component.text() + .append(Component.text("<")) + .append(nameComponent) + .append(Component.text("> ")) + .append(chatComponent).build(); + event.setCancelled(true); + event.getPlayer().getServer().sendMessage(newChatComponent); + } + Component titleComponent = title.getTitle(); + Component newChatComponent = Component.text().append(titleComponent) + .append(Component.text("<")) + .append(nameComponent) + .append(Component.text("> ")) + .append(chatComponent).build(); + event.setCancelled(true); + event.getPlayer().getServer().sendMessage(newChatComponent); } } diff --git a/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java b/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java index 4d17355..19a1762 100644 --- a/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java +++ b/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java @@ -4,7 +4,6 @@ import cn.lunadeer.newbtitle.utils.ConfigManager; import cn.lunadeer.newbtitle.utils.Database; import cn.lunadeer.newbtitle.utils.XLogger; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import java.util.Objects; diff --git a/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java b/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java index d2abac5..655684c 100644 --- a/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java +++ b/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java @@ -1,8 +1,8 @@ package cn.lunadeer.newbtitle; import cn.lunadeer.newbtitle.utils.Database; -import org.bukkit.entity.Player; +import java.sql.ResultSet; import java.util.UUID; public class PlayerTitle extends Title { @@ -20,8 +20,7 @@ public class PlayerTitle extends Title { sql += "INSERT INTO nt_player_title (title_id, player_uuid, expire_at) "; sql += "VALUES (" + title_id + ", '" + player_uuid.toString() + "', -1) "; sql += "RETURNING id;"; - java.sql.ResultSet rs = Database.query(sql); - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { return new PlayerTitle(title_id, player_uuid, -1L); } diff --git a/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java b/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java index eff9520..b4552e4 100644 --- a/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java +++ b/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java @@ -28,12 +28,10 @@ public class SaleTitle extends Title { sql += "INSERT INTO nt_title_shop (title_id, price, days, amount, sale_end_at) "; sql += "VALUES (" + title_id + ", 0, 0, 0, -1) "; sql += "RETURNING id;"; - ResultSet rs = Database.query(sql); - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { Integer id = rs.getInt("id"); - SaleTitle title = new SaleTitle(id, title_id, 0, 0, -1, System.currentTimeMillis()); - return title; + return new SaleTitle(id, title_id, 0, 0, -1, System.currentTimeMillis()); } } catch (Exception e) { XLogger.err("SaleTitle create failed: " + e.getMessage()); diff --git a/src/main/java/cn/lunadeer/newbtitle/Shop.java b/src/main/java/cn/lunadeer/newbtitle/Shop.java index ad2bf57..e8c520d 100644 --- a/src/main/java/cn/lunadeer/newbtitle/Shop.java +++ b/src/main/java/cn/lunadeer/newbtitle/Shop.java @@ -8,6 +8,7 @@ import cn.lunadeer.newbtitle.utils.XLogger; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.ClickEvent; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.sql.ResultSet; @@ -15,13 +16,20 @@ import java.util.HashMap; import java.util.Map; public class Shop { - public static void open(Player player, Integer page) { + public static void open(CommandSender sender, Integer page) { + Map titles = getSaleTitles(); + if (!(sender instanceof Player)) { + for (Integer title_sale_id : titles.keySet()) { + SaleTitle title = titles.get(title_sale_id); + XLogger.info("[" + title_sale_id + "] " + title.getTitle().toString() + " price:" + title.getPrice() + " days:" + title.getDays() + " amount:" + title.getAmount()); + } + return; + } + Player player = (Player) sender; Line header = Line.create(); header.set(Line.Slot.LEFT, "称号") .set(Line.Slot.MIDDLE, "价格|天|剩余") .set(Line.Slot.RIGHT, "操作"); - - Map titles = getSaleTitles(); int offset = (page - 1) * 4; if (offset >= titles.size() || offset < 0) { Notification.error(player, "页数超出范围"); @@ -39,13 +47,13 @@ public class Shop { SaleTitle title = titles.get(title_sale_id); Line line = Line.create(); TextComponent buy_button = Component.text("购买") - .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/nt shop buy " + title_sale_id)); + .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/nt buy " + title_sale_id)); line.set(Line.Slot.LEFT, idx.append(title.getTitle())) .set(Line.Slot.MIDDLE, title.getPrice() + "|" + (title.getDays() < 0 ? "∞" : title.getDays()) + "|" + (title.getAmount() < 0 ? "∞" : title.getAmount())) .set(Line.Slot.RIGHT, buy_button); - view.set(View.Slot.LINE_1, line); + view.set(i, line); } Line action_bar = Line.create(); TextComponent previous_button = Component.text("上一页") @@ -72,11 +80,10 @@ public class Shop { sql += "price, "; sql += "days, "; sql += "amount, "; - sql += "sale_end_at"; + sql += "sale_end_at "; sql += "FROM nt_title_shop;"; - ResultSet rs = Database.query(sql); Map titles = new HashMap<>(); - try { + try (ResultSet rs = Database.query(sql)) { while (rs != null && rs.next()) { Integer id = rs.getInt("id"); Integer title_id = rs.getInt("title_id"); @@ -101,11 +108,10 @@ public class Shop { sql += "price, "; sql += "days, "; sql += "amount, "; - sql += "sale_end_at"; + sql += "sale_end_at "; sql += "FROM nt_title_shop "; sql += "WHERE id = " + sale_id + ";"; - ResultSet rs = Database.query(sql); - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { Integer id = rs.getInt("id"); Integer title_id = rs.getInt("title_id"); diff --git a/src/main/java/cn/lunadeer/newbtitle/Title.java b/src/main/java/cn/lunadeer/newbtitle/Title.java index 1310be9..1cb96fb 100644 --- a/src/main/java/cn/lunadeer/newbtitle/Title.java +++ b/src/main/java/cn/lunadeer/newbtitle/Title.java @@ -1,22 +1,27 @@ package cn.lunadeer.newbtitle; import cn.lunadeer.newbtitle.utils.Database; +import cn.lunadeer.newbtitle.utils.Notification; +import cn.lunadeer.newbtitle.utils.STUI.Line; +import cn.lunadeer.newbtitle.utils.STUI.View; import cn.lunadeer.newbtitle.utils.XLogger; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.JoinConfiguration; import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; public class Title { protected Integer _id = null; protected String _title; protected String _description; protected Boolean _enabled; - protected String _created_at; - protected String _updated_at; JoinConfiguration join = JoinConfiguration.separator(Component.text(" ")); public static Title create(String title, String description) { @@ -26,10 +31,10 @@ public class Title { sql += "'" + description + "', "; sql += "true "; sql += ") RETURNING id;"; - ResultSet rs = Database.query(sql); - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { - return new Title(rs.getInt("id")); + int titleId = rs.getInt("id"); + return new Title(titleId); } } catch (Exception e) { XLogger.err("Title create failed: " + e.getMessage()); @@ -37,22 +42,75 @@ public class Title { return null; } + public static List all() { + List<Title> titles = new ArrayList<>(); + String sql = ""; + sql += "SELECT id FROM nt_title;"; + try (ResultSet rs = Database.query(sql)) { + if (rs != null) { + while (rs.next()) { + Integer id = rs.getInt("id"); + titles.add(new Title(id)); + } + } + } catch (Exception e) { + XLogger.err("Title all failed: " + e.getMessage()); + } + return titles; + } + + public static void listAllTitle(CommandSender sender, Integer page) { + List<Title> titles = all(); + if (!(sender instanceof Player)) { + for (Title title : titles) { + Notification.info(sender, title.getId() + " " + title.getTitle().toString()); + } + return; + } + Player player = (Player) sender; + Line header = Line.create(); + header.set(Line.Slot.LEFT, "ID") + .set(Line.Slot.MIDDLE, "称号"); + int offset = (page - 1) * 4; + if (offset >= titles.size() || offset < 0) { + Notification.error(player, "页数超出范围"); + return; + } + View view = View.create(); + view.title("|| 所有称号 ||") + .set(View.Slot.SUBTITLE, header); + for (int i = offset; i < offset + 4; i++) { + if (i >= titles.size()) { + break; + } + TextComponent idx = Component.text("[" + titles.get(i).getId() + "] "); + Line line = Line.create(); + line.set(Line.Slot.LEFT, idx) + .set(Line.Slot.MIDDLE, (TextComponent) titles.get(i).getTitle()); + view.set(i, line); + } + Line action_bar = Line.create(); + TextComponent previous_button = Component.text("上一页") + .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/nt all " + (page - 1))); + TextComponent next_button = Component.text("下一页") + .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/nt all " + (page + 1))); + action_bar.set(Line.Slot.MIDDLE, previous_button) + .set(Line.Slot.RIGHT, next_button); + view.set(View.Slot.ACTIONBAR, action_bar); + view.showOn(player); + } + public Title(Integer id) { this._id = id; String sql = ""; - sql += "SELECT id, title, description, enabled, "; - sql += "DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') AS created_at, "; - sql += "DATE_FORMAT(updated_at, '%Y-%m-%d %H:%i:%s') AS updated_at "; + sql += "SELECT id, title, description, enabled "; sql += "FROM nt_title "; sql += "WHERE id = " + id + ";"; - ResultSet rs = Database.query(sql); - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { this._title = rs.getString("title"); this._description = rs.getString("description"); this._enabled = rs.getBoolean("enabled"); - this._created_at = rs.getString("created_at"); - this._updated_at = rs.getString("updated_at"); } } catch (Exception e) { XLogger.err("Title load failed: " + e.getMessage()); @@ -89,22 +147,29 @@ public class Title { } public Component getTitle() { - String[] parts = this._title.split("&#"); - TextComponent[] components = new TextComponent[parts.length]; - if (!parts[0].isEmpty()) { - components[0] = Component.text(parts[0]); - } - for (int i = 1; i < parts.length; i++) { - String part = parts[i]; - String color_str = part.substring(0, 6); - String text = part.substring(6); - Color color = new Color(color_str); - components[i] = Component.text(text, color.getStyle()); - } TextComponent prefix = Component.text(NewbTitle.config.getPrefix()); TextComponent suffix = Component.text(NewbTitle.config.getSuffix()); - components[0] = prefix.append(components[0]); - components[parts.length - 1] = components[parts.length - 1].append(suffix); + String[] parts = this._title.split("&#"); + List<TextComponent> components = new ArrayList<>(); + components.add(prefix); + for (String part : parts) { + XLogger.debug(part); + if (part.isEmpty()) { + continue; + } + // match hex regx ^[0-9a-fA-F]{6}$ + Color color = new Color("#ffffff"); + String content; + if (part.length() > 6 && part.substring(0, 6).matches("^[0-9a-fA-F]{6}$")) { + String color_str = part.substring(0, 6); + color = new Color("#" + color_str); + content = part.substring(6); + } else { + content = part; + } + components.add(Component.text(content, color.getStyle())); + } + components.add(suffix); return Component.join(join, components).hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text(this._description))); } @@ -130,12 +195,4 @@ public class Title { this._enabled = enabled; this.save(); } - - public String getCreatedAt() { - return this._created_at; - } - - public String getUpdatedAt() { - return this._updated_at; - } } diff --git a/src/main/java/cn/lunadeer/newbtitle/XPlayer.java b/src/main/java/cn/lunadeer/newbtitle/XPlayer.java index 1e8418a..469c2ca 100644 --- a/src/main/java/cn/lunadeer/newbtitle/XPlayer.java +++ b/src/main/java/cn/lunadeer/newbtitle/XPlayer.java @@ -27,7 +27,14 @@ public class XPlayer { _titles = getTitles(player.getUniqueId()); _current_title_id = getCurrentTitleId(player.getUniqueId()); _coin = getCoin(player.getUniqueId()); - updateUsingTitle(_current_title_id); + checkTitleValid(); + } + + public PlayerTitle getTitle() { + if (_current_title_id == -1) { + return null; + } + return _titles.get(_current_title_id); } public void openBackpack(Integer page) { @@ -59,7 +66,7 @@ public class XPlayer { line.set(Line.Slot.LEFT, idx.append(title.getTitle())) .set(Line.Slot.MIDDLE, title.getExpireAt()) .set(Line.Slot.RIGHT, buy_button); - view.set(View.Slot.LINE_1, line); + view.set(i, line); } Line action_bar = Line.create(); TextComponent previous_button = Component.text("上一页") @@ -74,32 +81,35 @@ public class XPlayer { public void updateUsingTitle(Integer title_id) { _current_title_id = title_id; - applyCurrentTitle(); + checkTitleValid(); + if (_current_title_id == -1) { + return; + } String sql = ""; sql += "UPDATE nt_player_using_title "; sql += "SET title_id = " + _current_title_id + ", "; sql += "updated_at = CURRENT_TIMESTAMP "; sql += "WHERE uuid = '" + _player.getUniqueId().toString() + "';"; Database.query(sql); - Notification.info(_player, "成功使用称号: " + _titles.get(title_id).getTitle()); + Notification.info(_player, "成功使用称号: "); + Notification.info(_player, _titles.get(_current_title_id).getTitle()); } - private void applyCurrentTitle() { + private void checkTitleValid() { if (_current_title_id == -1) { return; } if (!_titles.containsKey(_current_title_id)) { - Notification.error(_player, "称号 " + _current_title_id + " 显示错误"); + Notification.error(_player, "称号 " + _current_title_id + " 不存在"); _current_title_id = -1; return; } PlayerTitle title = _titles.get(_current_title_id); if (title.isExpired()) { - Notification.error(_player, "称号 " + title.getTitle() + " 已过期"); + Notification.error(_player, "称号已过期"); + Notification.error(_player, title.getTitle()); _current_title_id = -1; - return; } - _player.sendPlayerListHeader(title.getTitle()); } public void set_coin(Integer coin) { @@ -122,9 +132,8 @@ public class XPlayer { sql += "title_id, expire_at "; sql += "FROM nt_player_title "; sql += "WHERE player_uuid = '" + uuid.toString() + "';"; - ResultSet rs = Database.query(sql); Map<Integer, PlayerTitle> titles = new HashMap<>(); - try { + try (ResultSet rs = Database.query(sql)) { while (rs != null && rs.next()) { Integer title_id = rs.getInt("title_id"); Long expire_at = rs.getLong("expire_at"); @@ -142,9 +151,8 @@ public class XPlayer { sql += "SELECT title_id "; sql += "FROM nt_player_using_title "; sql += "WHERE uuid = '" + uuid.toString() + "';"; - ResultSet rs = Database.query(sql); Integer current_title_id = null; - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { current_title_id = rs.getInt("title_id"); } else { @@ -166,9 +174,8 @@ public class XPlayer { sql += "SELECT coin "; sql += "FROM nt_player_coin "; sql += "WHERE uuid = '" + uuid.toString() + "';"; - ResultSet rs = Database.query(sql); Integer coin = null; - try { + try (ResultSet rs = Database.query(sql)) { if (rs != null && rs.next()) { coin = rs.getInt("coin"); } else { @@ -200,24 +207,27 @@ public class XPlayer { } if (!_titles.containsKey(title.getId())) { _titles.put(title.getId(), PlayerTitle.create(title.getId(), _player.getUniqueId())); - } - PlayerTitle title_bought = _titles.get(title.getId()); - if (title_bought.getExpireAtTimestamp() == -1) { + } else if (_titles.get(title.getId()).getExpireAtTimestamp() == -1) { Notification.warn(_player, "你已经拥有此称号"); return; } + PlayerTitle title_bought = _titles.get(title.getId()); set_coin(_coin - title.getPrice()); - Notification.info(_player, "成功购买称号: " + title.getTitle()); + SaleTitle.setAmount(title.getId(), title.getAmount() - 1); + Notification.info(_player, "成功购买称号: "); + Notification.info(_player, title.getTitle()); if (title.getDays() == -1) { title_bought.setExpireAtTimestamp(-1L); return; } if (title_bought.isExpired()) { title_bought.setExpireAtTimestamp(System.currentTimeMillis() + title.getDays() * 24 * 60 * 60 * 1000L); - Notification.info(_player, "称号 " + title.getTitle() + " 已重新激活,有效期至 " + title_bought.getExpireAt()); + Notification.info(_player, title.getTitle()); + Notification.info(_player, "称号已重新激活,有效期至 " + title_bought.getExpireAt()); } else { title_bought.setExpireAtTimestamp(title_bought.getExpireAtTimestamp() + title.getDays() * 24 * 60 * 60 * 1000L); - Notification.info(_player, "称号 " + title.getTitle() + " 已续期至 " + title_bought.getExpireAt()); + Notification.info(_player, title.getTitle()); + Notification.info(_player, "称号已续期至 " + title_bought.getExpireAt()); } } @@ -227,6 +237,7 @@ public class XPlayer { } PlayerTitle title = _titles.get(title_id); title.setExpireAtTimestamp(expire_at); - Notification.info(_player, "获得称号: " + title.getTitle() + ",有效期至 " + title.getExpireAt()); + Notification.info(_player, title.getTitle()); + Notification.info(_player, "获得称号,有效期至 " + title.getExpireAt()); } } diff --git a/src/main/java/cn/lunadeer/newbtitle/commands/AdminCommands.java b/src/main/java/cn/lunadeer/newbtitle/commands/AdminCommands.java index f354208..b8c23a7 100644 --- a/src/main/java/cn/lunadeer/newbtitle/commands/AdminCommands.java +++ b/src/main/java/cn/lunadeer/newbtitle/commands/AdminCommands.java @@ -1,12 +1,11 @@ package cn.lunadeer.newbtitle.commands; import cn.lunadeer.newbtitle.SaleTitle; -import cn.lunadeer.newbtitle.Shop; import cn.lunadeer.newbtitle.Title; -import org.bukkit.entity.Player; import cn.lunadeer.newbtitle.utils.Notification; import cn.lunadeer.newbtitle.utils.XLogger; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; public class AdminCommands { public static boolean createTitle(CommandSender sender, String[] args) { @@ -17,11 +16,11 @@ public class AdminCommands { return true; } } - if (args.length != 2) { + if (args.length != 3) { Notification.warn(sender, "用法: /nt create <称号名称> <称号描述>"); return true; } - Title.create(args[0], args[1]); + Title.create(args[1], args[2]); return true; } @@ -33,11 +32,32 @@ public class AdminCommands { return true; } } - if (args.length != 1) { + if (args.length != 2) { Notification.warn(sender, "用法: /nt delete <称号ID>"); return true; } - Title.delete(Integer.parseInt(args[0])); + Title.delete(Integer.parseInt(args[1])); + return true; + } + + public static boolean listAllTitle(CommandSender sender, String[] args) { + if (sender instanceof Player) { + Player player = (Player) sender; + if (!player.isOp()) { + XLogger.warn(player, "你没有权限执行该命令"); + return true; + } + } + int page = 1; + if (args.length == 2) { + try { + page = Integer.parseInt(args[1]); + } catch (Exception e) { + Notification.error(sender, "页数格式错误"); + return true; + } + } + Title.listAllTitle(sender, page); return true; } @@ -49,12 +69,12 @@ public class AdminCommands { return true; } } - if (args.length != 2) { + if (args.length != 3) { Notification.warn(sender, "用法: /nt setdesc <称号ID> <称号描述>"); return true; } - Title title = new Title(Integer.parseInt(args[0])); - title.setDescription(args[1]); + Title title = new Title(Integer.parseInt(args[1])); + title.setDescription(args[2]); return true; } @@ -66,12 +86,12 @@ public class AdminCommands { return true; } } - if (args.length != 2) { + if (args.length != 3) { Notification.warn(sender, "用法: /nt setname <称号ID> <称号名称>"); return true; } - Title title = new Title(Integer.parseInt(args[0])); - title.setTitle(args[1]); + Title title = new Title(Integer.parseInt(args[1])); + title.setTitle(args[2]); return true; } @@ -87,11 +107,12 @@ public class AdminCommands { Notification.warn(sender, "用法: /nt addshop <称号ID>"); return true; } - SaleTitle title = SaleTitle.create(Integer.parseInt(args[0])); + SaleTitle title = SaleTitle.create(Integer.parseInt(args[1])); if (title == null) { Notification.error(sender, "添加商品失败"); } else { - Notification.info(sender, "已添加称号 " + title.getTitle() + " 到商店, 商品ID: " + title.getId()); + Notification.info(sender, "已添加称号到商店, 商品ID: " + title.getId()); + Notification.info(sender, title.getTitle()); } return true; } @@ -104,11 +125,11 @@ public class AdminCommands { return true; } } - if (args.length != 1) { + if (args.length != 2) { Notification.warn(sender, "用法: /nt removeshop <商品ID>"); return true; } - SaleTitle.delete(Integer.parseInt(args[0])); + SaleTitle.delete(Integer.parseInt(args[1])); return true; } @@ -124,8 +145,8 @@ public class AdminCommands { Notification.warn(sender, "用法: /nt setprice <商品ID> <价格> <天数>(-1为永久)"); return true; } - SaleTitle.setPrice(Integer.parseInt(args[0]), Integer.parseInt(args[1])); - SaleTitle.setDays(Integer.parseInt(args[0]), Integer.parseInt(args[2])); + SaleTitle.setPrice(Integer.parseInt(args[1]), Integer.parseInt(args[2])); + SaleTitle.setDays(Integer.parseInt(args[1]), Integer.parseInt(args[3])); return true; } @@ -137,11 +158,11 @@ public class AdminCommands { return true; } } - if (args.length != 2) { + if (args.length != 3) { Notification.warn(sender, "用法: /nt setamount <商品ID> <数量>(-1为无限)"); return true; } - SaleTitle.setAmount(Integer.parseInt(args[0]), Integer.parseInt(args[1])); + SaleTitle.setAmount(Integer.parseInt(args[1]), Integer.parseInt(args[2])); return true; } @@ -153,11 +174,25 @@ public class AdminCommands { return true; } } - if (args.length != 2) { - Notification.warn(sender, "用法: /nt setendat <商品ID> <时间戳>(-1为永久)"); + if (args.length != 3) { + Notification.warn(sender, "用法: /nt setendat <商品ID> <时间YYYYMMDD>(-1为永久)"); return true; } - SaleTitle.setSaleEndAt(Integer.parseInt(args[0]), Long.parseLong(args[1])); + long time_stamp; + if (Integer.parseInt(args[2]) == -1) { + time_stamp = -1; + } else { + // 字符串转时间戳 + java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyyMMdd"); + try { + java.util.Date date = simpleDateFormat.parse(args[2]); + time_stamp = date.getTime(); + } catch (Exception e) { + Notification.error(sender, "时间格式错误"); + return true; + } + } + SaleTitle.setSaleEndAt(Integer.parseInt(args[1]), time_stamp); return true; } } diff --git a/src/main/java/cn/lunadeer/newbtitle/commands/PlayerCommands.java b/src/main/java/cn/lunadeer/newbtitle/commands/PlayerCommands.java index a2a7d1e..10e2617 100644 --- a/src/main/java/cn/lunadeer/newbtitle/commands/PlayerCommands.java +++ b/src/main/java/cn/lunadeer/newbtitle/commands/PlayerCommands.java @@ -14,13 +14,13 @@ public class PlayerCommands { return true; } org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; - if (args.length == 0) { + if (args.length != 2) { Notification.warn(player, "用法: /nt use <称号ID>"); return true; } XPlayer xPlayer = new XPlayer(player); - Integer title_id = Integer.parseInt(args[0]); + Integer title_id = Integer.parseInt(args[1]); xPlayer.updateUsingTitle(title_id); return true; } @@ -32,11 +32,11 @@ public class PlayerCommands { } org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; int page = 1; - if (args.length != 0) { + if (args.length == 2) { try { - page = Integer.parseInt(args[0]); + page = Integer.parseInt(args[1]); } catch (Exception e) { - Notification.warn(player, "用法: /nt list <页数>"); + Notification.error(player, "页数格式错误"); return true; } } @@ -46,21 +46,14 @@ public class PlayerCommands { } public static boolean shop(CommandSender sender, String[] args) { - if (!(sender instanceof org.bukkit.entity.Player)) { - XLogger.warn("该命令只能由玩家执行"); - return true; - } - org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; int page = 1; - if (args.length != 0) { + if (args.length == 2) { try { - page = Integer.parseInt(args[0]); - } catch (Exception e) { - Notification.warn(player, "用法: /nt shop <页数>"); - return true; + page = Integer.parseInt(args[1]); + } catch (Exception ignored) { } } - Shop.open(player, page); + Shop.open(sender, page); return true; } @@ -70,12 +63,12 @@ public class PlayerCommands { return true; } org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; - if (args.length == 0) { + if (args.length != 2) { Notification.warn(player, "用法: /nt buy <称号ID>"); return true; } XPlayer xPlayer = new XPlayer(player); - Integer sale_id = Integer.parseInt(args[0]); + Integer sale_id = Integer.parseInt(args[1]); SaleTitle saleTitle = Shop.getSaleTitle(sale_id); if (saleTitle == null) { Notification.error(player, "该称号不存在"); diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/Database.java b/src/main/java/cn/lunadeer/newbtitle/utils/Database.java index 7fab7c4..590f048 100644 --- a/src/main/java/cn/lunadeer/newbtitle/utils/Database.java +++ b/src/main/java/cn/lunadeer/newbtitle/utils/Database.java @@ -3,7 +3,6 @@ package cn.lunadeer.newbtitle.utils; import cn.lunadeer.newbtitle.NewbTitle; import java.sql.*; -import java.util.Objects; public class Database { @@ -18,15 +17,16 @@ public class Database { } public static ResultSet query(String sql) { + Connection conn = getConnection(); + if (conn == null) { + return null; + } try { - Connection connection = getConnection(); - Statement statement = Objects.requireNonNull(connection).createStatement(); - ResultSet res = statement.executeQuery(sql); - statement.close(); - connection.close(); - return res; + Statement stmt = conn.createStatement(); + return stmt.executeQuery(sql); } catch (SQLException e) { XLogger.err("Database query failed: " + e.getMessage()); + XLogger.err("SQL: " + sql); return null; } } @@ -35,7 +35,7 @@ public class Database { String sql = ""; // title table - sql += "CREATE TABLE IF NOT EXISTS 'nt_title' (" + + sql += "CREATE TABLE IF NOT EXISTS nt_title (" + " id SERIAL PRIMARY KEY," + " title TEXT NOT NULL," + " description TEXT NOT NULL," + @@ -45,20 +45,20 @@ public class Database { ");"; // title shop table - sql += "CREATE TABLE IF NOT EXISTS 'nt_title_shop' (" + + sql += "CREATE TABLE IF NOT EXISTS nt_title_shop (" + " id SERIAL PRIMARY KEY," + " title_id INTEGER NOT NULL," + " price INTEGER NOT NULL DEFAULT 0," + " days INTEGER NOT NULL DEFAULT 0," + " amount INTEGER NOT NULL DEFAULT -1," + - " sale_end_at TIMESTAMP," + + " sale_end_at BIGINT NOT NULL DEFAULT -1," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " FOREIGN KEY (title_id) REFERENCES nt_title(id) ON DELETE CASCADE" + ");"; // player coin table - sql += "CREATE TABLE IF NOT EXISTS 'nt_player_coin' (" + + sql += "CREATE TABLE IF NOT EXISTS nt_player_coin (" + " uuid UUID PRIMARY KEY," + " coin INTEGER NOT NULL DEFAULT 0," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + @@ -66,18 +66,18 @@ public class Database { ");"; // player title table - sql += "CREATE TABLE IF NOT EXISTS 'nt_player_title' (" + + sql += "CREATE TABLE IF NOT EXISTS nt_player_title (" + " id SERIAL PRIMARY KEY," + " player_uuid UUID NOT NULL," + " title_id INTEGER NOT NULL," + - " expire_at TIMESTAMP," + + " expire_at BIGINT NOT NULL DEFAULT -1," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " FOREIGN KEY (title_id) REFERENCES nt_title(id) ON DELETE CASCADE" + ");"; // player using title table - sql += "CREATE TABLE IF NOT EXISTS 'nt_player_using_title' (" + + sql += "CREATE TABLE IF NOT EXISTS nt_player_using_title (" + " uuid UUID PRIMARY KEY," + " title_id INTEGER NOT NULL," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + @@ -85,6 +85,23 @@ public class Database { " FOREIGN KEY (title_id) REFERENCES nt_title(id) ON DELETE CASCADE" + ");"; + sql += "INSERT INTO nt_title (" + + "id, " + + "title, " + + "description," + + "enabled, " + + "created_at, " + + "updated_at " + + ") VALUES (" + + "-1, " + + "'default', " + + "'default', " + + "TRUE, " + + "CURRENT_TIMESTAMP, " + + "CURRENT_TIMESTAMP " + + ") ON CONFLICT (id) DO NOTHING;"; + + query(sql); } } diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java b/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java index 7abcbfe..5b18bdb 100644 --- a/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java +++ b/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java @@ -34,4 +34,28 @@ public class Notification { public static void error(CommandSender sender, String msg) { sender.sendMessage(Component.text("[NewbTitle] " + msg, e_style)); } + + public static void info(Player player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] ", i_style).append(msg)); + } + + public static void warn(Player player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] " + msg, w_style).append(msg)); + } + + public static void error(Player player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] " + msg, e_style).append(msg)); + } + + public static void info(CommandSender player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] ", i_style).append(msg)); + } + + public static void warn(CommandSender player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] " + msg, w_style).append(msg)); + } + + public static void error(CommandSender player, Component msg) { + player.sendMessage(Component.text("[NewbTitle] " + msg, e_style).append(msg)); + } } diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/STUI/Line.java b/src/main/java/cn/lunadeer/newbtitle/utils/STUI/Line.java index 3f50aec..9980d12 100644 --- a/src/main/java/cn/lunadeer/newbtitle/utils/STUI/Line.java +++ b/src/main/java/cn/lunadeer/newbtitle/utils/STUI/Line.java @@ -16,9 +16,9 @@ public class Line { public Line() { - this.left_elements = Component.text().build(); - this.middle_elements = Component.text().build(); - this.right_elements = Component.text().build(); + this.left_elements = Component.text(" "); + this.middle_elements = Component.text(" "); + this.right_elements = Component.text(" "); } public TextComponent build() { diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/STUI/View.java b/src/main/java/cn/lunadeer/newbtitle/utils/STUI/View.java index 3085c99..bcb8499 100644 --- a/src/main/java/cn/lunadeer/newbtitle/utils/STUI/View.java +++ b/src/main/java/cn/lunadeer/newbtitle/utils/STUI/View.java @@ -14,35 +14,35 @@ public class View { ACTIONBAR } - protected TextComponent title; - protected TextComponent subtitle; - protected TextComponent content_line1; - protected TextComponent content_line2; - protected TextComponent content_line3; - protected TextComponent content_line4; - protected TextComponent actionbar; + protected TextComponent title = Component.text(" "); + protected TextComponent subtitle = Component.text(" "); + protected TextComponent content_line1 = Component.text(" "); + protected TextComponent content_line2 = Component.text(" "); + protected TextComponent content_line3 = Component.text(" "); + protected TextComponent content_line4 = Component.text(" "); + protected TextComponent actionbar = Component.text(" "); - public void showOn(Player player){ + public void showOn(Player player) { player.sendMessage(title); player.sendMessage(subtitle); player.sendMessage(content_line1); player.sendMessage(content_line2); player.sendMessage(content_line3); player.sendMessage(content_line4); - player.sendActionBar(actionbar); + player.sendMessage(actionbar); } - public static View create(){ + public static View create() { return new View(); } - public View title(String title){ + public View title(String title) { this.title = Component.text(title); return this; } - public View set(Slot line, TextComponent component){ - switch (line){ + public View set(Slot line, TextComponent component) { + switch (line) { case SUBTITLE: this.subtitle = component; break; @@ -65,8 +65,8 @@ public class View { return this; } - public View set(Slot line, String component){ - switch (line){ + public View set(Slot line, String component) { + switch (line) { case SUBTITLE: this.subtitle = Component.text(component); break; @@ -89,8 +89,23 @@ public class View { return this; } - public View set(Slot line, Line component){ - switch (line){ + public View set(int index, Line component) { + if (index % 4 == 0) { + this.set(View.Slot.LINE_1, component); + } else if (index % 4 == 1) { + this.set(View.Slot.LINE_2, component); + } else if (index % 4 == 2) { + this.set(View.Slot.LINE_3, component); + } else if (index % 4 == 3) { + this.set(View.Slot.LINE_4, component); + } else { + throw new IllegalArgumentException("index must be 0-3"); + } + return this; + } + + public View set(Slot line, Line component) { + switch (line) { case SUBTITLE: this.subtitle = component.build(); break;