Skip to content

Commit 711a1f0

Browse files
committed
feat: 添加 Velocity 代理服务器支持
- 新增 Velocity 平台完整支持,包括命令系统、消息组件、日志输出 - 实现 ZComponent 平台无关组件系统,支持 Bukkit/BungeeCord/Velocity 三平台 - 修复 Velocity 环境 BossBar 初始化问题,避免加载 Bukkit 类 - 新增 Adventure API 适配器,支持彩色代码和富文本组件 - 升级版本号至 2.11.0
1 parent 5b7369a commit 711a1f0

34 files changed

+1212
-163
lines changed

.claude/settings.local.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(./gradlew :zmusic-plugin:compileJava:*)"
5+
],
6+
"deny": [],
7+
"ask": []
8+
}
9+
}

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ allprojects {
1111
maven { url 'https://repo.tabooproject.org/repository/releases' }
1212
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi' }
1313
maven { url 'https://libraries.minecraft.net' }
14+
maven { url 'https://repo.velocitypowered.com/snapshots/' }
1415
}
1516
}
1617

gradle/libs.versions.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ shadow = "8.3.5"
33

44
spigot = "1.21-R0.1-SNAPSHOT"
55
bungeecord = "1.21-R0.2"
6+
velocity = "3.1.0-SNAPSHOT"
67

78
netty = "4.2.1.Final"
9+
adventure = "4.11.0"
810

911
placeholderapi = "2.11.6"
1012
vault = "1.7.1"
@@ -18,6 +20,10 @@ shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
1820
# Platform API
1921
spigot = { module = "org.spigotmc:spigot-api", version.ref = "spigot" }
2022
bungeecord = { module = "net.md-5:bungeecord-api", version.ref = "bungeecord" }
23+
velocity = { module = "com.velocitypowered:velocity-api", version.ref = "velocity" }
24+
# Adventure API (Velocity/Paper)
25+
adventure_api = { module = "net.kyori:adventure-api", version.ref = "adventure" }
26+
adventure_text_serializer_legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "adventure" }
2127
# netty
2228
netty_buffer = { module = "io.netty:netty-buffer", version.ref = "netty" }
2329
# PAPI

zmusic-plugin/build.gradle

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
alias(libs.plugins.shadow)
33
}
44

5-
version = '2.10.4'
5+
version = '2.11.0'
66

77
dependencies {
88
compileOnly 'ink.ptms:nms-all:1.0.0'
@@ -17,6 +17,11 @@ dependencies {
1717
implementation(project(":zmusic-nms:zmusic-nms-1.21.7"))
1818

1919
compileOnly libs.bungeecord
20+
compileOnly libs.velocity
21+
22+
// Adventure API (Velocity/Paper 使用) - 仅编译时依赖,运行时由平台提供
23+
compileOnly libs.adventure.api
24+
compileOnly libs.adventure.text.serializer.legacy
2025

2126
compileOnly libs.placeholderapi
2227
compileOnly libs.vault
@@ -36,4 +41,8 @@ processResources {
3641
filesMatching("plugin.yml") {
3742
expand "version": project.version
3843
}
44+
45+
filesMatching("velocity-plugin.json") {
46+
expand "version": project.version
47+
}
3948
}

zmusic-plugin/src/main/java/me/zhenxin/zmusic/ZMusic.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
public final class ZMusic {
2020

2121
public static boolean isFolia = false;
22-
public static boolean isBC;
22+
public static boolean isBC = false;
23+
public static boolean isVelocity = false;
2324

2425
public static Log log;
2526
public static Message message;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package me.zhenxin.zmusic;
2+
3+
import com.google.inject.Inject;
4+
import com.velocitypowered.api.event.Subscribe;
5+
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
6+
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
7+
import com.velocitypowered.api.plugin.Plugin;
8+
import com.velocitypowered.api.plugin.annotation.DataDirectory;
9+
import com.velocitypowered.api.command.CommandManager;
10+
import com.velocitypowered.api.command.CommandMeta;
11+
import com.velocitypowered.api.proxy.ProxyServer;
12+
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
13+
import me.zhenxin.zmusic.command.CmdVelocity;
14+
import me.zhenxin.zmusic.config.Config;
15+
import me.zhenxin.zmusic.event.EventVelocity;
16+
import me.zhenxin.zmusic.utils.CookieUtils;
17+
import me.zhenxin.zmusic.utils.log.LogVelocity;
18+
import me.zhenxin.zmusic.utils.message.MessageVelocity;
19+
import me.zhenxin.zmusic.utils.mod.SendVelocity;
20+
import me.zhenxin.zmusic.utils.music.Music;
21+
import me.zhenxin.zmusic.utils.player.PlayerVelocity;
22+
import me.zhenxin.zmusic.utils.runtask.RunTaskVelocity;
23+
import org.slf4j.Logger;
24+
25+
import java.nio.file.Path;
26+
27+
@Plugin(
28+
id = "zmusic",
29+
name = "ZMusic",
30+
version = "2.11.0",
31+
description = "A Minecraft music plugin supporting Bukkit, BungeeCord, and Velocity",
32+
url = "https://github.com/zhenxin/ZMusic",
33+
authors = {"ZhenXin"}
34+
)
35+
public class ZMusicVelocity {
36+
37+
public static ProxyServer server;
38+
public static ZMusicVelocity plugin;
39+
public static Logger logger;
40+
public static Path dataDirectory;
41+
42+
// 插件消息通道
43+
public static final MinecraftChannelIdentifier ZMUSIC_CHANNEL =
44+
MinecraftChannelIdentifier.create("zmusic", "channel");
45+
public static final MinecraftChannelIdentifier ALLMUSIC_CHANNEL =
46+
MinecraftChannelIdentifier.create("allmusic", "channel");
47+
48+
@Inject
49+
public ZMusicVelocity(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
50+
ZMusicVelocity.server = server;
51+
ZMusicVelocity.logger = logger;
52+
ZMusicVelocity.dataDirectory = dataDirectory;
53+
ZMusicVelocity.plugin = this;
54+
}
55+
56+
@Subscribe
57+
public void onProxyInitialization(ProxyInitializeEvent event) {
58+
ZMusic.log = new LogVelocity();
59+
ZMusic.isBC = false;
60+
ZMusic.isVelocity = true;
61+
ZMusic.runTask = new RunTaskVelocity();
62+
ZMusic.message = new MessageVelocity();
63+
ZMusic.music = new Music();
64+
ZMusic.send = new SendVelocity();
65+
ZMusic.player = new PlayerVelocity();
66+
ZMusic.dataFolder = dataDirectory.toFile();
67+
if (!ZMusic.dataFolder.exists()) {
68+
ZMusic.dataFolder.mkdir();
69+
}
70+
Config.debug = true;
71+
ZMusic.thisVer = "2.11.0";
72+
ZMusic.log.sendNormalMessage("正在加载中....");
73+
CookieUtils.initCookieManager();
74+
75+
// 注册插件消息通道
76+
server.getChannelRegistrar().register(ZMUSIC_CHANNEL);
77+
server.getChannelRegistrar().register(ALLMUSIC_CHANNEL);
78+
79+
// 注册命令
80+
CommandManager commandManager = server.getCommandManager();
81+
CommandMeta meta = commandManager.metaBuilder("zm")
82+
.aliases("zmusic", "music")
83+
.plugin(this)
84+
.build();
85+
commandManager.register(meta, new CmdVelocity());
86+
87+
// 注册事件监听器
88+
server.getEventManager().register(this, new EventVelocity());
89+
90+
ZMusic.loadEnd(null);
91+
}
92+
93+
@Subscribe
94+
public void onProxyShutdown(ProxyShutdownEvent event) {
95+
ZMusic.disable();
96+
}
97+
}

zmusic-plugin/src/main/java/me/zhenxin/zmusic/command/Cmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import me.zhenxin.zmusic.utils.HelpUtils;
1515
import me.zhenxin.zmusic.utils.OtherUtils;
1616
import me.zhenxin.zmusic.utils.Vault;
17-
import net.md_5.bungee.api.chat.TextComponent;
1817

1918
import java.io.UnsupportedEncodingException;
2019
import java.util.*;
@@ -285,7 +284,7 @@ public void run() {
285284
for (int i = 0; i < 100; i++) {
286285
progressBar.setProgress(i);
287286
try {
288-
ZMusic.message.sendActionBarMessage(new TextComponent(progressBar.getString()), sender);
287+
ZMusic.message.sendActionBarMessage(progressBar.getString(), sender);
289288
Thread.sleep(10);
290289
} catch (Exception ignored) {
291290
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package me.zhenxin.zmusic.command;
2+
3+
import com.velocitypowered.api.command.CommandSource;
4+
import com.velocitypowered.api.command.SimpleCommand;
5+
import com.velocitypowered.api.proxy.Player;
6+
import me.zhenxin.zmusic.ZMusicVelocity;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.stream.Collectors;
11+
12+
public class CmdVelocity implements SimpleCommand {
13+
14+
@Override
15+
public void execute(Invocation invocation) {
16+
CommandSource source = invocation.source();
17+
String[] args = invocation.arguments();
18+
Cmd.cmd(source, args);
19+
}
20+
21+
@Override
22+
public List<String> suggest(Invocation invocation) {
23+
CommandSource source = invocation.source();
24+
String[] args = invocation.arguments();
25+
Iterable<String> suggestions = Cmd.tab(source, args);
26+
List<String> result = new ArrayList<>();
27+
suggestions.forEach(result::add);
28+
return result;
29+
}
30+
31+
@Override
32+
public boolean hasPermission(Invocation invocation) {
33+
return true; // 权限在 Cmd 内部处理
34+
}
35+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package me.zhenxin.zmusic.component;
2+
3+
/**
4+
* 平台无关的点击事件
5+
* <p>
6+
* 用于替代 BungeeCord 的 ClickEvent
7+
*/
8+
public class ZClickEvent {
9+
10+
private final Action action;
11+
private final String value;
12+
13+
public ZClickEvent(Action action, String value) {
14+
this.action = action;
15+
this.value = value;
16+
}
17+
18+
public Action getAction() {
19+
return action;
20+
}
21+
22+
public String getValue() {
23+
return value;
24+
}
25+
26+
/**
27+
* 点击事件类型
28+
*/
29+
public enum Action {
30+
/**
31+
* 打开 URL
32+
*/
33+
OPEN_URL,
34+
/**
35+
* 执行命令
36+
*/
37+
RUN_COMMAND,
38+
/**
39+
* 建议命令(填充到聊天框)
40+
*/
41+
SUGGEST_COMMAND,
42+
/**
43+
* 复制到剪贴板
44+
*/
45+
COPY_TO_CLIPBOARD
46+
}
47+
48+
/**
49+
* 创建执行命令的点击事件
50+
*/
51+
public static ZClickEvent runCommand(String command) {
52+
return new ZClickEvent(Action.RUN_COMMAND, command);
53+
}
54+
55+
/**
56+
* 创建建议命令的点击事件
57+
*/
58+
public static ZClickEvent suggestCommand(String command) {
59+
return new ZClickEvent(Action.SUGGEST_COMMAND, command);
60+
}
61+
62+
/**
63+
* 创建打开 URL 的点击事件
64+
*/
65+
public static ZClickEvent openUrl(String url) {
66+
return new ZClickEvent(Action.OPEN_URL, url);
67+
}
68+
69+
/**
70+
* 创建复制到剪贴板的点击事件
71+
*/
72+
public static ZClickEvent copyToClipboard(String text) {
73+
return new ZClickEvent(Action.COPY_TO_CLIPBOARD, text);
74+
}
75+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package me.zhenxin.zmusic.component;
2+
3+
import java.util.List;
4+
5+
/**
6+
* 平台无关的消息组件接口
7+
* <p>
8+
* 用于替代 BungeeCord 的 TextComponent,支持 Bukkit/BungeeCord/Velocity 三平台
9+
*/
10+
public interface ZComponent {
11+
12+
/**
13+
* 获取组件的纯文本内容
14+
*/
15+
String getText();
16+
17+
/**
18+
* 设置文本内容
19+
*/
20+
ZComponent setText(String text);
21+
22+
/**
23+
* 获取点击事件
24+
*/
25+
ZClickEvent getClickEvent();
26+
27+
/**
28+
* 设置点击事件
29+
*/
30+
ZComponent setClickEvent(ZClickEvent clickEvent);
31+
32+
/**
33+
* 获取悬停事件
34+
*/
35+
ZHoverEvent getHoverEvent();
36+
37+
/**
38+
* 设置悬停事件
39+
*/
40+
ZComponent setHoverEvent(ZHoverEvent hoverEvent);
41+
42+
/**
43+
* 获取子组件列表
44+
*/
45+
List<ZComponent> getChildren();
46+
47+
/**
48+
* 添加子组件
49+
*/
50+
ZComponent addChild(ZComponent child);
51+
52+
/**
53+
* 转换为带格式的完整文本(包含子组件)
54+
*/
55+
String toPlainText();
56+
}

0 commit comments

Comments
 (0)