Files
netease-modsdk-wiki/docs/mcguide/27-网络游戏/课程4:简易网络服模板知识讲解/第5节:游戏外功能.md
2025-03-17 13:24:39 +08:00

152 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/wps13.a2434b82.jpg
hard: 进阶
time: 20分钟
---
# 游戏外功能
## 运营指令
运营指令接收外部http请求处理游戏相关逻辑比如给某个玩家发物品公告等。
master是运营执行入口开发者可以根据需要把请求分发到lobby/game/service。下面给AwesomeGame新增一个运营指令功能是打印指定玩家信息。
### 获取玩家数据运营指令
由于lobby是异步定时存档的因此mysql数据可能不是最新的。这里实现方案是
* 玩家在lobby从对应lobby的内存中拉取玩家数据。
* 玩家不在lobby选择任意一个可用lobby从db中读取玩家数据。
处理过程如下所示:
![img](./images/wps13.jpg)
master主要接受请求然后转发核心代码如下所示
```python
class AwesomeMaster(MasterSystem):
def __init__(self, namespace, systemName):
MasterSystem.__init__(self, namespace, systemName)
# 注册gm指令
masterHttp.RegisterMasterHttp('/get-user-info', self, self.OnGetUserInfo) self.DefineEvent('GetUserInfoRequestEvent')
self.ListenForEvent(
'Minecraft', 'AwesomeLobby',
'GetUserInfoResponseEvent',
self, self.OnGetUserInfoResponse
)
def OnGetUserInfo(self, client_id, request_body):
'''
获取gm指令
'''
import ujson as json
request = json.loads(request_body)
uid = request['uid']
redis_key_player = "online_user_%d" % uid
#获取玩家在线状态
redisPool.AsyncHgetall(
redis_key_player,
lambda record:self._GetUserInfoCb(client_id, uid, record)
)
def _GetUserInfoCb(self, client_id, uid, record):
'''
回调函数。获取目标lobby向lobby请求在线人数。
'''
serverid = None
serverlistConf = masterConf.netgameConf['serverlist']
if record:
#若玩家在game中则随机从一个lobby获取在线人数。
serverid = record.get('serverid', None)
tmpServerConf = masterConf.serverListMap.get(serverid, None)
if not tmpServerConf or tmpServerConf['type'] != 'lobby':
serverid = None
if not serverid:
for serverConf in serverlistConf:
#服务器可用且是lobby
if serverConf['type'] == 'lobby' \
and serverManager.IsValidServer(serverConf['serverid']):
serverid = serverConf['serverid']
break
if not serverid:
response = self.makeFailResponse(master_http.HTTP_CODE_FAIL, 'no valid lobby.')
masterHttp.SendHttpResponse(client_id, response)
return
request_data = {'uid' : uid, 'client_id' : client_id}
self.NotifyToServerNode(serverid, 'GetUserInfoRequestEvent', request_data)
def OnGetUserInfoResponse(self, args):
'''
接受玩家数据返回http请求。
'''
client_id = args['client_id']
entity = args['user_info']
response = self.makeResponse(master_http.HTTP_CODE_SUCCESS, '', entity)
masterHttp.SendHttpResponse(client_id, response)
```
Lobby主要获取玩家数据核心代码如下所示
```python
class AwesomeServer(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
self.ListenForEvent(
modConfig.Minecraft, modConfig.MasterSystemName, modConfig.GetUserInfoRequestEvent,
self, self.OnGetUserInfoRequest)
def OnGetUserInfoRequest(self, args):
'''
获取玩家数据。
'''
uid = args['uid']
client_id = args['client_id']
player_data = self.mPlayerMap.get(uid, None)
if not player_data:
if self.mDBType == DbType.Mongo:
self.mMongoMgr.QueryPlayerData(
uid, uid,
lambda data: self._OnGetUserInfoRequestCb(client_id, data))
elif self.mDBType == DbType.Mysql:
self.mMysqlMgr.QueryPlayerData(
uid, uid,
lambda data: self._OnGetUserInfoRequestCb(client_id, data))
else:
self._GetUserInfoResponse(client_id, player_data.toSaveDict())
def _OnGetUserInfoRequestCb(self, client_id, record):
'''
回调函数处理db操作结果把玩家数据告知master。
'''
if record:
player_data = playerData.PlayerData()
player_data.initPlayer(-1, record)
self._GetUserInfoResponse(client_id, player_data.toSaveDict())
else:
self._GetUserInfoResponse(client_id, {})
def _GetUserInfoResponse(self, client_id, player_info):
'''
玩家数据告知master。
'''
response_data = {'client_id' : client_id, 'user_info' : player_info}
self.NotifyToMaster('GetUserInfoResponseEvent', response_data)
```
### 验证
登录到开发机然后给master发送curl请求即可获取结果如下图示
<img src="./images/wps14.jpg" alt="img" style="zoom:150%;" />
## 官方运营指令
查看“服务器MOD SDK”中【运营指令】部分里面介绍了常用的指令比如禁言、踢人等。
## 总结
- 运营指令的实现通常分为两个步骤:
- master接受响应指令将指令请求转发到其他服务器
- lobby/game/serivce实现指令功能。
- 官方实现了常见的运营指令具体可以查看“服务器MOD SDK”中【运营指令】部分。