Files
netease-bedrock-wiki/mcguide/27-手机网络游戏/课程12:使用Allay开服/3-NetAllay常用接口文档.md
daoge fb9586cf5d feat: 添加Allay相关教程 (#48)
* feat: 添加Allay相关教程

* feat: 添加 3-NetAllay常用接口文档.md

* docs: 更新NetAllay支持说明,添加常用接口文档链接
2026-03-25 15:13:35 +08:00

9.4 KiB
Raw Blame History

front, hard, time
front hard time
进阶 30分钟

NetAllay常用接口文档

本文整理了NetAllay项目中最常用、最适合插件开发直接使用的接口方便您在Allay服务器中调用网易版独有能力例如PyRpc通信与商城能力。

如果您尚未安装NetAllay请先阅读启用网易支持

获取NetAllay实例

调用接口前,先拿到NetAllay插件实例:

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事件。

netAllay.listenForEvent(
        "MyMod",
        "MySystemCS",
        "OnButtonClick",
        (player, data) -> {
            String buttonId = (String) data.get("buttonId");
            plugin.getPluginLogger().info("玩家点击了按钮: {}", buttonId);
        }
);

参数说明:

  • namespace命名空间一般对应客户端Mod命名空间
  • systemName:客户端系统名
  • eventName:事件名
  • handler:回调函数,参数为PlayerMap<String, Object>

取消事件监听

如果您不再需要某个监听器,可以调用以下接口:

boolean removed = netAllay.unlistenForEvent(namespace, systemName, eventName, handler);

netAllay.unlistenAllForEvent(namespace, systemName, eventName);

其中:

  • unlistenForEvent:取消一个具体处理器
  • unlistenAllForEvent:取消某个事件下的全部处理器

向客户端发送PyRpc事件

发送给单个玩家

Map<String, Object> 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

立即发送

若您希望不经过缓冲立即下发,可以使用:

boolean success = netAllay.notifyToClientImmediately(
        player,
        "MyMod",
        "MySystemSS",
        "ServerMessage",
        data
);

发送给多个玩家

int successCount = netAllay.notifyToMultiClients(
        players,
        "MyMod",
        "MySystemSS",
        "Announcement",
        Map.of("content", "服务器公告")
);

返回值为成功发送的玩家数量。

发送给附近玩家

var center = player.getControlledEntity().getLocation();

int count = netAllay.notifyToClientsNearby(
        null,
        center,
        50.0,
        "MyMod",
        "MySystemSS",
        "NearbyEvent",
        Map.of("type", "explosion")
);

参数中的except可用于排除某个玩家;若不需要排除,传null即可。

广播到世界、维度或全服

广播接口统一为broadcastToAllClient,但有三个重载版本:

// 广播到指定世界
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
);

工具接口

判断玩家是否为网易客户端

boolean netease = netAllay.isNetEasePlayer(player);

获取当前注册的事件数量

int count = netAllay.getRegisteredEventCount();

特殊常量

LOCAL_PLAYER_ENTITY_ID

int entityId = NetAllay.LOCAL_PLAYER_ENTITY_ID; // -2

这个常量表示“接收消息的玩家自己”。常见用法是把实体ID传给客户端时使用-2代表当前玩家自身实体。

netAllay.notifyToClient(
        player,
        "MyMod",
        "MySystemSS",
        "Welcome",
        Map.of("entityId", NetAllay.LOCAL_PLAYER_ENTITY_ID)
);

注意:-2只能在单播接口notifyToClientnotifyToClientImmediately中使用,不要在多播或广播接口中使用。

事件数据支持的类型

NetAllay的事件数据类型为Map<String, Object>,其中值通常支持以下类型:

  • null
  • Boolean
  • IntegerLong
  • FloatDouble
  • String
  • byte[]
  • Map<String, Object>
  • List<?>Iterable<?>

一个常见示例:

Map<String, Object> 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,用于控制网易商城界面与监听商城事件。

获取商城管理器

var shopManager = netAllay.getShopManager();

控制商城入口与界面

// 是否启用自定义商城入口
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完成

注册示例:

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

取消监听:

boolean removed = shopManager.unlistenForShopEvent(ShopEvent.PLAYER_BUY_ITEM_SUCCESS, handler);

按玩家覆盖商城配置

如果您希望不同玩家拿到不同的商城参数,可以为玩家设置单独配置:

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

获取和移除配置:

ShopManager.PlayerShopConfig config = shopManager.getPlayerConfig(player);
shopManager.removePlayerConfig(player);

配置文件

NetAllay会在插件目录生成config.json。当前源码中的默认配置如下:

{
  "shop": {
    "gameId": "",
    "gameKey": "",
    "testGameKey": "",
    "testServer": false,
    "useCustomShop": false,
    "cacheTime": 1,
    "shopServerUrl": "",
    "webServerUrl": ""
  }
}

其中商城相关字段含义如下:

  • gameId资源数字ID
  • gameKey:正式服签名密钥
  • testGameKey:测试服签名密钥
  • testServer:是否使用测试服模式
  • useCustomShop:是否隐藏默认商城按钮并改为自定义入口
  • cacheTime:商城配置缓存时间,单位为秒
  • shopServerUrl:自定义订单服务地址,可留空
  • webServerUrl自定义Web服务地址可留空

如果您在运行中修改了配置,也可以调用以下接口:

netAllay.reloadConfig();
netAllay.saveConfig();

完整示例

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包