Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
20f395fa45 | |||
4d3d93887d | |||
518517a4e0 | |||
3570930b1f | |||
5724e5e662 | |||
e4425c0b1b | |||
5c913fa2db | |||
08a41c1209 | |||
d38bd5e41f | |||
52e25a0433 | |||
cc33304ad4 | |||
6d2abfa44b | |||
bc49510c46 | |||
74f1a4557d | |||
84721e31ee | |||
4e29246441 | |||
aa0e94c7b7 | |||
aac7248994 |
10
README.md
10
README.md
@@ -1,6 +1,6 @@
|
|||||||
# [HamsterBall](https://git.airgame.net/MiniDay/hamster-ball)
|
# [HamsterBall](https://git.airgame.net/MiniDay/hamster-ball)
|
||||||
|
|
||||||
仓鼠球:一个基于 Redis 的 Minecraft 服务端通用消息中间件(原HamsterService)
|
基于 Redis 的 Minecraft 服务端通用消息中间件
|
||||||
|
|
||||||
该插件依赖于 [仓鼠核心](https://git.airgame.net/MiniDay/hamster-core)
|
该插件依赖于 [仓鼠核心](https://git.airgame.net/MiniDay/hamster-core)
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// 对于 Bukkit 插件
|
// 对于 Bukkit 插件
|
||||||
compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.6.2")
|
compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.7.0")
|
||||||
// 对于 BungeeCord 插件
|
// 对于 BungeeCord 插件
|
||||||
compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.6.2")
|
compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.7.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -77,13 +77,13 @@ dependencies {
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hamster3.mc.plugin</groupId>
|
<groupId>cn.hamster3.mc.plugin</groupId>
|
||||||
<artifactId>ball-bukkit</artifactId>
|
<artifactId>ball-bukkit</artifactId>
|
||||||
<version>1.6.2</version>
|
<version>1.7.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--对于 BungeeCord 插件-->
|
<!--对于 BungeeCord 插件-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hamster3.mc.plugin</groupId>
|
<groupId>cn.hamster3.mc.plugin</groupId>
|
||||||
<artifactId>ball-bungee</artifactId>
|
<artifactId>ball-bungee</artifactId>
|
||||||
<version>1.6.2</version>
|
<version>1.7.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -6,18 +6,26 @@ import cn.hamster3.mc.plugin.ball.bukkit.listener.BallBukkitListener;
|
|||||||
import cn.hamster3.mc.plugin.ball.bukkit.listener.UpdatePlayerInfoListener;
|
import cn.hamster3.mc.plugin.ball.bukkit.listener.UpdatePlayerInfoListener;
|
||||||
import cn.hamster3.mc.plugin.ball.bukkit.util.BallBukkitUtils;
|
import cn.hamster3.mc.plugin.ball.bukkit.util.BallBukkitUtils;
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.BallCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
||||||
|
import cn.hamster3.mc.plugin.core.bukkit.api.CoreBukkitAPI;
|
||||||
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -129,4 +137,35 @@ public class HamsterBallPlugin extends JavaPlugin {
|
|||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
logger.info("仓鼠球已关闭,总计耗时 " + time + " ms");
|
logger.info("仓鼠球已关闭,总计耗时 " + time + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
return BallCommand.INSTANCE.onCommand(new AdaptCommandSender() {
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull String permission) {
|
||||||
|
return sender.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(@NotNull Component message) {
|
||||||
|
CoreBukkitAPI.getInstance().getAudienceProvider().sender(sender).sendMessage(message);
|
||||||
|
}
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
|
return BallCommand.INSTANCE.onTabComplete(new AdaptCommandSender() {
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull String permission) {
|
||||||
|
return sender.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(@NotNull Component message) {
|
||||||
|
CoreBukkitAPI.getInstance().getAudienceProvider().sender(sender).sendMessage(message);
|
||||||
|
}
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ package cn.hamster3.mc.plugin.ball.bukkit.listener;
|
|||||||
import cn.hamster3.mc.plugin.ball.bukkit.HamsterBallPlugin;
|
import cn.hamster3.mc.plugin.ball.bukkit.HamsterBallPlugin;
|
||||||
import cn.hamster3.mc.plugin.ball.bukkit.data.BukkitLocation;
|
import cn.hamster3.mc.plugin.ball.bukkit.data.BukkitLocation;
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||||
@@ -95,9 +94,6 @@ public class BallBukkitListener implements Listener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.GAME) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -106,9 +102,6 @@ public class BallBukkitListener implements Listener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
|
public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.GAME) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getUuid() != null) {
|
if (event.getUuid() != null) {
|
||||||
Player player = Bukkit.getPlayer(event.getUuid());
|
Player player = Bukkit.getPlayer(event.getUuid());
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
|
@@ -1,6 +1,13 @@
|
|||||||
# 是否允许在控制台输出调试信息
|
# 是否允许在控制台输出调试信息
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# 是否启用服务器 ID 单例模式
|
||||||
|
# 启用后,当一个服务器启动后将会占用 服务器唯一识别码
|
||||||
|
# 其他使用相同 服务器唯一识别码 的服务器将无法启动
|
||||||
|
# 测试端中可关闭该功能
|
||||||
|
# 推荐在正式服中开启该功能以防止服务器 ID 重复
|
||||||
|
singleton-server-id: false
|
||||||
|
|
||||||
# 频道名前缀
|
# 频道名前缀
|
||||||
# 使用这个配置选项可以划分子服消息通信分组
|
# 使用这个配置选项可以划分子服消息通信分组
|
||||||
# 只有在同一个频道名的子服才能互相通信
|
# 只有在同一个频道名的子服才能互相通信
|
||||||
|
@@ -4,8 +4,15 @@ version: ${version}
|
|||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
|
||||||
author: MiniDay
|
author: MiniDay
|
||||||
|
description: ${description}
|
||||||
website: https://git.airgame.net/MiniDay/hamster-ball
|
website: https://git.airgame.net/MiniDay/hamster-ball
|
||||||
description: 仓鼠球:一个基于 Redis 的 Minecraft 服务端通用消息中间件(原HamsterService)
|
|
||||||
|
UPDATE_CHECKER:
|
||||||
|
VERSION: ${version}
|
||||||
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
|
GIT_REPO: MiniDay/hamster-ball
|
||||||
|
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
||||||
|
|
||||||
load: STARTUP
|
load: STARTUP
|
||||||
|
|
||||||
@@ -14,3 +21,11 @@ depend:
|
|||||||
|
|
||||||
softdepend:
|
softdepend:
|
||||||
- PlaceholderAPI
|
- PlaceholderAPI
|
||||||
|
|
||||||
|
commands:
|
||||||
|
hamster-ball:
|
||||||
|
aliases: [ ball ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
hamster.ball.admin:
|
||||||
|
default: op
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
version: ${version}
|
|
||||||
CHECK_TYPE: GITEA_RELEASES
|
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
|
||||||
GIT_REPO: MiniDay/hamster-ball
|
|
||||||
GIT_TOKEN: a44a69a4d1b8601bf6091403247759cd28764d5e
|
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
|
@@ -1,6 +1,7 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.bungee;
|
package cn.hamster3.mc.plugin.ball.bungee;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.bungee.api.BallBungeeCordAPI;
|
import cn.hamster3.mc.plugin.ball.bungee.api.BallBungeeCordAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.bungee.command.BungeeBallCommand;
|
||||||
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeListener;
|
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeListener;
|
||||||
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeMainListener;
|
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeMainListener;
|
||||||
import cn.hamster3.mc.plugin.ball.bungee.listener.BungeeServerListener;
|
import cn.hamster3.mc.plugin.ball.bungee.listener.BungeeServerListener;
|
||||||
@@ -71,6 +72,8 @@ public class HamsterBallPlugin extends Plugin {
|
|||||||
ProxyServer.getInstance().stop("仓鼠球启动失败");
|
ProxyServer.getInstance().stop("仓鼠球启动失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerCommand(this, BungeeBallCommand.INSTANCE);
|
||||||
|
logger.info("已注册命令 BungeeBallCommand");
|
||||||
BallAPI.getInstance().getEventBus().register(BallBungeeListener.INSTANCE);
|
BallAPI.getInstance().getEventBus().register(BallBungeeListener.INSTANCE);
|
||||||
logger.info("已注册监听器 BallBungeeListener");
|
logger.info("已注册监听器 BallBungeeListener");
|
||||||
ProxyServer.getInstance().getPluginManager().registerListener(this, BallBungeeMainListener.INSTANCE);
|
ProxyServer.getInstance().getPluginManager().registerListener(this, BallBungeeMainListener.INSTANCE);
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.bungee.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.BallCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.core.bungee.api.CoreBungeeAPI;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class BungeeBallCommand extends Command {
|
||||||
|
public static final BungeeBallCommand INSTANCE = new BungeeBallCommand();
|
||||||
|
|
||||||
|
public BungeeBallCommand() {
|
||||||
|
super("hamster-bungee-ball", "hamster.ball.admin", "bungee-ball", "bball");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
BallCommand.INSTANCE.onCommand(new AdaptCommandSender() {
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull String permission) {
|
||||||
|
return sender.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(@NotNull Component message) {
|
||||||
|
CoreBungeeAPI.getInstance().getAudienceProvider().sender(sender).sendMessage(message);
|
||||||
|
}
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@ package cn.hamster3.mc.plugin.ball.bungee.listener;
|
|||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.bungee.HamsterBallPlugin;
|
import cn.hamster3.mc.plugin.ball.bungee.HamsterBallPlugin;
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
@@ -23,9 +22,6 @@ public class BallBungeeListener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.PROXY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -35,9 +31,6 @@ public class BallBungeeListener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchPlayerCommandEvent(DispatchPlayerCommandEvent event) {
|
public void onDispatchPlayerCommandEvent(DispatchPlayerCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.GAME) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProxyServer server = ProxyServer.getInstance();
|
ProxyServer server = ProxyServer.getInstance();
|
||||||
if (event.getUuid() != null) {
|
if (event.getUuid() != null) {
|
||||||
ProxiedPlayer player = server.getPlayer(event.getUuid());
|
ProxiedPlayer player = server.getPlayer(event.getUuid());
|
||||||
|
@@ -3,7 +3,15 @@ main: cn.hamster3.mc.plugin.ball.bungee.HamsterBallPlugin
|
|||||||
version: ${version}
|
version: ${version}
|
||||||
|
|
||||||
author: MiniDay
|
author: MiniDay
|
||||||
description: 仓鼠球:一个基于 Redis 的 Minecraft 服务端通用消息中间件(原HamsterService)
|
description: ${description}
|
||||||
|
website: https://git.airgame.net/MiniDay/hamster-ball
|
||||||
|
|
||||||
|
UPDATE_CHECKER:
|
||||||
|
VERSION: ${version}
|
||||||
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
|
GIT_REPO: MiniDay/hamster-ball
|
||||||
|
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
- HamsterCore
|
- HamsterCore
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
# 是否允许在控制台输出调试信息
|
# 是否允许在控制台输出调试信息
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# 是否启用服务器 ID 单例模式
|
||||||
|
# 启用后,服务器唯一识别码 相同的服务器将无法启动
|
||||||
|
singleton-server-id: false
|
||||||
|
|
||||||
# 频道名前缀
|
# 频道名前缀
|
||||||
# 使用这个配置选项可以划分子服消息通信分组
|
# 使用这个配置选项可以划分子服消息通信分组
|
||||||
# 只有在同一个频道名的子服才能互相通信
|
# 只有在同一个频道名的子服才能互相通信
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
version: ${version}
|
|
||||||
CHECK_TYPE: GITEA_RELEASES
|
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
|
||||||
GIT_REPO: MiniDay/hamster-ball
|
|
||||||
GIT_TOKEN: a44a69a4d1b8601bf6091403247759cd28764d5e
|
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
|
@@ -102,12 +102,13 @@ public abstract class BallAPI {
|
|||||||
getLogger().warning("已启用调试模式");
|
getLogger().warning("已启用调试模式");
|
||||||
eventBus.register(BallDebugListener.INSTANCE);
|
eventBus.register(BallDebugListener.INSTANCE);
|
||||||
}
|
}
|
||||||
|
CoreAPI.getInstance().getExecutorService().submit(() -> redisSub.subscribe(BallRedisListener.INSTANCE, BALL_CHANNEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void enable() throws SQLException, InterruptedException {
|
protected void enable() throws SQLException, InterruptedException {
|
||||||
try (Jedis jedis = CoreAPI.getInstance().getJedisPool().getResource()) {
|
try (Jedis jedis = CoreAPI.getInstance().getJedisPool().getResource()) {
|
||||||
String key = "HamsterBall:ServerInfo:" + localServerInfo.getId();
|
String key = "HamsterBall:ServerInfo:" + localServerInfo.getId();
|
||||||
if (jedis.exists(key)) {
|
if (jedis.exists(key) && ballConfig.isSingletonServerID()) {
|
||||||
throw new IllegalStateException("已经有一个服务器占用了该 ID");
|
throw new IllegalStateException("已经有一个服务器占用了该 ID");
|
||||||
}
|
}
|
||||||
jedis.hset(key, "id", localServerInfo.getId());
|
jedis.hset(key, "id", localServerInfo.getId());
|
||||||
@@ -179,7 +180,6 @@ public abstract class BallAPI {
|
|||||||
}
|
}
|
||||||
getLogger().info("从数据库中加载了 " + allServerInfo.size() + " 条服务器信息");
|
getLogger().info("从数据库中加载了 " + allServerInfo.size() + " 条服务器信息");
|
||||||
getLogger().info("从数据库中加载了 " + allPlayerInfo.size() + " 条玩家信息");
|
getLogger().info("从数据库中加载了 " + allPlayerInfo.size() + " 条玩家信息");
|
||||||
subscribeRaw(BALL_CHANNEL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void disable() throws SQLException, InterruptedException {
|
protected void disable() throws SQLException, InterruptedException {
|
||||||
@@ -257,25 +257,24 @@ public abstract class BallAPI {
|
|||||||
*/
|
*/
|
||||||
public void dispatchConsoleCommand(@Nullable BallServerType type, @Nullable String serverID, @NotNull String command) {
|
public void dispatchConsoleCommand(@Nullable BallServerType type, @Nullable String serverID, @NotNull String command) {
|
||||||
sendBallMessage(BALL_CHANNEL, new BallMessage(
|
sendBallMessage(BALL_CHANNEL, new BallMessage(
|
||||||
getLocalServerId(), null, BallServerType.GAME,
|
getLocalServerId(), null, type,
|
||||||
BallActions.DispatchConsoleCommand.name(),
|
BallActions.DispatchConsoleCommand.name(),
|
||||||
CoreAPI.getInstance().getGson().toJsonTree(new DispatchConsoleCommandEvent(type, serverID, command))
|
CoreAPI.getInstance().getGson().toJsonTree(new DispatchConsoleCommandEvent(serverID, command))
|
||||||
), false);
|
), false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 强制玩家执行命令
|
* 强制玩家执行命令
|
||||||
*
|
*
|
||||||
* @param type 执行对象的服务端类型
|
* @param type 执行对象的服务端类型,null代表所有类型
|
||||||
* @param uuid 执行对象的 UUID
|
* @param uuid 执行对象的 UUID,null代表所有玩家
|
||||||
* @param command 命令内容
|
* @param command 命令内容
|
||||||
*/
|
*/
|
||||||
public void dispatchPlayerCommand(@Nullable BallServerType type, @Nullable UUID uuid, @NotNull String command) {
|
public void dispatchPlayerCommand(@Nullable BallServerType type, @Nullable UUID uuid, @NotNull String command) {
|
||||||
sendBallMessage(BALL_CHANNEL, new BallMessage(
|
sendBallMessage(BALL_CHANNEL, new BallMessage(
|
||||||
getLocalServerId(), null, BallServerType.GAME,
|
getLocalServerId(), null, type,
|
||||||
BallActions.DispatchPlayerCommand.name(),
|
BallActions.DispatchPlayerCommand.name(),
|
||||||
CoreAPI.getInstance().getGson().toJsonTree(new DispatchPlayerCommandEvent(type, uuid, command))
|
CoreAPI.getInstance().getGson().toJsonTree(new DispatchPlayerCommandEvent(uuid, command))
|
||||||
), false);
|
), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,26 +505,29 @@ public abstract class BallAPI {
|
|||||||
* <p>
|
* <p>
|
||||||
* 会自动加上 config 中设置的频道前缀
|
* 会自动加上 config 中设置的频道前缀
|
||||||
*
|
*
|
||||||
* @param channel 频道名称
|
* @param channels 频道名称
|
||||||
*/
|
*/
|
||||||
public void subscribe(@NotNull String... channel) {
|
public void subscribe(@NotNull String... channels) {
|
||||||
for (int i = 0; i < channel.length; i++) {
|
for (int i = 0; i < channels.length; i++) {
|
||||||
channel[i] = ballConfig.getChannelPrefix() + channel[i];
|
channels[i] = ballConfig.getChannelPrefix() + channels[i];
|
||||||
}
|
}
|
||||||
CoreAPI.getInstance().getExecutorService().submit(
|
subscribeRaw(channels);
|
||||||
() -> redisSub.subscribe(BallRedisListener.INSTANCE, channel)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略频道前缀配置,订阅 redis 消息频道
|
* 忽略频道前缀配置,订阅 redis 消息频道
|
||||||
*
|
*
|
||||||
* @param channel 频道名称
|
* @param channels 频道名称
|
||||||
*/
|
*/
|
||||||
public void subscribeRaw(@NotNull String... channel) {
|
public void subscribeRaw(@NotNull String... channels) {
|
||||||
CoreAPI.getInstance().getExecutorService().submit(
|
BallRedisListener.INSTANCE.subscribe(channels);
|
||||||
() -> redisSub.subscribe(BallRedisListener.INSTANCE, channel)
|
// CoreAPI.getInstance().getExecutorService().submit(() -> {
|
||||||
);
|
// try {
|
||||||
|
// redisSub.subscribe(BallRedisListener.INSTANCE, channels);
|
||||||
|
// } catch (Exception | Error e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -534,9 +536,10 @@ public abstract class BallAPI {
|
|||||||
* @param patterns 频道名称正则表达式
|
* @param patterns 频道名称正则表达式
|
||||||
*/
|
*/
|
||||||
public void subscribePatterns(@NotNull String patterns) {
|
public void subscribePatterns(@NotNull String patterns) {
|
||||||
CoreAPI.getInstance().getExecutorService().submit(
|
BallRedisListener.INSTANCE.psubscribe(patterns);
|
||||||
() -> redisSub.psubscribe(BallRedisListener.INSTANCE, patterns)
|
// CoreAPI.getInstance().getExecutorService().submit(
|
||||||
);
|
// () -> redisSub.psubscribe(BallRedisListener.INSTANCE, patterns)
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,22 +547,22 @@ public abstract class BallAPI {
|
|||||||
* <p>
|
* <p>
|
||||||
* 会自动加上 config 中设置的频道前缀
|
* 会自动加上 config 中设置的频道前缀
|
||||||
*
|
*
|
||||||
* @param channel 频道名称
|
* @param channels 频道名称
|
||||||
*/
|
*/
|
||||||
public void unsubscribe(@NotNull String... channel) {
|
public void unsubscribe(@NotNull String... channels) {
|
||||||
for (int i = 0; i < channel.length; i++) {
|
for (int i = 0; i < channels.length; i++) {
|
||||||
channel[i] = ballConfig.getChannelPrefix() + channel[i];
|
channels[i] = ballConfig.getChannelPrefix() + channels[i];
|
||||||
}
|
}
|
||||||
BallRedisListener.INSTANCE.unsubscribe(channel);
|
unsubscribeRaw(channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略频道前缀配置,取消订阅 redis 消息频道
|
* 忽略频道前缀配置,取消订阅 redis 消息频道
|
||||||
*
|
*
|
||||||
* @param channel 频道名称
|
* @param channels 频道名称
|
||||||
*/
|
*/
|
||||||
public void unsubscribeIgnorePrefix(@NotNull String... channel) {
|
public void unsubscribeRaw(@NotNull String... channels) {
|
||||||
BallRedisListener.INSTANCE.unsubscribe(channel);
|
BallRedisListener.INSTANCE.unsubscribe(channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,21 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ParentCommand;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class BallCommand extends ParentCommand {
|
||||||
|
public static final BallCommand INSTANCE = new BallCommand();
|
||||||
|
|
||||||
|
private BallCommand() {
|
||||||
|
addChildCommand(PlayerInfoCommand.INSTANCE);
|
||||||
|
addChildCommand(SudoPlayerCommand.INSTANCE);
|
||||||
|
addChildCommand(SudoAllPlayerCommand.INSTANCE);
|
||||||
|
addChildCommand(SudoConsoleCommand.INSTANCE);
|
||||||
|
addChildCommand(SudoAllConsoleCommand.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "hamster-ball";
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,77 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PlayerInfoCommand extends ChildCommand {
|
||||||
|
public static final PlayerInfoCommand INSTANCE = new PlayerInfoCommand();
|
||||||
|
|
||||||
|
private PlayerInfoCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "player-info";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "player-info <玩家名|UUID>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "查看玩家信息";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return sender.hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length < 1) {
|
||||||
|
sender.sendMessage(BallCommand.INSTANCE.getUsage() + " " + getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallPlayerInfo info;
|
||||||
|
try {
|
||||||
|
UUID uuid = UUID.fromString(args[0]);
|
||||||
|
info = BallAPI.getInstance().getPlayerInfo(uuid);
|
||||||
|
} catch (Exception e) {
|
||||||
|
info = BallAPI.getInstance().getPlayerInfo(args[0]);
|
||||||
|
}
|
||||||
|
if (info == null) {
|
||||||
|
sender.sendMessage("§c未找到玩家 " + args[0] + " 的信息");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sender.sendMessage("§a玩家名称: " + info.getName());
|
||||||
|
sender.sendMessage("§a玩家UUID: " + info.getUuid());
|
||||||
|
sender.sendMessage("§a玩家在线: " + info.isOnline());
|
||||||
|
sender.sendMessage("§a接入点: " + info.getProxyServer());
|
||||||
|
sender.sendMessage("§a所在子服: " + info.getGameServer());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return BallAPI.getInstance().getAllPlayerInfo().values().stream()
|
||||||
|
.map(BallPlayerInfo::getName)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,75 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SudoAllConsoleCommand extends ChildCommand {
|
||||||
|
public static final SudoAllConsoleCommand INSTANCE = new SudoAllConsoleCommand();
|
||||||
|
|
||||||
|
private SudoAllConsoleCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "sudo-all-console";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "sudo-all-console <服务器类型> <命令内容>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "强制所有控制台执行指令";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return sender.hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length < 2) {
|
||||||
|
sender.sendMessage(BallCommand.INSTANCE.getUsage() + " " + getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallServerType serverType;
|
||||||
|
try {
|
||||||
|
serverType = BallServerType.valueOf(args[0].toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
sender.sendMessage("§c未知的服务器类型: " + args[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(args[1]);
|
||||||
|
for (int i = 2; i < args.length; i++) {
|
||||||
|
builder.append(" ").append(args[i]);
|
||||||
|
}
|
||||||
|
String command = builder.toString();
|
||||||
|
BallAPI.getInstance().dispatchConsoleCommand(serverType, null, command);
|
||||||
|
sender.sendMessage("§a已强制所有服务器控制台执行命令: §e/" + command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Arrays.stream(BallServerType.values())
|
||||||
|
.map(Enum::name)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,75 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SudoAllPlayerCommand extends ChildCommand {
|
||||||
|
public static final SudoAllPlayerCommand INSTANCE = new SudoAllPlayerCommand();
|
||||||
|
|
||||||
|
private SudoAllPlayerCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "sudo-all-player";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "sudo-all-player <服务器类型> <命令内容>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "强制所有玩家执行指令";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return sender.hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length < 2) {
|
||||||
|
sender.sendMessage(BallCommand.INSTANCE.getUsage() + " " + getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallServerType serverType;
|
||||||
|
try {
|
||||||
|
serverType = BallServerType.valueOf(args[0].toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
sender.sendMessage("§c未知的服务器类型: " + args[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(args[1]);
|
||||||
|
for (int i = 2; i < args.length; i++) {
|
||||||
|
builder.append(" ").append(args[i]);
|
||||||
|
}
|
||||||
|
String command = builder.toString();
|
||||||
|
BallAPI.getInstance().dispatchPlayerCommand(serverType, null, command);
|
||||||
|
sender.sendMessage("§a已强制所有玩家执行命令: §e/" + command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return Arrays.stream(BallServerType.values())
|
||||||
|
.map(Enum::name)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SudoConsoleCommand extends ChildCommand {
|
||||||
|
public static final SudoConsoleCommand INSTANCE = new SudoConsoleCommand();
|
||||||
|
|
||||||
|
private SudoConsoleCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "sudo-console";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "sudo-console <服务器ID> <命令内容>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "强制控制台执行指令";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return sender.hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length < 2) {
|
||||||
|
sender.sendMessage(BallCommand.INSTANCE.getUsage() + " " + getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallServerInfo info = BallAPI.getInstance().getServerInfo(args[0]);
|
||||||
|
if (info == null) {
|
||||||
|
sender.sendMessage("§c服务器 " + args[0] + " 不在线");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(args[1]);
|
||||||
|
for (int i = 2; i < args.length; i++) {
|
||||||
|
builder.append(" ").append(args[i]);
|
||||||
|
}
|
||||||
|
String command = builder.toString();
|
||||||
|
BallAPI.getInstance().dispatchConsoleCommand(null, info.getId(), command);
|
||||||
|
sender.sendMessage("§a已强制服务器 " + info.getName() + " 控制台执行命令: §e/" + command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return BallAPI.getInstance().getAllServerInfo().values().stream()
|
||||||
|
.map(BallServerInfo::getId)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,101 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.ChildCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SudoPlayerCommand extends ChildCommand {
|
||||||
|
public static final SudoPlayerCommand INSTANCE = new SudoPlayerCommand();
|
||||||
|
|
||||||
|
private SudoPlayerCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return "sudo-player";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getUsage() {
|
||||||
|
return "sudo-player <服务器类型> <玩家名|UUID> <命令内容>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "强制玩家执行指令";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return sender.hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length < 3) {
|
||||||
|
sender.sendMessage(BallCommand.INSTANCE.getUsage() + " " + getUsage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallServerType serverType;
|
||||||
|
try {
|
||||||
|
serverType = BallServerType.valueOf(args[0].toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
sender.sendMessage("§c未知的服务器类型: " + args[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BallPlayerInfo info;
|
||||||
|
try {
|
||||||
|
UUID uuid = UUID.fromString(args[1]);
|
||||||
|
info = BallAPI.getInstance().getPlayerInfo(uuid);
|
||||||
|
} catch (Exception e) {
|
||||||
|
info = BallAPI.getInstance().getPlayerInfo(args[1]);
|
||||||
|
}
|
||||||
|
if (info == null) {
|
||||||
|
sender.sendMessage("§c未找到玩家 " + args[1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!info.isOnline()) {
|
||||||
|
sender.sendMessage("§c玩家 " + args[1] + " 不在线");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder(args[2]);
|
||||||
|
for (int i = 3; i < args.length; i++) {
|
||||||
|
builder.append(" ").append(args[i]);
|
||||||
|
}
|
||||||
|
String command = builder.toString();
|
||||||
|
BallAPI.getInstance().dispatchPlayerCommand(serverType, info.getUuid(), command);
|
||||||
|
sender.sendMessage("§a已强制玩家 " + info.getName() + " 执行命令: §e/" + command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 1: {
|
||||||
|
return Arrays.stream(BallServerType.values())
|
||||||
|
.map(Enum::name)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
return BallAPI.getInstance().getAllPlayerInfo().values().stream()
|
||||||
|
.map(BallPlayerInfo::getName)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[1].toLowerCase()))
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command.adapt;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface AdaptCommandSender {
|
||||||
|
boolean hasPermission(@NotNull String permission);
|
||||||
|
|
||||||
|
void sendMessage(@NotNull Component message);
|
||||||
|
|
||||||
|
default void sendMessage(@NotNull String message) {
|
||||||
|
sendMessage(Component.text(message));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command.adapt;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class ChildCommand {
|
||||||
|
@NotNull
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract String getUsage();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract String getDescription();
|
||||||
|
|
||||||
|
public abstract boolean hasPermission(@NotNull AdaptCommandSender sender);
|
||||||
|
|
||||||
|
public abstract boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args);
|
||||||
|
}
|
@@ -0,0 +1,151 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.common.command.adapt;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class ParentCommand extends ChildCommand {
|
||||||
|
@NotNull
|
||||||
|
private final Map<String, ChildCommand> childCommands;
|
||||||
|
|
||||||
|
public ParentCommand() {
|
||||||
|
childCommands = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ParentCommand getParent() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Collection<ChildCommand> getChildCommands() {
|
||||||
|
return childCommands.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
ParentCommand parent = getParent();
|
||||||
|
if (parent == null) {
|
||||||
|
return "/" + getName();
|
||||||
|
}
|
||||||
|
return parent.getUsage() + " " + getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull AdaptCommandSender sender) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有子命令
|
||||||
|
* <p>
|
||||||
|
* 如果子命令也是 ParentCommand 类型,则继续递归获取该 ParentCommand 的子命令
|
||||||
|
*
|
||||||
|
* @return 所有子命令
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<ChildCommand> getEndChildCommands() {
|
||||||
|
ArrayList<ChildCommand> list = new ArrayList<>();
|
||||||
|
for (ChildCommand command : getChildCommands()) {
|
||||||
|
if (command instanceof ParentCommand) {
|
||||||
|
list.addAll(((ParentCommand) command).getEndChildCommands());
|
||||||
|
} else {
|
||||||
|
list.add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChildCommand(@NotNull ChildCommand command) {
|
||||||
|
childCommands.put(command.getName(), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Map<String, String> getCommandHelp(AdaptCommandSender sender) {
|
||||||
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
|
for (ChildCommand child : getChildCommands()) {
|
||||||
|
if (!child.hasPermission(sender)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (child instanceof ParentCommand) {
|
||||||
|
Map<String, String> childMap = ((ParentCommand) child).getCommandHelp(sender);
|
||||||
|
map.putAll(childMap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
map.put(getUsage() + " " + child.getUsage(), child.getDescription());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendHelp(@NotNull AdaptCommandSender sender) {
|
||||||
|
sender.sendMessage("§e==================== [ " + getName() + " 使用帮助] ====================");
|
||||||
|
Map<String, String> map = getCommandHelp(sender);
|
||||||
|
int maxLength = map.keySet().stream()
|
||||||
|
.map(String::length)
|
||||||
|
.max(Integer::compareTo)
|
||||||
|
.orElse(-1);
|
||||||
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
|
sender.sendMessage(String.format("§a%-" + maxLength + "s - %s", entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (!hasPermission(sender)) {
|
||||||
|
sender.sendMessage(Component.translatable("commands.help.failed").color(NamedTextColor.RED));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args.length == 0) {
|
||||||
|
sendHelp(sender);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (ChildCommand childCommand : getChildCommands()) {
|
||||||
|
if (!childCommand.getName().equalsIgnoreCase(args[0])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!childCommand.hasPermission(sender)) {
|
||||||
|
sender.sendMessage(Component.translatable("commands.help.failed").color(NamedTextColor.RED));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return childCommand.onCommand(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
}
|
||||||
|
sender.sendMessage(Component.translatable("commands.help.failed").color(NamedTextColor.RED));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull AdaptCommandSender sender, @NotNull String[] args) {
|
||||||
|
if (args.length == 0) {
|
||||||
|
return getChildCommands().stream()
|
||||||
|
.filter(o -> o.hasPermission(sender))
|
||||||
|
.map(ChildCommand::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
for (ChildCommand child : getChildCommands()) {
|
||||||
|
if (args[0].equalsIgnoreCase(child.getName())) {
|
||||||
|
return child.onTabComplete(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args[0] = args[0].toLowerCase();
|
||||||
|
return getChildCommands().stream()
|
||||||
|
.filter(o -> o.hasPermission(sender))
|
||||||
|
.map(ChildCommand::getName)
|
||||||
|
.filter(o -> o.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@@ -11,13 +11,16 @@ import java.util.List;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BallConfig {
|
public class BallConfig {
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
|
private boolean singletonServerID;
|
||||||
@NotNull
|
@NotNull
|
||||||
private String channelPrefix;
|
private String channelPrefix;
|
||||||
private boolean gameServerUpdatePlayerInfo;
|
private boolean gameServerUpdatePlayerInfo;
|
||||||
|
@NotNull
|
||||||
private List<String> loadPlayerInfoFilter;
|
private List<String> loadPlayerInfoFilter;
|
||||||
|
|
||||||
public BallConfig(@NotNull ConfigSection config) {
|
public BallConfig(@NotNull ConfigSection config) {
|
||||||
debug = config.getBoolean("debug", false);
|
debug = config.getBoolean("debug", false);
|
||||||
|
singletonServerID = config.getBoolean("singleton-server-id", false);
|
||||||
channelPrefix = config.getString("channel-prefix", "");
|
channelPrefix = config.getString("channel-prefix", "");
|
||||||
channelPrefix = channelPrefix.isEmpty() ? channelPrefix : channelPrefix + ":";
|
channelPrefix = channelPrefix.isEmpty() ? channelPrefix : channelPrefix + ":";
|
||||||
gameServerUpdatePlayerInfo = config.getBoolean("game-server-update-player-info", false);
|
gameServerUpdatePlayerInfo = config.getBoolean("game-server-update-player-info", false);
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.common.event.operate;
|
package cn.hamster3.mc.plugin.ball.common.event.operate;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -9,8 +8,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class DispatchConsoleCommandEvent {
|
public class DispatchConsoleCommandEvent {
|
||||||
@Nullable
|
|
||||||
private final BallServerType type;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String serverID;
|
private final String serverID;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.common.event.operate;
|
package cn.hamster3.mc.plugin.ball.common.event.operate;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -11,8 +10,6 @@ import java.util.UUID;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class DispatchPlayerCommandEvent {
|
public class DispatchPlayerCommandEvent {
|
||||||
@Nullable
|
|
||||||
private final BallServerType type;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@@ -15,8 +15,11 @@ public class BallRedisListener extends JedisPubSub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(String channel, String message) {
|
public void onMessage(String channel, String message) {
|
||||||
if (channel.startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) {
|
CoreAPI.getInstance().getExecutorService().submit(() -> {
|
||||||
channel = channel.substring(BallAPI.getInstance().getBallConfig().getChannelPrefix().length());
|
try {
|
||||||
|
String finalChannel = channel;
|
||||||
|
if (finalChannel.startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) {
|
||||||
|
finalChannel = finalChannel.substring(BallAPI.getInstance().getBallConfig().getChannelPrefix().length());
|
||||||
}
|
}
|
||||||
BallMessage ballMessage = CoreAPI.getInstance().getGson().fromJson(message, BallMessage.class);
|
BallMessage ballMessage = CoreAPI.getInstance().getGson().fromJson(message, BallMessage.class);
|
||||||
BallAPI ballAPI = BallAPI.getInstance();
|
BallAPI ballAPI = BallAPI.getInstance();
|
||||||
@@ -27,7 +30,11 @@ public class BallRedisListener extends JedisPubSub {
|
|||||||
if (ballMessage.getReceiverID() != null && !ballAPI.isLocalServer(ballMessage.getReceiverID())) {
|
if (ballMessage.getReceiverID() != null && !ballAPI.isLocalServer(ballMessage.getReceiverID())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eventBus.post(new MessageReceivedEvent(channel, ballMessage));
|
eventBus.post(new MessageReceivedEvent(finalChannel, ballMessage));
|
||||||
|
} catch (Exception | Error e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -5,6 +5,7 @@ import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
|||||||
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
||||||
import cn.hamster3.mc.plugin.ball.velocity.api.CoreVelocityAPI;
|
import cn.hamster3.mc.plugin.ball.velocity.api.CoreVelocityAPI;
|
||||||
|
import cn.hamster3.mc.plugin.ball.velocity.command.VelocityBallCommand;
|
||||||
import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityListener;
|
import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityListener;
|
||||||
import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityMainListener;
|
import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityMainListener;
|
||||||
import cn.hamster3.mc.plugin.ball.velocity.listener.UpdatePlayerInfoListener;
|
import cn.hamster3.mc.plugin.ball.velocity.listener.UpdatePlayerInfoListener;
|
||||||
@@ -12,6 +13,7 @@ import cn.hamster3.mc.plugin.ball.velocity.listener.VelocityServerListener;
|
|||||||
import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils;
|
import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils;
|
||||||
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
import cn.hamster3.mc.plugin.core.common.config.YamlConfig;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.command.CommandMeta;
|
||||||
import com.velocitypowered.api.event.PostOrder;
|
import com.velocitypowered.api.event.PostOrder;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||||
@@ -29,7 +31,6 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
@Plugin(
|
@Plugin(
|
||||||
id = "hamster-ball",
|
id = "hamster-ball",
|
||||||
@@ -60,12 +61,12 @@ public class HamsterBallPlugin {
|
|||||||
this.slf4jLogger = slf4jLogger;
|
this.slf4jLogger = slf4jLogger;
|
||||||
this.proxyServer = proxyServer;
|
this.proxyServer = proxyServer;
|
||||||
dataFolder = dataPath.toFile();
|
dataFolder = dataPath.toFile();
|
||||||
logger.info("仓鼠球正在初始化");
|
slf4jLogger.info("仓鼠球正在初始化");
|
||||||
instance = this;
|
instance = this;
|
||||||
try {
|
try {
|
||||||
File dataFolder = getDataFolder();
|
File dataFolder = getDataFolder();
|
||||||
if (dataFolder.mkdir()) {
|
if (dataFolder.mkdir()) {
|
||||||
logger.info("已生成插件存档文件夹");
|
slf4jLogger.info("已生成插件存档文件夹");
|
||||||
}
|
}
|
||||||
File configFile = new File(dataFolder, "config.yml");
|
File configFile = new File(dataFolder, "config.yml");
|
||||||
if (!configFile.exists()) {
|
if (!configFile.exists()) {
|
||||||
@@ -77,37 +78,42 @@ public class HamsterBallPlugin {
|
|||||||
}
|
}
|
||||||
config = YamlConfig.load(configFile);
|
config = YamlConfig.load(configFile);
|
||||||
CoreVelocityAPI.init(config);
|
CoreVelocityAPI.init(config);
|
||||||
logger.info("已初始化 BallAPI");
|
slf4jLogger.info("已初始化 BallAPI");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
slf4jLogger.error("BallAPI 初始化失败", e);
|
slf4jLogger.error("BallAPI 初始化失败", e);
|
||||||
proxyServer.shutdown(Component.text("由于 HamsterBall 初始化失败, 服务器将立即关闭"));
|
proxyServer.shutdown(Component.text("由于 HamsterBall 初始化失败, 服务器将立即关闭"));
|
||||||
}
|
}
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
logger.info("仓鼠球初始化完成,总计耗时 " + time + " ms");
|
slf4jLogger.info("仓鼠球初始化完成,总计耗时 " + time + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(order = PostOrder.EARLY)
|
@Subscribe(order = PostOrder.EARLY)
|
||||||
public void onProxyInitialization(ProxyInitializeEvent event) {
|
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
java.util.logging.Logger logger = getLogger();
|
slf4jLogger.info("仓鼠球正在启动");
|
||||||
logger.info("仓鼠球正在启动");
|
|
||||||
try {
|
try {
|
||||||
CoreVelocityAPI.getInstance().enable();
|
CoreVelocityAPI.getInstance().enable();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "仓鼠球启动失败", e);
|
slf4jLogger.error("仓鼠球启动失败", e);
|
||||||
logger.info("由于仓鼠球启动失败,服务器将立即关闭");
|
slf4jLogger.info("由于仓鼠球启动失败,服务器将立即关闭");
|
||||||
proxyServer.shutdown(Component.text("仓鼠球启动失败"));
|
proxyServer.shutdown(Component.text("仓鼠球启动失败"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
CommandMeta commandMeta = proxyServer.getCommandManager()
|
||||||
|
.metaBuilder("hamster-velocity-ball")
|
||||||
|
.aliases("velocity-ball", "vball")
|
||||||
|
.plugin(this)
|
||||||
|
.build();
|
||||||
|
proxyServer.getCommandManager().register(commandMeta, VelocityBallCommand.INSTANCE);
|
||||||
BallAPI.getInstance().getEventBus().register(BallVelocityListener.INSTANCE);
|
BallAPI.getInstance().getEventBus().register(BallVelocityListener.INSTANCE);
|
||||||
logger.info("已注册监听器 BallVelocityListener");
|
slf4jLogger.info("已注册监听器 BallVelocityListener");
|
||||||
proxyServer.getEventManager().register(this, BallVelocityMainListener.INSTANCE);
|
proxyServer.getEventManager().register(this, BallVelocityMainListener.INSTANCE);
|
||||||
logger.info("已注册监听器 BallVelocityMainListener");
|
slf4jLogger.info("已注册监听器 BallVelocityMainListener");
|
||||||
proxyServer.getEventManager().register(this, UpdatePlayerInfoListener.INSTANCE);
|
proxyServer.getEventManager().register(this, UpdatePlayerInfoListener.INSTANCE);
|
||||||
logger.info("已注册监听器 UpdatePlayerInfoListener");
|
slf4jLogger.info("已注册监听器 UpdatePlayerInfoListener");
|
||||||
if (config.getBoolean("auto-register-game-server", false)) {
|
if (config.getBoolean("auto-register-game-server", false)) {
|
||||||
BallAPI.getInstance().getEventBus().register(VelocityServerListener.INSTANCE);
|
BallAPI.getInstance().getEventBus().register(VelocityServerListener.INSTANCE);
|
||||||
logger.info("已注册监听器 VelocityServerListener");
|
slf4jLogger.info("已注册监听器 VelocityServerListener");
|
||||||
VelocityServerListener.INSTANCE.onEnable();
|
VelocityServerListener.INSTANCE.onEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,20 +136,19 @@ public class HamsterBallPlugin {
|
|||||||
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
||||||
});
|
});
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
logger.info("仓鼠球启动完成,总计耗时 " + time + " ms");
|
slf4jLogger.info("仓鼠球启动完成,总计耗时 {} ms", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(order = PostOrder.LATE)
|
@Subscribe(order = PostOrder.LATE)
|
||||||
public void onProxyShutdown(ProxyShutdownEvent event) {
|
public void onProxyShutdown(ProxyShutdownEvent event) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
java.util.logging.Logger logger = getLogger();
|
slf4jLogger.info("仓鼠球正在关闭");
|
||||||
logger.info("仓鼠球正在关闭");
|
|
||||||
try {
|
try {
|
||||||
CoreVelocityAPI.getInstance().disable();
|
CoreVelocityAPI.getInstance().disable();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "关闭仓鼠球时遇到了一个异常", e);
|
slf4jLogger.error("关闭仓鼠球时遇到了一个异常", e);
|
||||||
}
|
}
|
||||||
long time = System.currentTimeMillis() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
logger.info("仓鼠球已关闭,总计耗时 " + time + " ms");
|
slf4jLogger.info("仓鼠球已关闭,总计耗时 {} ms", time);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
package cn.hamster3.mc.plugin.ball.velocity.command;
|
||||||
|
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.BallCommand;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.command.adapt.AdaptCommandSender;
|
||||||
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.command.SimpleCommand;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VelocityBallCommand implements SimpleCommand {
|
||||||
|
public static final VelocityBallCommand INSTANCE = new VelocityBallCommand();
|
||||||
|
|
||||||
|
private VelocityBallCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Invocation invocation) {
|
||||||
|
BallCommand.INSTANCE.onCommand(adaptCommandSender(invocation.source()), invocation.arguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation invocation) {
|
||||||
|
return invocation.source().hasPermission("hamster.ball.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggest(Invocation invocation) {
|
||||||
|
return BallCommand.INSTANCE.onTabComplete(adaptCommandSender(invocation.source()), invocation.arguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdaptCommandSender adaptCommandSender(@NotNull CommandSource source) {
|
||||||
|
return new AdaptCommandSender() {
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NotNull String permission) {
|
||||||
|
return source.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(@NotNull Component message) {
|
||||||
|
source.sendMessage(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.velocity.listener;
|
package cn.hamster3.mc.plugin.ball.velocity.listener;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
||||||
import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin;
|
import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
@@ -23,9 +22,6 @@ public class BallVelocityListener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.PROXY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -35,9 +31,6 @@ public class BallVelocityListener {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
|
public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
|
||||||
if (event.getType() != null && event.getType() != BallServerType.GAME) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
|
ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
|
||||||
if (event.getUuid() != null) {
|
if (event.getUuid() != null) {
|
||||||
Player player = server.getPlayer(event.getUuid()).orElse(null);
|
Player player = server.getPlayer(event.getUuid()).orElse(null);
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
# 是否允许在控制台输出调试信息
|
# 是否允许在控制台输出调试信息
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# 是否启用服务器 ID 单例模式
|
||||||
|
# 启用后,服务器唯一识别码 相同的服务器将无法启动
|
||||||
|
singleton-server-id: false
|
||||||
|
|
||||||
# 频道名前缀
|
# 频道名前缀
|
||||||
# 使用这个配置选项可以划分子服消息通信分组
|
# 使用这个配置选项可以划分子服消息通信分组
|
||||||
# 只有在同一个频道名的子服才能互相通信
|
# 只有在同一个频道名的子服才能互相通信
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
version: ${version}
|
VERSION: ${version}
|
||||||
CHECK_TYPE: GITEA_RELEASES
|
CHECK_TYPE: GITEA_RELEASES
|
||||||
GIT_BASE_URL: https://git.airgame.net
|
GIT_BASE_URL: https://git.airgame.net
|
||||||
GIT_REPO: MiniDay/hamster-ball
|
GIT_REPO: MiniDay/hamster-ball
|
||||||
GIT_TOKEN: a44a69a4d1b8601bf6091403247759cd28764d5e
|
|
||||||
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
DOWNLOAD_URL: https://jenkins.airgame.net/job/opensource/job/hamster-ball/
|
||||||
|
@@ -5,7 +5,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "cn.hamster3.mc.plugin"
|
group = "cn.hamster3.mc.plugin"
|
||||||
version = "1.6.2"
|
version = "1.7.0"
|
||||||
|
description = "基于 Redis 的 Minecraft 服务端通用消息中间件"
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
apply {
|
apply {
|
||||||
@@ -16,6 +17,7 @@ subprojects {
|
|||||||
|
|
||||||
group = rootProject.group
|
group = rootProject.group
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
description = rootProject.description
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://maven.airgame.net/maven-public/")
|
maven("https://maven.airgame.net/maven-public/")
|
||||||
@@ -43,11 +45,6 @@ subprojects {
|
|||||||
from(rootProject.file("LICENSE"))
|
from(rootProject.file("LICENSE"))
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
processResources {
|
|
||||||
filesMatching("update.yml") {
|
|
||||||
expand(rootProject.properties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build {
|
build {
|
||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user