实现了基本的用户侧功能

tui需要优化
This commit is contained in:
zhangyuheng 2024-01-08 17:28:25 +08:00
parent 1260557973
commit f38cac39ff
15 changed files with 357 additions and 175 deletions

View File

@ -6,7 +6,7 @@
<groupId>cn.lunadeer</groupId> <groupId>cn.lunadeer</groupId>
<artifactId>NewbTitle</artifactId> <artifactId>NewbTitle</artifactId>
<version>0.2-alpha</version> <version>0.34-alpha</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>NewbTitle</name> <name>NewbTitle</name>

View File

@ -10,7 +10,10 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.*; import static cn.lunadeer.newbtitle.commands.PlayerCommands.*;
@ -32,12 +35,7 @@ public class Commands implements TabExecutor {
switch (label) { switch (label) {
case "nt": case "nt":
if (args.length == 0) { if (args.length == 0) {
if (sender instanceof Player) { printHelp(sender);
Player player = (Player) sender;
Notification.warn(player, "用法: /nt <use|list|shop|buy>");
} else {
XLogger.info("用法: /nt <use|list|shop|buy>");
}
return true; return true;
} }
switch (args[0]) { switch (args[0]) {
@ -67,17 +65,10 @@ public class Commands implements TabExecutor {
return AdminCommands.setAmount(sender, args); return AdminCommands.setAmount(sender, args);
case "setendat": case "setendat":
return AdminCommands.setSaleEndAt(sender, args); return AdminCommands.setSaleEndAt(sender, args);
case "listall":
return AdminCommands.listAllTitle(sender, args);
default: default:
if (sender instanceof Player) { printHelp(sender);
Player player = (Player) sender;
Notification.warn(player, "用法: /nt <use|list|shop|buy>");
if (player.isOp()){
Notification.warn(player, "用法: /nt <create|delete|setdesc|setname|addshop|removeshop|setprice|setamount|setendat>");
}
} else {
XLogger.info("用法: /nt <use|list|shop|buy>");
XLogger.info("用法: /nt <create|delete|setdesc|setname|addshop|removeshop|setprice|setamount|setendat>");
}
return true; return true;
} }
default: 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 <use|list|shop|buy>");
if (player.isOp()){
Notification.warn(player, "用法: /nt <create|delete|setdesc|setname|addshop|removeshop|setprice|setamount|setendat|listall>");
}
} else {
XLogger.info("用法: /nt <use|list|shop|buy>");
XLogger.info("用法: /nt <create|delete|setdesc|setname|addshop|removeshop|setprice|setamount|setendat|listall>");
}
}
/** /**
* Requests a list of possible completions for a command argument. * Requests a list of possible completions for a command argument.
* *
@ -104,7 +108,7 @@ public class Commands implements TabExecutor {
case "nt": case "nt":
if (args.length == 0) { if (args.length == 0) {
String[] player_cmd = {"use", "list", "shop", "buy"}; 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<String> res = new ArrayList<>(); List<String> res = new ArrayList<>();
if (sender instanceof Player) { if (sender instanceof Player) {
Player player = (Player) sender; Player player = (Player) sender;
@ -124,7 +128,6 @@ public class Commands implements TabExecutor {
case "use": case "use":
return Collections.singletonList("要使用的称号ID"); return Collections.singletonList("要使用的称号ID");
case "list": case "list":
return Collections.singletonList("页数(可选)");
case "shop": case "shop":
return Collections.singletonList("页数(可选)"); return Collections.singletonList("页数(可选)");
case "buy": case "buy":
@ -132,13 +135,12 @@ public class Commands implements TabExecutor {
case "create": case "create":
return Collections.singletonList("<称号名称> <称号描述>"); return Collections.singletonList("<称号名称> <称号描述>");
case "delete": case "delete":
case "addshop":
return Collections.singletonList("<称号ID>"); return Collections.singletonList("<称号ID>");
case "setdesc": case "setdesc":
return Collections.singletonList("<称号ID> <称号描述>"); return Collections.singletonList("<称号ID> <称号描述>");
case "setname": case "setname":
return Collections.singletonList("<称号ID> <称号名称>"); return Collections.singletonList("<称号ID> <称号名称>");
case "addshop":
return Collections.singletonList("<称号ID>");
case "removeshop": case "removeshop":
return Collections.singletonList("<商品ID>"); return Collections.singletonList("<商品ID>");
case "setprice": case "setprice":

View File

@ -1,6 +1,7 @@
package cn.lunadeer.newbtitle; 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.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
@ -9,6 +10,31 @@ public class Events implements Listener {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { 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);
} }
} }

View File

@ -4,7 +4,6 @@ import cn.lunadeer.newbtitle.utils.ConfigManager;
import cn.lunadeer.newbtitle.utils.Database; import cn.lunadeer.newbtitle.utils.Database;
import cn.lunadeer.newbtitle.utils.XLogger; import cn.lunadeer.newbtitle.utils.XLogger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.Objects; import java.util.Objects;

View File

@ -1,8 +1,8 @@
package cn.lunadeer.newbtitle; package cn.lunadeer.newbtitle;
import cn.lunadeer.newbtitle.utils.Database; import cn.lunadeer.newbtitle.utils.Database;
import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.util.UUID; import java.util.UUID;
public class PlayerTitle extends Title { 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 += "INSERT INTO nt_player_title (title_id, player_uuid, expire_at) ";
sql += "VALUES (" + title_id + ", '" + player_uuid.toString() + "', -1) "; sql += "VALUES (" + title_id + ", '" + player_uuid.toString() + "', -1) ";
sql += "RETURNING id;"; sql += "RETURNING id;";
java.sql.ResultSet rs = Database.query(sql); try (ResultSet rs = Database.query(sql)) {
try {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
return new PlayerTitle(title_id, player_uuid, -1L); return new PlayerTitle(title_id, player_uuid, -1L);
} }

View File

@ -28,12 +28,10 @@ public class SaleTitle extends Title {
sql += "INSERT INTO nt_title_shop (title_id, price, days, amount, sale_end_at) "; sql += "INSERT INTO nt_title_shop (title_id, price, days, amount, sale_end_at) ";
sql += "VALUES (" + title_id + ", 0, 0, 0, -1) "; sql += "VALUES (" + title_id + ", 0, 0, 0, -1) ";
sql += "RETURNING id;"; sql += "RETURNING id;";
ResultSet rs = Database.query(sql); try (ResultSet rs = Database.query(sql)) {
try {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
Integer id = rs.getInt("id"); Integer id = rs.getInt("id");
SaleTitle title = new SaleTitle(id, title_id, 0, 0, -1, System.currentTimeMillis()); return new SaleTitle(id, title_id, 0, 0, -1, System.currentTimeMillis());
return title;
} }
} catch (Exception e) { } catch (Exception e) {
XLogger.err("SaleTitle create failed: " + e.getMessage()); XLogger.err("SaleTitle create failed: " + e.getMessage());

View File

@ -8,6 +8,7 @@ import cn.lunadeer.newbtitle.utils.XLogger;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -15,13 +16,20 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Shop { public class Shop {
public static void open(Player player, Integer page) { public static void open(CommandSender sender, Integer page) {
Map<Integer, SaleTitle> 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(); Line header = Line.create();
header.set(Line.Slot.LEFT, "称号") header.set(Line.Slot.LEFT, "称号")
.set(Line.Slot.MIDDLE, "价格|天|剩余") .set(Line.Slot.MIDDLE, "价格|天|剩余")
.set(Line.Slot.RIGHT, "操作"); .set(Line.Slot.RIGHT, "操作");
Map<Integer, SaleTitle> titles = getSaleTitles();
int offset = (page - 1) * 4; int offset = (page - 1) * 4;
if (offset >= titles.size() || offset < 0) { if (offset >= titles.size() || offset < 0) {
Notification.error(player, "页数超出范围"); Notification.error(player, "页数超出范围");
@ -39,13 +47,13 @@ public class Shop {
SaleTitle title = titles.get(title_sale_id); SaleTitle title = titles.get(title_sale_id);
Line line = Line.create(); Line line = Line.create();
TextComponent buy_button = Component.text("购买") 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())) line.set(Line.Slot.LEFT, idx.append(title.getTitle()))
.set(Line.Slot.MIDDLE, title.getPrice() + "" + .set(Line.Slot.MIDDLE, title.getPrice() + "" +
(title.getDays() < 0 ? "" : title.getDays()) + "" + (title.getDays() < 0 ? "" : title.getDays()) + "" +
(title.getAmount() < 0 ? "" : title.getAmount())) (title.getAmount() < 0 ? "" : title.getAmount()))
.set(Line.Slot.RIGHT, buy_button); .set(Line.Slot.RIGHT, buy_button);
view.set(View.Slot.LINE_1, line); view.set(i, line);
} }
Line action_bar = Line.create(); Line action_bar = Line.create();
TextComponent previous_button = Component.text("上一页") TextComponent previous_button = Component.text("上一页")
@ -74,9 +82,8 @@ public class Shop {
sql += "amount, "; sql += "amount, ";
sql += "sale_end_at "; sql += "sale_end_at ";
sql += "FROM nt_title_shop;"; sql += "FROM nt_title_shop;";
ResultSet rs = Database.query(sql);
Map<Integer, SaleTitle> titles = new HashMap<>(); Map<Integer, SaleTitle> titles = new HashMap<>();
try { try (ResultSet rs = Database.query(sql)) {
while (rs != null && rs.next()) { while (rs != null && rs.next()) {
Integer id = rs.getInt("id"); Integer id = rs.getInt("id");
Integer title_id = rs.getInt("title_id"); Integer title_id = rs.getInt("title_id");
@ -104,8 +111,7 @@ public class Shop {
sql += "sale_end_at "; sql += "sale_end_at ";
sql += "FROM nt_title_shop "; sql += "FROM nt_title_shop ";
sql += "WHERE id = " + sale_id + ";"; sql += "WHERE id = " + sale_id + ";";
ResultSet rs = Database.query(sql); try (ResultSet rs = Database.query(sql)) {
try {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
Integer id = rs.getInt("id"); Integer id = rs.getInt("id");
Integer title_id = rs.getInt("title_id"); Integer title_id = rs.getInt("title_id");

View File

@ -1,22 +1,27 @@
package cn.lunadeer.newbtitle; package cn.lunadeer.newbtitle;
import cn.lunadeer.newbtitle.utils.Database; 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 cn.lunadeer.newbtitle.utils.XLogger;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.JoinConfiguration; import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class Title { public class Title {
protected Integer _id = null; protected Integer _id = null;
protected String _title; protected String _title;
protected String _description; protected String _description;
protected Boolean _enabled; protected Boolean _enabled;
protected String _created_at;
protected String _updated_at;
JoinConfiguration join = JoinConfiguration.separator(Component.text(" ")); JoinConfiguration join = JoinConfiguration.separator(Component.text(" "));
public static Title create(String title, String description) { public static Title create(String title, String description) {
@ -26,10 +31,10 @@ public class Title {
sql += "'" + description + "', "; sql += "'" + description + "', ";
sql += "true "; sql += "true ";
sql += ") RETURNING id;"; sql += ") RETURNING id;";
ResultSet rs = Database.query(sql); try (ResultSet rs = Database.query(sql)) {
try {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
return new Title(rs.getInt("id")); int titleId = rs.getInt("id");
return new Title(titleId);
} }
} catch (Exception e) { } catch (Exception e) {
XLogger.err("Title create failed: " + e.getMessage()); XLogger.err("Title create failed: " + e.getMessage());
@ -37,22 +42,75 @@ public class Title {
return null; return null;
} }
public static List<Title> 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) { public Title(Integer id) {
this._id = id; this._id = id;
String sql = ""; String sql = "";
sql += "SELECT id, title, description, enabled, "; 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 += "FROM nt_title "; sql += "FROM nt_title ";
sql += "WHERE id = " + id + ";"; sql += "WHERE id = " + id + ";";
ResultSet rs = Database.query(sql); try (ResultSet rs = Database.query(sql)) {
try {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
this._title = rs.getString("title"); this._title = rs.getString("title");
this._description = rs.getString("description"); this._description = rs.getString("description");
this._enabled = rs.getBoolean("enabled"); this._enabled = rs.getBoolean("enabled");
this._created_at = rs.getString("created_at");
this._updated_at = rs.getString("updated_at");
} }
} catch (Exception e) { } catch (Exception e) {
XLogger.err("Title load failed: " + e.getMessage()); XLogger.err("Title load failed: " + e.getMessage());
@ -89,22 +147,29 @@ public class Title {
} }
public Component getTitle() { 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 prefix = Component.text(NewbTitle.config.getPrefix());
TextComponent suffix = Component.text(NewbTitle.config.getSuffix()); TextComponent suffix = Component.text(NewbTitle.config.getSuffix());
components[0] = prefix.append(components[0]); String[] parts = this._title.split("&#");
components[parts.length - 1] = components[parts.length - 1].append(suffix); 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))); 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._enabled = enabled;
this.save(); this.save();
} }
public String getCreatedAt() {
return this._created_at;
}
public String getUpdatedAt() {
return this._updated_at;
}
} }

View File

@ -27,7 +27,14 @@ public class XPlayer {
_titles = getTitles(player.getUniqueId()); _titles = getTitles(player.getUniqueId());
_current_title_id = getCurrentTitleId(player.getUniqueId()); _current_title_id = getCurrentTitleId(player.getUniqueId());
_coin = getCoin(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) { public void openBackpack(Integer page) {
@ -59,7 +66,7 @@ public class XPlayer {
line.set(Line.Slot.LEFT, idx.append(title.getTitle())) line.set(Line.Slot.LEFT, idx.append(title.getTitle()))
.set(Line.Slot.MIDDLE, title.getExpireAt()) .set(Line.Slot.MIDDLE, title.getExpireAt())
.set(Line.Slot.RIGHT, buy_button); .set(Line.Slot.RIGHT, buy_button);
view.set(View.Slot.LINE_1, line); view.set(i, line);
} }
Line action_bar = Line.create(); Line action_bar = Line.create();
TextComponent previous_button = Component.text("上一页") TextComponent previous_button = Component.text("上一页")
@ -74,32 +81,35 @@ public class XPlayer {
public void updateUsingTitle(Integer title_id) { public void updateUsingTitle(Integer title_id) {
_current_title_id = title_id; _current_title_id = title_id;
applyCurrentTitle(); checkTitleValid();
if (_current_title_id == -1) {
return;
}
String sql = ""; String sql = "";
sql += "UPDATE nt_player_using_title "; sql += "UPDATE nt_player_using_title ";
sql += "SET title_id = " + _current_title_id + ", "; sql += "SET title_id = " + _current_title_id + ", ";
sql += "updated_at = CURRENT_TIMESTAMP "; sql += "updated_at = CURRENT_TIMESTAMP ";
sql += "WHERE uuid = '" + _player.getUniqueId().toString() + "';"; sql += "WHERE uuid = '" + _player.getUniqueId().toString() + "';";
Database.query(sql); 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) { if (_current_title_id == -1) {
return; return;
} }
if (!_titles.containsKey(_current_title_id)) { if (!_titles.containsKey(_current_title_id)) {
Notification.error(_player, "称号 " + _current_title_id + " 显示错误"); Notification.error(_player, "称号 " + _current_title_id + " 不存在");
_current_title_id = -1; _current_title_id = -1;
return; return;
} }
PlayerTitle title = _titles.get(_current_title_id); PlayerTitle title = _titles.get(_current_title_id);
if (title.isExpired()) { if (title.isExpired()) {
Notification.error(_player, "称号 " + title.getTitle() + " 已过期"); Notification.error(_player, "称号已过期");
Notification.error(_player, title.getTitle());
_current_title_id = -1; _current_title_id = -1;
return;
} }
_player.sendPlayerListHeader(title.getTitle());
} }
public void set_coin(Integer coin) { public void set_coin(Integer coin) {
@ -122,9 +132,8 @@ public class XPlayer {
sql += "title_id, expire_at "; sql += "title_id, expire_at ";
sql += "FROM nt_player_title "; sql += "FROM nt_player_title ";
sql += "WHERE player_uuid = '" + uuid.toString() + "';"; sql += "WHERE player_uuid = '" + uuid.toString() + "';";
ResultSet rs = Database.query(sql);
Map<Integer, PlayerTitle> titles = new HashMap<>(); Map<Integer, PlayerTitle> titles = new HashMap<>();
try { try (ResultSet rs = Database.query(sql)) {
while (rs != null && rs.next()) { while (rs != null && rs.next()) {
Integer title_id = rs.getInt("title_id"); Integer title_id = rs.getInt("title_id");
Long expire_at = rs.getLong("expire_at"); Long expire_at = rs.getLong("expire_at");
@ -142,9 +151,8 @@ public class XPlayer {
sql += "SELECT title_id "; sql += "SELECT title_id ";
sql += "FROM nt_player_using_title "; sql += "FROM nt_player_using_title ";
sql += "WHERE uuid = '" + uuid.toString() + "';"; sql += "WHERE uuid = '" + uuid.toString() + "';";
ResultSet rs = Database.query(sql);
Integer current_title_id = null; Integer current_title_id = null;
try { try (ResultSet rs = Database.query(sql)) {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
current_title_id = rs.getInt("title_id"); current_title_id = rs.getInt("title_id");
} else { } else {
@ -166,9 +174,8 @@ public class XPlayer {
sql += "SELECT coin "; sql += "SELECT coin ";
sql += "FROM nt_player_coin "; sql += "FROM nt_player_coin ";
sql += "WHERE uuid = '" + uuid.toString() + "';"; sql += "WHERE uuid = '" + uuid.toString() + "';";
ResultSet rs = Database.query(sql);
Integer coin = null; Integer coin = null;
try { try (ResultSet rs = Database.query(sql)) {
if (rs != null && rs.next()) { if (rs != null && rs.next()) {
coin = rs.getInt("coin"); coin = rs.getInt("coin");
} else { } else {
@ -200,24 +207,27 @@ public class XPlayer {
} }
if (!_titles.containsKey(title.getId())) { if (!_titles.containsKey(title.getId())) {
_titles.put(title.getId(), PlayerTitle.create(title.getId(), _player.getUniqueId())); _titles.put(title.getId(), PlayerTitle.create(title.getId(), _player.getUniqueId()));
} } else if (_titles.get(title.getId()).getExpireAtTimestamp() == -1) {
PlayerTitle title_bought = _titles.get(title.getId());
if (title_bought.getExpireAtTimestamp() == -1) {
Notification.warn(_player, "你已经拥有此称号"); Notification.warn(_player, "你已经拥有此称号");
return; return;
} }
PlayerTitle title_bought = _titles.get(title.getId());
set_coin(_coin - title.getPrice()); 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) { if (title.getDays() == -1) {
title_bought.setExpireAtTimestamp(-1L); title_bought.setExpireAtTimestamp(-1L);
return; return;
} }
if (title_bought.isExpired()) { if (title_bought.isExpired()) {
title_bought.setExpireAtTimestamp(System.currentTimeMillis() + title.getDays() * 24 * 60 * 60 * 1000L); 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 { } else {
title_bought.setExpireAtTimestamp(title_bought.getExpireAtTimestamp() + title.getDays() * 24 * 60 * 60 * 1000L); 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); PlayerTitle title = _titles.get(title_id);
title.setExpireAtTimestamp(expire_at); title.setExpireAtTimestamp(expire_at);
Notification.info(_player, "获得称号: " + title.getTitle() + ",有效期至 " + title.getExpireAt()); Notification.info(_player, title.getTitle());
Notification.info(_player, "获得称号,有效期至 " + title.getExpireAt());
} }
} }

View File

@ -1,12 +1,11 @@
package cn.lunadeer.newbtitle.commands; package cn.lunadeer.newbtitle.commands;
import cn.lunadeer.newbtitle.SaleTitle; import cn.lunadeer.newbtitle.SaleTitle;
import cn.lunadeer.newbtitle.Shop;
import cn.lunadeer.newbtitle.Title; import cn.lunadeer.newbtitle.Title;
import org.bukkit.entity.Player;
import cn.lunadeer.newbtitle.utils.Notification; import cn.lunadeer.newbtitle.utils.Notification;
import cn.lunadeer.newbtitle.utils.XLogger; import cn.lunadeer.newbtitle.utils.XLogger;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class AdminCommands { public class AdminCommands {
public static boolean createTitle(CommandSender sender, String[] args) { public static boolean createTitle(CommandSender sender, String[] args) {
@ -17,11 +16,11 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 2) { if (args.length != 3) {
Notification.warn(sender, "用法: /nt create <称号名称> <称号描述>"); Notification.warn(sender, "用法: /nt create <称号名称> <称号描述>");
return true; return true;
} }
Title.create(args[0], args[1]); Title.create(args[1], args[2]);
return true; return true;
} }
@ -33,11 +32,32 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 1) { if (args.length != 2) {
Notification.warn(sender, "用法: /nt delete <称号ID>"); Notification.warn(sender, "用法: /nt delete <称号ID>");
return true; 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; return true;
} }
@ -49,12 +69,12 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 2) { if (args.length != 3) {
Notification.warn(sender, "用法: /nt setdesc <称号ID> <称号描述>"); Notification.warn(sender, "用法: /nt setdesc <称号ID> <称号描述>");
return true; return true;
} }
Title title = new Title(Integer.parseInt(args[0])); Title title = new Title(Integer.parseInt(args[1]));
title.setDescription(args[1]); title.setDescription(args[2]);
return true; return true;
} }
@ -66,12 +86,12 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 2) { if (args.length != 3) {
Notification.warn(sender, "用法: /nt setname <称号ID> <称号名称>"); Notification.warn(sender, "用法: /nt setname <称号ID> <称号名称>");
return true; return true;
} }
Title title = new Title(Integer.parseInt(args[0])); Title title = new Title(Integer.parseInt(args[1]));
title.setTitle(args[1]); title.setTitle(args[2]);
return true; return true;
} }
@ -87,11 +107,12 @@ public class AdminCommands {
Notification.warn(sender, "用法: /nt addshop <称号ID>"); Notification.warn(sender, "用法: /nt addshop <称号ID>");
return true; return true;
} }
SaleTitle title = SaleTitle.create(Integer.parseInt(args[0])); SaleTitle title = SaleTitle.create(Integer.parseInt(args[1]));
if (title == null) { if (title == null) {
Notification.error(sender, "添加商品失败"); Notification.error(sender, "添加商品失败");
} else { } else {
Notification.info(sender, "已添加称号 " + title.getTitle() + " 到商店, 商品ID: " + title.getId()); Notification.info(sender, "已添加称号到商店, 商品ID: " + title.getId());
Notification.info(sender, title.getTitle());
} }
return true; return true;
} }
@ -104,11 +125,11 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 1) { if (args.length != 2) {
Notification.warn(sender, "用法: /nt removeshop <商品ID>"); Notification.warn(sender, "用法: /nt removeshop <商品ID>");
return true; return true;
} }
SaleTitle.delete(Integer.parseInt(args[0])); SaleTitle.delete(Integer.parseInt(args[1]));
return true; return true;
} }
@ -124,8 +145,8 @@ public class AdminCommands {
Notification.warn(sender, "用法: /nt setprice <商品ID> <价格> <天数>(-1为永久)"); Notification.warn(sender, "用法: /nt setprice <商品ID> <价格> <天数>(-1为永久)");
return true; return true;
} }
SaleTitle.setPrice(Integer.parseInt(args[0]), Integer.parseInt(args[1])); SaleTitle.setPrice(Integer.parseInt(args[1]), Integer.parseInt(args[2]));
SaleTitle.setDays(Integer.parseInt(args[0]), Integer.parseInt(args[2])); SaleTitle.setDays(Integer.parseInt(args[1]), Integer.parseInt(args[3]));
return true; return true;
} }
@ -137,11 +158,11 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 2) { if (args.length != 3) {
Notification.warn(sender, "用法: /nt setamount <商品ID> <数量>(-1为无限)"); Notification.warn(sender, "用法: /nt setamount <商品ID> <数量>(-1为无限)");
return true; return true;
} }
SaleTitle.setAmount(Integer.parseInt(args[0]), Integer.parseInt(args[1])); SaleTitle.setAmount(Integer.parseInt(args[1]), Integer.parseInt(args[2]));
return true; return true;
} }
@ -153,11 +174,25 @@ public class AdminCommands {
return true; return true;
} }
} }
if (args.length != 2) { if (args.length != 3) {
Notification.warn(sender, "用法: /nt setendat <商品ID> <时间>(-1为永久)"); Notification.warn(sender, "用法: /nt setendat <商品ID> <时间YYYYMMDD>(-1为永久)");
return true; 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; return true;
} }
} }

View File

@ -14,13 +14,13 @@ public class PlayerCommands {
return true; return true;
} }
org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender;
if (args.length == 0) { if (args.length != 2) {
Notification.warn(player, "用法: /nt use <称号ID>"); Notification.warn(player, "用法: /nt use <称号ID>");
return true; return true;
} }
XPlayer xPlayer = new XPlayer(player); XPlayer xPlayer = new XPlayer(player);
Integer title_id = Integer.parseInt(args[0]); Integer title_id = Integer.parseInt(args[1]);
xPlayer.updateUsingTitle(title_id); xPlayer.updateUsingTitle(title_id);
return true; return true;
} }
@ -32,11 +32,11 @@ public class PlayerCommands {
} }
org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender;
int page = 1; int page = 1;
if (args.length != 0) { if (args.length == 2) {
try { try {
page = Integer.parseInt(args[0]); page = Integer.parseInt(args[1]);
} catch (Exception e) { } catch (Exception e) {
Notification.warn(player, "用法: /nt list <页数>"); Notification.error(player, "页数格式错误");
return true; return true;
} }
} }
@ -46,21 +46,14 @@ public class PlayerCommands {
} }
public static boolean shop(CommandSender sender, String[] args) { 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; int page = 1;
if (args.length != 0) { if (args.length == 2) {
try { try {
page = Integer.parseInt(args[0]); page = Integer.parseInt(args[1]);
} catch (Exception e) { } catch (Exception ignored) {
Notification.warn(player, "用法: /nt shop <页数>");
return true;
} }
} }
Shop.open(player, page); Shop.open(sender, page);
return true; return true;
} }
@ -70,12 +63,12 @@ public class PlayerCommands {
return true; return true;
} }
org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender; org.bukkit.entity.Player player = (org.bukkit.entity.Player) sender;
if (args.length == 0) { if (args.length != 2) {
Notification.warn(player, "用法: /nt buy <称号ID>"); Notification.warn(player, "用法: /nt buy <称号ID>");
return true; return true;
} }
XPlayer xPlayer = new XPlayer(player); 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); SaleTitle saleTitle = Shop.getSaleTitle(sale_id);
if (saleTitle == null) { if (saleTitle == null) {
Notification.error(player, "该称号不存在"); Notification.error(player, "该称号不存在");

View File

@ -3,7 +3,6 @@ package cn.lunadeer.newbtitle.utils;
import cn.lunadeer.newbtitle.NewbTitle; import cn.lunadeer.newbtitle.NewbTitle;
import java.sql.*; import java.sql.*;
import java.util.Objects;
public class Database { public class Database {
@ -18,15 +17,16 @@ public class Database {
} }
public static ResultSet query(String sql) { public static ResultSet query(String sql) {
Connection conn = getConnection();
if (conn == null) {
return null;
}
try { try {
Connection connection = getConnection(); Statement stmt = conn.createStatement();
Statement statement = Objects.requireNonNull(connection).createStatement(); return stmt.executeQuery(sql);
ResultSet res = statement.executeQuery(sql);
statement.close();
connection.close();
return res;
} catch (SQLException e) { } catch (SQLException e) {
XLogger.err("Database query failed: " + e.getMessage()); XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);
return null; return null;
} }
} }
@ -35,7 +35,7 @@ public class Database {
String sql = ""; String sql = "";
// title table // title table
sql += "CREATE TABLE IF NOT EXISTS 'nt_title' (" + sql += "CREATE TABLE IF NOT EXISTS nt_title (" +
" id SERIAL PRIMARY KEY," + " id SERIAL PRIMARY KEY," +
" title TEXT NOT NULL," + " title TEXT NOT NULL," +
" description TEXT NOT NULL," + " description TEXT NOT NULL," +
@ -45,20 +45,20 @@ public class Database {
");"; ");";
// title shop table // 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," + " id SERIAL PRIMARY KEY," +
" title_id INTEGER NOT NULL," + " title_id INTEGER NOT NULL," +
" price INTEGER NOT NULL DEFAULT 0," + " price INTEGER NOT NULL DEFAULT 0," +
" days INTEGER NOT NULL DEFAULT 0," + " days INTEGER NOT NULL DEFAULT 0," +
" amount INTEGER NOT NULL DEFAULT -1," + " 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," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" updated_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" + " FOREIGN KEY (title_id) REFERENCES nt_title(id) ON DELETE CASCADE" +
");"; ");";
// player coin table // 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," + " uuid UUID PRIMARY KEY," +
" coin INTEGER NOT NULL DEFAULT 0," + " coin INTEGER NOT NULL DEFAULT 0," +
" created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
@ -66,18 +66,18 @@ public class Database {
");"; ");";
// player title table // 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," + " id SERIAL PRIMARY KEY," +
" player_uuid UUID NOT NULL," + " player_uuid UUID NOT NULL," +
" title_id INTEGER 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," + " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" updated_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" + " FOREIGN KEY (title_id) REFERENCES nt_title(id) ON DELETE CASCADE" +
");"; ");";
// player using title table // 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," + " uuid UUID PRIMARY KEY," +
" title_id INTEGER NOT NULL," + " title_id INTEGER NOT NULL," +
" created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + " 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" + " 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); query(sql);
} }
} }

View File

@ -34,4 +34,28 @@ public class Notification {
public static void error(CommandSender sender, String msg) { public static void error(CommandSender sender, String msg) {
sender.sendMessage(Component.text("[NewbTitle] " + msg, e_style)); 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));
}
} }

View File

@ -16,9 +16,9 @@ public class Line {
public Line() { public Line() {
this.left_elements = Component.text().build(); this.left_elements = Component.text(" ");
this.middle_elements = Component.text().build(); this.middle_elements = Component.text(" ");
this.right_elements = Component.text().build(); this.right_elements = Component.text(" ");
} }
public TextComponent build() { public TextComponent build() {

View File

@ -14,13 +14,13 @@ public class View {
ACTIONBAR ACTIONBAR
} }
protected TextComponent title; protected TextComponent title = Component.text(" ");
protected TextComponent subtitle; protected TextComponent subtitle = Component.text(" ");
protected TextComponent content_line1; protected TextComponent content_line1 = Component.text(" ");
protected TextComponent content_line2; protected TextComponent content_line2 = Component.text(" ");
protected TextComponent content_line3; protected TextComponent content_line3 = Component.text(" ");
protected TextComponent content_line4; protected TextComponent content_line4 = Component.text(" ");
protected TextComponent actionbar; protected TextComponent actionbar = Component.text(" ");
public void showOn(Player player) { public void showOn(Player player) {
player.sendMessage(title); player.sendMessage(title);
@ -29,7 +29,7 @@ public class View {
player.sendMessage(content_line2); player.sendMessage(content_line2);
player.sendMessage(content_line3); player.sendMessage(content_line3);
player.sendMessage(content_line4); player.sendMessage(content_line4);
player.sendActionBar(actionbar); player.sendMessage(actionbar);
} }
public static View create() { public static View create() {
@ -89,6 +89,21 @@ public class View {
return this; return this;
} }
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) { public View set(Slot line, Line component) {
switch (line) { switch (line) {
case SUBTITLE: case SUBTITLE: