This commit is contained in:
zhangyuheng 2024-02-04 17:54:17 +08:00
commit 49cff4d32d
17 changed files with 1102 additions and 0 deletions

View File

@ -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}}'

43
.github/workflows/main.yml vendored Normal file
View File

@ -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

113
.gitignore vendored Normal file
View File

@ -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/

80
pom.xml Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Dominion</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.20.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
</dependencies>
</project>

View File

@ -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;
}

View File

@ -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<DPlayer> search(String name) {
return select(name);
}
private static List<DPlayer> query(String sql) {
List<DPlayer> 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<DPlayer> players = query(sql);
if (players.size() == 0) return null;
return players.get(0);
}
private static List<DPlayer> 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<DPlayer> 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<DPlayer> 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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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<Component> 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;
}
}

View File

@ -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<Line> 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<Line> 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);
}
}

View File

@ -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<Component> 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();
}
}

View File

@ -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<TextComponent> 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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -0,0 +1,6 @@
name: Dominion
version: '${project.version}'
main: cn.lunadeer.dominion.Dominion
api-version: '1.20'
load: STARTUP
folia-supported: true