查看: 2199|回复: 0
打印 上一主题 下一主题

[交流] [教程]在游戏中显示报错和模组冲突的解决方法

[复制链接]

22

主题

317

回帖

174

积分

Lv.4 怪物猎人

UID
373726
小麦
3
金锭
608
下界之星
0

开发者认证勋章

跳转到指定楼层
楼主
发表于 2021-6-1 22:38:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 IP:上海
本帖最后由 sevenstars 于 2021-6-2 18:10 编辑

先看一个图,这是手机上的效果

此教程将教会你①如何在手机上显示报错②如何自定义指令③如何解决模组冲突
玩家来反馈mod失效,但是自己按照这个方法想要复现却没发现问题,这有可能是mod冲突了。mod冲突有很多可能,有可能是一些开发者不小心把回调函数发来的字典修改了,导致下一个接收这个字典的开发者遭殃。也有可能是官方接口失效,直接返回一个None,还有各种奇怪问题。作为一个合格的开发者要尽量避免mod冲突,使自己的代码更健壮,防止玩家来反馈失效。
①如何自定义指令,用于切换报错显示(大佬级开发者可以跳过不看)
需要一个开关来切换是否显示报错。这里使用自定义指令来做这个功能,因为相比监听聊天,指令输完后,发送就会自动关闭聊天窗口,显得方便一点。最重要的是做起来容易。
打开mod的服务端py文件,监听CommandEvent。我指定回调函数名字叫OnCommand,以下回调函数实现了两个指令,分别用于开/关开发者模式
  1. def OnCommand(self, args):
  2.     if args['command']=='/devmode true':
  3.         #设为True取消红字报错信息
  4.         args['cancel'] = True
  5.         #使用tellraw指令给玩家反馈结果,这个指令相比/say,优点是不显示前面那个名字
  6.         #CMD就是指令接口,CMD = serverApi.GetEngineCompFactory().CreateCommand(serverApi.GetLevelId()).SetCommand
  7.         CMD('/tellraw @s {"rawtext":[{"text":"§f[连锁采集]已开启开发者模式"}]}', args['entityId'])
  8.         #通知客户端,如果你想收集客户端错误的话
  9.         self.NotifyToClient(args['entityId'], 'SetDevMode', {'value':True})
  10.         #把类变量设为True
  11.         self.DevMode = True
  12.     elif args['command']=='/devmode false':
  13.         args['cancel'] = True
  14.         CMD('/tellraw @s {"rawtext":[{"text":"§f[连锁采集]已关闭开发者模式"}]}', args['entityId'])
  15.         self.NotifyToClient(args['entityId'], 'SetDevMode', {'value':False})
  16.         self.DevMode = False
复制代码
②如何在手机上显示报错把下面的代码,在class之前的,直接复制到服务端py文件的开头即可
  1. # -*- coding: utf-8 -*-
  2. import server.extraServerApi as serverApi
  3. from functools import wraps
  4. from traceback import format_exc
  5. #三个全局变量,使得调用接口时方便点
  6. CF = serverApi.GetEngineCompFactory()
  7. LVID = serverApi.GetLevelId()
  8. #第三个全局变量,也就是之前说的那个CMD
  9. CMD = CF.CreateCommand(LVID).SetCommand
  10. #一个装饰器,用来处理报错
  11. def CatchException(originFunc):
  12.     @wraps(originFunc)
  13.     def wrapper(self, *args, **kwargs):
  14.         try:
  15.             return originFunc(self, *args, **kwargs)
  16.         except:
  17.             text = format_exc()
  18.             #text就是获取到的报错信息了,你可以在下面调用类里面的任何函数,或者直接调用官方接口
  19.             #Logger是下面的类里的函数,用来检测是不是开发者模式,
  20.             #是的话就把字符串text用/say函数显示在游戏屏幕上
  21.             self.Logger(text)
  22.         return wrapper
  23. #这就是你的mod的服务端类
  24. class ServerSystem(serverApi.GetServerSystemCls()):
  25.     def __init__(self, namespace, systemName):
  26.         self.DevMode = False
  27.         ......
  28.     def Logger(self, text, playerId=''):
  29.         if self.DevMode:
  30.             CMD('/say @s '+text, playerId)
  31.         else:
  32.             print text
复制代码
然后,修饰器和日志函数都弄好了,现在就找个类函数,在它前面加上@CatchException吧,这样这个函数如果发生错误,就能在游戏里打印出来。
  1. @CatchException
  2. def function(self, args):
  3.     ......
复制代码
③如何解决模组冲突
将mod按教程更新,加入开发者模式和报错系统,如果玩家来反馈mod失效,就告诉他指令,让他复制后打开开发者模式,然后让他把报错截图给你看就行。当然,如果还是没有报错,多半是你的代码逻辑有问题。建议自己在一些关键节点调用Logger代替print。这样,玩家打开开发者模式后,能清楚的看到代码执行的流程,方便排查问题。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部