基本跨端通信
在 Minecraft Mod 开发中,跨端通信是实现客户端与服务端交互的核心功能。通过跨端通信接口,开发者可以在不同端之间传递事件和数据,从而实现复杂的游戏逻辑。
常用跨端通信接口
以下是常用的跨端通信接口及其功能描述:
NotifyToClient
服务端向指定客户端发送事件,用于单个玩家的定向通信。NotifyToServer
客户端向服务器发送事件,用于客户端向服务端传递数据或请求。NotifyToMultiClients
服务端向多个指定客户端批量发送事件,用于群体通信。BroadcastToAllClient
服务端向所有客户端广播事件,用于全局通信。
服务端向客户端发送消息
编写服务端发送逻辑
下文将演示使用NotifyToClient
发送消息到指定客户端。
python
# -*- coding: utf-8 -*-
# 服务端
import mod.server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
class MyServer(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
mcNamespace, mcSystemName = serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName()
self.ListenForEvent(mcNamespace, mcSystemName, "PlayerAttackEntityEvent", self, self.PlayerAttackEntityEvent)
def PlayerAttackEntityEvent(self, args={}):
playerId = args["playerId"]
victimId = args["victimId"]
# 在玩家命中生物时发送一个通信到客户端
# 参数: (玩家ID, 自定义事件名, dict参数表)
self.NotifyToClient(playerId, "playerAttackEntity", {"targetId": victimId})
编写客户端接收逻辑
客户端需要定义并注册回调处理函数(监听),以便在接收到消息后处理业务。
python
# -*- coding: utf-8 -*-
# 客户端
import mod.client.extraClientApi as clientApi
ClientSystem = clientApi.GetClientSystemCls()
class MyClient(ClientSystem):
def __init__(self, namespace, systemName):
ClientSystem.__init__(self, namespace, systemName)
# 使用ListenForEvent监听指定服务端的指定事件(命名空间:test,系统名:ser1)
self.ListenForEvent("test", "ser1", "playerAttackEntity", self, self.serPlayerAttackEntity)
def serPlayerAttackEntity(self, args):
# args包含了服务端传递的信息(仅支持py基本数据类型)
print("你命中了:{}".format(args["targetId"]))
说明
广播默认没有环境隔离,需要指定命名空间,系统名区分。也可以用于跨MOD联动(虽然有其他方案)。
客户端向服务端发送消息
与服务端向客户端发送消息
类似,同样是使用广播+监听组合完成。
编写客户端发送逻辑
客户端需要定义并注册回调处理函数(监听),以便在接收到消息后处理业务。
python
# -*- coding: utf-8 -*-
# 客户端
import mod.client.extraClientApi as clientApi
ClientSystem = clientApi.GetClientSystemCls()
playerId = clientApi.GetLocalPlayerId()
class MyClient(ClientSystem):
def __init__(self, namespace, systemName):
ClientSystem.__init__(self, namespace, systemName)
mcNamespace, mcSystemName = clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName()
self.ListenForEvent(mcNamespace, mcSystemName, "ClientJumpButtonReleaseEvent", self, self.ClientJumpButtonReleaseEvent)
def ClientJumpButtonReleaseEvent(self, _={}):
# 当玩家跳跃时发送跳跃信息到服务端 (注:在高版本中客户端广播会自动携带当前playerId,因此可以不需要传递自己的id,此处仅作参考)
self.NotifyToServer("playerJumpRelease", {"clPlayerId": playerId})
编写服务端接收逻辑
python
# -*- coding: utf-8 -*-
# 服务端
import mod.server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
levelId = serverApi.GetLevelId()
class MyServer(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
self.ListenForEvent("test", "cli1", "playerJumpRelease", self, self.playerJumpRelease)
def playerJumpRelease(self, args={}):
playerId = args["clPlayerId"]
# 杀死玩家,不许跳不许停
comp = serverApi.GetEngineCompFactory().CreateGame(levelId)
comp.KillEntity(playerId)
注意
若开发网络型MOD逻辑,不要相信客户端传递的任何数据,请在服务端
二次校验。
关于性能问题
跨端通信
会立即发送数据包,高频的广播会导致性能大幅度下降(在网络环境),请控制发包频率。
总结
跨端通信是 Minecraft Mod 开发中不可或缺的一部分,通过合理使用通信接口,可以实现客户端与服务端之间的高效交互。
需要注意的是,跨端通信的频率应尽量控制,以避免性能问题。同时,服务端应对客户端传递的数据进行严格校验(在重要数据场景),确保逻辑安全性。
通过以上内容的学习,开发者可以掌握基本的跨端通信方法,为实现复杂的游戏逻辑打下基础。