diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/0-Allay部署教程.md b/mcguide/27-手机网络游戏/课程12:使用Allay开服/0-Allay部署教程.md new file mode 100644 index 0000000..30d4760 --- /dev/null +++ b/mcguide/27-手机网络游戏/课程12:使用Allay开服/0-Allay部署教程.md @@ -0,0 +1,79 @@ +--- +front: +hard: 入门 +time: 15分钟 +--- + +# Allay部署教程 + +本系列教程将指导您使用Allay搭建一个服务器,安装NetAllay以使用网易独有接口,以及使用WaterdogPE搭建群组服。 + +本系列教程主要侧重于网易版相关内容。有关Allay的更多文档,请移步至[AllayMC官方文档站](https://docs.allaymc.org)。 + +相关链接: +- AllayMC交流群(QQ):1072132791 +- AllayMC官方文档站:https://docs.allaymc.org +- AllayMC插件市场:https://hub.allaymc.org +- AllayMC代码仓库:https://github.com/AllayMC/Allay + +## 安装Java + +Allay 需要**Java 21**才能运行。市面上有多种 Java 发行版,但我们推荐以下版本: + +- [**GraalVM**](https://www.graalvm.org/) – 提供更好的性能 +- [**OpenJDK**](https://adoptium.net/) – 提供更佳的稳定性 + +安装后,通过运行以下程序验证 Java 是否正确安装: + +```shell +java --version +``` + +如果 Java 安装正确,您应该能看到没有错误提示的版本输出。 + +## 使用AllayLauncher + +[AllayLauncher](https://github.com/AllayMC/AllayLauncher)是一个轻量级、快速的工具(用C++编写),能帮您轻松下载、更新和管理您的Allay实例。 + +安装它只需执行一个命令: + +Windows (PowerShell): +```powershell +Invoke-Expression (Invoke-WebRequest -Uri "https://raw.githubusercontent.com/AllayMC/AllayLauncher/refs/heads/main/scripts/install_windows.ps1").Content +``` + +Linux: +```bash +wget -qO- https://raw.githubusercontent.com/AllayMC/AllayLauncher/refs/heads/main/scripts/install_linux.sh | bash +``` + +## 手动安装Allay + +### 获取Allay核心文件 + +请从[GitHub Releases](https://github.com/AllayMC/Allay/releases/latest)页面获取最新稳定版本。您也可以尝试[Nightly Build](https://github.com/AllayMC/Allay/releases/tag/nightly)。 + +您应该会得到一个文件,名称如下: +``` +allay-server--[-dev]-shaded.jar +``` + +示例: +``` +allay-server-0.1.0-dev-shaded.jar +``` + +> `-dev`后缀表示开发版本。 + +### 运行服务器 + +如果您的系统有图形界面(GUI),只需双击jar文件即可。如果正确安装了Java,会出现类似这样的窗口: + +![installation-p1.png](images/installation-p1.png) + +如果您在无头服务器(无图形界面)上,使用以下命令启动服务器: +```bash +java -jar allay-server-*-shaded.jar +``` + +您会在终端看到同样的启动输出。 \ No newline at end of file diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/1-启用网易支持.md b/mcguide/27-手机网络游戏/课程12:使用Allay开服/1-启用网易支持.md new file mode 100644 index 0000000..69c6ad3 --- /dev/null +++ b/mcguide/27-手机网络游戏/课程12:使用Allay开服/1-启用网易支持.md @@ -0,0 +1,51 @@ +--- +front: +hard: 入门 +time: 20分钟 +--- + +# 启用网易支持 + +本文将指导您调整服务器设置以允许网易客户端进服,如果您并不了解如何部署一个Allay服务器,请移步至[Allay部署教程](0-Allay部署教程.md)。 + +## 调整`server-settings.yml` + +Allay默认不允许网易客户端进服,需要修改服务器根目录下`server-settings.yml`中的如下配置项: + +```yaml +network-settings: + # Enable support for NetEase (China) Minecraft clients + netease-client-support: true + # If set to true, only NetEase clients can join the server + # This option only takes effect when netease-client-support is enabled + only-allow-netease-client: false +``` + +您还可以将`only-allow-netease-client`设置为`true`,以阻止国际版客户端进服。 + +## 安装NetAllay(可选) + +Allay的API模块默认不提供网易版独有接口,例如PyRpc,商城接口等。如需使用,您需要在服务器上安装[NetAllay](https://github.com/AllayMC/NetAllay)。 +您需要从Release页面下载NetAllay的jar包并将其放入服务器的`plugins`文件夹内。 + +如果您的插件需要调用NetAllay的接口,需要在项目中引入NetAllay作为依赖: +```kotlin +repositories { + mavenCentral() +} + +dependencies { + compileOnly("org.allaymc:net-allay:") +} + +allay { + plugin { + dependency("NetAllay") + } +} +``` + +有关NetAllay的更多内容: + +- 常用接口文档请见[NetAllay常用接口文档](3-NetAllay常用接口文档.md) +- 源码与项目仓库请见:https://github.com/AllayMC/NetAllay diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/2-使用WaterdogPE搭建群组服.md b/mcguide/27-手机网络游戏/课程12:使用Allay开服/2-使用WaterdogPE搭建群组服.md new file mode 100644 index 0000000..9528f0d --- /dev/null +++ b/mcguide/27-手机网络游戏/课程12:使用Allay开服/2-使用WaterdogPE搭建群组服.md @@ -0,0 +1,85 @@ +--- +front: +hard: 进阶 +time: 30分钟 +--- + +# 使用WaterdogPE搭建群组服 + +本文将指导您使用WaterdogPE搭建群组服务器,您需要具有群组服部署相关经验。WaterdogPE是一款适用于MCBE的群组服(反代)软件,类似MCJE的BungeeCord以及Velocity。 +有关更多WaterdogPE的相关文档,您可以移步至其[官方文档站](https://docs.waterdog.dev/books/waterdogpe-setup),本文将侧重于网易相关内容。 + +## 构建WaterdogPE + +由于WaterdogPE官方仓库并未提供网易客户端支持,您需要使用[AllayMC的分叉版本](https://github.com/AllayMC/WaterdogPE),请自行构建jar包。 + +## 启用网易支持 + +WaterdogPE启动后会生成一个`config.yml`配置文件,您需要修改以下配置项以启用网易客户端支持: + +```yaml +netease_client_support: true +# Optional: only allow NetEase clients to connect +only_allow_netease_client: false +``` + +> 启用网易客户端支持后,所有RakNet v8客户端都将被视为网易客户端。 + +## 配置下游服务器 + +在`config.yml`中,您需要配置WaterdogPE所代理的下游Allay服务器。以下是一个示例配置: + +```yaml +# 下游服务器列表 +servers: + lobby: + address: 127.0.0.1:19133 + public_address: play.myserver.com:19133 + survival: + address: 127.0.0.1:19134 + +# 玩家连接时的服务器优先级(玩家进服后默认进入列表中的第一个服务器) +priorities: + - lobby + - survival + +# 强制域名映射(可选) +forced_hosts: + lobby.myserver.com: lobby +``` + +其中: +- `address`:下游服务器的实际地址和端口 +- `public_address`:(可选)公开地址,用于玩家直连该子服 +- `priorities`:玩家进入代理后默认连接的服务器顺序 + +## 其他常用配置 + +以下是`config.yml`中一些值得关注的配置项: + +```yaml +# 代理监听地址与端口 +host: 0.0.0.0:19132 +# 最大玩家数 +max_players: 20 + +# 传递玩家真实信息到下游服务器(推荐启用) +use_login_extras: true + +# 启用快速转服(玩家在子服之间转移时不会断开连接) +fast_transfer: true + +# 压缩等级设置 +# 上行(代理→客户端),值越高带宽越省但CPU占用越高 +upstream_compression_level: 7 +# 下行(代理→子服),本地网络可设为较低值 +downstream_compression_level: -1 +``` + +> `use_login_extras`启用后,代理会在LoginPacket中附加`Waterdog_IP`(玩家真实IP)和`Waterdog_XUID`(玩家XUID)等信息,方便下游服务器获取玩家的真实连接信息。 + +## 配置下游Allay服务器 + +下游Allay服务器同样需要启用网易客户端支持,请参考[启用网易支持](1-启用网易支持.md)。 + +此外,请确保每个下游Allay服务器监听的端口与WaterdogPE中配置的`address`端口一致。例如,若WaterdogPE中配置了`lobby`服务器地址为`127.0.0.1:19133`,则对应Allay服务器的端口应设置为`19133`。 \ No newline at end of file diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/3-NetAllay常用接口文档.md b/mcguide/27-手机网络游戏/课程12:使用Allay开服/3-NetAllay常用接口文档.md new file mode 100644 index 0000000..90a9218 --- /dev/null +++ b/mcguide/27-手机网络游戏/课程12:使用Allay开服/3-NetAllay常用接口文档.md @@ -0,0 +1,399 @@ +--- +front: +hard: 进阶 +time: 30分钟 +--- + +# NetAllay常用接口文档 + +本文整理了`NetAllay`项目中最常用、最适合插件开发直接使用的接口,方便您在Allay服务器中调用网易版独有能力,例如PyRpc通信与商城能力。 + +如果您尚未安装NetAllay,请先阅读[启用网易支持](1-启用网易支持.md)。 + +## 获取NetAllay实例 + +调用接口前,先拿到`NetAllay`插件实例: + +```java +import org.allaymc.api.server.Server; +import org.allaymc.netallay.NetAllay; + +// 方式一:直接获取静态实例 +NetAllay netAllay = NetAllay.getInstance(); + +// 方式二:通过插件管理器获取 +NetAllay netAllay = (NetAllay) Server.getInstance() + .getPluginManager() + .getPlugin("NetAllay"); +``` + +## PyRpc事件监听 + +### 监听客户端发来的事件 + +最常用的入口是`listenForEvent`,用于监听网易客户端发送到服务端的PyRpc事件。 + +```java +netAllay.listenForEvent( + "MyMod", + "MySystemCS", + "OnButtonClick", + (player, data) -> { + String buttonId = (String) data.get("buttonId"); + plugin.getPluginLogger().info("玩家点击了按钮: {}", buttonId); + } +); +``` + +参数说明: + +- `namespace`:命名空间,一般对应客户端Mod命名空间 +- `systemName`:客户端系统名 +- `eventName`:事件名 +- `handler`:回调函数,参数为`Player`和`Map` + +### 取消事件监听 + +如果您不再需要某个监听器,可以调用以下接口: + +```java +boolean removed = netAllay.unlistenForEvent(namespace, systemName, eventName, handler); + +netAllay.unlistenAllForEvent(namespace, systemName, eventName); +``` + +其中: + +- `unlistenForEvent`:取消一个具体处理器 +- `unlistenAllForEvent`:取消某个事件下的全部处理器 + +## 向客户端发送PyRpc事件 + +### 发送给单个玩家 + +```java +Map data = new LinkedHashMap<>(); +data.put("message", "Hello from server!"); +data.put("timestamp", System.currentTimeMillis()); + +boolean success = netAllay.notifyToClient( + player, + "MyMod", + "MySystemSS", + "ServerMessage", + data +); +``` + +该方法返回`boolean`,表示是否发送成功。若玩家不是网易客户端,则会返回`false`。 + +### 立即发送 + +若您希望不经过缓冲立即下发,可以使用: + +```java +boolean success = netAllay.notifyToClientImmediately( + player, + "MyMod", + "MySystemSS", + "ServerMessage", + data +); +``` + +### 发送给多个玩家 + +```java +int successCount = netAllay.notifyToMultiClients( + players, + "MyMod", + "MySystemSS", + "Announcement", + Map.of("content", "服务器公告") +); +``` + +返回值为成功发送的玩家数量。 + +### 发送给附近玩家 + +```java +var center = player.getControlledEntity().getLocation(); + +int count = netAllay.notifyToClientsNearby( + null, + center, + 50.0, + "MyMod", + "MySystemSS", + "NearbyEvent", + Map.of("type", "explosion") +); +``` + +参数中的`except`可用于排除某个玩家;若不需要排除,传`null`即可。 + +### 广播到世界、维度或全服 + +广播接口统一为`broadcastToAllClient`,但有三个重载版本: + +```java +// 广播到指定世界 +int worldCount = netAllay.broadcastToAllClient( + null, + world, + "MyMod", + "MySystemSS", + "WorldEvent", + data +); + +// 广播到指定维度 +int dimensionCount = netAllay.broadcastToAllClient( + null, + dimension, + "MyMod", + "MySystemSS", + "DimensionEvent", + data +); + +// 广播到整个服务器 +int serverCount = netAllay.broadcastToAllClient( + null, + "MyMod", + "MySystemSS", + "GlobalEvent", + data +); +``` + +## 工具接口 + +### 判断玩家是否为网易客户端 + +```java +boolean netease = netAllay.isNetEasePlayer(player); +``` + +### 获取当前注册的事件数量 + +```java +int count = netAllay.getRegisteredEventCount(); +``` + +## 特殊常量 + +### `LOCAL_PLAYER_ENTITY_ID` + +```java +int entityId = NetAllay.LOCAL_PLAYER_ENTITY_ID; // -2 +``` + +这个常量表示“接收消息的玩家自己”。常见用法是把实体ID传给客户端时,使用`-2`代表当前玩家自身实体。 + +```java +netAllay.notifyToClient( + player, + "MyMod", + "MySystemSS", + "Welcome", + Map.of("entityId", NetAllay.LOCAL_PLAYER_ENTITY_ID) +); +``` + +注意:`-2`只能在单播接口`notifyToClient`或`notifyToClientImmediately`中使用,不要在多播或广播接口中使用。 + +## 事件数据支持的类型 + +`NetAllay`的事件数据类型为`Map`,其中值通常支持以下类型: + +- `null` +- `Boolean` +- `Integer`、`Long` +- `Float`、`Double` +- `String` +- `byte[]` +- `Map` +- `List`、`Iterable` + +一个常见示例: + +```java +Map data = new LinkedHashMap<>(); +data.put("title", "测试标题"); +data.put("count", 1); +data.put("extra", Map.of("flag", true)); +data.put("list", List.of("a", "b", "c")); +``` + +## 商城接口 + +`NetAllay`内置了商城管理器`ShopManager`,用于控制网易商城界面与监听商城事件。 + +### 获取商城管理器 + +```java +var shopManager = netAllay.getShopManager(); +``` + +### 控制商城入口与界面 + +```java +// 是否启用自定义商城入口 +netAllay.enableCustomShopEntry(true); + +// 打开商城 +netAllay.openShop(player); + +// 关闭商城 +netAllay.closeShop(player); + +// 显示一行提示 +netAllay.showHint(player, "购买成功"); + +// 显示两行提示 +netAllay.showHint(player, "购买成功", "奖励已发放"); +``` + +这些方法本质上是对`ShopManager`的便捷封装。 + +### 监听商城事件 + +商城常见事件定义在`ShopEvent`中: + +- `ShopEvent.PLAYER_BUY_ITEM_SUCCESS`:玩家购买成功 +- `ShopEvent.PLAYER_URGE_SHIP`:玩家催发货 +- `ShopEvent.CLIENT_LOAD_ADDON_FINISH`:客户端加载Addon完成 + +注册示例: + +```java +shopManager.listenForShopEvent(ShopEvent.PLAYER_BUY_ITEM_SUCCESS, (player, data) -> { + plugin.getPluginLogger().info("玩家 {} 完成了一笔购买", player.getOriginName()); +}); + +shopManager.listenForShopEvent(ShopEvent.PLAYER_URGE_SHIP, (player, data) -> { + plugin.getPluginLogger().info("玩家 {} 请求催发货", player.getOriginName()); +}); +``` + +取消监听: + +```java +boolean removed = shopManager.unlistenForShopEvent(ShopEvent.PLAYER_BUY_ITEM_SUCCESS, handler); +``` + +### 按玩家覆盖商城配置 + +如果您希望不同玩家拿到不同的商城参数,可以为玩家设置单独配置: + +```java +ShopManager.PlayerShopConfig config = new ShopManager.PlayerShopConfig(); +config.setGameId("123456"); +config.setUseCustomShop(true); +config.setTestServer(false); +config.setCacheTime(1); +config.setUid(0L); +config.setPlatformUid(""); + +shopManager.setPlayerConfig(player, config); +``` + +获取和移除配置: + +```java +ShopManager.PlayerShopConfig config = shopManager.getPlayerConfig(player); +shopManager.removePlayerConfig(player); +``` + +## 配置文件 + +NetAllay会在插件目录生成`config.json`。当前源码中的默认配置如下: + +```json +{ + "shop": { + "gameId": "", + "gameKey": "", + "testGameKey": "", + "testServer": false, + "useCustomShop": false, + "cacheTime": 1, + "shopServerUrl": "", + "webServerUrl": "" + } +} +``` + +其中商城相关字段含义如下: + +- `gameId`:资源数字ID +- `gameKey`:正式服签名密钥 +- `testGameKey`:测试服签名密钥 +- `testServer`:是否使用测试服模式 +- `useCustomShop`:是否隐藏默认商城按钮并改为自定义入口 +- `cacheTime`:商城配置缓存时间,单位为秒 +- `shopServerUrl`:自定义订单服务地址,可留空 +- `webServerUrl`:自定义Web服务地址,可留空 + +如果您在运行中修改了配置,也可以调用以下接口: + +```java +netAllay.reloadConfig(); +netAllay.saveConfig(); +``` + +## 完整示例 + +```java +import org.allaymc.api.player.Player; +import org.allaymc.netallay.NetAllay; +import org.allaymc.netallay.shop.ShopEvent; + +import java.util.Map; + +public final class DemoService { + + public void register() { + NetAllay netAllay = NetAllay.getInstance(); + + netAllay.listenForEvent("MyMod", "MySystemCS", "RequestData", (player, data) -> { + netAllay.notifyToClient( + player, + "MyMod", + "MySystemSS", + "ResponseData", + Map.of( + "success", true, + "playerName", player.getOriginName() + ) + ); + }); + + netAllay.getShopManager().listenForShopEvent(ShopEvent.PLAYER_BUY_ITEM_SUCCESS, (player, data) -> { + netAllay.showHint(player, "购买成功", "请及时发货"); + }); + } + + public void welcome(Player player) { + NetAllay.getInstance().notifyToClient( + player, + "MyMod", + "MySystemSS", + "Welcome", + Map.of( + "entityId", NetAllay.LOCAL_PLAYER_ENTITY_ID, + "message", "欢迎来到服务器" + ) + ); + } +} +``` + +## 注意事项 + +- `NetAllay`只会向网易客户端发送数据,非网易玩家会被自动跳过 +- 广播、多播、附近广播时不要使用`NetAllay.LOCAL_PLAYER_ENTITY_ID` +- 插件禁用时,建议取消自己注册的事件监听 +- 单次发送的数据不宜过大,避免发送过大的PyRpc包 diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/README.md b/mcguide/27-手机网络游戏/课程12:使用Allay开服/README.md new file mode 100644 index 0000000..e69de29 diff --git a/mcguide/27-手机网络游戏/课程12:使用Allay开服/images/installation-p1.png b/mcguide/27-手机网络游戏/课程12:使用Allay开服/images/installation-p1.png new file mode 100644 index 0000000..739ecd4 Binary files /dev/null and b/mcguide/27-手机网络游戏/课程12:使用Allay开服/images/installation-p1.png differ