# 插件编写——制作篇(下)

# Game/Lobby编写

接下来开始制作Game/Lobby服的插件,我们按照官方要求的规范更改文件夹soldierLottery的命名。并创建脚本文件夹开始编写脚本。

同时由于我们这个插件不需要行为包和资源包,所以将对应文件夹删除。

更改命名后文件夹名字如下

然后开始编写Game/Lobby和Service通信的部分,基础部分将不再过多讲解。

下方编写的都是lotteryServerSystem.py中的代码

    def GetPlayerRandomNumber(self, uid, callback):
        """
        为玩家获取一个随机彩票号码
        :param uid: 玩家UID
        :param callback:int 参数唯一,随机彩票号码,请求失败值为-1
        :return:
        """
        self.RequestToServiceMod(ServiceServerType, GetPlayerRandomNumber, {"player": uid},
                                 lambda suc, args: callback(args["msg"]) if suc else callback(-1))

例如这个接口,调用后就可以为玩家申请一个随机彩票号码,然后将号码带入回调函数的参数中并调用。Service端的对应相关代码,可以在上一节的最后找到。

同时我们还需要监听玩家加入和退出,并根据是否转服判断是否需要通知Service服务器对缓存进行处理。

    def OnJoin(self, args):
        playerId = args["id"]
        uid = args["uid"]
        self.idUidMap[playerId] = uid
        if not args["isTransfer"]:
            print "玩家{}加入,进行缓存".format(uid)
            self.CachePlayer(uid)

    def OnLeave(self, args):
        playerId = args["id"]
        uid = args["uid"]
        del self.idUidMap[playerId]
        if not args["isTransfer"]:
            print "玩家{}退出,删除缓存".format(uid)
            self.SavePlayer(uid)

    def CachePlayer(self, uid):
        def callback(suc, args):
            print "缓存玩家: suc:{} ,args:{}".format(suc, args)

        self.RequestToServiceMod(ServiceServerType, PlayerJoin, {"player": uid}, callback)

    def SavePlayer(self, uid):
        def callback(suc, args):
            print "保存玩家: suc:{} ,args:{}".format(suc, args)

        self.RequestToServiceMod(ServiceServerType, PlayerLeave, {"player": uid}, callback)

然后再监听聊天事件,判断玩家是否输入cp1,cp2,并编写相应逻辑。

    def OnServerChat(self, args):
        playerId = args["playerId"]
        message = args["message"]
        uid = self.idUidMap[playerId]
        if message == "cp1":
            args["cancel"] = True

            def callback(number):
                if number != -1:
                    self.alertSystem.Alert(playerId, '§f本次领取的号码是 §a{}'.format(number), 3)
                else:
                    self.alertSystem.Alert(playerId, '§f今日领取的号码已超过上限', 3)

            self.GetPlayerRandomNumber(uid, callback)

        elif message == "cp2":
            args["cancel"] = True

            def callback(numbers):
                if numbers is None:
                    self.alertSystem.Alert(playerId, '§c获取失败,请稍后再试', 3)
                    return
                size = len(numbers)
                if size == 0:
                    self.alertSystem.Alert(playerId, '§c你还没有领取任何号码', 3)
                else:
                    self.alertSystem.Alert(playerId, '§c今日已领取{}个号码: {}'.format(size, self.FormatNumbers(numbers)), 3)

            self.GetPlayerNumbers(uid, callback)

这里使用调用了neteaseAlert插件来发送提示,我们可以到官方插件库中下载neteaseAlert并查看readme.txt,找到我们需要的接口文档。

(1)服务端向某一个玩家弹出一个提示,内容最多显示五行 函数:Alert(playerId, text, seconds, xratio, yratio, priority) 参数: playerId: 玩家的playerId text: 需要提示的内容 seconds: 内容显示停留的秒数,不传则用mod.json的default_show_time设置 xratio: 提示背景框中心与主屏横轴的位置比,0-1之间的小数,不传则用mod.json的default_xratio设置 yratio: 提示背景框中心与主屏纵轴的位置比,0-1之间的小数,不传则用mod.json的default_yratio设置 priority: 消息显示优先级,数值越大优先级越大。优先级大于0时消息按照优先级排序,顺序显示;优先级小于0时,覆盖显示当前消息,并清空之前保存的消息。默认优先级是-1 示例: import server.extraServerApi as serverApi alertSystem = serverApi.GetSystem("neteaseAlert", "neteaseAlertDev") alertSystem.Alert(playerId, '§c摊位方块只能放置于规定的摆摊区域。', 2, 0.5, 0.8, 50) # 提示框中点位于(横屏水平方向大小0.5, 横屏竖直方向大小0.8)处

# 代码下载

教程中仅展示了部分代码,全部代码可以在这里下载。

彩票插件——lobby/game部分 (opens new window)

随后我们就可以部署并测试啦!

Game/Lobby编写

代码下载