# Spigot服与客户端python通信
# 使用方法
spigot服需要安装SpigotMaster插件,插件api文档见SpigotMasterAPI文档
客户端到spigot
在spigot使用spigotMaster.listenForEvent监听事件。
在客户端使用NotifyToServer发送事件
spigot到客户端
在客户端使用ListenForEvent监听事件
在spigot使用spigotMaster.notifyToClient或其他多播接口发送事件
示例:
spigot侧
public void onEnable() { SpigotMaster spigotMaster = (SpigotMaster) Bukkit.getPluginManager().getPlugin("SpigotMaster"); if (spigotMaster != null){ // 监听事件,然后原封不动发回去 spigotMaster.listenForEvent("MyMod", "MySystemClient", "clientEvent", new PyRpcHandler() { @Override public void onEvent(Player player, Map<String, Object> map) { spigotMaster.notifyToClient(player, "MyMod", "MySystemServer", "serverEvent", map); } }); } }
python侧
# modMain.py @Mod.InitClient() def InitClient(self): clientApi.RegisterSystem("MyMod", "MySystemClient", client_system_class_path) # clientSystem class MySystemClient(ClientSystem): def __init__(self, namespace, systemName): ClientSystem.__init__(self, namespace, systemName) # 注册事件,在回调函数中打印参数 self.ListenForEvent("MyMod", "MySystemServer", "serverEvent", self, self.onEvent) # 给spigot发一个事件 self.NotifyToServer("clientEvent", {'a': 1}) def onEvent(self, data): # 可以在客户端日志中看到onEvent {"a": 1} print 'onEvent', data
# 事件支持的参数类型及映射关系
Java类型 | Python类型 |
---|---|
null | None |
boolean | bool |
int | int |
long | long |
BigInteger(2^63到2^64-1) | long |
float | float |
double | float |
String | str |
List<Object> | list |
Map<String, Object> | dict |
# Python发送给Java
Python类型 | Java类型 |
---|---|
None | null |
bool | Boolean |
int/long(-2^31到2^31-1) | Integer |
int/long(-2^63到-2^31-1,2^31到2^63-1) | Long |
int/long(2^63到2^64-1) | BigInteger |
float | Double |
str | String |
list | List<Object> |
dict(key必须为str) | Map<String, Object> |
# 关于entityId的注意事项
客户端侧的非玩家实体的entityId与spigot侧org.bukkit.entity.Entity.getEntityId()获取的实体id相同
请注意spigot获取的实体id类型为int,而客户端modsdk接口需要的实体id类型为str
但客户端侧会存在一些负数的实体id,会geyser做协议转换时生成的虚拟实体,在spigot侧没有对应的实体
在每个客户端视角来看,本地玩家的entityId永远为-2,其他玩家的entityId与spigot侧getEntityId相同,也就是说:
客户端使用GetLocalPlayerId永远返回-2。如果将他发给spigot,那spigot是不能直接根据这个id获取到玩家的,需要做一些特殊处理
spigotMaster.listenForEvent("MyMod", "MySystemClient", "clientEvent", new PyRpcHandler() { @Override public void onEvent(Player player, Map<String, Object> map) { Player eventPlayer; String entityId = (String) map.get("entityId"); if (entityId.equals("-2")) { eventPlayer = player; } else { // 将entityId转成int然后去获取对应player } // 处理eventPlayer的逻辑 } });
如果在spigot侧使用getEntityId的返回值发给该玩家,那玩家客户端无法根据这个id获取到本地玩家,需要做一些特殊处理
int entityId; if (sendPlayer == player) { entityId = -2; } else { entityId = player.getEntityId() } map.put("entityId", entityId) spigotMaster.notifyToClient(sendPlayer, "MyMod", "MySystemServer", "serverEvent", map);
# Demo详解
详见文档Python通信Demo详解