diff --git a/README.md b/README.md
index 6a15939..690a303 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
-# NoobTitle
+# NewbTitle
diff --git a/pom.xml b/pom.xml
index 394963b..9090c09 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,5 +71,10 @@
1.20.1-R0.1-SNAPSHOT
provided
+
+ org.postgresql
+ postgresql
+ 42.6.0
+
diff --git a/src/main/java/cn/lunadeer/newbtitle/Color.java b/src/main/java/cn/lunadeer/newbtitle/Color.java
new file mode 100644
index 0000000..e14717f
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/Color.java
@@ -0,0 +1,53 @@
+package cn.lunadeer.newbtitle;
+
+import cn.lunadeer.newbtitle.utils.XLogger;
+import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.TextColor;
+
+public class Color {
+ public Integer r;
+ public Integer g;
+ public Integer b;
+ public String hex;
+
+ public Color(Integer r, Integer g, Integer b) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.hex = String.format("#%02x%02x%02x", r, g, b);
+ }
+
+ public Color(String r, String g, String b) {
+ try {
+ this.r = Integer.valueOf(r);
+ this.g = Integer.valueOf(g);
+ this.b = Integer.valueOf(b);
+ this.hex = String.format("#%02x%02x%02x", this.r, this.g, this.b);
+ } catch (NumberFormatException e) {
+ this.r = 0;
+ this.g = 0;
+ this.b = 0;
+ this.hex = "#000000";
+ XLogger.err("Invalid color: " + r + ", " + g + ", " + b);
+ }
+ }
+
+ public Color(String hex) {
+ try {
+ this.hex = hex;
+ this.r = Integer.valueOf(hex.substring(1, 3), 16);
+ this.g = Integer.valueOf(hex.substring(3, 5), 16);
+ this.b = Integer.valueOf(hex.substring(5, 7), 16);
+ } catch (NumberFormatException e) {
+ this.r = 0;
+ this.g = 0;
+ this.b = 0;
+ this.hex = "#000000";
+ XLogger.err("Invalid color: " + hex);
+ }
+ }
+
+ public Style getStyle() {
+ return Style.style(TextColor.color(r, g, b));
+ }
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/Commands.java b/src/main/java/cn/lunadeer/newbtitle/Commands.java
new file mode 100644
index 0000000..deb2a37
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/Commands.java
@@ -0,0 +1,46 @@
+package cn.lunadeer.newbtitle;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class Commands implements TabExecutor {
+ /**
+ * Executes the given command, returning its success.
+ *
+ * If false is returned, then the "usage" plugin.yml entry for this command
+ * (if defined) will be sent to the player.
+ *
+ * @param sender Source of the command
+ * @param command Command which was executed
+ * @param label Alias of the command which was used
+ * @param args Passed command arguments
+ * @return true if a valid command, otherwise false
+ */
+ @Override
+ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ return false;
+ }
+
+ /**
+ * Requests a list of possible completions for a command argument.
+ *
+ * @param sender Source of the command. For players tab-completing a
+ * command inside a command block, this will be the player, not
+ * the command block.
+ * @param command Command which was executed
+ * @param label Alias of the command which was used
+ * @param args The arguments passed to the command, including final
+ * partial argument to be completed
+ * @return A List of possible completions for the final argument, or null
+ * to default to the command executor
+ */
+ @Override
+ public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ return null;
+ }
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/Events.java b/src/main/java/cn/lunadeer/newbtitle/Events.java
new file mode 100644
index 0000000..4de2d62
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/Events.java
@@ -0,0 +1,4 @@
+package cn.lunadeer.newbtitle;
+
+public class Events {
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java b/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java
index 9f0db79..d64acce 100644
--- a/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java
+++ b/src/main/java/cn/lunadeer/newbtitle/NewbTitle.java
@@ -1,6 +1,7 @@
package cn.lunadeer.newbtitle;
import cn.lunadeer.newbtitle.utils.ConfigManager;
+import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public final class NewbTitle extends JavaPlugin {
@@ -11,6 +12,7 @@ public final class NewbTitle extends JavaPlugin {
instance = this;
config = new ConfigManager(instance);
+
}
@Override
diff --git a/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java b/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java
new file mode 100644
index 0000000..dcac2fc
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/PlayerTitle.java
@@ -0,0 +1,28 @@
+package cn.lunadeer.newbtitle;
+
+public class PlayerTitle extends Title {
+ private Long _expire_at = -1L;
+
+ public PlayerTitle(Integer id, Long expire_at) {
+ super(id);
+ this._expire_at = expire_at;
+ }
+
+ public String getExpireAt() {
+ if (this._expire_at == -1L) {
+ return "永久";
+ } else if (this._expire_at < System.currentTimeMillis()) {
+ return "已过期";
+ } else {
+ return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(this._expire_at));
+ }
+ }
+
+ public Boolean isExpired() {
+ if (this._expire_at == -1L) {
+ return false;
+ } else {
+ return this._expire_at < System.currentTimeMillis();
+ }
+ }
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java b/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java
new file mode 100644
index 0000000..d3b598e
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/SaleTitle.java
@@ -0,0 +1,107 @@
+package cn.lunadeer.newbtitle;
+
+
+import cn.lunadeer.newbtitle.utils.Database;
+import cn.lunadeer.newbtitle.utils.XLogger;
+
+import java.sql.ResultSet;
+
+public class SaleTitle extends Title {
+ private final Integer _id;
+ private final Integer _title_id;
+ private Integer _price;
+ private Integer _days;
+ private Integer _amount;
+ private Long _sale_end_at;
+
+ public SaleTitle(Integer id, Integer title_id, Integer price, Integer days, Integer amount, Long sale_end_at) {
+ super(title_id);
+ this._id = id;
+ this._title_id = title_id;
+ this._price = price;
+ this._days = days;
+ this._amount = amount;
+ this._sale_end_at = sale_end_at;
+ }
+
+ public static SaleTitle create(Integer title_id) {
+ String sql = "";
+ sql += "INSERT INTO nt_title_shop (title_id, price, days, amount, sale_end_at) ";
+ sql += "VALUES (" + title_id + ", 0, 0, -1, CURRENT_TIMESTAMP) ";
+ sql += "RETURNING id;";
+ ResultSet rs = Database.query(sql);
+ try {
+ if (rs != null && rs.next()) {
+ Integer id = rs.getInt("id");
+ return new SaleTitle(id, title_id, 0, 0, -1, System.currentTimeMillis());
+ }
+ } catch (Exception e) {
+ XLogger.err("SaleTitle create failed: " + e.getMessage());
+ }
+ return null;
+ }
+
+ public Integer getPrice() {
+ return this._price;
+ }
+
+ public void setPrice(Integer price) {
+ this._price = price;
+ this.save();
+ }
+
+ public Integer getDays() {
+ return this._days;
+ }
+
+ public void setDays(Integer days) {
+ this._days = days;
+ this.save();
+ }
+
+ public Integer getAmount() {
+ return this._amount;
+ }
+
+ public void setAmount(Integer amount) {
+ this._amount = amount;
+ this.save();
+ }
+
+ public String getSaleEndAt() {
+ if (this._sale_end_at == -1L) {
+ return "常驻";
+ } else if (this._sale_end_at < System.currentTimeMillis()) {
+ return "已停售";
+ } else {
+ return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(this._sale_end_at));
+ }
+ }
+
+ public void setSaleEndAt(Long sale_end_at) {
+ this._sale_end_at = sale_end_at;
+ this.save();
+ }
+
+ public Boolean isSaleExpired() {
+ if (this._sale_end_at == -1L) {
+ return false;
+ } else {
+ return this._sale_end_at < System.currentTimeMillis();
+ }
+ }
+
+ private void save() {
+ String sql = "";
+ sql += "UPDATE nt_title_shop ";
+ sql += "SET title_id = " + this._title_id + ", ";
+ sql += "price = " + this._price + ", ";
+ sql += "days = " + this._days + ", ";
+ sql += "amount = " + this._amount + ", ";
+ sql += "sale_end_at = " + this._sale_end_at + ", ";
+ sql += "updated_at = CURRENT_TIMESTAMP ";
+ sql += "WHERE id = " + this._id + ";";
+
+ Database.query(sql);
+ }
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/Shop.java b/src/main/java/cn/lunadeer/newbtitle/Shop.java
new file mode 100644
index 0000000..1b35de8
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/Shop.java
@@ -0,0 +1,4 @@
+package cn.lunadeer.newbtitle;
+
+public class Shop {
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/Title.java b/src/main/java/cn/lunadeer/newbtitle/Title.java
new file mode 100644
index 0000000..b455dfe
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/Title.java
@@ -0,0 +1,129 @@
+package cn.lunadeer.newbtitle;
+
+import cn.lunadeer.newbtitle.utils.Database;
+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 java.sql.ResultSet;
+
+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 Title(String title, String description) {
+ this._title = title;
+ this._description = description;
+ this._enabled = true;
+ this.save();
+ }
+
+ 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 += "FROM nt_title ";
+ sql += "WHERE id = " + id + ";";
+ ResultSet rs = Database.query(sql);
+ try {
+ 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());
+ }
+ }
+
+ public static void delete(Integer id) {
+ String sql = "";
+ sql += "DELETE FROM nt_title WHERE id = " + id + ";";
+ Database.query(sql);
+ }
+
+ private void save() {
+ String sql = "";
+ if (this._id == null) {
+ sql += "INSERT INTO nt_title (title, description, enabled) VALUES (";
+ sql += "'" + this._title + "', ";
+ sql += "'" + this._description + "', ";
+ sql += this._enabled + " ";
+ sql += ");";
+ } else {
+ sql += "UPDATE nt_title SET ";
+ sql += "title = '" + this._title + "', ";
+ sql += "description = '" + this._description + "', ";
+ sql += "enabled = " + this._enabled + " ";
+ sql += "updated_at = CURRENT_TIMESTAMP ";
+ sql += "WHERE id = " + this._id + ";";
+ }
+ Database.query(sql);
+ }
+
+ public Integer getId() {
+ return this._id;
+ }
+
+ public Component getTitle() {
+ String[] parts = this._title.split("");
+ TextComponent[] components = new TextComponent[parts.length];
+ if (parts[0].length() > 0) {
+ 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);
+ return Component.join(join, components);
+ }
+
+ public void setTitle(String title) {
+ this._title = title;
+ this.save();
+ }
+
+ public String getDescription() {
+ return this._description;
+ }
+
+ public void setDescription(String description) {
+ this._description = description;
+ this.save();
+ }
+
+ public Boolean getEnabled() {
+ return this._enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ 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
new file mode 100644
index 0000000..5663e9f
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/XPlayer.java
@@ -0,0 +1,158 @@
+package cn.lunadeer.newbtitle;
+
+import cn.lunadeer.newbtitle.utils.Database;
+import cn.lunadeer.newbtitle.utils.Notification;
+import cn.lunadeer.newbtitle.utils.XLogger;
+import org.bukkit.entity.Player;
+
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class XPlayer {
+ private final Player _player;
+ private Integer _coin;
+ private final Map _titles;
+ private Integer _current_title_id = -1;
+
+ public XPlayer(Player player) {
+ _player = player;
+ _titles = getTitles(player.getUniqueId());
+ _current_title_id = getCurrentTitleId(player.getUniqueId());
+ _coin = getCoin(player.getUniqueId());
+ applyCurrentTitle();
+ }
+
+ public void updateUsingTitle(Integer title_id) {
+ _current_title_id = title_id;
+ applyCurrentTitle();
+ String sql = "";
+ sql += "UPDATE nt_player_using_title ";
+ sql += "SET title_id = " + title_id + ", ";
+ sql += "updated_at = CURRENT_TIMESTAMP ";
+ sql += "WHERE uuid = '" + _player.getUniqueId().toString() + "';";
+ Database.query(sql);
+ _current_title_id = title_id;
+ Notification.info(_player, "成功使用称号: " + _titles.get(title_id).getTitle());
+ }
+
+ private void applyCurrentTitle() {
+ if (_current_title_id == -1) {
+ return;
+ }
+ if (!_titles.containsKey(_current_title_id)) {
+ Notification.error(_player, "你没有这个称号");
+ _current_title_id = -1;
+ return;
+ }
+ PlayerTitle title = _titles.get(_current_title_id);
+ if (title.isExpired()) {
+ Notification.error(_player, "此称号已经过期");
+ _current_title_id = -1;
+ return;
+ }
+ _player.sendPlayerListHeader(title.getTitle());
+ }
+
+ public void set_coin(Integer coin) {
+ _coin = coin;
+ String sql = "";
+ sql += "UPDATE nt_player_coin ";
+ sql += "SET coin = " + coin + ", ";
+ sql += "updated_at = CURRENT_TIMESTAMP ";
+ sql += "WHERE uuid = '" + _player.getUniqueId().toString() + "';";
+ Database.query(sql);
+ }
+
+ public void add_coin(Integer coin) {
+ set_coin(_coin + coin);
+ }
+
+ private static Map getTitles(UUID uuid) {
+ String sql = "";
+ sql += "SELECT ";
+ sql += "title_id, expire_at ";
+ sql += "FROM nt_player_title ";
+ sql += "WHERE player_uuid = '" + uuid.toString() + "';";
+ ResultSet rs = Database.query(sql);
+ Map titles = new HashMap<>();
+ try {
+ while (rs != null && rs.next()) {
+ Integer title_id = rs.getInt("title_id");
+ Long expire_at = rs.getLong("expire_at");
+ PlayerTitle title = new PlayerTitle(title_id, expire_at);
+ titles.put(title_id, title);
+ }
+ } catch (Exception e) {
+ XLogger.err("XPlayer getTitles failed: " + e.getMessage());
+ }
+ return titles;
+ }
+
+ private static Integer getCurrentTitleId(UUID uuid) {
+ String sql = "";
+ 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 {
+ if (rs != null && rs.next()) {
+ current_title_id = rs.getInt("title_id");
+ } else {
+ current_title_id = -1;
+ sql = "";
+ sql += "INSERT INTO nt_player_using_title (uuid, title_id) VALUES (";
+ sql += "'" + uuid + "', ";
+ sql += current_title_id + ");";
+ Database.query(sql);
+ }
+ } catch (Exception e) {
+ XLogger.err("XPlayer getCurrentTitleId failed: " + e.getMessage());
+ }
+ return current_title_id;
+ }
+
+ private static Integer getCoin(UUID uuid) {
+ String sql = "";
+ sql += "SELECT coin ";
+ sql += "FROM nt_player_coin ";
+ sql += "WHERE uuid = '" + uuid.toString() + "';";
+ ResultSet rs = Database.query(sql);
+ Integer coin = null;
+ try {
+ if (rs != null && rs.next()) {
+ coin = rs.getInt("coin");
+ } else {
+ coin = 0;
+ sql = "";
+ sql += "INSERT INTO nt_player_coin (uuid, coin) VALUES (";
+ sql += "'" + uuid + "', ";
+ sql += coin + ");";
+ Database.query(sql);
+ }
+ } catch (Exception e) {
+ XLogger.err("XPlayer getCoin failed: " + e.getMessage());
+ }
+ return coin;
+ }
+
+ public void buyTitle(SaleTitle title) {
+ if (title.isSaleExpired()) {
+ Notification.error(_player, "此称号已停止销售");
+ return;
+ }
+ if (title.getAmount() != -1 && title.getAmount() <= 0) {
+ Notification.error(_player, "此称号已售罄");
+ return;
+ }
+ if (title.getPrice() > _coin) {
+ Notification.error(_player, "你的余额不足");
+ return;
+ }
+ // todo 校验是否已有此称号 以及是否已过期
+ // todo 如果已则续费 如果未则购买
+
+ }
+}
diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/ConfigManager.java b/src/main/java/cn/lunadeer/newbtitle/utils/ConfigManager.java
index 879264d..b457a1b 100644
--- a/src/main/java/cn/lunadeer/newbtitle/utils/ConfigManager.java
+++ b/src/main/java/cn/lunadeer/newbtitle/utils/ConfigManager.java
@@ -14,6 +14,13 @@ public class ConfigManager {
_plugin.reloadConfig();
_file = _plugin.getConfig();
_debug = _file.getBoolean("Debug", false);
+ _db_host = _file.getString("Database.Host", "localhost");
+ _db_port = _file.getString("Database.Port", "5432");
+ _db_name = _file.getString("Database.Name", "newbtitle");
+ _db_user = _file.getString("Database.User", "postgres");
+ _db_pass = _file.getString("Database.Pass", "postgres");
+ _prefix = _file.getString("Prefix", "[");
+ _suffix = _file.getString("Suffix", "]");
}
public Boolean isDebug() {
@@ -26,9 +33,76 @@ public class ConfigManager {
_plugin.saveConfig();
}
+ public String getDBConnectionUrl(){
+ return "jdbc:postgresql://" + _db_host + ":" + _db_port + "/" + _db_name;
+ }
+
+ public void setDbHost(String db_host) {
+ _db_host = db_host;
+ _file.set("Database.Host", db_host);
+ _plugin.saveConfig();
+ }
- private NewbTitle _plugin;
+ public void setDbPort(String db_port) {
+ _db_port = db_port;
+ _file.set("Database.Port", db_port);
+ _plugin.saveConfig();
+ }
+
+
+ public void setDbUser(String db_user) {
+ _db_user = db_user;
+ _file.set("Database.User", db_user);
+ _plugin.saveConfig();
+ }
+
+ public String getDbUser() {
+ if (_db_user.contains("@")) {
+ setDbUser("'" + _db_user + "'");
+ }
+ return _db_user;
+ }
+
+
+ public void setDbPass(String db_pass) {
+ _db_pass = db_pass;
+ _file.set("Database.Pass", db_pass);
+ _plugin.saveConfig();
+ }
+
+ public String getDbPass() {
+ if (_db_pass.contains("@")) {
+ setDbPass("'" + _db_pass + "'");
+ }
+ return _db_pass;
+ }
+
+
+ public void setDbName(String db_name) {
+ _db_name = db_name;
+ _file.set("Database.Name", db_name);
+ _plugin.saveConfig();
+ }
+
+ public String getPrefix() {
+ return _prefix;
+ }
+
+ public String getSuffix() {
+ return _suffix;
+ }
+
+
+ private final NewbTitle _plugin;
private FileConfiguration _file;
private Boolean _debug;
+
+ private String _db_host;
+ private String _db_port;
+ private String _db_user;
+ private String _db_pass;
+ private String _db_name;
+ private String _prefix;
+ private String _suffix;
}
diff --git a/src/main/java/cn/lunadeer/newbtitle/utils/Database.java b/src/main/java/cn/lunadeer/newbtitle/utils/Database.java
new file mode 100644
index 0000000..7fab7c4
--- /dev/null
+++ b/src/main/java/cn/lunadeer/newbtitle/utils/Database.java
@@ -0,0 +1,90 @@
+package cn.lunadeer.newbtitle.utils;
+
+import cn.lunadeer.newbtitle.NewbTitle;
+
+import java.sql.*;
+import java.util.Objects;
+
+public class Database {
+
+ private static Connection getConnection() {
+ try {
+ Class.forName("org.postgresql.Driver");
+ return DriverManager.getConnection(NewbTitle.config.getDBConnectionUrl(), NewbTitle.config.getDbUser(), NewbTitle.config.getDbPass());
+ } catch (ClassNotFoundException | SQLException e) {
+ XLogger.err("Database connection failed: " + e.getMessage());
+ return null;
+ }
+ }
+
+ public static ResultSet query(String sql) {
+ try {
+ Connection connection = getConnection();
+ Statement statement = Objects.requireNonNull(connection).createStatement();
+ ResultSet res = statement.executeQuery(sql);
+ statement.close();
+ connection.close();
+ return res;
+ } catch (SQLException e) {
+ XLogger.err("Database query failed: " + e.getMessage());
+ return null;
+ }
+ }
+
+ public static void migrate() {
+ String sql = "";
+
+ // title table
+ sql += "CREATE TABLE IF NOT EXISTS 'nt_title' (" +
+ " id SERIAL PRIMARY KEY," +
+ " title TEXT NOT NULL," +
+ " description TEXT NOT NULL," +
+ " enabled BOOLEAN NOT NULL DEFAULT TRUE," +
+ " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
+ " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" +
+ ");";
+
+ // title shop table
+ 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," +
+ " 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' (" +
+ " uuid UUID PRIMARY KEY," +
+ " coin INTEGER NOT NULL DEFAULT 0," +
+ " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
+ " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" +
+ ");";
+
+ // player title table
+ 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," +
+ " 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' (" +
+ " uuid UUID PRIMARY KEY," +
+ " title_id INTEGER NOT NULL," +
+ " 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" +
+ ");";
+
+ 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 6d2e95c..6327edb 100644
--- a/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java
+++ b/src/main/java/cn/lunadeer/newbtitle/utils/Notification.java
@@ -11,15 +11,14 @@ public class Notification {
private static final Style e_style = Style.style(TextColor.color(255, 96, 72));
public static void info(Player player, String msg) {
- player.sendMessage(Component.text("[LWE] " + msg, i_style));
+ player.sendMessage(Component.text("[NewbTitle] " + msg, i_style));
}
-
public static void warn(Player player, String msg) {
- player.sendMessage(Component.text("[LWE] " + msg, w_style));
+ player.sendMessage(Component.text("[NewbTitle] " + msg, w_style));
}
public static void error(Player player, String msg) {
- player.sendMessage(Component.text("[LWE] " + msg, e_style));
+ player.sendMessage(Component.text("[NewbTitle] " + msg, e_style));
}
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..9143437
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,11 @@
+Database:
+ Host: localhost
+ Port: 5432
+ Name: newbtitle
+ User: postgres
+ Pass: postgres
+
+Prefix: "["
+Suffix: "]"
+
+Debug: false
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 37fdd1e..e29c1a6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -2,3 +2,11 @@ name: NewbTitle
version: '${project.version}'
main: cn.lunadeer.newbtitle.NewbTitle
api-version: '1.20'
+description: 称号插件。
+website: https://lunadeer.cn
+folia-supported: true
+commands:
+ NewbTitle:
+ description: 称号插件命令
+ usage: /nt
+ aliases: [nt]