From 49cff4d32d32308e769b0eb2a037d28d0f4de598 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Sun, 4 Feb 2024 17:54:17 +0800 Subject: [PATCH] init --- .gitea/workflows/build.yml | 42 +++++ .github/workflows/main.yml | 43 +++++ .gitignore | 113 ++++++++++++ pom.xml | 80 +++++++++ .../java/cn/lunadeer/dominion/Dominion.java | 40 +++++ .../cn/lunadeer/dominion/dtos/DPlayer.java | 132 ++++++++++++++ .../dominion/utils/ConfigManager.java | 77 ++++++++ .../cn/lunadeer/dominion/utils/Database.java | 164 ++++++++++++++++++ .../lunadeer/dominion/utils/Notification.java | 63 +++++++ .../lunadeer/dominion/utils/STUI/Button.java | 12 ++ .../cn/lunadeer/dominion/utils/STUI/Line.java | 48 +++++ .../dominion/utils/STUI/ListView.java | 71 ++++++++ .../dominion/utils/STUI/Pagination.java | 38 ++++ .../cn/lunadeer/dominion/utils/STUI/View.java | 106 +++++++++++ .../dominion/utils/STUI/ViewStyles.java | 11 ++ .../cn/lunadeer/dominion/utils/XLogger.java | 56 ++++++ src/main/resources/plugin.yml | 6 + 17 files changed, 1102 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/cn/lunadeer/dominion/Dominion.java create mode 100644 src/main/java/cn/lunadeer/dominion/dtos/DPlayer.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/ConfigManager.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/Database.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/Notification.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/Button.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/Line.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/ListView.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/Pagination.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/View.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/STUI/ViewStyles.java create mode 100644 src/main/java/cn/lunadeer/dominion/utils/XLogger.java create mode 100644 src/main/resources/plugin.yml diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..70aaafc --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,42 @@ +name: Java CI-CD with Maven + +on: + push: + tags: + - '*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: "Pull & Checkout" + uses: https://ssl.lunadeer.cn:14446/actions/checkout@v3 + with: + fetch-depth: 0 + - name: "Set up Maven" + uses: https://ssl.lunadeer.cn:14446/actions/setup-maven@v4 + - name: "Set up JDK 17" + uses: https://ssl.lunadeer.cn:14446/actions/setup-java@v3 + with: + java-version: '17' + distribution: 'zulu' + cache: maven + - name: "Build with Maven" + run: mvn -B package --file pom.xml + - name: "Copy jar to staging" + run: mkdir staging && cp target/*.jar staging + - name: "Build & test" + run: | + echo "done!" + - name: "setup go for release script" + run: | + wget --no-check-certificate https://go.dev/dl/go1.21.6.linux-amd64.tar.gz + rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz + ln -s /usr/local/go/bin/go /usr/bin/go + go version + - name: "Release" + uses: https://ssl.lunadeer.cn:14446/actions/release-action@main + with: + files: |- + staging/*.jar + api_key: '${{secrets.RELEASE_TOKEN}}' \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..fdea07c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,43 @@ +name: Java CI-CD with Maven + +on: + push: + tags: + - '*' + +jobs: + build: +# 配置权限 + permissions: write-all + runs-on: ubuntu-latest + steps: +# 下载代码 + - uses: actions/checkout@v3 + - name: Set up JDK 17 +# 安装 JDK + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven +# Maven 打包 + - name: Build with Maven + run: mvn -B package --file pom.xml +# 将打包好的 Jar 包 放到 staging 文件夹 + - run: mkdir staging && cp target/*.jar staging +# 设置 jobs Maven pom 版本环境变量 + - name: Set Release version env variable + run: | + echo "RELEASE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV + - name: "Build & test" + run: | + echo "done!" +# 上传文件并发布 Release + - uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "${{ env.RELEASE_VERSION }}" + prerelease: false + title: "Release ${{ env.RELEASE_VERSION }}" + files: | + staging/*.jar diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4e3a5f3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + cn.lunadeer + Dominion + 1.0 + jar + + Dominion + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + + + + dev.folia + folia-api + 1.20.1-R0.1-SNAPSHOT + provided + + + org.postgresql + postgresql + 42.6.0 + + + diff --git a/src/main/java/cn/lunadeer/dominion/Dominion.java b/src/main/java/cn/lunadeer/dominion/Dominion.java new file mode 100644 index 0000000..5dc8ed6 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/Dominion.java @@ -0,0 +1,40 @@ +package cn.lunadeer.dominion; + +import cn.lunadeer.dominion.utils.ConfigManager; +import cn.lunadeer.dominion.utils.Database; +import cn.lunadeer.dominion.utils.XLogger; +import org.bukkit.plugin.java.JavaPlugin; + +import java.sql.Connection; + +public final class Dominion extends JavaPlugin { + + @Override + public void onEnable() { + // Plugin startup logic + instance = this; + config = new ConfigManager(this); + dbConnection = Database.createConnection(); + + + XLogger.info("领地插件已启动"); + XLogger.info("版本:" + this.getPluginMeta().getVersion()); + // http://patorjk.com/software/taag/#p=display&f=Big&t=Dominion + XLogger.info(" _____ _ _"); + XLogger.info(" | __ \\ (_) (_)"); + XLogger.info(" | | | | ___ _ __ ___ _ _ __ _ ___ _ __"); + XLogger.info(" | | | |/ _ \\| '_ ` _ \\| | '_ \\| |/ _ \\| '_ \\"); + XLogger.info(" | |__| | (_) | | | | | | | | | | | (_) | | | |"); + XLogger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|"); + XLogger.info(" "); + } + + @Override + public void onDisable() { + // Plugin shutdown logic + } + + public static Dominion instance; + public static ConfigManager config; + public static Connection dbConnection; +} diff --git a/src/main/java/cn/lunadeer/dominion/dtos/DPlayer.java b/src/main/java/cn/lunadeer/dominion/dtos/DPlayer.java new file mode 100644 index 0000000..f70e201 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/dtos/DPlayer.java @@ -0,0 +1,132 @@ +package cn.lunadeer.dominion.dtos; + +import cn.lunadeer.dominion.utils.Database; +import cn.lunadeer.dominion.utils.Notification; +import cn.lunadeer.dominion.utils.XLogger; +import org.bukkit.entity.Player; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class DPlayer { + + public static DPlayer get(Player player) { + DPlayer re = select(player.getUniqueId()); + if (re == null) { + re = insert(new DPlayer(player.getUniqueId(), player.getName(), System.currentTimeMillis())); + } + return re; + } + + public DPlayer join() { + return update(this); + } + + public static List search(String name) { + return select(name); + } + + private static List query(String sql) { + List players = new ArrayList<>(); + try (ResultSet rs = Database.query(sql)) { + if (rs == null) return players; + while (rs.next()) { + Integer id = rs.getInt("id"); + UUID uuid = UUID.fromString(rs.getString("uuid")); + String lastKnownName = rs.getString("last_known_name"); + Long lastJoinAt = rs.getTimestamp("last_join_at").getTime(); + DPlayer player = new DPlayer(id, uuid, lastKnownName, lastJoinAt); + players.add(player); + } + } catch (SQLException e) { + XLogger.err("Database query failed: " + e.getMessage()); + XLogger.err("SQL: " + sql); + } + return players; + } + + private static DPlayer select(UUID uuid) { + String sql = "SELECT * FROM player_name WHERE uuid = '" + uuid.toString() + "'"; + List players = query(sql); + if (players.size() == 0) return null; + return players.get(0); + } + + private static List select(String name) { + // 模糊搜索 + String sql = "SELECT * FROM player_name WHERE last_known_name LIKE '%" + name + "%'"; + return query(sql); + } + + private static DPlayer insert(DPlayer player) { + String sql = "INSERT INTO player_name (uuid, last_known_name, last_join_at) " + + "VALUES" + + " ('" + player.getUuid().toString() + "', '" + player.getLastKnownName() + "', CURRENT_TIMESTAMP) " + + "RETURNING *"; + List players = query(sql); + if (players.size() == 0) return null; + return players.get(0); + } + + private static DPlayer update(DPlayer player) { + String sql = "UPDATE player_name SET " + + "last_known_name = '" + player.getLastKnownName() + "', " + + "last_join_at = CURRENT_TIMESTAMP " + + "WHERE uuid = '" + player.getUuid().toString() + "' " + + "RETURNING *"; + List players = query(sql); + if (players.size() == 0) return null; + return players.get(0); + } + + private DPlayer(Integer id, UUID uuid, String lastKnownName, Long lastJoinAt) { + this.id = id; + this.uuid = uuid; + this.lastKnownName = lastKnownName; + this.lastJoinAt = lastJoinAt; + } + + private DPlayer(UUID uuid, String lastKnownName, Long lastJoinAt) { + this(null, uuid, lastKnownName, lastJoinAt); + } + + public Integer getId() { + return id; + } + + public UUID getUuid() { + return uuid; + } + + public String getLastKnownName() { + return lastKnownName; + } + + public Long getLastJoinAt() { + return lastJoinAt; + } + + public void setId(Integer id) { + this.id = id; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public void setLastKnownName(String lastKnownName) { + this.lastKnownName = lastKnownName; + } + + public void setLastJoinAt(Long lastJoinAt) { + this.lastJoinAt = lastJoinAt; + } + + private Integer id; + private UUID uuid; + private String lastKnownName; + private Long lastJoinAt; +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/ConfigManager.java b/src/main/java/cn/lunadeer/dominion/utils/ConfigManager.java new file mode 100644 index 0000000..8eb6820 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/ConfigManager.java @@ -0,0 +1,77 @@ +package cn.lunadeer.dominion.utils; + +import cn.lunadeer.dominion.Dominion; +import org.bukkit.configuration.file.FileConfiguration; + +public class ConfigManager { + public ConfigManager(Dominion plugin) { + _plugin = plugin; + _plugin.saveDefaultConfig(); + reload(); + _plugin.saveConfig(); + } + + public void reload() { + _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", "miniplayertitle"); + _db_user = _file.getString("Database.User", "postgres"); + _db_pass = _file.getString("Database.Pass", "postgres"); + } + + public Boolean isDebug() { + return _debug; + } + + public void setDebug(Boolean debug) { + _debug = debug; + _file.set("Debug", debug); + _plugin.saveConfig(); + } + + public String getDBConnectionUrl() { + return "jdbc:postgresql://" + _db_host + ":" + _db_port + "/" + _db_name; + } + + + 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; + } + + + private final Dominion _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; +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/Database.java b/src/main/java/cn/lunadeer/dominion/utils/Database.java new file mode 100644 index 0000000..06cb22c --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/Database.java @@ -0,0 +1,164 @@ +package cn.lunadeer.dominion.utils; + +import cn.lunadeer.dominion.Dominion; + +import java.sql.*; + +public class Database { + + public static Connection createConnection() { + try { + Class.forName("org.postgresql.Driver"); + return DriverManager.getConnection(Dominion.config.getDBConnectionUrl(), Dominion.config.getDbUser(), Dominion.config.getDbPass()); + } catch (ClassNotFoundException | SQLException e) { + XLogger.err("Database connection failed: " + e.getMessage()); + return null; + } + } + + public static ResultSet query(String sql) { + Connection conn = Dominion.dbConnection; + if (conn == null) { + return null; + } + try { + Statement stmt = conn.createStatement(); + // if query with no result return null + if (stmt.execute(sql)) { + return stmt.getResultSet(); + } else { + return null; + } + } catch (SQLException e) { + XLogger.err("Database query failed: " + e.getMessage()); + XLogger.err("SQL: " + sql); + return null; + } + } + + public static void migrate() { + String sql = ""; + + // player name + sql += "CREATE TABLE IF NOT EXISTS player_name (" + + " id SERIAL PRIMARY KEY," + + " uuid VARCHAR(36) NOT NULL," + + " last_known_name TEXT NOT NULL," + + " last_join_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" + + ")"; + + // dominion table + sql += "CREATE TABLE IF NOT EXISTS dominion (" + + " id SERIAL PRIMARY KEY," + + " owner VARCHAR(36) NOT NULL," + + " name TEXT NOT NULL UNIQUE," + + " world TEXT NOT NULL," + + " x1 INT NOT NULL," + + " y1 INT NOT NULL," + + " z1 INT NOT NULL," + + " x2 INT NOT NULL," + + " y2 INT NOT NULL," + + " z2 INT NOT NULL," + + " parent_dom_id INT NOT NULL DEFAULT -1," + + " join_message TEXT NOT NULL DEFAULT '欢迎', " + + " leave_message TEXT NOT NULL DEFAULT '再见', " + + + " anchor BOOLEAN NOT NULL DEFAULT FALSE," + + " animal_killing BOOLEAN NOT NULL DEFAULT FALSE," + + " anvil BOOLEAN NOT NULL DEFAULT FALSE," + + " anvil_break BOOLEAN NOT NULL DEFAULT FALSE," + + " beacon BOOLEAN NOT NULL DEFAULT FALSE," + + " bed BOOLEAN NOT NULL DEFAULT FALSE," + + " brew BOOLEAN NOT NULL DEFAULT FALSE," + + " button BOOLEAN NOT NULL DEFAULT FALSE," + + " cake BOOLEAN NOT NULL DEFAULT FALSE," + + " container BOOLEAN NOT NULL DEFAULT FALSE," + + " craft BOOLEAN NOT NULL DEFAULT FALSE," + + " creeper_explode BOOLEAN NOT NULL DEFAULT FALSE," + + " diode BOOLEAN NOT NULL DEFAULT FALSE," + + " door BOOLEAN NOT NULL DEFAULT FALSE," + + " dye BOOLEAN NOT NULL DEFAULT FALSE," + + " egg BOOLEAN NOT NULL DEFAULT FALSE," + + " enchant BOOLEAN NOT NULL DEFAULT FALSE," + + " ender_pearl BOOLEAN NOT NULL DEFAULT FALSE," + + " feed BOOLEAN NOT NULL DEFAULT FALSE," + + " fire_spread BOOLEAN NOT NULL DEFAULT FALSE," + + " flow_in_protection BOOLEAN NOT NULL DEFAULT FALSE," + + " glow BOOLEAN NOT NULL DEFAULT FALSE," + + " grow BOOLEAN NOT NULL DEFAULT FALSE," + + " honey BOOLEAN NOT NULL DEFAULT FALSE," + + " hook BOOLEAN NOT NULL DEFAULT FALSE," + + " ignite BOOLEAN NOT NULL DEFAULT FALSE," + + " mob_killing BOOLEAN NOT NULL DEFAULT FALSE," + + " move BOOLEAN NOT NULL DEFAULT TRUE," + + " place BOOLEAN NOT NULL DEFAULT FALSE," + + " pressure BOOLEAN NOT NULL DEFAULT FALSE," + + " riding BOOLEAN NOT NULL DEFAULT FALSE," + + " shear BOOLEAN NOT NULL DEFAULT FALSE," + + " shoot BOOLEAN NOT NULL DEFAULT FALSE," + + " tnt_explode BOOLEAN NOT NULL DEFAULT FALSE," + + " trade BOOLEAN NOT NULL DEFAULT FALSE," + + " vehicle_destroy BOOLEAN NOT NULL DEFAULT FALSE," + + " wither_spawn BOOLEAN NOT NULL DEFAULT FALSE," + + " harvest BOOLEAN NOT NULL DEFAULT FALSE," + + + " FOREIGN KEY (owner) REFERENCES player_name(uuid)," + + " FOREIGN KEY (parent_dom_id) REFERENCES dominion(id)" + + ")"; + + // privilege template + sql += "CREATE TABLE IF NOT EXISTS privilege_template (" + + " id SERIAL PRIMARY KEY," + + " name TEXT NOT NULL," + + " creator VARCHAR(36) NOT NULL," + + " is_group BOOLEAN NOT NULL DEFAULT TRUE," + + + " anchor BOOLEAN NOT NULL DEFAULT FALSE," + + " animal_killing BOOLEAN NOT NULL DEFAULT FALSE," + + " anvil BOOLEAN NOT NULL DEFAULT FALSE," + + " anvil_break BOOLEAN NOT NULL DEFAULT FALSE," + + " beacon BOOLEAN NOT NULL DEFAULT FALSE," + + " bed BOOLEAN NOT NULL DEFAULT FALSE," + + " brew BOOLEAN NOT NULL DEFAULT FALSE," + + " button BOOLEAN NOT NULL DEFAULT FALSE," + + " cake BOOLEAN NOT NULL DEFAULT FALSE," + + " container BOOLEAN NOT NULL DEFAULT FALSE," + + " craft BOOLEAN NOT NULL DEFAULT FALSE," + + " diode BOOLEAN NOT NULL DEFAULT FALSE," + + " door BOOLEAN NOT NULL DEFAULT FALSE," + + " dye BOOLEAN NOT NULL DEFAULT FALSE," + + " egg BOOLEAN NOT NULL DEFAULT FALSE," + + " enchant BOOLEAN NOT NULL DEFAULT FALSE," + + " ender_pearl BOOLEAN NOT NULL DEFAULT FALSE," + + " feed BOOLEAN NOT NULL DEFAULT FALSE," + + " glow BOOLEAN NOT NULL DEFAULT FALSE," + + " honey BOOLEAN NOT NULL DEFAULT FALSE," + + " hook BOOLEAN NOT NULL DEFAULT FALSE," + + " ignite BOOLEAN NOT NULL DEFAULT FALSE," + + " mob_killing BOOLEAN NOT NULL DEFAULT FALSE," + + " move BOOLEAN NOT NULL DEFAULT TRUE," + + " place BOOLEAN NOT NULL DEFAULT FALSE," + + " pressure BOOLEAN NOT NULL DEFAULT FALSE," + + " riding BOOLEAN NOT NULL DEFAULT FALSE," + + " shear BOOLEAN NOT NULL DEFAULT FALSE," + + " shoot BOOLEAN NOT NULL DEFAULT FALSE," + + " trade BOOLEAN NOT NULL DEFAULT FALSE," + + " vehicle_destroy BOOLEAN NOT NULL DEFAULT FALSE," + + " harvest BOOLEAN NOT NULL DEFAULT FALSE" + + ")"; + + // player dominion privilege + sql += "CREATE TABLE IF NOT EXISTS player_dom_privilege (" + + " id SERIAL PRIMARY KEY," + + " player_uuid VARCHAR(36) NOT NULL," + + " dom_id INT NOT NULL," + + " privilege_template_id INT NOT NULL," + + " FOREIGN KEY (player_uuid) REFERENCES player_name(uuid)," + + " FOREIGN KEY (dom_id) REFERENCES dominion(id)" + + ")"; + + + + query(sql); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/Notification.java b/src/main/java/cn/lunadeer/dominion/utils/Notification.java new file mode 100644 index 0000000..37e427b --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/Notification.java @@ -0,0 +1,63 @@ +package cn.lunadeer.dominion.utils; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class Notification { + private static final Style i_style = Style.style(TextColor.color(139, 255, 123)); + private static final Style w_style = Style.style(TextColor.color(255, 185, 69)); + private static final Style e_style = Style.style(TextColor.color(255, 96, 72)); + + private static final String prefix = "[MiniPlayerTitle] "; + + public static void info(Player player, String msg) { + player.sendMessage(Component.text(prefix + msg, i_style)); + } + + public static void warn(Player player, String msg) { + player.sendMessage(Component.text(prefix + msg, w_style)); + } + + public static void error(Player player, String msg) { + player.sendMessage(Component.text(prefix + msg, e_style)); + } + + public static void info(CommandSender sender, String msg) { + sender.sendMessage(Component.text(prefix + msg, i_style)); + } + + public static void warn(CommandSender sender, String msg) { + sender.sendMessage(Component.text(prefix + msg, w_style)); + } + + public static void error(CommandSender sender, String msg) { + sender.sendMessage(Component.text(prefix + msg, e_style)); + } + + public static void info(Player player, Component msg) { + player.sendMessage(Component.text(prefix, i_style).append(msg)); + } + + public static void warn(Player player, Component msg) { + player.sendMessage(Component.text(prefix, w_style).append(msg)); + } + + public static void error(Player player, Component msg) { + player.sendMessage(Component.text(prefix, e_style).append(msg)); + } + + public static void info(CommandSender player, Component msg) { + player.sendMessage(Component.text(prefix, i_style).append(msg)); + } + + public static void warn(CommandSender player, Component msg) { + player.sendMessage(Component.text(prefix, w_style).append(msg)); + } + + public static void error(CommandSender player, Component msg) { + player.sendMessage(Component.text(prefix, e_style).append(msg)); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/Button.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/Button.java new file mode 100644 index 0000000..2048497 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/Button.java @@ -0,0 +1,12 @@ +package cn.lunadeer.dominion.utils.STUI; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; + +public class Button { + + public static TextComponent create(String text, String command) { + return Component.text("[" + text + "]", ViewStyles.action_color) + .clickEvent(net.kyori.adventure.text.event.ClickEvent.clickEvent(net.kyori.adventure.text.event.ClickEvent.Action.RUN_COMMAND, command)); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/Line.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/Line.java new file mode 100644 index 0000000..949759d --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/Line.java @@ -0,0 +1,48 @@ +package cn.lunadeer.dominion.utils.STUI; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; + +import java.util.ArrayList; +import java.util.List; + + +public class Line { + private final List elements = new ArrayList<>(); + + private final TextComponent divider = Component.text(" - ", ViewStyles.sub_color); + + public Line() { + } + + public TextComponent build() { + TextComponent.Builder builder = Component.text(); + for (int i = 0; i < elements.size(); i++) { + builder.append(elements.get(i)); + if (i != elements.size() - 1) { + builder.append(divider); + } + } + return builder.build(); + } + + public static Line create() { + return new Line(); + } + + public Line append(TextComponent component) { + elements.add(component); + return this; + } + + public Line append(Component component) { + elements.add(component); + return this; + } + + public Line append(String component) { + elements.add(Component.text(component)); + return this; + } + +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/ListView.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/ListView.java new file mode 100644 index 0000000..b45c9cc --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/ListView.java @@ -0,0 +1,71 @@ +package cn.lunadeer.dominion.utils.STUI; + +import cn.lunadeer.dominion.utils.Notification; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class ListView { + + private final Integer page_size; + private final List lines = new ArrayList<>(); + private String command = ""; + private final View view = View.create(); + + public ListView(int page_size, String command) { + super(); + this.page_size = page_size; + this.command = command; + } + + public static ListView create(int page_size, String command) { + return new ListView(page_size, command); + } + + public ListView title(String title) { + view.title(title); + return this; + } + + public ListView title(String title, String subtitle) { + view.title(title); + view.subtitle(subtitle); + return this; + } + + public ListView subtitle(String subtitle) { + view.subtitle(subtitle); + return this; + } + + public ListView add(Line line) { + lines.add(line); + return this; + } + + public ListView addLines(List lines) { + this.lines.addAll(lines); + return this; + } + + public void showOn(Player player, Integer page) { + int offset = (page - 1) * page_size; + if (lines.isEmpty()) { + Notification.warn(player, "没有数据"); + return; + } + if (offset >= lines.size() || offset < 0) { + Notification.error(player, "页数超出范围"); + return; + } + for (int i = offset; i < offset + page_size; i++) { + if (i >= lines.size()) { + break; + } + view.addLine(lines.get(i)); + } + view.actionBar(Pagination.create(page, lines.size(), this.command)); + view.showOn(player); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/Pagination.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/Pagination.java new file mode 100644 index 0000000..8d4aac3 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/Pagination.java @@ -0,0 +1,38 @@ +package cn.lunadeer.dominion.utils.STUI; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; + +import java.util.ArrayList; +import java.util.List; + +import static cn.lunadeer.dominion.utils.STUI.ViewStyles.*; + + +public class Pagination { + public static TextComponent create(int page, int item_size, String command) { + // 第 x/y 页 [上一页] [下一页] + int page_size = 4; + int page_count = (int) Math.ceil((double) item_size / page_size); + if (page_count == 0) { + page_count = 1; + } + List componentList = new ArrayList<>(); + componentList.add(Component.text("第 ", main_color)); + componentList.add(Component.text(page, sub_color)); + componentList.add(Component.text("/", main_color)); + componentList.add(Component.text(page_count, sub_color)); + componentList.add(Component.text(" 页 ", main_color)); + if (page > 1) { + componentList.add(Button.create("上一页", command + " " + (page - 1))); + } + if (page < page_count) { + componentList.add(Button.create("下一页", command + " " + (page + 1))); + } + TextComponent.Builder builder = Component.text(); + for (Component component : componentList) { + builder.append(component); + } + return builder.build(); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/View.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/View.java new file mode 100644 index 0000000..c704d01 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/View.java @@ -0,0 +1,106 @@ +package cn.lunadeer.dominion.utils.STUI; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +import static cn.lunadeer.dominion.utils.STUI.ViewStyles.*; + +public class View { + protected TextComponent title_decorate = Component.text("━", main_color); + protected TextComponent space = Component.text(" "); + protected TextComponent sub_title_decorate = Component.text("- ", main_color); + protected TextComponent line_decorate = Component.text("⌗ ", main_color); + protected TextComponent action_decorate = Component.text("▸ ", main_color); + protected TextComponent title = Component.text(" "); + protected TextComponent subtitle = Component.text(""); + protected List content_lines = new ArrayList<>(); + protected TextComponent actionbar = Component.text(" "); + protected TextComponent edge = Component.text("━━━━━━━━━━━━━━━━━━━━━━━━━━━━", main_color); + protected TextComponent divide_line = Component.text("━━━━━━━━━━━━━━━━━━━━━━━━━━━━", main_color); + + public void showOn(Player player) { + player.sendMessage(edge); + TextComponent.Builder builder = Component.text(); + int title_length = title.content().length(); + int title_width = title_length * 2 + 2; + int decorate_count = divide_line.content().length() - title_width; + for (int i = 0; i < decorate_count / 2; i++) { + builder.append(title_decorate); + } + builder.append(space).append(title).append(space); + for (int i = 0; i < decorate_count / 2; i++) { + builder.append(title_decorate); + } + player.sendMessage(builder.build()); + if (subtitle.content().length() > 0) { + player.sendMessage(divide_line); + player.sendMessage(Component.text().append(sub_title_decorate).append(subtitle).build()); + } + player.sendMessage(divide_line); + for (TextComponent content_line : content_lines) { + player.sendMessage(Component.text().append(line_decorate).append(content_line).build()); + } + player.sendMessage(divide_line); + player.sendMessage(Component.text().append(action_decorate).append(actionbar).build()); + player.sendMessage(edge); + player.sendMessage(Component.text(" ")); + } + + public static View create() { + return new View(); + } + + public View title(String title) { + this.title = Component.text(title); + return this; + } + + public View title(TextComponent title) { + this.title = title; + return this; + } + + public View subtitle(String subtitle) { + this.subtitle = Component.text(subtitle); + return this; + } + + public View subtitle(TextComponent subtitle) { + this.subtitle = subtitle; + return this; + } + + public View actionBar(TextComponent actionbar) { + this.actionbar = actionbar; + return this; + } + + public View actionBar(String actionbar) { + this.actionbar = Component.text(actionbar); + return this; + } + + public View actionBar(Line actionbar) { + this.actionbar = actionbar.build(); + return this; + } + + public View addLine(TextComponent component) { + this.content_lines.add(component); + return this; + } + + public View addLine(String component) { + this.content_lines.add(Component.text(component)); + return this; + } + + public View addLine(Line component) { + this.content_lines.add(component.build()); + return this; + } +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/STUI/ViewStyles.java b/src/main/java/cn/lunadeer/dominion/utils/STUI/ViewStyles.java new file mode 100644 index 0000000..43b36bb --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/STUI/ViewStyles.java @@ -0,0 +1,11 @@ +package cn.lunadeer.dominion.utils.STUI; + +import net.kyori.adventure.text.format.TextColor; + +public class ViewStyles { + public static TextColor main_color = TextColor.color(0, 148, 213); + public static TextColor sub_color = TextColor.color(122, 122, 122); + public static TextColor action_color = TextColor.color(251, 255, 139); + public static TextColor error_color = TextColor.color(255, 96, 72); + public static TextColor success_color = TextColor.color(139, 255, 123); +} diff --git a/src/main/java/cn/lunadeer/dominion/utils/XLogger.java b/src/main/java/cn/lunadeer/dominion/utils/XLogger.java new file mode 100644 index 0000000..22d2018 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/XLogger.java @@ -0,0 +1,56 @@ +package cn.lunadeer.dominion.utils; + +import cn.lunadeer.dominion.Dominion; +import org.bukkit.entity.Player; + +import java.util.logging.Logger; + +public class XLogger { + private static final Dominion _plugin = Dominion.instance; + private static final Logger _logger = _plugin.getLogger(); + + private static final String prefix = "[MiniPlayerTitle] "; + + public static void info(Player player, String message) { + Notification.info(player, prefix + "I | " + message); + if (Dominion.config.isDebug()) + debug("来自玩家[ " + player.getName() + " ] 的信息 | " + message); + } + + public static void info(String message) { + _logger.info(" I | " + message); + } + + public static void warn(Player player, String message) { + Notification.warn(player, prefix + "W | " + message); + if (Dominion.config.isDebug()) + debug("来自玩家[ " + player.getName() + " ] 的警告 | " + message); + } + + public static void warn(String message) { + _logger.info(" W | " + message); + } + + public static void err(Player player, String message) { + Notification.error(player, prefix + "E | " + message); + if (Dominion.config.isDebug()) + debug("来自玩家[ " + player.getName() + " ] 的报错 | " + message); + } + + public static void err(String message) { + _logger.info(" E | " + message); + } + + public static void debug(Player player, String message) { + if (!Dominion.config.isDebug()) return; + if (player.isOp()) + Notification.info(player, prefix + "D | " + message); + else + debug("来自玩家[ " + player.getName() + " ] 的调试 | " + message); + } + + public static void debug(String message) { + if (!Dominion.config.isDebug()) return; + _logger.info(" D | " + message); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..994bb50 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,6 @@ +name: Dominion +version: '${project.version}' +main: cn.lunadeer.dominion.Dominion +api-version: '1.20' +load: STARTUP +folia-supported: true